Fix desync handling

This commit is contained in:
tomas
2022-03-15 19:59:00 +01:00
committed by Matthias Mailänder
parent dab8ee4f94
commit 8e19463450
3 changed files with 25 additions and 8 deletions

View File

@@ -100,9 +100,9 @@ namespace OpenRA.Network
{ {
public readonly ConnectionTarget Target; public readonly ConnectionTarget Target;
internal ReplayRecorder Recorder { get; private set; } internal ReplayRecorder Recorder { get; private set; }
readonly List<byte[]> queuedSyncPackets = new List<byte[]>();
readonly Queue<(int Frame, int SyncHash, ulong DefeatState)> sentSync = new Queue<(int, int, ulong)>(); readonly Queue<(int Frame, int SyncHash, ulong DefeatState)> sentSync = new Queue<(int, int, ulong)>();
readonly Queue<(int Frame, int SyncHash, ulong DefeatState)> queuedSyncPackets = new Queue<(int, int, ulong)>();
readonly Queue<(int Frame, OrderPacket Orders)> sentOrders = new Queue<(int, OrderPacket)>(); readonly Queue<(int Frame, OrderPacket Orders)> sentOrders = new Queue<(int, OrderPacket)>();
readonly Queue<OrderPacket> sentImmediateOrders = new Queue<OrderPacket>(); readonly Queue<OrderPacket> sentImmediateOrders = new Queue<OrderPacket>();
readonly ConcurrentQueue<(int FromClient, byte[] Data)> receivedPackets = new ConcurrentQueue<(int, byte[])>(); readonly ConcurrentQueue<(int FromClient, byte[] Data)> receivedPackets = new ConcurrentQueue<(int, byte[])>();
@@ -244,13 +244,12 @@ namespace OpenRA.Network
void IConnection.SendSync(int frame, int syncHash, ulong defeatState) void IConnection.SendSync(int frame, int syncHash, ulong defeatState)
{ {
var sync = (frame, syncHash, defeatState);
sentSync.Enqueue(sync);
// Send sync packets together with the next set of orders. // Send sync packets together with the next set of orders.
// This was originally explained as reducing network bandwidth // This was originally explained as reducing network bandwidth
// (TCP overhead?), but the original discussions have been lost to time. // (TCP overhead?), but the original discussions have been lost to time.
queuedSyncPackets.Add(OrderIO.SerializeSync(sync)); // Add the sync packets to the send queue before adding them to the local sync queue in the Send() method.
// Otherwise the client will process the local sync queue before sending the packet.
queuedSyncPackets.Enqueue((frame, syncHash, defeatState));
} }
void Send(byte[] packet) void Send(byte[] packet)
@@ -261,10 +260,14 @@ namespace OpenRA.Network
ms.WriteArray(BitConverter.GetBytes(packet.Length)); ms.WriteArray(BitConverter.GetBytes(packet.Length));
ms.WriteArray(packet); ms.WriteArray(packet);
foreach (var q in queuedSyncPackets) foreach (var s in queuedSyncPackets)
{ {
var q = OrderIO.SerializeSync(s);
ms.WriteArray(BitConverter.GetBytes(q.Length)); ms.WriteArray(BitConverter.GetBytes(q.Length));
ms.WriteArray(q); ms.WriteArray(q);
sentSync.Enqueue(s);
} }
queuedSyncPackets.Clear(); queuedSyncPackets.Clear();

View File

@@ -59,6 +59,7 @@ namespace OpenRA.Network
bool generateSyncReport = false; bool generateSyncReport = false;
int sentOrdersFrame = 0; int sentOrdersFrame = 0;
float tickScale = 1f; float tickScale = 1f;
bool outOfSync = false;
public struct ClientOrder public struct ClientOrder
{ {
@@ -73,8 +74,14 @@ namespace OpenRA.Network
void OutOfSync(int frame) void OutOfSync(int frame)
{ {
if (outOfSync)
return;
syncReport.DumpSyncReport(frame); syncReport.DumpSyncReport(frame);
throw new InvalidOperationException($"Out of sync in frame {frame}.\n Compare syncreport.log with other players."); World.OutOfSync();
outOfSync = true;
TextNotificationsManager.AddSystemLine($"Out of sync in frame {frame}.\nCompare syncreport.log with other players.");
} }
public void StartGame() public void StartGame()

View File

@@ -598,6 +598,13 @@ namespace OpenRA
Game.FinishBenchmark(); Game.FinishBenchmark();
} }
public void OutOfSync()
{
EndGame();
SetPauseState(true);
PauseStateLocked = true;
}
} }
public readonly struct TraitPair<T> : IEquatable<TraitPair<T>> public readonly struct TraitPair<T> : IEquatable<TraitPair<T>>