Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document bottleneck messages #1046

Merged
merged 4 commits into from
Mar 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 20 additions & 11 deletions server/gameconnection.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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):
"""
Expand Down
59 changes: 46 additions & 13 deletions tests/unit_tests/test_gameconnection.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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()

Expand Down
Loading