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:
@@ -24,11 +24,26 @@ private:
|
||||
// public static Logger logger = Logger.getLogger("Minecraft");
|
||||
public:
|
||||
vector<shared_ptr<ServerPlayer> > players;
|
||||
CRITICAL_SECTION m_playersCS; // Protects players vector for concurrent access
|
||||
vector<shared_ptr<ServerPlayer> > getPlayersSnapshot();
|
||||
|
||||
private:
|
||||
MinecraftServer *server;
|
||||
unsigned int maxPlayers;
|
||||
|
||||
// Pending disconnect queue: disconnect() enqueues here, tick() drains it.
|
||||
// This avoids holding done_cs across PlayerList operations (deadlock fix).
|
||||
struct PendingDisconnect
|
||||
{
|
||||
shared_ptr<ServerPlayer> player;
|
||||
int reason;
|
||||
wstring kickMessage;
|
||||
bool wasKicked;
|
||||
bool fourKitHandledQuit;
|
||||
};
|
||||
deque<PendingDisconnect> m_pendingDisconnects;
|
||||
CRITICAL_SECTION m_disconnectCS;
|
||||
|
||||
// 4J Added
|
||||
vector<PlayerUID> m_bannedXuids;
|
||||
CRITICAL_SECTION m_banCS; // 4J Added - protects m_bannedXuids for concurrent access
|
||||
@@ -82,6 +97,7 @@ public:
|
||||
void add(shared_ptr<ServerPlayer> player);
|
||||
void move(shared_ptr<ServerPlayer> player);
|
||||
void remove(shared_ptr<ServerPlayer> player);
|
||||
void queueDisconnect(shared_ptr<ServerPlayer> player, int reason, const wstring& kickMessage, bool wasKicked, bool fourKitHandledQuit);
|
||||
shared_ptr<ServerPlayer> getPlayerForLogin(PendingConnection *pendingConnection, const wstring& userName, PlayerUID xuid, PlayerUID OnlineXuid);
|
||||
shared_ptr<ServerPlayer> respawn(shared_ptr<ServerPlayer> serverPlayer, int targetDimension, bool keepAllPlayerData);
|
||||
void toggleDimension(shared_ptr<ServerPlayer> player, int targetDimension);
|
||||
|
||||
Reference in New Issue
Block a user