diff options
Diffstat (limited to 'resources/external/game_coordinator.py')
| -rw-r--r-- | resources/external/game_coordinator.py | 65 |
1 files changed, 40 insertions, 25 deletions
diff --git a/resources/external/game_coordinator.py b/resources/external/game_coordinator.py index 0f04e18..8daae7f 100644 --- a/resources/external/game_coordinator.py +++ b/resources/external/game_coordinator.py @@ -104,6 +104,7 @@ async def remove_player(lobby, player_id): del LOBBIES[lobby["lobby_id"]] elif was_host: # host must be transferred + print("changing host") new_host_id = None for player_id in lobby["players"]: @@ -128,7 +129,7 @@ async def disconnect_player(lobby, player_id, reason='disconnect'): dc_player = lobby["players"][player_id] dc_player["connection_status"] = 0 if "dead" not in dc_player: - response = {"type" : "disconnected", "message" : f"Disconnected. Reason: {reason}"} + response = {"type" : "disconnected", "message" : f"Disconnected. Reason: {reason}", "reason" : reason} try: await dc_player["socket"].send(json.dumps(response)) except: @@ -147,6 +148,9 @@ async def disconnect_player(lobby, player_id, reason='disconnect'): async def connection_lost(lobby, player_id): if player_id in lobby["players"]: lobby["players"][player_id]["connection_status"] = 0 + current_players = await get_player_info(lobby) + announcement = {"type" : "announcement_player_connerr", "player_id" : player_id, "current_players" : current_players } + await broadcast_active(lobby, announcement) await asyncio.sleep( DISCONNECT_GRACE_PERIOD if not lobby["paused"] else PAUSED_GRACE_PERIOD ) if player_id in lobby["players"] and lobby["players"][player_id]["connection_status"] == 0: lobby["players"][player_id]["dead"] = True @@ -188,6 +192,8 @@ async def lobby_loop(websocket, lobby, player): lobby_id = lobby["lobby_id"] async for message in websocket: event = json.loads(message) + lobby = LOBBIES[lobby_id] + player = lobby["players"][player_id] # handle messages sent from connected players yet unconfirmed by host if "waiting" in player: @@ -197,7 +203,10 @@ async def lobby_loop(websocket, lobby, player): if player["waiting_retries"] > MAX_JOIN_REQUESTS: await end_lobby(lobby_id) # does this need to be awaited? return True - await send_join_request_to_host(lobby, player_id) + try: + await send_join_request_to_host(lobby, player_id) + except Exception as e: + print(e) continue # deny any other requests @@ -218,33 +227,38 @@ async def lobby_loop(websocket, lobby, player): continue if not player["is_host"]: - response = {"type" : "gc_error", "message" : f"GC ERROR: Only host has access to command {event['command']}."} + response = {"type" : "gc_error", "message" : f"Only host has access to command {event['command']}."} await websocket.send(json.dumps(response)) continue # following commands only available to game host if event["command"] == "accept_player": if ("player_id" not in event) or (event["player_id"] not in lobby["players"]): - response = {"type" : "gc_error", "message" : "GC ERROR: No player ID given, or given player ID is not in the lobby."} + response = {"type" : "gc_error", "message" : "No player ID given, or given player ID is not in the lobby."} await websocket.send(json.dumps(response)) continue - + accepted_id = event["player_id"] if "waiting" not in lobby["players"][accepted_id]: - response = {"type" : "gc_error", "message" : "GC ERROR: Player already accepted."} + + response = {"type" : "gc_error", "message" : "Player already accepted."} await websocket.send(json.dumps(response)) continue + accepted_player = lobby["players"][accepted_id] del accepted_player["waiting"] del accepted_player["waiting_args"] del accepted_player["waiting_since"] del accepted_player["waiting_retries"] - notification = { "type" : "join_ok" } - + + current_players = await get_player_info(lobby) + notification = { "type" : "join_ok", "current_players" : current_players} + if "args" in event: notification["args"] = event["args"] + await accepted_player["socket"].send(json.dumps(notification)) # notify waiting player of acceptance elif event["command"] == "deny_player": if ("player_id" not in event) or (event["player_id"] not in lobby["players"]): - response = {"type" : "gc_error", "message" : "GC ERROR: No player ID given, or given player ID is not in the lobby."} + response = {"type" : "gc_error", "message" : "No player ID given, or given player ID is not in the lobby."} await websocket.send(json.dumps(response)) continue denied_id = event["player_id"] @@ -253,7 +267,7 @@ async def lobby_loop(websocket, lobby, player): await disconnect_player(lobby, denied_id, "denied"+reason_text) elif event["command"] == "kick_player": if ("player_id" not in event) or (event["player_id"] not in lobby["players"]): - response = {"type" : "gc_error", "message" : "GC ERROR: No player ID given, or given player ID is not in the lobby."} + response = {"type" : "gc_error", "message" : "No player ID given, or given player ID is not in the lobby."} await websocket.send(json.dumps(response)) continue kicked_id = event["player_id"] @@ -286,12 +300,13 @@ async def lobby_loop(websocket, lobby, player): response = {"type" : "request", "destination" : player_id, "request_fields" : event["request_fields"] } await game["players"][ event["source"] ]["socket"].send( json.dumps(response) ) elif event["type"] == "request_response": - response = {"type" : "request_response", "data" : event["requested_data"] } + response = {"type" : "request_response", "source" : player_id ,"requested_data" : event["requested_data"] } await game["players"][ event["destination"] ]["socket"].send( json.dumps(response) ) elif event["type"] == "broadcast": - message = {"type" : "broadcast", "payload" : event["payload"]} - for player in game["players"]: - if player["connection_status"] == 1 and ( (player != player_id) or ("to_self" in event) ): await player["socket"].send(json.dumps(message)) + message = {"type" : "broadcast", "command" : event["command"], "payload" : event["payload"]} + for _player_id in lobby["players"]: + player = lobby["players"][_player_id] + if player["connection_status"] == 1 and ( (_player_id != player_id) or ("to_self" in event) ): await player["socket"].send(json.dumps(message)) if lobby_id not in LOBBIES: return True # lobby closed if player_id not in LOBBIES[lobby_id]["players"] or ("dead" in LOBBIES[lobby_id]["players"][player_id]): return True # player removed @@ -301,39 +316,39 @@ async def lobby_loop(websocket, lobby, player): async def join_lobby(websocket, event): for required_field in ["lobby_id", "game_type", "username"]: if required_field not in event: - response = {"type" : "gc_error", "message" : f"GC ERROR: Missing required field: '{required_field}'."} + response = {"type" : "join_fail", "message" : f"Missing required field: '{required_field}'."} await websocket.send(json.dumps(response)) await asyncio.sleep(SOCKET_GRACE_PERIOD) return # close connection lobby_id = event["lobby_id"] if lobby_id not in LOBBIES: - response = {"type" : "gc_error", "message" : f"GC ERROR: Lobby '{lobby_id}' does not exist."} + response = {"type" : "join_fail", "message" : f"Lobby '{lobby_id}' does not exist."} await websocket.send(json.dumps(response)) await asyncio.sleep(SOCKET_GRACE_PERIOD) return # close connection lobby = LOBBIES[lobby_id] if str(event["game_type"]) != lobby["game_type"]: - response = {"type" : "gc_error", "message" : f"GC ERROR: Mismatched game types. Expected {LOBBIES[lobby_id]['game_type']}, received {event['game_type']}."} + response = {"type" : "join_fail", "message" : f"Mismatched game types. Expected {LOBBIES[lobby_id]['game_type']}, received {event['game_type']}."} await websocket.send(json.dumps(response)) await asyncio.sleep(SOCKET_GRACE_PERIOD) return # close connection if len(lobby["players"]) >= lobby["max_players"]: - response = {"type" : "gc_error", "message" : "GC ERROR: Lobby full."} + response = {"type" : "join_fail", "message" : "Lobby full."} await websocket.send(json.dumps(response)) await asyncio.sleep(SOCKET_GRACE_PERIOD) return # close connection if lobby["locked"] and ("rejoin_key" not in event): - response = {"type" : "gc_error", "message" : "GC ERROR: Lobby is locked, no new connections are being accepted."} + response = {"type" : "join_fail", "message" : "Lobby is locked, no new connections are being accepted."} await websocket.send(json.dumps(response)) await asyncio.sleep(SOCKET_GRACE_PERIOD) return # close connection if lobby["private"] and (event["password"] != lobby["password"]) and ("rejoin_key" not in event): - response = {"type" : "gc_error", "message" : "GC ERROR: Incorrect password for private lobby."} + response = {"type" : "join_fail", "message" : "Incorrect password for private lobby."} await websocket.send(json.dumps(response)) await asyncio.sleep(SOCKET_GRACE_PERIOD) return # close connection @@ -365,7 +380,7 @@ async def join_lobby(websocket, event): return # end of socket # Could not rejoin - response = {"type" : "gc_error", "message" : "GC ERROR: Could not rejoin with given key."} + response = {"type" : "rejoin_fail", "message" : "Could not rejoin with given key."} await websocket.send(json.dumps(response)) await asyncio.sleep(SOCKET_GRACE_PERIOD) return # end of socket @@ -379,7 +394,7 @@ async def join_lobby(websocket, event): player_info = await get_player_info(lobby) notification = {"type" : "announcement_player_joining", "current_players" : player_info} await broadcast_active(lobby, notification) - response = { "type" : "join_request_ok", "player_id" : new_player["player_id"], "rejoin_key" : new_player["rejoin_key"] } + response = { "type" : "join_request_ok", "player_id" : new_player["player_id"], "rejoin_key" : new_player["rejoin_key"], "current_players" : player_info, "max_players" : lobby["max_players"], "lobby_name" : lobby["lobby_name"], "private" : lobby["private"]} await websocket.send(json.dumps(response)) @@ -398,14 +413,14 @@ async def join_lobby(websocket, event): async def host_lobby(websocket, event): for reqd_i, required_field in enumerate(HOST_LOBBY_REQD_FIELDS): if required_field not in event: - response = {"type" : "gc_error", "message" : f"GC ERROR: Missing required field: '{required_field}'."} + response = {"type" : "host_fail", "message" : f"Missing required field: '{required_field}'."} await websocket.send(json.dumps(response)) await asyncio.sleep(SOCKET_GRACE_PERIOD) return # close connection try: - test_argument_type = HOST_LOBBY_REQD_FIELD_TYPES[reqd_i](event[required_field]) + HOST_LOBBY_REQD_FIELD_TYPES[reqd_i](event[required_field]) except: - response = { "type" : "gc_error", "message" : f"GC_ERROR: Invalid type for field '{required_field}'." } + response = { "type" : "host_fail", "message" : f"Invalid type for field '{required_field}'." } await websocket.send(json.dumps(response)) await asyncio.sleep(SOCKET_GRACE_PERIOD) return # close connection |
