Esempio n. 1
0
        public static MatchData GetMatchData(RocketLeagueReplayParser.Replay repObj)
        {
            string MatchId    = (string)repObj.Properties["Id"].Value;
            int    TeamSize   = (int)repObj.Properties["TeamSize"].Value;
            int    Team0Score = 0;

            if (repObj.Properties.ContainsKey("Team0Score"))
            {
                Team0Score = (int)repObj.Properties["Team0Score"].Value;
            }
            int Team1Score = 0;

            if (repObj.Properties.ContainsKey("Team1Score"))
            {
                Team1Score = (int)repObj.Properties["Team1Score"].Value;
            }
            string   MatchType = (string)repObj.Properties["MatchType"].Value;
            string   MapName   = (string)repObj.Properties["MapName"].Value;
            DateTime Date      = DateTime.ParseExact((string)repObj.Properties["Date"].Value, "yyyy-MM-dd HH-mm-ss", null);

            Console.WriteLine(Date);
            MatchData header = new MatchData(MatchId, Date, TeamSize, Team0Score, Team1Score, MatchType, MapName);

            return(header);
        }
Esempio n. 2
0
        public static Dictionary <long, uint> CarLookup(RocketLeagueReplayParser.Replay rep, List <long> ids)
        {
            Dictionary <long, uint> CarIds = new Dictionary <long, uint>();
            long tmpId = 0;

            for (int i = 0; i < rep.Frames[0].ActorStates.Count; i++)
            {
                foreach (UInt32 key in rep.Frames[0].ActorStates[i].Properties.Keys)
                {
                    if (rep.Frames[0].ActorStates[i].Properties[key].PropertyName == "Engine.PlayerReplicationInfo:UniqueId")
                    {
                        dynamic uniqueTest = rep.Frames[0].ActorStates[i].Properties[key].Data;
                        Int64   steamId    = uniqueTest.SteamID64;

                        if (!ids.Contains((long)steamId) || CarIds.ContainsKey(steamId))
                        {
                            break;
                        }
                        tmpId = steamId;
                    }

                    if (rep.Frames[0].ActorStates[i].Properties[key].PropertyName == "TAGame.PRI_TA:ClientLoadouts")
                    {
                        dynamic loadout = rep.Frames[0].ActorStates[i].Properties[key].Data;
                        uint    carType = loadout.Loadout1.BodyProductId;
                        CarIds.Add(tmpId, carType);
                    }
                }
            }
            return(CarIds);
        }
Esempio n. 3
0
        public static Dictionary <long, int> PlatformIdActorId(RocketLeagueReplayParser.Replay rep, List <long> ids)
        {
            Dictionary <long, int> PlatformIdActorId = new Dictionary <long, int>();
            long tmpId = 0;

            for (int i = 0; i < rep.Frames[0].ActorStates.Count; i++)
            {
                foreach (UInt32 key in rep.Frames[0].ActorStates[i].Properties.Keys)
                {
                    if (rep.Frames[0].ActorStates[i].Properties[key].PropertyName == "Engine.PlayerReplicationInfo:UniqueId")
                    {
                        dynamic uniqueTest = rep.Frames[0].ActorStates[i].Properties[key].Data;
                        Int64   steamId    = uniqueTest.SteamID64;

                        if (!ids.Contains((long)steamId) || PlatformIdActorId.ContainsKey(steamId))
                        {
                            break;
                        }
                        tmpId = steamId;
                    }

                    if (rep.Frames[0].ActorStates[i].Properties[key].PropertyName == "TAGame.PRI_TA:PersistentCamera")
                    {
                        dynamic id      = rep.Frames[0].ActorStates[i].Properties[key].Data;
                        int     ActorId = id.ActorId;
                        if (!PlatformIdActorId.ContainsValue(ActorId))
                        {
                            PlatformIdActorId.Add(tmpId, ActorId);
                        }
                    }
                }
            }
            return(PlatformIdActorId);
        }
