From 9eb237b3af9c142fb551580346c74d8bb8a50319 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Sat, 21 May 2022 22:24:49 +0200 Subject: [PATCH] Clients: some cleanup --- CommonClient.py | 36 +++++++++++++++++------------------- SNIClient.py | 2 +- Starcraft2Client.py | 13 ++++++++++++- 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/CommonClient.py b/CommonClient.py index a8374f3d..2c2236b3 100644 --- a/CommonClient.py +++ b/CommonClient.py @@ -24,7 +24,7 @@ import os logger = logging.getLogger("Client") -# without terminal we have to use gui mode +# without terminal, we have to use gui mode gui_enabled = not sys.stdout or "--nogui" not in sys.argv @@ -125,7 +125,7 @@ class CommonContext(): input_task: typing.Optional[asyncio.Task] = None keep_alive_task: typing.Optional[asyncio.Task] = None items_handling: typing.Optional[int] = None - current_energy_link_value = 0 # to display in UI, gets set by server + current_energy_link_value: int = 0 # to display in UI, gets set by server def __init__(self, server_address, password): # server state @@ -181,14 +181,24 @@ class CommonContext(): return len(self.checked_locations | self.missing_locations) async def connection_closed(self): + self.reset_server_state() + if self.server and self.server.socket is not None: + await self.server.socket.close() + + def reset_server_state(self): self.auth = None self.items_received = [] self.locations_info = {} self.server_version = Version(0, 0, 0) - if self.server and self.server.socket is not None: - await self.server.socket.close() self.server = None self.server_task = None + self.games = {} + self.hint_cost = None + self.permissions = { + "forfeit": "disabled", + "collect": "disabled", + "remaining": "disabled", + } # noinspection PyAttributeOutsideInit def set_getters(self, data_package: dict, network=False): @@ -219,13 +229,6 @@ class CommonContext(): self.location_name_getter = get_location_name_from_address - @property - def endpoints(self): - if self.server: - return [self.server] - else: - return [] - async def disconnect(self): if self.server and not self.server.socket.closed: await self.server.socket.close() @@ -385,7 +388,6 @@ async def keep_alive(ctx: CommonContext, seconds_between_checks=100): async def server_loop(ctx: CommonContext, address=None): - cached_address = None if ctx.server and ctx.server.socket: logger.error('Already connected') return @@ -413,16 +415,12 @@ async def server_loop(ctx: CommonContext, address=None): await process_server_cmd(ctx, msg) logger.warning('Disconnected from multiworld server, type /connect to reconnect') except ConnectionRefusedError: - if cached_address: - logger.error('Unable to connect to multiworld server at cached address. ' - 'Please use the connect button above.') - else: - logger.exception('Connection refused by the multiworld server') + logger.exception('Connection refused by the server. May not be running Archipelago on that address or port.') except websockets.InvalidURI: logger.exception('Failed to connect to the multiworld server (invalid URI)') - except (OSError, websockets.InvalidURI): + except OSError: logger.exception('Failed to connect to the multiworld server') - except Exception as e: + except Exception: logger.exception('Lost connection to the multiworld server, type /connect to reconnect') finally: await ctx.connection_closed() diff --git a/SNIClient.py b/SNIClient.py index 1fa46899..9173a451 100644 --- a/SNIClient.py +++ b/SNIClient.py @@ -28,7 +28,7 @@ from worlds.alttp.Rom import ROM_PLAYER_LIMIT from worlds.sm.Rom import ROM_PLAYER_LIMIT as SM_ROM_PLAYER_LIMIT from worlds.smz3.Rom import ROM_PLAYER_LIMIT as SMZ3_ROM_PLAYER_LIMIT import Utils -from CommonClient import CommonContext, server_loop, console_loop, ClientCommandProcessor, gui_enabled, get_base_parser +from CommonClient import CommonContext, server_loop, ClientCommandProcessor, gui_enabled, get_base_parser from Patch import GAME_ALTTP, GAME_SM, GAME_SMZ3 snes_logger = logging.getLogger("SNES") diff --git a/Starcraft2Client.py b/Starcraft2Client.py index 934f7171..e62fd7e4 100644 --- a/Starcraft2Client.py +++ b/Starcraft2Client.py @@ -43,7 +43,12 @@ class StarcraftClientProcessor(ClientCommandProcessor): mission_number = int(options[0]) if is_mission_available(mission_number, self.ctx.checked_locations, mission_req_table): - asyncio.create_task(starcraft_launch(self.ctx, mission_number), name="Starcraft Launch") + if self.ctx.sc2_run_task: + if not self.ctx.sc2_run_task.done(): + sc2_logger.warning("Starcraft 2 Client is still running!") + self.ctx.sc2_run_task.cancel() # doesn't actually close the game, just stops the python task + self.ctx.sc2_run_task = asyncio.create_task(starcraft_launch(self.ctx, mission_number), + name="Starcraft 2 Launch") else: sc2_logger.info( "This mission is not currently unlocked. Use /unfinished or /available to see what is available.") @@ -79,6 +84,7 @@ class Context(CommonContext): sent_announce_pos = 0 announcements = [] announcement_pos = 0 + sc2_run_task: typing.Optional[asyncio.Task] = None async def server_auth(self, password_requested: bool = False): if password_requested and not self.password: @@ -116,6 +122,11 @@ class Context(CommonContext): self.ui = SC2Manager(self) self.ui_task = asyncio.create_task(self.ui.async_run(), name="UI") + async def shutdown(self): + await super(Context, self).shutdown() + if self.sc2_run_task: + self.sc2_run_task.cancel() + async def main(): multiprocessing.freeze_support()