#4036 closed defect (fixed)
[PATCH] Unknown player has rejoined
Reported by: | elexis | Owned by: | elexis |
---|---|---|---|
Priority: | Must Have | Milestone: | Alpha 22 |
Component: | Network | Keywords: | patch |
Cc: | Patch: |
Description
Sometimes when two clients join simultaneously, it might show "Unkown player has rejoined" or "Bad connection to Unknown Player". This is due to g_Players
not being updated.
The server must likely either send another player-assignment netmessage or must process existing messages correctly in the loading screen.
The bug exists at least since alpha 19.
Attachments (2)
Change History (8)
by , 7 years ago
Attachment: | 0001-Network-server-cleanup.patch added |
---|
Removes the peculiarity of Broadcast
.
by , 7 years ago
Attachment: | 0002-Send-player-assignment-updates-to-rejoining-clients-.patch added |
---|
Fixes the actual bug.
comment:2 by , 7 years ago
Keywords: | patch review added |
---|---|
Milestone: | Backlog → Alpha 22 |
Summary: | Unknown player has rejoined → [PATCH] Unknown player has rejoined |
comment:4 by , 7 years ago
(The new Broadcast
could also be used instead of SendMessage
in KickPlayer
. All other SendMessage
calls don't apply.)
comment:6 by , 7 years ago
Keywords: | review removed |
---|
Note:
See TracTickets
for help on using tickets.
TLDR:
Broadcast
doesn't broadcast to rejoining clients, thus those don't receive playerassignment updates.Observeration: In alpha 21 the bug has shapeshifted and besides showing an unknown player having rejoined, it also throws the following error stack when that client posts chat:
On some event, the server sends the new player assignments, so the unknown player becomes identified and is displayed as "has rejoined" (when that feels to have occured long before). After that, the errorspam stops.
Blackbox analysis: Obviously the player GUID isn't found in the player assignments, meaning that the player assignments have not been sent to the rejoined client that experiences these error messages. As the bug only occurs to players who were rejoined when the other client has also rejoined simultaneously, it must mean that the server sends the player assignments message only when new client start to rejoin, but not when the rejoin has finished.
Whitebox analysis:
SendPlayerAssignments
is sent fromAddPlayer
,RemovePlayer
,SetPlayerReady
,ClearAllPlayerReady
,AssignPlayer
andStartGame
.AddPlayer
is only called fromOnUserJoin
which is only called fromOnAuthenticate
, which is called immediately after the rejoin was requested. TheReady
andStartGame
messages are never sent in running games. When some other client joins or leaves,AddPlayer
andRemovePlayer
will trigger a player assignment update and thus fix the bug, matching the observation.Reproduce:
Client 1 is getting the undefined player rejoin message and errors if that other player types chat.
Cause: The server does call
SendPlayerAssignments
which doesBroadcast
the message. ButBroadcast
skips all clients that are not inNSS_PREGAME
orNSS_INGAME
. Since our rejoining client 1 is in the stateNSS_JOIN_SYNCING
, it will not receive that message.Origin: The peculiarity must come from the way rejoins work: Rejoining clients don't receive any simulation commands until they have finished deserializing.
(When the client starts to rejoin
ReallyStartGame
fromGame.cpp
it first deserializes the savestate, then callsLoadFinished()
fromNetClient.cpp
to send theNMT_LOADED_GAME
message to the server who responds with sending the simulation commands of all clients from the turn nr of the deserialized state to the current turn inOnJoinSyncingLoadedGame
.)Resolution: A function like
Broadcast
should be more general and by default send to all clients that passed the handshake. Otherwise the receiving clients should be selected wisely and explicitly by the caller.