Always serialize orders.
This commit is contained in:
@@ -17,32 +17,32 @@ namespace OpenRA.Network
|
|||||||
{
|
{
|
||||||
public class OrderPacket
|
public class OrderPacket
|
||||||
{
|
{
|
||||||
readonly Order[] orders;
|
|
||||||
readonly MemoryStream data;
|
readonly MemoryStream data;
|
||||||
public OrderPacket(Order[] orders)
|
public OrderPacket(Order[] orders)
|
||||||
{
|
{
|
||||||
this.orders = orders;
|
// Orders may refer to actors that no longer exist by the time
|
||||||
data = null;
|
// that the order is resolved. In order to ensure consistent
|
||||||
|
// behaviour between local and remote clients, it is simplest
|
||||||
|
// to always serialize / deserialize orders, instead of storing
|
||||||
|
// the Order objects directly on the local client.
|
||||||
|
data = new MemoryStream();
|
||||||
|
foreach (var o in orders)
|
||||||
|
data.WriteArray(o.Serialize());
|
||||||
}
|
}
|
||||||
|
|
||||||
public OrderPacket(MemoryStream data)
|
public OrderPacket(MemoryStream data)
|
||||||
{
|
{
|
||||||
orders = null;
|
|
||||||
this.data = data;
|
this.data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Order> GetOrders(World world)
|
public IEnumerable<Order> GetOrders(World world)
|
||||||
{
|
{
|
||||||
return orders ?? ParseData(world);
|
if (data.Length == 0)
|
||||||
}
|
|
||||||
|
|
||||||
IEnumerable<Order> ParseData(World world)
|
|
||||||
{
|
|
||||||
if (data == null)
|
|
||||||
yield break;
|
yield break;
|
||||||
|
|
||||||
// Order deserialization depends on the current world state,
|
// Order deserialization depends on the current world state,
|
||||||
// so must be deferred until we are ready to consume them.
|
// so must be deferred until we are ready to consume them.
|
||||||
|
data.Position = 0;
|
||||||
var reader = new BinaryReader(data);
|
var reader = new BinaryReader(data);
|
||||||
while (data.Position < data.Length)
|
while (data.Position < data.Length)
|
||||||
{
|
{
|
||||||
@@ -54,29 +54,25 @@ namespace OpenRA.Network
|
|||||||
|
|
||||||
public byte[] Serialize(int frame)
|
public byte[] Serialize(int frame)
|
||||||
{
|
{
|
||||||
var ms = new MemoryStream();
|
var ms = new MemoryStream((int)data.Length + 4);
|
||||||
ms.WriteArray(BitConverter.GetBytes(frame));
|
ms.WriteArray(BitConverter.GetBytes(frame));
|
||||||
if (data != null)
|
|
||||||
data.CopyTo(ms);
|
|
||||||
else
|
|
||||||
foreach (var o in orders)
|
|
||||||
ms.WriteArray(o.Serialize());
|
|
||||||
|
|
||||||
return ms.ToArray();
|
data.Position = 0;
|
||||||
|
data.CopyTo(ms);
|
||||||
|
|
||||||
|
return ms.GetBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static OrderPacket Combine(IEnumerable<OrderPacket> packets)
|
public static OrderPacket Combine(IEnumerable<OrderPacket> packets)
|
||||||
{
|
{
|
||||||
var orders = new List<Order>();
|
var ms = new MemoryStream();
|
||||||
foreach (var packet in packets)
|
foreach (var packet in packets)
|
||||||
{
|
{
|
||||||
if (packet.orders == null)
|
packet.data.Position = 0;
|
||||||
throw new InvalidOperationException("OrderPacket.Combine can only be used with locally generated OrderPackets.");
|
packet.data.CopyTo(ms);
|
||||||
|
|
||||||
orders.AddRange(packet.orders);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new OrderPacket(orders.ToArray());
|
return new OrderPacket(ms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user