示例#1
0
 protected ActorStateProperty(ActorStateProperty copyFrom)
 {
     PropertyId     = copyFrom.PropertyId;
     PropertyName   = copyFrom.PropertyName;
     Data           = copyFrom.Data;
     _classNetCache = copyFrom._classNetCache;
 }
        public void Add(ActorStateProperty property)
        {
            if (PropertyId != property.PropertyId)
            {
                throw new ArgumentException("Property id mismatch, can not add to list");
            }

            ((List <object>)Data).Add(property.Data);
        }
示例#3
0
 // Create or update property.
 public void ProcessProperty(RocketLeagueReplayParser.NetworkStream.ActorStateProperty asp)
 {
     // Look for existing property with matching type (name).
     for (int i = 0; i < props.Count; i++)
     {
         if (props[i].name == asp.PropertyName)
         {
             props[i].value = asp.Data.ToString();
             return;
         }
     }
     // Add new property if no match found.
     props.Add(new MyProperty(asp));
 }
示例#4
0
        public static ActorStateProperty Deserialize(IClassNetCache classMap, string typeName, string[] objectIndexToName, UInt32 versionMajor, UInt32 versionMinor, BitReader br)
        {
            var asp = new ActorStateProperty();

            var maxPropId = classMap.MaxPropertyId;

            var className = objectIndexToName[classMap.ObjectIndex];

            asp.PropertyId = br.ReadUInt32Max(maxPropId + 1);
#if DEBUG
            asp.MaxPropertyId = (UInt32)maxPropId;
#endif
            asp.PropertyName = objectIndexToName[classMap.GetProperty((int)asp.PropertyId).Index];

            var startPosition = br.Position;

            asp.Data = new List <object>();

            switch (asp.PropertyName)
            {
            case "TAGame.GameEvent_TA:ReplicatedStateIndex":
                asp.Data.Add(br.ReadUInt32Max(140));     // number is made up, I dont know the max yet // TODO: Revisit this. It might work well enough, but looks fishy
                asp.MarkComplete();
                break;

            case "TAGame.RBActor_TA:ReplicatedRBState":
                asp.Data.Add(RigidBodyState.Deserialize(br));
                asp.MarkComplete();
                break;

            case "TAGame.CrowdActor_TA:ReplicatedOneShotSound":
            case "TAGame.CrowdManager_TA:ReplicatedGlobalOneShotSound":
            case "Engine.GameReplicationInfo:GameClass":
            case "TAGame.CrowdManager_TA:GameEvent":
            case "TAGame.CrowdActor_TA:GameEvent":
            case "TAGame.Team_TA:LogoData":
            case "TAGame.CameraSettingsActor_TA:PRI":
            case "TAGame.PRI_TA:PersistentCamera":
            case "TAGame.GameEvent_TA:MatchTypeClass":
            case "TAGame.GameEvent_Soccar_TA:SubRulesArchetype":
                // Theres a good chance that most of these can be moved to the next section
                asp.Data.Add(br.ReadBit());
                asp.Data.Add(br.ReadUInt32());
                asp.MarkComplete();
                break;

            case "TAGame.Team_TA:GameEvent":
            case "TAGame.Ball_TA:GameEvent":
            case "Engine.PlayerReplicationInfo:Team":
            case "Engine.Pawn:PlayerReplicationInfo":
            case "TAGame.PRI_TA:ReplicatedGameEvent":
            case "TAGame.CarComponent_TA:Vehicle":
            case "TAGame.Car_TA:AttachedPickup":
            case "TAGame.SpecialPickup_Targeted_TA:Targeted":
                // TODO: Use a real class so it can be accessed normally.
                // If Active == false, ActorId will be -1
                asp.Data.Add(ActiveActor.Deserialize(br));
                asp.MarkComplete();
                break;

            case "Engine.GameReplicationInfo:ServerName":
            case "Engine.PlayerReplicationInfo:PlayerName":
            case "TAGame.Team_TA:CustomTeamName":
            case "Engine.PlayerReplicationInfo:RemoteUserData":
            case "TAGame.GRI_TA:NewDedicatedServerIP":
                asp.Data.Add(br.ReadString());
                asp.MarkComplete();
                break;

            case "TAGame.GameEvent_Soccar_TA:SecondsRemaining":
            case "TAGame.GameEvent_TA:ReplicatedGameStateTimeRemaining":
            case "TAGame.CrowdActor_TA:ReplicatedCountDownNumber":
            case "TAGame.GameEvent_Team_TA:MaxTeamSize":
            case "Engine.PlayerReplicationInfo:PlayerID":
            case "TAGame.PRI_TA:TotalXP":
            case "TAGame.PRI_TA:MatchScore":
            case "TAGame.GameEvent_Soccar_TA:RoundNum":
            case "TAGame.GameEvent_TA:BotSkill":
            case "TAGame.PRI_TA:MatchShots":
            case "TAGame.PRI_TA:MatchSaves":
            case "ProjectX.GRI_X:ReplicatedGamePlaylist":
            case "Engine.TeamInfo:Score":
            case "Engine.PlayerReplicationInfo:Score":
            case "TAGame.PRI_TA:MatchGoals":
            case "TAGame.PRI_TA:MatchAssists":
            case "ProjectX.GRI_X:ReplicatedGameMutatorIndex":
            case "TAGame.PRI_TA:Title":
            case "TAGame.GameEvent_TA:ReplicatedStateName":
            case "TAGame.Team_Soccar_TA:GameScore":
            case "TAGame.GameEvent_Soccar_TA:GameTime":
            case "TAGame.CarComponent_Boost_TA:UnlimitedBoostRefCount":
            case "TAGame.CrowdActor_TA:ReplicatedRoundCountDownNumber":
                asp.Data.Add(br.ReadUInt32());
                asp.MarkComplete();
                break;

            case "TAGame.VehiclePickup_TA:ReplicatedPickupData":
                asp.Data.Add(br.ReadBit());
                asp.Data.Add(br.ReadUInt32());
                asp.Data.Add(br.ReadBit());

                asp.MarkComplete();
                break;

            case "Engine.PlayerReplicationInfo:Ping":
            case "TAGame.Vehicle_TA:ReplicatedSteer":
            case "TAGame.Vehicle_TA:ReplicatedThrottle":     // 0: full reverse, 128: No throttle.  255 full throttle/boosting
            case "TAGame.PRI_TA:CameraYaw":
            case "TAGame.PRI_TA:CameraPitch":
            case "TAGame.Ball_TA:HitTeamNum":
            case "TAGame.GameEvent_Soccar_TA:ReplicatedScoredOnTeam":
            case "TAGame.CarComponent_Boost_TA:ReplicatedBoostAmount":                     // Always 255?
            case "TAGame.CameraSettingsActor_TA:CameraPitch":
            case "TAGame.CameraSettingsActor_TA:CameraYaw":
            case "TAGame.PRI_TA:PawnType":
                asp.Data.Add(br.ReadByte());
                asp.MarkComplete();
                break;

            case "Engine.Actor:Location":
            case "TAGame.CarComponent_Dodge_TA:DodgeTorque":
                asp.Data.Add(Vector3D.Deserialize(br));
                asp.MarkComplete();
                break;

            case "Engine.Actor:bCollideWorld":
            case "Engine.PlayerReplicationInfo:bReadyToPlay":
            case "TAGame.Vehicle_TA:bReplicatedHandbrake":
            case "TAGame.Vehicle_TA:bDriving":
            case "Engine.Actor:bNetOwner":
            case "Engine.Actor:bBlockActors":
            case "TAGame.GameEvent_TA:bHasLeaveMatchPenalty":
            case "TAGame.PRI_TA:bUsingBehindView":
            case "TAGame.PRI_TA:bUsingSecondaryCamera":
            case "TAGame.GameEvent_TA:ActivatorCar":
            case "TAGame.GameEvent_Soccar_TA:bOverTime":
            case "ProjectX.GRI_X:bGameStarted":
            case "Engine.Actor:bCollideActors":
            case "TAGame.PRI_TA:bReady":
            case "TAGame.RBActor_TA:bFrozen":
            case "Engine.Actor:bHidden":
            case "TAGame.CarComponent_FlipCar_TA:bFlipRight":
            case "Engine.PlayerReplicationInfo:bBot":
            case "Engine.PlayerReplicationInfo:bWaitingPlayer":
            case "TAGame.RBActor_TA:bReplayActor":
            case "TAGame.PRI_TA:bIsInSplitScreen":
            case "Engine.GameReplicationInfo:bMatchIsOver":
            case "TAGame.CarComponent_Boost_TA:bUnlimitedBoost":
            case "Engine.PlayerReplicationInfo:bIsSpectator":
            case "TAGame.GameEvent_Soccar_TA:bBallHasBeenHit":
            case "TAGame.CameraSettingsActor_TA:bUsingSecondaryCamera":
            case "TAGame.CameraSettingsActor_TA:bUsingBehindView":
            case "TAGame.PRI_TA:bOnlineLoadoutSet":
            case "TAGame.PRI_TA:bMatchMVP":
            case "TAGame.PRI_TA:bOnlineLoadoutsSet":
            case "TAGame.RBActor_TA:bIgnoreSyncing":
            case "TAGame.SpecialPickup_BallVelcro_TA:bHit":
            case "TAGame.GameEvent_TA:bCanVoteToForfeit":
            case "TAGame.SpecialPickup_BallVelcro_TA:bBroken":
            case "TAGame.GameEvent_Team_TA:bForfeit":
                asp.Data.Add(br.ReadBit());
                asp.MarkComplete();
                break;

            case "TAGame.CarComponent_TA:ReplicatedActive":
                // The car component is active if (ReplicatedValue%2)!=0
                // For now I am only adding that logic to the JSON serializer
                asp.Data.Add(br.ReadByte());

                asp.MarkComplete();
                break;

            case "Engine.PlayerReplicationInfo:UniqueId":
                asp.Data.Add(UniqueId.Deserialize(br));
                asp.MarkComplete();
                break;

            case "TAGame.PRI_TA:PartyLeader":
                asp.Data.Add(PartyLeader.Deserialize(br));
                asp.MarkComplete();
                break;

            case "TAGame.PRI_TA:ClientLoadout":
                asp.Data.Add(ClientLoadout.Deserialize(br));
                asp.MarkComplete();
                break;

            case "TAGame.PRI_TA:CameraSettings":
            case "TAGame.CameraSettingsActor_TA:ProfileSettings":
                asp.Data.Add(CameraSettings.Deserialize(br));
                asp.MarkComplete();
                break;

            case "TAGame.Car_TA:TeamPaint":
                asp.Data.Add(TeamPaint.Deserialize(br));
                asp.MarkComplete();
                break;

            case "ProjectX.GRI_X:GameServerID":
                asp.Data.Add(br.ReadUInt32());
                asp.Data.Add(br.ReadUInt32());
                asp.MarkComplete();
                break;

            case "ProjectX.GRI_X:Reservations":
                asp.Data.Add(Reservation.Deserialize(versionMajor, versionMinor, br));
                asp.MarkComplete();
                break;

            case "TAGame.Ball_TA:ReplicatedExplosionData":
                asp.Data.Add(br.ReadBit());
                asp.Data.Add(br.ReadUInt32());
                asp.Data.Add(Vector3D.Deserialize(br));     // Almost definitely position
                asp.MarkComplete();
                break;

            case "TAGame.Car_TA:ReplicatedDemolish":
                asp.Data.Add(ReplicatedDemolish.Deserialize(br));
                asp.MarkComplete();
                break;

            case "TAGame.GameEvent_Soccar_TA:ReplicatedMusicStinger":
                asp.Data.Add(br.ReadBit());
                asp.Data.Add(br.ReadByte());
                asp.Data.Add(br.ReadUInt32());
                asp.MarkComplete();
                break;

            case "TAGame.CarComponent_FlipCar_TA:FlipCarTime":
            case "TAGame.Ball_TA:ReplicatedBallScale":
            case "TAGame.CarComponent_Boost_TA:RechargeDelay":
            case "TAGame.CarComponent_Boost_TA:RechargeRate":
            case "TAGame.Ball_TA:ReplicatedAddedCarBounceScale":
            case "TAGame.Ball_TA:ReplicatedBallMaxLinearSpeedScale":
            case "TAGame.Ball_TA:ReplicatedWorldBounceScale":
            case "TAGame.CarComponent_Boost_TA:BoostModifier":
            case "Engine.Actor:DrawScale":
            case "TAGame.CrowdActor_TA:ModifiedNoise":
            case "TAGame.CarComponent_TA:ReplicatedActivityTime":
            case "TAGame.SpecialPickup_BallFreeze_TA:RepOrigSpeed":
            case "TAGame.SpecialPickup_BallVelcro_TA:AttachTime":
            case "TAGame.SpecialPickup_BallVelcro_TA:BreakTime":
            case "TAGame.Car_TA:AddedCarForceMultiplier":
            case "TAGame.Car_TA:AddedBallForceMultiplier":
                asp.Data.Add(br.ReadFloat());
                asp.MarkComplete();
                break;

            case "TAGame.GameEvent_SoccarPrivate_TA:MatchSettings":
                asp.Data.Add(PrivateMatchSettings.Deserialize(br));
                asp.MarkComplete();
                break;

            case "TAGame.PRI_TA:ClientLoadoutOnline":
                asp.Data.Add(ClientLoadoutOnline.Deserialize(br));
                asp.MarkComplete();
                break;

            case "TAGame.GameEvent_TA:GameMode":
                if (versionMajor >= 868 && versionMinor >= 12)
                {
                    asp.Data.Add(br.ReadByte());
                }
                else
                {
                    asp.Data.Add(br.ReadUInt32Max(4));
                }
                asp.MarkComplete();
                break;

            case "TAGame.PRI_TA:ClientLoadoutsOnline":
                asp.Data.Add(ClientLoadoutsOnline.Deserialize(br));
                asp.MarkComplete();
                break;

            case "TAGame.PRI_TA:ClientLoadouts":
                asp.Data.Add(ClientLoadouts.Deserialize(br));
                asp.MarkComplete();
                break;

            case "TAGame.Team_TA:ClubColors":
            case "TAGame.Car_TA:ClubColors":
                asp.Data.Add(br.ReadBit());
                asp.Data.Add(br.ReadByte());
                asp.Data.Add(br.ReadBit());
                asp.Data.Add(br.ReadByte());
                asp.MarkComplete();
                break;

            case "TAGame.RBActor_TA:WeldedInfo":
                asp.Data.Add(WeldedInfo.Deserialize(br));
                asp.MarkComplete();
                break;

            default:
                throw new NotSupportedException(string.Format("Unknown property {0}. Next bits in the data are {1}. Figure it out!", asp.PropertyName, br.GetBits(br.Position, Math.Min(4096, br.Length - br.Position)).ToBinaryString()));
            }

#if DEBUG
            asp.KnownDataBits = br.GetBits(startPosition, br.Position - startPosition);
#endif
            return(asp);
        }
