This commit is contained in:
Chris Forbes
2009-12-01 18:29:24 +13:00
parent 1b8208892d
commit 116f7d3b53
2 changed files with 34 additions and 39 deletions

View File

@@ -24,11 +24,8 @@ namespace OpenRA.Server
for (; ; ) for (; ; )
{ {
var checkRead = new ArrayList(); var checkRead = new ArrayList();
var checkWrite = new ArrayList();
var checkError = new ArrayList();
checkRead.Add(listener.Server); checkRead.Add(listener.Server);
foreach (var c in conns) foreach (var c in conns) checkRead.Add(c.socket);
checkRead.Add(c.socket);
Socket.Select(checkRead, null, null, 1000000 /* 1s */); Socket.Select(checkRead, null, null, 1000000 /* 1s */);
@@ -45,6 +42,7 @@ namespace OpenRA.Server
{ {
var newConn = new Connection { socket = listener.AcceptSocket() }; var newConn = new Connection { socket = listener.AcceptSocket() };
newConn.socket.Blocking = false; newConn.socket.Blocking = false;
newConn.socket.NoDelay = true;
conns.Add(newConn); conns.Add(newConn);
/* todo: assign a player number, setup host behavior, etc */ /* todo: assign a player number, setup host behavior, etc */
@@ -94,8 +92,8 @@ namespace OpenRA.Server
{ {
case ReceiveState.Header: case ReceiveState.Header:
{ {
conn.ExpectLength = BitConverter.ToInt32(bytes, 4) - 4;
conn.Frame = BitConverter.ToInt32(bytes, 0); conn.Frame = BitConverter.ToInt32(bytes, 0);
conn.ExpectLength = BitConverter.ToInt32(bytes, 4);
conn.State = ReceiveState.Data; conn.State = ReceiveState.Data;
} break; } break;
@@ -119,8 +117,8 @@ namespace OpenRA.Server
try try
{ {
c.socket.Blocking = true; c.socket.Blocking = true;
c.socket.Send(BitConverter.GetBytes(data.Length + 4));
c.socket.Send(BitConverter.GetBytes(frame)); c.socket.Send(BitConverter.GetBytes(frame));
c.socket.Send(BitConverter.GetBytes(data.Length));
c.socket.Send(data); c.socket.Send(data);
c.socket.Blocking = false; c.socket.Blocking = false;
} }

View File

@@ -108,12 +108,11 @@ namespace OpenRa.Game
{ {
try try
{ {
uint fn; var len = replayReader.ReadInt32() - 4;
var frame = replayReader.ReadInt32();
var ret = replayReader.ReadBytes( len ).ToOrderList();
var len = replayReader.ReadInt32(); if( frameNumber != frame )
var ret = replayReader.ReadBytes( len ).ToOrderList( out fn );
if( frameNumber != fn )
throw new InvalidOperationException( "Attempted time-travel in OrdersForFrame (replay)" ); throw new InvalidOperationException( "Attempted time-travel in OrdersForFrame (replay)" );
return ret; return ret;
@@ -135,7 +134,7 @@ namespace OpenRa.Game
int nextLocalOrderFrame = 1; int nextLocalOrderFrame = 1;
TcpClient socket; TcpClient socket;
Dictionary<int, byte[]> orderBuffers = new Dictionary<int, byte[]>(); Dictionary<int, List<byte[]>> orderBuffers = new Dictionary<int, List<byte[]>>();
public NetworkOrderSource( TcpClient socket ) public NetworkOrderSource( TcpClient socket )
{ {
@@ -143,43 +142,42 @@ namespace OpenRa.Game
this.socket.NoDelay = true; this.socket.NoDelay = true;
var reader = new BinaryReader( socket.GetStream() ); var reader = new BinaryReader( socket.GetStream() );
var nextFrameId = BitConverter.GetBytes( nextLocalOrderFrame );
socket.GetStream().Write( nextFrameId, 0, nextFrameId.Length );
new Thread( () => new Thread( () =>
{ {
var firstFrameNum = reader.ReadInt32(); for (; ; )
if( firstFrameNum != 0 )
throw new InvalidOperationException( "Wrong frame number at start of stream" );
var currentFrame = 0;
var ret = new List<Order>();
while( true )
{ {
var len = reader.ReadInt32(); var len = reader.ReadInt32();
var buf = reader.ReadBytes( len ); var frame = reader.ReadInt32();
var buf = reader.ReadBytes(len - 4);
lock (orderBuffers) lock (orderBuffers)
orderBuffers[ currentFrame ] = buf; {
++currentFrame; /* accumulate this chunk */
if (orderBuffers[frame] == null)
orderBuffers[frame] = new List<byte[]>();
orderBuffers[frame].Add(buf);
}
} }
} ) { IsBackground = true }.Start(); } ) { IsBackground = true }.Start();
} }
static List<byte[]> NoOrders = new List<byte[]>();
List<byte[]> ExtractOrders(int frame)
{
lock (orderBuffers)
{
List<byte[]> result;
return orderBuffers.TryGetValue(frame, out result)
? result : NoOrders;
}
}
public List<Order> OrdersForFrame( int currentFrame ) public List<Order> OrdersForFrame( int currentFrame )
{ {
// TODO: prune `orderBuffers` based on currentFrame. var orderData = ExtractOrders(currentFrame);
byte[] orderBuffer; /* todo: immediate orders hooked in here? */
lock( orderBuffers )
orderBuffer = orderBuffers[ currentFrame ];
uint frameNumber; return orderData.SelectMany(a => a.ToOrderList()).ToList();
var ret = orderBuffer.ToOrderList( out frameNumber );
if( frameNumber != currentFrame )
throw new InvalidOperationException( "Attempted time-travel in OrdersForFrame (network)" );
return ret;
} }
public void SendLocalOrders( int localFrame, List<Order> localOrders ) public void SendLocalOrders( int localFrame, List<Order> localOrders )
@@ -223,11 +221,10 @@ namespace OpenRa.Game
ms.WriteTo( s ); ms.WriteTo( s );
} }
public static List<Order> ToOrderList( this byte[] bytes, out uint frameNumber ) public static List<Order> ToOrderList( this byte[] bytes )
{ {
var ms = new MemoryStream( bytes ); var ms = new MemoryStream( bytes );
var reader = new BinaryReader( ms ); var reader = new BinaryReader( ms );
frameNumber = reader.ReadUInt32();
var ret = new List<Order>(); var ret = new List<Order>();
while( ms.Position < ms.Length ) while( ms.Position < ms.Length )
ret.Add( Order.Deserialize( reader ) ); ret.Add( Order.Deserialize( reader ) );