From f8127ab9dfdd38be43dcdbf6750fbe14b39ba224 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Sat, 24 Dec 2011 20:55:18 +1300 Subject: [PATCH] don't start writing replays until gamestart --- .../Network/ReplayRecorderConnection.cs | 41 +++++++++++++++---- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/OpenRA.Game/Network/ReplayRecorderConnection.cs b/OpenRA.Game/Network/ReplayRecorderConnection.cs index 4e86039efb..c7aba98b6b 100644 --- a/OpenRA.Game/Network/ReplayRecorderConnection.cs +++ b/OpenRA.Game/Network/ReplayRecorderConnection.cs @@ -21,24 +21,27 @@ namespace OpenRA.Network IConnection inner; BinaryWriter writer; Func chooseFilename; + MemoryStream preStartBuffer = new MemoryStream(); public ReplayRecorderConnection( IConnection inner, Func chooseFilename ) { this.chooseFilename = chooseFilename; this.inner = inner; - StartSavingReplay(); + writer = new BinaryWriter(preStartBuffer); } - void StartSavingReplay() + void StartSavingReplay(byte[] initialContent) { var filename = chooseFilename(); - var replayPath = Path.Combine( Platform.SupportDir, "Replays" ); + var replayPath = Path.Combine(Platform.SupportDir, "Replays"); if (!Directory.Exists(replayPath)) Directory.CreateDirectory(replayPath); - this.writer = new BinaryWriter(File.Create(Path.Combine(replayPath, filename))); + var file = File.Create(Path.Combine(replayPath, filename)); + file.Write(initialContent); + this.writer = new BinaryWriter(file); } public int LocalClientId { get { return inner.LocalClientId; } } @@ -50,15 +53,35 @@ namespace OpenRA.Network public void Receive( Action packetFn ) { - inner.Receive( ( client, data ) => + inner.Receive((client, data) => { - writer.Write( client ); - writer.Write( data.Length ); - writer.Write( data ); - packetFn( client, data ); + if (preStartBuffer != null && IsGameStart(data)) + { + writer.Flush(); + var preStartData = preStartBuffer.ToArray(); + preStartBuffer = null; + StartSavingReplay(preStartData); + } + + writer.Write(client); + writer.Write(data.Length); + writer.Write(data); + packetFn(client, data); } ); } + bool IsGameStart(byte[] data) + { + if (data.Length == 5 && data[4] == 0xbf) + return false; + if (data.Length >= 5 && data[4] == 0x65) + return false; + + var frame = BitConverter.ToInt32(data, 0); + return frame == 0 && data.ToOrderList(null).Any( + o => o.OrderString == "StartGame"); + } + bool disposed; public void Dispose()