home · contact · privacy
Server: Read in former "config" data as normal server god commands.
[plomrogue] / src / server / io.c
index e4a40d0ccc13685d076080a82d467bbd8c920d99..317c088b1148bb0475e71b32b1599ef0d128f90b 100644 (file)
@@ -6,12 +6,12 @@
 #include <limits.h> /* PIPE_BUF */
 #include <stddef.h> /* size_t, NULL */
 #include <stdint.h> /* uint8_t, uint16_t, uint32_t */
-#include <stdio.h> /* defines EOF, FILE, sprintf() */
+#include <stdio.h> /* defines EOF, FILE, sprintf(), fprintf() */
 #include <stdlib.h> /* free() */
-#include <string.h> /* strlen(), memcpy(), memset() */
+#include <string.h> /* strlen(), memcpy(), memset(), strchr() */
 #include <sys/types.h> /* time_t */
 #include <time.h> /* time(), nanosleep() */
-#include "../common/readwrite.h" /* try_fopen(), try_fclose_unlink_rename(),
+#include "../common/readwrite.h" /* atomic_write_start(), atomic_write_finish(),
                                   * try_fwrite(), try_fputc(), try_fgetc()
                                   */
 #include "../common/rexit.h" /* exit_trouble() */
 #include "field_of_view.h" /* VISIBLE */
 #include "hardcoded_strings.h" /* s */
 #include "map.h" /* yx_to_map_pos() */
-#include "things.h" /* Thing, ThingType, get_thing_type(), get_player() */
+#include "things.h" /* Thing, ThingType, ThingAction, get_thing_type(),
+                     * get_player()
+                     */
 #include "world.h" /* global world  */
 
 
 
 /* Write to "file" god commands (one per line) to recreate thing "t". */
 static void write_key_value(FILE * file, char * key, uint32_t value);
+static void write_key_string(FILE * file, char * key, char * string);
 
 /* Write to "file" \n-delimited line of "key" + space + "value" as string. */
 static void write_thing(FILE * file, struct Thing * t);
@@ -72,7 +75,7 @@ static void write_key_value(FILE * file, char * key, uint32_t value)
     try_fwrite(key, strlen(key), 1, file, f_name);
     try_fputc(' ', file, f_name);
     char * line = try_malloc(11, f_name);
-    exit_trouble(-1 == sprintf(line, "%u", value), f_name, "sprintf()");
+    exit_trouble(-1 == sprintf(line, "%u", value), f_name, s[S_FCN_SPRINTF]);
     try_fwrite(line, strlen(line), 1, file, f_name);
     free(line);
     try_fputc('\n', file, f_name);
@@ -80,6 +83,26 @@ static void write_key_value(FILE * file, char * key, uint32_t value)
 
 
 
+static void write_key_string(FILE * file, char * key, char * string)
+{
+    char * f_name = "write_key_string()";
+    try_fwrite(key, strlen(key), 1, file, f_name);
+    try_fputc(' ', file, f_name);
+    uint8_t contains_space = NULL != strchr(string, ' ');
+    if (contains_space)
+    {
+        try_fputc('\'', file, f_name);
+    }
+    try_fwrite(string, strlen(string), 1, file, f_name);
+    if (contains_space)
+    {
+        try_fputc('\'', file, f_name);
+    }
+    try_fputc('\n', file, f_name);
+}
+
+
+
 static void write_thing(FILE * file, struct Thing * t)
 {
     char * f_name = "write_thing()";
@@ -89,16 +112,16 @@ static void write_thing(FILE * file, struct Thing * t)
         write_thing(file, o);
     }
     write_key_value(file, s[S_CMD_THING], t->id);
-    write_key_value(file, s[S_CMD_TYPE], t->type);
-    write_key_value(file, s[S_CMD_POS_Y], t->pos.y);
-    write_key_value(file, s[S_CMD_POS_X], t->pos.x);
-    write_key_value(file, s[S_CMD_COMMAND], t->command);
-    write_key_value(file, s[S_CMD_ARGUMENT], t->arg);
-    write_key_value(file, s[S_CMD_PROGRESS], t->progress);
-    write_key_value(file, s[S_CMD_LIFEPOINTS], t->lifepoints);
+    write_key_value(file, s[S_CMD_T_TYPE], t->type);
+    write_key_value(file, s[S_CMD_T_POSY], t->pos.y);
+    write_key_value(file, s[S_CMD_T_POSX], t->pos.x);
+    write_key_value(file, s[S_CMD_T_COMMAND], t->command);
+    write_key_value(file, s[S_CMD_T_ARGUMENT], t->arg);
+    write_key_value(file, s[S_CMD_T_PROGRESS], t->progress);
+    write_key_value(file, s[S_CMD_T_HP], t->lifepoints);
     for (o = t->owns; o; o = o->next)
     {
-        write_key_value(file, s[S_CMD_CARRIES], o->id);
+        write_key_value(file, s[S_CMD_T_CARRIES], o->id);
     }
     try_fputc('\n', file, f_name);
 }