示例#5
0
        public static ActorState Deserialize(int maxChannels, IDictionary <UInt32, ActorState> existingActorStates, List <ActorState> frameActorStates, string[] objectIndexToName, IDictionary <string, ClassNetCache> classNetCacheByName, UInt32 engineVersion, UInt32 licenseeVersion, UInt32 netVersion, BitReader br)
        {
            var        startPosition = br.Position;
            ActorState a             = new ActorState();

            try
            {
                var actorId = br.ReadUInt32Max(maxChannels);

                a.Id = actorId;

                if (br.ReadBit())
                {
                    if (br.ReadBit())
                    {
                        a.State = ActorStateState.New;

                        if (engineVersion > 868 || (engineVersion == 868 && licenseeVersion >= 14))
                        {
                            a.NameId = br.ReadUInt32();
                        }

                        a.Unknown1 = br.ReadBit();
                        a.TypeId   = br.ReadUInt32();

                        var typeName = objectIndexToName[(int)a.TypeId.Value];
                        a._classNetCache = ObjectNameToClassNetCache(typeName, classNetCacheByName);
                        a.ClassId        = a._classNetCache.ObjectIndex;

                        if (!ClassHasInitialPosition(objectIndexToName[a.ClassId.Value]))
                        {
#if DEBUG
                            a.KnownBits = br.GetBits(startPosition, br.Position - startPosition);
                            a.Complete  = true;
#endif
                            return(a);
                        }

                        a.Position = Vector3D.Deserialize(br, netVersion);

                        if (ClassHasRotation(objectIndexToName[a.ClassId.Value]))
                        {
                            a.Rotation = Rotator.Deserialize(br);
                        }
#if DEBUG
                        a.Complete = true;
#endif
                    }
                    else
                    {
                        a.State = ActorStateState.Existing;
                        var oldState = existingActorStates[a.Id];

                        ActorStateProperty lastProp = null;
                        while (br.ReadBit())
                        {
                            lastProp = ActorStateProperty.Deserialize(oldState._classNetCache, objectIndexToName, engineVersion, licenseeVersion, netVersion, br);

                            ActorStateProperty existingProperty = null;
                            if (!a.Properties.TryGetValue(lastProp.PropertyId, out existingProperty))
                            {
                                a.Properties.Add(lastProp.PropertyId, lastProp);
                            }
                            else
                            {
                                // Combine this property's data into the existing property's data.
                                // TODO: If/When concrete property types are created, we should convert to an array type

                                // The "pretty" json serializer methods try hard to avoid serializing extra data.
                                // But, it gets confused by these cases where we have multiple properties with the same name on a single ActorState.
                                // The serializer could consider them all as a single array of values,
                                // but I think it makes more sense to treat them as an array in the parser.
                                // It probably more closely reflects the object in Rocket League that way.

                                // This implementation is a bit of a hack though. But the whole property class is a little hacky...

                                var listProperty = existingProperty as ActorStateListProperty;
                                if (listProperty == null)
                                {
                                    listProperty = new ActorStateListProperty(existingProperty);
                                    a.Properties[listProperty.PropertyId] = listProperty;
                                }

                                listProperty.Add(lastProp);
                            }
                        }

#if DEBUG
                        a.Complete = true;
#endif
                    }
                }
                else
                {
                    a.State = ActorStateState.Deleted;
#if DEBUG
                    a.Complete = true;
#endif
                    var endPosition = br.Position;
                }
#if DEBUG
                if (!a.Complete)
                {
                    // Read a bunch of data so we have something to look at in the logs
                    // Otherwise the logs may not show any data bits for whatever is broken, which is hard to interpret
                    br.ReadBytes(16);
                }

                a.KnownBits = br.GetBits(startPosition, br.Position - startPosition);
#endif
                return(a);
            }
            catch (Exception e)
            {
#if DEBUG
                a.KnownBits   = br.GetBits(startPosition, br.Position - startPosition);
                a.UnknownBits = br.GetBits(br.Position, 100);
                Console.WriteLine(e.ToString());
                a.Failed   = true;
                a.Complete = false;
                return(a);
#else
                throw;
#endif
            }
        }
