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 | \ No newline at end of file | 111 | \ No newline at end of file |