Esempio n. 4
0
        public static void ParseAndStore(string filepath)
        {
            string conStr = @"Data Source=PSML65609\SQLEXPRESS;Initial Catalog=rlstat;Integrated Security=True";

            RocketLeagueReplayParser.Replay      replay = GetReplay(filepath);
            Tuple <List <MatchStats>, MatchData> parse  = ExtractReplayData(replay);

            List <MatchStats> stats = parse.Item1;
            MatchData         data  = parse.Item2;

            ProcessMatchData(data, conStr);
            int i = 0;

            foreach (MatchStats entry in stats)
            {
                dynamic tmp          = replay.Properties["PlayerStats"];
                string  platformName = tmp[i]["Platform"].Value.Value;
                string  username     = tmp[i]["Name"].Value;
                Player  tmpPlayer    = new Player(entry.PlatformId, platformName, username);
                ProcessPlayer(tmpPlayer, conStr);
                ProcessMatchStats(entry, conStr);

                i++;
            }
        }
Esempio n. 5
0
        public static Tuple <List <MatchStats>, MatchData> ExtractReplayData(RocketLeagueReplayParser.Replay repObj)
        {
            dynamic     PlayerStats = repObj.Properties["PlayerStats"].Value;
            MatchData   data        = GetMatchData(repObj);
            List <long> IDS         = new List <long>();

            for (int i = 0; i < PlayerStats.Count; i++)
            {
                long OnlineID = PlayerStats[i]["OnlineID"].Value;
                IDS.Add(OnlineID);
            }
            Dictionary <long, uint>          CarIds         = CarLookup(repObj, IDS);
            Dictionary <long, List <float> > CameraSettings = CameraLookup(repObj, IDS);

            List <MatchStats> PlayerStatList = GetMatchStats(PlayerStats, CarIds, CameraSettings, data);

            return(Tuple.Create(PlayerStatList, data));
        }
Esempio n. 6
0
        public static Dictionary <int, List <float> > ActorIdCamera(RocketLeagueReplayParser.Replay rep)
        {
            Dictionary <int, List <float> > ActorIdCamera = new Dictionary <int, List <float> >();
            dynamic tmp = rep.Properties["PlayerStats"].Value;

            for (int i = 0; i < rep.Frames.Count; i++)
            {
                for (int j = 0; j < rep.Frames[i].ActorStates.Count; j++)
                {
                    foreach (UInt32 key in rep.Frames[i].ActorStates[j].Properties.Keys)
                    {
                        if (rep.Frames[i].ActorStates[j].Properties[key].PropertyName == "TAGame.CameraSettingsActor_TA:ProfileSettings")
                        {
                            List <float> CameraSettings = new List <float>();
                            dynamic      settings       = rep.Frames[i].ActorStates[j].Properties[key].Data;
                            CameraSettings.Add(settings.FieldOfView);
                            CameraSettings.Add(settings.Height);
                            CameraSettings.Add(settings.Pitch);
                            CameraSettings.Add(settings.Distance);
                            CameraSettings.Add(settings.Stiffness);
                            CameraSettings.Add(settings.SwivelSpeed);
                            CameraSettings.Add(settings.TransitionSpeed);

                            if (!ActorIdCamera.ContainsKey((int)rep.Frames[i].ActorStates[j].Id))
                            {
                                ActorIdCamera.Add((int)rep.Frames[i].ActorStates[j].Id, CameraSettings);
                            }
                            break;
                        }
                    }
                }
                if (ActorIdCamera.Count == tmp.Count)
                {
                    break;
                }
            }
            return(ActorIdCamera);
        }
