From 07514a620c4af0e3b43efffa90087594e4e62577 Mon Sep 17 00:00:00 2001 From: Christian Heller Date: Tue, 28 Jan 2014 06:40:12 +0100 Subject: [PATCH] Also built checks for server config files, and accordingly reformatted those. --- README | 11 ++++--- confserver/defs | 49 ++++++++++++++++++++++++---- confserver/map_object_actions | 25 ++++++++++++--- src/server/main.c | 2 ++ src/server/map_object_actions.c | 45 ++++++++++++++++++-------- src/server/map_objects.c | 57 +++++++++++++++++++++++++-------- 6 files changed, 147 insertions(+), 42 deletions(-) diff --git a/README b/README index d6883c1..7b71967 100644 --- a/README +++ b/README @@ -80,9 +80,11 @@ Hacking / server internals and configuration -------------------------------------------- The movements/actions available to the player and the enemies are defined and -can be changed in ./confserver/map_object_actions. Each line consists of, first, -a numerical ID used internally to manage the action, secondly the number of -turns the action takes, and thirdly a string representing the action internally. +can be changed in ./confserver/map_object_actions. Each entry consists of a +first line of a numerical ID used internally to uniquely identify and manage the +action, a second line of the number of turns the action takes, and a third line +of a string that maps the action to the game logic to perform when it is called. +Finally, a delimiter line of "%%" ends the entry. The different map object types, i.e. species (including the player's human one) and item types, can be edited in ./confserver/defs. Here the first value is a @@ -91,7 +93,8 @@ this object decomposes to when it gets destroyed/killed, the third value is the character used to represent the object visually on the map, the fourth value is the number of hitpoints the object starts with (items are dead and start with zero hitpoints, anything else moves), the fifth is the string that names the -object in the game log. Note that the only valid item use so far, consuming +object in the game log. Finally, the same delimiter as for the map object action +definitions file follows. Note that the only valid item use so far, consuming "magic meat" to gain hitpoints, is so far hard-coded (this should change in the future). diff --git a/confserver/defs b/confserver/defs index f114ce2..3eb9791 100644 --- a/confserver/defs +++ b/confserver/defs @@ -1,7 +1,42 @@ -0 5 @ 5 HUMAN -1 4 a 1 ANT -2 5 z 3 ZOMBIE -3 6 S 9 SHOGGOTH -4 4 # 0 DIRT -5 4 % 0 SKELETON -6 4 m 0 MAGIC MEAT +0 +5 +@ +5 +HUMAN +%% +1 +4 +a +1 +ANT +%% +2 +5 +z +3 +ZOMBIE +%% +3 +6 +S +9 +SHOGGOTH +%% +4 +4 +# +0 +DIRT +%% +5 +4 +% +0 +SKELETON +%% +6 +4 +m +0 +MAGIC MEAT +%% diff --git a/confserver/map_object_actions b/confserver/map_object_actions index 1ed03ea..da514e6 100644 --- a/confserver/map_object_actions +++ b/confserver/map_object_actions @@ -1,5 +1,20 @@ -0 1 wait -1 3 move -2 10 pick_up -3 3 drop -4 30 use +0 +1 +wait +%% +1 +3 +move +%% +2 +10 +pick_up +%% +3 +3 +drop +%% +4 +30 +use +%% diff --git a/src/server/main.c b/src/server/main.c index 6cf6b41..09ce530 100644 --- a/src/server/main.c +++ b/src/server/main.c @@ -5,6 +5,7 @@ #include /* exit() */ #include /* mkfifo(), mkdir() */ #include /* access() */ +#include "../common/err_try_fgets.h" /* set_err_try_fgets_delim() */ #include "../common/rexit.h" /* exit_err, exit_trouble(), set_cleanup_func() */ #include "cleanup.h" /* set_cleanup_flag(), cleanup() */ #include "init.h" /* run_game(), obey_argv() */ @@ -44,6 +45,7 @@ int main(int argc, char ** argv) world.path_out = "server/out"; world.path_record = "record"; world.tmp_suffix = "_tmp"; + set_err_try_fgets_delim("%%\n"); /* Treat world.path_in file as server process lock file. */ char * err = "Found pre-existing input fifo file. This indicates another " diff --git a/src/server/map_object_actions.c b/src/server/map_object_actions.c index b77ffb9..476ba91 100644 --- a/src/server/map_object_actions.c +++ b/src/server/map_object_actions.c @@ -2,14 +2,17 @@ #include "map_object_actions.h" #include /* NULL */ -#include /* uint8_t, uint16_t */ -#include /* sprintf() */ +#include /* uint8_t, uint16_t, UINT8_MAx */ +#include /* sprintf(), ungetc() */ #include /* free(), atoi() */ -#include /* strlen(), strcmp(), memcpy(), strtok(), strncmp() */ +#include /* strlen(), strcmp(), memcpy(), strncmp() */ +#include "../common/err_try_fgets.h" /* err_try_fgets(), err_line(), + * reset_err_try_fgets_counter() + */ #include "../common/readwrite.h" /* textfile_sizes(), try_fopen(), try_fclose(), - * try_fgets() + * try_fgetc() */ -#include "../common/rexit.h" /* exit_err() */ +#include "../common/rexit.h" /* exit_err(), exit_trouble() */ #include "../common/try_malloc.h" /* try_malloc() */ #include "../common/yx_uint16.h" /* yx_uint16 struct */ #include "cleanup.h" /* set_cleanup_flag() */ @@ -223,20 +226,35 @@ extern void init_map_object_actions(char * path) uint16_t linemax = textfile_sizes(file, NULL); char line[linemax + 1]; struct MapObjAct ** moa_ptr_ptr = &world.map_obj_acts; - char * delim = " "; - while (try_fgets(line, linemax + 1, file, f_name)) + char * context = "Failed reading map object actions config file. "; + char * err_toolarge = "Value is too large."; + char * err_uniq = "Declaration of ID already used."; + reset_err_try_fgets_counter(); + while (1) { - if ('\n' == line[0] || 0 == line[0]) + int test_for_end = try_fgetc(file, f_name); + if (EOF == test_for_end || '\n' == test_for_end) { break; } + exit_trouble(EOF == ungetc(test_for_end, file), f_name, "ungetc()"); struct MapObjAct * moa = try_malloc(sizeof(struct MapObjAct), f_name); - moa->id = atoi(strtok(line, delim)); - moa->effort = atoi(strtok(NULL, delim)); - char * funcname = strtok(NULL, "\n"); - uint8_t len_name = strlen(funcname) + 1; + err_try_fgets(line, linemax, file, context, "nfi"); + err_line(atoi(line) > UINT8_MAX, line, context, err_toolarge); + moa->id = atoi(line); + struct MapObjAct * moa_test = world.map_obj_acts; + for (; NULL != moa_test; moa_test = moa_test->next) + { + err_line(moa->id == moa_test->id, line, context, err_uniq); + } + err_try_fgets(line, linemax, file, context, "0nfi"); + err_line(atoi(line) > UINT8_MAX, line, context, err_toolarge); + moa->effort = atoi(line); + err_try_fgets(line, linemax, file, context, "0nf"); + line[strlen(line) - 1] = '\0'; + uint8_t len_name = strlen(line) + 1; moa->name = try_malloc(len_name, f_name); - memcpy(moa->name, funcname, len_name); + memcpy(moa->name, line, len_name); if (!( try_func_name(moa, "move", actor_move) || try_func_name(moa, "pick_up", actor_pick) || try_func_name(moa, "drop", actor_drop) @@ -247,6 +265,7 @@ extern void init_map_object_actions(char * path) moa->next = NULL; * moa_ptr_ptr = moa; moa_ptr_ptr = &moa->next; + err_try_fgets(line, linemax, file, context, "d"); } try_fclose(file, f_name); set_cleanup_flag(CLEANUP_MAP_OBJECT_ACTS); diff --git a/src/server/map_objects.c b/src/server/map_objects.c index 36fb9b7..05cfc9a 100644 --- a/src/server/map_objects.c +++ b/src/server/map_objects.c @@ -3,12 +3,16 @@ #include "map_objects.h" #include /* NULL */ #include /* FILE typedef */ -#include /* uint8_t, uint16_t */ +#include /* uint8_t, uint16_t, UINT8_MAX */ #include /* free(), atoi() */ -#include /* strlen(), memcpy(), strtok(), memset() */ -#include "../common/readwrite.h" /* try_fopen(), try_fclose(), try_fgets(), +#include /* strlen(), memcpy(), memset() */ +#include "../common/err_try_fgets.h" /* err_try_fgets(), err_line(), + * reset_err_try_fgets_counter() + */ +#include "../common/readwrite.h" /* try_fopen(), try_fclose(), try_fgetc(), * textfile_sizes() */ +#include "../common/rexit.h" /* exit_err(), exit_trouble() */ #include "../common/try_malloc.h" /* try_malloc() */ #include "../common/yx_uint16.h" /* yx_uint16 struct */ #include "cleanup.h" /* set_cleanup_flag() */ @@ -100,24 +104,47 @@ static void add_map_object(uint8_t type) extern void init_map_object_defs(char * filename) { char * f_name = "init_map_object_defs()"; + char * context = "Failed reading map object definitions file. "; + char * err_toolarge = "Value is too large."; + char * err_uniq = "Declaration of ID already used."; FILE * file = try_fopen(filename, "r", f_name); uint16_t linemax = textfile_sizes(file, NULL); struct MapObjDef ** last_mod_ptr_ptr = &world.map_obj_defs; - char * delim = " "; char line[linemax + 1]; - while (try_fgets(line, linemax + 1, file, f_name)) + reset_err_try_fgets_counter(); + while (1) { + int test_for_end = try_fgetc(file, f_name); + if (EOF == test_for_end || '\n' == test_for_end) + { + break; + } + exit_trouble(EOF == ungetc(test_for_end, file), f_name, "ungetc()"); struct MapObjDef * mod = try_malloc(sizeof(struct MapObjDef), f_name); mod->next = NULL; - mod->id = atoi(strtok(line, delim)); - mod->corpse_id = atoi(strtok(NULL, delim)); - mod->char_on_map = * strtok(NULL, delim); - mod->lifepoints = atoi(strtok(NULL, delim)); - char * name = strtok(NULL, "\n"); - mod->name = try_malloc(strlen(name) + 1, f_name); - memcpy(mod->name, name, strlen(name) + 1); + err_try_fgets(line, linemax, file, context, "nfi"); + err_line(atoi(line) > UINT8_MAX, line, context, err_toolarge); + mod->id = atoi(line); + struct MapObjDef * mod_test = world.map_obj_defs; + for (; NULL != mod_test; mod_test = mod_test->next) + { + err_line(mod->id == mod_test->id, line, context, err_uniq); + } + err_try_fgets(line, linemax, file, context, "0nfi"); + err_line(atoi(line) > UINT8_MAX, line, context, err_toolarge); + mod->corpse_id = atoi(line); + err_try_fgets(line, linemax, file, context, "0nfs"); + mod->char_on_map = line[0]; + err_try_fgets(line, linemax, file, context, "0nfi"); + err_line(atoi(line) > UINT8_MAX, line, context, err_toolarge); + mod->lifepoints = atoi(line); + err_try_fgets(line, linemax, file, context, "0nf"); + line[strlen(line) - 1] = '\0'; + mod->name = try_malloc(strlen(line) + 1, f_name); + memcpy(mod->name, line, strlen(line) + 1); * last_mod_ptr_ptr = mod; last_mod_ptr_ptr = &mod->next; + err_try_fgets(line, linemax, file, context, "d"); } try_fclose(file, f_name); set_cleanup_flag(CLEANUP_MAP_OBJECT_DEFS); @@ -207,7 +234,11 @@ extern struct MapObj * get_player() extern struct MapObjDef * get_map_object_def(uint8_t id) { struct MapObjDef * mod = world.map_obj_defs; - for (; id != mod->id; mod = mod->next); + for (; NULL != mod && id != mod->id; mod = mod->next); + char * err_intro = "Requested map object definition of unused ID "; + char err[strlen(err_intro) + 3 + 1 + 1]; + sprintf(err, "%s%d.", err_intro, id); + exit_err(NULL == mod, err); return mod; } -- 2.30.2