def obey(command, prefix, replay=False, do_record=False): """Call function from commands_db mapped to command's first token. Tokenize command string with shlex.split(comments=True). If replay is set, a non-meta command from the commands_db merely triggers obey() on the next command from the records file. If not, non-meta commands set io_db["worldstate_updateable"] to world_db["WORLD_ACTIVE"], and, if do_record is set, are recorded to io_db["record_chunk"], and save_world() is called (and io_db["record_chunk"] written) if io_db["save_wait"] seconds have passed since the last time it was called. The prefix string is inserted into the server's input message between its beginning 'input ' and ':'. All activity is preceded by a server_test() call. Commands that start with a lowercase letter are ignored when world_db["WORLD_ACTIVE"] is False/0. """ import shlex from server.config.commands import commands_db server_test() if io_db["verbose"]: print("input " + prefix + ": " + command) try: tokens = shlex.split(command, comments=True) except ValueError as err: print("Can't tokenize command string: " + str(err) + ".") return 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](*tokens[1:]) elif tokens[0][0].islower() and not world_db["WORLD_ACTIVE"]: print("Ignoring lowercase-starting commands when world inactive.") elif replay: print("Due to replay mode, reading command as 'go on in record'.") line = io_db["file_record"].readline() if len(line) > 0: obey( line.rstrip(), io_db["file_record"].prefix + str(io_db["file_record"].line_n)) io_db["file_record"].line_n = io_db["file_record"].line_n + 1 else: print("Reached end of record file.") else: commands_db[tokens[0]][2](*tokens[1:]) if do_record: io_db["record_chunk"] += command + "\n" if time.time() > io_db["save_wait_start"] + io_db["save_wait"]: atomic_write(io_db["path_record"], io_db["record_chunk"], do_append=True) if world_db["WORLD_ACTIVE"]: save_world() io_db["record_chunk"] = "" io_db["save_wait_start"] = time.time() io_db["worldstate_updateable"] = world_db["WORLD_ACTIVE"] elif 0 != len(tokens): print("Invalid command/argument, or bad number of tokens: " + command)
def obey(command, prefix, replay=False, do_record=False): """Call function from commands_db mapped to command's first token. Tokenize command string with shlex.split(comments=True). If replay is set, a non-meta command from the commands_db merely triggers obey() on the next command from the records file. If not, non-meta commands set io_db["worldstate_updateable"] to world_db["WORLD_ACTIVE"], and, if do_record is set, are recorded to io_db["record_chunk"], and save_world() is called (and io_db["record_chunk"] written) if io_db["save_wait"] seconds have passed since the last time it was called. The prefix string is inserted into the server's input message between its beginning 'input ' and ':'. All activity is preceded by a server_test() call. Commands that start with a lowercase letter are ignored when world_db["WORLD_ACTIVE"] is False/0. """ import shlex from server.config.commands import commands_db server_test() if io_db["verbose"]: print("input " + prefix + ": " + command) try: tokens = shlex.split(command, comments=True) except ValueError as err: print("Can't tokenize command string: " + str(err) + ".") return 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](*tokens[1:]) elif tokens[0][0].islower() and not world_db["WORLD_ACTIVE"]: print("Ignoring lowercase-starting commands when world inactive.") elif replay: print("Due to replay mode, reading command as 'go on in record'.") line = io_db["file_record"].readline() if len(line) > 0: obey(line.rstrip(), io_db["file_record"].prefix + str(io_db["file_record"].line_n)) io_db["file_record"].line_n = io_db["file_record"].line_n + 1 else: print("Reached end of record file.") else: commands_db[tokens[0]][2](*tokens[1:]) if do_record: io_db["record_chunk"] += command + "\n" if time.time() > io_db["save_wait_start"] + io_db["save_wait"]: atomic_write(io_db["path_record"], io_db["record_chunk"], do_append=True) if world_db["WORLD_ACTIVE"]: save_world() io_db["record_chunk"] = "" io_db["save_wait_start"] = time.time() io_db["worldstate_updateable"] = world_db["WORLD_ACTIVE"] elif 0 != len(tokens): print("Invalid command/argument, or bad number of tokens: " + command)
def read_command(): """Return next newline-delimited command from server in file. Keep building return string until a newline is encountered. Pause between unsuccessful reads, and after too much waiting, run server_test(). """ wait_on_fail = io_db["wait_on_read_fail"] max_wait = io_db["max_wait_on_read_fail"] now = time.time() command = "" while True: add = io_db["file_in"].readline() if len(add) > 0: command = command + add if len(command) > 0 and "\n" == command[-1]: command = command[:-1] break else: time.sleep(wait_on_fail) if now + max_wait < time.time(): server_test() now = time.time() return command
def safely_remove_worldstate_file(): from server.io import server_test if os.access(io_db["path_worldstate"], os.F_OK): server_test() os.remove(io_db["path_worldstate"])