private IDictionary<string, object> SerializePretty(Frame frame, JavaScriptSerializer serializer) { List<UInt32> deletedActorStateIds = new List<UInt32>(); Dictionary<UInt32, ActorStateJson> updatedActorStates = new Dictionary<UInt32, ActorStateJson>(); foreach (var a in frame.ActorStates.Where(x => x.State == ActorStateState.Deleted)) { _existingActorStates.Remove(a.Id); deletedActorStateIds.Add(a.Id); } foreach (var a in frame.ActorStates.Where(x => x.State == ActorStateState.New)) { // Skip anything thats not truly new. Dont want keyframes in our json (for now) // (If there are property changes for a "new" actor we already have, they'll be caught below) if (!_existingActorStates.ContainsKey(a.Id)) { var actorState = new RocketLeagueReplayParser.Serializers.JsonSerializer.ActorStateJson(); actorState.Id = a.Id; actorState.UnknownBit = a.Unknown1; actorState.TypeName = a.TypeName; actorState.ClassName = a.ClassName; actorState.InitialPosition = a.Position; actorState.Properties = new List<ActorStateProperty>(); _existingActorStates[a.Id] = actorState; updatedActorStates[a.Id] = actorState; } } foreach (var a in frame.ActorStates.Where(x => x.State == ActorStateState.Existing)) { var existingActorState = _existingActorStates[a.Id]; RocketLeagueReplayParser.Serializers.JsonSerializer.ActorStateJson actorState = null; if (updatedActorStates.ContainsKey(a.Id)) { // Actor that's new as of this frame. Use the object we created above. actorState = updatedActorStates[a.Id]; } else { // Existing actor. Start a new state object to track changes actorState = new RocketLeagueReplayParser.Serializers.JsonSerializer.ActorStateJson(); actorState.Id = a.Id; actorState.Properties = new List<RocketLeagueReplayParser.Serializers.JsonSerializer.ActorStateProperty>(); // Maybe skip some of the following for existing actors //actorState.UnknownBit = existingActorState.UnknownBit; //actorState.TypeName = existingActorState.TypeName; //actorState.ClassName = existingActorState.ClassName; //actorState.InitialPosition = existingActorState.InitialPosition; } foreach (var p in a.Properties) { var property = new RocketLeagueReplayParser.Serializers.JsonSerializer.ActorStateProperty { Name = p.PropertyName, Data = p.Data }; var existingProperty = existingActorState.Properties.Where(ep => ep.Name == property.Name).FirstOrDefault(); if (existingProperty == null) { // new property actorState.Properties.Add(property); existingActorState.Properties.Add(property); } else { // Existing property. if (/* property.Name == "TAGame.Ball_TA:HitTeamNum" // Keep "Event" properties. TODO: Check if keyframes have this no matter what || property.Name.Contains("Music") // Kind of guessing at some of these event properties. We'll see how they turn out. || property.Name.Contains("Sound") || property.Name.Contains("Event") || */ !existingProperty.IsDeepEqual(property)) // Only keep if it is truly different { actorState.Properties.Add(property); // replace the property in our main set of data, so we have it for the next frame existingActorState.Properties = existingActorState.Properties.Where(ep => ep.Name != property.Name).ToList(); existingActorState.Properties.Add(property); } } } // Dont keep this state if we havent found any properties worth keeping if (actorState.Properties.Any()) { updatedActorStates[a.Id] = actorState; } } if (deletedActorStateIds.Any() || updatedActorStates.Any()) { Dictionary<string, object> result = new Dictionary<string, object>(); result["Time"] = frame.Time; result["DeletedActorIds"] = deletedActorStateIds; result["ActorUpdates"] = updatedActorStates.Values; return result; } else { return null; } }
public static Frame Deserialize(int maxChannels, ref List<ActorState> existingActorStates, string[] objectIdToName, IDictionary<string, ClassNetCache> classNetCacheByName, UInt32 versionMajor, UInt32 versionMinor, BitReader br) { var f = new Frame(); f.Position = br.Position; f.Time = br.ReadFloat(); f.Delta = br.ReadFloat(); if (f.Time < 0 || f.Delta < 0 || (f.Time > 0 && f.Time < 1E-10) || (f.Delta > 0 && f.Delta < 1E-10)) { string error = string.Format("\"Frame\" at postion {0} has time values that are negative or suspicious. The parser got lost. Check the previous frame for bad data. Time {1}, Delta {2}", f.Position, f.Time, f.Delta); #if DEBUG Console.WriteLine(error); f.Failed = true; return f; #endif throw new Exception(error); } f.ActorStates = new List<ActorState>(); ActorState lastActorState = null; while (br.ReadBit()) { lastActorState = ActorState.Deserialize(maxChannels, existingActorStates, f.ActorStates, objectIdToName, classNetCacheByName, versionMajor, versionMinor, br); var existingActor = existingActorStates.Where(x => x.Id == lastActorState.Id).SingleOrDefault(); if (lastActorState.State != ActorStateState.Deleted) { if (existingActor == null) { existingActorStates.Add(lastActorState); } } else { existingActorStates = existingActorStates.Where(x => x.Id != lastActorState.Id).ToList(); } f.ActorStates.Add(lastActorState); #if DEBUG if(!lastActorState.Complete) { break; } #endif } #if DEBUG if (lastActorState == null || lastActorState.Complete) { f.Complete = true; } if (lastActorState != null && lastActorState.Failed) { f.Failed = true; } f.RawData = br.GetBits(f.Position, br.Position - f.Position).ToArray(); #endif return f; }
private IDictionary<string, object> SerializeRaw(Frame frame, JavaScriptSerializer serializer) { List<UInt32> deletedActorStateIds = new List<UInt32>(); List<ActorStateJson> newActorStates = new List<ActorStateJson>(); List<ActorStateJson> updatedActorStates = new List<ActorStateJson>(); Dictionary<int, ActorStateJson> actor = new Dictionary<int, ActorStateJson>(); foreach (var a in frame.ActorStates.Where(x => x.State == ActorStateState.Deleted)) { deletedActorStateIds.Add(a.Id); } foreach (var a in frame.ActorStates.Where(x => x.State == ActorStateState.New)) { var actorState = new ActorStateJson(); actorState.Id = a.Id; actorState.UnknownBit = a.Unknown1; actorState.TypeName = a.TypeName; actorState.ClassName = a.ClassName; actorState.InitialPosition = a.Position; actorState.Properties = new List<ActorStateProperty>(); newActorStates.Add(actorState); } foreach (var a in frame.ActorStates.Where(x => x.State == ActorStateState.Existing)) { var actorState = new ActorStateJson(); actorState.Id = a.Id; actorState.Properties = new List<ActorStateProperty>(); actorState.Properties = a.Properties.Select(p => new ActorStateProperty { Name = p.PropertyName, Data = p.Data }).ToList(); updatedActorStates.Add(actorState); } Dictionary<string, object> result = new Dictionary<string, object>(); result["Time"] = frame.Time; result["DeletedActorIds"] = deletedActorStateIds; result["NewActors"] = newActorStates; result["UpdatedActors"] = updatedActorStates; return result; }