about summary refs log tree commit diff stats
path: root/apworld/context.py
diff options
context:
space:
mode:
Diffstat (limited to 'apworld/context.py')
-rw-r--r--apworld/context.py42
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
9import Utils 9import Utils
10import settings 10import settings
11from BaseClasses import ItemClassification
11from CommonClient import CommonContext, server_loop, gui_enabled, logger, get_base_parser, handle_url_arg 12from CommonClient import CommonContext, server_loop, gui_enabled, logger, get_base_parser, handle_url_arg
12from NetUtils import Endpoint, decode, encode 13from NetUtils import Endpoint, decode, encode
13from Utils import async_start 14from Utils import async_start
15from . import Lingo2World
16from .tracker import Tracker
14 17
15PORT = 43182 18PORT = 43182
16MESSAGE_MAX_SIZE = 16*1024*1024 19MESSAGE_MAX_SIZE = 16*1024*1024
@@ -19,9 +22,11 @@ MESSAGE_MAX_SIZE = 16*1024*1024
19class Lingo2GameContext: 22class 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
199async def pipe_loop(ctx: Lingo2GameContext): 233async 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):
237async def run_game(): 272async 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 )