diff --git a/server/gameconnection.py b/server/gameconnection.py index a1e128279..2f3d9f6b1 100644 --- a/server/gameconnection.py +++ b/server/gameconnection.py @@ -505,7 +505,7 @@ async def handle_game_ended(self, *args: list[Any]): self.finished_sim = True await self.game.check_game_finish(self.player) - async def handle_rehost(self, *args: list[Any]): + async def handle_rehost(self, *args: Any): """ Signals that the user has rehosted the game. This is currently unused but included for documentation purposes. @@ -519,26 +519,35 @@ async def handle_launch_status(self, status: str): """ pass - async def handle_bottleneck(self, *args: list[Any]): + async def handle_bottleneck(self, code: str, *args: str): """ - Not sure what this command means. This is currently unused but - included for documentation purposes. + Not entirely sure what this command means. Seems to be sent when a + player is getting behind on data, slowing down the game. + + Example: + ```python + { + "command": "Bottleneck", + "target": "game", + "args": ["data", "19508", "517268,516974,344419", "5980.1"], + } + ``` """ - pass + self._logger.debug("Bottleneck: %s", list((code, *args))) - async def handle_bottleneck_cleared(self, *args: list[Any]): + async def handle_bottleneck_cleared(self): """ - Not sure what this command means. This is currently unused but - included for documentation purposes. + Not entirely sure what this command means. Probably sent when the game + is no longer being slowed down due to players being behind on data. """ - pass + self._logger.debug("BottleneckCleared") - async def handle_disconnected(self, *args: list[Any]): + async def handle_disconnected(self, *args: Any): """ Not sure what this command means. This is currently unused but included for documentation purposes. """ - pass + self._logger.debug("Disconnected: %s", list(args)) async def handle_chat(self, message: str): """ diff --git a/tests/unit_tests/test_gameconnection.py b/tests/unit_tests/test_gameconnection.py index 26c47a230..f39b9facb 100644 --- a/tests/unit_tests/test_gameconnection.py +++ b/tests/unit_tests/test_gameconnection.py @@ -350,6 +350,34 @@ async def test_handle_action_AIOption_not_host( game.set_ai_option.assert_not_called() +async def test_handle_action_Bottleneck(game_connection: GameConnection): + args = ["ack", "17654", "466996,436136,443631,402513,302866", "14222.5"] + await game_connection.handle_action("Bottleneck", args) + await game_connection.handle_bottleneck(*args) + + # 517268,516974,344419 are the player ids of other players (not the sender) + # 5980.1 is an increasing value, maybe total data sent? + args = ["data", "19508", "517268,516974,344419", "5980.1"] + await game_connection.handle_action("Bottleneck", args) + await game_connection.handle_bottleneck(*args) + + args = ["readiness", "1", "234112", "5220.7"] + await game_connection.handle_action("Bottleneck", args) + await game_connection.handle_bottleneck(*args) + + +async def test_handle_action_BottleneckCleared(game_connection: GameConnection): + args = [] + await game_connection.handle_action("BottleneckCleared", args) + await game_connection.handle_bottleneck_cleared(*args) + + +async def test_handle_action_Chat(game_connection: GameConnection): + args = ["Hello World!"] + await game_connection.handle_action("Chat", args) + await game_connection.handle_chat(*args) + + async def test_handle_action_ClearSlot( game: Game, game_connection: GameConnection @@ -370,6 +398,18 @@ async def test_handle_action_ClearSlot_not_host( game.clear_slot.assert_not_called() +async def test_handle_action_Disconnected(game_connection: GameConnection): + args = ["foo", "bar"] + await game_connection.handle_action("Disconnected", args) + await game_connection.handle_disconnected(*args) + + +async def test_handle_action_GameFull(game_connection: GameConnection): + args = [] + await game_connection.handle_action("GameFull", args) + await game_connection.handle_game_full(*args) + + async def test_handle_action_GameResult_calls_add_result( game: Game, game_connection: GameConnection @@ -491,6 +531,12 @@ async def test_handle_action_EnforceRating( assert game.enforce_rating is True +async def test_handle_action_Rehost(game_connection: GameConnection): + args = ["foo", "bar"] + await game_connection.handle_action("Rehost", args) + await game_connection.handle_rehost(*args) + + async def test_handle_action_TeamkillReport( game: Game, game_connection: GameConnection, @@ -722,19 +768,6 @@ async def test_handle_action_IceMsg_for_non_connected( await game_connection.handle_action("IceMsg", [2, "the message"]) -@pytest.mark.parametrize("action", ( - "Rehost", - "Bottleneck", - "BottleneckCleared", - "Disconnected", - "Chat", - "GameFull" -)) -async def test_handle_action_ignored(game_connection: GameConnection, action): - # No exceptions raised - await game_connection.handle_action(action, []) - - async def test_handle_action_invalid(game_connection: GameConnection): game_connection.abort = mock.AsyncMock()