Esempio n. 7
0
        public static Dictionary <long, List <float> > CameraLookup(RocketLeagueReplayParser.Replay rep, List <long> ids)
        {
            Dictionary <long, int>          PlatformActor = PlatformIdActorId(rep, ids);
            Dictionary <int, List <float> > ActorCamera   = ActorIdCamera(rep);
            List <long>          BadPlatform = new List <long>();
            List <List <float> > BadCamera   = new List <List <float> >();

            dynamic tmp = rep.Properties["PlayerStats"].Value;

            Dictionary <long, List <float> > PlatformCamera = new Dictionary <long, List <float> >();

            foreach (long key in PlatformActor.Keys)
            {
                if (ActorCamera.ContainsKey(PlatformActor[key]))
                {
                    PlatformCamera.Add(key, ActorCamera[PlatformActor[key]]);
                }
                else
                {
                    BadPlatform.Add(PlatformActor[key]);
                }
            }
            foreach (int key in ActorCamera.Keys)
            {
                if (!PlatformActor.ContainsValue(key))
                {
                    BadCamera.Add(ActorCamera[key]);
                }
            }
            if (PlatformCamera.Count != tmp.Count)
            {
                if (BadCamera.Count == 1 && BadPlatform.Count == 1)
                {
                    PlatformCamera.Add(BadPlatform[0], BadCamera[0]);
                }
            }
            return(PlatformCamera);
        }
Esempio n. 8
0
        public static Replay DeserializeHeader(BinaryReader br)
        {
            var replay = new Replay();

            replay.Part1Length = br.ReadInt32();
            replay.Part1Crc = br.ReadUInt32();
            replay.VersionMajor = br.ReadUInt32();
            replay.VersionMinor = br.ReadUInt32();
            replay.Unknown5 = br.ReadString2();

            replay.Properties = PropertyDictionary.Deserialize(br);

            return replay;
        }
