From 57466417f5a3038fea939e3708b68d1d8d4e0efe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kriszti=C3=A1n=20Fekete?=
<49228974+donCalculator@users.noreply.github.com>
Date: Mon, 12 Jun 2023 13:18:41 +0200
Subject: [PATCH 1/4] rename ReplayVersionHistory.HISTORY_2500
---
src/Unreal.Core/Models/Enums/ReplayVersionHistory.cs | 4 ++--
src/Unreal.Core/ReplayReader.cs | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/Unreal.Core/Models/Enums/ReplayVersionHistory.cs b/src/Unreal.Core/Models/Enums/ReplayVersionHistory.cs
index eb3c2ba..3107a92 100644
--- a/src/Unreal.Core/Models/Enums/ReplayVersionHistory.cs
+++ b/src/Unreal.Core/Models/Enums/ReplayVersionHistory.cs
@@ -1,7 +1,7 @@
namespace Unreal.Core.Models
{
///
- /// see https://github.com/EpicGames/UnrealEngine/blob/70bc980c6361d9a7d23f6d23ffe322a2d6ef16fb/Engine/Source/Runtime/NetworkReplayStreaming/LocalFileNetworkReplayStreaming/Private/LocalFileNetworkReplayStreaming.cpp#L45
+ /// see https://github.com/EpicGames/UnrealEngine/blob/996ef9a9f4ad5a899abf70fb292d2914a46d0876/Engine/Source/Runtime/NetworkReplayStreaming/LocalFileNetworkReplayStreaming/Public/LocalFileNetworkReplayStreaming.h#L34
///
[System.Flags]
public enum ReplayVersionHistory : uint
@@ -13,7 +13,7 @@ public enum ReplayVersionHistory : uint
HISTORY_STREAM_CHUNK_TIMES = 4,
HISTORY_FRIENDLY_NAME_ENCODING = 5,
HISTORY_ENCRYPTION = 6,
- HISTORY_2500 = 7, // TODO, FIND THE NAME OF THIS
+ HISTORY_CUSTOM_VERSIONS = 7,
HISTORY_PLUS_ONE,
LATEST = HISTORY_PLUS_ONE - 1
diff --git a/src/Unreal.Core/ReplayReader.cs b/src/Unreal.Core/ReplayReader.cs
index ae3664f..8483fdc 100644
--- a/src/Unreal.Core/ReplayReader.cs
+++ b/src/Unreal.Core/ReplayReader.cs
@@ -531,7 +531,7 @@ public virtual void ReadReplayInfo(FArchive archive)
{
_logger?.LogWarning("Found unexpected ReplayVersionHistory: {}", fileVersion);
}
- if (archive.ReplayVersion >= ReplayVersionHistory.HISTORY_2500)
+ if (archive.ReplayVersion >= ReplayVersionHistory.HISTORY_CUSTOM_VERSIONS)
{
var customVersionCount = archive.ReadInt32();
From 93015a61ef06e1daea89de5de21044ef88792228 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kriszti=C3=A1n=20Fekete?=
<49228974+donCalculator@users.noreply.github.com>
Date: Mon, 12 Jun 2023 13:51:23 +0200
Subject: [PATCH 2/4] adding parsing of ReplicatedWorldTimeSecondsDouble
---
.../FortniteReplayBuilderTest.cs | 1 +
.../FortniteReplayBuilder.cs | 16 +++++++++++++++-
src/FortniteReplayReader/Models/KillFeedEntry.cs | 1 +
src/FortniteReplayReader/Models/Llama.cs | 1 +
.../Models/NetFieldExports/GameState.cs | 3 +++
src/FortniteReplayReader/Models/PlayerData.cs | 5 ++++-
src/FortniteReplayReader/Models/SupplyDrop.cs | 2 ++
src/Unreal.Core/Contracts/ITelemetryEvent.cs | 2 ++
src/Unreal.Core/Models/Enums/RepLayoutCmdType.cs | 1 +
src/Unreal.Core/NetBitReader.cs | 5 +++++
src/Unreal.Core/NetFieldParser.cs | 3 +++
11 files changed, 38 insertions(+), 2 deletions(-)
diff --git a/src/FortniteReplayReader.Test/FortniteReplayBuilderTest.cs b/src/FortniteReplayReader.Test/FortniteReplayBuilderTest.cs
index 9cde900..aca9777 100644
--- a/src/FortniteReplayReader.Test/FortniteReplayBuilderTest.cs
+++ b/src/FortniteReplayReader.Test/FortniteReplayBuilderTest.cs
@@ -25,6 +25,7 @@ public void GameStateTest()
GameSessionId = "123",
WinningTeam = 99,
ReplicatedWorldTimeSeconds = 1,
+ ReplicatedWorldTimeSecondsDouble = 1,
};
builder.UpdateGameState(state);
diff --git a/src/FortniteReplayReader/FortniteReplayBuilder.cs b/src/FortniteReplayReader/FortniteReplayBuilder.cs
index 90314d6..5560933 100644
--- a/src/FortniteReplayReader/FortniteReplayBuilder.cs
+++ b/src/FortniteReplayReader/FortniteReplayBuilder.cs
@@ -37,6 +37,7 @@ public class FortniteReplayBuilder
private readonly Dictionary _unknownWeapons = new();
private float? ReplicatedWorldTimeSeconds = 0;
+ private float? ReplicatedWorldTimeSecondsDouble = 0;
public void AddActorChannel(uint channelIndex, uint guid)
{
@@ -132,6 +133,11 @@ public void UpdateGameState(GameState state)
ReplicatedWorldTimeSeconds = state.ReplicatedWorldTimeSeconds;
}
+ if (state.ReplicatedWorldTimeSecondsDouble != null)
+ {
+ ReplicatedWorldTimeSecondsDouble = state.ReplicatedWorldTimeSecondsDouble;
+ }
+
GameData.WinningPlayerIds ??= state.WinningPlayerList;
GameData.WinningTeam ??= state.WinningTeam;
GameData.RecorderId ??= state.RecorderPlayerState?.Value;
@@ -246,6 +252,8 @@ public void UpdatePlayerState(uint channelIndex, FortPlayerState state)
if (state.DeathTags != null)
{
playerData.DeathTime = ReplicatedWorldTimeSeconds;
+ playerData.DeathTimeDouble = ReplicatedWorldTimeSecondsDouble;
+
}
playerData.Cosmetics.Parts ??= state.Parts?.Name;
@@ -262,7 +270,8 @@ public void UpdateKillFeed(uint channelIndex, PlayerData data, FortPlayerState s
{
KillFeedEntry? entry = new KillFeedEntry()
{
- ReplicatedWorldTimeSeconds = ReplicatedWorldTimeSeconds
+ ReplicatedWorldTimeSeconds = ReplicatedWorldTimeSeconds,
+ ReplicatedWorldTimeSecondsDouble = ReplicatedWorldTimeSecondsDouble,
};
if (state.RebootCounter != null)
@@ -363,6 +372,7 @@ public void UpdatePlayerPawn(uint channelIndex, PlayerPawn pawn)
{
ReplicatedMovement = pawn.ReplicatedMovement,
ReplicatedWorldTimeSeconds = ReplicatedWorldTimeSeconds,
+ ReplicatedWorldTimeSecondsDouble = ReplicatedWorldTimeSecondsDouble,
LastUpdateTime = pawn.ReplayLastTransformUpdateTimeStamp,
bIsCrouched = pawn.bIsCrouched,
bIsInAnyStorm = pawn.bIsInAnyStorm,
@@ -495,6 +505,7 @@ public void UpdateLlama(uint channelIndex, SupplyDropLlama supplyDropLlama)
{
llama.Looted = true;
llama.LootedTime = ReplicatedWorldTimeSeconds;
+ llama.LootedTimeDouble = ReplicatedWorldTimeSecondsDouble;
}
if (supplyDropLlama.bHasSpawnedPickups)
@@ -517,12 +528,15 @@ public void UpdateSupplyDrop(uint channelIndex, Models.NetFieldExports.SupplyDro
{
drop.Looted = true;
drop.LootedTime = ReplicatedWorldTimeSeconds;
+ drop.LootedTimeDouble = ReplicatedWorldTimeSecondsDouble;
}
if (supplyDrop.BalloonPopped)
{
drop.BalloonPopped = true;
drop.BalloonPoppedTime = ReplicatedWorldTimeSeconds;
+ drop.BalloonPoppedTimeDouble = ReplicatedWorldTimeSecondsDouble;
+
}
if (supplyDrop.bHasSpawnedPickups)
diff --git a/src/FortniteReplayReader/Models/KillFeedEntry.cs b/src/FortniteReplayReader/Models/KillFeedEntry.cs
index 854dbb2..43fbc11 100644
--- a/src/FortniteReplayReader/Models/KillFeedEntry.cs
+++ b/src/FortniteReplayReader/Models/KillFeedEntry.cs
@@ -14,6 +14,7 @@ public class KillFeedEntry
public bool FinisherOrDownerIsBot { get; set; }
public float? ReplicatedWorldTimeSeconds { get; set; }
+ public float? ReplicatedWorldTimeSecondsDouble { get; set; }
public float? Distance { get; set; }
public int? DeathCause { get; set; }
public FVector DeathLocation { get; set; }
diff --git a/src/FortniteReplayReader/Models/Llama.cs b/src/FortniteReplayReader/Models/Llama.cs
index ddd1a92..08e37ba 100644
--- a/src/FortniteReplayReader/Models/Llama.cs
+++ b/src/FortniteReplayReader/Models/Llama.cs
@@ -24,6 +24,7 @@ public Llama(uint channelIndex, SupplyDropLlama drop)
public bool HasSpawnedPickups { get; set; }
public bool Looted { get; set; }
public float? LootedTime { get; set; }
+ public double? LootedTimeDouble { get; set; }
public FVector? LandingLocation { get; set; }
}
}
diff --git a/src/FortniteReplayReader/Models/NetFieldExports/GameState.cs b/src/FortniteReplayReader/Models/NetFieldExports/GameState.cs
index 594d6a8..bd4dc46 100644
--- a/src/FortniteReplayReader/Models/NetFieldExports/GameState.cs
+++ b/src/FortniteReplayReader/Models/NetFieldExports/GameState.cs
@@ -108,6 +108,9 @@ public class GameState : INetFieldExportGroup
[NetFieldExport("ReplicatedWorldTimeSeconds", RepLayoutCmdType.PropertyFloat)]
public float? ReplicatedWorldTimeSeconds { get; set; }
+ [NetFieldExport("ReplicatedWorldTimeSecondsDouble", RepLayoutCmdType.PropertyDouble)]
+ public float? ReplicatedWorldTimeSecondsDouble { get; set; }
+
[NetFieldExport("MatchState", RepLayoutCmdType.Property)]
public FName MatchState { get; set; }
diff --git a/src/FortniteReplayReader/Models/PlayerData.cs b/src/FortniteReplayReader/Models/PlayerData.cs
index 97fd8f4..48e7227 100644
--- a/src/FortniteReplayReader/Models/PlayerData.cs
+++ b/src/FortniteReplayReader/Models/PlayerData.cs
@@ -71,7 +71,7 @@ public PlayerData(FortPlayerState playerState)
public IEnumerable DeathTags { get; set; }
public FVector DeathLocation { get; set; }
public float? DeathTime { get; set; }
-
+ public double? DeathTimeDouble { get; set; }
public Cosmetics Cosmetics { get; set; }
public uint? CurrentWeapon { get; internal set; }
@@ -104,6 +104,9 @@ public class PlayerMovement
{
public FRepMovement? ReplicatedMovement { get; set; }
public float? ReplicatedWorldTimeSeconds { get; set; }
+
+ public float? ReplicatedWorldTimeSecondsDouble { get; set; }
+
public float? LastUpdateTime { get; set; }
public bool? bIsCrouched { get; set; }
diff --git a/src/FortniteReplayReader/Models/SupplyDrop.cs b/src/FortniteReplayReader/Models/SupplyDrop.cs
index ad52764..9819fad 100644
--- a/src/FortniteReplayReader/Models/SupplyDrop.cs
+++ b/src/FortniteReplayReader/Models/SupplyDrop.cs
@@ -21,8 +21,10 @@ public SupplyDrop(uint channelIndex, NetFieldExports.SupplyDrop drop)
public bool HasSpawnedPickups { get; set; }
public bool Looted { get; set; }
public float? LootedTime { get; set; }
+ public double? LootedTimeDouble { get; set; }
public bool BalloonPopped { get; set; }
public float? BalloonPoppedTime { get; set; }
+ public double? BalloonPoppedTimeDouble { get; set; }
public float FallSpeed { get; set; }
public FVector LandingLocation { get; set; }
public float FallHeight { get; set; }
diff --git a/src/Unreal.Core/Contracts/ITelemetryEvent.cs b/src/Unreal.Core/Contracts/ITelemetryEvent.cs
index d4ac4a2..8927bb6 100644
--- a/src/Unreal.Core/Contracts/ITelemetryEvent.cs
+++ b/src/Unreal.Core/Contracts/ITelemetryEvent.cs
@@ -6,5 +6,7 @@
public interface ITelemetryEvent
{
public float? ReplicatedWorldTimeSeconds { get; set; }
+
+ public float? ReplicatedWorldTimeSecondsDouble { get; set; }
}
}
diff --git a/src/Unreal.Core/Models/Enums/RepLayoutCmdType.cs b/src/Unreal.Core/Models/Enums/RepLayoutCmdType.cs
index a818965..08eb72b 100644
--- a/src/Unreal.Core/Models/Enums/RepLayoutCmdType.cs
+++ b/src/Unreal.Core/Models/Enums/RepLayoutCmdType.cs
@@ -32,6 +32,7 @@ public enum RepLayoutCmdType
PropertySoftObject = 22,
PropertyWeakObject = 23,
+ PropertyDouble = 94,
PropertyVector2D = 95,
PropertyInt16 = 96,
PropertyUInt16 = 97,
diff --git a/src/Unreal.Core/NetBitReader.cs b/src/Unreal.Core/NetBitReader.cs
index 6ec7ff8..ac80c94 100644
--- a/src/Unreal.Core/NetBitReader.cs
+++ b/src/Unreal.Core/NetBitReader.cs
@@ -41,6 +41,11 @@ public float SerializePropertyFloat()
return ReadSingle();
}
+ public double SerializePropertyDouble()
+ {
+ return ReadDouble();
+ }
+
public string SerializePropertyName()
{
return ReadFName();
diff --git a/src/Unreal.Core/NetFieldParser.cs b/src/Unreal.Core/NetFieldParser.cs
index a140aa3..7cfad59 100644
--- a/src/Unreal.Core/NetFieldParser.cs
+++ b/src/Unreal.Core/NetFieldParser.cs
@@ -379,6 +379,9 @@ private void SetType(INetFieldExportGroup obj, NetFieldInfo netFieldInfo, NetFie
case RepLayoutCmdType.PropertyFloat:
data = netBitReader.SerializePropertyFloat();
break;
+ case RepLayoutCmdType.PropertyDouble:
+ data = netBitReader.SerializePropertyDouble();
+ break;
case RepLayoutCmdType.PropertyNativeBool:
data = netBitReader.SerializePropertyNativeBool();
break;
From edc5b950e7b2cc74cdcb7e741adaf005b5be42c9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kriszti=C3=A1n=20Fekete?=
<49228974+donCalculator@users.noreply.github.com>
Date: Mon, 12 Jun 2023 14:19:18 +0200
Subject: [PATCH 3/4] fix types
---
src/FortniteReplayReader/FortniteReplayBuilder.cs | 2 +-
src/FortniteReplayReader/Models/KillFeedEntry.cs | 2 +-
src/FortniteReplayReader/Models/NetFieldExports/GameState.cs | 2 +-
src/FortniteReplayReader/Models/PlayerData.cs | 2 +-
src/Unreal.Core/Contracts/ITelemetryEvent.cs | 2 +-
5 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/FortniteReplayReader/FortniteReplayBuilder.cs b/src/FortniteReplayReader/FortniteReplayBuilder.cs
index 5560933..05854ac 100644
--- a/src/FortniteReplayReader/FortniteReplayBuilder.cs
+++ b/src/FortniteReplayReader/FortniteReplayBuilder.cs
@@ -37,7 +37,7 @@ public class FortniteReplayBuilder
private readonly Dictionary _unknownWeapons = new();
private float? ReplicatedWorldTimeSeconds = 0;
- private float? ReplicatedWorldTimeSecondsDouble = 0;
+ private double? ReplicatedWorldTimeSecondsDouble = 0;
public void AddActorChannel(uint channelIndex, uint guid)
{
diff --git a/src/FortniteReplayReader/Models/KillFeedEntry.cs b/src/FortniteReplayReader/Models/KillFeedEntry.cs
index 43fbc11..1c72a7f 100644
--- a/src/FortniteReplayReader/Models/KillFeedEntry.cs
+++ b/src/FortniteReplayReader/Models/KillFeedEntry.cs
@@ -14,7 +14,7 @@ public class KillFeedEntry
public bool FinisherOrDownerIsBot { get; set; }
public float? ReplicatedWorldTimeSeconds { get; set; }
- public float? ReplicatedWorldTimeSecondsDouble { get; set; }
+ public double? ReplicatedWorldTimeSecondsDouble { get; set; }
public float? Distance { get; set; }
public int? DeathCause { get; set; }
public FVector DeathLocation { get; set; }
diff --git a/src/FortniteReplayReader/Models/NetFieldExports/GameState.cs b/src/FortniteReplayReader/Models/NetFieldExports/GameState.cs
index bd4dc46..b22e0e1 100644
--- a/src/FortniteReplayReader/Models/NetFieldExports/GameState.cs
+++ b/src/FortniteReplayReader/Models/NetFieldExports/GameState.cs
@@ -109,7 +109,7 @@ public class GameState : INetFieldExportGroup
public float? ReplicatedWorldTimeSeconds { get; set; }
[NetFieldExport("ReplicatedWorldTimeSecondsDouble", RepLayoutCmdType.PropertyDouble)]
- public float? ReplicatedWorldTimeSecondsDouble { get; set; }
+ public double? ReplicatedWorldTimeSecondsDouble { get; set; }
[NetFieldExport("MatchState", RepLayoutCmdType.Property)]
public FName MatchState { get; set; }
diff --git a/src/FortniteReplayReader/Models/PlayerData.cs b/src/FortniteReplayReader/Models/PlayerData.cs
index 48e7227..6bd01e1 100644
--- a/src/FortniteReplayReader/Models/PlayerData.cs
+++ b/src/FortniteReplayReader/Models/PlayerData.cs
@@ -105,7 +105,7 @@ public class PlayerMovement
public FRepMovement? ReplicatedMovement { get; set; }
public float? ReplicatedWorldTimeSeconds { get; set; }
- public float? ReplicatedWorldTimeSecondsDouble { get; set; }
+ public double? ReplicatedWorldTimeSecondsDouble { get; set; }
public float? LastUpdateTime { get; set; }
diff --git a/src/Unreal.Core/Contracts/ITelemetryEvent.cs b/src/Unreal.Core/Contracts/ITelemetryEvent.cs
index 8927bb6..bdc4be5 100644
--- a/src/Unreal.Core/Contracts/ITelemetryEvent.cs
+++ b/src/Unreal.Core/Contracts/ITelemetryEvent.cs
@@ -7,6 +7,6 @@ public interface ITelemetryEvent
{
public float? ReplicatedWorldTimeSeconds { get; set; }
- public float? ReplicatedWorldTimeSecondsDouble { get; set; }
+ public double? ReplicatedWorldTimeSecondsDouble { get; set; }
}
}
From 4fed5c1f8f1b355a9d2438a0c161a4683de99b82 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kriszti=C3=A1n=20Fekete?=
<49228974+donCalculator@users.noreply.github.com>
Date: Mon, 12 Jun 2023 14:41:06 +0200
Subject: [PATCH 4/4] adding 31 to EngineNetworkCustomVersion.h
---
src/Unreal.Core/Models/Enums/EngineNetworkVersionHistory.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/Unreal.Core/Models/Enums/EngineNetworkVersionHistory.cs b/src/Unreal.Core/Models/Enums/EngineNetworkVersionHistory.cs
index b4cd62e..2d16a71 100644
--- a/src/Unreal.Core/Models/Enums/EngineNetworkVersionHistory.cs
+++ b/src/Unreal.Core/Models/Enums/EngineNetworkVersionHistory.cs
@@ -35,6 +35,7 @@ public enum EngineNetworkVersionHistory
HISTORY_RUNTIME_FEATURES_COMPATIBILITY = 28, // Bump version to add network runtime feature compatibility test to handshake (hello/upgrade) control messages
HISTORY_SOFTOBJECTPTR_NETGUIDS = 29, // Bump version to support replicating SoftObjectPtrs by NetGuid instead of raw strings.
HISTORY_SUBOBJECT_DESTROY_FLAG = 30, // Bump version to support subobject destruction message flags
+ HISTORY_GAMESTATE_REPLCIATED_TIME_AS_DOUBLE = 31, // Bump version to support AGameStateBase::ReplicatedWorldTimeSeconds as double instead of float.
HISTORY_ENGINENETVERSION_PLUS_ONE,
LATEST = HISTORY_ENGINENETVERSION_PLUS_ONE - 1,