summaryrefslogtreecommitdiff
path: root/resources/external/game_coordinator.py
diff options
context:
space:
mode:
Diffstat (limited to 'resources/external/game_coordinator.py')
-rw-r--r--resources/external/game_coordinator.py65
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