// // world.c // mcc // // Created by Finn Behrens on 28.02.21. // #include #include "world.h" #include "main.h" #define MC_DIM_CODEC_CNAME "element" #define MC_DIM_CODEC_NAME_PIGLIN_SAFE "piglin_safe" #define MC_DIM_CODEC_NAME_NATURAL "natural" #define MC_DIM_CODEC_NAME_AMBIENT_LIGHT "ambient_light" #define MC_DIM_CODEC_NAME_FIXED_TIME "fixed_time" #define MC_DIM_CODEC_NAME_INFINIBURN "infiniburn" #define MC_DIM_CODEC_NAME_RESPAWN_ANCHOR_WORKS "respawn_anchor_works" #define MC_DIM_CODEC_NAME_HAS_SKYLIGHT "has_skylight" #define MC_DIM_CODEC_NAME_BED_WORKS "bed_works" #define MC_DIM_CODEC_NAME_EFFECTS "effects" #define MC_DIM_CODEC_NAME_HAS_RAIDS "has_raids" #define MC_DIM_CODEC_NAME_LOGICAL_HEIGHT "logical_height" #define MC_DIM_CODEC_NAME_COORDINATE_SCALE "coordinate_scale" #define MC_DIM_CODEC_NAME_ULTRAWARM "ultrawarm" #define MC_DIM_CODEC_NAME_HAS_CEILING "has_ceiling" int mc_nbt_tail_list_byte(struct nbt_list *list, int8_t data, char* name) { struct nbt_list *new; new = malloc(sizeof(struct nbt_list)); if (new == NULL) { return -ENOMEM; } new->data = malloc(sizeof(nbt_node)); new->data->type = TAG_BYTE; new->data->payload.tag_byte = data; new->data->name = malloc(strlen(name) + 1); strcpy(new->data->name, name); list_add_tail(&new->entry, &list->entry); return 0; } int mc_nbt_tail_list_int(struct nbt_list *list, int32_t data, char* name) { struct nbt_list *new; new = malloc(sizeof(struct nbt_list)); if (new == NULL) { return -ENOMEM; } new->data = malloc(sizeof(nbt_node)); new->data->type = TAG_INT; new->data->payload.tag_int = data; new->data->name = malloc(strlen(name) + 1); strcpy(new->data->name, name); list_add_tail(&new->entry, &list->entry); return 0; } int mc_nbt_tail_list_long(struct nbt_list *list, int64_t data, char* name) { struct nbt_list *new; new = malloc(sizeof(struct nbt_list)); if (new == NULL) { return -ENOMEM; } new->data = malloc(sizeof(nbt_node)); new->data->type = TAG_LONG; new->data->payload.tag_long = data; new->data->name = malloc(strlen(name) + 1); strcpy(new->data->name, name); list_add_tail(&new->entry, &list->entry); return 0; } int mc_nbt_tail_list_float(struct nbt_list *list, float data, char* name) { struct nbt_list *new; new = malloc(sizeof(struct nbt_list)); if (new == NULL) { return -ENOMEM; } new->data = malloc(sizeof(nbt_node)); new->data->type = TAG_FLOAT; new->data->payload.tag_float = data; new->data->name = malloc(strlen(name) + 1); strcpy(new->data->name, name); list_add_tail(&new->entry, &list->entry); return 0; } int mc_nbt_tail_list_strcpy(struct nbt_list *list, char* data, char* name) { struct nbt_list *new; if (data == NULL || name == NULL) return -EFAULT; new = malloc(sizeof(struct nbt_list)); if (new == NULL) { return -ENOMEM; } new->data = malloc(sizeof(nbt_node)); new->data->type = TAG_STRING; new->data->payload.tag_string = malloc(strlen(data) + 1); strcpy(new->data->payload.tag_string, data); new->data->name = malloc(strlen(name) + 1); strcpy(new->data->name, name); list_add_tail(&new->entry, &list->entry); return 0; } struct nbt_list *mc_dimension_codec_to_list(mc_dimension_element_t *codec) { struct nbt_list *ret, *new; struct list_head *pos; if (codec == NULL) { errno = -EFAULT; return NULL; } ret = malloc(sizeof(*ret)); if (ret == NULL) { errno = -ENOMEM; return NULL; } INIT_LIST_HEAD(&ret->entry); if ((errno = mc_nbt_tail_list_byte(ret, codec->piglin_safe, MC_DIM_CODEC_NAME_PIGLIN_SAFE)) != 0) goto out_err; if ((errno = mc_nbt_tail_list_byte(ret, codec->natural, MC_DIM_CODEC_NAME_NATURAL)) != 0) goto out_err; if ((errno = mc_nbt_tail_list_float(ret, codec->ambient_light, MC_DIM_CODEC_NAME_AMBIENT_LIGHT)) != 0) goto out_err; if (codec->fixed_time >= 0 && codec->fixed_time <= 24000) if ((errno = mc_nbt_tail_list_long(ret, codec->fixed_time, MC_DIM_CODEC_NAME_FIXED_TIME)) != 0) goto out_err; if ((errno = mc_nbt_tail_list_strcpy(ret, codec->infiniburn, MC_DIM_CODEC_NAME_INFINIBURN)) != 0) goto out_err; if ((errno = mc_nbt_tail_list_byte(ret, codec->respawn_anchor_works, MC_DIM_CODEC_NAME_RESPAWN_ANCHOR_WORKS)) != 0) goto out_err; if ((errno = mc_nbt_tail_list_byte(ret, codec->has_skylight, MC_DIM_CODEC_NAME_HAS_SKYLIGHT)) != 0) goto out_err; if ((errno = mc_nbt_tail_list_byte(ret, codec->bed_works, MC_DIM_CODEC_NAME_BED_WORKS)) != 0) goto out_err; if ((errno = mc_nbt_tail_list_strcpy(ret, codec->effects, MC_DIM_CODEC_NAME_EFFECTS)) != 0) goto out_err; if ((errno = mc_nbt_tail_list_byte(ret, codec->has_raids, MC_DIM_CODEC_NAME_HAS_RAIDS)) != 0) goto out_err; if ((errno = mc_nbt_tail_list_int(ret, codec->logical_height, MC_DIM_CODEC_NAME_LOGICAL_HEIGHT)) != 0) goto out_err; if ((errno = mc_nbt_tail_list_float(ret, codec->coordinate_scale, MC_DIM_CODEC_NAME_COORDINATE_SCALE)) != 0) goto out_err; if ((errno = mc_nbt_tail_list_byte(ret, codec->ultrawarm, MC_DIM_CODEC_NAME_ULTRAWARM)) != 0) goto out_err; if ((errno = mc_nbt_tail_list_byte(ret, codec->has_ceiling, MC_DIM_CODEC_NAME_HAS_CEILING)) != 0) goto out_err; return ret; out_err: nbt_free_list(ret); return NULL; } nbt_node *mc_dimension_element_to_nbt(mc_dimension_element_t *codec) { // TODO: memleak at error struct nbt_list *list; nbt_node *root = malloc(sizeof(nbt_node)); list = mc_dimension_codec_to_list(codec); if (list == NULL) return NULL; root->type = TAG_COMPOUND; root->payload.tag_compound = list; root->name = malloc(strlen(MC_DIM_CODEC_CNAME) + 1); strcpy(root->name, MC_DIM_CODEC_CNAME); return root; } nbt_node *mc_dimension_registry_element_to_nbt(mc_dimension_registry_element_t *el) { struct nbt_list *new; nbt_node *root = malloc(sizeof(nbt_node)); if (root == NULL) { errno = -ENOMEM; return NULL; } root->type = TAG_COMPOUND; root->name = malloc(0); root->payload.tag_compound = malloc(sizeof(struct nbt_list)); if (root->payload.tag_compound == NULL) { errno = -ENOMEM; goto out_err; } INIT_LIST_HEAD(&root->payload.tag_compound->entry); if ((errno = mc_nbt_tail_list_strcpy(root->payload.tag_compound, el->name, "name")) != 0) goto out_err; if ((errno = mc_nbt_tail_list_int(root->payload.tag_compound, el->id, "id")) != 0) goto out_err; new = malloc(sizeof(*new)); if (new == NULL) { errno = -ENOMEM; goto out_err; } new->data = mc_dimension_element_to_nbt(el->element); if (new->data == NULL) goto out_err_new; list_add_tail(&new->entry, &root->payload.tag_compound->entry); return root; out_err_new: nbt_free_list(new); out_err: nbt_free(root); return NULL; } mc_dimension_element_t *mc_dim_element_default_overworld() { mc_dimension_element_t *dimc = malloc(sizeof(mc_dimension_element_t)); if (dimc == NULL) { errno = -ENOMEM; return NULL; } dimc->piglin_safe = false; dimc->natural = true; dimc->ambient_light = 0.0; dimc->fixed_time = -1; // no fixed time dimc->infiniburn = malloc(strlen("minecraft:infiburn-overworld") + 1); strcpy(dimc->infiniburn, "minecraft:infiburn-overworld"); dimc->respawn_anchor_works = false; dimc->has_skylight = true; dimc->bed_works = true; dimc->effects = malloc(strlen("minecraft:overworld") + 1); strcpy(dimc->effects, "minecraft:overworld"); dimc->has_raids = true; dimc->logical_height = 256; dimc->coordinate_scale = 1.0; dimc->ultrawarm = false; dimc->has_ceiling = false; return dimc; } mc_dimension_registry_element_t *mc_dim_registry_element_default_overworld() { mc_dimension_registry_element_t *reg = malloc(sizeof(mc_dimension_registry_element_t)); if (reg == NULL) { errno = -ENOMEM; return NULL; } reg->element = mc_dim_element_default_overworld(); if (reg->element == NULL) { // errno set by mc_dim_element_default_overworld(); free(reg); return NULL; } reg->name = malloc(strlen("minecraft:overworld") + 1); if (reg->name == NULL) { free(reg->element); free(reg); return NULL; } strcpy(reg->name, "minecraft:overworld"); reg->id = 0; return reg; } mc_world_t *world; int init_world() { world = calloc(1, sizeof(mc_world_t)); if (world == NULL) return -ENOMEM; world->max_players = config->max_user; // TODO: read from config world->curr_players = 5; // TODO: get real data }