Exemple #1
0
        /// <summary>
        /// see https://github.com/EpicGames/UnrealEngine/blob/70bc980c6361d9a7d23f6d23ffe322a2d6ef16fb/Engine/Source/Runtime/NetworkReplayStreaming/LocalFileNetworkReplayStreaming/Private/LocalFileNetworkReplayStreaming.cpp#L363
        /// </summary>
        /// <param name="archive"></param>
        /// <returns></returns>
        protected override void ReadEvent(FArchive archive)
        {
            var info = new EventInfo
            {
                Id          = archive.ReadFString(),
                Group       = archive.ReadFString(),
                Metadata    = archive.ReadFString(),
                StartTime   = archive.ReadUInt32(),
                EndTime     = archive.ReadUInt32(),
                SizeInBytes = archive.ReadInt32()
            };

            _logger?.LogDebug($"Encountered event {info.Group} ({info.Metadata}) at {info.StartTime} of size {info.SizeInBytes}");

            // Every event seems to start with some unknown int
            if (info.Group == ReplayEventTypes.PLAYER_ELIMINATION)
            {
                var elimination = ParseElimination(archive, info);
                Replay.Eliminations.Add(elimination);
                return;
            }
            else if (info.Metadata == ReplayEventTypes.MATCH_STATS)
            {
                Replay.Stats = ParseMatchStats(archive, info);
                return;
            }
            else if (info.Metadata == ReplayEventTypes.TEAM_STATS)
            {
                Replay.TeamStats = ParseTeamStats(archive, info);
                return;
            }
            else if (info.Metadata == ReplayEventTypes.ENCRYPTION_KEY)
            {
                Replay.GameInformation.PlayerStateEncryptionKey = ParseEncryptionKeyEvent(archive, info);
                return;
            }
            else if (info.Metadata == ReplayEventTypes.CHARACTER_SAMPLE)
            {
                ParseCharacterSample(archive, info);
                return;
            }
            else if (info.Group == ReplayEventTypes.ZONE_UPDATE)
            {
                ParseZoneUpdateEvent(archive, info);
                return;
            }
            else if (info.Group == ReplayEventTypes.BATTLE_BUS)
            {
                ParseBattleBusFlightEvent(archive, info);
                return;
            }
            else if (info.Group == "fortBenchEvent")
            {
                return;
            }

            _logger?.LogWarning($"Unknown event {info.Group} ({info.Metadata}) of size {info.SizeInBytes}");
            // optionally throw?
            throw new UnknownEventException($"Unknown event {info.Group} ({info.Metadata}) of size {info.SizeInBytes}");
        }
        public override void ReadEvent(FArchive archive)
        {
            int startPosition = archive.Position;

            var info = new EventInfo
            {
                Id          = archive.ReadFString(),
                Group       = archive.ReadFString(),
                Metadata    = archive.ReadFString(),
                StartTime   = archive.ReadUInt32(),
                EndTime     = archive.ReadUInt32(),
                SizeInBytes = archive.ReadInt32()
            };

            int infoSize = archive.Position - startPosition;

            using var decryptedReader = (Unreal.Core.BinaryReader)base.DecryptBuffer(archive, info.SizeInBytes);

            _writer.Write(infoSize + decryptedReader.Bytes.Length); //Chunk Size
            _writer.Write(info.Id);
            _writer.Write(info.Group);
            _writer.Write(info.Metadata);
            _writer.Write(info.StartTime);
            _writer.Write(info.EndTime);
            _writer.Write(decryptedReader.Bytes.Length);    //Decrypted size
            _writer.Write(decryptedReader.Bytes.ToArray()); //Decrypted bytes
        }
        public override void ReadCheckpoint(FArchive archive)
        {
            int startPosition = archive.Position;

            var info = new CheckpointInfo
            {
                Id          = archive.ReadFString(),
                Group       = archive.ReadFString(),
                Metadata    = archive.ReadFString(),
                StartTime   = archive.ReadUInt32(),
                EndTime     = archive.ReadUInt32(),
                SizeInBytes = archive.ReadInt32()
            };

            int infoSize = archive.Position - startPosition;

            using var decrypted     = (Unreal.Core.BinaryReader)DecryptBuffer(archive, info.SizeInBytes);
            using var binaryArchive = (Unreal.Core.BinaryReader)Decompress(decrypted, decrypted.Bytes.Length);

            _writer.Write(infoSize + binaryArchive.Bytes.Length); //Chunk Size
            _writer.Write(info.Id);
            _writer.Write(info.Group);
            _writer.Write(info.Metadata);
            _writer.Write(info.StartTime);
            _writer.Write(info.EndTime);
            _writer.Write(binaryArchive.Bytes.Length);    //Decompressed checkpoint length
            _writer.Write(binaryArchive.Bytes.ToArray()); //Decompressed checkpoint
        }
Exemple #4
0
 protected virtual TeamStats ParseTeamStats(FArchive archive, EventInfo info)
 {
     return(new TeamStats()
     {
         Info = info,
         Unknown = archive.ReadUInt32(),
         Position = archive.ReadUInt32(),
         TotalPlayers = archive.ReadUInt32()
     });
 }
        public override void ReadReplayData(FArchive archive)
        {
            int startPosition = archive.Position;

            var info = new ReplayDataInfo();

            if (archive.ReplayVersion >= ReplayVersionHistory.HISTORY_STREAM_CHUNK_TIMES)
            {
                info.Start  = archive.ReadUInt32();
                info.End    = archive.ReadUInt32();
                info.Length = archive.ReadUInt32();
            }
            else
            {
                info.Length = archive.ReadUInt32();
            }

            int memorySizeInBytes = (int)info.Length;

            if (archive.ReplayVersion >= ReplayVersionHistory.HISTORY_ENCRYPTION)
            {
                memorySizeInBytes = archive.ReadInt32();
            }

            int infoSize = archive.Position - startPosition;

            using var decryptedReader = DecryptBuffer(archive, (int)info.Length);
            using var binaryArchive   = (Unreal.Core.BinaryReader)Decompress(decryptedReader, memorySizeInBytes);

            //Chunk size
            _writer.Write(infoSize + binaryArchive.Bytes.Length);

            if (archive.ReplayVersion >= ReplayVersionHistory.HISTORY_STREAM_CHUNK_TIMES)
            {
                _writer.Write(info.Start);
                _writer.Write(info.End);
                _writer.Write(binaryArchive.Bytes.Length);
            }
            else
            {
                _writer.Write(binaryArchive.Bytes.Length);
            }

            if (archive.ReplayVersion >= ReplayVersionHistory.HISTORY_ENCRYPTION)
            {
                _writer.Write(binaryArchive.Bytes.Length);
            }

            _writer.Write(binaryArchive.Bytes.ToArray());
        }
Exemple #6
0
 protected virtual Stats ParseMatchStats(FArchive archive, EventInfo info)
 {
     return(new Stats()
     {
         Info = info,
         Unknown = archive.ReadUInt32(),
         Accuracy = archive.ReadSingle(),
         Assists = archive.ReadUInt32(),
         Eliminations = archive.ReadUInt32(),
         WeaponDamage = archive.ReadUInt32(),
         OtherDamage = archive.ReadUInt32(),
         Revives = archive.ReadUInt32(),
         DamageTaken = archive.ReadUInt32(),
         DamageToStructures = archive.ReadUInt32(),
         MaterialsGathered = archive.ReadUInt32(),
         MaterialsUsed = archive.ReadUInt32(),
         TotalTraveled = archive.ReadUInt32()
     });
 }