diff --git a/OpenRA.Game/Network/SyncReport.cs b/OpenRA.Game/Network/SyncReport.cs index e8b911f7cf..9850b2cbff 100755 --- a/OpenRA.Game/Network/SyncReport.cs +++ b/OpenRA.Game/Network/SyncReport.cs @@ -8,40 +8,42 @@ */ #endregion +using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Reflection.Emit; -using System; using OpenRA.FileFormats; namespace OpenRA.Network { class SyncReport { - static Cache>> dumpFuncCache = new Cache>>( t => GenerateDumpFunc( t ) ); + const int NumSyncReports = 5; + + static Cache>> dumpFuncCache = new Cache>>(t => GenerateDumpFunc(t)); readonly OrderManager orderManager; - const int numSyncReports = 5; - Report[] syncReports = new Report[numSyncReports]; + + Report[] syncReports = new Report[NumSyncReports]; int curIndex = 0; - public SyncReport( OrderManager orderManager ) + public SyncReport(OrderManager orderManager) { this.orderManager = orderManager; - for (var i = 0; i < numSyncReports; i++) + for (var i = 0; i < NumSyncReports; i++) syncReports[i] = new SyncReport.Report(); } internal void UpdateSyncReport() { GenerateSyncReport(syncReports[curIndex]); - curIndex = ++curIndex % numSyncReports; + curIndex = ++curIndex % NumSyncReports; } - public static Dictionary DumpSyncTrait( object obj ) + public static Dictionary DumpSyncTrait(object obj) { - return dumpFuncCache[ obj.GetType() ]( obj ); + return dumpFuncCache[obj.GetType()](obj); } public static Func> GenerateDumpFunc(Type t) @@ -66,8 +68,8 @@ namespace OpenRA.Network il.Emit(OpCodes.Newobj, dictCtor_); il.Emit(OpCodes.Stloc, dict_); - const BindingFlags bf = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; - foreach (var field in t.GetFields(bf).Where(x => x.HasAttribute())) + const BindingFlags Flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; + foreach (var field in t.GetFields(Flags).Where(x => x.HasAttribute())) { if (field.IsLiteral || field.IsStatic) continue; @@ -94,7 +96,7 @@ namespace OpenRA.Network il.MarkLabel(lblNull); } - foreach (var prop in t.GetProperties(bf).Where(x => x.HasAttribute())) + foreach (var prop in t.GetProperties(Flags).Where(x => x.HasAttribute())) { var lblNull = il.DefineLabel(); @@ -121,7 +123,7 @@ namespace OpenRA.Network il.Emit(OpCodes.Ldloc, dict_); il.Emit(OpCodes.Ret); - return (Func>) d.CreateDelegate(typeof(Func>)); + return (Func>)d.CreateDelegate(typeof(Func>)); } void GenerateSyncReport(Report report) @@ -136,23 +138,44 @@ namespace OpenRA.Network if (sync != 0) { var tr = new TraitReport() - { - ActorID = a.Actor.ActorID, - Type = a.Actor.Info.Name, - Owner = (a.Actor.Owner == null) ? "null" : a.Actor.Owner.PlayerName, - Trait = a.Trait.GetType().Name, - Hash = sync - }; + { + ActorID = a.Actor.ActorID, + Type = a.Actor.Info.Name, + Owner = (a.Actor.Owner == null) ? "null" : a.Actor.Owner.PlayerName, + Trait = a.Trait.GetType().Name, + Hash = sync + }; tr.Fields = DumpSyncTrait(a.Trait); report.Traits.Add(tr); } } + + foreach (var e in orderManager.world.Effects) + { + var sync = e as ISync; + if (sync != null) + { + var hash = Sync.CalculateSyncHash(sync); + if (hash != 0) + { + var er = new EffectReport() + { + Name = sync.ToString().Split('.').Last(), + Hash = hash + }; + + er.Fields = DumpSyncTrait(sync); + report.Effects.Add(er); + } + } + } } internal void DumpSyncReport(int frame) { foreach (var r in syncReports) + { if (r.Frame == frame) { Log.Write("sync", "Sync for net frame {0} -------------", r.Frame); @@ -160,21 +183,24 @@ namespace OpenRA.Network Log.Write("sync", "Synced Traits:"); foreach (var a in r.Traits) { - Log.Write("sync", "\t {0} {1} {2} {3} ({4})".F( - a.ActorID, - a.Type, - a.Owner, - a.Trait, - a.Hash - )); + Log.Write("sync", "\t {0} {1} {2} {3} ({4})".F(a.ActorID, a.Type, a.Owner, a.Trait, a.Hash)); foreach (var f in a.Fields) Log.Write("sync", "\t\t {0}: {1}".F(f.Key, f.Value)); + } + Log.Write("sync", "Synced Effects:"); + foreach (var e in r.Effects) + { + Log.Write("sync", "\t {0} ({1})", e.Name, e.Hash); + foreach (var f in e.Fields) + Log.Write("sync", "\t\t {0}: {1}".F(f.Key, f.Value)); } return; } - Log.Write("sync", "No sync report available!"); + + Log.Write("sync", "No sync report available!"); + } } class Report @@ -183,6 +209,7 @@ namespace OpenRA.Network public int SyncedRandom; public int TotalCount; public List Traits = new List(); + public List Effects = new List(); } struct TraitReport @@ -195,5 +222,11 @@ namespace OpenRA.Network public Dictionary Fields; } + struct EffectReport + { + public string Name; + public int Hash; + public Dictionary Fields; + } } } diff --git a/OpenRA.Game/World.cs b/OpenRA.Game/World.cs index 1ba2aa50e0..8934ba0c3e 100644 --- a/OpenRA.Game/World.cs +++ b/OpenRA.Game/World.cs @@ -246,6 +246,14 @@ namespace OpenRA foreach (var x in traitDict.ActorsWithTraitMultiple(this)) ret += n++ * (int)(1+x.Actor.ActorID) * Sync.CalculateSyncHash(x.Trait); + // TODO: don't go over all effects + foreach (var e in Effects) + { + var sync = e as ISync; + if (sync != null) + ret += n++ * Sync.CalculateSyncHash(sync); + } + // Hash the shared rng ret += SharedRandom.Last;