First frame is No. 1, not 0. Order no longer needs to use that bit to signify playerness.
This commit is contained in:
@@ -31,7 +31,6 @@ namespace OpenRa.Game
|
|||||||
switch (OrderString)
|
switch (OrderString)
|
||||||
{
|
{
|
||||||
// Format:
|
// Format:
|
||||||
// u32 : player, with msb set. (if msb is clear, not an order)
|
|
||||||
// u8 : orderID.
|
// u8 : orderID.
|
||||||
// 0xFF: Full serialized order.
|
// 0xFF: Full serialized order.
|
||||||
// varies: rest of order.
|
// varies: rest of order.
|
||||||
@@ -40,8 +39,8 @@ namespace OpenRa.Game
|
|||||||
{
|
{
|
||||||
var ret = new MemoryStream();
|
var ret = new MemoryStream();
|
||||||
var w = new BinaryWriter(ret);
|
var w = new BinaryWriter(ret);
|
||||||
w.Write((uint)Player.Index | 0x80000000u);
|
w.Write( (byte)0xFF );
|
||||||
w.Write((byte)0xFF);
|
w.Write( (uint)Player.Index );
|
||||||
w.Write(OrderString);
|
w.Write(OrderString);
|
||||||
w.Write(Subject == null ? 0xFFFFFFFF : Subject.ActorID);
|
w.Write(Subject == null ? 0xFFFFFFFF : Subject.ActorID);
|
||||||
w.Write(TargetActor == null ? 0xFFFFFFFF : TargetActor.ActorID);
|
w.Write(TargetActor == null ? 0xFFFFFFFF : TargetActor.ActorID);
|
||||||
@@ -55,15 +54,13 @@ namespace OpenRa.Game
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Order Deserialize(BinaryReader r, uint first)
|
public static Order Deserialize(BinaryReader r)
|
||||||
{
|
{
|
||||||
if ((first >> 31) == 0) return null;
|
|
||||||
|
|
||||||
var player = Game.players.Where(x => x.Value.Index == (first & 0x7FFFFFFF)).First().Value;
|
|
||||||
switch (r.ReadByte())
|
switch (r.ReadByte())
|
||||||
{
|
{
|
||||||
case 0xFF:
|
case 0xFF:
|
||||||
{
|
{
|
||||||
|
var playerID = r.ReadUInt32();
|
||||||
var order = r.ReadString();
|
var order = r.ReadString();
|
||||||
var subject = ActorFromUInt(r.ReadUInt32());
|
var subject = ActorFromUInt(r.ReadUInt32());
|
||||||
var targetActor = ActorFromUInt(r.ReadUInt32());
|
var targetActor = ActorFromUInt(r.ReadUInt32());
|
||||||
@@ -72,7 +69,9 @@ namespace OpenRa.Game
|
|||||||
var targetString = null as string;
|
var targetString = null as string;
|
||||||
if (r.ReadBoolean())
|
if (r.ReadBoolean())
|
||||||
targetString = r.ReadString();
|
targetString = r.ReadString();
|
||||||
return new Order(player, order, subject, targetActor, targetLocation, targetString);
|
|
||||||
|
var player = Game.players.Where( x => x.Value.Index == playerID ).First().Value;
|
||||||
|
return new Order( player, order, subject, targetActor, targetLocation, targetString );
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ namespace OpenRa.Game
|
|||||||
{
|
{
|
||||||
class OrderManager
|
class OrderManager
|
||||||
{
|
{
|
||||||
BinaryWriter savingReplay;
|
Stream savingReplay;
|
||||||
List<OrderSource> players;
|
List<OrderSource> players;
|
||||||
int frameNumber = 0;
|
int frameNumber = 1;
|
||||||
|
|
||||||
const int FramesAhead = 3;
|
const int FramesAhead = 3;
|
||||||
|
|
||||||
@@ -22,14 +22,14 @@ namespace OpenRa.Game
|
|||||||
this.players = players.ToList();
|
this.players = players.ToList();
|
||||||
|
|
||||||
foreach( var p in this.players )
|
foreach( var p in this.players )
|
||||||
for( int i = 0 ; i < FramesAhead ; i++ )
|
for( int i = 1 ; i <= FramesAhead ; i++ )
|
||||||
p.SendLocalOrders( i, new List<Order>() );
|
p.SendLocalOrders( i, new List<Order>() );
|
||||||
}
|
}
|
||||||
|
|
||||||
public OrderManager( IEnumerable<OrderSource> players, string replayFilename )
|
public OrderManager( IEnumerable<OrderSource> players, string replayFilename )
|
||||||
: this( players )
|
: this( players )
|
||||||
{
|
{
|
||||||
savingReplay = new BinaryWriter( new FileStream( replayFilename, FileMode.Create ) );
|
savingReplay = new FileStream( replayFilename, FileMode.Create );
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsReadyForNextFrame
|
public bool IsReadyForNextFrame
|
||||||
@@ -50,16 +50,12 @@ namespace OpenRa.Game
|
|||||||
foreach( var p in players )
|
foreach( var p in players )
|
||||||
p.SendLocalOrders( frameNumber + FramesAhead, localOrders );
|
p.SendLocalOrders( frameNumber + FramesAhead, localOrders );
|
||||||
|
|
||||||
if( savingReplay != null )
|
var allOrders = players.SelectMany(p => p.OrdersForFrame(frameNumber)).OrderBy(o => o.Player.Index).ToList();
|
||||||
savingReplay.Write( frameNumber );
|
|
||||||
|
|
||||||
var allOrders = players.SelectMany(p => p.OrdersForFrame(frameNumber)).OrderBy(o => o.Player.Index);
|
|
||||||
foreach (var order in allOrders)
|
foreach (var order in allOrders)
|
||||||
{
|
|
||||||
UnitOrders.ProcessOrder(order);
|
UnitOrders.ProcessOrder(order);
|
||||||
if (savingReplay != null)
|
|
||||||
savingReplay.Write(order.Serialize());
|
if( savingReplay != null )
|
||||||
}
|
savingReplay.WriteFrameData( allOrders, frameNumber );
|
||||||
|
|
||||||
++frameNumber;
|
++frameNumber;
|
||||||
// sanity check on the framenumber. This is 2^31 frames maximum, or multiple *years* at 40ms/frame.
|
// sanity check on the framenumber. This is 2^31 frames maximum, or multiple *years* at 40ms/frame.
|
||||||
@@ -104,32 +100,27 @@ namespace OpenRa.Game
|
|||||||
public ReplayOrderSource( string replayFilename )
|
public ReplayOrderSource( string replayFilename )
|
||||||
{
|
{
|
||||||
replayReader = new BinaryReader( File.Open( replayFilename, FileMode.Open ) );
|
replayReader = new BinaryReader( File.Open( replayFilename, FileMode.Open ) );
|
||||||
replayReader.ReadUInt32();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendLocalOrders( int localFrame, List<Order> localOrders ) { }
|
public void SendLocalOrders( int localFrame, List<Order> localOrders ) { }
|
||||||
|
|
||||||
public List<Order> OrdersForFrame( int frameNumber )
|
public List<Order> OrdersForFrame( int frameNumber )
|
||||||
{
|
|
||||||
var ret = new List<Order>();
|
|
||||||
while( true )
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var first = replayReader.ReadUInt32();
|
uint fn;
|
||||||
var order = Order.Deserialize( replayReader, first );
|
|
||||||
if( order == null )
|
var len = replayReader.ReadInt32();
|
||||||
{
|
var ret = replayReader.ReadBytes( len ).ToOrderList( out fn );
|
||||||
if( (uint)frameNumber + 1 != first )
|
|
||||||
throw new NotImplementedException();
|
if( frameNumber != fn )
|
||||||
|
throw new InvalidOperationException( "Attempted time-travel in OrdersForFrame (replay)" );
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
ret.Add( order );
|
|
||||||
}
|
|
||||||
catch( EndOfStreamException )
|
catch( EndOfStreamException )
|
||||||
{
|
{
|
||||||
return ret;
|
return new List<Order>();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,7 +132,7 @@ namespace OpenRa.Game
|
|||||||
|
|
||||||
class NetworkOrderSource : OrderSource
|
class NetworkOrderSource : OrderSource
|
||||||
{
|
{
|
||||||
int nextLocalOrderFrame = 0;
|
int nextLocalOrderFrame = 1;
|
||||||
TcpClient socket;
|
TcpClient socket;
|
||||||
|
|
||||||
Dictionary<int, byte[]> orderBuffers = new Dictionary<int, byte[]>();
|
Dictionary<int, byte[]> orderBuffers = new Dictionary<int, byte[]>();
|
||||||
@@ -182,19 +173,12 @@ namespace OpenRa.Game
|
|||||||
lock( orderBuffers )
|
lock( orderBuffers )
|
||||||
orderBuffer = orderBuffers[ currentFrame ];
|
orderBuffer = orderBuffers[ currentFrame ];
|
||||||
|
|
||||||
var ms = new MemoryStream( orderBuffer );
|
uint frameNumber;
|
||||||
var reader = new BinaryReader( ms );
|
var ret = orderBuffer.ToOrderList( out frameNumber );
|
||||||
var ret = new List<Order>();
|
|
||||||
|
|
||||||
if( reader.ReadUInt32() != currentFrame )
|
if( frameNumber != currentFrame )
|
||||||
throw new InvalidOperationException( "Attempted time-travel in OrdersForFrame (network)" );
|
throw new InvalidOperationException( "Attempted time-travel in OrdersForFrame (network)" );
|
||||||
|
|
||||||
while( ms.Position < ms.Length )
|
|
||||||
{
|
|
||||||
var first = reader.ReadUInt32();
|
|
||||||
ret.Add( Order.Deserialize( reader, first ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,17 +187,7 @@ namespace OpenRa.Game
|
|||||||
if( nextLocalOrderFrame != localFrame )
|
if( nextLocalOrderFrame != localFrame )
|
||||||
throw new InvalidOperationException( "Attempted time-travel in NetworkOrderSource.SendLocalOrders()" );
|
throw new InvalidOperationException( "Attempted time-travel in NetworkOrderSource.SendLocalOrders()" );
|
||||||
|
|
||||||
var ms = new MemoryStream();
|
socket.GetStream().WriteFrameData( localOrders, nextLocalOrderFrame++ );
|
||||||
|
|
||||||
ms.Write( BitConverter.GetBytes( nextLocalOrderFrame ) );
|
|
||||||
|
|
||||||
foreach( var order in localOrders )
|
|
||||||
ms.Write( order.Serialize() );
|
|
||||||
|
|
||||||
++nextLocalOrderFrame;
|
|
||||||
|
|
||||||
socket.GetStream().Write( BitConverter.GetBytes( (int)ms.Length ) );
|
|
||||||
ms.WriteTo( socket.GetStream() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsReadyForFrame( int frameNumber )
|
public bool IsReadyForFrame( int frameNumber )
|
||||||
@@ -230,4 +204,34 @@ namespace OpenRa.Game
|
|||||||
s.Write( buf, 0, buf.Length );
|
s.Write( buf, 0, buf.Length );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class OrderIO
|
||||||
|
{
|
||||||
|
public static MemoryStream ToMemoryStream( this List<Order> orders, int nextLocalOrderFrame )
|
||||||
|
{
|
||||||
|
var ms = new MemoryStream();
|
||||||
|
ms.Write( BitConverter.GetBytes( nextLocalOrderFrame ) );
|
||||||
|
foreach( var order in orders )
|
||||||
|
ms.Write( order.Serialize() );
|
||||||
|
return ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void WriteFrameData( this Stream s, List<Order> orders, int frameNumber )
|
||||||
|
{
|
||||||
|
var ms = orders.ToMemoryStream( frameNumber );
|
||||||
|
s.Write( BitConverter.GetBytes( (int)ms.Length ) );
|
||||||
|
ms.WriteTo( s );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Order> ToOrderList( this byte[] bytes, out uint frameNumber )
|
||||||
|
{
|
||||||
|
var ms = new MemoryStream( bytes );
|
||||||
|
var reader = new BinaryReader( ms );
|
||||||
|
frameNumber = reader.ReadUInt32();
|
||||||
|
var ret = new List<Order>();
|
||||||
|
while( ms.Position < ms.Length )
|
||||||
|
ret.Add( Order.Deserialize( reader ) );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user