From f4a2f344a7cac15edb800c0b621eccc93527cc8b Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Sat, 19 Jun 2021 03:03:06 +0200 Subject: [PATCH] format MultiServer.py --- MultiServer.py | 68 +++++++++++++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 26 deletions(-) diff --git a/MultiServer.py b/MultiServer.py index feba63bf..9d51352f 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -39,6 +39,7 @@ all_items = frozenset(lookup_any_item_name_to_id) all_locations = frozenset(lookup_any_location_name_to_id) all_console_names = frozenset(all_items | all_locations) + class Client(Endpoint): version = Version(0, 0, 0) tags: typing.List[str] = [] @@ -75,10 +76,10 @@ class Context(Node): self.save_filename = None self.saving = False self.player_names = {} - self.connect_names = {} # names of slots clients can connect to + self.connect_names = {} # names of slots clients can connect to self.allow_forfeits = {} self.remote_items = set() - self.locations:typing.Dict[int, typing.Dict[int, typing.Tuple[int, int]]] = {} + self.locations: typing.Dict[int, typing.Dict[int, typing.Tuple[int, int]]] = {} self.host = host self.port = port self.server_password = server_password @@ -166,7 +167,6 @@ class Context(Node): server_options = decoded_obj.get("server_options", {}) self._set_options(server_options) - def get_players_package(self): return [NetworkPlayer(t, p, self.get_aliased_name(t, p), n) for (t, p), n in self.player_names.items()] @@ -174,7 +174,7 @@ class Context(Node): for key, value in server_options.items(): data_type = self.simple_options.get(key, None) if data_type is not None: - if value not in {False, True, None}: # some can be boolean OR text, such as password + if value not in {False, True, None}: # some can be boolean OR text, such as password try: value = data_type(value) except Exception as e: @@ -200,7 +200,7 @@ class Context(Node): return False - def _save(self, exit_save:bool=False) -> bool: + def _save(self, exit_save: bool = False) -> bool: try: encoded_save = pickle.dumps(self.get_save()) with open(self.save_filename, "wb") as f: @@ -366,7 +366,8 @@ async def server(websocket, path, ctx: Context): if not isinstance(e, websockets.WebSocketException): logging.exception(e) finally: - logging.info("Disconnected") + if ctx.log_network: + logging.info("Disconnected") await ctx.disconnect(client) @@ -374,8 +375,10 @@ async def on_client_connected(ctx: Context, client: Client): await ctx.send_msgs(client, [{ 'cmd': 'RoomInfo', 'password': ctx.password is not None, - 'players': [NetworkPlayer(client.team, client.slot, ctx.name_aliases.get((client.team, client.slot), client.name), client.name) for client - in ctx.endpoints if client.auth], + 'players': [ + NetworkPlayer(client.team, client.slot, ctx.name_aliases.get((client.team, client.slot), client.name), + client.name) for client + in ctx.endpoints if client.auth], # tags are for additional features in the communication. # Name them by feature or fork, as you feel is appropriate. 'tags': ctx.tags, @@ -403,9 +406,11 @@ async def on_client_joined(ctx: Context, client: Client): ctx.client_connection_timers[client.team, client.slot] = datetime.datetime.now(datetime.timezone.utc) + async def on_client_left(ctx: Context, client: Client): update_client_status(ctx, client, ClientStatus.CLIENT_UNKNOWN) - ctx.notify_all("%s (Team #%d) has left the game" % (ctx.get_aliased_name(client.team, client.slot), client.team + 1)) + ctx.notify_all( + "%s (Team #%d) has left the game" % (ctx.get_aliased_name(client.team, client.slot), client.team + 1)) ctx.client_connection_timers[client.team, client.slot] = datetime.datetime.now(datetime.timezone.utc) @@ -447,7 +452,7 @@ def get_received_items(ctx: Context, team: int, player: int) -> typing.List[Netw def send_new_items(ctx: Context): for client in ctx.endpoints: - if client.auth: # can't send to disconnected client + if client.auth: # can't send to disconnected client items = get_received_items(ctx, client.team, client.slot) if len(items) > client.send_index: asyncio.create_task(ctx.send_msgs(client, [{ @@ -504,7 +509,6 @@ def notify_team(ctx: Context, team: int, text: str): ctx.broadcast_team(team, [['Print', {"text": text}]]) - def collect_hints(ctx: Context, team: int, slot: int, item: str) -> typing.List[NetUtils.Hint]: hints = [] seeked_item_id = lookup_any_item_name_to_id[item] @@ -520,7 +524,6 @@ def collect_hints(ctx: Context, team: int, slot: int, item: str) -> typing.List[ def collect_hints_location(ctx: Context, team: int, slot: int, location: str) -> typing.List[NetUtils.Hint]: - seeked_location: int = Regions.lookup_name_to_id[location] item_id, receiving_player = ctx.locations[slot].get(seeked_location, (None, None)) if item_id: @@ -540,6 +543,7 @@ def format_hint(ctx: Context, team: int, hint: NetUtils.Hint) -> str: text += f" at {hint.entrance}" return text + (". (found)" if hint.found else ".") + def json_format_send_event(net_item: NetworkItem, receiving_player: int): parts = [] NetUtils.add_json_text(parts, net_item.player, type=NetUtils.JSONTypes.player_id) @@ -559,7 +563,9 @@ def json_format_send_event(net_item: NetworkItem, receiving_player: int): return {"cmd": "PrintJSON", "data": parts, "type": "ItemSend", "receiving": receiving_player, "sending": net_item.player} -def get_intended_text(input_text: str, possible_answers: typing.Iterable[str]= all_console_names) -> typing.Tuple[str, bool, str]: + +def get_intended_text(input_text: str, possible_answers: typing.Iterable[str] = all_console_names) -> typing.Tuple[ + str, bool, str]: picks = fuzzy_process.extract(input_text, possible_answers, limit=2) if len(picks) > 1: dif = picks[0][1] - picks[1][1] @@ -684,11 +690,12 @@ class CommonCommandProcessor(CommandProcessor): """List all current options. Warning: lists password.""" self.output("Current options:") for option in self.ctx.simple_options: - if option == "server_password" and self.marker == "!": #Do not display the server password to the client. - self.output(f"Option server_password is set to {('*' * random.randint(4,16))}") + if option == "server_password" and self.marker == "!": # Do not display the server password to the client. + self.output(f"Option server_password is set to {('*' * random.randint(4, 16))}") else: self.output(f"Option {option} is set to {getattr(self.ctx, option)}") + class ClientMessageProcessor(CommonCommandProcessor): marker = "!" @@ -715,11 +722,14 @@ class ClientMessageProcessor(CommonCommandProcessor): """Allow remote administration of the multiworld server""" output = f"!admin {command}" - if output.lower().startswith("!admin login"): # disallow others from seeing the supplied password, whether or not it is correct. + if output.lower().startswith( + "!admin login"): # disallow others from seeing the supplied password, whether or not it is correct. output = f"!admin login {('*' * random.randint(4, 16))}" - elif output.lower().startswith("!admin /option server_password"): # disallow others from knowing what the new remote administration password is. + elif output.lower().startswith( + "!admin /option server_password"): # disallow others from knowing what the new remote administration password is. output = f"!admin /option server_password {('*' * random.randint(4, 16))}" - self.ctx.notify_all(self.ctx.get_aliased_name(self.client.team, self.client.slot) + ': ' + output) # Otherwise notify the others what is happening. + self.ctx.notify_all(self.ctx.get_aliased_name(self.client.team, + self.client.slot) + ': ' + output) # Otherwise notify the others what is happening. if not self.ctx.server_password: self.output("Sorry, Remote administration is disabled") @@ -727,7 +737,8 @@ class ClientMessageProcessor(CommonCommandProcessor): if not command: if self.is_authenticated(): - self.output("Usage: !admin [Server command].\nUse !admin /help for help.\nUse !admin logout to log out of the current session.") + self.output( + "Usage: !admin [Server command].\nUse !admin /help for help.\nUse !admin logout to log out of the current session.") else: self.output("Usage: !admin login [password]") return True @@ -810,7 +821,6 @@ class ClientMessageProcessor(CommonCommandProcessor): "Sorry, !remaining requires you to have beaten the game on this server") return False - def _cmd_missing(self) -> bool: """List all missing location checks from the server's perspective""" @@ -850,7 +860,9 @@ class ClientMessageProcessor(CommonCommandProcessor): if usable: new_item = NetworkItem(Items.item_table[item_name][2], -1, self.client.slot) get_received_items(self.ctx, self.client.team, self.client.slot).append(new_item) - self.ctx.notify_all('Cheat console: sending "' + item_name + '" to ' + self.ctx.get_aliased_name(self.client.team, self.client.slot)) + self.ctx.notify_all( + 'Cheat console: sending "' + item_name + '" to ' + self.ctx.get_aliased_name(self.client.team, + self.client.slot)) send_new_items(self.ctx) return True else: @@ -959,7 +971,7 @@ def get_client_points(ctx: Context, client: Client) -> int: async def process_client_cmd(ctx: Context, client: Client, args: dict): try: - cmd:str = args["cmd"] + cmd: str = args["cmd"] except: logging.exception(f"Could not get command from {args}") raise @@ -1045,7 +1057,7 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict): items = get_received_items(ctx, client.team, client.slot) if items: client.send_index = len(items) - await ctx.send_msgs(client, [{"cmd": "ReceivedItems","index": 0, + await ctx.send_msgs(client, [{"cmd": "ReceivedItems", "index": 0, "items": items}]) elif cmd == 'LocationChecks': @@ -1067,11 +1079,12 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict): if cmd == 'Say': if "text" not in args or type(args["text"]) is not str or not args["text"].isprintable(): - await ctx.send_msgs(client, [{"cmd": "InvalidArguments", "text" : 'Say'}]) + await ctx.send_msgs(client, [{"cmd": "InvalidArguments", "text": 'Say'}]) return client.messageprocessor(args["text"]) + def update_client_status(ctx: Context, client: Client, new_status: ClientStatus): current = ctx.client_game_state[client.team, client.slot] if current != ClientStatus.CLIENT_GOAL: # can't undo goal completion @@ -1083,6 +1096,7 @@ def update_client_status(ctx: Context, client: Client, new_status: ClientStatus) ctx.client_game_state[client.team, client.slot] = new_status + class ServerCommandProcessor(CommonCommandProcessor): def __init__(self, ctx: Context): self.ctx = ctx @@ -1190,7 +1204,8 @@ class ServerCommandProcessor(CommonCommandProcessor): for (team, slot), name in self.ctx.player_names.items(): if name.lower() == seeked_player: self.ctx.allow_forfeits[(team, slot)] = False - self.output(f"Player {player_name} has to follow the server restrictions on use of the !forfeit command.") + self.output( + f"Player {player_name} has to follow the server restrictions on use of the !forfeit command.") return True self.output(f"Could not find player {player_name} to forbid the !forfeit command for.") @@ -1270,6 +1285,7 @@ class ServerCommandProcessor(CommonCommandProcessor): f"{', '.join(known)}") return False + async def console(ctx: Context): session = prompt_toolkit.PromptSession() while ctx.running: @@ -1356,7 +1372,7 @@ async def auto_shutdown(ctx, to_cancel=None): async def main(args: argparse.Namespace): - logging.basicConfig(force = True, + logging.basicConfig(force=True, format='[%(asctime)s] %(message)s', level=getattr(logging, args.loglevel.upper(), logging.INFO)) ctx = Context(args.host, args.port, args.server_password, args.password, args.location_check_points,