X-Git-Url: https://plomlompom.com/repos/test.html?a=blobdiff_plain;f=plomrogue-server.py;h=72e0fdb7225504833e7772a03919836b3d88dda0;hb=7543a2420dd05a73aa8f6569ecd4a8517873cebb;hp=f5c3c102a16c7182ce510c15414e9f33964802f0;hpb=7cb786bc1b01c60c7112b377128baf24df0c3628;p=plomrogue
diff --git a/plomrogue-server.py b/plomrogue-server.py
index f5c3c10..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")
@@ -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)
@@ -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})
@@ -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
@@ -370,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.
@@ -407,8 +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()
+ strong_write(io_db["file_out"], "PONG\n")
def command_quit():
@@ -416,6 +445,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)
@@ -423,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"]:
@@ -444,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"]:
@@ -498,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
@@ -527,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")
@@ -744,6 +769,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 +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,