int signs(chunk *r, int x, int z, void *ctx) { tag t; t.data = NULL; tag_parse(&t,r); if(t.data == NULL) return 0; tag *tents; if(tag_find(&t,&tents,1,"TileEntities") && tents->type == 9) { tag *ents = (tag*)tents->data; tag *tid; tag *ttext; int i; for(i = 0; i < tents->length; i++) { if(tag_find(ents+i,&tid,1,"id") && tid->type == 8) { if(tid->length == 4 && strncmp((char*)tid->data,"Sign",4) == 0) { int *pos[3]; tag *text[4]; ttile_pos(pos,ents+i); if(!tag_find(ents+i,text+0,1,"Text1")) continue; if(!tag_find(ents+i,text+1,1,"Text2")) continue; if(!tag_find(ents+i,text+2,1,"Text3")) continue; if(!tag_find(ents+i,text+3,1,"Text4")) continue; printf("(%i+%i,%i,%i+%i)\n",x,*pos[0],*pos[1],z,*pos[2]); if(text[0]->data != NULL) { printf("\"%s\"\n",(char*)text[0]->data); } else { printf("\"\"\n"); } if(text[1]->data != NULL) { printf("\"%s\"\n",(char*)text[1]->data); } else { printf("\"\"\n"); } if(text[2]->data != NULL) { printf("\"%s\"\n",(char*)text[2]->data); } else { printf("\"\"\n"); } if(text[3]->data != NULL) { printf("\"%s\"\n",(char*)text[3]->data); } else { printf("\"\"\n"); } printf("\n"); } } } } tag_destroy(&t); return 0; }
int main(int argc, char *argv[]) { if(argc != 2) { printf("Usage: %s [.dat]\n",argv[0]); return 2; } chunk *f = chunk_opengz(argv[1],"r"); if(!f) { printf("Cound not open file\n"); return 3; } tag t; t.data = NULL; tag_parse(&t,f); chunk_close(f); if(!t.data) { printf("No data found\n"); return 5; } tag_tree(&t); tag_destroy(&t); }
bool tag_read( uint8_t* buf, uint32_t buf_len, bool one_byte_name_is_id, TAG** tag_out, uint8_t** after_tag_out, uint32_t* bytes_read_out ) { bool result = false; uint32_t tag_len = 0; TAG* tag = NULL; uint8_t* p = NULL; uint8_t* pout = NULL; uint8_t type = 0; uint32_t i = 0; uint32_t io_bytes = 0; do { if (!buf || !buf_len || !tag_out) break; if (!tag_length(buf, buf_len, &tag_len)){ LOG_ERROR("Failed to calculate tag size."); break; } tag = (TAG*)mem_alloc(tag_len); if (!tag){ LOG_ERROR("Failed to allocate memory for tag."); break; } p = buf; type = *p++; if (type & TAG_NAME_ID_FLAG){ // Name id is used. type &= ~TAG_NAME_ID_FLAG; tag->name_id = *p++; } else { tag->name_len = *(uint16_t*)p; p += sizeof(uint16_t); if (one_byte_name_is_id && tag->name_len == 1){ tag->name_id = *p++; } else { for (uint32_t i = 0; i < tag->name_len; i++){ tag->name[i] = *(p + i); } p += tag->name_len; } } tag->type = type; tag->data_offset = tag->name_len?(10 + (tag->name_len - 1) * 2):10; pout = (uint8_t*)tag + tag->data_offset; switch (type){ case TAGTYPE_HASH16: memcpy(pout, p, 16); p += 16; break; case TAGTYPE_STRING: // Bytes count in utf-8 encoded string *(uint16_t*)pout = *(uint16_t*)p; str_utf8_to_unicode( (char*)(p + 2), *(uint16_t*)p, (wchar_t*)(pout + 2), *((uint16_t*)pout) * 2, &io_bytes ); p += sizeof(uint16_t) + *(uint16_t*)p; break; case TAGTYPE_UINT32: *(uint32_t*)pout = *(uint32_t*)p; p += sizeof(uint32_t); break; case TAGTYPE_FLOAT32: memcpy(pout, p, sizeof(float)); p += sizeof(float); break; case TAGTYPE_BOOL: *pout = *p; p++; break; case TAGTYPE_BOOLARRAY: // [IMPLEMENT] break; case TAGTYPE_BLOB: *(uint32_t*)pout = *(uint32_t*)p; memcpy(pout + 4, p + 4, *(uint32_t*)p); p += sizeof(uint32_t) + *(uint32_t*)p; break; case TAGTYPE_UINT16: *(uint16_t*)pout = *(uint16_t*)p; p += sizeof(uint16_t); break; case TAGTYPE_UINT8: *pout = *p; p++; break; case TAGTYPE_BSOB: *pout = *p; memcpy(pout + 1, p + 1, *p); p += sizeof(uint8_t) + *p; break; case TAGTYPE_UINT64: *(uint64_t*)pout = *(uint64_t*)p; p += sizeof(uint64_t); break; } *tag_out = tag; if (after_tag_out) *after_tag_out = p; if (bytes_read_out) *bytes_read_out = p - buf; result = true; } while (false); if (!result && tag) tag_destroy(tag); return result; }