示例#6
0
 public MyProperty(RocketLeagueReplayParser.NetworkStream.ActorStateProperty asp)
 {
     name  = asp.PropertyName;
     value = asp.Data.ToString();
 }
示例#7
0
        public static ActorStateProperty Deserialize(IClassNetCache classMap, string[] objectIndexToName, UInt32 engineVersion, UInt32 licenseeVersion, UInt32 netVersion, BitReader br)
        {
            var asp = new ActorStateProperty();

            asp._classNetCache = classMap;
            var maxPropId = classMap.MaxPropertyId;

            asp.PropertyId   = br.ReadUInt32Max(maxPropId + 1);
            asp.PropertyName = objectIndexToName[classMap.GetProperty((int)asp.PropertyId).Index];

            asp.Data = new List <object>();

            switch (asp.PropertyName)
            {
            case "TAGame.GameEvent_TA:ReplicatedStateIndex":
                asp.Data = br.ReadUInt32Max(140);     // number is made up, I dont know the max yet // TODO: Revisit this. It might work well enough, but looks fishy
                break;

            case "TAGame.RBActor_TA:ReplicatedRBState":
                asp.Data = RigidBodyState.Deserialize(br, netVersion);
                break;

            case "TAGame.Team_TA:LogoData":
                asp.Data = LogoData.Deserialize(br);
                break;

            case "TAGame.CrowdManager_TA:GameEvent":
            case "TAGame.CrowdActor_TA:GameEvent":
            case "TAGame.PRI_TA:PersistentCamera":
            case "TAGame.Team_TA:GameEvent":
            case "TAGame.Ball_TA:GameEvent":
            case "Engine.PlayerReplicationInfo:Team":
            case "Engine.Pawn:PlayerReplicationInfo":
            case "TAGame.PRI_TA:ReplicatedGameEvent":
            case "TAGame.CarComponent_TA:Vehicle":
            case "TAGame.Car_TA:AttachedPickup":
            case "TAGame.SpecialPickup_Targeted_TA:Targeted":
            case "TAGame.CameraSettingsActor_TA:PRI":
            case "TAGame.GameEvent_Soccar_TA:MVP":
            case "TAGame.GameEvent_Soccar_TA:MatchWinner":
            case "TAGame.GameEvent_Soccar_TA:GameWinner":
                asp.Data = ActiveActor.Deserialize(br);
                break;

            case "TAGame.CrowdManager_TA:ReplicatedGlobalOneShotSound":
            case "TAGame.CrowdActor_TA:ReplicatedOneShotSound":
            case "TAGame.GameEvent_TA:MatchTypeClass":
            case "Engine.GameReplicationInfo:GameClass":
            case "TAGame.GameEvent_Soccar_TA:SubRulesArchetype":
            case "TAGame.Ball_TA:ReplicatedPhysMatOverride":
                var objectTarget = ObjectTarget.Deserialize(br);
                asp.Data = objectTarget;
                ValidateObjectIndex(objectTarget.ObjectIndex, objectIndexToName);
                break;

            case "Engine.GameReplicationInfo:ServerName":
            case "Engine.PlayerReplicationInfo:PlayerName":
            case "TAGame.Team_TA:CustomTeamName":
            case "Engine.PlayerReplicationInfo:RemoteUserData":
            case "TAGame.GRI_TA:NewDedicatedServerIP":
            case "ProjectX.GRI_X:MatchGUID":
                asp.Data = br.ReadString();
                break;

            case "TAGame.GameEvent_Soccar_TA:SecondsRemaining":
            case "TAGame.GameEvent_TA:ReplicatedGameStateTimeRemaining":
            case "TAGame.CrowdActor_TA:ReplicatedCountDownNumber":
            case "TAGame.GameEvent_Team_TA:MaxTeamSize":
            case "Engine.PlayerReplicationInfo:PlayerID":
            case "TAGame.PRI_TA:TotalXP":
            case "TAGame.PRI_TA:MatchScore":
            case "TAGame.GameEvent_Soccar_TA:RoundNum":
            case "TAGame.GameEvent_TA:BotSkill":
            case "TAGame.PRI_TA:MatchShots":
            case "TAGame.PRI_TA:MatchSaves":
            case "ProjectX.GRI_X:ReplicatedGamePlaylist":
            case "Engine.TeamInfo:Score":
            case "Engine.PlayerReplicationInfo:Score":
            case "TAGame.PRI_TA:MatchGoals":
            case "TAGame.PRI_TA:MatchAssists":
            case "TAGame.PRI_TA:Title":
            case "TAGame.GameEvent_TA:ReplicatedStateName":
            case "TAGame.Team_Soccar_TA:GameScore":
            case "TAGame.GameEvent_Soccar_TA:GameTime":
            case "TAGame.CarComponent_Boost_TA:UnlimitedBoostRefCount":
            case "TAGame.CrowdActor_TA:ReplicatedRoundCountDownNumber":
            case "TAGame.Ball_Breakout_TA:DamageIndex":
            case "TAGame.PRI_TA:MatchBreakoutDamage":
            case "TAGame.PRI_TA:BotProductName":
            case "TAGame.GameEvent_TA:ReplicatedRoundCountDownNumber":
            case "TAGame.GameEvent_Soccar_TA:SeriesLength":
            case "TAGame.PRI_TA:SpectatorShortcut":
            case "Engine.Pawn:HealthMax":
                asp.Data = br.ReadUInt32();
                break;

            case "ProjectX.GRI_X:ReplicatedGameMutatorIndex":
            case "TAGame.PRI_TA:TimeTillItem":
            case "TAGame.PRI_TA:MaxTimeTillItem":
                asp.Data = br.ReadInt32();
                break;

            case "TAGame.VehiclePickup_TA:ReplicatedPickupData":
                asp.Data = ReplicatedPickupData.Deserialize(br);
                break;

            case "Engine.PlayerReplicationInfo:Ping":
            case "TAGame.Vehicle_TA:ReplicatedSteer":
            case "TAGame.Vehicle_TA:ReplicatedThrottle":     // 0: full reverse, 128: No throttle.  255 full throttle/boosting
            case "TAGame.PRI_TA:CameraYaw":
            case "TAGame.PRI_TA:CameraPitch":
            case "TAGame.Ball_TA:HitTeamNum":
            case "TAGame.GameEvent_Soccar_TA:ReplicatedScoredOnTeam":
            case "TAGame.CarComponent_Boost_TA:ReplicatedBoostAmount":
            case "TAGame.CameraSettingsActor_TA:CameraPitch":
            case "TAGame.CameraSettingsActor_TA:CameraYaw":
            case "TAGame.PRI_TA:PawnType":
            case "TAGame.Ball_Breakout_TA:LastTeamTouch":
            case "TAGame.Ball_Haunted_TA:LastTeamTouch":
            case "TAGame.PRI_TA:ReplicatedWorstNetQualityBeyondLatency":
            case "TAGame.GameEvent_Soccar_TA:ReplicatedServerPerformanceState":
            case "TAGame.Ball_Haunted_TA:TotalActiveBeams":
            case "TAGame.Ball_Haunted_TA:DeactivatedGoalIndex":
            case "TAGame.Ball_Haunted_TA:ReplicatedBeamBrokenValue":
                asp.Data = br.ReadByte();
                break;

            case "TAGame.PRI_TA:SkillTier":
                asp.Data = br.ReadUInt32Max(500);     // 9 bits. I picked a value that works, but could just be 1 bit + 1 byte instead of a single value.
                break;

            case "Engine.Actor:Location":
            case "TAGame.CarComponent_Dodge_TA:DodgeTorque":
                asp.Data = Vector3D.Deserialize(br, netVersion);
                break;

            case "Engine.Actor:bCollideWorld":
            case "Engine.PlayerReplicationInfo:bReadyToPlay":
            case "TAGame.Vehicle_TA:bReplicatedHandbrake":
            case "TAGame.Vehicle_TA:bDriving":
            case "Engine.Actor:bNetOwner":
            case "Engine.Actor:bBlockActors":
            case "TAGame.GameEvent_TA:bHasLeaveMatchPenalty":
            case "TAGame.PRI_TA:bUsingBehindView":
            case "TAGame.PRI_TA:bUsingSecondaryCamera":     // Ball cam on when true
            case "TAGame.GameEvent_TA:ActivatorCar":
            case "TAGame.GameEvent_Soccar_TA:bOverTime":
            case "ProjectX.GRI_X:bGameStarted":
            case "Engine.Actor:bCollideActors":
            case "TAGame.PRI_TA:bReady":
            case "TAGame.RBActor_TA:bFrozen":
            case "Engine.Actor:bHidden":
            case "TAGame.CarComponent_FlipCar_TA:bFlipRight":
            case "Engine.PlayerReplicationInfo:bBot":
            case "Engine.PlayerReplicationInfo:bWaitingPlayer":
            case "TAGame.RBActor_TA:bReplayActor":
            case "TAGame.PRI_TA:bIsInSplitScreen":
            case "Engine.GameReplicationInfo:bMatchIsOver":
            case "TAGame.CarComponent_Boost_TA:bUnlimitedBoost":
            case "Engine.PlayerReplicationInfo:bIsSpectator":
            case "TAGame.GameEvent_Soccar_TA:bBallHasBeenHit":
            case "TAGame.CameraSettingsActor_TA:bUsingSecondaryCamera":
            case "TAGame.CameraSettingsActor_TA:bUsingBehindView":
            case "TAGame.PRI_TA:bOnlineLoadoutSet":
            case "TAGame.PRI_TA:bMatchMVP":
            case "TAGame.PRI_TA:bOnlineLoadoutsSet":
            case "TAGame.RBActor_TA:bIgnoreSyncing":
            case "TAGame.SpecialPickup_BallVelcro_TA:bHit":
            case "TAGame.GameEvent_TA:bCanVoteToForfeit":
            case "TAGame.SpecialPickup_BallVelcro_TA:bBroken":
            case "TAGame.GameEvent_Team_TA:bForfeit":
            case "TAGame.PRI_TA:bUsingItems":
            case "TAGame.VehiclePickup_TA:bNoPickup":
            case "TAGame.CarComponent_Boost_TA:bNoBoost":
            case "TAGame.PRI_TA:PlayerHistoryValid":
            case "TAGame.GameEvent_Soccar_TA:bUnlimitedTime":
            case "TAGame.GameEvent_Soccar_TA:bClubMatch":
            case "TAGame.GameEvent_Soccar_TA:bMatchEnded":
            case "TAGame.GameEvent_TA:bAllowReadyUp":
            case "Engine.Actor:bTearOff":
            case "Engine.PlayerReplicationInfo:bTimedOut":
            case "TAGame.CameraSettingsActor_TA:bMouseCameraToggleEnabled":
            case "TAGame.CameraSettingsActor_TA:bUsingSwivel":
            case "TAGame.Ball_Haunted_TA:bIsBallBeamed":
            case "TAGame.SpecialPickup_Rugby_TA:bBallWelded":
                asp.Data = br.ReadBit();
                break;

            case "TAGame.CarComponent_TA:ReplicatedActive":
                // The car component is active if (ReplicatedValue%2)!=0
                // For now I am only adding that logic to the JSON serializer
                asp.Data = br.ReadByte();
                break;

            case "Engine.PlayerReplicationInfo:UniqueId":
                asp.Data = UniqueId.Deserialize(br, licenseeVersion, netVersion);
                break;

            case "TAGame.PRI_TA:PartyLeader":
                asp.Data = PartyLeader.Deserialize(br, licenseeVersion, netVersion);
                break;

            case "TAGame.PRI_TA:ClientLoadout":
                asp.Data = ClientLoadout.Deserialize(br);
                break;

            case "TAGame.PRI_TA:CameraSettings":
            case "TAGame.CameraSettingsActor_TA:ProfileSettings":
                asp.Data = CameraSettings.Deserialize(br, engineVersion, licenseeVersion);
                break;

            case "TAGame.Car_TA:TeamPaint":
                asp.Data = TeamPaint.Deserialize(br);
                break;

            case "ProjectX.GRI_X:GameServerID":
                asp.Data = br.ReadBytes(8);
                break;

            case "ProjectX.GRI_X:Reservations":
                asp.Data = Reservation.Deserialize(engineVersion, licenseeVersion, netVersion, br);
                break;

            case "TAGame.Car_TA:ReplicatedDemolish":
                asp.Data = ReplicatedDemolish.Deserialize(br, netVersion);
                break;

            case "TAGame.GameEvent_Soccar_TA:ReplicatedMusicStinger":
                asp.Data = ReplicatedMusicStinger.Deserialize(br);
                break;

            case "TAGame.CarComponent_FlipCar_TA:FlipCarTime":
            case "TAGame.Ball_TA:ReplicatedBallScale":
            case "TAGame.CarComponent_Boost_TA:RechargeDelay":
            case "TAGame.CarComponent_Boost_TA:RechargeRate":
            case "TAGame.Ball_TA:ReplicatedAddedCarBounceScale":
            case "TAGame.Ball_TA:ReplicatedBallMaxLinearSpeedScale":
            case "TAGame.Ball_TA:ReplicatedWorldBounceScale":
            case "TAGame.CarComponent_Boost_TA:BoostModifier":
            case "Engine.Actor:DrawScale":
            case "TAGame.CrowdActor_TA:ModifiedNoise":
            case "TAGame.CarComponent_TA:ReplicatedActivityTime":
            case "TAGame.SpecialPickup_BallFreeze_TA:RepOrigSpeed":
            case "TAGame.SpecialPickup_BallVelcro_TA:AttachTime":
            case "TAGame.SpecialPickup_BallVelcro_TA:BreakTime":
            case "TAGame.Car_TA:AddedCarForceMultiplier":
            case "TAGame.Car_TA:AddedBallForceMultiplier":
            case "TAGame.PRI_TA:SteeringSensitivity":
            case "TAGame.Car_TA:ReplicatedCarScale":
            case "Engine.WorldInfo:WorldGravityZ":
            case "Engine.WorldInfo:TimeDilation":
                asp.Data = br.ReadFloat();
                break;

            case "TAGame.GameEvent_SoccarPrivate_TA:MatchSettings":
                asp.Data = PrivateMatchSettings.Deserialize(br);
                break;

            case "TAGame.PRI_TA:ClientLoadoutOnline":
                asp.Data = ClientLoadoutOnline.Deserialize(br, engineVersion, licenseeVersion, objectIndexToName);
                break;

            case "TAGame.GameEvent_TA:GameMode":
                if (engineVersion >= 868 && licenseeVersion >= 12)
                {
                    asp.Data = br.ReadByte();
                }
                else
                {
                    asp.Data = br.ReadUInt32Max(4);
                }
                break;

            case "TAGame.PRI_TA:ClientLoadoutsOnline":
                asp.Data = ClientLoadoutsOnline.Deserialize(br, engineVersion, licenseeVersion, objectIndexToName);
                break;

            case "TAGame.PRI_TA:ClientLoadouts":
                asp.Data = ClientLoadouts.Deserialize(br);
                break;

            case "TAGame.Team_TA:ClubColors":
            case "TAGame.Car_TA:ClubColors":
                asp.Data = ClubColors.Deserialize(br);
                break;

            case "TAGame.RBActor_TA:WeldedInfo":
                asp.Data = WeldedInfo.Deserialize(br, netVersion);
                break;

            case "TAGame.BreakOutActor_Platform_TA:DamageState":
                asp.Data = DamageState.Deserialize(br, netVersion);
                break;

            case "TAGame.Ball_Breakout_TA:AppliedDamage":
                asp.Data = AppliedDamage.Deserialize(br, netVersion);
                break;

            case "TAGame.Ball_TA:ReplicatedExplosionData":
                asp.Data = ReplicatedExplosionData.Deserialize(br, netVersion);
                break;

            case "TAGame.Ball_TA:ReplicatedExplosionDataExtended":
                asp.Data = ReplicatedExplosionDataExtended.Deserialize(br, netVersion);
                break;

            case "TAGame.PRI_TA:SecondaryTitle":
            case "TAGame.PRI_TA:PrimaryTitle":
                asp.Data = Title.Deserialize(br);
                break;

            case "TAGame.PRI_TA:PlayerHistoryKey":
                // Betting ReadUInt32Max is more likely, since 14 bits is a weird number
                asp.Data = br.ReadUInt32FromBits(14);
                break;

            case "TAGame.GameEvent_Soccar_TA:ReplicatedStatEvent":
                asp.Data = ReplicatedStatEvent.Deserialize(br);
                break;

            case "TAGame.Team_TA:ClubID":
            case "TAGame.PRI_TA:ClubID":
                asp.Data = br.ReadUInt64();
                break;

            case "TAGame.PRI_TA:RepStatTitles":
                asp.Data = RepStatTitle.Deserialize(br);
                break;

            case "TAGame.VehiclePickup_TA:NewReplicatedPickupData":
                asp.Data = NewReplicatedPickupData.Deserialize(br);
                break;

            default:
                throw new NotSupportedException(string.Format("Unknown property {0}. Next bits in the data are {1}. Figure it out!", asp.PropertyName, br.GetBits(br.Position, Math.Min(4096, br.Length - br.Position)).ToBinaryString()));
            }

            return(asp);
        }
