mirror of
https://github.com/ArchipelagoMW/Archipelago.git
synced 2026-08-20 16:46:38 -07:00
CommonClient: reset session state when connecting to a different room or slot (#6231)
This commit is contained in:
@@ -341,6 +341,10 @@ class CommonContext:
|
||||
"""Name used in Connect packet"""
|
||||
seed_name: str | None
|
||||
"""Seed name that will be validated on opening a socket if present"""
|
||||
server_seed_name: str | None
|
||||
"""Actual seed_name reported by the server in RoomInfo"""
|
||||
connected_identity: tuple[str, int, int] | None
|
||||
"""(server_seed_name, team, slot) of the last successful connection, used to detect a session switch"""
|
||||
|
||||
# locations
|
||||
locations_checked: set[int]
|
||||
@@ -399,6 +403,10 @@ class CommonContext:
|
||||
self.slot = None
|
||||
self.auth = None
|
||||
self.seed_name = None
|
||||
self.server_seed_name = None
|
||||
self.connected_identity = None
|
||||
# decouple from the class-level mutable set so tag changes (e.g. DeathLink) don't leak across instances
|
||||
self.tags = set(type(self).tags)
|
||||
|
||||
self.locations_checked = set() # local state
|
||||
self.locations_scouted = set()
|
||||
@@ -459,6 +467,7 @@ class CommonContext:
|
||||
self.team = None
|
||||
self.items_received = []
|
||||
self.locations_info = {}
|
||||
self.server_seed_name = None
|
||||
self.server_version = Version(0, 0, 0)
|
||||
self.generator_version = Version(0, 0, 0)
|
||||
self.server = None
|
||||
@@ -470,6 +479,21 @@ class CommonContext:
|
||||
"remaining": "disabled",
|
||||
}
|
||||
|
||||
def reset_session_state(self):
|
||||
"""Clear local progress and data-storage state tied to a single session."""
|
||||
self.locations_checked = set()
|
||||
self.locations_scouted = set()
|
||||
self.locations_info = {}
|
||||
self.items_received = []
|
||||
self.missing_locations = set()
|
||||
self.checked_locations = set()
|
||||
self.server_locations = set()
|
||||
self.finished_game = False
|
||||
self.ready = False
|
||||
self.stored_data = {}
|
||||
self.stored_data_notification_keys = set()
|
||||
self.current_energy_link_value = None
|
||||
|
||||
async def disconnect(self, allow_autoreconnect: bool = False):
|
||||
if not allow_autoreconnect:
|
||||
self.disconnected_intentionally = True
|
||||
@@ -924,6 +948,7 @@ async def process_server_cmd(ctx: CommonContext, args: dict):
|
||||
logger.exception(f"Could not get command from {args}")
|
||||
raise
|
||||
if cmd == 'RoomInfo':
|
||||
ctx.server_seed_name = args["seed_name"]
|
||||
if ctx.seed_name and ctx.seed_name != args["seed_name"]:
|
||||
msg = "The server is running a different multiworld than your client is. (invalid seed_name)"
|
||||
logger.info(msg, extra={'compact_gui': True})
|
||||
@@ -1004,6 +1029,11 @@ async def process_server_cmd(ctx: CommonContext, args: dict):
|
||||
ctx.username = ctx.auth
|
||||
ctx.team = args["team"]
|
||||
ctx.slot = args["slot"]
|
||||
# on a switch to a different session, clear session state before stale checks/goal are replayed below
|
||||
identity = (ctx.server_seed_name, ctx.team, ctx.slot)
|
||||
if ctx.connected_identity is not None and identity != ctx.connected_identity:
|
||||
ctx.reset_session_state()
|
||||
ctx.connected_identity = identity
|
||||
# int keys get lost in JSON transfer
|
||||
ctx.slot_info = {0: NetworkSlot("Archipelago", "Archipelago", SlotType.player)}
|
||||
ctx.slot_info.update({int(pid): data for pid, data in args["slot_info"].items()})
|
||||
|
||||
@@ -120,7 +120,6 @@ class BizHawkClientCommandProcessor(ClientCommandProcessor):
|
||||
class BizHawkClientContext(CommonContext):
|
||||
command_processor = BizHawkClientCommandProcessor
|
||||
text_passthrough_categories: set[str]
|
||||
server_seed_name: str | None = None
|
||||
auth_status: AuthStatus
|
||||
password_requested: bool
|
||||
client_handler: BizHawkClient | None
|
||||
@@ -169,8 +168,6 @@ class BizHawkClientContext(CommonContext):
|
||||
if cmd == "Connected":
|
||||
self.slot_data = args.get("slot_data", None)
|
||||
self.auth_status = AuthStatus.AUTHENTICATED
|
||||
elif cmd == "RoomInfo":
|
||||
self.server_seed_name = args.get("seed_name", None)
|
||||
|
||||
if self.client_handler is not None:
|
||||
self.client_handler.on_package(self, cmd, args)
|
||||
@@ -203,7 +200,6 @@ class BizHawkClientContext(CommonContext):
|
||||
|
||||
async def disconnect(self, allow_autoreconnect: bool=False):
|
||||
self.auth_status = AuthStatus.NOT_AUTHENTICATED
|
||||
self.server_seed_name = None
|
||||
await super().disconnect(allow_autoreconnect)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user