fix: improve minigame reconnect flow
This commit is contained in:
@@ -192,6 +192,67 @@ namespace XWorld.Server.Gateway.Tests
|
||||
Assert.Contains(Frames(c), f => f.Channel == Channel.Framework && f.Opcode == (ushort)FrameworkOpcode.Error);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatchCancel_AfterRoomCreated_ClearsRoomAndAllowsPlayerToMatchAgain()
|
||||
{
|
||||
var loop = NewLoop(matchTimeoutTicks: 0);
|
||||
var c = new FakeConnection(5);
|
||||
loop.Submit(new ConnectCommand { PlayerId = 5, Connection = c });
|
||||
loop.Submit(new FrameCommand { PlayerId = 5, Frame = FrameworkFrame(FrameworkOpcode.RandomMatchRequest) });
|
||||
loop.DrainAndTick(1f);
|
||||
|
||||
Assert.True(HasMatchFound(c), "precondition: player should be in a room before cancel");
|
||||
|
||||
c.Sent.Clear();
|
||||
loop.Submit(new FrameCommand { PlayerId = 5, Frame = FrameworkFrame(FrameworkOpcode.MatchCancel) });
|
||||
loop.DrainAndTick(1f);
|
||||
|
||||
loop.Submit(new FrameCommand { PlayerId = 5, Frame = FrameworkFrame(FrameworkOpcode.RandomMatchRequest) });
|
||||
loop.DrainAndTick(1f);
|
||||
|
||||
Assert.Contains(Frames(c), f => f.Channel == Channel.Framework && f.Opcode == (ushort)FrameworkOpcode.MatchAssigned);
|
||||
Assert.DoesNotContain(Frames(c), f =>
|
||||
f.Channel == Channel.Framework &&
|
||||
f.Opcode == (ushort)FrameworkOpcode.Error &&
|
||||
ErrorMsg.Decode(f.Payload).Message == "already in room or queue");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatchCancel_InTwoPlayerRoom_ClearsRoomForAllPlayers()
|
||||
{
|
||||
var loop = NewLoop(matchTimeoutTicks: 100);
|
||||
var c1 = new FakeConnection(1);
|
||||
var c2 = new FakeConnection(2);
|
||||
loop.Submit(new ConnectCommand { PlayerId = 1, Connection = c1 });
|
||||
loop.Submit(new ConnectCommand { PlayerId = 2, Connection = c2 });
|
||||
loop.Submit(new FrameCommand { PlayerId = 1, Frame = FrameCodec.Decode(RpsJoinFrame()) });
|
||||
loop.Submit(new FrameCommand { PlayerId = 2, Frame = FrameCodec.Decode(RpsJoinFrame()) });
|
||||
loop.DrainAndTick(1f);
|
||||
|
||||
Assert.True(HasMatchFound(c1), "precondition: player 1 should be in a room before cancel");
|
||||
Assert.True(HasMatchFound(c2), "precondition: player 2 should be in a room before cancel");
|
||||
|
||||
c1.Sent.Clear();
|
||||
c2.Sent.Clear();
|
||||
loop.Submit(new FrameCommand { PlayerId = 1, Frame = FrameworkFrame(FrameworkOpcode.MatchCancel) });
|
||||
loop.DrainAndTick(1f);
|
||||
|
||||
loop.Submit(new FrameCommand { PlayerId = 1, Frame = FrameCodec.Decode(RpsJoinFrame()) });
|
||||
loop.Submit(new FrameCommand { PlayerId = 2, Frame = FrameCodec.Decode(RpsJoinFrame()) });
|
||||
loop.DrainAndTick(1f);
|
||||
|
||||
Assert.True(HasMatchFound(c1), "player 1 should be able to match again after cancel");
|
||||
Assert.True(HasMatchFound(c2), "player 2 should be able to match again after the room was cancelled");
|
||||
Assert.DoesNotContain(Frames(c1), f =>
|
||||
f.Channel == Channel.Framework &&
|
||||
f.Opcode == (ushort)FrameworkOpcode.Error &&
|
||||
ErrorMsg.Decode(f.Payload).Message == "already in room or queue");
|
||||
Assert.DoesNotContain(Frames(c2), f =>
|
||||
f.Channel == Channel.Framework &&
|
||||
f.Opcode == (ushort)FrameworkOpcode.Error &&
|
||||
ErrorMsg.Decode(f.Payload).Message == "already in room or queue");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Player 1 disconnects while still queued (before match forms).
|
||||
/// DrainAndTick processes the DisconnectCommand (which dequeues pid=1) BEFORE Poll,
|
||||
|
||||
Reference in New Issue
Block a user