示例#8
0
        public static ActorState Deserialize(int maxChannels, List <ActorState> existingActorStates, List <ActorState> frameActorStates, string[] objectIndexToName, IDictionary <string, ClassNetCache> classNetCacheByName, UInt32 engineVersion, UInt32 licenseeVersion, UInt32 netVersion, BitReader br)
        {
            var        startPosition = br.Position;
            ActorState a             = new ActorState();

            try
            {
                var actorId = br.ReadUInt32Max(maxChannels);

                a.Id = actorId;

                if (br.ReadBit())
                {
                    if (br.ReadBit())
                    {
                        a.State = ActorStateState.New;

                        if (engineVersion > 868 || (engineVersion == 868 && licenseeVersion >= 14))
                        {
                            a.NameId = br.ReadUInt32();
                        }

                        a.Unknown1 = br.ReadBit();
                        a.TypeId   = br.ReadUInt32();

                        a.TypeName       = objectIndexToName[(int)a.TypeId.Value];
                        a._classNetCache = ObjectNameToClassNetCache(a.TypeName, classNetCacheByName);
                        a.ClassName      = objectIndexToName[a._classNetCache.ObjectIndex];

                        if (!ClassHasInitialPosition(a.ClassName))
                        {
#if DEBUG
                            a.KnownBits = br.GetBits(startPosition, br.Position - startPosition);
                            a.Complete  = true;
#endif
                            return(a);
                        }

                        a.Position = Vector3D.Deserialize(br);

                        if (ClassHasRotation(a.ClassName))
                        {
                            a.Rotation = Rotator.Deserialize(br);
                        }
#if DEBUG
                        a.Complete = true;
#endif
                    }
                    else
                    {
                        a.State = ActorStateState.Existing;
                        var oldState = existingActorStates.Where(x => x.Id == a.Id).Single();

                        a.TypeId = oldState.TypeId;

                        a.Properties = new List <ActorStateProperty>();
                        ActorStateProperty lastProp = null;
                        while (br.ReadBit())
                        {
                            lastProp = ActorStateProperty.Deserialize(oldState._classNetCache, oldState.TypeName, objectIndexToName, engineVersion, licenseeVersion, netVersion, br);
                            a.Properties.Add(lastProp);

#if DEBUG
                            if (!lastProp.IsComplete)
                            {
                                break;
                            }
#endif
                        }

#if DEBUG
                        a.Complete = lastProp.IsComplete;
                        if (lastProp.Data.Count > 0 && lastProp.Data.Last().ToString() == "FAILED")
                        {
                            a.Failed = true;
                        }
#endif
                        var endPosition = br.Position;
                    }
                }
                else
                {
                    a.State = ActorStateState.Deleted;

                    var actor = existingActorStates.Where(x => x.Id == a.Id).SingleOrDefault();
#if DEBUG
                    a.Complete = true;
#endif
                    var endPosition = br.Position;
                }
#if DEBUG
                if (!a.Complete)
                {
                    // Read a bunch of data so we have something to look at in the logs
                    // Otherwise the logs may not show any data bits for whatever is broken, which is hard to interpret
                    br.ReadBytes(16);
                }

                a.KnownBits = br.GetBits(startPosition, br.Position - startPosition);
#endif
                return(a);
            }
            catch (Exception e)
            {
#if DEBUG
                a.KnownBits   = br.GetBits(startPosition, br.Position - startPosition);
                a.UnknownBits = br.GetBits(br.Position, 100);
                Console.WriteLine(e.ToString());
                a.Failed   = true;
                a.Complete = false;
                return(a);
#else
                throw;
#endif
            }
        }
