diff --git a/Source/Common/PlayerManager.cs b/Source/Common/PlayerManager.cs index ab394fd7..cc3da928 100644 --- a/Source/Common/PlayerManager.cs +++ b/Source/Common/PlayerManager.cs @@ -71,6 +71,12 @@ public void SetDisconnected(ConnectionBase conn, MpDisconnectReason reason) ServerPlayer player = conn.serverPlayer; Players.Remove(player); + if (player.IsHost && server.worldData.CreatingJoinPoint) + { + server.worldData.AbortJoinPointCreation(); + ServerLog.Log("Aborted join point creation because the host disconnected."); + } + if (player.hasJoined) { // Send PlayerCount command to remove the player from their last known map diff --git a/Source/Common/WorldData.cs b/Source/Common/WorldData.cs index 06d88f07..a76e18df 100644 --- a/Source/Common/WorldData.cs +++ b/Source/Common/WorldData.cs @@ -52,6 +52,17 @@ public void EndJoinPointCreation() tmpMapCmds = null; lastJoinPointAtWorkTicks = Server.workTicks; dataSource!.SetResult(this); + dataSource = null; + } + + public void AbortJoinPointCreation() + { + if (!CreatingJoinPoint) + return; + + tmpMapCmds = null; + dataSource?.SetResult(this); + dataSource = null; } public Task WaitJoinPoint() diff --git a/Source/Tests/ServerTest.cs b/Source/Tests/ServerTest.cs index b8fbab89..a8450859 100644 --- a/Source/Tests/ServerTest.cs +++ b/Source/Tests/ServerTest.cs @@ -45,6 +45,31 @@ public void Test() } } + [Test] + public async Task JoinPointAbortUnblocksWaiters() + { + var server = new MultiplayerServer(new ServerSettings + { + gameName = "Test", + direct = false, + lan = false + }); + + Assert.That(server.worldData.TryStartJoinPointCreation(true), Is.True); + Assert.That(server.worldData.CreatingJoinPoint, Is.True); + + var waitTask = server.worldData.WaitJoinPoint(); + Assert.That(waitTask.IsCompleted, Is.False); + + server.worldData.AbortJoinPointCreation(); + + var completed = await waitTask.WaitAsync(TimeSpan.FromSeconds(1)); + + Assert.That(completed, Is.SameAs(server.worldData)); + Assert.That(server.worldData.CreatingJoinPoint, Is.False); + Assert.That(server.worldData.WaitJoinPoint().IsCompleted, Is.True); + } + private void ConnectClient(int port) { var clientListener = new TestNetListener();