diff options
Diffstat (limited to 'apworld/context.py')
| -rw-r--r-- | apworld/context.py | 42 |
1 files changed, 37 insertions, 5 deletions
| diff --git a/apworld/context.py b/apworld/context.py index 05f75a3..2a2149f 100644 --- a/apworld/context.py +++ b/apworld/context.py | |||
| @@ -8,9 +8,12 @@ import websockets | |||
| 8 | 8 | ||
| 9 | import Utils | 9 | import Utils |
| 10 | import settings | 10 | import settings |
| 11 | from BaseClasses import ItemClassification | ||
| 11 | from CommonClient import CommonContext, server_loop, gui_enabled, logger, get_base_parser, handle_url_arg | 12 | from CommonClient import CommonContext, server_loop, gui_enabled, logger, get_base_parser, handle_url_arg |
| 12 | from NetUtils import Endpoint, decode, encode | 13 | from NetUtils import Endpoint, decode, encode |
| 13 | from Utils import async_start | 14 | from Utils import async_start |
| 15 | from . import Lingo2World | ||
| 16 | from .tracker import Tracker | ||
| 14 | 17 | ||
| 15 | PORT = 43182 | 18 | PORT = 43182 |
| 16 | MESSAGE_MAX_SIZE = 16*1024*1024 | 19 | MESSAGE_MAX_SIZE = 16*1024*1024 |
| @@ -19,9 +22,11 @@ MESSAGE_MAX_SIZE = 16*1024*1024 | |||
| 19 | class Lingo2GameContext: | 22 | class Lingo2GameContext: |
| 20 | server: Endpoint | None | 23 | server: Endpoint | None |
| 21 | client: "Lingo2ClientContext" | 24 | client: "Lingo2ClientContext" |
| 25 | tracker: Tracker | ||
| 22 | 26 | ||
| 23 | def __init__(self): | 27 | def __init__(self): |
| 24 | self.server = None | 28 | self.server = None |
| 29 | self.tracker = Tracker() | ||
| 25 | 30 | ||
| 26 | def send_connected(self): | 31 | def send_connected(self): |
| 27 | msg = { | 32 | msg = { |
| @@ -84,6 +89,22 @@ class Lingo2GameContext: | |||
| 84 | 89 | ||
| 85 | async_start(self.send_msgs([msg]), name="notif") | 90 | async_start(self.send_msgs([msg]), name="notif") |
| 86 | 91 | ||
| 92 | def send_accessible_locations(self): | ||
| 93 | msg = { | ||
| 94 | "cmd": "AccessibleLocations", | ||
| 95 | "locations": list(self.tracker.accessible_locations), | ||
| 96 | } | ||
| 97 | |||
| 98 | async_start(self.send_msgs([msg]), name="accessible locations") | ||
| 99 | |||
| 100 | def send_update_locations(self, locations): | ||
| 101 | msg = { | ||
| 102 | "cmd": "UpdateLocations", | ||
| 103 | "locations": locations, | ||
| 104 | } | ||
| 105 | |||
| 106 | async_start(self.send_msgs([msg]), name="update locations") | ||
| 107 | |||
| 87 | async def send_msgs(self, msgs: list[Any]) -> None: | 108 | async def send_msgs(self, msgs: list[Any]) -> None: |
| 88 | """ `msgs` JSON serializable """ | 109 | """ `msgs` JSON serializable """ |
| 89 | if not self.server or not self.server.socket.open or self.server.socket.closed: | 110 | if not self.server or not self.server.socket.open or self.server.socket.closed: |
| @@ -119,7 +140,14 @@ class Lingo2ClientContext(CommonContext): | |||
| 119 | 140 | ||
| 120 | if self.game_ctx.server is not None: | 141 | if self.game_ctx.server is not None: |
| 121 | self.game_ctx.send_connected() | 142 | self.game_ctx.send_connected() |
| 143 | |||
| 144 | self.game_ctx.tracker.setup_slot(self.slot_data) | ||
| 145 | elif cmd == "RoomUpdate": | ||
| 146 | if self.game_ctx.server is not None: | ||
| 147 | self.game_ctx.send_update_locations(args["checked_locations"]) | ||
| 122 | elif cmd == "ReceivedItems": | 148 | elif cmd == "ReceivedItems": |
| 149 | self.game_ctx.tracker.set_collected_items(self.items_received) | ||
| 150 | |||
| 123 | if self.game_ctx.server is not None: | 151 | if self.game_ctx.server is not None: |
| 124 | cur_index = 0 | 152 | cur_index = 0 |
| 125 | items = [] | 153 | items = [] |
| @@ -141,6 +169,9 @@ class Lingo2ClientContext(CommonContext): | |||
| 141 | items.append(item_msg) | 169 | items.append(item_msg) |
| 142 | 170 | ||
| 143 | self.game_ctx.send_item_received(items) | 171 | self.game_ctx.send_item_received(items) |
| 172 | |||
| 173 | if any(ItemClassification.progression in ItemClassification(item.flags) for item in args["items"]): | ||
| 174 | self.game_ctx.send_accessible_locations() | ||
| 144 | elif cmd == "PrintJSON": | 175 | elif cmd == "PrintJSON": |
| 145 | if self.game_ctx.server is not None: | 176 | if self.game_ctx.server is not None: |
| 146 | if "receiving" in args and "item" in args and args["item"].player == self.slot: | 177 | if "receiving" in args and "item" in args and args["item"].player == self.slot: |
| @@ -195,6 +226,9 @@ class Lingo2ClientContext(CommonContext): | |||
| 195 | 226 | ||
| 196 | self.game_ctx.send_location_info(locations) | 227 | self.game_ctx.send_location_info(locations) |
| 197 | 228 | ||
| 229 | if cmd in ["Connected", "RoomUpdate"]: | ||
| 230 | self.game_ctx.tracker.set_checked_locations(self.checked_locations) | ||
| 231 | |||
| 198 | 232 | ||
| 199 | async def pipe_loop(ctx: Lingo2GameContext): | 233 | async def pipe_loop(ctx: Lingo2GameContext): |
| 200 | while not ctx.client.exit_event.is_set(): | 234 | while not ctx.client.exit_event.is_set(): |
| @@ -205,6 +239,7 @@ async def pipe_loop(ctx: Lingo2GameContext): | |||
| 205 | logger.info("Connected to Lingo 2!") | 239 | logger.info("Connected to Lingo 2!") |
| 206 | if ctx.client.auth is not None: | 240 | if ctx.client.auth is not None: |
| 207 | ctx.send_connected() | 241 | ctx.send_connected() |
| 242 | ctx.send_accessible_locations() | ||
| 208 | async for data in ctx.server.socket: | 243 | async for data in ctx.server.socket: |
| 209 | for msg in decode(data): | 244 | for msg in decode(data): |
| 210 | await process_game_cmd(ctx, msg) | 245 | await process_game_cmd(ctx, msg) |
| @@ -237,10 +272,7 @@ async def process_game_cmd(ctx: Lingo2GameContext, args: dict): | |||
| 237 | async def run_game(): | 272 | async def run_game(): |
| 238 | exe_file = settings.get_settings().lingo2_options.exe_file | 273 | exe_file = settings.get_settings().lingo2_options.exe_file |
| 239 | 274 | ||
| 240 | from worlds import AutoWorldRegister | 275 | if Lingo2World.zip_path is not None: |
| 241 | world = AutoWorldRegister.world_types["Lingo 2"] | ||
| 242 | |||
| 243 | if world.zip_path is not None: | ||
| 244 | # This is a packaged apworld. | 276 | # This is a packaged apworld. |
| 245 | init_scene = pkgutil.get_data(__name__, "client/run_from_apworld.tscn") | 277 | init_scene = pkgutil.get_data(__name__, "client/run_from_apworld.tscn") |
| 246 | init_path = Utils.local_path("data", "lingo2_init.tscn") | 278 | init_path = Utils.local_path("data", "lingo2_init.tscn") |
| @@ -254,7 +286,7 @@ async def run_game(): | |||
| 254 | "--scene", | 286 | "--scene", |
| 255 | init_path, | 287 | init_path, |
| 256 | "--", | 288 | "--", |
| 257 | str(world.zip_path.absolute()), | 289 | str(Lingo2World.zip_path.absolute()), |
| 258 | ], | 290 | ], |
| 259 | cwd=os.path.dirname(exe_file), | 291 | cwd=os.path.dirname(exe_file), |
| 260 | ) | 292 | ) |
