Merge pull request #6868 from Mailaender/network-code-clean
StyleCop cleanup of the Network code
This commit is contained in:
@@ -139,12 +139,12 @@ namespace OpenRA
|
||||
map = modData.PrepareMap(mapUID);
|
||||
using (new PerfTimer("NewWorld"))
|
||||
{
|
||||
orderManager.world = new World(map, orderManager, isShellmap);
|
||||
orderManager.world.Timestep = Timestep;
|
||||
orderManager.World = new World(map, orderManager, isShellmap);
|
||||
orderManager.World.Timestep = Timestep;
|
||||
}
|
||||
worldRenderer = new WorldRenderer(orderManager.world);
|
||||
worldRenderer = new WorldRenderer(orderManager.World);
|
||||
using (new PerfTimer("LoadComplete"))
|
||||
orderManager.world.LoadComplete(worldRenderer);
|
||||
orderManager.World.LoadComplete(worldRenderer);
|
||||
|
||||
if (orderManager.GameStarted)
|
||||
return;
|
||||
@@ -398,7 +398,7 @@ namespace OpenRA
|
||||
{
|
||||
var tick = RunTime;
|
||||
|
||||
var world = orderManager.world;
|
||||
var world = orderManager.World;
|
||||
|
||||
var uiTickDelta = tick - Ui.LastTickTime;
|
||||
if (uiTickDelta >= Timestep)
|
||||
@@ -474,7 +474,7 @@ namespace OpenRA
|
||||
}
|
||||
|
||||
InnerLogicTick(orderManager);
|
||||
if (worldRenderer != null && orderManager.world != worldRenderer.world)
|
||||
if (worldRenderer != null && orderManager.World != worldRenderer.world)
|
||||
InnerLogicTick(worldRenderer.world.orderManager);
|
||||
}
|
||||
|
||||
@@ -506,7 +506,7 @@ namespace OpenRA
|
||||
}
|
||||
|
||||
using (new PerfSample("render_flip"))
|
||||
Renderer.EndFrame(new DefaultInputHandler(orderManager.world));
|
||||
Renderer.EndFrame(new DefaultInputHandler(orderManager.World));
|
||||
}
|
||||
|
||||
PerfHistory.items["render"].Tick();
|
||||
@@ -663,8 +663,8 @@ namespace OpenRA
|
||||
|
||||
public static void Disconnect()
|
||||
{
|
||||
if (orderManager.world != null)
|
||||
orderManager.world.traitDict.PrintReport();
|
||||
if (orderManager.World != null)
|
||||
orderManager.World.traitDict.PrintReport();
|
||||
|
||||
orderManager.Dispose();
|
||||
CloseServer();
|
||||
@@ -704,7 +704,7 @@ namespace OpenRA
|
||||
|
||||
public static bool IsCurrentWorld(World world)
|
||||
{
|
||||
return orderManager != null && orderManager.world == world;
|
||||
return orderManager != null && orderManager.World == world;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ namespace OpenRA.Network
|
||||
public int FromClient;
|
||||
public byte[] Data;
|
||||
}
|
||||
|
||||
protected List<ReceivedPacket> receivedPackets = new List<ReceivedPacket>();
|
||||
|
||||
public virtual int LocalClientId
|
||||
@@ -120,7 +121,7 @@ namespace OpenRA.Network
|
||||
|
||||
public NetworkConnection(string host, int port)
|
||||
{
|
||||
t = new Thread( _ =>
|
||||
t = new Thread(_ =>
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -145,7 +146,7 @@ namespace OpenRA.Network
|
||||
if (len == 0)
|
||||
throw new NotImplementedException();
|
||||
lock (this)
|
||||
receivedPackets.Add(new ReceivedPacket { FromClient = client, Data = buf } );
|
||||
receivedPackets.Add(new ReceivedPacket { FromClient = client, Data = buf });
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
@@ -155,8 +156,7 @@ namespace OpenRA.Network
|
||||
if (socket != null)
|
||||
socket.Close();
|
||||
}
|
||||
}
|
||||
) { IsBackground = true };
|
||||
}) { IsBackground = true };
|
||||
t.Start();
|
||||
}
|
||||
|
||||
@@ -182,12 +182,14 @@ namespace OpenRA.Network
|
||||
var ms = new MemoryStream();
|
||||
ms.Write(BitConverter.GetBytes((int)packet.Length));
|
||||
ms.Write(packet);
|
||||
|
||||
foreach (var q in queuedSyncPackets)
|
||||
{
|
||||
ms.Write(BitConverter.GetBytes((int)q.Length));
|
||||
ms.Write(q);
|
||||
base.Send(q);
|
||||
}
|
||||
|
||||
queuedSyncPackets.Clear();
|
||||
ms.WriteTo(socket.GetStream());
|
||||
}
|
||||
@@ -209,11 +211,13 @@ namespace OpenRA.Network
|
||||
if (disposing)
|
||||
if (socket != null)
|
||||
socket.Client.Close();
|
||||
|
||||
using (new PerfSample("Thread.Join"))
|
||||
{
|
||||
if (!t.Join(1000))
|
||||
return;
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,15 +24,15 @@ namespace OpenRA.Network
|
||||
readonly Dictionary<int, int> clientQuitTimes = new Dictionary<int, int>();
|
||||
readonly Dictionary<int, Dictionary<int, byte[]>> framePackets = new Dictionary<int, Dictionary<int, byte[]>>();
|
||||
|
||||
public IEnumerable<int> ClientsPlayingInFrame( int frame )
|
||||
public IEnumerable<int> ClientsPlayingInFrame(int frame)
|
||||
{
|
||||
return clientQuitTimes
|
||||
.Where( x => frame <= x.Value )
|
||||
.Select( x => x.Key )
|
||||
.OrderBy( x => x );
|
||||
.Where(x => frame <= x.Value)
|
||||
.Select(x => x.Key)
|
||||
.OrderBy(x => x);
|
||||
}
|
||||
|
||||
public void ClientQuit( int clientId, int lastClientFrame )
|
||||
public void ClientQuit(int clientId, int lastClientFrame)
|
||||
{
|
||||
if (lastClientFrame == -1)
|
||||
lastClientFrame = framePackets
|
||||
@@ -42,10 +42,10 @@ namespace OpenRA.Network
|
||||
clientQuitTimes[clientId] = lastClientFrame;
|
||||
}
|
||||
|
||||
public void AddFrameOrders( int clientId, int frame, byte[] orders )
|
||||
public void AddFrameOrders(int clientId, int frame, byte[] orders)
|
||||
{
|
||||
var frameData = framePackets.GetOrAdd( frame );
|
||||
frameData.Add( clientId, orders );
|
||||
var frameData = framePackets.GetOrAdd(frame);
|
||||
frameData.Add(clientId, orders);
|
||||
}
|
||||
|
||||
public bool IsReadyForFrame(int frame)
|
||||
@@ -60,16 +60,16 @@ namespace OpenRA.Network
|
||||
.Where(client => !frameData.ContainsKey(client));
|
||||
}
|
||||
|
||||
public IEnumerable<ClientOrder> OrdersForFrame( World world, int frame )
|
||||
public IEnumerable<ClientOrder> OrdersForFrame(World world, int frame)
|
||||
{
|
||||
var frameData = framePackets[ frame ];
|
||||
var clientData = ClientsPlayingInFrame( frame )
|
||||
.ToDictionary( k => k, v => frameData[ v ] );
|
||||
var frameData = framePackets[frame];
|
||||
var clientData = ClientsPlayingInFrame(frame)
|
||||
.ToDictionary(k => k, v => frameData[v]);
|
||||
|
||||
return clientData
|
||||
.SelectMany( x => x.Value
|
||||
.ToOrderList( world )
|
||||
.Select( o => new ClientOrder { Client = x.Key, Order = o } ) );
|
||||
.SelectMany(x => x.Value
|
||||
.ToOrderList(world)
|
||||
.Select(o => new ClientOrder { Client = x.Key, Order = o }));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,70 +62,6 @@ namespace OpenRA
|
||||
this.ExtraData = extraData;
|
||||
}
|
||||
|
||||
// For scripting special powers
|
||||
public Order()
|
||||
: this(null, null, null, CPos.Zero, null, false, CPos.Zero, 0) { }
|
||||
|
||||
public Order(string orderString, Actor subject, bool queued)
|
||||
: this(orderString, subject, null, CPos.Zero, null, queued, CPos.Zero, 0) { }
|
||||
|
||||
public Order(string orderstring, Order order)
|
||||
: this(orderstring, order.Subject, order.TargetActor, order.TargetLocation,
|
||||
order.TargetString, order.Queued, order.ExtraLocation, order.ExtraData) {}
|
||||
|
||||
public byte[] Serialize()
|
||||
{
|
||||
if (IsImmediate) /* chat, whatever */
|
||||
{
|
||||
var ret = new MemoryStream();
|
||||
var w = new BinaryWriter(ret);
|
||||
w.Write((byte)0xfe);
|
||||
w.Write(OrderString);
|
||||
w.Write(TargetString);
|
||||
return ret.ToArray();
|
||||
}
|
||||
|
||||
switch (OrderString)
|
||||
{
|
||||
// Format:
|
||||
// u8 : orderID.
|
||||
// 0xFF: Full serialized order.
|
||||
// varies: rest of order.
|
||||
default:
|
||||
// TODO: specific serializers for specific orders.
|
||||
{
|
||||
var ret = new MemoryStream();
|
||||
var w = new BinaryWriter(ret);
|
||||
w.Write( (byte)0xFF );
|
||||
w.Write(OrderString);
|
||||
w.Write(UIntFromActor(Subject));
|
||||
|
||||
OrderFields fields = 0;
|
||||
if (TargetActor != null) fields |= OrderFields.TargetActor;
|
||||
if (TargetLocation != CPos.Zero) fields |= OrderFields.TargetLocation;
|
||||
if (TargetString != null) fields |= OrderFields.TargetString;
|
||||
if (Queued) fields |= OrderFields.Queued;
|
||||
if (ExtraLocation != CPos.Zero) fields |= OrderFields.ExtraLocation;
|
||||
if (ExtraData != 0) fields |= OrderFields.ExtraData;
|
||||
|
||||
w.Write((byte)fields);
|
||||
|
||||
if (TargetActor != null)
|
||||
w.Write(UIntFromActor(TargetActor));
|
||||
if (TargetLocation != CPos.Zero)
|
||||
w.Write(TargetLocation);
|
||||
if (TargetString != null)
|
||||
w.Write(TargetString);
|
||||
if (ExtraLocation != CPos.Zero)
|
||||
w.Write(ExtraLocation);
|
||||
if (ExtraData != 0)
|
||||
w.Write(ExtraData);
|
||||
|
||||
return ret.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Order Deserialize(World world, BinaryReader r)
|
||||
{
|
||||
switch (r.ReadByte())
|
||||
@@ -136,8 +72,8 @@ namespace OpenRA
|
||||
var subjectId = r.ReadUInt32();
|
||||
var flags = (OrderFields)r.ReadByte();
|
||||
|
||||
var targetActorId = flags.HasField(OrderFields.TargetActor) ? r.ReadUInt32() : 0xffffffff;
|
||||
var targetLocation = (CPos)( flags.HasField(OrderFields.TargetLocation) ? r.ReadInt2() : int2.Zero );
|
||||
var targetActorId = flags.HasField(OrderFields.TargetActor) ? r.ReadUInt32() : 0xffffffff;
|
||||
var targetLocation = (CPos)(flags.HasField(OrderFields.TargetLocation) ? r.ReadInt2() : int2.Zero);
|
||||
var targetString = flags.HasField(OrderFields.TargetString) ? r.ReadString() : null;
|
||||
var queued = flags.HasField(OrderFields.Queued);
|
||||
var extraLocation = (CPos)(flags.HasField(OrderFields.ExtraLocation) ? r.ReadInt2() : int2.Zero);
|
||||
@@ -155,7 +91,7 @@ namespace OpenRA
|
||||
var name = r.ReadString();
|
||||
var data = r.ReadString();
|
||||
|
||||
return new Order( name, null, false ) { IsImmediate = true, TargetString = data };
|
||||
return new Order(name, null, false) { IsImmediate = true, TargetString = data };
|
||||
}
|
||||
|
||||
default:
|
||||
@@ -163,13 +99,6 @@ namespace OpenRA
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return ("OrderString: \"{0}\" \n\t Subject: \"{1}\". \n\t TargetActor: \"{2}\" \n\t TargetLocation: {3}." +
|
||||
"\n\t TargetString: \"{4}\".\n\t IsImmediate: {5}.\n\t Player(PlayerName): {6}\n").F(
|
||||
OrderString, Subject, TargetActor != null ? TargetActor.Info.Name : null , TargetLocation, TargetString, IsImmediate, Player != null ? Player.PlayerName : null);
|
||||
}
|
||||
|
||||
static uint UIntFromActor(Actor a)
|
||||
{
|
||||
if (a == null) return 0xffffffff;
|
||||
@@ -190,6 +119,7 @@ namespace OpenRA
|
||||
ret = a;
|
||||
return true;
|
||||
}
|
||||
|
||||
ret = null;
|
||||
return false;
|
||||
}
|
||||
@@ -197,10 +127,9 @@ namespace OpenRA
|
||||
|
||||
// Named constructors for Orders.
|
||||
// Now that Orders are resolved by individual Actors, these are weird; you unpack orders manually, but not pack them.
|
||||
|
||||
public static Order Chat(bool team, string text)
|
||||
{
|
||||
return new Order(team ? "TeamChat" : "Chat", null, false) { IsImmediate = true, TargetString = text};
|
||||
return new Order(team ? "TeamChat" : "Chat", null, false) { IsImmediate = true, TargetString = text };
|
||||
}
|
||||
|
||||
public static Order HandshakeResponse(string text)
|
||||
@@ -237,5 +166,78 @@ namespace OpenRA
|
||||
{
|
||||
return new Order("CancelProduction", subject, false) { TargetString = item, ExtraLocation = new CPos(queueID, count) };
|
||||
}
|
||||
|
||||
// For scripting special powers
|
||||
public Order()
|
||||
: this(null, null, null, CPos.Zero, null, false, CPos.Zero, 0) { }
|
||||
|
||||
public Order(string orderString, Actor subject, bool queued)
|
||||
: this(orderString, subject, null, CPos.Zero, null, queued, CPos.Zero, 0) { }
|
||||
|
||||
public Order(string orderstring, Order order)
|
||||
: this(orderstring, order.Subject, order.TargetActor, order.TargetLocation,
|
||||
order.TargetString, order.Queued, order.ExtraLocation, order.ExtraData) { }
|
||||
|
||||
public byte[] Serialize()
|
||||
{
|
||||
if (IsImmediate)
|
||||
{
|
||||
var ret = new MemoryStream();
|
||||
var w = new BinaryWriter(ret);
|
||||
w.Write((byte)0xfe);
|
||||
w.Write(OrderString);
|
||||
w.Write(TargetString);
|
||||
return ret.ToArray();
|
||||
}
|
||||
|
||||
switch (OrderString)
|
||||
{
|
||||
/*
|
||||
* Format:
|
||||
* u8: orderID.
|
||||
* 0xFF: Full serialized order.
|
||||
* varies: rest of order.
|
||||
*/
|
||||
default:
|
||||
// TODO: specific serializers for specific orders.
|
||||
{
|
||||
var ret = new MemoryStream();
|
||||
var w = new BinaryWriter(ret);
|
||||
w.Write((byte)0xFF);
|
||||
w.Write(OrderString);
|
||||
w.Write(UIntFromActor(Subject));
|
||||
|
||||
OrderFields fields = 0;
|
||||
if (TargetActor != null) fields |= OrderFields.TargetActor;
|
||||
if (TargetLocation != CPos.Zero) fields |= OrderFields.TargetLocation;
|
||||
if (TargetString != null) fields |= OrderFields.TargetString;
|
||||
if (Queued) fields |= OrderFields.Queued;
|
||||
if (ExtraLocation != CPos.Zero) fields |= OrderFields.ExtraLocation;
|
||||
if (ExtraData != 0) fields |= OrderFields.ExtraData;
|
||||
|
||||
w.Write((byte)fields);
|
||||
|
||||
if (TargetActor != null)
|
||||
w.Write(UIntFromActor(TargetActor));
|
||||
if (TargetLocation != CPos.Zero)
|
||||
w.Write(TargetLocation);
|
||||
if (TargetString != null)
|
||||
w.Write(TargetString);
|
||||
if (ExtraLocation != CPos.Zero)
|
||||
w.Write(ExtraLocation);
|
||||
if (ExtraData != 0)
|
||||
w.Write(ExtraData);
|
||||
|
||||
return ret.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return ("OrderString: \"{0}\" \n\t Subject: \"{1}\". \n\t TargetActor: \"{2}\" \n\t TargetLocation: {3}." +
|
||||
"\n\t TargetString: \"{4}\".\n\t IsImmediate: {5}.\n\t Player(PlayerName): {6}\n").F(
|
||||
OrderString, Subject, TargetActor != null ? TargetActor.Info.Name : null, TargetLocation, TargetString, IsImmediate, Player != null ? Player.PlayerName : null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,24 +25,26 @@ namespace OpenRA.Network
|
||||
var ms = new MemoryStream(bytes, 4, bytes.Length - 4);
|
||||
var reader = new BinaryReader(ms);
|
||||
var ret = new List<Order>();
|
||||
while( ms.Position < ms.Length )
|
||||
while (ms.Position < ms.Length)
|
||||
{
|
||||
var o = Order.Deserialize( world, reader );
|
||||
if( o != null )
|
||||
ret.Add( o );
|
||||
var o = Order.Deserialize(world, reader);
|
||||
if (o != null)
|
||||
ret.Add(o);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static byte[] SerializeSync( this List<int> sync )
|
||||
public static byte[] SerializeSync(this List<int> sync)
|
||||
{
|
||||
var ms = new MemoryStream();
|
||||
using( var writer = new BinaryWriter( ms ) )
|
||||
using (var writer = new BinaryWriter(ms))
|
||||
{
|
||||
writer.Write( (byte)0x65 );
|
||||
foreach( var s in sync )
|
||||
writer.Write( s );
|
||||
writer.Write((byte)0x65);
|
||||
foreach (var s in sync)
|
||||
writer.Write(s);
|
||||
}
|
||||
|
||||
return ms.ToArray();
|
||||
}
|
||||
|
||||
|
||||
@@ -18,12 +18,14 @@ namespace OpenRA.Network
|
||||
{
|
||||
public sealed class OrderManager : IDisposable
|
||||
{
|
||||
static readonly IEnumerable<Session.Client> NoClients = new Session.Client[] { };
|
||||
|
||||
readonly SyncReport syncReport;
|
||||
readonly FrameData frameData = new FrameData();
|
||||
|
||||
public Session LobbyInfo = new Session();
|
||||
public Session.Client LocalClient { get { return LobbyInfo.ClientWithIndex(Connection.LocalClientId); } }
|
||||
public World world;
|
||||
public World World;
|
||||
|
||||
public readonly string Host;
|
||||
public readonly int Port;
|
||||
@@ -46,14 +48,25 @@ namespace OpenRA.Network
|
||||
List<Order> localOrders = new List<Order>();
|
||||
|
||||
List<ChatLine> chatCache = new List<ChatLine>();
|
||||
|
||||
public readonly ReadOnlyList<ChatLine> ChatCache;
|
||||
|
||||
static void OutOfSync(int frame)
|
||||
{
|
||||
throw new InvalidOperationException("Out of sync in frame {0}.\n Compare syncreport.log with other players.".F(frame));
|
||||
}
|
||||
|
||||
static void OutOfSync(int frame, string blame)
|
||||
{
|
||||
throw new InvalidOperationException("Out of sync in frame {0}: Blame {1}.\n Compare syncreport.log with other players.".F(frame, blame));
|
||||
}
|
||||
|
||||
public void StartGame()
|
||||
{
|
||||
if (GameStarted) return;
|
||||
|
||||
NetFrameNumber = 1;
|
||||
for (var i = NetFrameNumber ; i <= FramesAhead ; i++)
|
||||
for (var i = NetFrameNumber; i <= FramesAhead; i++)
|
||||
Connection.Send(i, new List<byte[]>());
|
||||
}
|
||||
|
||||
@@ -87,15 +100,15 @@ namespace OpenRA.Network
|
||||
|
||||
public void TickImmediate()
|
||||
{
|
||||
var immediateOrders = localOrders.Where( o => o.IsImmediate ).ToList();
|
||||
if( immediateOrders.Count != 0 )
|
||||
Connection.SendImmediate( immediateOrders.Select( o => o.Serialize() ).ToList() );
|
||||
localOrders.RemoveAll( o => o.IsImmediate );
|
||||
var immediateOrders = localOrders.Where(o => o.IsImmediate).ToList();
|
||||
if (immediateOrders.Count != 0)
|
||||
Connection.SendImmediate(immediateOrders.Select(o => o.Serialize()).ToList());
|
||||
localOrders.RemoveAll(o => o.IsImmediate);
|
||||
|
||||
var immediatePackets = new List<Pair<int, byte[]>>();
|
||||
|
||||
Connection.Receive(
|
||||
( clientId, packet ) =>
|
||||
(clientId, packet) =>
|
||||
{
|
||||
var frame = BitConverter.ToInt32(packet, 0);
|
||||
if (packet.Length == 5 && packet[4] == 0xBF)
|
||||
@@ -106,11 +119,11 @@ namespace OpenRA.Network
|
||||
immediatePackets.Add(Pair.New(clientId, packet));
|
||||
else
|
||||
frameData.AddFrameOrders(clientId, frame, packet);
|
||||
} );
|
||||
});
|
||||
|
||||
foreach (var p in immediatePackets)
|
||||
foreach (var o in p.Second.ToOrderList(world))
|
||||
UnitOrders.ProcessOrder(this, world, p.First, o);
|
||||
foreach (var o in p.Second.ToOrderList(World))
|
||||
UnitOrders.ProcessOrder(this, World, p.First, o);
|
||||
}
|
||||
|
||||
Dictionary<int, byte[]> syncForFrame = new Dictionary<int, byte[]>();
|
||||
@@ -148,7 +161,7 @@ namespace OpenRA.Network
|
||||
|
||||
void OutOfSync(int frame, int index)
|
||||
{
|
||||
var orders = frameData.OrdersForFrame(world, frame);
|
||||
var orders = frameData.OrdersForFrame(World, frame);
|
||||
|
||||
// Invalid index
|
||||
if (index >= orders.Count())
|
||||
@@ -157,22 +170,11 @@ namespace OpenRA.Network
|
||||
throw new InvalidOperationException("Out of sync in frame {0}.\n {1}\n Compare syncreport.log with other players.".F(frame, orders.ElementAt(index).Order.ToString()));
|
||||
}
|
||||
|
||||
static void OutOfSync(int frame)
|
||||
{
|
||||
throw new InvalidOperationException("Out of sync in frame {0}.\n Compare syncreport.log with other players.".F(frame));
|
||||
}
|
||||
|
||||
static void OutOfSync(int frame, string blame)
|
||||
{
|
||||
throw new InvalidOperationException("Out of sync in frame {0}: Blame {1}.\n Compare syncreport.log with other players.".F(frame, blame));
|
||||
}
|
||||
|
||||
public bool IsReadyForNextFrame
|
||||
{
|
||||
get { return NetFrameNumber >= 1 && frameData.IsReadyForFrame(NetFrameNumber); }
|
||||
}
|
||||
|
||||
static readonly IEnumerable<Session.Client> NoClients = new Session.Client[] {};
|
||||
public IEnumerable<Session.Client> GetClientsNotReadyForNextFrame
|
||||
{
|
||||
get
|
||||
@@ -193,12 +195,12 @@ namespace OpenRA.Network
|
||||
localOrders.Clear();
|
||||
|
||||
var sync = new List<int>();
|
||||
sync.Add(world.SyncHash());
|
||||
sync.Add(World.SyncHash());
|
||||
|
||||
foreach (var order in frameData.OrdersForFrame(world, NetFrameNumber))
|
||||
foreach (var order in frameData.OrdersForFrame(World, NetFrameNumber))
|
||||
{
|
||||
UnitOrders.ProcessOrder(this, world, order.Client, order.Order);
|
||||
sync.Add(world.SyncHash());
|
||||
UnitOrders.ProcessOrder(this, World, order.Client, order.Order);
|
||||
sync.Add(World.SyncHash());
|
||||
}
|
||||
|
||||
var ss = sync.SerializeSync();
|
||||
|
||||
@@ -25,6 +25,17 @@ namespace OpenRA.Network
|
||||
Func<string> chooseFilename;
|
||||
MemoryStream preStartBuffer = new MemoryStream();
|
||||
|
||||
static bool IsGameStart(byte[] data)
|
||||
{
|
||||
if (data.Length == 5 && data[4] == 0xbf)
|
||||
return false;
|
||||
if (data.Length >= 5 && data[4] == 0x65)
|
||||
return false;
|
||||
|
||||
var frame = BitConverter.ToInt32(data, 0);
|
||||
return frame == 0 && data.ToOrderList(null).Any(o => o.OrderString == "StartGame");
|
||||
}
|
||||
|
||||
public ReplayRecorderConnection(IConnection inner, Func<string> chooseFilename)
|
||||
{
|
||||
this.chooseFilename = chooseFilename;
|
||||
@@ -85,17 +96,6 @@ namespace OpenRA.Network
|
||||
});
|
||||
}
|
||||
|
||||
static bool IsGameStart(byte[] data)
|
||||
{
|
||||
if (data.Length == 5 && data[4] == 0xbf)
|
||||
return false;
|
||||
if (data.Length >= 5 && data[4] == 0x65)
|
||||
return false;
|
||||
|
||||
var frame = BitConverter.ToInt32(data, 0);
|
||||
return frame == 0 && data.ToOrderList(null).Any(o => o.OrderString == "StartGame");
|
||||
}
|
||||
|
||||
bool disposed;
|
||||
|
||||
public void Dispose()
|
||||
|
||||
@@ -94,10 +94,14 @@ namespace OpenRA.Network
|
||||
|
||||
public class Client
|
||||
{
|
||||
public static Client Deserialize(MiniYaml data)
|
||||
{
|
||||
return FieldLoader.Load<Client>(data);
|
||||
}
|
||||
|
||||
public int Index;
|
||||
public HSLColor PreferredColor; // Color that the client normally uses from settings.yaml.
|
||||
public HSLColor Color; // Actual color that the client is using.
|
||||
// Usually the same as PreferredColor but can be different on maps with locked colors.
|
||||
public HSLColor Color; // Actual color that the client is using. Usually the same as PreferredColor but can be different on maps with locked colors.
|
||||
public string Country;
|
||||
public int SpawnPoint;
|
||||
public string Name;
|
||||
@@ -116,11 +120,6 @@ namespace OpenRA.Network
|
||||
{
|
||||
return new MiniYamlNode("Client@{0}".F(this.Index), FieldSaver.Save(this));
|
||||
}
|
||||
|
||||
public static Client Deserialize(MiniYaml data)
|
||||
{
|
||||
return FieldLoader.Load<Client>(data);
|
||||
}
|
||||
}
|
||||
|
||||
public ClientPing PingFromClient(Client client)
|
||||
@@ -135,15 +134,15 @@ namespace OpenRA.Network
|
||||
public int LatencyJitter = -1;
|
||||
public int[] LatencyHistory = { };
|
||||
|
||||
public MiniYamlNode Serialize()
|
||||
{
|
||||
return new MiniYamlNode("ClientPing@{0}".F(this.Index), FieldSaver.Save(this));
|
||||
}
|
||||
|
||||
public static ClientPing Deserialize(MiniYaml data)
|
||||
{
|
||||
return FieldLoader.Load<ClientPing>(data);
|
||||
}
|
||||
|
||||
public MiniYamlNode Serialize()
|
||||
{
|
||||
return new MiniYamlNode("ClientPing@{0}".F(this.Index), FieldSaver.Save(this));
|
||||
}
|
||||
}
|
||||
|
||||
public class Slot
|
||||
@@ -158,15 +157,15 @@ namespace OpenRA.Network
|
||||
public bool LockSpawn;
|
||||
public bool Required;
|
||||
|
||||
public MiniYamlNode Serialize()
|
||||
{
|
||||
return new MiniYamlNode("Slot@{0}".F(this.PlayerReference), FieldSaver.Save(this));
|
||||
}
|
||||
|
||||
public static Slot Deserialize(MiniYaml data)
|
||||
{
|
||||
return FieldLoader.Load<Slot>(data);
|
||||
}
|
||||
|
||||
public MiniYamlNode Serialize()
|
||||
{
|
||||
return new MiniYamlNode("Slot@{0}".F(this.PlayerReference), FieldSaver.Save(this));
|
||||
}
|
||||
}
|
||||
|
||||
public class Global
|
||||
@@ -185,20 +184,20 @@ namespace OpenRA.Network
|
||||
public bool Fog = true;
|
||||
public bool AllyBuildRadius = true;
|
||||
public int StartingCash = 5000;
|
||||
public String TechLevel = "none";
|
||||
public string TechLevel = "none";
|
||||
public string StartingUnitsClass = "none";
|
||||
public bool AllowVersionMismatch;
|
||||
public string GameUid;
|
||||
|
||||
public MiniYamlNode Serialize()
|
||||
{
|
||||
return new MiniYamlNode("GlobalSettings", FieldSaver.Save(this));
|
||||
}
|
||||
|
||||
public static Global Deserialize(MiniYaml data)
|
||||
{
|
||||
return FieldLoader.Load<Global>(data);
|
||||
}
|
||||
|
||||
public MiniYamlNode Serialize()
|
||||
{
|
||||
return new MiniYamlNode("GlobalSettings", FieldSaver.Save(this));
|
||||
}
|
||||
}
|
||||
|
||||
public string Serialize()
|
||||
|
||||
49
OpenRA.Game/Network/SyncReport.cs
Executable file → Normal file
49
OpenRA.Game/Network/SyncReport.cs
Executable file → Normal file
@@ -29,6 +29,21 @@ namespace OpenRA.Network
|
||||
readonly Report[] syncReports = new Report[NumSyncReports];
|
||||
int curIndex = 0;
|
||||
|
||||
static NamesValuesPair DumpSyncTrait(ISync sync)
|
||||
{
|
||||
var type = sync.GetType();
|
||||
TypeInfo typeInfo;
|
||||
lock (typeInfoCache)
|
||||
typeInfo = typeInfoCache[type];
|
||||
var values = new string[typeInfo.Names.Length];
|
||||
var index = 0;
|
||||
|
||||
foreach (var func in typeInfo.MemberToStringFunctions)
|
||||
values[index++] = func(sync);
|
||||
|
||||
return Pair.New(typeInfo.Names, values);
|
||||
}
|
||||
|
||||
public SyncReport(OrderManager orderManager)
|
||||
{
|
||||
this.orderManager = orderManager;
|
||||
@@ -45,10 +60,10 @@ namespace OpenRA.Network
|
||||
void GenerateSyncReport(Report report)
|
||||
{
|
||||
report.Frame = orderManager.NetFrameNumber;
|
||||
report.SyncedRandom = orderManager.world.SharedRandom.Last;
|
||||
report.TotalCount = orderManager.world.SharedRandom.TotalCount;
|
||||
report.SyncedRandom = orderManager.World.SharedRandom.Last;
|
||||
report.TotalCount = orderManager.World.SharedRandom.TotalCount;
|
||||
report.Traits.Clear();
|
||||
foreach (var a in orderManager.world.ActorsWithTrait<ISync>())
|
||||
foreach (var a in orderManager.World.ActorsWithTrait<ISync>())
|
||||
{
|
||||
var sync = Sync.CalculateSyncHash(a.Trait);
|
||||
if (sync != 0)
|
||||
@@ -63,7 +78,7 @@ namespace OpenRA.Network
|
||||
});
|
||||
}
|
||||
|
||||
foreach (var e in orderManager.world.Effects)
|
||||
foreach (var e in orderManager.World.Effects)
|
||||
{
|
||||
var sync = e as ISync;
|
||||
if (sync != null)
|
||||
@@ -80,21 +95,6 @@ namespace OpenRA.Network
|
||||
}
|
||||
}
|
||||
|
||||
static NamesValuesPair DumpSyncTrait(ISync sync)
|
||||
{
|
||||
var type = sync.GetType();
|
||||
TypeInfo typeInfo;
|
||||
lock (typeInfoCache)
|
||||
typeInfo = typeInfoCache[type];
|
||||
var values = new string[typeInfo.Names.Length];
|
||||
var index = 0;
|
||||
|
||||
foreach (var func in typeInfo.MemberToStringFunctions)
|
||||
values[index++] = func(sync);
|
||||
|
||||
return Pair.New(typeInfo.Names, values);
|
||||
}
|
||||
|
||||
internal void DumpSyncReport(int frame)
|
||||
{
|
||||
foreach (var r in syncReports)
|
||||
@@ -182,11 +182,10 @@ namespace OpenRA.Network
|
||||
"Invalid Property: " + prop.DeclaringType.FullName + "." + prop.Name);
|
||||
|
||||
var sync = Expression.Convert(syncParam, type);
|
||||
MemberToStringFunctions = fields.Select(
|
||||
fi => MemberToString(Expression.Field(sync, fi), fi.FieldType, fi.Name))
|
||||
.Concat(properties.Select(
|
||||
pi => MemberToString(Expression.Property(sync, pi), pi.PropertyType, pi.Name))
|
||||
).ToArray();
|
||||
MemberToStringFunctions = fields
|
||||
.Select(fi => MemberToString(Expression.Field(sync, fi), fi.FieldType, fi.Name))
|
||||
.Concat(properties.Select(pi => MemberToString(Expression.Property(sync, pi), pi.PropertyType, pi.Name)))
|
||||
.ToArray();
|
||||
|
||||
Names = fields.Select(fi => fi.Name).Concat(properties.Select(pi => pi.Name)).ToArray();
|
||||
}
|
||||
@@ -198,7 +197,6 @@ namespace OpenRA.Network
|
||||
var toString = memberType.GetMethod("ToString", Type.EmptyTypes);
|
||||
Expression getString;
|
||||
if (memberType.IsValueType)
|
||||
// (ISync sync) => ((TSync)sync).Foo.ToString()
|
||||
getString = Expression.Call(getMember, toString);
|
||||
else
|
||||
{
|
||||
@@ -210,6 +208,7 @@ namespace OpenRA.Network
|
||||
var nullMember = Expression.Constant(null, memberType);
|
||||
getString = Expression.Condition(Expression.Equal(member, nullMember), nullString, getString);
|
||||
}
|
||||
|
||||
return Expression.Lambda<Func<ISync, string>>(getString, name, new[] { syncParam }).Compile();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,15 +62,15 @@ namespace OpenRA.Network
|
||||
NatDevice = args.Device;
|
||||
Log.Write("server", "Type: {0}", NatDevice.GetType());
|
||||
Log.Write("server", "Your external IP is: {0}", NatDevice.GetExternalIP());
|
||||
|
||||
|
||||
foreach (var mp in NatDevice.GetAllMappings())
|
||||
Log.Write("server", "Existing port mapping: protocol={0}, public={1}, private={2}",
|
||||
mp.Protocol, mp.PublicPort, mp.PrivatePort);
|
||||
mp.Protocol, mp.PublicPort, mp.PrivatePort);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Write("server", "Can't fetch information from NAT device: {0}", e);
|
||||
|
||||
|
||||
Game.Settings.Server.NatDeviceAvailable = false;
|
||||
Game.Settings.Server.AllowPortForward = false;
|
||||
}
|
||||
|
||||
@@ -80,13 +80,14 @@ namespace OpenRA.Network
|
||||
var player = world.FindPlayerByClient(client);
|
||||
if (player == null) return;
|
||||
|
||||
if (world.LocalPlayer != null && player.Stances[world.LocalPlayer] == Stance.Ally || player.WinState == WinState.Lost)
|
||||
if ((world.LocalPlayer != null && player.Stances[world.LocalPlayer] == Stance.Ally) || player.WinState == WinState.Lost)
|
||||
{
|
||||
var suffix = player.WinState == WinState.Lost ? " (Dead)" : " (Team)";
|
||||
Game.AddChatLine(client.Color.RGB, client.Name + suffix, order.TargetString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -103,15 +104,16 @@ namespace OpenRA.Network
|
||||
if (client != null)
|
||||
{
|
||||
var pause = order.TargetString == "Pause";
|
||||
if (orderManager.world.Paused != pause && !world.LobbyInfo.IsSinglePlayer)
|
||||
if (orderManager.World.Paused != pause && !world.LobbyInfo.IsSinglePlayer)
|
||||
{
|
||||
var pausetext = "The game is {0} by {1}".F(pause ? "paused" : "un-paused", client.Name);
|
||||
Game.AddChatLine(Color.White, "", pausetext);
|
||||
}
|
||||
|
||||
orderManager.world.Paused = pause;
|
||||
orderManager.world.PredictedPaused = pause;
|
||||
orderManager.World.Paused = pause;
|
||||
orderManager.World.PredictedPaused = pause;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -248,7 +250,7 @@ namespace OpenRA.Network
|
||||
if (newStance == Stance.Enemy && targetPlayer.Stances[order.Player] == Stance.Ally)
|
||||
{
|
||||
targetPlayer.SetStance(order.Player, newStance);
|
||||
Game.Debug("{0} has reciprocated",targetPlayer.PlayerName);
|
||||
Game.Debug("{0} has reciprocated", targetPlayer.PlayerName);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -270,6 +272,7 @@ namespace OpenRA.Network
|
||||
foreach (var t in self.TraitsImplementing<IResolveOrder>())
|
||||
t.ResolveOrder(self, order);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,22 +29,13 @@ namespace OpenRA.Orders
|
||||
}
|
||||
|
||||
public GenericSelectTarget(IEnumerable<Actor> subjects, string order, string cursor)
|
||||
: this(subjects, order, cursor, MouseButton.Left)
|
||||
{
|
||||
|
||||
}
|
||||
: this(subjects, order, cursor, MouseButton.Left) { }
|
||||
|
||||
public GenericSelectTarget(Actor subject, string order, string cursor)
|
||||
: this(new Actor[] { subject }, order, cursor)
|
||||
{
|
||||
|
||||
}
|
||||
: this(new Actor[] { subject }, order, cursor) { }
|
||||
|
||||
public GenericSelectTarget(Actor subject, string order, string cursor, MouseButton button)
|
||||
: this(new Actor[] { subject }, order, cursor, button)
|
||||
{
|
||||
|
||||
}
|
||||
: this(new Actor[] { subject }, order, cursor, button) { }
|
||||
|
||||
public IEnumerable<Order> Order(World world, CPos xy, MouseInput mi)
|
||||
{
|
||||
|
||||
@@ -526,7 +526,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
musicButton.OnClick = () => Ui.OpenWindow("MUSIC_PANEL", new WidgetArgs
|
||||
{
|
||||
{ "onExit", DoNothing },
|
||||
{ "world", orderManager.world }
|
||||
{ "world", orderManager.World }
|
||||
});
|
||||
|
||||
var settingsButton = lobby.GetOrNull<ButtonWidget>("SETTINGS_BUTTON");
|
||||
|
||||
@@ -138,7 +138,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
|
||||
Action<HSLColor> onChange = c => preview.Color = c;
|
||||
|
||||
var colorChooser = Game.LoadWidget(orderManager.world, "COLOR_CHOOSER", null, new WidgetArgs()
|
||||
var colorChooser = Game.LoadWidget(orderManager.World, "COLOR_CHOOSER", null, new WidgetArgs()
|
||||
{
|
||||
{ "onChange", onChange },
|
||||
{ "initialColor", client.Color }
|
||||
|
||||
Reference in New Issue
Block a user