Skip to content

Commit 7f9a439

Browse files
Fix NPE and lobby spam on unregistered peer disconnects (#10453)
Any TCP connection that drops on the game-server port before completing Forge's registration handshake (probes, crashed handshakes, failed rejoins) triggered an NPE in ServerGameLobby.disconnectPlayer and broadcast "null left the lobby." to real users. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 8975a57 commit 7f9a439

2 files changed

Lines changed: 9 additions & 2 deletions

File tree

forge-gui/src/main/java/forge/gamemodes/net/server/FServerManager.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -945,11 +945,15 @@ public void run() {
945945
String.format("%s disconnected. Waiting %s for reconnect...", username, formatTime(RECONNECT_TIMEOUT_SECONDS))));
946946
lobbyListener.message(null, "(Host can use /skipreconnect to replace disconnected player with AI, or /skiptimeout to wait indefinitely.)");
947947
netLog.info("[Disconnect] Player disconnected mid-game: {} (slot {}). Waiting for reconnect.", username, playerIndex);
948-
} else {
949-
// Normal disconnect (lobby or no valid slot)
948+
} else if (client.hasValidSlot()) {
949+
// Peer completed registration but match isn't active (or slot was freed earlier)
950950
localLobby.disconnectPlayer(playerIndex);
951951
broadcast(new MessageEvent(String.format("%s left the lobby.", username)));
952952
broadcast(new LogoutEvent(username));
953+
} else {
954+
// Peer disconnected before completing registration — probe, crashed handshake, or rejection
955+
netLog.info("[Disconnect] Unregistered peer disconnected from {}",
956+
ctx.channel().remoteAddress());
953957
}
954958
super.channelInactive(ctx);
955959
}

forge-gui/src/main/java/forge/gamemodes/net/server/ServerGameLobby.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ private void connectPlayer(final String name, final int avatarIndex, final int s
4747
}
4848
public void disconnectPlayer(final int index) {
4949
final LobbySlot slot = getSlot(index);
50+
if (slot == null) {
51+
return;
52+
}
5053
slot.setType(LobbySlotType.OPEN);
5154
slot.setName(StringUtils.EMPTY);
5255
slot.setIsReady(false);

0 commit comments

Comments
 (0)