示例#9
0
        public static ActorState Deserialize(int maxChannels, List <ActorState> existingActorStates, List <ActorState> frameActorStates, string[] objectIndexToName, IEnumerable <ClassNetCache> classNetCache, BitReader br)
        {
            var        startPosition = br.Position;
            ActorState a             = new ActorState();

            try
            {
                var actorId = br.ReadInt32Max(maxChannels);

                a.Id = actorId;

                if (br.ReadBit())
                {
                    if (br.ReadBit())
                    {
                        a.State    = ActorStateState.New;
                        a.Unknown1 = br.ReadBit();

                        a.TypeId = br.ReadInt32();

                        a.TypeName = objectIndexToName[(int)a.TypeId.Value];
                        var classMap = ObjectNameToClassNetCache(a.TypeName, objectIndexToName, classNetCache);
                        a.ClassName = objectIndexToName[classMap.ObjectIndex];

                        if (a.ClassName == "TAGame.CrowdActor_TA" ||
                            a.ClassName == "TAGame.CrowdManager_TA" ||
                            a.ClassName == "TAGame.VehiclePickup_Boost_TA" ||
                            a.ClassName == "Core.Object")
                        {
#if DEBUG
                            a.KnownBits = br.GetBits(startPosition, br.Position - startPosition);
                            a.Complete  = true;
#endif
                            return(a);
                        }

                        a.Position = Vector3D.Deserialize(br);

                        if (a.ClassName == "Engine.GameReplicationInfo" ||
                            a.ClassName == "TAGame.GameEvent_SoccarSplitscreen_TA" ||
                            a.ClassName == "TAGame.CarComponent_Boost_TA" ||
                            a.ClassName == "TAGame.CarComponent_Jump_TA" ||
                            a.ClassName == "TAGame.CarComponent_DoubleJump_TA" ||
                            a.ClassName == "TAGame.CarComponent_Dodge_TA" ||
                            a.ClassName == "TAGame.CarComponent_FlipCar_TA" ||
                            a.ClassName == "TAGame.Team_TA" ||                             // Team1 = Orange, Team0 = Blue (probably different for season mode)
                            a.ClassName == "TAGame.PRI_TA" ||
                            a.ClassName == "TAGame.GameEvent_Soccar_TA" ||
                            a.ClassName == "TAGame.GRI_TA" ||
                            a.ClassName == "TAGame.GameEvent_SoccarPrivate_TA" ||
                            a.ClassName == "TAGame.GameEvent_Season_TA")
                        {
#if DEBUG
                            a.Complete = true;
#endif
                        }
                        else if (a.ClassName == "TAGame.Ball_TA" ||
                                 a.ClassName == "TAGame.Car_TA" ||
                                 a.ClassName == "TAGame.Car_Season_TA")
                        {
                            if (br.ReadBit())
                            {
                                br.ReadByte();
                            }
                            if (br.ReadBit())
                            {
                                br.ReadByte();
                            }
                            if (br.ReadBit())
                            {
                                br.ReadByte();
                            }
#if DEBUG
                            a.Complete = true;
#endif
                        }
                    }
                    else
                    {
                        a.State    = ActorStateState.Existing;
                        a.TypeId   = existingActorStates.Where(x => x.Id == a.Id).Single().TypeId;
                        a.TypeName = objectIndexToName[(int)a.TypeId.Value];
                        var classMap = ObjectNameToClassNetCache(a.TypeName, objectIndexToName, classNetCache);
                        a.ClassName = objectIndexToName[classMap.ObjectIndex];

                        a.Properties = new List <ActorStateProperty>();
                        ActorStateProperty lastProp = null;
                        while (br.ReadBit())
                        {
                            lastProp = ActorStateProperty.Deserialize(classMap, objectIndexToName, br);
                            a.Properties.Add(lastProp);

#if DEBUG
                            if (!lastProp.IsComplete)
                            {
                                break;
                            }
#endif
                        }

#if DEBUG
                        a.Complete = lastProp.IsComplete;
                        if (lastProp.Data.Count > 0 && lastProp.Data.Last().ToString() == "FAILED")
                        {
                            a.Failed = true;
                        }
#endif
                        var endPosition = br.Position;
                    }
                }
                else
                {
                    a.State = ActorStateState.Deleted;

                    var actor = existingActorStates.Where(x => x.Id == a.Id).SingleOrDefault();
                    if (actor != null)                     // TODO remove this someday. Only here because we might be deleting objects we havent figured out how to parse yet
                    {
                        a.TypeId   = actor.TypeId;
                        a.TypeName = objectIndexToName[(int)a.TypeId.Value];
                        var classMap = ObjectNameToClassNetCache(a.TypeName, objectIndexToName, classNetCache);
                        a.ClassName = objectIndexToName[classMap.ObjectIndex];
                    }
#if DEBUG
                    a.Complete = true;
#endif
                    var endPosition = br.Position;
                }
#if DEBUG
                if (!a.Complete)
                {
                    // Read a bunch of data so we have something to look at in the logs
                    // Otherwise the logs may not show any data bits for whatever is broken, which is hard to interpret
                    br.ReadBytes(16);
                }

                a.KnownBits = br.GetBits(startPosition, br.Position - startPosition);
#endif
                return(a);
            }
            catch (Exception e)
            {
#if DEBUG
                a.KnownBits   = br.GetBits(startPosition, br.Position - startPosition);
                a.UnknownBits = br.GetBits(br.Position, 100);
                Console.WriteLine(e.ToString());
                a.Failed   = true;
                a.Complete = false;
                return(a);
#else
                throw;
#endif
            }
        }
        public static ActorStateProperty Deserialize(IClassNetCache classMap, string[] objectIndexToName, BitReader br)
        {
            var asp = new ActorStateProperty();

            var maxPropId = classMap.MaxPropertyId;

            var className = objectIndexToName[classMap.ObjectIndex];

            asp.PropertyId = br.ReadInt32Max(maxPropId + 1);
#if DEBUG
            asp.MaxPropertyId = maxPropId;
#endif
            asp.PropertyName = objectIndexToName[classMap.GetProperty(asp.PropertyId).Index];

            var startPosition = br.Position;

            asp.Data = new List <object>();

            switch (asp.PropertyName)
            {
            case "TAGame.GameEvent_TA:ReplicatedStateIndex":
                asp.Data.Add(br.ReadInt32Max(140));     // number is made up, I dont know the max yet // TODO: Revisit this. It might work well enough, but looks fishy
                asp.MarkComplete();
                break;

            case "TAGame.RBActor_TA:ReplicatedRBState":
                asp.Data.Add(RigidBodyState.Deserialize(br));
                asp.MarkComplete();
                break;

            case "TAGame.Team_TA:GameEvent":
            case "TAGame.CrowdActor_TA:ReplicatedOneShotSound":
            case "TAGame.CrowdManager_TA:ReplicatedGlobalOneShotSound":
            case "Engine.Actor:Owner":
            case "Engine.GameReplicationInfo:GameClass":
            case "Engine.PlayerReplicationInfo:Team":
            case "TAGame.CrowdManager_TA:GameEvent":
            case "Engine.Pawn:PlayerReplicationInfo":     // Actor Id. Ties cars to players
            case "TAGame.PRI_TA:ReplicatedGameEvent":
            case "TAGame.Ball_TA:GameEvent":
            case "TAGame.CrowdActor_TA:GameEvent":
            case "TAGame.Team_TA:LogoData":
                asp.Data.Add(br.ReadBit());
                asp.Data.Add(br.ReadInt32());
                asp.MarkComplete();
                break;

            case "TAGame.CarComponent_TA:Vehicle":
                asp.Data.Add(br.ReadBit());
                asp.Data.Add(br.ReadInt32());
                asp.MarkComplete();
                break;

            case "Engine.GameReplicationInfo:ServerName":
            case "Engine.PlayerReplicationInfo:PlayerName":
            case "TAGame.Team_TA:CustomTeamName":
                asp.Data.Add(br.ReadString());
                asp.MarkComplete();
                break;

            case "TAGame.GameEvent_Soccar_TA:SecondsRemaining":
            case "TAGame.GameEvent_TA:ReplicatedGameStateTimeRemaining":
            case "TAGame.CrowdActor_TA:ReplicatedCountDownNumber":
            case "TAGame.GameEvent_Team_TA:MaxTeamSize":
            case "Engine.PlayerReplicationInfo:PlayerID":
            case "TAGame.PRI_TA:TotalXP":
            case "TAGame.PRI_TA:MatchScore":
            case "TAGame.GameEvent_Soccar_TA:RoundNum":
            case "TAGame.GameEvent_TA:BotSkill":
            case "TAGame.PRI_TA:MatchShots":
            case "TAGame.PRI_TA:MatchSaves":
            case "ProjectX.GRI_X:ReplicatedGamePlaylist":
            case "Engine.TeamInfo:Score":
            case "Engine.PlayerReplicationInfo:Score":
            case "TAGame.PRI_TA:MatchGoals":
            case "TAGame.PRI_TA:MatchAssists":
            case "ProjectX.GRI_X:ReplicatedGameMutatorIndex":
            case "TAGame.PRI_TA:Title":
                asp.Data.Add(br.ReadInt32());
                asp.MarkComplete();
                break;

            case "TAGame.VehiclePickup_TA:ReplicatedPickupData":
                // 1011101000000000000000000000000001
                // 0111111111111111111111111111111110
                // 1111001000000000000000000000000001
                // 1000001000000000000000000000000001
                // 1111110000000000000000000000000001
                // 1101110000000000000000000000000001

                // reverify the above data, especially the short stuff
                asp.Data.Add(br.ReadBit());
                asp.Data.Add(br.ReadInt32());
                asp.Data.Add(br.ReadBit());

                asp.MarkComplete();
                break;

            case "Engine.PlayerReplicationInfo:Ping":
            case "TAGame.Vehicle_TA:ReplicatedSteer":
            case "TAGame.Vehicle_TA:ReplicatedThrottle":     // 0: full reverse, 128: No throttle.  255 full throttle/boosting
            case "TAGame.PRI_TA:CameraYaw":
            case "TAGame.PRI_TA:CameraPitch":
            case "TAGame.Ball_TA:HitTeamNum":
            case "TAGame.GameEvent_Soccar_TA:ReplicatedScoredOnTeam":
            case "TAGame.CarComponent_Boost_TA:ReplicatedBoostAmount":                     // Always 255?
                asp.Data.Add(br.ReadByte());
                asp.MarkComplete();
                break;

            case "Engine.Actor:Location":
            case "TAGame.CarComponent_Dodge_TA:DodgeTorque":
                asp.Data.Add(Vector3D.Deserialize(br));
                asp.MarkComplete();
                break;

            case "Engine.Actor:bCollideWorld":
            case "Engine.PlayerReplicationInfo:bReadyToPlay":
            case "TAGame.Vehicle_TA:bReplicatedHandbrake":
            case "TAGame.Vehicle_TA:bDriving":
            case "Engine.Actor:bNetOwner":
            case "Engine.Actor:bBlockActors":
            case "TAGame.GameEvent_TA:bHasLeaveMatchPenalty":
            case "TAGame.PRI_TA:bUsingBehindView":
            case "TAGame.PRI_TA:bUsingSecondaryCamera":
            case "TAGame.GameEvent_TA:ActivatorCar":
            case "TAGame.GameEvent_Soccar_TA:bOverTime":
            case "ProjectX.GRI_X:bGameStarted":
            case "Engine.Actor:bCollideActors":
            case "TAGame.PRI_TA:bReady":
            case "TAGame.RBActor_TA:bFrozen":
            case "Engine.Actor:bHidden":
            case "TAGame.CarComponent_FlipCar_TA:bFlipRight":
            case "Engine.PlayerReplicationInfo:bBot":
            case "Engine.PlayerReplicationInfo:bWaitingPlayer":
            case "TAGame.RBActor_TA:bReplayActor":
            case "TAGame.PRI_TA:bIsInSplitScreen":
            case "Engine.GameReplicationInfo:bMatchIsOver":
            case "TAGame.CarComponent_Boost_TA:bUnlimitedBoost":
            case "Engine.PlayerReplicationInfo:bIsSpectator":
            case "TAGame.GameEvent_Soccar_TA:bBallHasBeenHit":
                asp.Data.Add(br.ReadBit());
                asp.MarkComplete();
                break;

            case "TAGame.CarComponent_TA:ReplicatedActive":
                // The car component is active if (ReplicatedValue%2)!=0
                // For now I am only adding that logic to the JSON serializer
                asp.Data.Add(br.ReadByte());

                asp.MarkComplete();
                break;

            case "Engine.PlayerReplicationInfo:UniqueId":
            case "TAGame.PRI_TA:PartyLeader":
                asp.Data.Add(UniqueId.Deserialize(br));
                asp.MarkComplete();
                break;

            case "TAGame.PRI_TA:ClientLoadout":
                asp.Data.Add(ClientLoadout.Deserialize(br));
                asp.MarkComplete();
                break;

            case "TAGame.PRI_TA:CameraSettings":
                asp.Data.Add(CameraSettings.Deserialize(br));
                asp.MarkComplete();
                break;

            case "TAGame.Car_TA:TeamPaint":
                asp.Data.Add(TeamPaint.Deserialize(br));
                asp.MarkComplete();
                break;

            case "ProjectX.GRI_X:GameServerID":
                asp.Data.Add(br.ReadInt32());
                asp.Data.Add(br.ReadInt32());
                asp.MarkComplete();
                break;

            case "ProjectX.GRI_X:Reservations":
                asp.Data.Add(Reservation.Deserialize(br));
                asp.MarkComplete();
                break;

            case "TAGame.Ball_TA:ReplicatedExplosionData":
                // 0 01010111000000000000000000000000 0011 01010010000001 01111010001011 00000110000001
                // 0 01110111000000000000000000000000 0011 10011110010001 11111010001011 01010110000001
                // 0 11010111000000000000000000000000 0011 00001111011110 11000110001011 10111010000001
                // 0 11010111000000000000000000000000 0011 10011000100001 00100110001011 10111010000001
                // 0 00110111000000000000000000000000 0011 00000001010001 11000110001011 00100110000001
                asp.Data.Add(br.ReadBit());
                asp.Data.Add(br.ReadInt32());
                asp.Data.Add(Vector3D.Deserialize(br));     // Almost definitely position
                asp.MarkComplete();
                break;

            case "TAGame.Car_TA:ReplicatedDemolish":
                asp.Data.Add(ReplicatedDemolish.Deserialize(br));
                asp.MarkComplete();
                break;

            case "TAGame.GameEvent_Soccar_TA:ReplicatedMusicStinger":
                asp.Data.Add(br.ReadBit());
                asp.Data.Add(br.ReadByte());
                asp.Data.Add(br.ReadInt32());
                asp.MarkComplete();
                break;

            case "TAGame.CarComponent_FlipCar_TA:FlipCarTime":
            case "TAGame.Ball_TA:ReplicatedBallScale":
            case "TAGame.CarComponent_Boost_TA:RechargeDelay":
            case "TAGame.CarComponent_Boost_TA:RechargeRate":
            case "TAGame.Ball_TA:ReplicatedAddedCarBounceScale":
            case "TAGame.Ball_TA:ReplicatedBallMaxLinearSpeedScale":
            case "TAGame.Ball_TA:ReplicatedWorldBounceScale":
            case "TAGame.CarComponent_Boost_TA:BoostModifier":
            case "Engine.Actor:DrawScale":
            case "TAGame.CrowdActor_TA:ModifiedNoise":
                asp.Data.Add(br.ReadFloat());
                asp.MarkComplete();
                break;

            case "TAGame.GameEvent_SoccarPrivate_TA:MatchSettings":
                asp.Data.Add(PrivateMatchSettings.Deserialize(br));
                asp.MarkComplete();
                break;

            case "TAGame.PRI_TA:ClientLoadoutOnline":
                asp.Data.Add(br.ReadInt32());
                asp.Data.Add(br.ReadInt32());
                asp.Data.Add(br.ReadInt32());
                asp.MarkComplete();
                break;

            default:
                throw new NotSupportedException(string.Format("Unknown property {0}. Next bits in the data are {1}. Figure it out!", asp.PropertyName, br.GetBits(br.Position, Math.Min(4096, br.Length - br.Position)).ToBinaryString()));
            }

#if DEBUG
            asp.KnownDataBits = br.GetBits(startPosition, br.Position - startPosition);
#endif
            return(asp);
        }
 public ActorStateListProperty(ActorStateProperty convertFromProperty) : base(convertFromProperty)
 {
     Data = new List <object> {
         convertFromProperty.Data
     };
 }
        public static ActorStateProperty Deserialize(IClassNetCache classMap, string typeName, string[] objectIndexToName, UInt32 versionMajor, UInt32 versionMinor, BitReader br)
        {
            var asp = new ActorStateProperty();

            var maxPropId = classMap.MaxPropertyId;

            var className = objectIndexToName[classMap.ObjectIndex];
            asp.PropertyId = br.ReadUInt32Max(maxPropId + 1);
            #if DEBUG
            asp.MaxPropertyId = (UInt32)maxPropId;
            #endif
            asp.PropertyName = objectIndexToName[classMap.GetProperty((int)asp.PropertyId).Index];

            var startPosition = br.Position;

            asp.Data = new List<object>();

            switch (asp.PropertyName)
            {
                case "TAGame.GameEvent_TA:ReplicatedStateIndex":
                    asp.Data.Add(br.ReadUInt32Max(140)); // number is made up, I dont know the max yet // TODO: Revisit this. It might work well enough, but looks fishy
                    asp.MarkComplete();
                    break;
                case "TAGame.RBActor_TA:ReplicatedRBState":
                    asp.Data.Add(RigidBodyState.Deserialize(br));
                    asp.MarkComplete();
                    break;
                case "TAGame.CrowdActor_TA:ReplicatedOneShotSound":
                case "TAGame.CrowdManager_TA:ReplicatedGlobalOneShotSound":
                case "Engine.GameReplicationInfo:GameClass":
                case "TAGame.CrowdManager_TA:GameEvent":
                case "TAGame.CrowdActor_TA:GameEvent":
                case "TAGame.Team_TA:LogoData":
                case "TAGame.CameraSettingsActor_TA:PRI":
                case "TAGame.PRI_TA:PersistentCamera":
                case "TAGame.GameEvent_TA:MatchTypeClass":
                case "TAGame.GameEvent_Soccar_TA:SubRulesArchetype":
                    // Theres a good chance that most of these can be moved to the next section
                    asp.Data.Add(br.ReadBit());
                    asp.Data.Add(br.ReadUInt32());
                    asp.MarkComplete();
                    break;
                case "TAGame.Team_TA:GameEvent":
                case "TAGame.Ball_TA:GameEvent":
                case "Engine.PlayerReplicationInfo:Team":
                case "Engine.Pawn:PlayerReplicationInfo":
                case "TAGame.PRI_TA:ReplicatedGameEvent":
                case "TAGame.CarComponent_TA:Vehicle":
                case "TAGame.Car_TA:AttachedPickup":
                case "TAGame.SpecialPickup_Targeted_TA:Targeted":
                    // TODO: Use a real class so it can be accessed normally.
                    // If Active == false, ActorId will be -1
                    asp.Data.Add(ActiveActor.Deserialize(br));
                    asp.MarkComplete();
                    break;
                case "Engine.GameReplicationInfo:ServerName":
                case "Engine.PlayerReplicationInfo:PlayerName":
                case "TAGame.Team_TA:CustomTeamName":
                case "Engine.PlayerReplicationInfo:RemoteUserData":
                case "TAGame.GRI_TA:NewDedicatedServerIP":
                    asp.Data.Add(br.ReadString());
                    asp.MarkComplete();
                    break;
                case "TAGame.GameEvent_Soccar_TA:SecondsRemaining":
                case "TAGame.GameEvent_TA:ReplicatedGameStateTimeRemaining":
                case "TAGame.CrowdActor_TA:ReplicatedCountDownNumber":
                case "TAGame.GameEvent_Team_TA:MaxTeamSize":
                case "Engine.PlayerReplicationInfo:PlayerID":
                case "TAGame.PRI_TA:TotalXP":
                case "TAGame.PRI_TA:MatchScore":
                case "TAGame.GameEvent_Soccar_TA:RoundNum":
                case "TAGame.GameEvent_TA:BotSkill":
                case "TAGame.PRI_TA:MatchShots":
                case "TAGame.PRI_TA:MatchSaves":
                case "ProjectX.GRI_X:ReplicatedGamePlaylist":
                case "Engine.TeamInfo:Score":
                case "Engine.PlayerReplicationInfo:Score":
                case "TAGame.PRI_TA:MatchGoals":
                case "TAGame.PRI_TA:MatchAssists":
                case "ProjectX.GRI_X:ReplicatedGameMutatorIndex":
                case "TAGame.PRI_TA:Title":
                case "TAGame.GameEvent_TA:ReplicatedStateName":
                case "TAGame.Team_Soccar_TA:GameScore":
                case "TAGame.GameEvent_Soccar_TA:GameTime":
                case "TAGame.CarComponent_Boost_TA:UnlimitedBoostRefCount":
                case "TAGame.CrowdActor_TA:ReplicatedRoundCountDownNumber":
                    asp.Data.Add(br.ReadUInt32());
                    asp.MarkComplete();
                    break;
                case "TAGame.VehiclePickup_TA:ReplicatedPickupData":
                    asp.Data.Add(br.ReadBit());
                    asp.Data.Add(br.ReadUInt32());
                    asp.Data.Add(br.ReadBit());

                    asp.MarkComplete();
                    break;
                case "Engine.PlayerReplicationInfo:Ping":
                case "TAGame.Vehicle_TA:ReplicatedSteer":
                case "TAGame.Vehicle_TA:ReplicatedThrottle": // 0: full reverse, 128: No throttle.  255 full throttle/boosting
                case "TAGame.PRI_TA:CameraYaw":
                case "TAGame.PRI_TA:CameraPitch":
                case "TAGame.Ball_TA:HitTeamNum":
                case "TAGame.GameEvent_Soccar_TA:ReplicatedScoredOnTeam":
                case "TAGame.CarComponent_Boost_TA:ReplicatedBoostAmount": // Always 255?
                case "TAGame.CameraSettingsActor_TA:CameraPitch":
                case "TAGame.CameraSettingsActor_TA:CameraYaw":
                case "TAGame.PRI_TA:PawnType":
                    asp.Data.Add(br.ReadByte());
                    asp.MarkComplete();
                    break;
                case "Engine.Actor:Location":
                case "TAGame.CarComponent_Dodge_TA:DodgeTorque":
                    asp.Data.Add(Vector3D.Deserialize(br));
                    asp.MarkComplete();
                    break;

                case "Engine.Actor:bCollideWorld":
                case "Engine.PlayerReplicationInfo:bReadyToPlay":
                case "TAGame.Vehicle_TA:bReplicatedHandbrake":
                case "TAGame.Vehicle_TA:bDriving":
                case "Engine.Actor:bNetOwner":
                case "Engine.Actor:bBlockActors":
                case "TAGame.GameEvent_TA:bHasLeaveMatchPenalty":
                case "TAGame.PRI_TA:bUsingBehindView":
                case "TAGame.PRI_TA:bUsingSecondaryCamera":
                case "TAGame.GameEvent_TA:ActivatorCar":
                case "TAGame.GameEvent_Soccar_TA:bOverTime":
                case "ProjectX.GRI_X:bGameStarted":
                case "Engine.Actor:bCollideActors":
                case "TAGame.PRI_TA:bReady":
                case "TAGame.RBActor_TA:bFrozen":
                case "Engine.Actor:bHidden":
                case "TAGame.CarComponent_FlipCar_TA:bFlipRight":
                case "Engine.PlayerReplicationInfo:bBot":
                case "Engine.PlayerReplicationInfo:bWaitingPlayer":
                case "TAGame.RBActor_TA:bReplayActor":
                case "TAGame.PRI_TA:bIsInSplitScreen":
                case "Engine.GameReplicationInfo:bMatchIsOver":
                case "TAGame.CarComponent_Boost_TA:bUnlimitedBoost":
                case "Engine.PlayerReplicationInfo:bIsSpectator":
                case "TAGame.GameEvent_Soccar_TA:bBallHasBeenHit":
                case "TAGame.CameraSettingsActor_TA:bUsingSecondaryCamera":
                case "TAGame.CameraSettingsActor_TA:bUsingBehindView":
                case "TAGame.PRI_TA:bOnlineLoadoutSet":
                case "TAGame.PRI_TA:bMatchMVP":
                case "TAGame.PRI_TA:bOnlineLoadoutsSet":
                case "TAGame.RBActor_TA:bIgnoreSyncing":
                case "TAGame.SpecialPickup_BallVelcro_TA:bHit":
                case "TAGame.GameEvent_TA:bCanVoteToForfeit":
                case "TAGame.SpecialPickup_BallVelcro_TA:bBroken":
                case "TAGame.GameEvent_Team_TA:bForfeit":
                    asp.Data.Add(br.ReadBit());
                    asp.MarkComplete();
                    break;
                case "TAGame.CarComponent_TA:ReplicatedActive":
                    // The car component is active if (ReplicatedValue%2)!=0
                    // For now I am only adding that logic to the JSON serializer
                    asp.Data.Add(br.ReadByte());

                    asp.MarkComplete();
                    break;
                case "Engine.PlayerReplicationInfo:UniqueId":
                    asp.Data.Add(UniqueId.Deserialize(br));
                    asp.MarkComplete();
                    break;
                case "TAGame.PRI_TA:PartyLeader":
                    asp.Data.Add(PartyLeader.Deserialize(br));
                    asp.MarkComplete();
                    break;
                case "TAGame.PRI_TA:ClientLoadout":
                    asp.Data.Add(ClientLoadout.Deserialize(br));
                    asp.MarkComplete();
                    break;
                case "TAGame.PRI_TA:CameraSettings":
                case "TAGame.CameraSettingsActor_TA:ProfileSettings":
                    asp.Data.Add(CameraSettings.Deserialize(br));
                    asp.MarkComplete();
                    break;
                case "TAGame.Car_TA:TeamPaint":
                    asp.Data.Add(TeamPaint.Deserialize(br));
                    asp.MarkComplete();
                    break;
                case "ProjectX.GRI_X:GameServerID":
                    asp.Data.Add(br.ReadUInt32());
                    asp.Data.Add(br.ReadUInt32());
                    asp.MarkComplete();
                    break;
                case "ProjectX.GRI_X:Reservations":
                    asp.Data.Add(Reservation.Deserialize(versionMajor, versionMinor, br));
                    asp.MarkComplete();
                    break;
                case "TAGame.Ball_TA:ReplicatedExplosionData":
                    asp.Data.Add(br.ReadBit());
                    asp.Data.Add(br.ReadUInt32());
                    asp.Data.Add(Vector3D.Deserialize(br)); // Almost definitely position
                    asp.MarkComplete();
                    break;
                case "TAGame.Car_TA:ReplicatedDemolish":
                    asp.Data.Add(ReplicatedDemolish.Deserialize(br));
                    asp.MarkComplete();
                    break;
                case "TAGame.GameEvent_Soccar_TA:ReplicatedMusicStinger":
                    asp.Data.Add(br.ReadBit());
                    asp.Data.Add(br.ReadByte());
                    asp.Data.Add(br.ReadUInt32());
                    asp.MarkComplete();
                    break;
                case "TAGame.CarComponent_FlipCar_TA:FlipCarTime":
                case "TAGame.Ball_TA:ReplicatedBallScale":
                case "TAGame.CarComponent_Boost_TA:RechargeDelay":
                case "TAGame.CarComponent_Boost_TA:RechargeRate":
                case "TAGame.Ball_TA:ReplicatedAddedCarBounceScale":
                case "TAGame.Ball_TA:ReplicatedBallMaxLinearSpeedScale":
                case "TAGame.Ball_TA:ReplicatedWorldBounceScale":
                case "TAGame.CarComponent_Boost_TA:BoostModifier":
                case "Engine.Actor:DrawScale":
                case "TAGame.CrowdActor_TA:ModifiedNoise":
                case "TAGame.CarComponent_TA:ReplicatedActivityTime":
                case "TAGame.SpecialPickup_BallFreeze_TA:RepOrigSpeed":
                case "TAGame.SpecialPickup_BallVelcro_TA:AttachTime":
                case "TAGame.SpecialPickup_BallVelcro_TA:BreakTime":
                case "TAGame.Car_TA:AddedCarForceMultiplier":
                case "TAGame.Car_TA:AddedBallForceMultiplier":
                    asp.Data.Add(br.ReadFloat());
                    asp.MarkComplete();
                    break;
                case "TAGame.GameEvent_SoccarPrivate_TA:MatchSettings":
                    asp.Data.Add(PrivateMatchSettings.Deserialize(br));
                    asp.MarkComplete();
                    break;
                case "TAGame.PRI_TA:ClientLoadoutOnline":
                    asp.Data.Add(ClientLoadoutOnline.Deserialize(br));
                    asp.MarkComplete();
                    break;
                case "TAGame.GameEvent_TA:GameMode":
                    if (versionMajor >= 868 && versionMinor >= 12)
                    {
                        asp.Data.Add(br.ReadByte());
                    }
                    else
                    {
                        asp.Data.Add(br.ReadUInt32Max(4));
                    }
                    asp.MarkComplete();
                    break;
                case "TAGame.PRI_TA:ClientLoadoutsOnline":
                    asp.Data.Add(ClientLoadoutsOnline.Deserialize(br));
                    asp.MarkComplete();
                    break;
                case "TAGame.PRI_TA:ClientLoadouts":
                    asp.Data.Add(ClientLoadouts.Deserialize(br));
                    asp.MarkComplete();
                    break;
                case "TAGame.Team_TA:ClubColors":
                case "TAGame.Car_TA:ClubColors":
                    asp.Data.Add(br.ReadBit());
                    asp.Data.Add(br.ReadByte());
                    asp.Data.Add(br.ReadBit());
                    asp.Data.Add(br.ReadByte());
                    asp.MarkComplete();
                    break;
                case "TAGame.RBActor_TA:WeldedInfo":
                    asp.Data.Add(WeldedInfo.Deserialize(br));
                    asp.MarkComplete();
                    break;
                default:
                    throw new NotSupportedException(string.Format("Unknown property {0}. Next bits in the data are {1}. Figure it out!", asp.PropertyName, br.GetBits(br.Position, Math.Min(4096, br.Length - br.Position)).ToBinaryString()));
            }

            #if DEBUG
            asp.KnownDataBits = br.GetBits(startPosition, br.Position - startPosition);
            #endif
            return asp;
        }