X-Git-Url: https://plomlompom.com/repos/?a=blobdiff_plain;f=plomrogue-server.py;h=72e0fdb7225504833e7772a03919836b3d88dda0;hb=7543a2420dd05a73aa8f6569ecd4a8517873cebb;hp=d6c1930da2613a88c98e844b830b861c9fd2c482;hpb=21ba1d03b1e883564d301c2781039017dd704b20;p=plomrogue diff --git a/plomrogue-server.py b/plomrogue-server.py index d6c1930..72e0fdb 100755 --- a/plomrogue-server.py +++ b/plomrogue-server.py @@ -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") @@ -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) @@ -160,7 +164,7 @@ def save_world(): string = "" for key in world_db: - if dict != type(world_db[key]): + if dict != type(world_db[key]) and key != "MAP": string = string + key + " " + str(world_db[key]) + "\n" string = string + helper("ThingActions", "TA_ID") string = string + helper("ThingTypes", "TT_ID", {"TT_CORPSE_ID": False}) @@ -270,9 +274,7 @@ def try_worldstate_update(): string = string + line + "\n" # TODO: no proper user-subjective map atomic_write(io_db["path_worldstate"], string) - io_db["file_out"].write("WORLD_UPDATED\n") - io_db["file_out"].flush() - os.fsync(io_db["file_out"]) + strong_write(io_db["file_out"], "WORLD_UPDATED\n") io_db["worldstate_updateable"] = False @@ -379,6 +381,25 @@ def setter(category, key, min, max): return f +def new_Thing(type): + """Return prototype for Thing of T_TYPE of type.""" + return { + "T_LIFEPOINTS": world_db["ThingTypes"][type]["TT_LIFEPOINTS"], + "T_ARGUMENT": 0, + "T_PROGRESS": 0, + "T_SATIATION": 0, + "T_COMMAND": 0, + "T_TYPE": type, + "T_POSY": 0, + "T_POSX": 0, + "T_CARRIES": [], + "carried": False, + "T_MEMTHING": [], + "T_MEMMAP": False, + "T_MEMDEPTHMAP": False + } + + def id_setter(id, category, id_store=False, start_at_1=False): """Set ID of object of category to manipulate ID unused? Create new one. @@ -416,9 +437,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() - os.fsync(io_db["file_out"].fileno()) + strong_write(io_db["file_out"], "PONG\n") def command_quit(): @@ -438,8 +457,18 @@ def command_seedmap(seed_string): def command_makeworld(seed_string): - # DUMMY. + """(Re-)build game world, i.e. map, things, to a new turn 1 from seed. + + Make seed world_db["SEED_RANDOMNESS"] and world_db["SEED_MAP"]. Do more + only with a "wait" ThingAction and world["PLAYER_TYPE"] matching ThingType + of TT_START_NUMBER > 0. Then, world_db["Things"] emptied, call remake_map() + and set world_db["WORLD_ACTIVE"], world_db["TURN"] to 1. Build new Things + according to ThingTypes' TT_START_NUMBERS, with Thing of ID 0 to ThingType + of ID = world["PLAYER_TYPE"]. Place Things randomly, and actors not on each + other. Init player's FOV/memory map. Write "NEW_WORLD" line to out file. + """ setter(None, "SEED_RANDOMNESS", 0, 4294967295)(seed_string) + setter(None, "SEED_MAP", 0, 4294967295)(seed_string) player_will_be_generated = False playertype = world_db["PLAYER_TYPE"] for ThingType in world_db["ThingTypes"]: @@ -459,42 +488,37 @@ def command_makeworld(seed_string): print("Ignoring beyond SEED_MAP: " + "No thing action with name 'wait' defined.") return - setter(None, "SEED_MAP", 0, 4294967295)(seed_string) world_db["Things"] = {} remake_map() world_db["WORLD_ACTIVE"] = 1 world_db["TURN"] = 1 for i in range(world_db["ThingTypes"][playertype]["TT_START_NUMBER"]): - world_db["Things"][id_setter(-1, "Things")] = { - "T_LIFEPOINTS": world_db["ThingTypes"][playertype]["TT_LIFEPOINTS"], - "T_TYPE": playertype, - "T_POSY": 0, # randomize safely - "T_POSX": 0, # randomize safely - "T_ARGUMENT": 0, - "T_PROGRESS": 0, - "T_SATIATION": 0, - "T_COMMAND": 0, - "T_CARRIES": [], - "carried": False, - "T_MEMTHING": [], - "T_MEMMAP": False, - "T_MEMDEPTHMAP": False - } - # generate fov map? - # TODO: Generate things (player first, with updated memory) - atomic_write(io_db["path_out"], "NEW_WORLD\n", do_append=True) + id = id_setter(-1, "Things") + world_db["Things"][id] = new_Thing(playertype) + # TODO: Positioning. Init player's FOV / memory map. + for type in world_db["ThingTypes"]: + for i in range(world_db["ThingTypes"][type]["TT_START_NUMBER"]): + id = id_setter(-1, "Things") + world_db["Things"][id] = new_Thing(playertype) + # TODO: Positioning. + strong_write(io_db["file_out"], "NEW_WORLD\n") def command_maplength(maplength_string): - # DUMMY. + """Redefine map length. Invalidate map, therefore lose all things on it.""" set_world_inactive() - # TODO: remove map (is this necessary? no memory management trouble …) world_db["Things"] = {} setter(None, "MAP_LENGTH", 1, 256)(maplength_string) def command_worldactive(worldactive_string): - # DUMMY. + """Toggle world_db["WORLD_ACTIVE"] if possible. + + An active world can always be set inactive. An inactive world can only be + set active with a "wait" ThingAction, and a player Thing (of ID 0). On + activation, rebuild all Things' FOVs and map memories. + """ + # In original version, map existence was also tested (unnecessarily?). val = integer_test(worldactive_string, 0, 1) if val: if 0 != world_db["WORLD_ACTIVE"]: @@ -513,8 +537,7 @@ def command_worldactive(worldactive_string): if 0 == Thing: player_exists = True break - map_exists = "MAP" in world_db - if wait_exists and player_exists and map_exists: + if wait_exists and player_exists: # TODO: rebuild all things' FOVs, map memories world_db["WORLD_ACTIVE"] = 1 @@ -542,21 +565,8 @@ def command_tid(id_string): if world_db["ThingTypes"] == {}: print("Ignoring: No ThingType to settle new Thing in.") return - world_db["Things"][id] = { - "T_LIFEPOINTS": 0, - "T_ARGUMENT": 0, - "T_PROGRESS": 0, - "T_SATIATION": 0, - "T_COMMAND": 0, - "T_TYPE": list(world_db["ThingTypes"].keys())[0], - "T_POSY": 0, - "T_POSX": 0, - "T_CARRIES": [], - "carried": False, - "T_MEMTHING": [], - "T_MEMMAP": False, - "T_MEMDEPTHMAP": False - } + type = list(world_db["ThingTypes"].keys())[0] + world_db["Things"][id] = new_Thing(type) test_Thing_id = test_for_id_maker(command_tid, "Thing") @@ -800,7 +810,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,