Skip to content

Commit

Permalink
fix: parse FGameplayTag with new bUseDynamicReplication (#61)
Browse files Browse the repository at this point in the history
* fix: parse game play tag with new bUseDynamicReplication

* fixup! fix: parse game play tag with new bUseDynamicReplication
  • Loading branch information
Shiqan authored Nov 9, 2024
1 parent 3e16518 commit 2a22812
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 10 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Interfaces to support proper DI
- Register types to be parsed with DI

## [2.2.3] - 2024-11-05
## [2.3.1] - 2024-11-08
### Changed
- fix parsing of `FGameplayTag` with new `bUseDynamicReplication`

## [2.3.0] - 2024-11-05
### Changed
- add support for Fortnite v32 (see [issue 58](https://github.com/Shiqan/FortniteReplayDecompressor/issues/58)) (by [SL-x-TnT](https://github.com/SL-x-TnT))

Expand Down
2 changes: 1 addition & 1 deletion src/ConsoleReader/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ private static void Main(string[] args)
//var replayFilesFolder = Path.Combine(localAppDataFolder, @"FortniteGame\Saved\Demos");
//var replayFilesFolder = @"F:\Projects\FortniteReplayCollection\_upload\";
var replayFilesFolder = @"C:\Users\ferro\Downloads\";
var replayFiles = Directory.EnumerateFiles(replayFilesFolder, "*.replay");
var replayFiles = Directory.EnumerateFiles(replayFilesFolder, "*919.replay");

var sw = new Stopwatch();
#if DEBUG
Expand Down
33 changes: 27 additions & 6 deletions src/Unreal.Core.Test/FGameplayTagContainerTest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Unreal.Core.Models;
using Unreal.Core.Models.Enums;
using Xunit;

namespace Unreal.Core.Test;
Expand All @@ -11,22 +12,42 @@ public class FGameplayTagContainerTest
0x58, 0xE7, 0x8C, 0xE9, 0x8C, 0x5B, 0x34, 0xDF, 0x8C, 0x0F, 0xB6, 0x5F,
0x80, 0x4D, 0x7E, 0xE3, 0x7E, 0x83, 0x7E, 0xBB, 0x7E, 0x89, 0x52, 0x5F,
0xF0, 0x6D, 0xD0, 0xC9, 0xBE, 0x55, 0xCE, 0x35, 0xCE, 0x85, 0x7E, 0xC5,
0x7C }, 392)]
0x7C }, 392, EngineNetworkVersionHistory.HISTORY_INITIAL)]
[InlineData(new byte[] {
0x38, 0x67, 0x56, 0x73, 0xCA, 0xFD, 0xB4, 0x79, 0xCC, 0xA5, 0x32, 0x69,
0x58, 0xE7, 0x8C, 0xE9, 0x8C, 0x5B, 0x34, 0xDF, 0x8C, 0x0F, 0xB6, 0x5F,
0x80, 0x57, 0x34, 0xD7, 0x14, 0xCF, 0x14, 0x4D, 0x7E, 0xE3, 0x7E, 0x83,
0x7E, 0xBB, 0x7E, 0xAD, 0xEE, 0x41, 0xBE, 0x71, 0x7E, 0x95, 0x7E, 0xF7,
0x12, 0xDB, 0x7E, 0x3F, 0xBE, 0xCB, 0x7C, 0xCF, 0x7C }, 456)]
0x12, 0xDB, 0x7E, 0x3F, 0xBE, 0xCB, 0x7C, 0xCF, 0x7C }, 456, EngineNetworkVersionHistory.HISTORY_INITIAL)]
[InlineData(new byte[] {
0x4C, 0x02, 0x2E, 0x30, 0x02, 0xCB, 0x24, 0x00, 0x04, 0x2E, 0x30, 0x02,
0xB1, 0x24, 0x00, 0x06, 0x2E, 0x30, 0x02, 0xB3, 0x24, 0x00, 0x08, 0x2E,
0x30, 0x02, 0xAF, 0x24, 0x00, 0x0A, 0x2E, 0x30, 0x02, 0x67, 0x24, 0x00,
0x0C, 0x2E, 0x30, 0x02, 0xC1, 0x24, 0x00, 0x0E, 0x2E }, 360)]
[InlineData(new byte[] { 0x04, 0x7F, 0x32, 0x8B, 0x32 }, 40)]
public void GameplayTagContainerTest(byte[] rawData, int bitCount)
0x0C, 0x2E, 0x30, 0x02, 0xC1, 0x24, 0x00, 0x0E, 0x2E }, 360, EngineNetworkVersionHistory.HISTORY_INITIAL)]
[InlineData(new byte[] { 0x04, 0x7F, 0x32, 0x8B, 0x32 }, 40, EngineNetworkVersionHistory.HISTORY_INITIAL)]
[InlineData(new byte[] {
0x40, 0xEE, 0x12, 0xB4, 0x97, 0xA0, 0xBF, 0x04, 0x0D, 0x26, 0xE8, 0x30,
0x41, 0x47, 0x0C, 0x5A, 0x62, 0xD0, 0x63, 0x82, 0x26, 0x13, 0x94, 0xA4,
0x27, 0x06, 0xE5, 0xA8, 0x47, 0x41, 0x2A, 0xD2, 0x0D, 0x82, 0x7E, 0x1B,
0x74, 0x9E, 0xA0, 0xCF, 0x04, 0x8D, 0x26, 0xE8, 0x34, 0x41, 0xAB, 0x09,
0xBA, 0x4D, 0xD0, 0x31, 0x83, 0x96, 0x19, 0xF4, 0xCC, 0xA0, 0x69, 0x06,
0x5D, 0x33, 0x68, 0x9B, 0x41, 0xDF, 0x0C, 0xFA, 0x4E, 0xD0, 0x78, 0x82
}, 576, EngineNetworkVersionHistory.CustomExports)]
[InlineData(new byte[] {
0x42, 0xEE, 0x12, 0xB4, 0x97, 0xA0, 0xBF, 0x04, 0x0D, 0x26, 0xE8, 0x30,
0x41, 0x47, 0x0C, 0x5A, 0x62, 0xD0, 0x63, 0x82, 0x26, 0x13, 0x94, 0xA4,
0x27, 0x06, 0xE5, 0xA8, 0x47, 0x41, 0x2A, 0xD2, 0x6B, 0x81, 0xCE, 0x13,
0xF4, 0x99, 0xA0, 0xD1, 0x04, 0x9D, 0x26, 0x68, 0x35, 0x41, 0xB7, 0x09,
0x3A, 0x66, 0xD0, 0x32, 0x83, 0x9E, 0x19, 0x34, 0xCD, 0xA0, 0x6B, 0x06,
0x6D, 0x33, 0xE8, 0x9B, 0x41, 0xDF, 0x09, 0x1A, 0x4F, 0xD0, 0x38, 0x83,
0xCE, 0x19, 0x04
}, 595, EngineNetworkVersionHistory.CustomExports)]
public void GameplayTagContainerTest(byte[] rawData, int bitCount, EngineNetworkVersionHistory engineNetworkVersionHistory)
{
var reader = new NetBitReader(rawData, bitCount);
var reader = new NetBitReader(rawData, bitCount)
{
EngineNetworkVersion = engineNetworkVersionHistory,
};
var tagcontainer = new FGameplayTagContainer();
tagcontainer.Serialize(reader);

Expand Down
4 changes: 3 additions & 1 deletion src/Unreal.Core/Models/Enums/EngineNetworkVersionHistory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ public enum EngineNetworkVersionHistory
DynamicMontageSerialization = 33, // Bump version to support dynamic montage serialization in the Gameplay Ability System
PredictionKeyBaseNotReplicated = 34, // Bump version to stop FPredictionKey::Base from being replicated (it was unused).
RepMoveOptionalAcceleration = 35, // Bump version to support serialization changes to RepMove for optional Acceleration
CustomExports = 36, // Bump version to support CustomExports (such as NetTokens used for supporting "Dynamic Replication" of GameplayTags -- see FGameplayTag::NetSerialize_Packed) // -----<new versions can be added above this line>-------------------------------------------------
CustomExports = 36, // Bump version to support CustomExports (such as NetTokens used for supporting "Dynamic Replication" of GameplayTags -- see FGameplayTag::NetSerialize_Packed)

// -----<new versions can be added above this line>-------------------------------------------------

HISTORY_ENGINENETVERSION_PLUS_ONE,
LATEST = HISTORY_ENGINENETVERSION_PLUS_ONE - 1,
Expand Down
48 changes: 47 additions & 1 deletion src/Unreal.Core/Models/FGameplayTag.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,53 @@ public FGameplayTag(NetBitReader reader)
/// see https://github.com/EpicGames/UnrealEngine/blob/6c20d9831a968ad3cb156442bebb41a883e62152/Engine/Source/Runtime/GameplayTags/Private/GameplayTagContainer.cpp#L1210
/// </summary>
/// <param name="reader"></param>
public void Serialize(NetBitReader reader) => TagIndex = reader.ReadIntPacked();
public void Serialize(NetBitReader reader)
{
var bSerializeReplicationMethod = reader.EngineNetworkVersion >= Enums.EngineNetworkVersionHistory.CustomExports;
var bUseFastReplication = true;
var bUseDynamicReplication = false;

if (bSerializeReplicationMethod)
{
bUseFastReplication = reader.ReadBit();
if (!bUseFastReplication)
{
bUseDynamicReplication = reader.ReadBit();
}
}

if (bUseFastReplication)
{
// https://github.com/EpicGames/UnrealEngine/blob/55e6c59d10463ba45392a915f89cdf31660a41c7/Engine/Source/Runtime/GameplayTags/Private/GameplayTagContainer.cpp#L1226
TagIndex = reader.ReadIntPacked();
}
else if (bUseDynamicReplication)
{
// https://github.com/EpicGames/UnrealEngine/blob/55e6c59d10463ba45392a915f89cdf31660a41c7/Engine/Source/Runtime/GameplayTags/Private/GameplayTagContainer.cpp#L1393
// https://github.com/EpicGames/UnrealEngine/blob/85fe5dd282a00eb15e7ba41cbe46a46c440dea79/Engine/Source/Runtime/Experimental/Iris/Core/Private/Iris/ReplicationSystem/NetTokenStore.cpp#L117
TagIndex = reader.ReadIntPacked();

//if (const bool bIsValid = (TokenIndex != FNetToken::InvalidTokenIndex))
if (TagIndex > 0)
{
var bIsAssignedByAuthority = reader.ReadBit();

// pray we dont need this :)
//if (TokenTypeId == FNetToken::InvalidTokenTypeId)
//{
// uint32 TempTokenTypeId = 0;
// Ar.SerializeBits(&TempTokenTypeId, FNetToken::TokenTypeIdBits);
// TokenTypeId = TempTokenTypeId;
//}
}
}
//else
//{
// // not implemented
// // reader.ReadFName();
//}

}

public void Resolve(NetGuidCache cache)
{
Expand Down
6 changes: 6 additions & 0 deletions src/Unreal.Core/Models/NetGuidCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,16 @@ public NetFieldExportGroup? NetworkGameplayTagNodeIndex
{
if (_networkGameplayTagNodeIndex == null)
{
// bUseFastReplication
if (NetFieldExportGroupMap.TryGetValue("NetworkGameplayTagNodeIndex", out var nodeIndex))
{
_networkGameplayTagNodeIndex = nodeIndex;
}
// bUseDynamicReplication
else if (NetFieldExportGroupMap.TryGetValue("NetworkGameplayTagDynamicIndex", out nodeIndex))
{
_networkGameplayTagNodeIndex = nodeIndex;
}
}
return _networkGameplayTagNodeIndex;
}
Expand Down

0 comments on commit 2a22812

Please sign in to comment.