hax.
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 ) );
|
||||||
|
|||||||
Reference in New Issue
Block a user