From c2d8f2443e25d74e19ff1344f7d5e3950e4d13ce Mon Sep 17 00:00:00 2001 From: threeandthreee Date: Sat, 5 Apr 2025 12:39:31 -0400 Subject: [PATCH] LADX: more tracker support (#4355) * init * oops --- LinksAwakeningClient.py | 34 +++++++++++++++++++++------------- worlds/ladx/Tracker.py | 13 ++++++------- worlds/ladx/__init__.py | 2 ++ 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/LinksAwakeningClient.py b/LinksAwakeningClient.py index 2f2c94f6..26a0d553 100644 --- a/LinksAwakeningClient.py +++ b/LinksAwakeningClient.py @@ -139,7 +139,7 @@ class RAGameboy(): def set_checks_range(self, checks_start, checks_size): self.checks_start = checks_start self.checks_size = checks_size - + def set_location_range(self, location_start, location_size, critical_addresses): self.location_start = location_start self.location_size = location_size @@ -237,7 +237,7 @@ class RAGameboy(): self.cache[start:start + len(hram_block)] = hram_block self.last_cache_read = time.time() - + async def read_memory_block(self, address: int, size: int): block = bytearray() remaining_size = size @@ -245,7 +245,7 @@ class RAGameboy(): chunk = await self.async_read_memory(address + len(block), remaining_size) remaining_size -= len(chunk) block += chunk - + return block async def read_memory_cache(self, addresses): @@ -514,8 +514,8 @@ class LinksAwakeningContext(CommonContext): magpie_task = None won = False - @property - def slot_storage_key(self): + @property + def slot_storage_key(self): return f"{self.slot_info[self.slot].name}_{storage_key}" def __init__(self, server_address: typing.Optional[str], password: typing.Optional[str], magpie: typing.Optional[bool]) -> None: @@ -558,7 +558,7 @@ class LinksAwakeningContext(CommonContext): self.ui = LADXManager(self) self.ui_task = asyncio.create_task(self.ui.async_run(), name="UI") - + async def send_new_entrances(self, entrances: typing.Dict[str, str]): # Store the entrances we find on the server for future sessions message = [{ @@ -597,12 +597,12 @@ class LinksAwakeningContext(CommonContext): logger.info("victory!") await self.send_msgs(message) self.won = True - + async def request_found_entrances(self): await self.send_msgs([{"cmd": "Get", "keys": [self.slot_storage_key]}]) - # Ask for updates so that players can co-op entrances in a seed - await self.send_msgs([{"cmd": "SetNotify", "keys": [self.slot_storage_key]}]) + # Ask for updates so that players can co-op entrances in a seed + await self.send_msgs([{"cmd": "SetNotify", "keys": [self.slot_storage_key]}]) async def on_deathlink(self, data: typing.Dict[str, typing.Any]) -> None: if self.ENABLE_DEATHLINK: @@ -638,12 +638,18 @@ class LinksAwakeningContext(CommonContext): if cmd == "Connected": self.game = self.slot_info[self.slot].game self.slot_data = args.get("slot_data", {}) - + # This is sent to magpie over local websocket to make its own connection + self.slot_data.update({ + "server_address": self.server_address, + "slot_name": self.player_names[self.slot], + "password": self.password, + }) + # TODO - use watcher_event if cmd == "ReceivedItems": for index, item in enumerate(args["items"], start=args["index"]): self.client.recvd_checks[index] = item - + if cmd == "Retrieved" and self.magpie_enabled and self.slot_storage_key in args["keys"]: self.client.gps_tracker.receive_found_entrances(args["keys"][self.slot_storage_key]) @@ -722,8 +728,10 @@ class LinksAwakeningContext(CommonContext): try: self.magpie.set_checks(self.client.tracker.all_checks) await self.magpie.set_item_tracker(self.client.item_tracker) - self.magpie.slot_data = self.slot_data - + if self.slot_data and "slot_data" in self.magpie.features and not self.magpie.has_sent_slot_data: + self.magpie.slot_data = self.slot_data + await self.magpie.send_slot_data() + if self.client.gps_tracker.needs_found_entrances: await self.request_found_entrances() self.client.gps_tracker.needs_found_entrances = False diff --git a/worlds/ladx/Tracker.py b/worlds/ladx/Tracker.py index 1842ceae..93b74632 100644 --- a/worlds/ladx/Tracker.py +++ b/worlds/ladx/Tracker.py @@ -184,6 +184,7 @@ class MagpieBridge: ws = None features = [] slot_data = {} + has_sent_slot_data = False def use_entrance_tracker(self): return "entrances" in self.features \ @@ -199,7 +200,7 @@ class MagpieBridge: logger.info( f"Connected, supported features: {message['features']}") self.features = message["features"] - + await self.send_handshAck() if message["type"] == "sendFull": @@ -207,8 +208,6 @@ class MagpieBridge: await self.send_all_inventory() if "checks" in self.features: await self.send_all_checks() - if "slot_data" in self.features and self.slot_data: - await self.send_slot_data(self.slot_data) if self.use_entrance_tracker(): await self.send_gps(diff=False) @@ -220,7 +219,7 @@ class MagpieBridge: if the_id == "0x2A7": return "0x2A1-1" return the_id - + async def send_handshAck(self): if not self.ws: return @@ -288,17 +287,17 @@ class MagpieBridge: return await self.gps_tracker.send_entrances(self.ws, diff) - async def send_slot_data(self, slot_data): + async def send_slot_data(self): if not self.ws: return logger.debug("Sending slot_data to magpie.") message = { "type": "slot_data", - "slot_data": slot_data + "slot_data": self.slot_data } - await self.ws.send(json.dumps(message)) + self.has_sent_slot_data = True async def serve(self): async with websockets.serve(lambda w: self.handler(w), "", 17026, logger=logger): diff --git a/worlds/ladx/__init__.py b/worlds/ladx/__init__.py index 71c7fc6f..78ae1ce8 100644 --- a/worlds/ladx/__init__.py +++ b/worlds/ladx/__init__.py @@ -589,4 +589,6 @@ class LinksAwakeningWorld(World): for option, value in dataclasses.asdict(self.options).items() if option in slot_options_display_name }) + slot_data.update({"entrance_mapping": self.ladxr_logic.world_setup.entrance_mapping}) + return slot_data