@@ -180,11 +203,8 @@ static void read_file_into_queue()
 static void update_worldstate_file()
 {
     char * f_name = "update_worldstate_file()";
-    uint16_t size = strlen(s[S_PATH_WORLDSTATE])+strlen(s[S_PATH_SUFFIX_TMP])+1;
-    char * path_tmp = try_malloc(size, f_name);
-    int test=sprintf(path_tmp,"%s%s",s[S_PATH_WORLDSTATE],s[S_PATH_SUFFIX_TMP]);
-    exit_trouble(test < 0, f_name, "sprintf()");
-    FILE * file = try_fopen(path_tmp, "w", f_name);
+    char * path_tmp;
+    FILE * file = atomic_write_start(s[S_PATH_WORLDSTATE], &path_tmp);
     struct Thing * player = get_player();
     write_value_as_line(world.turn, file);
     write_value_as_line(player->lifepoints, file);
@@ -197,10 +217,9 @@ static void update_worldstate_file()
     {
         try_fwrite(world.log, strlen(world.log), 1, file, f_name);
     }
-    try_fclose_unlink_rename(file, path_tmp, s[S_PATH_WORLDSTATE], f_name);
-    free(path_tmp);
+    atomic_write_finish(file, s[S_PATH_WORLDSTATE], path_tmp);
     set_cleanup_flag(CLEANUP_WORLDSTATE);
-    char * dot = ".\n";;
+    char * dot = ".\n";
     try_fwrite(dot, strlen(dot), 1, world.file_out, f_name);
     fflush(world.file_out);
 }
@@ -211,7 +230,7 @@ static void write_value_as_line(uint32_t value, FILE * file)
 {
     char * f_name = "write_value_as_line()";
     char write_buf[12];     /* Holds 10 digits of uint32_t maximum + \n + \0. */
-    exit_trouble(sprintf(write_buf, "%u\n", value) < 0, f_name, "sprintf()");
+    exit_trouble(sprintf(write_buf, "%u\n",value) < 0, f_name,s[S_FCN_SPRINTF]);
     try_fwrite(write_buf, strlen(write_buf), 1, file, f_name);
 }
 
@@ -308,10 +327,10 @@ extern char * io_round()
     {
         return get_message_from_queue();
     }
-    if (world.turn != world.last_update_turn)
+    if (world.do_update)
     {
         update_worldstate_file();
-        world.last_update_turn = world.turn;
+        world.do_update = 0;
     }
     read_file_into_queue();
     if (world.queue_size && '\0' != world.queue[world.queue_size - 1])
@@ -331,9 +350,36 @@ extern char * io_round()
 extern void save_world()
 {
     char * f_name = "save_world()";
-    char * path = s[S_PATH_SAVE];
-    FILE * file = try_fopen(path, "w", f_name);
-    write_key_value(file, s[S_CMD_DO_FOV], 0);
+    char * path_tmp;
+    FILE * file = atomic_write_start(s[S_PATH_SAVE], &path_tmp);
+    write_key_value(file, s[S_CMD_MAPLENGTH], world.map.length);
+    write_key_value(file, s[S_CMD_PLAYTYPE], world.player_type);
+    try_fputc('\n', file, f_name);
+    struct ThingAction * ta;
+    for (ta = world.thing_actions; ta; ta = ta->next)
+    {
+        write_key_value(file, s[S_CMD_THINGACTION], ta->id);
+        write_key_value(file, s[S_CMD_TA_EFFORT], ta->effort);
+        write_key_string(file, s[S_CMD_TA_NAME], ta->name);
+        try_fputc('\n', file, f_name);
+    }
+    struct ThingType * tt;
+    for (tt = world.thing_types; tt; tt = tt->next)
+    {
+        write_key_value(file, s[S_CMD_THINGTYPE], tt->id);
+        write_key_value(file, s[S_CMD_TT_STARTN], tt->start_n);
+        write_key_value(file, s[S_CMD_TT_HP], tt->lifepoints);
+        int test = fprintf(file, "%s %c\n", s[S_CMD_TT_SYMB], tt->char_on_map);
+        exit_trouble(test < 0, f_name, "fprintf()");
+        write_key_string(file, s[S_CMD_TT_NAME], tt->name);
+        write_key_value(file, s[S_CMD_TT_CONSUM], tt->consumable);
+        try_fputc('\n', file, f_name);
+    }
+    for (tt = world.thing_types; tt; tt = tt->next)
+    {
+        write_key_value(file, s[S_CMD_THINGTYPE], tt->id);
+        write_key_value(file, s[S_CMD_TT_CORPS], tt->corpse_id);
+    }
     try_fputc('\n', file, f_name);
     write_key_value(file, s[S_CMD_SEED_MAP], world.seed_map);
     write_key_value(file, s[S_CMD_SEED_RAND], world.seed);
@@ -344,6 +390,6 @@ extern void save_world()
     {
         write_thing(file, t);
     }
-    write_key_value(file, s[S_CMD_DO_FOV], 1);
-    try_fclose(file, f_name);
+    write_key_value(file, s[S_CMD_WORLD_ACTIVE], 1);
+    atomic_write_finish(file, s[S_PATH_SAVE], path_tmp);
 }