diff options
Diffstat (limited to 'Minecraft.Client/PendingConnection.cpp')
| -rw-r--r-- | Minecraft.Client/PendingConnection.cpp | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/Minecraft.Client/PendingConnection.cpp b/Minecraft.Client/PendingConnection.cpp index 29ab7c28..839cd550 100644 --- a/Minecraft.Client/PendingConnection.cpp +++ b/Minecraft.Client/PendingConnection.cpp @@ -190,9 +190,34 @@ void PendingConnection::handleLogin(shared_ptr<LoginPacket> packet) } else if (duplicateXuid) { - // if same XUID already in use by another player so disconnect this one. - app.DebugPrintf("Rejecting duplicate xuid for name: %ls\n", name.c_str()); - disconnect(DisconnectPacket::eDisconnect_Banned); + // The old player is still in PlayerList (disconnect hasn't been + // processed yet). Force-close the stale connection so the + // reconnecting client isn't rejected. + app.DebugPrintf("RECONNECT: Duplicate xuid for name: %ls, forcing old connection closed\n", name.c_str()); + shared_ptr<ServerPlayer> stalePlayer = server->getPlayers()->getPlayer(loginXuid); + if (stalePlayer == nullptr && packet->m_onlineXuid != INVALID_XUID) + stalePlayer = server->getPlayers()->getPlayer(packet->m_onlineXuid); + + if (stalePlayer != nullptr && stalePlayer->connection != nullptr) + { + BYTE oldSmallId = 0; + if (stalePlayer->connection->connection != nullptr && stalePlayer->connection->connection->getSocket() != nullptr) + oldSmallId = stalePlayer->connection->connection->getSocket()->getSmallId(); + app.DebugPrintf("RECONNECT: Force-disconnecting old player smallId=%d\n", oldSmallId); + stalePlayer->connection->disconnect(DisconnectPacket::eDisconnect_Closed); + + // Queue the old SmallId for recycling so it's not permanently leaked. + // PlayerList::tick() will call PushFreeSmallId/ClearSocketForSmallId. + if (oldSmallId != 0) + server->getPlayers()->queueSmallIdForRecycle(oldSmallId); + + app.DebugPrintf("RECONNECT: Old player force-disconnect complete\n"); + } + + // Accept the login now that the old entry is removed. + app.DebugPrintf("RECONNECT: Calling handleAcceptedLogin for new connection\n"); + handleAcceptedLogin(packet); + app.DebugPrintf("RECONNECT: handleAcceptedLogin complete\n"); } #ifdef _WINDOWS64 else if (g_bRejectDuplicateNames) |
