From fae58cf0715e36ee2e715b559245d25be22cff8d Mon Sep 17 00:00:00 2001 From: Crystal Date: Sun, 2 Nov 2025 16:23:28 -0500 Subject: [PATCH 1/3] Finish FunctionExport serialization code --- UAssetAPI/ExportTypes/FunctionExport.cs | 44 ++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/UAssetAPI/ExportTypes/FunctionExport.cs b/UAssetAPI/ExportTypes/FunctionExport.cs index d460c50f..6a81b761 100644 --- a/UAssetAPI/ExportTypes/FunctionExport.cs +++ b/UAssetAPI/ExportTypes/FunctionExport.cs @@ -1,6 +1,7 @@ using System.IO; -using UAssetAPI.UnrealTypes; +using System.Reflection.PortableExecutable; using UAssetAPI.ExportTypes; +using UAssetAPI.UnrealTypes; namespace UAssetAPI.ExportTypes { @@ -9,7 +10,11 @@ namespace UAssetAPI.ExportTypes /// public class FunctionExport : StructExport { - public EFunctionFlags FunctionFlags; + public EFunctionFlags FunctionFlags; + public int RepOffset; + public FPackageIndex EventGraphFunction; + public int EventGraphCallOffset; + public FunctionExport(Export super) : base(super) { Asset = super.Asset; @@ -30,14 +35,43 @@ public override void Read(AssetBinaryReader reader, int nextStarting) { base.Read(reader, nextStarting); FunctionFlags = (EFunctionFlags)reader.ReadUInt32(); - // TODO + + if (FunctionFlags.HasFlag(EFunctionFlags.FUNC_Net)) + { + RepOffset = reader.ReadInt32(); + } + else + { + RepOffset = 0; + } + + if (reader.Asset.ObjectVersion >= ObjectVersion.VER_UE4_SERIALIZE_BLUEPRINT_EVENTGRAPH_FASTCALLS_IN_UFUNCTION) + { + EventGraphFunction = new(reader.ReadInt32()); + EventGraphCallOffset = reader.ReadInt32(); + } + else + { + EventGraphFunction = null; + EventGraphCallOffset = 0; + } } public override void Write(AssetBinaryWriter writer) { base.Write(writer); writer.Write((uint)FunctionFlags); - // TODO - } + + if (FunctionFlags.HasFlag(EFunctionFlags.FUNC_Net)) + { + writer.Write(RepOffset); + } + + if (writer.Asset.ObjectVersion >= ObjectVersion.VER_UE4_SERIALIZE_BLUEPRINT_EVENTGRAPH_FASTCALLS_IN_UFUNCTION) + { + writer.Write(EventGraphFunction.Index); + writer.Write(EventGraphCallOffset); + } + } } } From adb85a607fafbcaa99993e16646254f35ed83a3c Mon Sep 17 00:00:00 2001 From: Crystal Date: Sun, 2 Nov 2025 16:27:39 -0500 Subject: [PATCH 2/3] Fix crash in AncestryInfo.SetAsParent --- UAssetAPI/PropertyTypes/Objects/PropertyData.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UAssetAPI/PropertyTypes/Objects/PropertyData.cs b/UAssetAPI/PropertyTypes/Objects/PropertyData.cs index 0a85ec3d..f2e1cf28 100644 --- a/UAssetAPI/PropertyTypes/Objects/PropertyData.cs +++ b/UAssetAPI/PropertyTypes/Objects/PropertyData.cs @@ -96,7 +96,7 @@ public void Initialize(AncestryInfo ancestors, FName dad, FName modulePath = nul public void SetAsParent(FName dad, FName modulePath = null) { - if (dad != null) Ancestors.Add(string.IsNullOrEmpty(modulePath?.Value?.Value) ? dad : FName.DefineDummy(null, modulePath.Value.Value + "." + dad.Value.Value)); + if (dad?.Value != null) Ancestors.Add(string.IsNullOrEmpty(modulePath?.Value?.Value) ? dad : FName.DefineDummy(null, modulePath.Value.Value + "." + dad.Value.Value)); } } From 7a5b2260169119f23e8a20d97fdb8c4c48316aa3 Mon Sep 17 00:00:00 2001 From: Crystal Date: Sun, 2 Nov 2025 17:02:24 -0500 Subject: [PATCH 3/3] FunctionExport.RepOffset is 2 bytes, not 4 --- UAssetAPI/ExportTypes/FunctionExport.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UAssetAPI/ExportTypes/FunctionExport.cs b/UAssetAPI/ExportTypes/FunctionExport.cs index 6a81b761..f1fd1d86 100644 --- a/UAssetAPI/ExportTypes/FunctionExport.cs +++ b/UAssetAPI/ExportTypes/FunctionExport.cs @@ -11,7 +11,7 @@ namespace UAssetAPI.ExportTypes public class FunctionExport : StructExport { public EFunctionFlags FunctionFlags; - public int RepOffset; + public short RepOffset; public FPackageIndex EventGraphFunction; public int EventGraphCallOffset; @@ -38,7 +38,7 @@ public override void Read(AssetBinaryReader reader, int nextStarting) if (FunctionFlags.HasFlag(EFunctionFlags.FUNC_Net)) { - RepOffset = reader.ReadInt32(); + RepOffset = reader.ReadInt16(); } else {