sync checked between clients
This commit is contained in:
@@ -5,8 +5,9 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using OpenRa.FileFormats;
|
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
|
using OpenRa;
|
||||||
|
using OpenRa.FileFormats;
|
||||||
|
|
||||||
namespace OpenRA.Server
|
namespace OpenRA.Server
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
namespace OpenRa.FileFormats
|
namespace OpenRa
|
||||||
{
|
{
|
||||||
public static class Exts
|
public static class Exts
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -41,5 +41,18 @@ namespace OpenRa.Network
|
|||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static byte[] SerializeSync( this List<int> sync, int frameNumber )
|
||||||
|
{
|
||||||
|
var ms = new MemoryStream();
|
||||||
|
using( var writer = new BinaryWriter( ms ) )
|
||||||
|
{
|
||||||
|
writer.Write( frameNumber );
|
||||||
|
writer.Write( (byte)0x65 );
|
||||||
|
foreach( var s in sync )
|
||||||
|
writer.Write( s );
|
||||||
|
}
|
||||||
|
return ms.ToArray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,6 +67,8 @@ namespace OpenRa.Network
|
|||||||
var frame = BitConverter.ToInt32( packet, 0 );
|
var frame = BitConverter.ToInt32( packet, 0 );
|
||||||
if( packet.Length == 5 && packet[ 4 ] == 0xEF )
|
if( packet.Length == 5 && packet[ 4 ] == 0xEF )
|
||||||
readyForFrames.Add( frame );
|
readyForFrames.Add( frame );
|
||||||
|
else if( packet.Length >= 5 && packet[ 4 ] == 0x65 )
|
||||||
|
CheckSync( packet );
|
||||||
else if( frame == 0 )
|
else if( frame == 0 )
|
||||||
immediatePackets.Add( packet );
|
immediatePackets.Add( packet );
|
||||||
else
|
else
|
||||||
@@ -78,6 +80,30 @@ namespace OpenRa.Network
|
|||||||
UnitOrders.ProcessOrder( o );
|
UnitOrders.ProcessOrder( o );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Dictionary<int, byte[]> syncForFrame = new Dictionary<int, byte[]>();
|
||||||
|
|
||||||
|
void CheckSync( byte[] packet )
|
||||||
|
{
|
||||||
|
var frame = BitConverter.ToInt32( packet, 0 );
|
||||||
|
byte[] existingSync;
|
||||||
|
if( syncForFrame.TryGetValue( frame, out existingSync ) )
|
||||||
|
{
|
||||||
|
if( packet.Length != existingSync.Length )
|
||||||
|
OutOfSync( frame );
|
||||||
|
else
|
||||||
|
for( int i = 0 ; i < packet.Length ; i++ )
|
||||||
|
if( packet[ i ] != existingSync[ i ] )
|
||||||
|
OutOfSync( frame );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
syncForFrame.Add( frame, packet );
|
||||||
|
}
|
||||||
|
|
||||||
|
void OutOfSync( int frame )
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException( "out of sync in frame {0}".F( frame ) );
|
||||||
|
}
|
||||||
|
|
||||||
public bool IsReadyForNextFrame
|
public bool IsReadyForNextFrame
|
||||||
{
|
{
|
||||||
get { return readyForFrames.Contains( FrameNumber ); }
|
get { return readyForFrames.Contains( FrameNumber ); }
|
||||||
@@ -93,8 +119,18 @@ namespace OpenRa.Network
|
|||||||
localOrders.Clear();
|
localOrders.Clear();
|
||||||
|
|
||||||
var frameData = frameClientData[ FrameNumber ];
|
var frameData = frameClientData[ FrameNumber ];
|
||||||
|
var sync = new List<int>();
|
||||||
|
sync.Add( world.SyncHash() );
|
||||||
|
|
||||||
foreach( var order in frameData.OrderBy( p => p.Key ).SelectMany( o => o.Value.ToOrderList( world ) ) )
|
foreach( var order in frameData.OrderBy( p => p.Key ).SelectMany( o => o.Value.ToOrderList( world ) ) )
|
||||||
|
{
|
||||||
UnitOrders.ProcessOrder( order );
|
UnitOrders.ProcessOrder( order );
|
||||||
|
sync.Add( world.SyncHash() );
|
||||||
|
}
|
||||||
|
|
||||||
|
var ss = sync.SerializeSync( FrameNumber );
|
||||||
|
CheckSync( ss );
|
||||||
|
Connection.Send( ss );
|
||||||
|
|
||||||
++frameNumber;
|
++frameNumber;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user