Skip to content

Abort join point creation when host disconnects#863

Merged
notfood merged 1 commit intorwmt:devfrom
MhaWay:server-joinpoint-reconnect
Apr 7, 2026
Merged

Abort join point creation when host disconnects#863
notfood merged 1 commit intorwmt:devfrom
MhaWay:server-joinpoint-reconnect

Conversation

@MhaWay
Copy link
Copy Markdown

@MhaWay MhaWay commented Apr 7, 2026

Summary

Abort an in-progress join point when the host disconnects so reconnect does not remain blocked in ServerLoading.

Fixes #860.

What changed

  • add WorldData.AbortJoinPointCreation() to cleanly end a pending join point wait without replacing the current world snapshot
  • abort join point creation from PlayerManager.SetDisconnected() when the disconnected player is the host
  • log the abort so server-side behavior is visible in diagnostics
  • add a regression test to verify aborting a join point unblocks waiters

Why this fixes the issue

Previously, if the host disconnected during join point creation, WorldData.CreatingJoinPoint stayed active and ServerLoading kept waiting on WaitJoinPoint(). That prevented reconnect from progressing.

After this change, disconnecting the host resets the pending join point creation and releases waiting loading states so reconnect can proceed against the last stable world snapshot.

Validation

  • dotnet build Source/Server/Server.csproj -c Release
  • ServerTest regression passes
  • selected server/common tests pass

Copilot AI review requested due to automatic review settings April 7, 2026 09:07
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a server-side escape hatch to end an in-progress join point when the host disconnects, preventing reconnects from getting stuck waiting in ServerLoading (Fixes #860).

Changes:

  • Introduces WorldData.AbortJoinPointCreation() to complete pending WaitJoinPoint() waiters without swapping the current snapshot.
  • Calls abort logic from PlayerManager.SetDisconnected() when the host disconnects during join point creation, with a diagnostic log line.
  • Adds a regression test ensuring aborting a join point unblocks WaitJoinPoint().

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
Source/Tests/ServerTest.cs Adds a regression test that verifies aborting join point creation releases waiters.
Source/Common/WorldData.cs Adds abort API and clears the join point TCS on completion/abort to unblock WaitJoinPoint().
Source/Common/PlayerManager.cs Hooks host disconnect to abort join point creation and logs the action.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 72 to +77
Players.Remove(player);

if (player.IsHost && server.worldData.CreatingJoinPoint)
{
server.worldData.AbortJoinPointCreation();
ServerLog.Log("Aborted join point creation because the host disconnected.");
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SetDisconnected aborts join point creation only when the disconnected player is IsHost. In arbiter mode, join point creation uploads are accepted only from the arbiter (Server.ArbiterPlaying ? Player.IsArbiter : Player.IsHost in ServerPlayingState.HandleWorldDataUpload), so if the arbiter disconnects during an in-progress join point the server can still remain stuck in CreatingJoinPoint and keep ServerLoadingState waiters blocked. Consider aborting when the disconnecting player is the current join point upload source (host vs arbiter), and note that you may need to capture the arbiter/host mode before Players.Remove(player) so the decision isn't affected by the removal.

Suggested change
Players.Remove(player);
if (player.IsHost && server.worldData.CreatingJoinPoint)
{
server.worldData.AbortJoinPointCreation();
ServerLog.Log("Aborted join point creation because the host disconnected.");
bool arbiterPlaying = server.ArbiterPlaying;
bool isJoinPointUploadSource = arbiterPlaying ? player.IsArbiter : player.IsHost;
Players.Remove(player);
if (isJoinPointUploadSource && server.worldData.CreatingJoinPoint)
{
server.worldData.AbortJoinPointCreation();
ServerLog.Log($"Aborted join point creation because the {(arbiterPlaying ? "arbiter" : "host")} disconnected.");

Copilot uses AI. Check for mistakes.
@MhaWay
Copy link
Copy Markdown
Author

MhaWay commented Apr 7, 2026

As i seen arbiter is not supported for standalone server(i may be wrong)

@notfood
Copy link
Copy Markdown
Member

notfood commented Apr 7, 2026

Arbiter has been disabled for a while. It causes issues, specially when evaluating camera.

@notfood notfood added fix Fixes for a bug or desync. 1.6 Fixes or bugs relating to 1.6 (Not Odyssey). labels Apr 7, 2026
@notfood notfood linked an issue Apr 7, 2026 that may be closed by this pull request
@notfood notfood merged commit aa55356 into rwmt:dev Apr 7, 2026
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

1.6 Fixes or bugs relating to 1.6 (Not Odyssey). fix Fixes for a bug or desync.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Server can deadlock reconnects while a join point is still being created

3 participants