int nbt_read_tag(nbt_file *nbt, nbt_tag **parent) { nbt_type type = 0; /* Read the type */ gzread(nbt->fp, &type, 1); (*parent)->type = type; (*parent)->name = NULL; (*parent)->value = NULL; if (type != TAG_END) /* TAG_END has no name */ nbt_read_string(nbt, &((*parent)->name)); nbt_read(nbt, type, &((*parent)->value)); return type; }
void packet_send_join_game(struct client *client) { bedrock_packet packet; int32_t dimension; uint8_t b; nbt_copy(client->data, TAG_INT, &dimension, sizeof(dimension), 1, "Dimension"); packet_init(&packet, SERVER_JOIN_GAME); packet_pack_int(&packet, &client->id, sizeof(client->id)); /* Entity ID */ b = client->gamemode; packet_pack_int(&packet, &b, sizeof(b)); b = dimension; packet_pack_int(&packet, &b, sizeof(b)); packet_pack_int(&packet, nbt_read(client->world->data, TAG_BYTE, 2, "Data", "hardcore"), sizeof(uint8_t)); /* hardcore */ b = server_maxusers; packet_pack_int(&packet, &b, sizeof(b)); /* Max players */ packet_pack_string(&packet, nbt_read_string(client->world->data, 2, "Data", "generatorName")); /* Level type */ client_send_packet(client, &packet); bedrock_assert(client->state == STATE_LOGGED_IN, ;);
int nbt_read(nbt_file *nbt, nbt_type type, void **parent) { switch (type) { case TAG_END: break; case TAG_BYTE: nbt_read_byte(nbt, (char **)parent); break; case TAG_SHORT: nbt_read_short(nbt, (int16_t **)parent); break; case TAG_INT: nbt_read_int(nbt, (int32_t **)parent); break; case TAG_LONG: nbt_read_long(nbt, (int64_t **)parent); break; case TAG_FLOAT: nbt_read_float(nbt, (float **)parent); break; case TAG_DOUBLE: nbt_read_double(nbt, (double **)parent); break; case TAG_STRING: ;; /* to make it shut up about the variable declaration */ char *string = NULL; nbt_read_string(nbt, &string); *parent = string; break; case TAG_BYTE_ARRAY: ;; /* ... */ unsigned char *bytestring; int32_t len = nbt_read_byte_array(nbt, &bytestring); nbt_byte_array *t = malloc(sizeof(nbt_byte_array)); t->length = len; t->content = bytestring; *parent = t; break; case TAG_LIST: ;; char type; void **target; int32_t length = nbt_read_list(nbt, &type, &target); nbt_list *l = malloc(sizeof(nbt_list)); l->length = length; l->type = type; l->content = target; *parent = l; break; case TAG_COMPOUND: ;; nbt_compound *c = malloc(sizeof(nbt_compound)); nbt_tag **tags = NULL; int32_t lc = nbt_read_compound(nbt, &tags); c->tags = tags; c->length = lc; *parent = c; } return type; /* Use to abort looping in TAG_Read_compound on TAG_END */ }