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;
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)> queuedSyncPackets = new Queue<(int, int, ulong)>();
readonly Queue<(int Frame, OrderPacket Orders)> sentOrders = new Queue<(int, OrderPacket)>();
readonly Queue<OrderPacket> sentImmediateOrders = new Queue<OrderPacket>();
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)
{
var sync = (frame, syncHash, defeatState);
sentSync.Enqueue(sync);
// Send sync packets together with the next set of orders.
// This was originally explained as reducing network bandwidth
// (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)
@@ -261,10 +260,14 @@ namespace OpenRA.Network
ms.WriteArray(BitConverter.GetBytes(packet.Length));
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(q);
sentSync.Enqueue(s);
}
queuedSyncPackets.Clear();

View File

@@ -59,6 +59,7 @@ namespace OpenRA.Network
bool generateSyncReport = false;
int sentOrdersFrame = 0;
float tickScale = 1f;
bool outOfSync = false;
public struct ClientOrder
{
@@ -73,8 +74,14 @@ namespace OpenRA.Network
void OutOfSync(int frame)
{
if (outOfSync)
return;
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()

View File

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