fix: dedicated server thread safety, disconnect deadlock, and console freeze

- Protect PlayerList and ServerConnection players vectors with critical
  sections; all iterations use copy-on-read snapshots to prevent iterator
  invalidation during concurrent join/leave
- Add null check on player bounding box in movement validation to prevent
  crash when player is removed mid-tick
- Re-validate socket player pointer immediately before SendData to narrow
  the TOCTOU race window on disconnect
- Replace inline disconnect cleanup with a queued system drained on the
  main tick thread, eliminating the done_cs -> m_playersCS lock inversion
  that caused deadlocks under load
- Disable Windows QuickEdit mode at server startup to prevent console
  input selection from freezing the process
- Move chunk priority sort behind ServerConnection::sortPlayersByChunkPriority()
  to keep the players vector lock-protected
This commit is contained in:
itsRevela
2026-04-10 01:12:59 -05:00
parent 055bce517d
commit 20229fc07b
9 changed files with 309 additions and 158 deletions
+1 -30
View File
@@ -2401,36 +2401,7 @@ void MinecraftServer::chunkPacketManagement_PreTick()
s_tickStartTime = System::currentTimeMillis();
s_sentTo.clear();
vector< shared_ptr<PlayerConnection> > *players = connection->getPlayers();
if( players->size() )
{
vector< shared_ptr<PlayerConnection> > playersOrig = *players;
players->clear();
do
{
int longestTime = 0;
auto playerConnectionBest = playersOrig.begin();
for( auto it = playersOrig.begin(); it != playersOrig.end(); it++)
{
int thisTime = 0;
INetworkPlayer *np = (*it)->getNetworkPlayer();
if( np )
{
thisTime = np->GetTimeSinceLastChunkPacket_ms();
}
if( thisTime > longestTime )
{
playerConnectionBest = it;
longestTime = thisTime;
}
}
players->push_back(*playerConnectionBest);
playersOrig.erase(playerConnectionBest);
} while ( playersOrig.size() > 0 );
}
connection->sortPlayersByChunkPriority();
}
void MinecraftServer::chunkPacketManagement_PostTick()