diff options
Diffstat (limited to 'apworld/context.py')
-rw-r--r-- | apworld/context.py | 72 |
1 files changed, 67 insertions, 5 deletions
diff --git a/apworld/context.py b/apworld/context.py index bc3b1bf..4a85868 100644 --- a/apworld/context.py +++ b/apworld/context.py | |||
@@ -35,6 +35,7 @@ class Lingo2Manager: | |||
35 | tracker: Tracker | 35 | tracker: Tracker |
36 | 36 | ||
37 | keyboard: dict[str, int] | 37 | keyboard: dict[str, int] |
38 | worldports: set[int] | ||
38 | 39 | ||
39 | def __init__(self, game_ctx: "Lingo2GameContext", client_ctx: "Lingo2ClientContext"): | 40 | def __init__(self, game_ctx: "Lingo2GameContext", client_ctx: "Lingo2ClientContext"): |
40 | self.game_ctx = game_ctx | 41 | self.game_ctx = game_ctx |
@@ -43,6 +44,7 @@ class Lingo2Manager: | |||
43 | self.client_ctx.manager = self | 44 | self.client_ctx.manager = self |
44 | self.tracker = Tracker(self) | 45 | self.tracker = Tracker(self) |
45 | self.keyboard = {} | 46 | self.keyboard = {} |
47 | self.worldports = set() | ||
46 | 48 | ||
47 | self.reset() | 49 | self.reset() |
48 | 50 | ||
@@ -50,6 +52,8 @@ class Lingo2Manager: | |||
50 | for k in ALL_LETTERS: | 52 | for k in ALL_LETTERS: |
51 | self.keyboard[k] = 0 | 53 | self.keyboard[k] = 0 |
52 | 54 | ||
55 | self.worldports = set() | ||
56 | |||
53 | def update_keyboard(self, new_keyboard: dict[str, int]) -> dict[str, int]: | 57 | def update_keyboard(self, new_keyboard: dict[str, int]) -> dict[str, int]: |
54 | ret: dict[str, int] = {} | 58 | ret: dict[str, int] = {} |
55 | 59 | ||
@@ -64,6 +68,16 @@ class Lingo2Manager: | |||
64 | 68 | ||
65 | return ret | 69 | return ret |
66 | 70 | ||
71 | def update_worldports(self, new_worldports: set[int]) -> set[int]: | ||
72 | ret = new_worldports.difference(self.worldports) | ||
73 | self.worldports.update(new_worldports) | ||
74 | |||
75 | if len(ret) > 0: | ||
76 | self.tracker.refresh_state() | ||
77 | self.game_ctx.send_accessible_locations() | ||
78 | |||
79 | return ret | ||
80 | |||
67 | 81 | ||
68 | class Lingo2GameContext: | 82 | class Lingo2GameContext: |
69 | server: Endpoint | None | 83 | server: Endpoint | None |
@@ -160,6 +174,9 @@ class Lingo2GameContext: | |||
160 | "locations": list(self.manager.tracker.accessible_locations), | 174 | "locations": list(self.manager.tracker.accessible_locations), |
161 | } | 175 | } |
162 | 176 | ||
177 | if len(self.manager.tracker.accessible_worldports) > 0: | ||
178 | msg["worldports"] = list(self.manager.tracker.accessible_worldports) | ||
179 | |||
163 | async_start(self.send_msgs([msg]), name="accessible locations") | 180 | async_start(self.send_msgs([msg]), name="accessible locations") |
164 | 181 | ||
165 | def send_update_locations(self, locations): | 182 | def send_update_locations(self, locations): |
@@ -184,6 +201,17 @@ class Lingo2GameContext: | |||
184 | 201 | ||
185 | async_start(self.send_msgs([msg]), name="update keyboard") | 202 | async_start(self.send_msgs([msg]), name="update keyboard") |
186 | 203 | ||
204 | def send_update_worldports(self, worldports): | ||
205 | if self.server is None: | ||
206 | return | ||
207 | |||
208 | msg = { | ||
209 | "cmd": "UpdateWorldports", | ||
210 | "worldports": worldports, | ||
211 | } | ||
212 | |||
213 | async_start(self.send_msgs([msg]), name="update worldports") | ||
214 | |||
187 | async def send_msgs(self, msgs: list[Any]) -> None: | 215 | async def send_msgs(self, msgs: list[Any]) -> None: |
188 | """ `msgs` JSON serializable """ | 216 | """ `msgs` JSON serializable """ |
189 | if not self.server or not self.server.socket.open or self.server.socket.closed: | 217 | if not self.server or not self.server.socket.open or self.server.socket.closed: |
@@ -226,7 +254,7 @@ class Lingo2ClientContext(CommonContext): | |||
226 | self.manager.game_ctx.send_accessible_locations() | 254 | self.manager.game_ctx.send_accessible_locations() |
227 | 255 | ||
228 | self.set_notify(self.get_datastorage_key("keyboard1"), self.get_datastorage_key("keyboard2")) | 256 | self.set_notify(self.get_datastorage_key("keyboard1"), self.get_datastorage_key("keyboard2")) |
229 | async_start(self.send_msgs([{ | 257 | msg_batch = [{ |
230 | "cmd": "Set", | 258 | "cmd": "Set", |
231 | "key": self.get_datastorage_key("keyboard1"), | 259 | "key": self.get_datastorage_key("keyboard1"), |
232 | "default": 0, | 260 | "default": 0, |
@@ -238,7 +266,19 @@ class Lingo2ClientContext(CommonContext): | |||
238 | "default": 0, | 266 | "default": 0, |
239 | "want_reply": True, | 267 | "want_reply": True, |
240 | "operations": [{"operation": "default", "value": 0}] | 268 | "operations": [{"operation": "default", "value": 0}] |
241 | }]), name="default keys") | 269 | }] |
270 | |||
271 | if self.slot_data["shuffle_worldports"]: | ||
272 | self.set_notify(self.get_datastorage_key("worldports")) | ||
273 | msg_batch.append({ | ||
274 | "cmd": "Set", | ||
275 | "key": self.get_datastorage_key("worldports"), | ||
276 | "default": [], | ||
277 | "want_reply": True, | ||
278 | "operations": [{"operation": "default", "value": []}] | ||
279 | }) | ||
280 | |||
281 | async_start(self.send_msgs(msg_batch), name="default keys") | ||
242 | elif cmd == "RoomUpdate": | 282 | elif cmd == "RoomUpdate": |
243 | self.manager.tracker.set_checked_locations(self.checked_locations) | 283 | self.manager.tracker.set_checked_locations(self.checked_locations) |
244 | self.manager.game_ctx.send_update_locations(args["checked_locations"]) | 284 | self.manager.game_ctx.send_update_locations(args["checked_locations"]) |
@@ -276,7 +316,7 @@ class Lingo2ClientContext(CommonContext): | |||
276 | 316 | ||
277 | if args["type"] == "Hint" and not args.get("found", False): | 317 | if args["type"] == "Hint" and not args.get("found", False): |
278 | self.manager.game_ctx.send_hint_received(item_name, location_name, receiver_name, args["item"].flags, | 318 | self.manager.game_ctx.send_hint_received(item_name, location_name, receiver_name, args["item"].flags, |
279 | int(args["receiving"]) == self.slot) | 319 | int(args["receiving"]) == self.slot) |
280 | elif args["receiving"] != self.slot: | 320 | elif args["receiving"] != self.slot: |
281 | self.manager.game_ctx.send_item_sent_notification(item_name, receiver_name, args["item"].flags) | 321 | self.manager.game_ctx.send_item_sent_notification(item_name, receiver_name, args["item"].flags) |
282 | 322 | ||
@@ -324,6 +364,10 @@ class Lingo2ClientContext(CommonContext): | |||
324 | self.handle_keyboard_update(1, args) | 364 | self.handle_keyboard_update(1, args) |
325 | elif args["key"] == self.get_datastorage_key("keyboard2"): | 365 | elif args["key"] == self.get_datastorage_key("keyboard2"): |
326 | self.handle_keyboard_update(2, args) | 366 | self.handle_keyboard_update(2, args) |
367 | elif args["key"] == self.get_datastorage_key("worldports"): | ||
368 | updates = self.manager.update_worldports(set(args["value"])) | ||
369 | if len(updates) > 0: | ||
370 | self.manager.game_ctx.send_update_worldports(updates) | ||
327 | 371 | ||
328 | def get_datastorage_key(self, name: str): | 372 | def get_datastorage_key(self, name: str): |
329 | return f"Lingo2_{self.slot}_{name}" | 373 | return f"Lingo2_{self.slot}_{name}" |
@@ -373,8 +417,6 @@ class Lingo2ClientContext(CommonContext): | |||
373 | }) | 417 | }) |
374 | 418 | ||
375 | if len(msgs) > 0: | 419 | if len(msgs) > 0: |
376 | print(updates) | ||
377 | print(msgs) | ||
378 | await self.send_msgs(msgs) | 420 | await self.send_msgs(msgs) |
379 | 421 | ||
380 | def handle_keyboard_update(self, field: int, args: dict[str, Any]): | 422 | def handle_keyboard_update(self, field: int, args: dict[str, Any]): |
@@ -391,6 +433,17 @@ class Lingo2ClientContext(CommonContext): | |||
391 | if len(updates) > 0: | 433 | if len(updates) > 0: |
392 | self.manager.game_ctx.send_update_keyboard(updates) | 434 | self.manager.game_ctx.send_update_keyboard(updates) |
393 | 435 | ||
436 | async def update_worldports(self, updates: set[int]): | ||
437 | await self.send_msgs([{ | ||
438 | "cmd": "Set", | ||
439 | "key": self.get_datastorage_key("worldports"), | ||
440 | "want_reply": True, | ||
441 | "operations": [{ | ||
442 | "operation": "update", | ||
443 | "value": updates | ||
444 | }] | ||
445 | }]) | ||
446 | |||
394 | 447 | ||
395 | async def pipe_loop(manager: Lingo2Manager): | 448 | async def pipe_loop(manager: Lingo2Manager): |
396 | while not manager.client_ctx.exit_event.is_set(): | 449 | while not manager.client_ctx.exit_event.is_set(): |
@@ -433,6 +486,15 @@ async def process_game_cmd(manager: Lingo2Manager, args: dict): | |||
433 | updates = manager.update_keyboard(args["keyboard"]) | 486 | updates = manager.update_keyboard(args["keyboard"]) |
434 | if len(updates) > 0: | 487 | if len(updates) > 0: |
435 | async_start(manager.client_ctx.update_keyboard(updates), name="client update keyboard") | 488 | async_start(manager.client_ctx.update_keyboard(updates), name="client update keyboard") |
489 | elif cmd == "CheckWorldport": | ||
490 | port_id = args["port_id"] | ||
491 | worldports = {port_id} | ||
492 | if str(port_id) in manager.client_ctx.slot_data["port_pairings"]: | ||
493 | worldports.add(manager.client_ctx.slot_data["port_pairings"][str(port_id)]) | ||
494 | |||
495 | updates = manager.update_worldports(worldports) | ||
496 | if len(updates) > 0: | ||
497 | async_start(manager.client_ctx.update_worldports(updates), name="client update worldports") | ||
436 | elif cmd == "Quit": | 498 | elif cmd == "Quit": |
437 | manager.client_ctx.exit_event.set() | 499 | manager.client_ctx.exit_event.set() |
438 | 500 | ||