aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.Client/PendingConnection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Minecraft.Client/PendingConnection.cpp')
-rw-r--r--Minecraft.Client/PendingConnection.cpp31
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)