home · contact · privacy
Server/py: Fix replay to turn 1.
[plomrogue] / plomrogue-server.py
index f5c3c102a16c7182ce510c15414e9f33964802f0..0e42ceeccbaf3d0665a29cecf1e94aae1048a848 100755 (executable)
@@ -6,6 +6,13 @@ import shutil
 import time
 
 
+def strong_write(file, string):
+    """Apply write(string), flush() and os.fsync() to file."""
+    file.write(string)
+    file.flush()
+    os.fsync(file)
+
+
 def setup_server_io():
     """Fill IO files DB with proper file( path)s. Write process IO test string.
 
@@ -25,8 +32,7 @@ def setup_server_io():
     io_db["teststring"] = str(os.getpid()) + " " + str(time.time())
     os.makedirs(io_db["path_server"], exist_ok=True)
     io_db["file_out"] = open(io_db["path_out"], "w")
-    io_db["file_out"].write(io_db["teststring"] + "\n")
-    io_db["file_out"].flush()
+    strong_write(io_db["file_out"], io_db["teststring"] + "\n")
     if os.access(io_db["path_in"], os.F_OK):
         os.remove(io_db["path_in"])
     io_db["file_in"] = open(io_db["path_in"], "w")
@@ -72,7 +78,7 @@ def obey(command, prefix, replay=False, do_record=False):
     if len(tokens) > 0 and tokens[0] in commands_db \
        and len(tokens) == commands_db[tokens[0]][0] + 1:
         if commands_db[tokens[0]][1]:
-            commands_db[tokens[0]][2]()
+            commands_db[tokens[0]][2](*tokens[1:])
         elif replay:
             print("Due to replay mode, reading command as 'go on in record'.")
             line = io_db["file_record"].readline()
@@ -101,9 +107,7 @@ def atomic_write(path, text, do_append=False):
         if os.access(path, os.F_OK):
             shutil.copyfile(path, path_tmp)
     file = open(path_tmp, mode)
-    file.write(text)
-    file.flush()
-    os.fsync(file.fileno())
+    strong_write(file, text)
     file.close()
     if os.access(path, os.F_OK):
         os.remove(path)
@@ -249,21 +253,28 @@ def read_command():
 def try_worldstate_update():
     """Write worldstate file if io_db["worldstate_updateable"] is set."""
     if io_db["worldstate_updateable"]:
+        inventory = ""
+        if [] == world_db["Things"][0]["T_CARRIES"]:
+            inventory = "(none)\n"
+        else:
+            for id in world_db["Things"][0]["T_CARRIES"]:
+                type_id = world_db["Things"][id]["T_TYPE"]
+                name = world_db["ThingTypes"][type_id]["TT_NAME"]
+                inventory = inventory + name + "\n"
         string = str(world_db["TURN"]) + "\n" + \
                  str(world_db["Things"][0]["T_LIFEPOINTS"]) + "\n" + \
                  str(world_db["Things"][0]["T_SATIATION"]) + "\n" + \
-                 "(none)\n%\n" + \
+                 inventory + "%\n" + \
                  str(world_db["Things"][0]["T_POSY"]) + "\n" + \
                  str(world_db["Things"][0]["T_POSX"]) + "\n" + \
                  str(world_db["MAP_LENGTH"]) + "\n"
-        # TODO: no inventory so far
         length = world_db["MAP_LENGTH"]
         for i in range(length):
             line = world_db["MAP"][i * length:(i * length) + length].decode()
             string = string + line + "\n"
         # TODO: no proper user-subjective map
         atomic_write(io_db["path_worldstate"], string)
-        atomic_write(io_db["path_out"], "WORLD_UPDATED\n", do_append=True)
+        strong_write(io_db["file_out"], "WORLD_UPDATED\n")
         io_db["worldstate_updateable"] = False
 
 
@@ -407,8 +418,7 @@ def id_setter(id, category, id_store=False, start_at_1=False):
 
 def command_ping():
     """Send PONG line to server output file."""
-    io_db["file_out"].write("PONG\n")
-    io_db["file_out"].flush()
+    strong_write(io_db["file_out"], "PONG\n")
 
 
 def command_quit():
@@ -416,6 +426,11 @@ def command_quit():
     raise SystemExit("received QUIT command")
 
 
+def command_thingshere(y, x):
+    # DUMMY
+    print("Ignoring not-yet implemented THINGS_HERE command.")
+
+
 def command_seedmap(seed_string):
     """Set world_db["SEED_MAP"] to int(seed_string), then (re-)make map."""
     setter(None, "SEED_MAP", 0, 4294967295)(seed_string)
@@ -467,7 +482,7 @@ def command_makeworld(seed_string):
         }
     # generate fov map?
     # TODO: Generate things (player first, with updated memory)
-    atomic_write(io_db["path_out"], "NEW_WORLD\n", do_append=True)
+    strong_write(io_db["file_out"], "NEW_WORLD\n")
 
 
 def command_maplength(maplength_string):
@@ -744,6 +759,7 @@ to be called on it.
 commands_db = {
     "QUIT": (0, True, command_quit),
     "PING": (0, True, command_ping),
+    "THINGS_HERE": (2, True, command_thingshere),
     "MAKE_WORLD": (1, False, command_makeworld),
     "SEED_MAP": (1, False, command_seedmap),
     "SEED_RANDOMNESS": (1, False, setter(None, "SEED_RANDOMNESS",
@@ -784,7 +800,7 @@ commands_db = {
 
 """World state database. With sane default values."""
 world_db = {
-    "TURN": 1,
+    "TURN": 0,
     "SEED_MAP": 0,
     "SEED_RANDOMNESS": 0,
     "PLAYER_TYPE": 0,