Esempio n. 9
0
        public static Replay Deserialize(BinaryReader br)
        {
            var replay = new Replay();

            try
            {
                replay.Part1Length  = br.ReadInt32();
                replay.Part1Crc     = br.ReadUInt32();
                replay.VersionMajor = br.ReadUInt32();
                replay.VersionMinor = br.ReadUInt32();
                replay.Unknown5     = br.ReadString2();

                var s = br.BaseStream.Position;
                replay.Properties = new List <Property>();
                Property prop;
                do
                {
                    prop = Property.Deserialize(br);
                    replay.Properties.Add(prop);
                }while (prop.Name != "None");

                replay.Part2Length = br.ReadInt32();
                replay.Part2Crc    = br.ReadUInt32();

                replay.LevelLength = br.ReadInt32();
                // looks like sfx data, not level data. shrug
                replay.Levels = new List <Level>();
                for (int i = 0; i < replay.LevelLength; i++)
                {
                    replay.Levels.Add(Level.Deserialize(br));
                }

                replay.KeyFrameLength = br.ReadInt32();
                replay.KeyFrames      = new List <KeyFrame>();
                for (int i = 0; i < replay.KeyFrameLength; i++)
                {
                    replay.KeyFrames.Add(KeyFrame.Deserialize(br));
                }

                replay.NetworkStreamLength = br.ReadInt32();
                replay.NetworkStream       = new List <byte>();
                for (int i = 0; i < replay.NetworkStreamLength; ++i)
                {
                    replay.NetworkStream.Add(br.ReadByte());
                }

                replay.DebugStringLength = br.ReadInt32();
                replay.DebugStrings      = new List <DebugString>();
                for (int i = 0; i < replay.DebugStringLength; i++)
                {
                    replay.DebugStrings.Add(DebugString.Deserialize(br));
                }

                replay.TickMarkLength = br.ReadInt32();
                replay.TickMarks      = new List <TickMark>();
                for (int i = 0; i < replay.TickMarkLength; i++)
                {
                    replay.TickMarks.Add(TickMark.Deserialize(br));
                }

                replay.PackagesLength = br.ReadInt32();
                replay.Packages       = new List <string>();
                for (int i = 0; i < replay.PackagesLength; i++)
                {
                    replay.Packages.Add(br.ReadString2());
                }

                replay.ObjectLength = br.ReadInt32();
                replay.Objects      = new string[replay.ObjectLength];
                for (int i = 0; i < replay.ObjectLength; i++)
                {
                    replay.Objects[i] = br.ReadString2();
                }

                replay.NamesLength = br.ReadInt32();
                replay.Names       = new string[replay.NamesLength];
                for (int i = 0; i < replay.NamesLength; i++)
                {
                    replay.Names[i] = br.ReadString2();
                }

                replay.ClassIndexLength = br.ReadInt32();
                replay.ClassIndexes     = new List <ClassIndex>();
                for (int i = 0; i < replay.ClassIndexLength; i++)
                {
                    replay.ClassIndexes.Add(ClassIndex.Deserialize(br));
                }

                replay.ClassNetCacheLength = br.ReadInt32();
                replay.ClassNetCaches      = new ClassNetCache[replay.ClassNetCacheLength];
                for (int i = 0; i < replay.ClassNetCacheLength; i++)
                {
                    var classNetCache = ClassNetCache.Deserialize(br);
                    replay.ClassNetCaches[i] = classNetCache;

                    for (int j = i - 1; j >= 0; --j)
                    {
                        if (classNetCache.ParentId == replay.ClassNetCaches[j].Id)
                        {
                            classNetCache.Parent = replay.ClassNetCaches[j];
                            replay.ClassNetCaches[j].Children.Add(classNetCache);
                            break;
                        }
                    }

                    if (replay.ClassNetCaches[i].Parent == null)
                    {
                        replay.ClassNetCaches[i].Root = true;
                    }
                }

                // 2016/02/10 patch replays have TAGame.PRI_TA classes with no parent.
                // Deserialization may have failed somehow, but for now manually fix it up.
                replay.FixClassParent("ProjectX.PRI_X", "Engine.PlayerReplicationInfo");
                replay.FixClassParent("TAGame.PRI_TA", "ProjectX.PRI_X");

                // A lot of replays have messed up class hierarchies, commonly giving
                // both Engine.TeamInfo, TAGame.CarComponent_TA, and others the same id.
                // Some ambiguities may have become more common since the 2016-06-20 patch,
                // but there have always been issues.
                //
                // For example, from E8B66F8A4561A2DAACC61FA9FBB710CD:
                //    Index 26(TAGame.CarComponent_TA) ParentId 21 Id 24
                //        Index 28(TAGame.CarComponent_Dodge_TA) ParentId 24 Id 25
                //        Index 188(TAGame.CarComponent_Jump_TA) ParentId 24 Id 24
                //            Index 190(TAGame.CarComponent_DoubleJump_TA) ParentId 24 Id 24
                //    Index 30(Engine.Info) ParentId 21 Id 21
                //        Index 31(Engine.ReplicationInfo) ParentId 21 Id 21
                //            Index 195(Engine.TeamInfo) ParentId 21 Id 24
                //                Index 214(TAGame.CarComponent_Boost_TA) ParentId 24 Id 31
                //                Index 237(TAGame.CarComponent_FlipCar_TA) ParentId 24 Id 26
                // Problems:
                //     TAGame.CarComponent_Jump_TA's parent id and id are both 24 (happens to work fine in this case)
                //     TAGame.CarComponent_DoubleJump_TA's parent id and id are both 24 (incorrectly picks CarComponent_Jump_TA as parent)
                //     Engine.TeamInfo's ID is 24, even though there are 3 other classes with that id
                //     TAGame.CarComponent_Boost_TA's parent is 24 (Incorrectly picks Engine.TeamInfo, since it's ambiguous)
                //     TAGame.CarComponent_FlipCar_TA's parent is 24 (Incorrectly picks Engine.TeamInfo, since it's ambiguous)
                //     Engine.ReplicationInfo and Engine.Info have the same parent id and id (no ill effects so far)
                //
                // Note: The heirarchy problems do not always cause parsing errors! But they can if you're unlucky.

                replay.FixClassParent("TAGame.CarComponent_Boost_TA", "TAGame.CarComponent_TA");
                replay.FixClassParent("TAGame.CarComponent_FlipCar_TA", "TAGame.CarComponent_TA");
                replay.FixClassParent("TAGame.CarComponent_Jump_TA", "TAGame.CarComponent_TA");
                replay.FixClassParent("TAGame.CarComponent_Dodge_TA", "TAGame.CarComponent_TA");
                replay.FixClassParent("TAGame.CarComponent_DoubleJump_TA", "TAGame.CarComponent_TA");
                replay.FixClassParent("TAGame.GameEvent_TA", "Engine.Actor");
                replay.FixClassParent("TAGame.SpecialPickup_TA", "TAGame.CarComponent_TA");
                replay.FixClassParent("TAGame.SpecialPickup_BallVelcro_TA", "TAGame.SpecialPickup_TA");
                replay.FixClassParent("TAGame.SpecialPickup_Targeted_TA", "TAGame.SpecialPickup_TA");
                replay.FixClassParent("TAGame.SpecialPickup_Spring_TA", "TAGame.SpecialPickup_Targeted_TA");
                replay.FixClassParent("TAGame.SpecialPickup_BallLasso_TA", "TAGame.SpecialPickup_Spring_TA");
                replay.FixClassParent("TAGame.SpecialPickup_BoostOverride_TA", "TAGame.SpecialPickup_Targeted_TA");
                replay.FixClassParent("TAGame.SpecialPickup_BallCarSpring_TA", "TAGame.SpecialPickup_Spring_TA");
                replay.FixClassParent("TAGame.SpecialPickup_BallFreeze_TA", "TAGame.SpecialPickup_Targeted_TA");
                replay.FixClassParent("TAGame.SpecialPickup_Swapper_TA", "TAGame.SpecialPickup_Targeted_TA");
                replay.FixClassParent("TAGame.SpecialPickup_GrapplingHook_TA", "TAGame.SpecialPickup_Targeted_TA");
                replay.FixClassParent("TAGame.SpecialPickup_BallGravity_TA", "TAGame.SpecialPickup_TA");
                replay.FixClassParent("TAGame.SpecialPickup_HitForce_TA", "TAGame.SpecialPickup_TA");
                replay.FixClassParent("TAGame.SpecialPickup_Tornado_TA", "TAGame.SpecialPickup_TA");

                // Havent had problems with these yet. They (among others) can be ambiguous,
                // but I havent found a replay yet where my parent choosing algorithm
                // (which picks the matching class that was most recently read) picks the wrong class.
                // Just a safeguard for now.
                replay.FixClassParent("Engine.TeamInfo", "Engine.ReplicationInfo");
                replay.FixClassParent("TAGame.Team_TA", "Engine.TeamInfo");

                replay.Frames = ExtractFrames(replay.MaxChannels(), replay.NetworkStream, replay.KeyFrames.Select(x => x.FilePosition), replay.Objects, replay.ClassNetCaches, replay.VersionMajor, replay.VersionMinor);

                if (br.BaseStream.Position != br.BaseStream.Length)
                {
                    throw new Exception("Extra data somewhere!");
                }

                return(replay);
            }
            catch (Exception)
            {
#if DEBUG
                return(replay);
#else
                throw;
#endif
            }
        }
