Commit 4f07b8766a5497ad8476be6b6ebb7a8405d1adc0
0 parents
First import
Showing
1 changed file
with
110 additions
and
0 deletions
mcplayerstat.c
0 → 100644
1 | +++ a/mcplayerstat.c | |
1 | +#include <stdio.h> | |
2 | +#include <unistd.h> | |
3 | +#include <sys/mman.h> | |
4 | +#include <sys/stat.h> | |
5 | +#include <fcntl.h> | |
6 | +#include <stdint.h> | |
7 | +#include <byteswap.h> | |
8 | + | |
9 | +#include "nbt.h" | |
10 | + | |
11 | +double convertDouble(uint64_t data) { | |
12 | + double d = 0; | |
13 | + uint64_t swapped = __bswap_64(data); | |
14 | + memcpy(&d,&swapped,sizeof(uint64_t)); | |
15 | + return d; | |
16 | +} | |
17 | + | |
18 | +void printInventory(TagList *inv) { | |
19 | + for(int j = 0; j < inv->size; ++j) { | |
20 | + TagCompound item = *(TagCompound*)inv->list[j].payload; | |
21 | + uint8_t slot = 0; | |
22 | + char* id; | |
23 | + uint8_t count = 0; | |
24 | + for(int k = 0; k < item.numTags; ++k) { | |
25 | + Tag attr = item.list[k]; | |
26 | + if(!strncmp(attr.name,"Slot",attr.nameLength)) { | |
27 | + slot = *((uint8_t*)attr.payload); | |
28 | + } else if(!strncmp(attr.name,"id",attr.nameLength)) { | |
29 | + id = (char*)attr.payload; | |
30 | + } else if(!strncmp(attr.name,"Count",attr.nameLength)) { | |
31 | + count = *((uint8_t*)attr.payload); | |
32 | + } | |
33 | + } | |
34 | + printf("\t- [%u] %ux %s\n",slot,count,id); | |
35 | + } | |
36 | +} | |
37 | + | |
38 | +int parseMCPlayerFile(const char* filename) { | |
39 | + struct stat sb; | |
40 | + unsigned int pos = 0; | |
41 | + | |
42 | + int fd = open(filename,O_RDONLY); | |
43 | + if(fd == -1) { | |
44 | + perror("Can't open file"); | |
45 | + return 3; | |
46 | + } | |
47 | + fstat(fd, &sb); | |
48 | + | |
49 | + void* mappedFile = mmap(NULL,sb.st_size,PROT_READ,MAP_PRIVATE,fd,0); | |
50 | + | |
51 | + // int playerGameType | |
52 | + // int XpLevel | |
53 | + // list(compound) Inventory | |
54 | + // list(compound) EnderItems | |
55 | + // list(float) Pos | |
56 | + | |
57 | + Tag t; | |
58 | + pos = parseTag((mappedFile + pos),&t); | |
59 | + if(pos != sb.st_size) { | |
60 | + fprintf(stderr,"Didn't reach end of NBT file\n"); | |
61 | + return 4; | |
62 | + } | |
63 | + | |
64 | + TagCompound root = *(TagCompound*) t.payload; | |
65 | + for(int i = 0; i < root.numTags; ++i) { | |
66 | + Tag node = root.list[i]; | |
67 | + if(node.type == TAG_INT) { | |
68 | + if(!strncmp(node.name,"playerGameType",node.nameLength)) { | |
69 | + int playerGameType = __bswap_32(*((uint32_t*)node.payload)); | |
70 | + printf("playerGameType: %s\n",(playerGameType == 0 ? "Survival" : (playerGameType == 1 ? "Creative" : (playerGameType == 2 ? "Adventure" : (playerGameType == 3 ? "Spectator" : "UNKNOWN"))))); | |
71 | + } else if (!strncmp(node.name,"XpLevel",node.nameLength)) { | |
72 | + int xpLevel = __bswap_32(*((uint32_t*)node.payload)); | |
73 | + printf("XpLevel: %u\n",xpLevel); | |
74 | + } | |
75 | + } else if(node.type == TAG_LIST) { | |
76 | + TagList* l = (TagList*)node.payload; | |
77 | + if(!strncmp(node.name,"Inventory",node.nameLength)) { | |
78 | + printf("Inventory:\n"); | |
79 | + printInventory(l); | |
80 | + } else if (!strncmp(node.name,"EnderItems",node.nameLength)) { | |
81 | + printf("Ender Inventory:\n"); | |
82 | + printInventory(l); | |
83 | + } else if (!strncmp(node.name,"Pos",node.nameLength)) { | |
84 | + double x = convertDouble((*(uint64_t*)l->list[0].payload)); | |
85 | + double y = convertDouble((*(uint64_t*)l->list[1].payload)); | |
86 | + double z = convertDouble((*(uint64_t*)l->list[2].payload)); | |
87 | + printf("Pos: (x: %f,y: %f,z: %f)\n",x,y,z); | |
88 | + } | |
89 | + } | |
90 | + } | |
91 | + | |
92 | + destroyTag(&t); | |
93 | + munmap(mappedFile,sb.st_size); | |
94 | + close(fd); | |
95 | + return 0; | |
96 | +} | |
97 | + | |
98 | +int main(int argc, char** argv) { | |
99 | + if(argc != 2) { | |
100 | + fprintf(stderr,"No file specified\n"); | |
101 | + return 1; | |
102 | + } | |
103 | + | |
104 | + if(access(argv[1],R_OK) == -1) { | |
105 | + perror("Can't access file"); | |
106 | + return 2; | |
107 | + } | |
108 | + | |
109 | + return parseMCPlayerFile(argv[1]); | |
110 | +} | |
0 | 111 | \ No newline at end of file | ... | ... |