diff --git b/mcplayerstat.c a/mcplayerstat.c new file mode 100644 index 0000000..a9f9479 --- /dev/null +++ a/mcplayerstat.c @@ -0,0 +1,110 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "nbt.h" + +double convertDouble(uint64_t data) { + double d = 0; + uint64_t swapped = __bswap_64(data); + memcpy(&d,&swapped,sizeof(uint64_t)); + return d; +} + +void printInventory(TagList *inv) { + for(int j = 0; j < inv->size; ++j) { + TagCompound item = *(TagCompound*)inv->list[j].payload; + uint8_t slot = 0; + char* id; + uint8_t count = 0; + for(int k = 0; k < item.numTags; ++k) { + Tag attr = item.list[k]; + if(!strncmp(attr.name,"Slot",attr.nameLength)) { + slot = *((uint8_t*)attr.payload); + } else if(!strncmp(attr.name,"id",attr.nameLength)) { + id = (char*)attr.payload; + } else if(!strncmp(attr.name,"Count",attr.nameLength)) { + count = *((uint8_t*)attr.payload); + } + } + printf("\t- [%u] %ux %s\n",slot,count,id); + } +} + +int parseMCPlayerFile(const char* filename) { + struct stat sb; + unsigned int pos = 0; + + int fd = open(filename,O_RDONLY); + if(fd == -1) { + perror("Can't open file"); + return 3; + } + fstat(fd, &sb); + + void* mappedFile = mmap(NULL,sb.st_size,PROT_READ,MAP_PRIVATE,fd,0); + + // int playerGameType + // int XpLevel + // list(compound) Inventory + // list(compound) EnderItems + // list(float) Pos + + Tag t; + pos = parseTag((mappedFile + pos),&t); + if(pos != sb.st_size) { + fprintf(stderr,"Didn't reach end of NBT file\n"); + return 4; + } + + TagCompound root = *(TagCompound*) t.payload; + for(int i = 0; i < root.numTags; ++i) { + Tag node = root.list[i]; + if(node.type == TAG_INT) { + if(!strncmp(node.name,"playerGameType",node.nameLength)) { + int playerGameType = __bswap_32(*((uint32_t*)node.payload)); + printf("playerGameType: %s\n",(playerGameType == 0 ? "Survival" : (playerGameType == 1 ? "Creative" : (playerGameType == 2 ? "Adventure" : (playerGameType == 3 ? "Spectator" : "UNKNOWN"))))); + } else if (!strncmp(node.name,"XpLevel",node.nameLength)) { + int xpLevel = __bswap_32(*((uint32_t*)node.payload)); + printf("XpLevel: %u\n",xpLevel); + } + } else if(node.type == TAG_LIST) { + TagList* l = (TagList*)node.payload; + if(!strncmp(node.name,"Inventory",node.nameLength)) { + printf("Inventory:\n"); + printInventory(l); + } else if (!strncmp(node.name,"EnderItems",node.nameLength)) { + printf("Ender Inventory:\n"); + printInventory(l); + } else if (!strncmp(node.name,"Pos",node.nameLength)) { + double x = convertDouble((*(uint64_t*)l->list[0].payload)); + double y = convertDouble((*(uint64_t*)l->list[1].payload)); + double z = convertDouble((*(uint64_t*)l->list[2].payload)); + printf("Pos: (x: %f,y: %f,z: %f)\n",x,y,z); + } + } + } + + destroyTag(&t); + munmap(mappedFile,sb.st_size); + close(fd); + return 0; +} + +int main(int argc, char** argv) { + if(argc != 2) { + fprintf(stderr,"No file specified\n"); + return 1; + } + + if(access(argv[1],R_OK) == -1) { + perror("Can't access file"); + return 2; + } + + return parseMCPlayerFile(argv[1]); +} \ No newline at end of file