Esempio n. 10
0
        public static Replay Deserialize(BinaryReader br, out string log)
        {
            var logSb = new StringBuilder();

            var replay = new Replay();
            replay.Unknown1 = br.ReadInt32();
            replay.Unknown2 = br.ReadInt32();
            replay.Unknown3 = br.ReadInt32();
            replay.Unknown4 = br.ReadInt32();

            // This looks almost like an ArrayProperty, but without type and the unknown ints
            replay.Unknown5 = br.ReadAsciiString();
            replay.Properties = new List<Property>();
            Property prop;
            do
            {
                prop = Property.Deserialize(br);
                replay.Properties.Add(prop);
            }
            while (prop.Name != "None");

            replay.LengthOfRemainingData = br.ReadInt32();
            replay.Unknown7 = br.ReadInt32();
            replay.LevelLength = br.ReadInt32();

            // looks like sfx data, not level data. shrug
            replay.Levels = new List<Level>();
            for (int i = 0; i < replay.LevelLength; i++ )
            {
                replay.Levels.Add(Level.Deserialize(br));
            }

            replay.KeyFrameLength = br.ReadInt32();
            replay.KeyFrames = new List<KeyFrame>();
            for (int i = 0; i < replay.KeyFrameLength; i++)
            {
                replay.KeyFrames.Add(KeyFrame.Deserialize(br));
            }

            replay.NetworkStreamLength = br.ReadInt32();
            replay.NetworkStream = new List<byte>();
            for (int i = 0; i < replay.NetworkStreamLength; ++i)
            {
                replay.NetworkStream.Add(br.ReadByte());
            }

            replay.DebugStringLength = br.ReadInt32();
            replay.DebugStrings = new List<string>();
            for (int i = 0; i < replay.DebugStringLength; i++)
            {
                replay.DebugStrings.Add(br.ReadAsciiString());
            }

            replay.TickMarkLength = br.ReadInt32();
            replay.TickMarks = new List<TickMark>();
            for (int i = 0; i < replay.TickMarkLength; i++)
            {
                replay.TickMarks.Add(TickMark.Deserialize(br));
            }

            replay.PackagesLength = br.ReadInt32();
            replay.Packages = new List<string>();
            for (int i = 0; i < replay.PackagesLength; i++)
            {
                replay.Packages.Add(br.ReadAsciiString());
            }

            replay.ObjectLength = br.ReadInt32();
            replay.Objects = new string[replay.ObjectLength];
            for (int i = 0; i < replay.ObjectLength; i++)
            {
                replay.Objects[i] = br.ReadAsciiString();
            }

            //replay.Unknown9 = br.ReadInt32();

            replay.NamesLength = br.ReadInt32();
            replay.Names = new List<string>();
            for (int i = 0; i < replay.NamesLength; i++)
            {
                replay.Names.Add(br.ReadAsciiString());
            }

            replay.ClassIndexLength = br.ReadInt32();
            replay.ClassIndexes = new List<ClassIndex>();
            for (int i = 0; i < replay.ClassIndexLength; i++)
            {
                replay.ClassIndexes.Add(ClassIndex.Deserialize(br));
            }

            replay.ClassNetCacheLength = br.ReadInt32();
            replay.ClassNetCaches = new ClassNetCache[replay.ClassNetCacheLength];
            for (int i = 0; i < replay.ClassNetCacheLength; i++)
            {
                replay.ClassNetCaches[i] = ClassNetCache.Deserialize(br);

                int j = 0;
                for(j = i-1; j >=0; --j)
                {
                    if ( replay.ClassNetCaches[i].ParentId == replay.ClassNetCaches[j].Id)
                    {
                        replay.ClassNetCaches[i].Parent = replay.ClassNetCaches[j];
                        replay.ClassNetCaches[j].Children.Add(replay.ClassNetCaches[i]);
                        break;
                    }
                }
                if ( j < 0 )
                {
                    replay.ClassNetCaches[i].Root = true;
                }
            }

            // break into frames, using best guesses
            var objectIndexToName = Enumerable.Range(0, replay.Objects.Length).ToDictionary(i => i, i => replay.Objects[i]);
            replay.Frames = ExtractFrames(replay.NetworkStream, replay.KeyFrames.Select(x => x.FilePosition), objectIndexToName, replay.ClassNetCaches, logSb);

            //var minSize = replay.Frames.Where(x => !x.Complete /*&& x.BitLength != 163*/ && x.ActorStates.Count > 0 && !string.IsNullOrWhiteSpace(x.ActorStates[0].TypeName)).Min(x => x.BitLength);
            foreach (var f in replay.Frames.Where(x => !x.Complete))// x.Failed) )//Complete && x.BitLength == minSize))
            {
                //if ( f.ActorStates.Count >= 1 && f.ActorStates.First().State == "New")
                //{
                    logSb.AppendLine(f.ToDebugString(replay.Objects));
                //}
            }

            //logSb.AppendLine(replay.Frames.First().ToDebugString(replay.Objects));

            if ( br.BaseStream.Position != br.BaseStream.Length )
            {
                throw new Exception("Extra data somewhere!");
            }

            log = logSb.ToString();
            //Console.WriteLine(log);

            return replay;
        }