From a04fe81b5a6bb3332bf1522c998cd9059b1690d1 Mon Sep 17 00:00:00 2001 From: Rirurin Date: Mon, 29 Jun 2026 13:08:55 +0800 Subject: [PATCH 1/7] Object Logging and FMemory for UE 5.0 - 5.7 --- README.md | 26 +-- .../Unreal/Factories/UE5_0_3/UnrealFactory.cs | 176 ++++++++++++++++++ .../Unreal/Factories/UE5_1_1/UnrealFactory.cs | 176 ++++++++++++++++++ .../Unreal/Factories/UE5_2_1/UnrealFactory.cs | 176 ++++++++++++++++++ .../Unreal/Factories/UE5_3_2/UnrealFactory.cs | 176 ++++++++++++++++++ .../Unreal/Factories/UE5_5_4/UnrealFactory.cs | 176 ++++++++++++++++++ .../Unreal/Factories/UE5_6_1/UnrealFactory.cs | 176 ++++++++++++++++++ .../Unreal/Factories/UE5_7_4/UnrealFactory.cs | 176 ++++++++++++++++++ UE.Toolkit.Core/UE.Toolkit.Core.csproj | 2 +- UE.Toolkit.Interfaces/IUnrealObjects.cs | 5 + .../UE.Toolkit.Interfaces.csproj | 2 +- UE.Toolkit.Reloaded/ModConfig.json | 2 +- .../SMT5V-Win64-Shipping/scans.ini | 3 + .../iostoretest_50-win64-shipping/scans.ini | 66 +++++++ .../iostoretest_50-win64-shipping/unreal.ini | 20 ++ .../iostoretest_51-win64-shipping/scans.ini | 65 +++++++ .../iostoretest_51-win64-shipping/unreal.ini | 20 ++ .../iostoretest_52-win64-shipping/scans.ini | 64 +++++++ .../iostoretest_52-win64-shipping/unreal.ini | 20 ++ .../iostoretest_53-win64-shipping/scans.ini | 64 +++++++ .../iostoretest_53-win64-shipping/unreal.ini | 20 ++ .../iostoretest_55-win64-shipping/scans.ini | 65 +++++++ .../iostoretest_55-win64-shipping/unreal.ini | 20 ++ .../iostoretest_56-win64-shipping/scans.ini | 67 +++++++ .../iostoretest_56-win64-shipping/unreal.ini | 20 ++ .../iostoretest_57-win64-shipping/scans.ini | 68 +++++++ .../iostoretest_57-win64-shipping/unreal.ini | 20 ++ .../Project/UE.Toolkit.Reloaded/p3r/scans.ini | 4 +- .../Project/UE.Toolkit.Reloaded/scans.ini | 3 + UE.Toolkit.Reloaded/Unreal/UnrealObjects.cs | 23 +++ 30 files changed, 1884 insertions(+), 17 deletions(-) create mode 100644 UE.Toolkit.Core/Types/Unreal/Factories/UE5_0_3/UnrealFactory.cs create mode 100644 UE.Toolkit.Core/Types/Unreal/Factories/UE5_1_1/UnrealFactory.cs create mode 100644 UE.Toolkit.Core/Types/Unreal/Factories/UE5_2_1/UnrealFactory.cs create mode 100644 UE.Toolkit.Core/Types/Unreal/Factories/UE5_3_2/UnrealFactory.cs create mode 100644 UE.Toolkit.Core/Types/Unreal/Factories/UE5_5_4/UnrealFactory.cs create mode 100644 UE.Toolkit.Core/Types/Unreal/Factories/UE5_6_1/UnrealFactory.cs create mode 100644 UE.Toolkit.Core/Types/Unreal/Factories/UE5_7_4/UnrealFactory.cs create mode 100644 UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_50-win64-shipping/scans.ini create mode 100644 UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_50-win64-shipping/unreal.ini create mode 100644 UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_51-win64-shipping/scans.ini create mode 100644 UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_51-win64-shipping/unreal.ini create mode 100644 UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_52-win64-shipping/scans.ini create mode 100644 UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_52-win64-shipping/unreal.ini create mode 100644 UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_53-win64-shipping/scans.ini create mode 100644 UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_53-win64-shipping/unreal.ini create mode 100644 UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_55-win64-shipping/scans.ini create mode 100644 UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_55-win64-shipping/unreal.ini create mode 100644 UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_56-win64-shipping/scans.ini create mode 100644 UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_56-win64-shipping/unreal.ini create mode 100644 UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_57-win64-shipping/scans.ini create mode 100644 UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_57-win64-shipping/unreal.ini diff --git a/README.md b/README.md index a727a0f..09b9673 100644 --- a/README.md +++ b/README.md @@ -22,19 +22,19 @@ Object XML requires game-specific support with an extension mod. Supported games [are listed here](#installing-the-ue-toolkit-extension-mod). -| Feature | UE 4.27.2 | UE 5.4.4 | -| - | - | - | -| Object Logging | ✅| ✅ -| Object Editing | ✅| ✅ -| `FMemory` Functions | ✅| ✅ -| Dumper | ✅| ✅ -| Property Editing (Object XML) | ✅| ✅ -| Add List Entry (Object XML) | ✅| ❔ -| Add Map Entry (Object XML) | ✅| ❔ -| Type Information | ✅| ✅ -| Custom Constructor | ✅| ❔ -| Add Properties | ✅| ❌ -| Register Struct | ✅| ❌ +| Feature | 4.27 | 5.0 | 5.1 | 5.2 | 5.3 | 5.4 | 5.5 | 5.6 | 5.7 +| - | - | - | - | - | - | - | - | - | - | +| Object Logging |✅|✅|✅|✅|✅|✅|✅|✅|✅ +| Object Editing |✅|❔|❔|❔|❔|✅|❔|❔|❔ +| `FMemory` Functions |✅|✅|✅|✅|✅|✅|✅|✅|✅ +| Dumper |✅|❔|❔|❔|❔|✅|❔|❔|❔ +| Property Editing (Object XML) |✅|❔|❔|❔|❔|✅|❔|❔|❔ +| Add List Entry (Object XML) |✅|❔|❔|❔|❔|❔|❔|❔|❔ +| Add Map Entry (Object XML) |✅|❔|❔|❔|❔|❔|❔|❔|❔ +| Type Information |✅|❔|❔|❔|❔|✅|❔|❔|❔ +| Custom Constructor |✅|❔|❔|❔|❔|❔|❔|❔|❔ +| Add Properties |✅|❔|❔|❔|❔|❌|❔|❔|❔ +| Register Struct |✅|❔|❔|❔|❔|❌|❔|❔|❔ Features marked with ❔ are currently untested. diff --git a/UE.Toolkit.Core/Types/Unreal/Factories/UE5_0_3/UnrealFactory.cs b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_0_3/UnrealFactory.cs new file mode 100644 index 0000000..9e492fc --- /dev/null +++ b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_0_3/UnrealFactory.cs @@ -0,0 +1,176 @@ +using UE.Toolkit.Core.Types.Unreal.Factories.Interfaces; + +namespace UE.Toolkit.Core.Types.Unreal.Factories.UE5_0_3; + +public class UnrealFactory : BaseUnrealFactory +{ + public override IntPtr SizeOf() + { + throw new NotImplementedException(); + } + + public override IFProperty CreateFProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFBoolProperty CreateFBoolProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFByteProperty CreateFByteProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFEnumProperty CreateFEnumProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFObjectProperty CreateFObjectProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFSoftClassProperty CreateFSoftClassProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFClassProperty CreateFClassProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFStructProperty CreateFStructProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFMapProperty CreateFMapProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFInterfaceProperty CreateFInterfaceProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFArrayProperty CreateFArrayProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFSetProperty CreateFSetProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFOptionalProperty CreateFOptionalProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFDelegateProperty CreateFDelegateProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUObjectArray CreateUObjectArray(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUObject CreateUObject(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUClass CreateUClass(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUScriptStruct CreateUScriptStruct(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUEnum CreateUEnum(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUField CreateUField(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUStruct CreateUStruct(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUUserDefinedEnum CreateUUserDefinedEnum(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUFunction CreateUFunction(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFFieldClass CreateFFieldClass(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFField CreateFField(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFStructParams CreateFStructParams(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFPropertyParams CreateFPropertyParams(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFGenericPropertyParams CreateFGenericPropertyParams(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFWorldContext CreateFWorldContext(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUEngine CreateUEngine(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUGameInstance CreateUGameInstance(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFStaticConstructObjectParameters CreateFStaticConstructObjectParameters() + { + throw new NotImplementedException(); + } + + public override IFActorSpawnParameters CreateFActorSpawnParameters() + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/UE.Toolkit.Core/Types/Unreal/Factories/UE5_1_1/UnrealFactory.cs b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_1_1/UnrealFactory.cs new file mode 100644 index 0000000..38dc2bd --- /dev/null +++ b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_1_1/UnrealFactory.cs @@ -0,0 +1,176 @@ +using UE.Toolkit.Core.Types.Unreal.Factories.Interfaces; + +namespace UE.Toolkit.Core.Types.Unreal.Factories.UE5_1_1; + +public class UnrealFactory : BaseUnrealFactory +{ + public override IntPtr SizeOf() + { + throw new NotImplementedException(); + } + + public override IFProperty CreateFProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFBoolProperty CreateFBoolProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFByteProperty CreateFByteProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFEnumProperty CreateFEnumProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFObjectProperty CreateFObjectProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFSoftClassProperty CreateFSoftClassProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFClassProperty CreateFClassProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFStructProperty CreateFStructProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFMapProperty CreateFMapProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFInterfaceProperty CreateFInterfaceProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFArrayProperty CreateFArrayProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFSetProperty CreateFSetProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFOptionalProperty CreateFOptionalProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFDelegateProperty CreateFDelegateProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUObjectArray CreateUObjectArray(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUObject CreateUObject(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUClass CreateUClass(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUScriptStruct CreateUScriptStruct(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUEnum CreateUEnum(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUField CreateUField(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUStruct CreateUStruct(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUUserDefinedEnum CreateUUserDefinedEnum(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUFunction CreateUFunction(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFFieldClass CreateFFieldClass(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFField CreateFField(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFStructParams CreateFStructParams(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFPropertyParams CreateFPropertyParams(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFGenericPropertyParams CreateFGenericPropertyParams(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFWorldContext CreateFWorldContext(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUEngine CreateUEngine(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUGameInstance CreateUGameInstance(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFStaticConstructObjectParameters CreateFStaticConstructObjectParameters() + { + throw new NotImplementedException(); + } + + public override IFActorSpawnParameters CreateFActorSpawnParameters() + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/UE.Toolkit.Core/Types/Unreal/Factories/UE5_2_1/UnrealFactory.cs b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_2_1/UnrealFactory.cs new file mode 100644 index 0000000..be83540 --- /dev/null +++ b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_2_1/UnrealFactory.cs @@ -0,0 +1,176 @@ +using UE.Toolkit.Core.Types.Unreal.Factories.Interfaces; + +namespace UE.Toolkit.Core.Types.Unreal.Factories.UE5_2_1; + +public class UnrealFactory : BaseUnrealFactory +{ + public override IntPtr SizeOf() + { + throw new NotImplementedException(); + } + + public override IFProperty CreateFProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFBoolProperty CreateFBoolProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFByteProperty CreateFByteProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFEnumProperty CreateFEnumProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFObjectProperty CreateFObjectProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFSoftClassProperty CreateFSoftClassProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFClassProperty CreateFClassProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFStructProperty CreateFStructProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFMapProperty CreateFMapProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFInterfaceProperty CreateFInterfaceProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFArrayProperty CreateFArrayProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFSetProperty CreateFSetProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFOptionalProperty CreateFOptionalProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFDelegateProperty CreateFDelegateProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUObjectArray CreateUObjectArray(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUObject CreateUObject(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUClass CreateUClass(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUScriptStruct CreateUScriptStruct(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUEnum CreateUEnum(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUField CreateUField(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUStruct CreateUStruct(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUUserDefinedEnum CreateUUserDefinedEnum(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUFunction CreateUFunction(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFFieldClass CreateFFieldClass(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFField CreateFField(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFStructParams CreateFStructParams(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFPropertyParams CreateFPropertyParams(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFGenericPropertyParams CreateFGenericPropertyParams(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFWorldContext CreateFWorldContext(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUEngine CreateUEngine(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUGameInstance CreateUGameInstance(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFStaticConstructObjectParameters CreateFStaticConstructObjectParameters() + { + throw new NotImplementedException(); + } + + public override IFActorSpawnParameters CreateFActorSpawnParameters() + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/UE.Toolkit.Core/Types/Unreal/Factories/UE5_3_2/UnrealFactory.cs b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_3_2/UnrealFactory.cs new file mode 100644 index 0000000..315ef45 --- /dev/null +++ b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_3_2/UnrealFactory.cs @@ -0,0 +1,176 @@ +using UE.Toolkit.Core.Types.Unreal.Factories.Interfaces; + +namespace UE.Toolkit.Core.Types.Unreal.Factories.UE5_3_2; + +public class UnrealFactory : BaseUnrealFactory +{ + public override IntPtr SizeOf() + { + throw new NotImplementedException(); + } + + public override IFProperty CreateFProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFBoolProperty CreateFBoolProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFByteProperty CreateFByteProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFEnumProperty CreateFEnumProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFObjectProperty CreateFObjectProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFSoftClassProperty CreateFSoftClassProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFClassProperty CreateFClassProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFStructProperty CreateFStructProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFMapProperty CreateFMapProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFInterfaceProperty CreateFInterfaceProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFArrayProperty CreateFArrayProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFSetProperty CreateFSetProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFOptionalProperty CreateFOptionalProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFDelegateProperty CreateFDelegateProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUObjectArray CreateUObjectArray(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUObject CreateUObject(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUClass CreateUClass(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUScriptStruct CreateUScriptStruct(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUEnum CreateUEnum(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUField CreateUField(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUStruct CreateUStruct(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUUserDefinedEnum CreateUUserDefinedEnum(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUFunction CreateUFunction(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFFieldClass CreateFFieldClass(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFField CreateFField(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFStructParams CreateFStructParams(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFPropertyParams CreateFPropertyParams(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFGenericPropertyParams CreateFGenericPropertyParams(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFWorldContext CreateFWorldContext(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUEngine CreateUEngine(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUGameInstance CreateUGameInstance(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFStaticConstructObjectParameters CreateFStaticConstructObjectParameters() + { + throw new NotImplementedException(); + } + + public override IFActorSpawnParameters CreateFActorSpawnParameters() + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/UE.Toolkit.Core/Types/Unreal/Factories/UE5_5_4/UnrealFactory.cs b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_5_4/UnrealFactory.cs new file mode 100644 index 0000000..d468253 --- /dev/null +++ b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_5_4/UnrealFactory.cs @@ -0,0 +1,176 @@ +using UE.Toolkit.Core.Types.Unreal.Factories.Interfaces; + +namespace UE.Toolkit.Core.Types.Unreal.Factories.UE5_5_4; + +public class UnrealFactory : BaseUnrealFactory +{ + public override IntPtr SizeOf() + { + throw new NotImplementedException(); + } + + public override IFProperty CreateFProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFBoolProperty CreateFBoolProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFByteProperty CreateFByteProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFEnumProperty CreateFEnumProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFObjectProperty CreateFObjectProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFSoftClassProperty CreateFSoftClassProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFClassProperty CreateFClassProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFStructProperty CreateFStructProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFMapProperty CreateFMapProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFInterfaceProperty CreateFInterfaceProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFArrayProperty CreateFArrayProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFSetProperty CreateFSetProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFOptionalProperty CreateFOptionalProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFDelegateProperty CreateFDelegateProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUObjectArray CreateUObjectArray(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUObject CreateUObject(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUClass CreateUClass(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUScriptStruct CreateUScriptStruct(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUEnum CreateUEnum(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUField CreateUField(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUStruct CreateUStruct(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUUserDefinedEnum CreateUUserDefinedEnum(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUFunction CreateUFunction(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFFieldClass CreateFFieldClass(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFField CreateFField(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFStructParams CreateFStructParams(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFPropertyParams CreateFPropertyParams(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFGenericPropertyParams CreateFGenericPropertyParams(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFWorldContext CreateFWorldContext(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUEngine CreateUEngine(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUGameInstance CreateUGameInstance(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFStaticConstructObjectParameters CreateFStaticConstructObjectParameters() + { + throw new NotImplementedException(); + } + + public override IFActorSpawnParameters CreateFActorSpawnParameters() + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/UE.Toolkit.Core/Types/Unreal/Factories/UE5_6_1/UnrealFactory.cs b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_6_1/UnrealFactory.cs new file mode 100644 index 0000000..e4e11cc --- /dev/null +++ b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_6_1/UnrealFactory.cs @@ -0,0 +1,176 @@ +using UE.Toolkit.Core.Types.Unreal.Factories.Interfaces; + +namespace UE.Toolkit.Core.Types.Unreal.Factories.UE5_6_1; + +public class UnrealFactory : BaseUnrealFactory +{ + public override IntPtr SizeOf() + { + throw new NotImplementedException(); + } + + public override IFProperty CreateFProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFBoolProperty CreateFBoolProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFByteProperty CreateFByteProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFEnumProperty CreateFEnumProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFObjectProperty CreateFObjectProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFSoftClassProperty CreateFSoftClassProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFClassProperty CreateFClassProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFStructProperty CreateFStructProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFMapProperty CreateFMapProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFInterfaceProperty CreateFInterfaceProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFArrayProperty CreateFArrayProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFSetProperty CreateFSetProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFOptionalProperty CreateFOptionalProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFDelegateProperty CreateFDelegateProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUObjectArray CreateUObjectArray(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUObject CreateUObject(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUClass CreateUClass(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUScriptStruct CreateUScriptStruct(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUEnum CreateUEnum(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUField CreateUField(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUStruct CreateUStruct(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUUserDefinedEnum CreateUUserDefinedEnum(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUFunction CreateUFunction(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFFieldClass CreateFFieldClass(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFField CreateFField(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFStructParams CreateFStructParams(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFPropertyParams CreateFPropertyParams(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFGenericPropertyParams CreateFGenericPropertyParams(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFWorldContext CreateFWorldContext(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUEngine CreateUEngine(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUGameInstance CreateUGameInstance(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFStaticConstructObjectParameters CreateFStaticConstructObjectParameters() + { + throw new NotImplementedException(); + } + + public override IFActorSpawnParameters CreateFActorSpawnParameters() + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/UE.Toolkit.Core/Types/Unreal/Factories/UE5_7_4/UnrealFactory.cs b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_7_4/UnrealFactory.cs new file mode 100644 index 0000000..4904e25 --- /dev/null +++ b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_7_4/UnrealFactory.cs @@ -0,0 +1,176 @@ +using UE.Toolkit.Core.Types.Unreal.Factories.Interfaces; + +namespace UE.Toolkit.Core.Types.Unreal.Factories.UE5_7_4; + +public class UnrealFactory : BaseUnrealFactory +{ + public override IntPtr SizeOf() + { + throw new NotImplementedException(); + } + + public override IFProperty CreateFProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFBoolProperty CreateFBoolProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFByteProperty CreateFByteProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFEnumProperty CreateFEnumProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFObjectProperty CreateFObjectProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFSoftClassProperty CreateFSoftClassProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFClassProperty CreateFClassProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFStructProperty CreateFStructProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFMapProperty CreateFMapProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFInterfaceProperty CreateFInterfaceProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFArrayProperty CreateFArrayProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFSetProperty CreateFSetProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFOptionalProperty CreateFOptionalProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFDelegateProperty CreateFDelegateProperty(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUObjectArray CreateUObjectArray(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUObject CreateUObject(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUClass CreateUClass(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUScriptStruct CreateUScriptStruct(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUEnum CreateUEnum(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUField CreateUField(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUStruct CreateUStruct(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUUserDefinedEnum CreateUUserDefinedEnum(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUFunction CreateUFunction(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFFieldClass CreateFFieldClass(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFField CreateFField(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFStructParams CreateFStructParams(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFPropertyParams CreateFPropertyParams(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFGenericPropertyParams CreateFGenericPropertyParams(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFWorldContext CreateFWorldContext(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUEngine CreateUEngine(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IUGameInstance CreateUGameInstance(IntPtr ptr) + { + throw new NotImplementedException(); + } + + public override IFStaticConstructObjectParameters CreateFStaticConstructObjectParameters() + { + throw new NotImplementedException(); + } + + public override IFActorSpawnParameters CreateFActorSpawnParameters() + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/UE.Toolkit.Core/UE.Toolkit.Core.csproj b/UE.Toolkit.Core/UE.Toolkit.Core.csproj index cd84b4d..f3a7522 100644 --- a/UE.Toolkit.Core/UE.Toolkit.Core.csproj +++ b/UE.Toolkit.Core/UE.Toolkit.Core.csproj @@ -6,7 +6,7 @@ enable true https://github.com/RyoTune/UE.Toolkit - 1.6.6 + 1.8.0 diff --git a/UE.Toolkit.Interfaces/IUnrealObjects.cs b/UE.Toolkit.Interfaces/IUnrealObjects.cs index 2083ccc..17db782 100644 --- a/UE.Toolkit.Interfaces/IUnrealObjects.cs +++ b/UE.Toolkit.Interfaces/IUnrealObjects.cs @@ -17,6 +17,11 @@ public unsafe interface IUnrealObjects : IObjectCreator /// Action>? OnObjectLoaded { get; set; } + /// + /// Notify when an object will be destroyed. + /// + Action>? OnObjectBeginDestroy { get; set; } + /// /// Gets the global UObject array. /// diff --git a/UE.Toolkit.Interfaces/UE.Toolkit.Interfaces.csproj b/UE.Toolkit.Interfaces/UE.Toolkit.Interfaces.csproj index b32a888..e1feca4 100644 --- a/UE.Toolkit.Interfaces/UE.Toolkit.Interfaces.csproj +++ b/UE.Toolkit.Interfaces/UE.Toolkit.Interfaces.csproj @@ -6,7 +6,7 @@ enable true https://github.com/RyoTune/UE.Toolkit - 1.6.6 + 1.8.0 diff --git a/UE.Toolkit.Reloaded/ModConfig.json b/UE.Toolkit.Reloaded/ModConfig.json index 1ccab30..2df488a 100644 --- a/UE.Toolkit.Reloaded/ModConfig.json +++ b/UE.Toolkit.Reloaded/ModConfig.json @@ -2,7 +2,7 @@ "ModId": "UE.Toolkit.Reloaded", "ModName": "Unreal Toolkit", "ModAuthor": "RyoTune, Rirurin", - "ModVersion": "1.7.2", + "ModVersion": "1.8.0", "ModDescription": "Modding toolkit for Unreal Engine games.\r\n\r\nSupported:\r\n- UE 5.4.4 (Clair Obscur)\r\n- UE 4.27.2 (P3R/SMTVV)", "ModDll": "UE.Toolkit.Reloaded.dll", "ModIcon": "Preview.png", diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/SMT5V-Win64-Shipping/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/SMT5V-Win64-Shipping/scans.ini index fb0e5a6..52d1d44 100644 --- a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/SMT5V-Win64-Shipping/scans.ini +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/SMT5V-Win64-Shipping/scans.ini @@ -17,6 +17,9 @@ FText_ToString=40 53 48 83 EC 20 48 8B D9 E8 ?? ?? ?? ?? 48 8B 0B 48 8B 01 UObject_PostLoadSubobjects=40 53 48 83 EC 20 48 8B 41 ?? 48 8B D9 8B 90 ?? ?? ?? ?? C1 EA 17 ;UObject_PostLoadSubobjects_RESULT= +UObject_BeginDestroy=40 53 48 83 EC 30 8B 41 ?? 48 8B D9 C1 E8 0F +;UObject_BeginDestroy_RESULT= + GUObjectArray=48 8B 05 ?? ?? ?? ?? 48 8B 0C ?? 48 8D 04 ?? 48 85 C0 74 ?? 44 39 40 ?? 75 ?? F7 40 ?? 00 00 00 30 75 ?? 48 8B 00 GUObjectArray_RESULT=GetGlobalAddress(result + 3) - 0x10 diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_50-win64-shipping/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_50-win64-shipping/scans.ini new file mode 100644 index 0000000..5bffbbc --- /dev/null +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_50-win64-shipping/scans.ini @@ -0,0 +1,66 @@ +;Based on Third Person Template for UE 5.0 + +[Scans] +GFNamePool=48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 4C 8B C0 C6 05 ?? ?? ?? ?? 01 8B D3 0F B7 C3 89 44 24 +GFNamePool_RESULT=GetGlobalAddress(result + 3) + +;FNameHelper_FindOrStoreString=48 89 74 24 ?? 57 48 83 EC 60 81 79 ?? 00 04 00 00 +;FNameHelper_FindOrStoreString_RESULT= + +;??0FName@@QEAA@PEB_WW4EFindName@@@Z +FName_Ctor_Wide=48 89 5C 24 ?? 57 48 83 EC 30 48 8B D9 48 89 54 24 ?? 33 C9 +;FName_Ctor_Wide_RESULT= + +;LaunchFixGameNameCase +FText_FromString=E8 ?? ?? ?? ?? 83 7C 24 ?? 00 48 8D 4C 24 ?? 49 8B D4 +FText_FromString_RESULT=GetGlobalAddress(result + 1) + +FText_ToString=40 53 48 83 EC 20 48 8B D9 E8 ?? ?? ?? ?? 48 8B 0B 48 8B 01 48 83 C4 20 +;FText_ToString_RESULT= + +UObject_PostLoadSubobjects=40 53 48 83 EC 20 48 8B 41 ?? 48 8B D9 8B 90 ?? ?? ?? ?? +;UObject_PostLoadSubobjects_RESULT= + +UObject_BeginDestroy=40 53 48 83 EC 20 8B 41 ?? 48 8B D9 C1 E8 0F A8 01 75 ?? 48 89 4C 24 ?? +;UObject_BeginDestroy_RESULT= + +;From UObjectBaseInit +GUObjectArray=89 15 ?? ?? ?? ?? 85 FF +GUObjectArray_RESULT=GetGlobalAddress(result + 2) + +;Inlined +UStruct_IsChildOf=DISABLED +;UStruct_IsChildOf_RESULT= + +UEnum_GetDisplayNameTextByIndex=48 89 5C 24 ?? 55 56 57 48 83 EC 30 48 8B FA +;UEnum_GetDisplayNameTextByIndex_RESULT= + +UDataTable_HandleDataTableChanged=48 89 54 24 ?? 55 53 56 48 8D 6C 24 ?? 48 81 EC A0 00 00 00 +;UDataTable_HandleDataTableChanged_RESULT= + +GMalloc=48 8B 0D ?? ?? ?? ?? 48 85 C9 75 ?? E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? 48 8B 01 48 8B D3 FF 50 ?? 48 83 C4 20 +GMalloc_RESULT=GetGlobalAddress(result + 3) + +FTextInspector_GetTableIdAndKey=48 89 5C 24 ?? 48 89 74 24 ?? 41 56 48 83 EC 30 48 8B D9 +;FTextInspector_GetTableIdAndKey + +GetPrivateStaticClassBody_UE4=DISABLED +;GetPrivateStaticClassBody_RESULT= + +GetPrivateStaticClassBody_UE5=48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 54 41 55 41 56 41 57 48 83 EC 60 45 33 ED +;GetPrivateStaticClassBody_RESULT= + +StaticConstructObject_Internal=4C 8B DC 49 89 5B ?? 49 89 73 ?? 55 57 41 54 41 56 41 57 49 8D AB ?? ?? ?? ?? +;StaticConstructObject_Internal_RESULT= + +GetStaticStruct=48 89 5C 24 ?? 48 89 6C 24 ?? 56 57 41 56 48 83 EC 40 4D 8B F0 48 8B DA 48 8B F1 48 8B C2 66 90 48 83 78 ?? 00 48 8D 78 ?? 74 ?? 33 C9 F7 40 ?? 00 00 00 10 74 ?? 48 8B C8 E8 ?? ?? ?? ?? 48 8B C8 48 8B C1 48 85 C0 75 ?? 48 8B 07 EB ?? 48 8B 48 ?? 48 8D 54 24 ?? 48 89 4C 24 ?? 48 8D 4C 24 ?? E8 ?? ?? ?? ?? 83 7C 24 ?? 00 48 8D 2D ?? ?? ?? ?? 41 B9 01 00 00 00 C6 44 24 ?? 00 48 8B CD 48 C7 44 24 ?? 00 00 00 00 48 0F 45 4C 24 ?? 49 8B D6 45 8D 41 ?? E8 ?? ?? ?? ?? 48 8B 4C 24 ?? 48 85 C9 74 ?? E8 ?? ?? ?? ?? FF D6 48 8B F0 90 48 83 7B ?? 00 48 8D 7B ?? 74 ?? 33 C0 F7 43 ?? 00 00 00 10 74 ?? 48 8B CB E8 ?? ?? ?? ?? 48 8B D8 48 85 DB 75 ?? 48 8B 1F EB ?? 48 8B 43 ?? 48 8D 54 24 ?? 48 8D 4C 24 ?? 48 89 44 24 ?? E8 ?? ?? ?? ?? 83 7C 24 ?? 00 41 B9 02 00 00 00 C6 44 24 ?? 00 45 8B C1 +;GetStaticStruct_RESULT= + +ConstructUScriptStruct=40 53 56 57 41 55 41 56 41 57 48 81 EC C8 03 00 00 +;ConstructUScriptStruct + +GEngine=48 89 05 ?? ?? ?? ?? 48 85 C9 74 ?? E8 ?? ?? ?? ?? 48 8D 4D ?? +GEngine_RESULT=GetGlobalAddress(result + 3) + +UWorld_SpawnActor=E8 ?? ?? ?? ?? 48 8B D0 48 89 84 24 ?? ?? ?? ?? 48 8B CD +UWorld_SpawnActor_RESULT=GetGlobalAddress(result + 1) \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_50-win64-shipping/unreal.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_50-win64-shipping/unreal.ini new file mode 100644 index 0000000..bad97ad --- /dev/null +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_50-win64-shipping/unreal.ini @@ -0,0 +1,20 @@ +;Based on Third Person Template for UE 5.0 + +[FMallocBinned2] +Free=0x30 +GetAllocSize=0x40 +Malloc=0x10 +Realloc=0x20 +QuantizeSize=0x38 + +[UObject] +ProcessEvent=0x268 + +[UScriptStruct] +GetCustomGuid=0x378 + +[UPackage] +GamePackage=/Script/SandFall + +[UStruct] +Link=0x2d0 \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_51-win64-shipping/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_51-win64-shipping/scans.ini new file mode 100644 index 0000000..69f47d1 --- /dev/null +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_51-win64-shipping/scans.ini @@ -0,0 +1,65 @@ +;Based on Third Person Template for UE 5.1 + +[Scans] +GFNamePool=48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 4C 8B C0 C6 05 ?? ?? ?? ?? 01 8B D3 0F B7 C3 89 44 24 +GFNamePool_RESULT=GetGlobalAddress(result + 3) + +;FNameHelper_FindOrStoreString=48 89 74 24 ?? 57 48 83 EC 60 81 79 ?? 00 04 00 00 +;FNameHelper_FindOrStoreString_RESULT= + +;??0FName@@QEAA@PEB_WW4EFindName@@@Z +FName_Ctor_Wide=48 89 5C 24 ?? 57 48 83 EC 30 48 8B D9 48 89 54 24 ?? 33 C9 +;FName_Ctor_Wide_RESULT= + +;?FromString@FText@@SA?AV1@$$QEAVFString@@@Z +FText_FromString=48 89 6C 24 ?? 57 48 83 EC 50 83 7A ?? 01 48 8B F9 48 89 74 24 ?? C7 44 24 ?? 00 00 00 00 7F ?? E8 ?? ?? ?? ?? 48 8B 48 ?? 48 8B 10 48 89 54 24 ?? 48 89 4C 24 ?? 48 85 C9 74 ?? F0 FF 41 ?? 8B 40 ?? BE 01 00 00 00 89 44 24 ?? 48 8D 44 24 ?? EB ?? 48 8D 4C 24 ?? E8 ?? ?? ?? ?? BE 02 00 00 00 48 8B 10 48 89 17 48 8B 48 ?? 48 89 4F ?? 48 85 C9 74 ?? F0 FF 41 ?? 8B 40 ?? BD FF FF FF FF 89 47 ?? 48 89 5C 24 ?? 40 F6 C6 02 74 ?? 48 8B 5C 24 ?? 83 E6 FD 48 85 DB 74 ?? 8B C5 F0 0F C1 43 ?? 83 F8 01 75 ?? 48 8B 03 48 8B CB FF 10 8B C5 F0 0F C1 43 ?? 83 F8 01 75 ?? 48 8B 03 8D 55 ?? 48 8B CB FF 50 ?? 40 F6 C6 01 48 8B 74 24 ?? 74 ?? 48 8B 4C 24 ?? 48 85 C9 74 ?? 8B C5 F0 0F C1 41 ?? 83 F8 01 75 ?? 48 8B 5C 24 ?? 48 8B CB 48 8B 03 FF 10 F0 0F C1 6B ?? 83 FD 01 75 ?? 48 8B 4C 24 ?? 8B D5 48 8B 01 FF 50 ?? 83 4F ?? 12 +;FText_FromString_RESULT= + +FText_ToString=40 53 48 83 EC 20 48 8B D9 E8 ?? ?? ?? ?? 48 8B 0B 48 8B 01 48 83 C4 20 +;FText_ToString_RESULT= + +UObject_PostLoadSubobjects=40 53 48 83 EC 20 48 8B 41 ?? 48 8B D9 8B 90 ?? ?? ?? ?? +;UObject_PostLoadSubobjects_RESULT= + +UObject_BeginDestroy=40 53 48 83 EC 30 8B 41 ?? 48 8B D9 C1 E8 0F +;UObject_BeginDestroy_RESULT= + +;From UObjectBaseInit +GUObjectArray=89 15 ?? ?? ?? ?? 85 FF +GUObjectArray_RESULT=GetGlobalAddress(result + 2) + +UStruct_IsChildOf=48 85 D2 74 ?? 48 63 42 ?? 4C 8D 42 +;UStruct_IsChildOf_RESULT= + +UEnum_GetDisplayNameTextByIndex=48 89 5C 24 ?? 55 56 57 48 83 EC 30 48 8B FA +;UEnum_GetDisplayNameTextByIndex_RESULT= + +UDataTable_HandleDataTableChanged=48 89 54 24 ?? 55 53 56 48 8D 6C 24 ?? 48 81 EC A0 00 00 00 +;UDataTable_HandleDataTableChanged_RESULT= + +GMalloc=48 8B 0D ?? ?? ?? ?? 48 85 C9 75 ?? E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? 48 8B 01 48 8B D3 FF 50 ?? 48 83 C4 20 +GMalloc_RESULT=GetGlobalAddress(result + 3) + +FTextInspector_GetTableIdAndKey=48 89 5C 24 ?? 48 89 74 24 ?? 41 56 48 83 EC 30 48 8B D9 +;FTextInspector_GetTableIdAndKey + +GetPrivateStaticClassBody_UE4=DISABLED +;GetPrivateStaticClassBody_RESULT= + +GetPrivateStaticClassBody_UE5=48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 54 41 55 41 56 41 57 48 83 EC 60 45 33 ED +;GetPrivateStaticClassBody_RESULT= + +StaticConstructObject_Internal=4C 8B DC 49 89 5B ?? 49 89 73 ?? 55 57 41 54 41 56 41 57 49 8D AB ?? ?? ?? ?? +;StaticConstructObject_Internal_RESULT= + +GetStaticStruct=48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 50 49 8B E8 48 8B DA FF D1 48 8B F0 90 48 83 7B ?? 00 48 8D 7B ?? 74 ?? 33 C0 F7 43 ?? 00 00 00 10 74 ?? 48 8B CB E8 ?? ?? ?? ?? 48 8B D8 48 85 DB 75 ?? 48 8B 1F EB ?? 48 8B 43 ?? 48 8D 54 24 ?? 48 8D 4C 24 ?? 48 89 44 24 ?? E8 ?? ?? ?? ?? 83 7C 24 ?? 00 48 8D 0D ?? ?? ?? ?? 41 B9 02 00 00 00 48 89 74 24 ?? 48 0F 45 4C 24 ?? 45 8B C1 +;GetStaticStruct_RESULT= + +ConstructUScriptStruct=40 53 56 57 41 55 41 56 41 57 48 81 EC C8 03 00 00 +;ConstructUScriptStruct + +GEngine=48 89 05 ?? ?? ?? ?? 48 85 C9 74 ?? E8 ?? ?? ?? ?? 48 8D 4D ?? +GEngine_RESULT=GetGlobalAddress(result + 3) + +UWorld_SpawnActor=E8 ?? ?? ?? ?? 48 8B D0 48 89 44 24 ?? 48 8B CD E8 ?? ?? ?? ?? 8B 45 ?? +UWorld_SpawnActor_RESULT=GetGlobalAddress(result + 1) \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_51-win64-shipping/unreal.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_51-win64-shipping/unreal.ini new file mode 100644 index 0000000..94609dc --- /dev/null +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_51-win64-shipping/unreal.ini @@ -0,0 +1,20 @@ +;Based on Third Person Template for UE 5.1 + +[FMallocBinned2] +Free=0x30 +GetAllocSize=0x40 +Malloc=0x10 +Realloc=0x20 +QuantizeSize=0x38 + +[UObject] +ProcessEvent=0x268 + +[UScriptStruct] +GetCustomGuid=0x378 + +[UPackage] +GamePackage=/Script/SandFall + +[UStruct] +Link=0x2d0 \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_52-win64-shipping/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_52-win64-shipping/scans.ini new file mode 100644 index 0000000..bd5e42e --- /dev/null +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_52-win64-shipping/scans.ini @@ -0,0 +1,64 @@ +;Based on Third Person Template for UE 5.2 + +[Scans] +GFNamePool=48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 4C 8B C0 C6 05 ?? ?? ?? ?? 01 8B D3 0F B7 C3 89 44 24 +GFNamePool_RESULT=GetGlobalAddress(result + 3) + +;FNameHelper_FindOrStoreString=48 89 74 24 ?? 57 48 83 EC 60 81 79 ?? 00 04 00 00 +;FNameHelper_FindOrStoreString_RESULT= + +;??0FName@@QEAA@PEB_WW4EFindName@@@Z +FName_Ctor_Wide=48 89 5C 24 ?? 57 48 83 EC 30 48 8B D9 48 89 54 24 ?? 33 C9 +;FName_Ctor_Wide_RESULT= + +;?FromString@FText@@SA?AV1@$$QEAVFString@@@Z +FText_FromString=48 89 6C 24 ?? 57 48 83 EC 50 83 7A ?? 01 48 8B F9 48 89 74 24 ?? C7 44 24 ?? 00 00 00 00 7F ?? E8 ?? ?? ?? ?? 48 8B 48 ?? 48 8B 10 48 89 54 24 ?? 48 89 4C 24 ?? 48 85 C9 74 ?? F0 FF 41 ?? 8B 40 ?? BE 01 00 00 00 89 44 24 ?? 48 8D 44 24 ?? EB ?? 48 8D 4C 24 ?? E8 ?? ?? ?? ?? BE 02 00 00 00 48 8B 10 48 89 17 48 8B 48 ?? 48 89 4F ?? 48 85 C9 74 ?? F0 FF 41 ?? 8B 40 ?? BD FF FF FF FF 89 47 ?? 48 89 5C 24 ?? 40 F6 C6 02 74 ?? 48 8B 5C 24 ?? 83 E6 FD 48 85 DB 74 ?? 8B C5 F0 0F C1 43 ?? 83 F8 01 75 ?? 48 8B 03 48 8B CB FF 10 8B C5 F0 0F C1 43 ?? 83 F8 01 75 ?? 48 8B 03 8D 55 ?? 48 8B CB FF 50 ?? 40 F6 C6 01 48 8B 74 24 ?? 74 ?? 48 8B 4C 24 ?? 48 85 C9 74 ?? 8B C5 F0 0F C1 41 ?? 83 F8 01 75 ?? 48 8B 5C 24 ?? 48 8B CB 48 8B 03 FF 10 F0 0F C1 6B ?? 83 FD 01 75 ?? 48 8B 4C 24 ?? 8B D5 48 8B 01 FF 50 ?? 83 4F ?? 12 +;FText_FromString_RESULT= + +FText_ToString=40 53 48 83 EC 20 48 8B D9 E8 ?? ?? ?? ?? 48 8B 0B 48 8B 01 48 83 C4 20 +;FText_ToString_RESULT= + +UObject_PostLoadSubobjects=E8 ?? ?? ?? ?? 48 8B CB E8 ?? ?? ?? ?? 48 8B 83 ?? ?? ?? ?? 48 85 C0 0F 84 ?? ?? ?? ?? +UObject_PostLoadSubobjects_RESULT=GetGlobalAddress(result + 1) + +UObject_BeginDestroy=40 53 48 83 EC 30 8B 41 ?? 48 8B D9 C1 E8 0F +;UObject_BeginDestroy_RESULT= + +;From UObjectBaseInit +GUObjectArray=89 15 ?? ?? ?? ?? 85 FF +GUObjectArray_RESULT=GetGlobalAddress(result + 2) + +UStruct_IsChildOf=48 85 D2 74 ?? 48 63 42 ?? 4C 8D 42 +;UStruct_IsChildOf_RESULT= + +UEnum_GetDisplayNameTextByIndex=48 89 5C 24 ?? 55 56 57 48 83 EC 30 48 8B FA +;UEnum_GetDisplayNameTextByIndex_RESULT= + +UDataTable_HandleDataTableChanged=48 89 54 24 ?? 55 53 56 48 8D 6C 24 ?? 48 81 EC C0 00 00 00 +;UDataTable_HandleDataTableChanged_RESULT= + +GMalloc=48 8B 0D ?? ?? ?? ?? 48 85 C9 75 ?? E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? 48 8B 01 48 8B D3 FF 50 ?? 48 83 C4 20 +GMalloc_RESULT=GetGlobalAddress(result + 3) + +FTextInspector_GetTableIdAndKey=48 89 5C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 41 56 48 83 EC 30 48 8B F9 48 8D 1D + +GetPrivateStaticClassBody_UE4=DISABLED +;GetPrivateStaticClassBody_RESULT= + +GetPrivateStaticClassBody_UE5=48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 54 41 55 41 56 41 57 48 83 EC 60 45 33 ED +;GetPrivateStaticClassBody_RESULT= + +StaticConstructObject_Internal=4C 8B DC 49 89 5B ?? 49 89 73 ?? 55 57 41 54 41 56 41 57 49 8D AB ?? ?? ?? ?? +;StaticConstructObject_Internal_RESULT= + +GetStaticStruct=48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 50 49 8B E8 48 8B DA FF D1 48 8B F0 90 48 83 7B ?? 00 48 8D 7B ?? 74 ?? 33 C0 F7 43 ?? 00 00 00 10 74 ?? 48 8B CB E8 ?? ?? ?? ?? 48 8B D8 48 85 DB 75 ?? 48 8B 1F EB ?? 48 8B 43 ?? 48 8D 54 24 ?? 48 8D 4C 24 ?? 48 89 44 24 ?? E8 ?? ?? ?? ?? 83 7C 24 ?? 00 48 8D 0D ?? ?? ?? ?? 41 B9 02 00 00 00 48 89 74 24 ?? 48 0F 45 4C 24 ?? 45 8B C1 +;GetStaticStruct_RESULT= + +ConstructUScriptStruct=40 53 56 57 41 55 41 56 41 57 48 81 EC C8 03 00 00 +;ConstructUScriptStruct + +GEngine=48 89 05 ?? ?? ?? ?? 48 85 C9 74 ?? E8 ?? ?? ?? ?? 48 8D 4D ?? +GEngine_RESULT=GetGlobalAddress(result + 3) + +UWorld_SpawnActor=40 55 53 56 57 41 54 41 55 41 56 41 57 48 8D AC 24 ?? ?? ?? ?? 48 81 EC D8 03 00 00 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 85 ?? ?? ?? ?? 33 C0 +;UWorld_SpawnActor_RESULT= \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_52-win64-shipping/unreal.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_52-win64-shipping/unreal.ini new file mode 100644 index 0000000..13d35c1 --- /dev/null +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_52-win64-shipping/unreal.ini @@ -0,0 +1,20 @@ +;Based on Third Person Template for UE 5.2 + +[FMallocBinned2] +Free=0x40 +GetAllocSize=0x50 +Malloc=0x20 +Realloc=0x30 +QuantizeSize=0x48 + +[UObject] +ProcessEvent=0x268 + +[UScriptStruct] +GetCustomGuid=0x378 + +[UPackage] +GamePackage=/Script/SandFall + +[UStruct] +Link=0x2d0 \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_53-win64-shipping/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_53-win64-shipping/scans.ini new file mode 100644 index 0000000..85a86b9 --- /dev/null +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_53-win64-shipping/scans.ini @@ -0,0 +1,64 @@ +;Based on Third Person Template for UE 5.3 + +[Scans] +GFNamePool=48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 4C 8B C0 C6 05 ?? ?? ?? ?? 01 8B D3 0F B7 C3 89 44 24 +GFNamePool_RESULT=GetGlobalAddress(result + 3) + +;FNameHelper_FindOrStoreString=48 89 74 24 ?? 57 48 83 EC 60 81 79 ?? 00 04 00 00 +;FNameHelper_FindOrStoreString_RESULT= + +;??0FName@@QEAA@PEB_WW4EFindName@@@Z +FName_Ctor_Wide=48 89 5C 24 ?? 57 48 83 EC 30 48 8B D9 48 89 54 24 ?? 33 C9 +;FName_Ctor_Wide_RESULT= + +;?FromString@FText@@SA?AV1@$$QEAVFString@@@Z +FText_FromString=48 89 6C 24 ?? 57 48 83 EC 50 83 7A ?? 01 48 8B F9 48 89 74 24 ?? C7 44 24 ?? 00 00 00 00 7F ?? E8 ?? ?? ?? ?? 48 8B 48 ?? 48 8B 10 48 89 54 24 ?? 48 89 4C 24 ?? 48 85 C9 74 ?? F0 FF 41 ?? 8B 40 ?? BE 01 00 00 00 89 44 24 ?? 48 8D 44 24 ?? EB ?? 48 8D 4C 24 ?? E8 ?? ?? ?? ?? BE 02 00 00 00 48 8B 10 48 89 17 48 8B 48 ?? 48 89 4F ?? 48 85 C9 74 ?? F0 FF 41 ?? 8B 40 ?? BD FF FF FF FF 89 47 ?? 48 89 5C 24 ?? 40 F6 C6 02 74 ?? 48 8B 5C 24 ?? 83 E6 FD 48 85 DB 74 ?? 8B C5 F0 0F C1 43 ?? 83 F8 01 75 ?? 48 8B 03 48 8B CB FF 10 8B C5 F0 0F C1 43 ?? 83 F8 01 75 ?? 48 8B 03 8D 55 ?? 48 8B CB FF 50 ?? 40 F6 C6 01 48 8B 74 24 ?? 74 ?? 48 8B 4C 24 ?? 48 85 C9 74 ?? 8B C5 F0 0F C1 41 ?? 83 F8 01 75 ?? 48 8B 5C 24 ?? 48 8B CB 48 8B 03 FF 10 F0 0F C1 6B ?? 83 FD 01 75 ?? 48 8B 4C 24 ?? 8B D5 48 8B 01 FF 50 ?? 83 4F ?? 12 +;FText_FromString_RESULT= + +FText_ToString=40 53 48 83 EC 20 48 8B D9 E8 ?? ?? ?? ?? 48 8B 0B 48 8B 01 48 83 C4 20 +;FText_ToString_RESULT= + +UObject_PostLoadSubobjects=E8 ?? ?? ?? ?? 48 8B CF E8 ?? ?? ?? ?? 48 8B 87 ?? ?? ?? ?? 48 85 C0 74 ?? 48 8B 80 ?? ?? ?? ?? +UObject_PostLoadSubobjects_RESULT=GetGlobalAddress(result + 1) + +UObject_BeginDestroy=40 53 48 83 EC 40 8B 41 ?? 48 8B D9 C1 E8 0F +;UObject_BeginDestroy_RESULT= + +;From UObjectBaseInit +GUObjectArray=89 15 ?? ?? ?? ?? 85 FF +GUObjectArray_RESULT=GetGlobalAddress(result + 2) + +UStruct_IsChildOf=48 85 D2 74 ?? 48 63 42 ?? 4C 8D 42 +;UStruct_IsChildOf_RESULT= + +UEnum_GetDisplayNameTextByIndex=48 89 5C 24 ?? 55 56 57 48 83 EC 30 48 8B FA +;UEnum_GetDisplayNameTextByIndex_RESULT= + +UDataTable_HandleDataTableChanged=40 55 53 57 48 8D 6C 24 ?? 48 81 EC C0 00 00 00 8B 41 +;UDataTable_HandleDataTableChanged_RESULT= + +GMalloc=48 8B 0D ?? ?? ?? ?? 48 85 C9 75 ?? E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? 48 8B 01 48 8B D3 FF 50 ?? 48 83 C4 20 +GMalloc_RESULT=GetGlobalAddress(result + 3) + +FTextInspector_GetTableIdAndKey=48 89 5C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 41 56 48 83 EC 30 48 8B F9 48 8D 1D + +GetPrivateStaticClassBody_UE4=DISABLED +;GetPrivateStaticClassBody_RESULT= + +GetPrivateStaticClassBody_UE5=48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 54 41 55 41 56 41 57 48 83 EC 60 45 33 ED +;GetPrivateStaticClassBody_RESULT= + +StaticConstructObject_Internal=4C 8B DC 49 89 5B ?? 49 89 73 ?? 55 57 41 54 41 56 41 57 49 8D AB ?? ?? ?? ?? +;StaticConstructObject_Internal_RESULT= + +GetStaticStruct=48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 50 49 8B F8 48 8B DA FF D1 48 8B CB 48 8B F0 E8 ?? ?? ?? ?? 48 8D 54 24 ?? 48 8B 48 ?? 48 89 4C 24 ?? 48 8D 4C 24 ?? E8 ?? ?? ?? ?? 83 7C 24 ?? 00 48 8D 0D ?? ?? ?? ?? 41 B9 02 00 00 00 48 89 74 24 ?? 48 0F 45 4C 24 ?? 45 8B C1 +;GetStaticStruct_RESULT= + +ConstructUScriptStruct=40 53 56 57 41 55 41 56 41 57 48 81 EC A8 03 00 00 +;ConstructUScriptStruct + +GEngine=48 89 05 ?? ?? ?? ?? 48 85 C9 74 ?? E8 ?? ?? ?? ?? 48 8D 4D ?? +GEngine_RESULT=GetGlobalAddress(result + 3) + +UWorld_SpawnActor=40 55 53 56 57 41 54 41 55 41 56 41 57 48 8D AC 24 ?? ?? ?? ?? 48 81 EC A8 04 00 00 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 85 ?? ?? ?? ?? 33 C0 +;UWorld_SpawnActor_RESULT= \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_53-win64-shipping/unreal.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_53-win64-shipping/unreal.ini new file mode 100644 index 0000000..ccff884 --- /dev/null +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_53-win64-shipping/unreal.ini @@ -0,0 +1,20 @@ +;Based on Third Person Template for UE 5.3 + +[FMallocBinned2] +Free=0x48 +GetAllocSize=0x58 +Malloc=0x28 +Realloc=0x38 +QuantizeSize=0x50 + +[UObject] +ProcessEvent=0x268 + +[UScriptStruct] +GetCustomGuid=0x378 + +[UPackage] +GamePackage=/Script/SandFall + +[UStruct] +Link=0x2d0 \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_55-win64-shipping/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_55-win64-shipping/scans.ini new file mode 100644 index 0000000..cde343e --- /dev/null +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_55-win64-shipping/scans.ini @@ -0,0 +1,65 @@ +;Based on Third Person Template for UE 5.5 + +[Scans] +GFNamePool=48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 4C 8B C0 C6 05 ?? ?? ?? ?? 01 8B D3 0F B7 C3 89 44 24 +GFNamePool_RESULT=GetGlobalAddress(result + 3) + +;FNameHelper_FindOrStoreString=48 89 74 24 ?? 57 48 83 EC 60 81 79 ?? 00 04 00 00 +;FNameHelper_FindOrStoreString_RESULT= + +;??0FName@@QEAA@PEB_WW4EFindName@@@Z +FName_Ctor_Wide=48 89 5C 24 ?? 57 48 83 EC 30 48 8B D9 41 8B F8 +;FName_Ctor_Wide_RESULT= + +;LaunchFixGameNameCase +FText_FromString=E8 ?? ?? ?? ?? 83 7C 24 ?? 00 48 8D 4C 24 ?? 48 8B D7 4C 8B E0 +FText_FromString_RESULT=GetGlobalAddress(result + 1) + +FText_ToString=40 53 48 83 EC 20 48 8B D9 E8 ?? ?? ?? ?? 48 8B 0B 48 8B 01 48 83 C4 20 +;FText_ToString_RESULT= + +UObject_PostLoadSubobjects=40 55 56 41 56 48 8D AC 24 ?? ?? ?? ?? 48 81 EC 10 02 00 00 +;UObject_PostLoadSubobjects_RESULT= + +UObject_BeginDestroy=40 53 48 83 EC 30 8B 41 ?? 48 8B D9 C1 E8 0F +;UObject_BeginDestroy_RESULT= + +;From UObjectBaseInit +GUObjectArray=89 0D ?? ?? ?? ?? 85 FF 7F ?? +GUObjectArray_RESULT=GetGlobalAddress(result + 2) + +UStruct_IsChildOf=48 85 D2 74 ?? 48 63 42 ?? 4C 8D 42 +;UStruct_IsChildOf_RESULT= + +UEnum_GetDisplayNameTextByIndex=48 89 5C 24 ?? 55 56 57 48 83 EC 30 48 8B FA +;UEnum_GetDisplayNameTextByIndex_RESULT= + +UDataTable_HandleDataTableChanged=40 55 53 57 48 8D 6C 24 ?? 48 81 EC C0 00 00 00 8B 41 +;UDataTable_HandleDataTableChanged_RESULT= + +GMalloc=48 8B 0D ?? ?? ?? ?? 48 85 C9 75 ?? E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? 48 8B 01 48 8B D3 FF 50 ?? 48 83 C4 20 +GMalloc_RESULT=GetGlobalAddress(result + 3) + +FTextInspector_GetTableIdAndKey=48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 7C 24 ?? 41 56 48 83 EC 20 48 8B D9 + +GetPrivateStaticClassBody_UE4=DISABLED +;GetPrivateStaticClassBody_RESULT= + +GetPrivateStaticClassBody_UE5=48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 56 41 57 48 83 EC 30 4D 8B F1 49 8B F8 +;GetPrivateStaticClassBody_RESULT= + +StaticConstructObject_Internal=4C 8B DC 49 89 5B ?? 49 89 73 ?? 55 57 41 54 41 56 41 57 49 8D AB ?? ?? ?? ?? +;StaticConstructObject_Internal_RESULT= + +GetStaticStruct=48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 50 49 8B E8 48 8B DA FF D1 48 8B F0 90 48 83 7B ?? 00 48 8D 7B ?? 74 ?? 8B 43 ?? 33 C9 0F BA E0 1C 73 ?? 48 8B CB E8 ?? ?? ?? ?? 48 8B C8 48 8B D9 48 85 DB 75 ?? 48 8B 1F EB ?? 48 8B 43 ?? 48 8D 54 24 ?? 48 8D 4C 24 ?? 48 89 44 24 ?? E8 ?? ?? ?? ?? 83 7C 24 ?? 00 48 8D 0D ?? ?? ?? ?? 41 B9 02 00 00 00 48 89 74 24 ?? 48 0F 45 4C 24 ?? 45 8B C1 +;GetStaticStruct_RESULT= + +ConstructUScriptStruct=40 53 56 57 41 54 41 55 41 56 48 81 EC A8 03 00 00 +;ConstructUScriptStruct + +;FEngineLoop::Init +GEngine=48 89 05 ?? ?? ?? ?? 48 85 C9 74 ?? E8 ?? ?? ?? ?? 48 8D 4D ?? +GEngine_RESULT=GetGlobalAddress(result + 3) + +UWorld_SpawnActor=40 55 53 56 57 41 54 41 55 41 56 41 57 48 8D AC 24 ?? ?? ?? ?? 48 81 EC A8 04 00 00 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 85 ?? ?? ?? ?? 33 C0 +;UWorld_SpawnActor_RESULT= \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_55-win64-shipping/unreal.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_55-win64-shipping/unreal.ini new file mode 100644 index 0000000..3e002b0 --- /dev/null +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_55-win64-shipping/unreal.ini @@ -0,0 +1,20 @@ +;Based on Third Person Template for UE 5.5 + +[FMallocBinned2] +Free=0x48 +GetAllocSize=0x68 +Malloc=0x28 +Realloc=0x38 +QuantizeSize=0x60 + +[UObject] +ProcessEvent=0x268 + +[UScriptStruct] +GetCustomGuid=0x378 + +[UPackage] +GamePackage=/Script/SandFall + +[UStruct] +Link=0x2e0 \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_56-win64-shipping/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_56-win64-shipping/scans.ini new file mode 100644 index 0000000..8aae039 --- /dev/null +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_56-win64-shipping/scans.ini @@ -0,0 +1,67 @@ +;Based on Third Person Template for UE 5.6 + +[Scans] +;DebugDumpInternal +GFNamePool=48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? C6 05 ?? ?? ?? ?? 01 48 8D 54 24 ?? +GFNamePool_RESULT=GetGlobalAddress(result + 3) + +;FNameHelper_FindOrStoreString=48 89 74 24 ?? 57 48 83 EC 60 81 79 ?? 00 04 00 00 +;FNameHelper_FindOrStoreString_RESULT= + +;??0FName@@QEAA@PEB_WW4EFindName@@@Z +FName_Ctor_Wide=48 89 5C 24 ?? 57 48 83 EC 30 48 8B D9 41 8B F8 +;FName_Ctor_Wide_RESULT= + +;LaunchFixGameNameCase +FText_FromString=E8 ?? ?? ?? ?? 83 7C 24 ?? 00 48 8D 4D ?? 49 8B D6 +FText_FromString_RESULT=GetGlobalAddress(result + 1) + +FText_ToString=40 53 48 83 EC 20 48 8B D9 E8 ?? ?? ?? ?? 48 8B 0B 48 8B 01 48 83 C4 20 +;FText_ToString_RESULT= + +UObject_PostLoadSubobjects=40 55 53 41 56 48 8D AC 24 ?? ?? ?? ?? 48 81 EC 10 02 00 00 +;UObject_PostLoadSubobjects_RESULT= + +UObject_BeginDestroy=40 53 48 83 EC 30 8B 41 ?? 48 8B D9 C1 E8 0F +;UObject_BeginDestroy_RESULT= + +;From UObjectBaseInit +GUObjectArray=89 0D ?? ?? ?? ?? 85 FF 7F ?? +GUObjectArray_RESULT=GetGlobalAddress(result + 2) + +UStruct_IsChildOf=48 85 D2 74 ?? 48 63 42 ?? 4C 8D 42 +;UStruct_IsChildOf_RESULT= + +UEnum_GetDisplayNameTextByIndex=48 89 5C 24 ?? 55 56 57 48 83 EC 30 48 8B FA +;UEnum_GetDisplayNameTextByIndex_RESULT= + +UDataTable_HandleDataTableChanged=48 89 54 24 ?? 55 53 56 48 8D 6C 24 ?? 48 81 EC C0 00 00 00 +;UDataTable_HandleDataTableChanged_RESULT= + +GMalloc=48 8B 0D ?? ?? ?? ?? 48 85 C9 75 ?? E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? 48 8B 01 48 8B D3 FF 50 ?? 48 83 C4 20 +GMalloc_RESULT=GetGlobalAddress(result + 3) + +FTextInspector_GetTableIdAndKey=48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 7C 24 ?? 41 56 48 83 EC 20 48 8B D9 + +GetPrivateStaticClassBody_UE4=DISABLED +;GetPrivateStaticClassBody_RESULT= + +GetPrivateStaticClassBody_UE5=48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 56 41 57 48 83 EC 30 49 8B E9 49 8B D8 +;GetPrivateStaticClassBody_RESULT= + +StaticConstructObject_Internal=4C 8B DC 49 89 5B ?? 49 89 73 ?? 55 57 41 54 41 56 41 57 49 8D AB ?? ?? ?? ?? +;StaticConstructObject_Internal_RESULT= + +GetStaticStruct=48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 50 49 8B E8 48 8B DA FF D1 48 8B F0 90 48 83 7B ?? 00 48 8D 7B ?? 74 ?? 8B 43 ?? 33 C9 0F BA E0 1C 73 ?? 48 8B CB E8 ?? ?? ?? ?? 48 8B C8 48 8B D9 48 85 DB 75 ?? 48 8B 1F EB ?? 48 8B 43 ?? 48 8D 54 24 ?? 48 8D 4C 24 ?? 48 89 44 24 ?? E8 ?? ?? ?? ?? 83 7C 24 ?? 00 48 8D 0D ?? ?? ?? ?? 41 B9 02 00 00 00 48 89 74 24 ?? 48 0F 45 4C 24 ?? 45 8B C1 +;GetStaticStruct_RESULT= + +ConstructUScriptStruct=40 53 56 57 41 54 41 55 41 56 48 81 EC B8 03 00 00 +;ConstructUScriptStruct + +;FEngineLoop::Init +GEngine=48 89 05 ?? ?? ?? ?? 48 85 C9 74 ?? E8 ?? ?? ?? ?? 48 8D 4C 24 ?? +GEngine_RESULT=GetGlobalAddress(result + 3) + +;ConvertInstanceToActor +UWorld_SpawnActor=E8 ?? ?? ?? ?? 48 8D 15 ?? ?? ?? ?? 48 8B F8 48 8D 0D ?? ?? ?? ?? +UWorld_SpawnActor_RESULT=GetGlobalAddress(result + 1) \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_56-win64-shipping/unreal.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_56-win64-shipping/unreal.ini new file mode 100644 index 0000000..9730976 --- /dev/null +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_56-win64-shipping/unreal.ini @@ -0,0 +1,20 @@ +;Based on Third Person Template for UE 5.6 + +[FMallocBinned2] +Free=0x48 +GetAllocSize=0x68 +Malloc=0x28 +Realloc=0x38 +QuantizeSize=0x60 + +[UObject] +ProcessEvent=0x268 + +[UScriptStruct] +GetCustomGuid=0x378 + +[UPackage] +GamePackage=/Script/SandFall + +[UStruct] +Link=0x2c8 \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_57-win64-shipping/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_57-win64-shipping/scans.ini new file mode 100644 index 0000000..aa82aa5 --- /dev/null +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_57-win64-shipping/scans.ini @@ -0,0 +1,68 @@ +;Based on Third Person Template for UE 5.7 + +[Scans] +;DebugDumpInternal +GFNamePool=48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? C6 05 ?? ?? ?? ?? 01 48 8D 54 24 ?? +GFNamePool_RESULT=GetGlobalAddress(result + 3) + +;FNameHelper_FindOrStoreString=48 89 74 24 ?? 57 48 83 EC 60 81 79 ?? 00 04 00 00 +;FNameHelper_FindOrStoreString_RESULT= + +;??0FName@@QEAA@PEB_WW4EFindName@@@Z +FName_Ctor_Wide=48 89 5C 24 ?? 57 48 83 EC 30 48 8B D9 48 89 54 24 ?? 33 C9 +;FName_Ctor_Wide_RESULT= + +;LaunchFixGameNameCase +FText_FromString=E8 ?? ?? ?? ?? 83 7C 24 ?? 00 48 8D 4D ?? 48 8B D3 4C 8B F0 +FText_FromString_RESULT=GetGlobalAddress(result + 1) + +FText_ToString=40 53 48 83 EC 20 48 8B D9 E8 ?? ?? ?? ?? 48 8B 0B 48 8B 01 48 83 C4 20 +;FText_ToString_RESULT= + +UObject_PostLoadSubobjects=40 55 53 41 56 48 8D AC 24 ?? ?? ?? ?? 48 81 EC B0 02 00 00 +;UObject_PostLoadSubobjects_RESULT= + +UObject_BeginDestroy=40 53 48 83 EC 40 8B 41 ?? 48 8B D9 0F BA E0 0F +;UObject_BeginDestroy_RESULT= + +;From UObjectBaseInit +GUObjectArray=89 0D ?? ?? ?? ?? 85 FF 7F ?? +GUObjectArray_RESULT=GetGlobalAddress(result + 2) + +;Inlined +UStruct_IsChildOf=DISABLED +;UStruct_IsChildOf_RESULT= + +UEnum_GetDisplayNameTextByIndex=48 89 5C 24 ?? 55 56 57 48 83 EC 30 48 8B FA +;UEnum_GetDisplayNameTextByIndex_RESULT= + +UDataTable_HandleDataTableChanged=40 55 53 56 48 8D 6C 24 ?? 48 81 EC 90 00 00 00 8B 41 ?? +;UDataTable_HandleDataTableChanged_RESULT= + +GMalloc=48 8B 0D ?? ?? ?? ?? 48 85 C9 75 ?? E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? 48 8B 01 48 8B D3 FF 50 ?? 48 83 C4 20 +GMalloc_RESULT=GetGlobalAddress(result + 3) + +FTextInspector_GetTableIdAndKey=48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 7C 24 ?? 41 56 48 83 EC 20 48 8B D9 + +GetPrivateStaticClassBody_UE4=DISABLED +;GetPrivateStaticClassBody_RESULT= + +GetPrivateStaticClassBody_UE5=48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 56 41 57 48 83 EC 30 49 8B E9 49 8B D8 +;GetPrivateStaticClassBody_RESULT= + +StaticConstructObject_Internal=4C 8B DC 55 53 41 56 49 8D AB ?? ?? ?? ?? 48 81 EC B0 02 00 00 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 85 ?? ?? ?? ?? 8B 41 ?? +;StaticConstructObject_Internal_RESULT= + +GetStaticStruct=48 89 5C 24 ?? 55 56 57 48 83 EC 50 49 8B D8 48 8B FA FF D1 48 8B D3 48 8D 4C 24 ?? 48 8B E8 E8 ?? ?? ?? ?? 48 8B 18 66 0F 1F 84 ?? 00 00 00 00 48 83 7F ?? 00 48 8D 77 ?? 74 ?? 8B 47 ?? 33 C9 0F BA E0 1C 73 ?? 48 8B CF E8 ?? ?? ?? ?? 48 8B C8 48 8B F9 48 85 FF 75 ?? 48 8B 3E EB ?? 48 8B 47 ?? 48 8D 54 24 ?? 48 8D 4C 24 ?? 48 89 44 24 ?? E8 ?? ?? ?? ?? 83 7C 24 ?? 00 48 8D 15 ?? ?? ?? ?? 48 8D 8C 24 ?? ?? ?? ?? 48 0F 45 54 24 ?? E8 ?? ?? ?? ?? 41 B9 02 00 00 00 +;GetStaticStruct_RESULT= + +ConstructUScriptStruct=40 53 56 57 41 54 41 55 41 56 48 81 EC B8 03 00 00 +;ConstructUScriptStruct + +;FEngineLoop::Init +GEngine=48 89 05 ?? ?? ?? ?? 48 85 C9 74 ?? E8 ?? ?? ?? ?? 48 8D 4C 24 ?? +GEngine_RESULT=GetGlobalAddress(result + 3) + +;ConvertInstanceToActor +UWorld_SpawnActor=E8 ?? ?? ?? ?? 48 8D 15 ?? ?? ?? ?? 48 8B F8 48 8D 0D ?? ?? ?? ?? +UWorld_SpawnActor_RESULT=GetGlobalAddress(result + 1) \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_57-win64-shipping/unreal.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_57-win64-shipping/unreal.ini new file mode 100644 index 0000000..623c523 --- /dev/null +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_57-win64-shipping/unreal.ini @@ -0,0 +1,20 @@ +;Based on Third Person Template for UE 5.7 + +[FMallocBinned2] +Free=0x48 +GetAllocSize=0x68 +Malloc=0x28 +Realloc=0x38 +QuantizeSize=0x60 + +[UObject] +ProcessEvent=0x268 + +[UScriptStruct] +GetCustomGuid=0x378 + +[UPackage] +GamePackage=/Script/SandFall + +[UStruct] +Link=0x2c8 \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/p3r/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/p3r/scans.ini index 747dacc..30494ee 100644 --- a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/p3r/scans.ini +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/p3r/scans.ini @@ -17,6 +17,9 @@ FText_ToString=40 53 48 83 EC 20 48 8B D9 E8 ?? ?? ?? ?? 48 8B 0B 48 8B 01 UObject_PostLoadSubobjects=40 53 48 83 EC 20 48 8B 41 ?? 48 8B D9 8B 90 ?? ?? ?? ?? C1 EA 17 ;UObject_PostLoadSubobjects_RESULT= +UObject_BeginDestroy=40 53 48 83 EC 30 8B 41 ?? 48 8B D9 C1 E8 0F +;UObject_BeginDestroy_RESULT= + GUObjectArray=48 8B 05 ?? ?? ?? ?? 48 8B 0C ?? 48 8D 04 ?? 48 85 C0 74 ?? 44 39 40 ?? 75 ?? F7 40 ?? 00 00 00 30 75 ?? 48 8B 00 GUObjectArray_RESULT=GetGlobalAddress(result + 3) - 0x10 @@ -33,7 +36,6 @@ UDataTable_HandleDataTableChanged=48 89 54 24 ?? 55 53 56 57 48 8D 6C 24 ?? 48 8 ;GMalloc= ;GMalloc_RESULT= - GetPrivateStaticClassBody_UE4=48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 54 41 55 41 56 41 57 48 83 EC 60 45 33 ED ;GetPrivateStaticClassBody_RESULT= diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/scans.ini index 2a10aca..6c56137 100644 --- a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/scans.ini +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/scans.ini @@ -19,6 +19,9 @@ FText_ToString=40 53 48 83 EC 20 48 8B D9 E8 ?? ?? ?? ?? 48 8B 0B 48 8B 01 48 83 UObject_PostLoadSubobjects=40 55 53 41 56 48 8D AC 24 ?? ?? ?? ?? 48 81 EC 10 02 00 00 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 85 ?? ?? ?? ?? 48 8B 41 ;UObject_PostLoadSubobjects_RESULT= +UObject_BeginDestroy=40 53 48 83 EC 30 8B 41 ?? 48 8B D9 C1 E8 0F +;UObject_BeginDestroy_RESULT= + GUObjectArray=2B 05 ?? ?? ?? ?? 44 89 05 GUObjectArray_RESULT=GetGlobalAddress(result + 2) diff --git a/UE.Toolkit.Reloaded/Unreal/UnrealObjects.cs b/UE.Toolkit.Reloaded/Unreal/UnrealObjects.cs index 7421214..782925b 100644 --- a/UE.Toolkit.Reloaded/Unreal/UnrealObjects.cs +++ b/UE.Toolkit.Reloaded/Unreal/UnrealObjects.cs @@ -24,7 +24,9 @@ public unsafe class UnrealObjects : IUnrealObjects private readonly SHFunction _FText_ToString = new(); private static IHook? _UObject_PostLoadSubobjects; + private static IHook? _UObject_BeginDestroy; private static Action? _onObjectLoaded; + private static Action? _onObjectDestroy; internal ConcurrentDictionary> OnCDOLoaded = new(); @@ -38,6 +40,16 @@ private static void UObject_PostLoadSubobjects(nint self, nint outerInstanceGrap _onObjectLoaded?.Invoke(self); } + [UnmanagedCallersOnly(CallConvs = [typeof(CallConvStdcall)])] + private static void UObject_BeginDestroy(nint self) + { + if (Mod.Config.LogObjectsEnabled) + Log.Information($"{nameof(UObject_BeginDestroy)} || {ToolkitUtils.GetPrivateName(self)} || {ToolkitUtils.GetPrivateName((nint)((UObjectBase*)self)->ClassPrivate)}"); + + _UObject_BeginDestroy!.OriginalFunction.Value.Invoke(self); + _onObjectDestroy?.Invoke(self); + } + private IUnrealFactory Factory; public UnrealObjects(IUnrealFactory factory) @@ -47,6 +59,9 @@ public UnrealObjects(IUnrealFactory factory) Project.Scans.AddScanHook(nameof(UObject_PostLoadSubobjects), (result, hooks) => _UObject_PostLoadSubobjects = hooks.CreateHook((delegate* unmanaged[Stdcall])&UObject_PostLoadSubobjects, result).Activate()); + Project.Scans.AddScanHook(nameof(UObject_BeginDestroy), + (result, hooks) => _UObject_BeginDestroy = hooks.CreateHook((delegate* unmanaged[Stdcall])&UObject_BeginDestroy, result).Activate()); + Project.Scans.AddScan(nameof(GUObjectArray), result => GUObjectArray = factory.CreateUObjectArray(result)); @@ -54,9 +69,12 @@ public UnrealObjects(IUnrealFactory factory) (result, hooks) => UStruct.UStruct_IsChildOf = hooks.CreateWrapper(result, out _)); _onObjectLoaded += objPtr => OnObjectLoaded?.Invoke(new((UObjectBase*)objPtr)); + _onObjectDestroy += objPtr => OnObjectBeginDestroy?.Invoke(new((UObjectBase*)objPtr)); } public Action>? OnObjectLoaded { get; set; } + + public Action>? OnObjectBeginDestroy { get; set; } public IUObjectArray GUObjectArray { get; private set; } = null!; @@ -107,4 +125,9 @@ private struct PostLoadSubobjectsFunction { public FuncPtr Value; } + + private struct BeginDestroyFunction + { + public FuncPtr Value; + } } \ No newline at end of file From 738e38b1eb281abc16b2562135bdd138b13eccca Mon Sep 17 00:00:00 2001 From: Rirurin Date: Tue, 30 Jun 2026 00:08:47 +0800 Subject: [PATCH 2/7] Add object dumper support for UE 5.0 - 5.7 --- README.md | 2 +- .../Unreal/Factories/UE5_2_1/UnrealFactory.cs | 314 ++++++++---------- .../Unreal/Factories/UE5_4_4/UnrealFactory.cs | 26 -- .../Unreal/Factories/UE5_6_1/UnrealFactory.cs | 299 ++++++++--------- .../Unreal/Factories/UE5_7_4/UnrealFactory.cs | 291 ++++++++-------- .../Types/Unreal/UE5_4_4/FUObjectArray.cs | 70 ++++ .../Types/Unreal/UE5_6_1/UScriptStruct.cs | 13 + .../Types/Unreal/UE5_6_1/UStruct.cs | 21 ++ .../Types/Unreal/UE5_7_4/FFieldClass.cs | 23 ++ UE.Toolkit.Core/Types/Unreal/UE5_7_4/UEnum.cs | 41 +++ UE.Toolkit.DumperMod/Dumper.cs | 14 +- UE.Toolkit.DumperMod/ModConfig.json | 2 +- .../Common/GameConfigs/GameConfig.cs | 10 +- .../Common/GameConfigs/Games/UE5_2_1.cs | 13 + .../Common/GameConfigs/Games/UE5_3_2.cs | 14 + .../Common/GameConfigs/Games/UE5_6_1.cs | 13 + .../Common/GameConfigs/Games/UE5_7_4.cs | 13 + .../SMT5V-Win64-Shipping/scans.ini | 4 +- .../chronos-win64-shipping/scans.ini | 64 ++++ .../chronos-win64-shipping/unreal.ini | 20 ++ .../iostoretest_50-win64-shipping/scans.ini | 4 +- .../iostoretest_51-win64-shipping/scans.ini | 4 +- .../iostoretest_52-win64-shipping/scans.ini | 4 +- .../iostoretest_53-win64-shipping/scans.ini | 4 +- .../iostoretest_55-win64-shipping/scans.ini | 4 +- .../iostoretest_56-win64-shipping/scans.ini | 4 +- .../iostoretest_57-win64-shipping/scans.ini | 4 +- .../Project/UE.Toolkit.Reloaded/p3r/scans.ini | 4 +- .../Project/UE.Toolkit.Reloaded/scans.ini | 4 +- UE.Toolkit.Reloaded/Unreal/UnrealStrings.cs | 7 +- 30 files changed, 777 insertions(+), 533 deletions(-) create mode 100644 UE.Toolkit.Core/Types/Unreal/UE5_6_1/UScriptStruct.cs create mode 100644 UE.Toolkit.Core/Types/Unreal/UE5_6_1/UStruct.cs create mode 100644 UE.Toolkit.Core/Types/Unreal/UE5_7_4/FFieldClass.cs create mode 100644 UE.Toolkit.Core/Types/Unreal/UE5_7_4/UEnum.cs create mode 100644 UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_2_1.cs create mode 100644 UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_3_2.cs create mode 100644 UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_6_1.cs create mode 100644 UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_7_4.cs create mode 100644 UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/chronos-win64-shipping/scans.ini create mode 100644 UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/chronos-win64-shipping/unreal.ini diff --git a/README.md b/README.md index 09b9673..9a90e2c 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Object XML requires game-specific support with an extension mod. Supported games | Object Logging |✅|✅|✅|✅|✅|✅|✅|✅|✅ | Object Editing |✅|❔|❔|❔|❔|✅|❔|❔|❔ | `FMemory` Functions |✅|✅|✅|✅|✅|✅|✅|✅|✅ -| Dumper |✅|❔|❔|❔|❔|✅|❔|❔|❔ +| Dumper |✅|✅|✅|✅|️️️️️️✅|✅|✅|✅️|️️️️✅️ | Property Editing (Object XML) |✅|❔|❔|❔|❔|✅|❔|❔|❔ | Add List Entry (Object XML) |✅|❔|❔|❔|❔|❔|❔|❔|❔ | Add Map Entry (Object XML) |✅|❔|❔|❔|❔|❔|❔|❔|❔ diff --git a/UE.Toolkit.Core/Types/Unreal/Factories/UE5_2_1/UnrealFactory.cs b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_2_1/UnrealFactory.cs index be83540..665d39a 100644 --- a/UE.Toolkit.Core/Types/Unreal/Factories/UE5_2_1/UnrealFactory.cs +++ b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_2_1/UnrealFactory.cs @@ -1,176 +1,156 @@ using UE.Toolkit.Core.Types.Unreal.Factories.Interfaces; +using UE.Toolkit.Core.Types.Unreal.Factories.UE5_4_4; +using UE.Toolkit.Core.Types.Unreal.UE5_4_4; + +using FProperty = UE.Toolkit.Core.Types.Unreal.UE4_27_2.FProperty; +using FByteProperty = UE.Toolkit.Core.Types.Unreal.UE4_27_2.FByteProperty; +using FBoolProperty = UE.Toolkit.Core.Types.Unreal.UE4_27_2.FBoolProperty; +using FEnumProperty = UE.Toolkit.Core.Types.Unreal.UE4_27_2.FEnumProperty; +using FObjectProperty = UE.Toolkit.Core.Types.Unreal.UE4_27_2.FObjectProperty; +using FClassProperty = UE.Toolkit.Core.Types.Unreal.UE4_27_2.FClassProperty; +using FStructProperty = UE.Toolkit.Core.Types.Unreal.UE4_27_2.FStructProperty; + +using FMapProperty = UE.Toolkit.Core.Types.Unreal.UE4_27_2.FMapProperty; +// using FInterfaceProperty = UE.Toolkit.Core.Types.Unreal.UE4_27_2.FInterfaceProperty; +using FArrayProperty = UE.Toolkit.Core.Types.Unreal.UE4_27_2.FArrayProperty; +using FSetProperty = UE.Toolkit.Core.Types.Unreal.UE4_27_2.FSetProperty; +// using FOptionalProperty = UE.Toolkit.Core.Types.Unreal.UE4_27_2.FOptionalProperty; +using FDelegateProperty = UE.Toolkit.Core.Types.Unreal.UE4_27_2.FDelegateProperty; namespace UE.Toolkit.Core.Types.Unreal.Factories.UE5_2_1; public class UnrealFactory : BaseUnrealFactory { - public override IntPtr SizeOf() - { - throw new NotImplementedException(); - } - - public override IFProperty CreateFProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFBoolProperty CreateFBoolProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFByteProperty CreateFByteProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFEnumProperty CreateFEnumProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFObjectProperty CreateFObjectProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFSoftClassProperty CreateFSoftClassProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFClassProperty CreateFClassProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFStructProperty CreateFStructProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFMapProperty CreateFMapProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFInterfaceProperty CreateFInterfaceProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFArrayProperty CreateFArrayProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFSetProperty CreateFSetProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFOptionalProperty CreateFOptionalProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFDelegateProperty CreateFDelegateProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IUObjectArray CreateUObjectArray(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IUObject CreateUObject(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IUClass CreateUClass(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IUScriptStruct CreateUScriptStruct(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IUEnum CreateUEnum(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IUField CreateUField(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IUStruct CreateUStruct(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IUUserDefinedEnum CreateUUserDefinedEnum(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IUFunction CreateUFunction(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFFieldClass CreateFFieldClass(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFField CreateFField(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFStructParams CreateFStructParams(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFPropertyParams CreateFPropertyParams(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFGenericPropertyParams CreateFGenericPropertyParams(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFWorldContext CreateFWorldContext(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IUEngine CreateUEngine(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IUGameInstance CreateUGameInstance(IntPtr ptr) - { - throw new NotImplementedException(); - } - + + public override nint SizeOf() + { + var TypeName = typeof(T).Name; + unsafe + { + return TypeName switch + { + nameof(IUObject) => sizeof(UObjectBase), + nameof(IUClass) => sizeof(UClass), + nameof(IUScriptStruct) => sizeof(UScriptStruct), + nameof(IUEnum) => sizeof(UEnum), + nameof(IUUserDefinedEnum) => sizeof(UUserDefinedEnum), + nameof(IFProperty) => sizeof(FProperty), + nameof(IFByteProperty) => sizeof(FByteProperty), + nameof(IFBoolProperty) => sizeof(FBoolProperty), + nameof(IFEnumProperty) => sizeof(FEnumProperty), + nameof(IFObjectProperty) => sizeof(FObjectProperty), + nameof(IFSoftClassProperty) => sizeof(FSoftClassProperty), + nameof(IFClassProperty) => sizeof(FClassProperty), + nameof(IFStructProperty) => sizeof(FStructProperty), + nameof(IFMapProperty) => sizeof(FMapProperty), + nameof(IFInterfaceProperty) => sizeof(FInterfaceProperty), + nameof(IFArrayProperty) => sizeof(FArrayProperty), + nameof(IFSetProperty) => sizeof(FSetProperty), + nameof(IFOptionalProperty) => sizeof(FOptionalProperty), + nameof(IFDelegateProperty) => sizeof(FDelegateProperty), + _ => throw new NotSupportedException(TypeName) + }; + } + } + + public override IFProperty CreateFProperty(nint ptr) => new UE4_27_2.FPropertyUE4_27_2(ptr, this); + public override IFByteProperty CreateFByteProperty(nint ptr) => new UE4_27_2.FBytePropertyUE4_27_2(ptr, this); + public override IFBoolProperty CreateFBoolProperty(nint ptr) => new UE4_27_2.FBoolPropertyUE4_27_2(ptr, this); + public override IFEnumProperty CreateFEnumProperty(nint ptr) => new UE4_27_2.FEnumPropertyUE4_27_2(ptr, this); + public override IFObjectProperty CreateFObjectProperty(nint ptr) => new UE4_27_2.FObjectPropertyUE4_27_2(ptr, this); + public override IFSoftClassProperty CreateFSoftClassProperty(nint ptr) => new UE4_27_2.FSoftClassPropertyUE4_27_2(ptr, this); + public override IFClassProperty CreateFClassProperty(nint ptr) => new UE4_27_2.FClassPropertyUE4_27_2(ptr, this); + public override IFStructProperty CreateFStructProperty(nint ptr) => new UE4_27_2.FStructPropertyUE4_27_2(ptr, this); + public override IFMapProperty CreateFMapProperty(nint ptr) => new UE4_27_2.FMapPropertyUE4_27_2(ptr, this); + public override IFInterfaceProperty CreateFInterfaceProperty(nint ptr) => new UE4_27_2.FInterfacePropertyUE4_27_2(ptr, this); + public override IFArrayProperty CreateFArrayProperty(nint ptr) => new UE4_27_2.FArrayPropertyUE4_27_2(ptr, this); + public override IFSetProperty CreateFSetProperty(nint ptr) => new UE4_27_2.FSetPropertyUE4_27_2(ptr, this); + // public override IFOptionalProperty CreateFOptionalProperty(nint ptr) => new UE4_27_2.FOptionalPropertyUE4_27_2(ptr, this); + public override IFOptionalProperty CreateFOptionalProperty(nint ptr) => throw new NotSupportedException(); + public override IFDelegateProperty CreateFDelegateProperty(nint ptr) => new UE4_27_2.FDelegatePropertyUE4_27_2(ptr, this); + public override IUObjectArray CreateUObjectArray(nint ptr) => new UObjectArray_UE5_4_4(ptr, this); + public override IUObject CreateUObject(nint ptr) => new UObject_UE5_4_4(ptr, this); + public override IUClass CreateUClass(nint ptr) => new UClass_UE5_2_1(ptr, this); + public override IUScriptStruct CreateUScriptStruct(nint ptr) => new UScriptStruct_UE5_2_1(ptr, this); + public override IUEnum CreateUEnum(nint ptr) => new UEnum_UE5_4_4(ptr, this); + public override IUField CreateUField(nint ptr) => new UField_UE5_4_4(ptr, this); + public override IUStruct CreateUStruct(nint ptr) => new UStruct_UE5_2_1(ptr, this); + public override IUUserDefinedEnum CreateUUserDefinedEnum(nint ptr) => new UUserDefinedEnum_UE5_4_4(ptr, this); + public override IUFunction CreateUFunction(nint ptr) => new UFunction_UE5_4_4(ptr, this); + public override IFFieldClass CreateFFieldClass(nint ptr) => new FFieldClass_UE5_4_4(ptr, this); + public override IFField CreateFField(nint ptr) => new FField_UE5_4_4(ptr, this); + public override IFStructParams CreateFStructParams(nint ptr) => new FStructParams_UE5_4_4(ptr, this); + public override IFPropertyParams CreateFPropertyParams(nint ptr) => new FPropertyParams_UE5_4_4(ptr, this); + public override IFGenericPropertyParams CreateFGenericPropertyParams(nint ptr) => new FGenericPropertyParams_UE5_4_4(ptr, this); + public override IFWorldContext CreateFWorldContext(nint ptr) => new FWorldContext_UE5_4_4(ptr, this); + public override IUEngine CreateUEngine(nint ptr) => new UEngine_UE5_4_4(ptr, this); + public override IUGameInstance CreateUGameInstance(nint ptr) => new UGameInstance_UE5_4_4(ptr, this); public override IFStaticConstructObjectParameters CreateFStaticConstructObjectParameters() - { - throw new NotImplementedException(); - } - + => new FStaticConstructObjectParameters_UE5_4_4(this); public override IFActorSpawnParameters CreateFActorSpawnParameters() - { - throw new NotImplementedException(); - } + => new FActorSpawnParameters_UE5_4_4(this); +} + +public unsafe class UScriptStruct_UE5_2_1(nint ptr, IUnrealFactory factory) + : UStruct_UE5_2_1(ptr, factory), IUScriptStruct +{ + private readonly UScriptStruct* _self = (UScriptStruct*)ptr; + public EStructFlags StructFlags => _self->StructFlags; + public bool bPrepareCppStructOpsCompleted => _self->bPrepareCppStructOpsCompleted; + public nint CppStructOps => _self->CppStructOps; +} + +public unsafe class UStruct_UE5_2_1(nint ptr, IUnrealFactory factory) + : UField_UE5_4_4(ptr, factory), IUStruct +{ + private readonly UStruct* _self = (UStruct*)ptr; + + public IUStruct? SuperStruct + => _self->SuperStruct != null ? _factory.CreateUStruct((nint)_self->SuperStruct) : null; + public IEnumerable Children + => new IUFieldEnumerable(_self->Children != null ? _factory.CreateUField((nint)_self->Children) : null); + public IEnumerable ChildProperties => + new IFFieldEnumerable(_self->ChildProperties != null ? _factory.CreateFField((nint)_self->ChildProperties) : null); + public int PropertiesSize => _self->PropertiesSize; + public int MinAlignment => _self->MinAlignment; + public TArray Script { get; } = new(); + + public IEnumerable PropertyLink + => new UE4_27_2.IFPropertyEnumerable(_factory.CreateFProperty((nint)_self->PropertyLink), PropertyType.PropertyLink, + _factory); + + public IEnumerable RefLink + => new UE4_27_2.IFPropertyEnumerable(_factory.CreateFProperty((nint)_self->RefLink), PropertyType.NextRef, + _factory); + public IEnumerable DestructorLink + => new UE4_27_2.IFPropertyEnumerable(_factory.CreateFProperty((nint)_self->DestructorLink), PropertyType.DestructorLink, + _factory); + public IEnumerable PostConstructLink + => new UE4_27_2.IFPropertyEnumerable(_factory.CreateFProperty((nint)_self->PostConstructLink), PropertyType.PostConstructLink, + _factory); +} + +public unsafe class UClass_UE5_2_1(nint ptr, IUnrealFactory factory) + : UStruct_UE5_2_1(ptr, factory), IUClass +{ + private readonly UClass* _self = (UClass*)ptr; + + public IUClass? GetSuperClass() + => _self->GetSuperClass() != null ? _factory.CreateUClass((nint)_self->GetSuperClass()) : null; + + public IUFunction? GetFunction(string Name) + { + var FuncMapDict = new TMapDictionary( + (TMap*)(&_self->FuncMap), factory.Memory + ); + return FuncMapDict.TryGetValue(new(Name), out var Function) + ? factory.CreateUFunction((nint)Function.Value) + : null; + } + + public IUObject? ClassDefaultObject + => _self->ClassDefaultObject != null ? factory.CreateUObject((nint)_self->ClassDefaultObject ) : null; + + public nint Constructor => _self->ClassConstructor; + public EClassFlags ClassFlags => _self->ClassFlags; } \ No newline at end of file diff --git a/UE.Toolkit.Core/Types/Unreal/Factories/UE5_4_4/UnrealFactory.cs b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_4_4/UnrealFactory.cs index b301eef..e766436 100644 --- a/UE.Toolkit.Core/Types/Unreal/Factories/UE5_4_4/UnrealFactory.cs +++ b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_4_4/UnrealFactory.cs @@ -200,32 +200,6 @@ public IEnumerable PostConstructLinkNext public string RepNotifyFunc => _self->RepNotifyFunc.ToString(); } -public unsafe class FProperty_4_27_2(nint ptr, IUnrealFactory factory) - : FField_UE5_4_4(ptr, factory), IFProperty -{ - private readonly FProperty* _self = (FProperty*)ptr; - - public int ArrayDim => _self->ArrayDim; - public int ElementSize => _self->ElementSize; - public EPropertyFlags PropertyFlags => _self->PropertyFlags; - public ushort RepIndex => _self->RepIndex; - public byte BlueprintReplicationCondition => _self->BlueprintReplicationCondition; - public int Offset_Internal => _self->Offset_Internal; - public IEnumerable PropertyLinkNext - => new IFPropertyEnumerable(_factory.CreateFProperty((nint)_self->PropertyLinkNext), PropertyType.PropertyLink, - _factory); - public IEnumerable NextRef - => new IFPropertyEnumerable(_factory.CreateFProperty((nint)_self->NextRef), PropertyType.NextRef, - _factory); - public IEnumerable DestructorLinkNext - => new IFPropertyEnumerable(_factory.CreateFProperty((nint)_self->DestructorLinkNext), PropertyType.DestructorLink, - _factory); - public IEnumerable PostConstructLinkNext - => new IFPropertyEnumerable(_factory.CreateFProperty((nint)_self->PostConstructLinkNext), PropertyType.PostConstructLink, - _factory); - public string RepNotifyFunc => _self->RepNotifyFunc.ToString(); -} - public unsafe class IFPropertyEnumerable(IFProperty initial, PropertyType propType, IUnrealFactory factory) : IEnumerator, IEnumerable { diff --git a/UE.Toolkit.Core/Types/Unreal/Factories/UE5_6_1/UnrealFactory.cs b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_6_1/UnrealFactory.cs index e4e11cc..fee2b12 100644 --- a/UE.Toolkit.Core/Types/Unreal/Factories/UE5_6_1/UnrealFactory.cs +++ b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_6_1/UnrealFactory.cs @@ -1,176 +1,141 @@ using UE.Toolkit.Core.Types.Unreal.Factories.Interfaces; +using UE.Toolkit.Core.Types.Unreal.Factories.UE5_4_4; +using UE.Toolkit.Core.Types.Unreal.UE5_4_4; +using UStruct = UE.Toolkit.Core.Types.Unreal.UE5_6_1.UStruct; +using UScriptStruct = UE.Toolkit.Core.Types.Unreal.UE5_6_1.UScriptStruct; namespace UE.Toolkit.Core.Types.Unreal.Factories.UE5_6_1; public class UnrealFactory : BaseUnrealFactory { - public override IntPtr SizeOf() - { - throw new NotImplementedException(); - } - - public override IFProperty CreateFProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFBoolProperty CreateFBoolProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFByteProperty CreateFByteProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFEnumProperty CreateFEnumProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFObjectProperty CreateFObjectProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFSoftClassProperty CreateFSoftClassProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFClassProperty CreateFClassProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFStructProperty CreateFStructProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFMapProperty CreateFMapProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFInterfaceProperty CreateFInterfaceProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFArrayProperty CreateFArrayProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFSetProperty CreateFSetProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFOptionalProperty CreateFOptionalProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFDelegateProperty CreateFDelegateProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IUObjectArray CreateUObjectArray(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IUObject CreateUObject(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IUClass CreateUClass(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IUScriptStruct CreateUScriptStruct(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IUEnum CreateUEnum(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IUField CreateUField(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IUStruct CreateUStruct(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IUUserDefinedEnum CreateUUserDefinedEnum(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IUFunction CreateUFunction(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFFieldClass CreateFFieldClass(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFField CreateFField(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFStructParams CreateFStructParams(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFPropertyParams CreateFPropertyParams(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFGenericPropertyParams CreateFGenericPropertyParams(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFWorldContext CreateFWorldContext(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IUEngine CreateUEngine(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IUGameInstance CreateUGameInstance(IntPtr ptr) - { - throw new NotImplementedException(); - } - + public override nint SizeOf() + { + var TypeName = typeof(T).Name; + unsafe + { + return TypeName switch + { + nameof(IUObject) => sizeof(UObjectBase), + nameof(IUClass) => sizeof(UClass), + nameof(IUScriptStruct) => sizeof(UScriptStruct), + nameof(IUEnum) => sizeof(UEnum), + nameof(IUUserDefinedEnum) => sizeof(UUserDefinedEnum), + nameof(IFProperty) => sizeof(FProperty), + nameof(IFByteProperty) => sizeof(FByteProperty), + nameof(IFBoolProperty) => sizeof(FBoolProperty), + nameof(IFEnumProperty) => sizeof(FEnumProperty), + nameof(IFObjectProperty) => sizeof(FObjectProperty), + nameof(IFSoftClassProperty) => sizeof(FSoftClassProperty), + nameof(IFClassProperty) => sizeof(FClassProperty), + nameof(IFStructProperty) => sizeof(FStructProperty), + nameof(IFMapProperty) => sizeof(FMapProperty), + nameof(IFInterfaceProperty) => sizeof(FInterfaceProperty), + nameof(IFArrayProperty) => sizeof(FArrayProperty), + nameof(IFSetProperty) => sizeof(FSetProperty), + nameof(IFOptionalProperty) => sizeof(FOptionalProperty), + nameof(IFDelegateProperty) => sizeof(FDelegateProperty), + _ => throw new NotSupportedException(TypeName) + }; + } + } + + public override IFProperty CreateFProperty(nint ptr) => new FProperty_UE5_4_4(ptr, this); + public override IFByteProperty CreateFByteProperty(nint ptr) => new FByteProperty_UE5_4_4(ptr, this); + public override IFBoolProperty CreateFBoolProperty(nint ptr) => new FBoolProperty_UE5_4_4(ptr, this); + public override IFEnumProperty CreateFEnumProperty(nint ptr) => new FEnumProperty_UE5_4_4(ptr, this); + public override IFObjectProperty CreateFObjectProperty(nint ptr) => new FObjectProperty_UE5_4_4(ptr, this); + public override IFSoftClassProperty CreateFSoftClassProperty(nint ptr) => new FSoftClassProperty_UE5_4_4(ptr, this); + public override IFClassProperty CreateFClassProperty(nint ptr) => new FClassProperty_UE5_4_4(ptr, this); + public override IFStructProperty CreateFStructProperty(nint ptr) => new FStructProperty_UE5_4_4(ptr, this); + public override IFMapProperty CreateFMapProperty(nint ptr) => new FMapProperty_UE5_4_4(ptr, this); + public override IFInterfaceProperty CreateFInterfaceProperty(nint ptr) => new FInterfaceProperty_UE5_4_4(ptr, this); + public override IFArrayProperty CreateFArrayProperty(nint ptr) => new FArrayProperty_UE5_4_4(ptr, this); + public override IFSetProperty CreateFSetProperty(nint ptr) => new FSetProperty_UE5_4_4(ptr, this); + public override IFOptionalProperty CreateFOptionalProperty(nint ptr) => new FOptionalProperty_UE5_4_4(ptr, this); + public override IFDelegateProperty CreateFDelegateProperty(nint ptr) => new FDelegateProperty_UE5_4_4(ptr, this); + public override IUObjectArray CreateUObjectArray(nint ptr) => new UObjectArray_UE5_4_4(ptr, this); + public override IUObject CreateUObject(nint ptr) => new UObject_UE5_4_4(ptr, this); + public override IUClass CreateUClass(nint ptr) => new UClass_UE5_6_1(ptr, this); + public override IUScriptStruct CreateUScriptStruct(nint ptr) => new UScriptStruct_UE5_6_1(ptr, this); + public override IUEnum CreateUEnum(nint ptr) => new UEnum_UE5_4_4(ptr, this); + public override IUField CreateUField(nint ptr) => new UField_UE5_4_4(ptr, this); + public override IUStruct CreateUStruct(nint ptr) => new UStruct_UE5_6_1(ptr, this); + public override IUUserDefinedEnum CreateUUserDefinedEnum(nint ptr) => new UUserDefinedEnum_UE5_4_4(ptr, this); + public override IUFunction CreateUFunction(nint ptr) => new UFunction_UE5_4_4(ptr, this); + public override IFFieldClass CreateFFieldClass(nint ptr) => new FFieldClass_UE5_4_4(ptr, this); + public override IFField CreateFField(nint ptr) => new FField_UE5_4_4(ptr, this); + public override IFStructParams CreateFStructParams(nint ptr) => new FStructParams_UE5_4_4(ptr, this); + public override IFPropertyParams CreateFPropertyParams(nint ptr) => new FPropertyParams_UE5_4_4(ptr, this); + public override IFGenericPropertyParams CreateFGenericPropertyParams(nint ptr) => new FGenericPropertyParams_UE5_4_4(ptr, this); + public override IFWorldContext CreateFWorldContext(nint ptr) => new FWorldContext_UE5_4_4(ptr, this); + public override IUEngine CreateUEngine(nint ptr) => new UEngine_UE5_4_4(ptr, this); + public override IUGameInstance CreateUGameInstance(nint ptr) => new UGameInstance_UE5_4_4(ptr, this); public override IFStaticConstructObjectParameters CreateFStaticConstructObjectParameters() - { - throw new NotImplementedException(); - } - + => new FStaticConstructObjectParameters_UE5_4_4(this); public override IFActorSpawnParameters CreateFActorSpawnParameters() - { - throw new NotImplementedException(); - } + => new FActorSpawnParameters_UE5_4_4(this); +} + +public unsafe class UStruct_UE5_6_1(nint ptr, IUnrealFactory factory) + : UField_UE5_4_4(ptr, factory), IUStruct +{ + private readonly UStruct* _self = (UStruct*)ptr; + + public IUStruct? SuperStruct + => _self->SuperStruct != null ? _factory.CreateUStruct((nint)_self->SuperStruct) : null; + public IEnumerable Children + => new IUFieldEnumerable(_self->Children != null ? _factory.CreateUField((nint)_self->Children) : null); + public IEnumerable ChildProperties => + new IFFieldEnumerable(_self->ChildProperties != null ? _factory.CreateFField((nint)_self->ChildProperties) : null); + public int PropertiesSize => _self->PropertiesSize; + public int MinAlignment => _self->MinAlignment; + public TArray Script { get; } = new(); + + public IEnumerable PropertyLink + => new IFPropertyEnumerable(_factory.CreateFProperty((nint)_self->PropertyLink), PropertyType.PropertyLink, + _factory); + + public IEnumerable RefLink + => new IFPropertyEnumerable(_factory.CreateFProperty((nint)_self->RefLink), PropertyType.NextRef, + _factory); + public IEnumerable DestructorLink + => new IFPropertyEnumerable(_factory.CreateFProperty((nint)_self->DestructorLink), PropertyType.DestructorLink, + _factory); + public IEnumerable PostConstructLink + => new IFPropertyEnumerable(_factory.CreateFProperty((nint)_self->PostConstructLink), PropertyType.PostConstructLink, + _factory); +} + +public unsafe class UScriptStruct_UE5_6_1(nint ptr, IUnrealFactory factory) + : UStruct_UE5_6_1(ptr, factory), IUScriptStruct +{ + private readonly UScriptStruct* _self = (UScriptStruct*)ptr; + public EStructFlags StructFlags => _self->StructFlags; + public bool bPrepareCppStructOpsCompleted => _self->bPrepareCppStructOpsCompleted; + public nint CppStructOps => _self->CppStructOps; +} + +public unsafe class UClass_UE5_6_1(nint ptr, IUnrealFactory factory) + : UStruct_UE5_6_1(ptr, factory), IUClass +{ + private readonly UClass* _self = (UClass*)ptr; + + public IUClass? GetSuperClass() + => _self->GetSuperClass() != null ? _factory.CreateUClass((nint)_self->GetSuperClass()) : null; + + public IUFunction? GetFunction(string Name) + { + var FuncMapDict = new TMapDictionary( + (TMap*)(&_self->FuncMap), factory.Memory + ); + return FuncMapDict.TryGetValue(new(Name), out var Function) + ? factory.CreateUFunction((nint)Function.Value) + : null; + } + + public IUObject? ClassDefaultObject + => _self->ClassDefaultObject != null ? factory.CreateUObject((nint)_self->ClassDefaultObject ) : null; + + public nint Constructor => _self->ClassConstructor; + public EClassFlags ClassFlags => _self->ClassFlags; } \ No newline at end of file diff --git a/UE.Toolkit.Core/Types/Unreal/Factories/UE5_7_4/UnrealFactory.cs b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_7_4/UnrealFactory.cs index 4904e25..324e272 100644 --- a/UE.Toolkit.Core/Types/Unreal/Factories/UE5_7_4/UnrealFactory.cs +++ b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_7_4/UnrealFactory.cs @@ -1,176 +1,179 @@ +using System.Runtime.InteropServices; +using UE.Toolkit.Core.Types.Interfaces; using UE.Toolkit.Core.Types.Unreal.Factories.Interfaces; +using UE.Toolkit.Core.Types.Unreal.Factories.UE5_4_4; +using UE.Toolkit.Core.Types.Unreal.UE5_4_4; +using FFieldClass = UE.Toolkit.Core.Types.Unreal.UE5_7_4.FFieldClass; namespace UE.Toolkit.Core.Types.Unreal.Factories.UE5_7_4; public class UnrealFactory : BaseUnrealFactory { - public override IntPtr SizeOf() - { - throw new NotImplementedException(); - } - - public override IFProperty CreateFProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFBoolProperty CreateFBoolProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFByteProperty CreateFByteProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFEnumProperty CreateFEnumProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFObjectProperty CreateFObjectProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFSoftClassProperty CreateFSoftClassProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFClassProperty CreateFClassProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFStructProperty CreateFStructProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFMapProperty CreateFMapProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFInterfaceProperty CreateFInterfaceProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFArrayProperty CreateFArrayProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFSetProperty CreateFSetProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFOptionalProperty CreateFOptionalProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IFDelegateProperty CreateFDelegateProperty(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IUObjectArray CreateUObjectArray(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IUObject CreateUObject(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IUClass CreateUClass(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IUScriptStruct CreateUScriptStruct(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IUEnum CreateUEnum(IntPtr ptr) - { - throw new NotImplementedException(); - } - - public override IUField CreateUField(IntPtr ptr) - { - throw new NotImplementedException(); - } + public override nint SizeOf() + { + var TypeName = typeof(T).Name; + unsafe + { + return TypeName switch + { + nameof(IUObject) => sizeof(UObjectBase), + nameof(IUClass) => sizeof(UClass), + nameof(IUScriptStruct) => sizeof(UScriptStruct), + nameof(IUEnum) => sizeof(UEnum), + nameof(IUUserDefinedEnum) => sizeof(UUserDefinedEnum), + nameof(IFProperty) => sizeof(FProperty), + nameof(IFByteProperty) => sizeof(FByteProperty), + nameof(IFBoolProperty) => sizeof(FBoolProperty), + nameof(IFEnumProperty) => sizeof(FEnumProperty), + nameof(IFObjectProperty) => sizeof(FObjectProperty), + nameof(IFSoftClassProperty) => sizeof(FSoftClassProperty), + nameof(IFClassProperty) => sizeof(FClassProperty), + nameof(IFStructProperty) => sizeof(FStructProperty), + nameof(IFMapProperty) => sizeof(FMapProperty), + nameof(IFInterfaceProperty) => sizeof(FInterfaceProperty), + nameof(IFArrayProperty) => sizeof(FArrayProperty), + nameof(IFSetProperty) => sizeof(FSetProperty), + nameof(IFOptionalProperty) => sizeof(FOptionalProperty), + nameof(IFDelegateProperty) => sizeof(FDelegateProperty), + _ => throw new NotSupportedException(TypeName) + }; + } + } + + public override IFProperty CreateFProperty(nint ptr) => new FProperty_UE5_4_4(ptr, this); + public override IFByteProperty CreateFByteProperty(nint ptr) => new FByteProperty_UE5_4_4(ptr, this); + public override IFBoolProperty CreateFBoolProperty(nint ptr) => new FBoolProperty_UE5_4_4(ptr, this); + public override IFEnumProperty CreateFEnumProperty(nint ptr) => new FEnumProperty_UE5_4_4(ptr, this); + public override IFObjectProperty CreateFObjectProperty(nint ptr) => new FObjectProperty_UE5_4_4(ptr, this); + public override IFSoftClassProperty CreateFSoftClassProperty(nint ptr) => new FSoftClassProperty_UE5_4_4(ptr, this); + public override IFClassProperty CreateFClassProperty(nint ptr) => new FClassProperty_UE5_4_4(ptr, this); + public override IFStructProperty CreateFStructProperty(nint ptr) => new FStructProperty_UE5_4_4(ptr, this); + public override IFMapProperty CreateFMapProperty(nint ptr) => new FMapProperty_UE5_4_4(ptr, this); + public override IFInterfaceProperty CreateFInterfaceProperty(nint ptr) => new FInterfaceProperty_UE5_4_4(ptr, this); + public override IFArrayProperty CreateFArrayProperty(nint ptr) => new FArrayProperty_UE5_4_4(ptr, this); + public override IFSetProperty CreateFSetProperty(nint ptr) => new FSetProperty_UE5_4_4(ptr, this); + public override IFOptionalProperty CreateFOptionalProperty(nint ptr) => new FOptionalProperty_UE5_4_4(ptr, this); + public override IFDelegateProperty CreateFDelegateProperty(nint ptr) => new FDelegateProperty_UE5_4_4(ptr, this); + public override IUObjectArray CreateUObjectArray(nint ptr) => new UObjectArray_UE5_7_4(ptr, this); + public override IUObject CreateUObject(nint ptr) => new UObject_UE5_4_4(ptr, this); + public override IUClass CreateUClass(nint ptr) => new UE5_6_1.UClass_UE5_6_1(ptr, this); + public override IUScriptStruct CreateUScriptStruct(nint ptr) => new UE5_6_1.UScriptStruct_UE5_6_1(ptr, this); + public override IUEnum CreateUEnum(nint ptr) => new UEnum_UE5_7_4(ptr, this); + public override IUField CreateUField(nint ptr) => new UField_UE5_4_4(ptr, this); + public override IUStruct CreateUStruct(nint ptr) => new UE5_6_1.UStruct_UE5_6_1(ptr, this); + public override IUUserDefinedEnum CreateUUserDefinedEnum(nint ptr) => new UUserDefinedEnum_UE5_4_4(ptr, this); + public override IUFunction CreateUFunction(nint ptr) => new UFunction_UE5_4_4(ptr, this); + public override IFFieldClass CreateFFieldClass(nint ptr) => new FFieldClass_UE5_7_4(ptr, this); + public override IFField CreateFField(nint ptr) => new FField_UE5_4_4(ptr, this); + public override IFStructParams CreateFStructParams(nint ptr) => new FStructParams_UE5_4_4(ptr, this); + public override IFPropertyParams CreateFPropertyParams(nint ptr) => new FPropertyParams_UE5_4_4(ptr, this); + public override IFGenericPropertyParams CreateFGenericPropertyParams(nint ptr) => new FGenericPropertyParams_UE5_4_4(ptr, this); + public override IFWorldContext CreateFWorldContext(nint ptr) => new FWorldContext_UE5_4_4(ptr, this); + public override IUEngine CreateUEngine(nint ptr) => new UEngine_UE5_4_4(ptr, this); + public override IUGameInstance CreateUGameInstance(nint ptr) => new UGameInstance_UE5_4_4(ptr, this); + public override IFStaticConstructObjectParameters CreateFStaticConstructObjectParameters() + => new FStaticConstructObjectParameters_UE5_4_4(this); + public override IFActorSpawnParameters CreateFActorSpawnParameters() + => new FActorSpawnParameters_UE5_4_4(this); +} - public override IUStruct CreateUStruct(IntPtr ptr) - { - throw new NotImplementedException(); - } +public unsafe class FFieldClass_UE5_7_4(nint ptr, IUnrealFactory factory) + : IFFieldClass +{ + private readonly FFieldClass* _self = (FFieldClass*)ptr; + + public nint Ptr => ptr; + public string Name => _self->Name.ToString(); + public ulong Id => _self->Id; + public ulong CastFlags => _self->CastFlags; + public EClassFlags ClassFlags => _self->ClassFlags; + public IFFieldClass SuperClass => factory.CreateFFieldClass((nint)_self->SuperClass); + public IFField DefaultObject => factory.CreateFField((nint)_self->DefaultObject); + public nint FieldConstructor => _self->FieldConstructor; +} + +public unsafe class UObjectArray_UE5_7_4(nint ptr, IUnrealFactory factory) : IUObjectArray +{ + private readonly FUObjectArray_UE5_7* _self = (FUObjectArray_UE5_7*)ptr; - public override IUUserDefinedEnum CreateUUserDefinedEnum(IntPtr ptr) - { - throw new NotImplementedException(); - } + public int ObjLastNonGCIndex => _self->ObjLastNonGCIndex; - public override IUFunction CreateUFunction(IntPtr ptr) + public IUObject? IndexToObject(int idx) { - throw new NotImplementedException(); + var objItem = _self->ObjObjects.GetItem(idx); + if (objItem == null || objItem->Object == null) return null; + + return factory.CreateUObject((nint)objItem->Object); } - public override IFFieldClass CreateFFieldClass(IntPtr ptr) - { - throw new NotImplementedException(); - } + public int NumElements => _self->ObjObjects.NumElements; - public override IFField CreateFField(IntPtr ptr) + public void AddToRootSet(int idx) { - throw new NotImplementedException(); + var objItem = _self->ObjObjects.GetItem(idx); + if (objItem == null || objItem->Object == null) return; + objItem->Flags |= EInternalObjectFlags.RootSet; + objItem->Object->ObjectFlags |= EObjectFlags.RF_MarkAsRootSet; } - public override IFStructParams CreateFStructParams(IntPtr ptr) + public void RemoveFromRootSet(int idx) { - throw new NotImplementedException(); + var objItem = _self->ObjObjects.GetItem(idx); + if (objItem == null || objItem->Object == null) return; + objItem->Flags &= ~EInternalObjectFlags.RootSet; + objItem->Object->ObjectFlags &= ~EObjectFlags.RF_MarkAsRootSet; } +} - public override IFPropertyParams CreateFPropertyParams(IntPtr ptr) - { - throw new NotImplementedException(); - } +public unsafe class UEnum_UE5_7_4(nint ptr, IUnrealFactory factory) + : UField_UE5_4_4(ptr, factory), IUEnum, IDisposable +{ + private readonly Unreal.UE5_7_4.UEnum* _self = (Unreal.UE5_7_4.UEnum*)ptr; + public string CppType => _self->CppType.ToString(); - public override IFGenericPropertyParams CreateFGenericPropertyParams(IntPtr ptr) - { - throw new NotImplementedException(); - } + private TArray>? CachedNames; + private bool _isDisposed; - public override IFWorldContext CreateFWorldContext(IntPtr ptr) - { - throw new NotImplementedException(); - } + private const nint MASK_POINTER = ~1; - public override IUEngine CreateUEngine(IntPtr ptr) + public TArray> Names { - throw new NotImplementedException(); + get + { + if (CachedNames == null) + { + var NamesToCache = new TArray> + { + ArrayNum = _self->NameData.NumValues, + ArrayMax = _self->NameData.NumValues + }; + NamesToCache.AllocatorInstance = (TPair*)_factory.Memory.Malloc(NamesToCache.ArrayNum * sizeof(TPair)); + // assert: This function should only be used after compiled-in enums have copied their static string names into FNames if mask pointer is off + // extra tag bit to indicate if the pointer is dynamically allocated or static + var pTaggedNames = (FName*)((nint)_self->NameData.TaggedNames & MASK_POINTER); + var pTaggedValues = (long*)((nint)_self->NameData.TaggedValues & MASK_POINTER); + for (var i = 0; i < NamesToCache.ArrayNum; i++) + { + NamesToCache.AllocatorInstance[i].Key = pTaggedNames[i]; + NamesToCache.AllocatorInstance[i].Value = pTaggedValues[i]; + } + CachedNames = NamesToCache; + } + return CachedNames.Value; + } } - public override IUGameInstance CreateUGameInstance(IntPtr ptr) - { - throw new NotImplementedException(); - } + ~UEnum_UE5_7_4() => Dispose(false); - public override IFStaticConstructObjectParameters CreateFStaticConstructObjectParameters() + public void Dispose() { - throw new NotImplementedException(); + Dispose(true); + GC.SuppressFinalize(this); } - public override IFActorSpawnParameters CreateFActorSpawnParameters() + protected virtual void Dispose(bool disposing) { - throw new NotImplementedException(); + if (disposing && CachedNames.Value.AllocatorInstance != null) + _factory.Memory.Free((nint)CachedNames.Value.AllocatorInstance); } } \ No newline at end of file diff --git a/UE.Toolkit.Core/Types/Unreal/UE5_4_4/FUObjectArray.cs b/UE.Toolkit.Core/Types/Unreal/UE5_4_4/FUObjectArray.cs index 6fa2c2d..f6aa85d 100644 --- a/UE.Toolkit.Core/Types/Unreal/UE5_4_4/FUObjectArray.cs +++ b/UE.Toolkit.Core/Types/Unreal/UE5_4_4/FUObjectArray.cs @@ -44,6 +44,25 @@ public struct FUObjectArray_Pack4 public FChunkedFixedUObjectArray_Pack4 ObjObjects; } +[StructLayout(LayoutKind.Sequential)] +public struct FUObjectArray_UE5_7 +{ + /** First index into objects array taken into account for GC. */ + public int ObjFirstGCIndex; + + /** Index pointing to last object created in range disregarded for GC. */ + public int ObjLastNonGCIndex; + + /** Maximum number of objects in the disregard for GC Pool */ + public int MaxObjectsNotConsideredByGC; + + /** If true this is the intial load and we should load objects int the disregarded for GC range. */ + public bool OpenForDisregardForGC; + + /** Array of all live objects. */ + public FChunkedFixedUObjectArray_UE5_7 ObjObjects; +} + [StructLayout(LayoutKind.Sequential, Pack = 4)] public unsafe struct FChunkedFixedUObjectArray_Pack4 { @@ -108,6 +127,38 @@ public unsafe struct FChunkedFixedUObjectArray } } +[StructLayout(LayoutKind.Sequential)] +public unsafe struct FChunkedFixedUObjectArray_UE5_7 +{ + const int NumElementsPerChunk = 64 * 1024; + + /** Primary table to chunks of pointers **/ + public FUObjectItem_5_7** Objects; + + /** If requested, a contiguous memory where all objects are allocated **/ + public FUObjectItem_5_7* PreAllocatedObjects; + + /** Maximum number of elements **/ + public int MaxElements; + + /** Number of elements we currently have **/ + public int NumElements; + + /** Maximum number of chunks **/ + public int MaxChunks; + + /** Number of chunks we currently have **/ + public int NumChunks; + + public readonly FUObjectItem_5_7* GetItem(int idx) + { + var chunkIndex = idx / NumElementsPerChunk; + var withinChunkIndex = idx % NumElementsPerChunk; + var chunk = Objects[chunkIndex]; + return chunk + withinChunkIndex; + } +} + [StructLayout(LayoutKind.Sequential, Pack = 8)] // Packing in source says 4, but 8 in Clair Obscur at least. public unsafe struct FUObjectItem { @@ -120,6 +171,25 @@ public unsafe struct FUObjectItem // UObject Owner Cluster Index public int ClusterRootIndex; + // Weak Object Pointer Serial number associated with the object + public int SerialNumber; +} + +[StructLayout(LayoutKind.Sequential, Pack = 8)] // Packing in source says 4, but 8 in Clair Obscur at least. +public unsafe struct FUObjectItem_5_7 +{ + // int64 FlagsAndRefCount; + public int RefCount; + + // Internal flags. These can only be changed via Set* and Clear* functions + public EInternalObjectFlags Flags; + + // Pointer to the allocated object + public UObjectBase* Object; + + // UObject Owner Cluster Index + public int ClusterRootIndex; + // Weak Object Pointer Serial number associated with the object public int SerialNumber; } \ No newline at end of file diff --git a/UE.Toolkit.Core/Types/Unreal/UE5_6_1/UScriptStruct.cs b/UE.Toolkit.Core/Types/Unreal/UE5_6_1/UScriptStruct.cs new file mode 100644 index 0000000..35278a7 --- /dev/null +++ b/UE.Toolkit.Core/Types/Unreal/UE5_6_1/UScriptStruct.cs @@ -0,0 +1,13 @@ +using System.Runtime.InteropServices; +using UE.Toolkit.Core.Types.Unreal.UE5_4_4; + +namespace UE.Toolkit.Core.Types.Unreal.UE5_6_1; + +[StructLayout(LayoutKind.Sequential, Size = 0xC0)] +public struct UScriptStruct +{ + public UStruct Super; + public EStructFlags StructFlags; + public bool bPrepareCppStructOpsCompleted; + public nint CppStructOps; +} \ No newline at end of file diff --git a/UE.Toolkit.Core/Types/Unreal/UE5_6_1/UStruct.cs b/UE.Toolkit.Core/Types/Unreal/UE5_6_1/UStruct.cs new file mode 100644 index 0000000..3fa3008 --- /dev/null +++ b/UE.Toolkit.Core/Types/Unreal/UE5_6_1/UStruct.cs @@ -0,0 +1,21 @@ +using System.Runtime.InteropServices; +using UE.Toolkit.Core.Types.Unreal.UE5_4_4; + +namespace UE.Toolkit.Core.Types.Unreal.UE5_6_1; + +[StructLayout(LayoutKind.Explicit, Size = 0xb0, Pack = 8)] +public unsafe struct UStruct +{ + [FieldOffset(0x0)] public UField _super; + [FieldOffset(0x40)] public UStruct* SuperStruct; // ObjectPtr_Private::TNonAccessTrackedObjectPtr (sizeof = 0x8) + [FieldOffset(0x48)] public UField* Children; // anything not a type field (e.g a class method) - beginning of linked list + [FieldOffset(0x50)] public FField* ChildProperties; // the data model - beginning of linked list + [FieldOffset(0x58)] public int PropertiesSize; + [FieldOffset(0x5c)] public short MinAlignment; + [FieldOffset(0x5e)] public short StructStateFlags; // std::atomic + [FieldOffset(0x60)] public TArray Script; + [FieldOffset(0x70)] public FProperty* PropertyLink; + [FieldOffset(0x78)] public FProperty* RefLink; + [FieldOffset(0x80)] public FProperty* DestructorLink; + [FieldOffset(0x88)] public FProperty* PostConstructLink; +} \ No newline at end of file diff --git a/UE.Toolkit.Core/Types/Unreal/UE5_7_4/FFieldClass.cs b/UE.Toolkit.Core/Types/Unreal/UE5_7_4/FFieldClass.cs new file mode 100644 index 0000000..9663a46 --- /dev/null +++ b/UE.Toolkit.Core/Types/Unreal/UE5_7_4/FFieldClass.cs @@ -0,0 +1,23 @@ +using System.Runtime.InteropServices; +using UE.Toolkit.Core.Types.Unreal.UE5_4_4; + +namespace UE.Toolkit.Core.Types.Unreal.UE5_7_4; + +[StructLayout(LayoutKind.Sequential, Pack = 8)] +public unsafe struct FFieldClass +{ + public FName Name; + public EClassFlags ClassFlags; + public ulong Id; + public ulong CastFlags; + public FFieldClass* SuperClass; + public FField* DefaultObject; + public nint FieldConstructor; + public FThreadSafeCounter UnqiueNameIndexCounter; +} + +[StructLayout(LayoutKind.Sequential)] +public struct FThreadSafeCounter +{ + public int Counter; +} \ No newline at end of file diff --git a/UE.Toolkit.Core/Types/Unreal/UE5_7_4/UEnum.cs b/UE.Toolkit.Core/Types/Unreal/UE5_7_4/UEnum.cs new file mode 100644 index 0000000..49ac2bc --- /dev/null +++ b/UE.Toolkit.Core/Types/Unreal/UE5_7_4/UEnum.cs @@ -0,0 +1,41 @@ +// ReSharper disable InvalidXmlDocComment + +using System.Runtime.InteropServices; +using UE.Toolkit.Core.Types.Unreal.UE5_4_4; + +namespace UE.Toolkit.Core.Types.Unreal.UE5_7_4; + +[StructLayout(LayoutKind.Sequential, Size = 0x18)] +public struct FNameData +{ + public unsafe FName* TaggedNames; + public unsafe int* TaggedValues; + public int NumValues; +} + +[StructLayout(LayoutKind.Sequential, Size = 0x70)] +public struct UEnum +{ + public UField Super; + public FString CppType; + public FNameData NameData; + // public TArray> Names; + + /* How the enum was originally defined. */ + //ECppForm CppForm; + + /* Enum flags. */ + //EEnumFlags EnumFlags; + + /* pointer to function used to look up the enum's display name. Currently only assigned for UEnums generated for nativized blueprints */ + //FEnumDisplayNameFn EnumDisplayNameFn; + + /* Package name this enum was in when its names were being added to the primary list */ + //FName EnumPackage; + + /* lock to be taken when accessing AllEnumNames */ + //static FRWLock AllEnumNamesLock; + + /* global list of all value names used by all enums in memory, used for property text import */ + //static TMap > AllEnumNames; +} \ No newline at end of file diff --git a/UE.Toolkit.DumperMod/Dumper.cs b/UE.Toolkit.DumperMod/Dumper.cs index 40b5d27..fc2451c 100644 --- a/UE.Toolkit.DumperMod/Dumper.cs +++ b/UE.Toolkit.DumperMod/Dumper.cs @@ -251,7 +251,7 @@ private static string GetHeaderNameForObject(IUObject obj) private static void AddHeader(StringBuilder sb) { - sb.AppendLine("/* Generated with UE Toolkit: Dumper (1.6.0) */"); + sb.AppendLine("/* Generated with UE Toolkit: Dumper (1.8.0) */"); sb.AppendLine("/* GitHub: https://github.com/RyoTune/UE.Toolkit */"); sb.AppendLine("/* Author: RyoTune */"); sb.AppendLine("/* Special thanks to UE4SS team and Rirurin */"); @@ -346,7 +346,7 @@ private void GenerateEnumDefinition(IUEnum uenum, string? knownType = null) if (uenum.IsChildOf()) { var userEnum = _factory.Cast(uenum); - for (int i = 0; i < uenum.Names.ArrayNum; i++) + for (var i = 0; i < uenum.Names.ArrayNum; i++) { var dispName = _strs.UEnumGetDisplayNameTextByIndex(userEnum.Ptr, i); dispNames[i] = $"{name}::{dispName}"; @@ -503,6 +503,7 @@ private Func GetPropertyTypeNameLazy(IFProperty prop) var structPropType = _factory.Cast(prop).Struct.NamePrivate.ToString(); return () => SanitizeName(_UStructDefinitions.TryGetValue(structPropType, out var knownStruct) ? knownStruct.DisplayName : structPropType); case "ClassProperty": + case "ClassPtrProperty": var classPropClass = _factory.Cast(prop).MetaClass; var classPropType = classPropClass != null ? classPropClass.NamePrivate.ToString() : "UClass*"; return () => SanitizeName(_UStructDefinitions.TryGetValue(classPropType, out var knownStruct) ? $"{knownStruct.DisplayName}*" : classPropType); @@ -575,6 +576,10 @@ private Func GetPropertyTypeNameLazy(IFProperty prop) return $"TLazyObjectPtr<{SanitizeName(lazyObjType)}>"; }; + case "Utf8StrProperty": + return () => "FUtf8String"; + case "AnsiStrProperty": + return () => "FAnsiString"; default: Log.Warning($"Unknown Property: {className}"); return () => className; @@ -628,6 +633,7 @@ private string GetPropertyTypeName(IFProperty prop) case "StructProperty": return _factory.Cast(prop).Struct.NamePrivate.ToString(); case "ClassProperty": + case "ClassPtrProperty": return _factory.Cast(prop).MetaClass!.NamePrivate.ToString(); case "EnumProperty": return _factory.Cast(prop).Enum.NamePrivate.ToString(); @@ -651,6 +657,10 @@ private string GetPropertyTypeName(IFProperty prop) return "FWeakObjectPtr"; case "FieldPathProperty": return "FFieldPath"; + case "Utf8StrProperty": + return "FUtf8String"; + case "AnsiStrProperty": + return "FAnsiString"; default: Log.Warning($"Unknown Property: {className}"); return className; diff --git a/UE.Toolkit.DumperMod/ModConfig.json b/UE.Toolkit.DumperMod/ModConfig.json index 63b77c9..89f46da 100644 --- a/UE.Toolkit.DumperMod/ModConfig.json +++ b/UE.Toolkit.DumperMod/ModConfig.json @@ -2,7 +2,7 @@ "ModId": "UE.Toolkit.DumperMod", "ModName": "UE Toolkit: Dumper", "ModAuthor": "RyoTune", - "ModVersion": "1.6.5", + "ModVersion": "1.8.0", "ModDescription": "Unreal Engine object dumper to C# types.", "ModDll": "UE.Toolkit.DumperMod.dll", "ModIcon": "Preview.png", diff --git a/UE.Toolkit.Reloaded/Common/GameConfigs/GameConfig.cs b/UE.Toolkit.Reloaded/Common/GameConfigs/GameConfig.cs index ed95f93..3b745c6 100644 --- a/UE.Toolkit.Reloaded/Common/GameConfigs/GameConfig.cs +++ b/UE.Toolkit.Reloaded/Common/GameConfigs/GameConfig.cs @@ -27,17 +27,23 @@ public static void SetGame(string appId) Instance = appId switch { "p3r.exe" or "smt5v-win64-shipping.exe" => new UE4_27_2_P3R(), + "iostoretest_50-win64-shipping.exe" or "iostoretest_51-win64-shipping.exe" + or "iostoretest_52-win64-shipping.exe" or "chronos-win64-shipping.exe" => new UE5_2_1(), + "iostoretest_53-win64-shipping.exe" => new UE5_3_2(), + "iostoretest_56-win64-shipping.exe" => new UE5_6_1(), + "iostoretest_57-win64-shipping.exe" => new UE5_7_4(), _ => new UE5_4_4_ClairObscur() }; Log.Information($"Game config set to: {Instance.Id} (App ID: {appId})"); } + // public static Type GetFText() { return Instance.Id switch { - "P3R" => typeof(UE.Toolkit.Core.Types.Unreal.UE4_27_2.FText), + "P3R" or "UE5_2_1" or "UE5_3_2" => typeof(UE.Toolkit.Core.Types.Unreal.UE4_27_2.FText), _ => typeof(UE.Toolkit.Core.Types.Unreal.UE5_4_4.FText) }; } @@ -48,7 +54,7 @@ public static int GetFTextSize() { return Instance.Id switch { - "P3R" => sizeof(UE.Toolkit.Core.Types.Unreal.UE4_27_2.FText), + "P3R" or "UE5_2_1" or "UE5_3_2" => sizeof(UE.Toolkit.Core.Types.Unreal.UE4_27_2.FText), _ => sizeof(UE.Toolkit.Core.Types.Unreal.UE5_4_4.FText) }; } diff --git a/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_2_1.cs b/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_2_1.cs new file mode 100644 index 0000000..6247200 --- /dev/null +++ b/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_2_1.cs @@ -0,0 +1,13 @@ +using UE.Toolkit.Core.Types.Unreal.Factories; +using UE.Toolkit.Core.Types.Unreal.Factories.UE5_2_1; +using UE.Toolkit.Interfaces; +using UE.Toolkit.Reloaded.Unreal; + +namespace UE.Toolkit.Reloaded.Common.GameConfigs.Games; + +public class UE5_2_1: UE5_4_4_ClairObscur +{ + public override string Id => "UE5_2_1"; + public override IUnrealFactory Factory { get; } = new UnrealFactory(); + public override IUnrealMemory Memory { get; } = new UnrealMemory(); +} \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_3_2.cs b/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_3_2.cs new file mode 100644 index 0000000..1eaa0d9 --- /dev/null +++ b/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_3_2.cs @@ -0,0 +1,14 @@ +using UE.Toolkit.Core.Types.Unreal.Factories; +using UE.Toolkit.Core.Types.Unreal.Factories.UE5_4_4; +using UE.Toolkit.Interfaces; +using UE.Toolkit.Reloaded.Unreal; + +namespace UE.Toolkit.Reloaded.Common.GameConfigs.Games; + +// ReSharper disable once InconsistentNaming +public class UE5_3_2 : IGameConfig +{ + public virtual string Id => "UE5_3_2"; + public virtual IUnrealFactory Factory { get; } = new UnrealFactory(); + public virtual IUnrealMemory Memory { get; } = new UnrealMemory(); +} \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_6_1.cs b/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_6_1.cs new file mode 100644 index 0000000..fad22d6 --- /dev/null +++ b/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_6_1.cs @@ -0,0 +1,13 @@ +using UE.Toolkit.Core.Types.Unreal.Factories; +using UE.Toolkit.Core.Types.Unreal.Factories.UE5_6_1; +using UE.Toolkit.Interfaces; +using UE.Toolkit.Reloaded.Unreal; + +namespace UE.Toolkit.Reloaded.Common.GameConfigs.Games; + +public class UE5_6_1: UE5_4_4_ClairObscur +{ + public override string Id => "UE5_6_1"; + public override IUnrealFactory Factory { get; } = new UnrealFactory(); + public override IUnrealMemory Memory { get; } = new UnrealMemory(); +} \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_7_4.cs b/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_7_4.cs new file mode 100644 index 0000000..ecaef77 --- /dev/null +++ b/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_7_4.cs @@ -0,0 +1,13 @@ +using UE.Toolkit.Core.Types.Unreal.Factories; +using UE.Toolkit.Core.Types.Unreal.Factories.UE5_7_4; +using UE.Toolkit.Interfaces; +using UE.Toolkit.Reloaded.Unreal; + +namespace UE.Toolkit.Reloaded.Common.GameConfigs.Games; + +public class UE5_7_4: UE5_4_4_ClairObscur +{ + public override string Id => "UE5_7_4"; + public override IUnrealFactory Factory { get; } = new UnrealFactory(); + public override IUnrealMemory Memory { get; } = new UnrealMemory(); +} \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/SMT5V-Win64-Shipping/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/SMT5V-Win64-Shipping/scans.ini index 52d1d44..8429952 100644 --- a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/SMT5V-Win64-Shipping/scans.ini +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/SMT5V-Win64-Shipping/scans.ini @@ -27,8 +27,8 @@ GUObjectArray_RESULT=GetGlobalAddress(result + 3) - 0x10 UStruct_IsChildOf=DISABLED ;UStruct_IsChildOf_RESULT= -UEnum_GetDisplayNameTextByIndex=48 89 5C 24 ?? 55 56 57 48 83 EC 30 48 8B FA 41 8B E8 -;UEnum_GetDisplayNameTextByIndex_RESULT= +UUserDefinedEnum_GetDisplayNameTextByIndex=48 89 5C 24 ?? 55 56 57 48 83 EC 30 48 8B FA 41 8B E8 +;UUserDefinedEnum_GetDisplayNameTextByIndex_RESULT= ;Unused and the signature below fails. Disable this signature so it doesn't appear as an error in bug reports ;UDataTable_HandleDataTableChanged=48 89 54 24 ?? 55 53 56 57 48 8D 6C 24 ?? 48 81 EC 98 00 00 00 diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/chronos-win64-shipping/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/chronos-win64-shipping/scans.ini new file mode 100644 index 0000000..eba4497 --- /dev/null +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/chronos-win64-shipping/scans.ini @@ -0,0 +1,64 @@ +;Life is Strange: Double Exposure (THIS IS THE SAME AS REGULAR 5.2) + +[Scans] +GFNamePool=48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 4C 8B C0 C6 05 ?? ?? ?? ?? 01 8B D3 0F B7 C3 89 44 24 +GFNamePool_RESULT=GetGlobalAddress(result + 3) + +;FNameHelper_FindOrStoreString=48 89 74 24 ?? 57 48 83 EC 60 81 79 ?? 00 04 00 00 +;FNameHelper_FindOrStoreString_RESULT= + +;??0FName@@QEAA@PEB_WW4EFindName@@@Z +FName_Ctor_Wide=48 89 5C 24 ?? 57 48 83 EC 30 48 8B D9 48 89 54 24 ?? 33 C9 +;FName_Ctor_Wide_RESULT= + +;?FromString@FText@@SA?AV1@$$QEAVFString@@@Z +FText_FromString=48 89 6C 24 ?? 57 48 83 EC 50 83 7A ?? 01 48 8B F9 48 89 74 24 ?? C7 44 24 ?? 00 00 00 00 7F ?? E8 ?? ?? ?? ?? 48 8B 48 ?? 48 8B 10 48 89 54 24 ?? 48 89 4C 24 ?? 48 85 C9 74 ?? F0 FF 41 ?? 8B 40 ?? BE 01 00 00 00 89 44 24 ?? 48 8D 44 24 ?? EB ?? 48 8D 4C 24 ?? E8 ?? ?? ?? ?? BE 02 00 00 00 48 8B 10 48 89 17 48 8B 48 ?? 48 89 4F ?? 48 85 C9 74 ?? F0 FF 41 ?? 8B 40 ?? BD FF FF FF FF 89 47 ?? 48 89 5C 24 ?? 40 F6 C6 02 74 ?? 48 8B 5C 24 ?? 83 E6 FD 48 85 DB 74 ?? 8B C5 F0 0F C1 43 ?? 83 F8 01 75 ?? 48 8B 03 48 8B CB FF 10 8B C5 F0 0F C1 43 ?? 83 F8 01 75 ?? 48 8B 03 8D 55 ?? 48 8B CB FF 50 ?? 40 F6 C6 01 48 8B 74 24 ?? 74 ?? 48 8B 4C 24 ?? 48 85 C9 74 ?? 8B C5 F0 0F C1 41 ?? 83 F8 01 75 ?? 48 8B 5C 24 ?? 48 8B CB 48 8B 03 FF 10 F0 0F C1 6B ?? 83 FD 01 75 ?? 48 8B 4C 24 ?? 8B D5 48 8B 01 FF 50 ?? 83 4F ?? 12 +;FText_FromString_RESULT= + +FText_ToString=40 53 48 83 EC 20 48 8B D9 E8 ?? ?? ?? ?? 48 8B 0B 48 8B 01 48 83 C4 20 +;FText_ToString_RESULT= + +UObject_PostLoadSubobjects=E8 ?? ?? ?? ?? 48 8B CB E8 ?? ?? ?? ?? 48 8B 83 ?? ?? ?? ?? 48 85 C0 0F 84 ?? ?? ?? ?? +UObject_PostLoadSubobjects_RESULT=GetGlobalAddress(result + 1) + +UObject_BeginDestroy=40 53 48 83 EC 30 8B 41 ?? 48 8B D9 C1 E8 0F +;UObject_BeginDestroy_RESULT= + +;From UObjectBaseInit +GUObjectArray=89 15 ?? ?? ?? ?? 85 FF +GUObjectArray_RESULT=GetGlobalAddress(result + 2) + +UStruct_IsChildOf=48 85 D2 74 ?? 48 63 42 ?? 4C 8D 42 +;UStruct_IsChildOf_RESULT= + +UUserDefinedEnum_GetDisplayNameTextByIndex=48 89 5C 24 ?? 55 56 57 48 83 EC 30 48 8B FA 41 8B E8 +;UUserDefinedEnum_GetDisplayNameTextByIndex_RESULT= + +UDataTable_HandleDataTableChanged=48 89 54 24 ?? 55 53 56 48 8D 6C 24 ?? 48 81 EC C0 00 00 00 +;UDataTable_HandleDataTableChanged_RESULT= + +GMalloc=48 8B 0D ?? ?? ?? ?? 48 85 C9 75 ?? E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? 48 8B 01 48 8B D3 FF 50 ?? 48 83 C4 20 +GMalloc_RESULT=GetGlobalAddress(result + 3) + +FTextInspector_GetTableIdAndKey=48 89 5C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 41 56 48 83 EC 30 48 8B F9 48 8D 1D + +GetPrivateStaticClassBody_UE4=DISABLED +;GetPrivateStaticClassBody_RESULT= + +GetPrivateStaticClassBody_UE5=48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 54 41 55 41 56 41 57 48 83 EC 60 45 33 ED +;GetPrivateStaticClassBody_RESULT= + +StaticConstructObject_Internal=4C 8B DC 49 89 5B ?? 49 89 73 ?? 55 57 41 54 41 56 41 57 49 8D AB ?? ?? ?? ?? +;StaticConstructObject_Internal_RESULT= + +GetStaticStruct=48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 50 49 8B E8 48 8B DA FF D1 48 8B F0 90 48 83 7B ?? 00 48 8D 7B ?? 74 ?? 33 C0 F7 43 ?? 00 00 00 10 74 ?? 48 8B CB E8 ?? ?? ?? ?? 48 8B D8 48 85 DB 75 ?? 48 8B 1F EB ?? 48 8B 43 ?? 48 8D 54 24 ?? 48 8D 4C 24 ?? 48 89 44 24 ?? E8 ?? ?? ?? ?? 83 7C 24 ?? 00 48 8D 0D ?? ?? ?? ?? 41 B9 02 00 00 00 48 89 74 24 ?? 48 0F 45 4C 24 ?? 45 8B C1 +;GetStaticStruct_RESULT= + +ConstructUScriptStruct=40 53 56 57 41 55 41 56 41 57 48 81 EC C8 03 00 00 +;ConstructUScriptStruct + +GEngine=48 89 05 ?? ?? ?? ?? 48 85 C9 74 ?? E8 ?? ?? ?? ?? 48 8D 4D ?? +GEngine_RESULT=GetGlobalAddress(result + 3) + +UWorld_SpawnActor=40 55 53 56 57 41 54 41 55 41 56 41 57 48 8D AC 24 ?? ?? ?? ?? 48 81 EC D8 03 00 00 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 85 ?? ?? ?? ?? 33 C0 +;UWorld_SpawnActor_RESULT= \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/chronos-win64-shipping/unreal.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/chronos-win64-shipping/unreal.ini new file mode 100644 index 0000000..13d35c1 --- /dev/null +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/chronos-win64-shipping/unreal.ini @@ -0,0 +1,20 @@ +;Based on Third Person Template for UE 5.2 + +[FMallocBinned2] +Free=0x40 +GetAllocSize=0x50 +Malloc=0x20 +Realloc=0x30 +QuantizeSize=0x48 + +[UObject] +ProcessEvent=0x268 + +[UScriptStruct] +GetCustomGuid=0x378 + +[UPackage] +GamePackage=/Script/SandFall + +[UStruct] +Link=0x2d0 \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_50-win64-shipping/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_50-win64-shipping/scans.ini index 5bffbbc..9f84289 100644 --- a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_50-win64-shipping/scans.ini +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_50-win64-shipping/scans.ini @@ -32,8 +32,8 @@ GUObjectArray_RESULT=GetGlobalAddress(result + 2) UStruct_IsChildOf=DISABLED ;UStruct_IsChildOf_RESULT= -UEnum_GetDisplayNameTextByIndex=48 89 5C 24 ?? 55 56 57 48 83 EC 30 48 8B FA -;UEnum_GetDisplayNameTextByIndex_RESULT= +UUserDefinedEnum_GetDisplayNameTextByIndex=48 89 5C 24 ?? 55 56 57 48 83 EC 30 48 8B FA +;UUserDefinedEnum_GetDisplayNameTextByIndex_RESULT= UDataTable_HandleDataTableChanged=48 89 54 24 ?? 55 53 56 48 8D 6C 24 ?? 48 81 EC A0 00 00 00 ;UDataTable_HandleDataTableChanged_RESULT= diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_51-win64-shipping/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_51-win64-shipping/scans.ini index 69f47d1..d57c0f1 100644 --- a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_51-win64-shipping/scans.ini +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_51-win64-shipping/scans.ini @@ -31,8 +31,8 @@ GUObjectArray_RESULT=GetGlobalAddress(result + 2) UStruct_IsChildOf=48 85 D2 74 ?? 48 63 42 ?? 4C 8D 42 ;UStruct_IsChildOf_RESULT= -UEnum_GetDisplayNameTextByIndex=48 89 5C 24 ?? 55 56 57 48 83 EC 30 48 8B FA -;UEnum_GetDisplayNameTextByIndex_RESULT= +UUserDefinedEnum_GetDisplayNameTextByIndex=48 89 5C 24 ?? 55 56 57 48 83 EC 30 48 8B FA +;UUserDefinedEnum_GetDisplayNameTextByIndex_RESULT= UDataTable_HandleDataTableChanged=48 89 54 24 ?? 55 53 56 48 8D 6C 24 ?? 48 81 EC A0 00 00 00 ;UDataTable_HandleDataTableChanged_RESULT= diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_52-win64-shipping/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_52-win64-shipping/scans.ini index bd5e42e..8911883 100644 --- a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_52-win64-shipping/scans.ini +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_52-win64-shipping/scans.ini @@ -31,8 +31,8 @@ GUObjectArray_RESULT=GetGlobalAddress(result + 2) UStruct_IsChildOf=48 85 D2 74 ?? 48 63 42 ?? 4C 8D 42 ;UStruct_IsChildOf_RESULT= -UEnum_GetDisplayNameTextByIndex=48 89 5C 24 ?? 55 56 57 48 83 EC 30 48 8B FA -;UEnum_GetDisplayNameTextByIndex_RESULT= +UUserDefinedEnum_GetDisplayNameTextByIndex=48 89 5C 24 ?? 55 56 57 48 83 EC 30 48 8B FA 41 8B E8 +;UUserDefinedEnum_GetDisplayNameTextByIndex_RESULT= UDataTable_HandleDataTableChanged=48 89 54 24 ?? 55 53 56 48 8D 6C 24 ?? 48 81 EC C0 00 00 00 ;UDataTable_HandleDataTableChanged_RESULT= diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_53-win64-shipping/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_53-win64-shipping/scans.ini index 85a86b9..b0e1d81 100644 --- a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_53-win64-shipping/scans.ini +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_53-win64-shipping/scans.ini @@ -31,8 +31,8 @@ GUObjectArray_RESULT=GetGlobalAddress(result + 2) UStruct_IsChildOf=48 85 D2 74 ?? 48 63 42 ?? 4C 8D 42 ;UStruct_IsChildOf_RESULT= -UEnum_GetDisplayNameTextByIndex=48 89 5C 24 ?? 55 56 57 48 83 EC 30 48 8B FA -;UEnum_GetDisplayNameTextByIndex_RESULT= +UUserDefinedEnum_GetDisplayNameTextByIndex=48 89 5C 24 ?? 55 56 57 48 83 EC 30 48 8B FA +;UUserDefinedEnum_GetDisplayNameTextByIndex_RESULT= UDataTable_HandleDataTableChanged=40 55 53 57 48 8D 6C 24 ?? 48 81 EC C0 00 00 00 8B 41 ;UDataTable_HandleDataTableChanged_RESULT= diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_55-win64-shipping/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_55-win64-shipping/scans.ini index cde343e..463e21c 100644 --- a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_55-win64-shipping/scans.ini +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_55-win64-shipping/scans.ini @@ -31,8 +31,8 @@ GUObjectArray_RESULT=GetGlobalAddress(result + 2) UStruct_IsChildOf=48 85 D2 74 ?? 48 63 42 ?? 4C 8D 42 ;UStruct_IsChildOf_RESULT= -UEnum_GetDisplayNameTextByIndex=48 89 5C 24 ?? 55 56 57 48 83 EC 30 48 8B FA -;UEnum_GetDisplayNameTextByIndex_RESULT= +UUserDefinedEnum_GetDisplayNameTextByIndex=48 89 5C 24 ?? 55 56 57 48 83 EC 30 48 8B FA +;UUserDefinedEnum_GetDisplayNameTextByIndex_RESULT= UDataTable_HandleDataTableChanged=40 55 53 57 48 8D 6C 24 ?? 48 81 EC C0 00 00 00 8B 41 ;UDataTable_HandleDataTableChanged_RESULT= diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_56-win64-shipping/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_56-win64-shipping/scans.ini index 8aae039..b390c11 100644 --- a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_56-win64-shipping/scans.ini +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_56-win64-shipping/scans.ini @@ -32,8 +32,8 @@ GUObjectArray_RESULT=GetGlobalAddress(result + 2) UStruct_IsChildOf=48 85 D2 74 ?? 48 63 42 ?? 4C 8D 42 ;UStruct_IsChildOf_RESULT= -UEnum_GetDisplayNameTextByIndex=48 89 5C 24 ?? 55 56 57 48 83 EC 30 48 8B FA -;UEnum_GetDisplayNameTextByIndex_RESULT= +UUserDefinedEnum_GetDisplayNameTextByIndex=48 89 5C 24 ?? 55 56 57 48 83 EC 30 48 8B FA +;UUserDefinedEnum_GetDisplayNameTextByIndex_RESULT= UDataTable_HandleDataTableChanged=48 89 54 24 ?? 55 53 56 48 8D 6C 24 ?? 48 81 EC C0 00 00 00 ;UDataTable_HandleDataTableChanged_RESULT= diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_57-win64-shipping/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_57-win64-shipping/scans.ini index aa82aa5..82bbc1c 100644 --- a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_57-win64-shipping/scans.ini +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_57-win64-shipping/scans.ini @@ -33,8 +33,8 @@ GUObjectArray_RESULT=GetGlobalAddress(result + 2) UStruct_IsChildOf=DISABLED ;UStruct_IsChildOf_RESULT= -UEnum_GetDisplayNameTextByIndex=48 89 5C 24 ?? 55 56 57 48 83 EC 30 48 8B FA -;UEnum_GetDisplayNameTextByIndex_RESULT= +UUserDefinedEnum_GetDisplayNameTextByIndex=48 89 5C 24 ?? 55 56 57 48 83 EC 30 48 8B FA +;UUserDefinedEnum_GetDisplayNameTextByIndex_RESULT= UDataTable_HandleDataTableChanged=40 55 53 56 48 8D 6C 24 ?? 48 81 EC 90 00 00 00 8B 41 ?? ;UDataTable_HandleDataTableChanged_RESULT= diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/p3r/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/p3r/scans.ini index 30494ee..94bf467 100644 --- a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/p3r/scans.ini +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/p3r/scans.ini @@ -27,8 +27,8 @@ GUObjectArray_RESULT=GetGlobalAddress(result + 3) - 0x10 UStruct_IsChildOf=DISABLED ;UStruct_IsChildOf_RESULT= -UEnum_GetDisplayNameTextByIndex=48 89 5C 24 ?? 55 56 57 48 83 EC 30 48 8B FA 41 8B E8 -;UEnum_GetDisplayNameTextByIndex_RESULT= +UUserDefinedEnum_GetDisplayNameTextByIndex=48 89 5C 24 ?? 55 56 57 48 83 EC 30 48 8B FA 41 8B E8 +;UUserDefinedEnum_GetDisplayNameTextByIndex_RESULT= UDataTable_HandleDataTableChanged=48 89 54 24 ?? 55 53 56 57 48 8D 6C 24 ?? 48 81 EC 98 00 00 00 ;UDataTable_HandleDataTableChanged_RESULT= diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/scans.ini index 6c56137..d688a28 100644 --- a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/scans.ini +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/scans.ini @@ -28,8 +28,8 @@ GUObjectArray_RESULT=GetGlobalAddress(result + 2) UStruct_IsChildOf=48 85 D2 74 ?? 48 63 42 ?? 4C 8D 42 ;UStruct_IsChildOf_RESULT= -UEnum_GetDisplayNameTextByIndex=48 89 5C 24 ?? 55 56 57 48 83 EC 30 48 8B FA -;UEnum_GetDisplayNameTextByIndex_RESULT= +UUserDefinedEnum_GetDisplayNameTextByIndex=48 89 5C 24 ?? 55 56 57 48 83 EC 30 48 8B FA +;UUserDefinedEnum_GetDisplayNameTextByIndex_RESULT= UDataTable_HandleDataTableChanged=40 55 53 57 48 8D 6C 24 ?? 48 81 EC C0 00 00 00 8B 41 ;UDataTable_HandleDataTableChanged_RESULT= diff --git a/UE.Toolkit.Reloaded/Unreal/UnrealStrings.cs b/UE.Toolkit.Reloaded/Unreal/UnrealStrings.cs index 4a951eb..4e4a6f8 100644 --- a/UE.Toolkit.Reloaded/Unreal/UnrealStrings.cs +++ b/UE.Toolkit.Reloaded/Unreal/UnrealStrings.cs @@ -3,6 +3,7 @@ using System.Text; using UE.Toolkit.Core.Types.Unreal.UE5_4_4; using UE.Toolkit.Interfaces; +using UE.Toolkit.Reloaded.Common.GameConfigs; // ReSharper disable InconsistentNaming @@ -16,8 +17,8 @@ public unsafe class UnrealStrings : IUnrealStrings private delegate byte FTextInspector_GetTableIdAndKey(FText* text, FName* tableId, FString* key); private readonly SHFunction _FTextInspector_GetTableIdAndKey = new(); - private delegate FText* UEnum_GetDisplayNameTextByIndex(UUserDefinedEnum* userEnum, FText* outName, int index); - private readonly SHFunction _getDispNameTextByIdx = new(); + private delegate FText* UUserDefinedEnum_GetDisplayNameTextByIndex(UUserDefinedEnum* userEnum, FText* outName, int index); + private readonly SHFunction _getDispNameTextByIdx = new(); public bool FTextInspectorGetTableIdAndKey(FText* text, [NotNullWhen(true)]out string? tableId, [NotNullWhen(true)]out string? key) { @@ -43,7 +44,7 @@ public bool FTextInspectorGetTableIdAndKey(FText* text, [NotNullWhen(true)]out s public string UEnumGetDisplayNameTextByIndex(nint userEnum, int index) { - var outText = (FText*)Marshal.AllocHGlobal(sizeof(FText)); + var outText = (FText*)Marshal.AllocHGlobal(GameConfig.GetFTextSize()); var dispNameFText = _getDispNameTextByIdx.Wrapper((UUserDefinedEnum*)userEnum, outText, index); From 96e4781d1fff491acc1564417829eabcb6964349 Mon Sep 17 00:00:00 2001 From: Rirurin Date: Tue, 30 Jun 2026 15:37:02 +0800 Subject: [PATCH 3/7] Custom Constructor + Add Properties support, fix linked properties attaching to super type --- README.md | 6 +- .../Types/Unreal/UE5_6_1/FStructProperty.cs | 11 + .../Types/Unreal/UE5_7_4/FField.cs | 16 ++ .../Types/Unreal/UE5_7_4/FStructProperty.cs | 11 + .../Types/Unreal/UE5_7_4/UScriptStruct.cs | 13 ++ .../Types/Unreal/UE5_7_4/UStruct.cs | 21 ++ .../chronos-win64-shipping/unreal.ini | 2 +- .../iostoretest_50-win64-shipping/scans.ini | 2 +- .../iostoretest_50-win64-shipping/unreal.ini | 4 +- .../iostoretest_51-win64-shipping/scans.ini | 2 +- .../iostoretest_51-win64-shipping/unreal.ini | 4 +- .../iostoretest_52-win64-shipping/scans.ini | 2 +- .../iostoretest_52-win64-shipping/unreal.ini | 2 +- .../iostoretest_53-win64-shipping/scans.ini | 2 +- .../iostoretest_53-win64-shipping/unreal.ini | 2 +- .../iostoretest_54-win64-shipping/scans.ini | 61 +++++ .../iostoretest_54-win64-shipping/unreal.ini | 20 ++ .../iostoretest_55-win64-shipping/unreal.ini | 2 +- .../iostoretest_56-win64-shipping/unreal.ini | 2 +- .../iostoretest_57-win64-shipping/unreal.ini | 2 +- .../Project/UE.Toolkit.Reloaded/p3r/scans.ini | 2 + .../Reflection/PropertyFactory.cs | 18 +- .../Reflection/UE4_27_2/PropertyFactory.cs | 2 +- .../Reflection/UE5_2_1/PropertyFactory.cs | 208 +++++++++++++++++ .../UE5_2_1/PropertyFlagsBuilder.cs | 23 ++ .../Reflection/UE5_2_1/TypeFactory.cs | 77 +++++++ .../Reflection/UE5_4_4/PropertyFactory.cs | 3 +- .../Reflection/UE5_6_1/PropertyFactory.cs | 210 +++++++++++++++++ .../UE5_6_1/PropertyFlagsBuilder.cs | 23 ++ .../Reflection/UE5_6_1/TypeFactory.cs | 77 +++++++ .../Reflection/UE5_7_4/PropertyFactory.cs | 212 ++++++++++++++++++ .../UE5_7_4/PropertyFlagsBuilder.cs | 23 ++ .../Reflection/UE5_7_4/TypeFactory.cs | 77 +++++++ UE.Toolkit.Reloaded/Unreal/UnrealClasses.cs | 12 +- 34 files changed, 1125 insertions(+), 29 deletions(-) create mode 100644 UE.Toolkit.Core/Types/Unreal/UE5_6_1/FStructProperty.cs create mode 100644 UE.Toolkit.Core/Types/Unreal/UE5_7_4/FField.cs create mode 100644 UE.Toolkit.Core/Types/Unreal/UE5_7_4/FStructProperty.cs create mode 100644 UE.Toolkit.Core/Types/Unreal/UE5_7_4/UScriptStruct.cs create mode 100644 UE.Toolkit.Core/Types/Unreal/UE5_7_4/UStruct.cs create mode 100644 UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_54-win64-shipping/scans.ini create mode 100644 UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_54-win64-shipping/unreal.ini create mode 100644 UE.Toolkit.Reloaded/Reflection/UE5_2_1/PropertyFactory.cs create mode 100644 UE.Toolkit.Reloaded/Reflection/UE5_2_1/PropertyFlagsBuilder.cs create mode 100644 UE.Toolkit.Reloaded/Reflection/UE5_2_1/TypeFactory.cs create mode 100644 UE.Toolkit.Reloaded/Reflection/UE5_6_1/PropertyFactory.cs create mode 100644 UE.Toolkit.Reloaded/Reflection/UE5_6_1/PropertyFlagsBuilder.cs create mode 100644 UE.Toolkit.Reloaded/Reflection/UE5_6_1/TypeFactory.cs create mode 100644 UE.Toolkit.Reloaded/Reflection/UE5_7_4/PropertyFactory.cs create mode 100644 UE.Toolkit.Reloaded/Reflection/UE5_7_4/PropertyFlagsBuilder.cs create mode 100644 UE.Toolkit.Reloaded/Reflection/UE5_7_4/TypeFactory.cs diff --git a/README.md b/README.md index 9a90e2c..a387da4 100644 --- a/README.md +++ b/README.md @@ -31,9 +31,9 @@ Object XML requires game-specific support with an extension mod. Supported games | Property Editing (Object XML) |✅|❔|❔|❔|❔|✅|❔|❔|❔ | Add List Entry (Object XML) |✅|❔|❔|❔|❔|❔|❔|❔|❔ | Add Map Entry (Object XML) |✅|❔|❔|❔|❔|❔|❔|❔|❔ -| Type Information |✅|❔|❔|❔|❔|✅|❔|❔|❔ -| Custom Constructor |✅|❔|❔|❔|❔|❔|❔|❔|❔ -| Add Properties |✅|❔|❔|❔|❔|❌|❔|❔|❔ +| Type Information |✅|✅|✅|✅|✅|✅|✅|✅|✅ +| Custom Constructor |✅|✅|✅|✅|✅|✅|✅|✅|✅ +| Add Properties |✅|⚠️|⚠️|⚠️|✅|✅|✅|✅|✅ | Register Struct |✅|❔|❔|❔|❔|❌|❔|❔|❔ Features marked with ❔ are currently untested. diff --git a/UE.Toolkit.Core/Types/Unreal/UE5_6_1/FStructProperty.cs b/UE.Toolkit.Core/Types/Unreal/UE5_6_1/FStructProperty.cs new file mode 100644 index 0000000..bbc1a6c --- /dev/null +++ b/UE.Toolkit.Core/Types/Unreal/UE5_6_1/FStructProperty.cs @@ -0,0 +1,11 @@ +using System.Runtime.InteropServices; +using UE.Toolkit.Core.Types.Unreal.UE5_4_4; + +namespace UE.Toolkit.Core.Types.Unreal.UE5_6_1; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct FStructProperty +{ + public FProperty Super; + public UScriptStruct* Struct; +} \ No newline at end of file diff --git a/UE.Toolkit.Core/Types/Unreal/UE5_7_4/FField.cs b/UE.Toolkit.Core/Types/Unreal/UE5_7_4/FField.cs new file mode 100644 index 0000000..f8ebf22 --- /dev/null +++ b/UE.Toolkit.Core/Types/Unreal/UE5_7_4/FField.cs @@ -0,0 +1,16 @@ +using System.Runtime.InteropServices; +using UE.Toolkit.Core.Types.Unreal.UE5_4_4; + +namespace UE.Toolkit.Core.Types.Unreal.UE5_7_4; + +[StructLayout(LayoutKind.Sequential, Pack = 8)] +public unsafe struct FField +{ + public nint VTable; + public FFieldClass* ClassPrivate; + public FFieldObjectUnion Owner; // May be garbage? The following fields are correctly placed, + // but within a UserDefinedStruct this field is random data (not null). + public FField* Next; + public FName NamePrivate; + public EObjectFlags FlagsPrivate; +} \ No newline at end of file diff --git a/UE.Toolkit.Core/Types/Unreal/UE5_7_4/FStructProperty.cs b/UE.Toolkit.Core/Types/Unreal/UE5_7_4/FStructProperty.cs new file mode 100644 index 0000000..7d62087 --- /dev/null +++ b/UE.Toolkit.Core/Types/Unreal/UE5_7_4/FStructProperty.cs @@ -0,0 +1,11 @@ +using System.Runtime.InteropServices; +using UE.Toolkit.Core.Types.Unreal.UE5_4_4; + +namespace UE.Toolkit.Core.Types.Unreal.UE5_7_4; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct FStructProperty +{ + public FProperty Super; + public UScriptStruct* Struct; +} \ No newline at end of file diff --git a/UE.Toolkit.Core/Types/Unreal/UE5_7_4/UScriptStruct.cs b/UE.Toolkit.Core/Types/Unreal/UE5_7_4/UScriptStruct.cs new file mode 100644 index 0000000..0c1855e --- /dev/null +++ b/UE.Toolkit.Core/Types/Unreal/UE5_7_4/UScriptStruct.cs @@ -0,0 +1,13 @@ +using System.Runtime.InteropServices; +using UE.Toolkit.Core.Types.Unreal.UE5_4_4; + +namespace UE.Toolkit.Core.Types.Unreal.UE5_7_4; + +[StructLayout(LayoutKind.Sequential, Size = 0xC0)] +public struct UScriptStruct +{ + public UStruct Super; + public EStructFlags StructFlags; + public bool bPrepareCppStructOpsCompleted; + public nint CppStructOps; +} \ No newline at end of file diff --git a/UE.Toolkit.Core/Types/Unreal/UE5_7_4/UStruct.cs b/UE.Toolkit.Core/Types/Unreal/UE5_7_4/UStruct.cs new file mode 100644 index 0000000..d30526f --- /dev/null +++ b/UE.Toolkit.Core/Types/Unreal/UE5_7_4/UStruct.cs @@ -0,0 +1,21 @@ +using System.Runtime.InteropServices; +using UE.Toolkit.Core.Types.Unreal.UE5_4_4; + +namespace UE.Toolkit.Core.Types.Unreal.UE5_7_4; + +[StructLayout(LayoutKind.Explicit, Size = 0xb0, Pack = 8)] +public unsafe struct UStruct +{ + [FieldOffset(0x0)] public UField _super; + [FieldOffset(0x40)] public UStruct* SuperStruct; // ObjectPtr_Private::TNonAccessTrackedObjectPtr (sizeof = 0x8) + [FieldOffset(0x48)] public UField* Children; // anything not a type field (e.g a class method) - beginning of linked list + [FieldOffset(0x50)] public FField* ChildProperties; // the data model - beginning of linked list + [FieldOffset(0x58)] public int PropertiesSize; + [FieldOffset(0x5c)] public short MinAlignment; + [FieldOffset(0x5e)] public short StructStateFlags; // std::atomic + [FieldOffset(0x60)] public TArray Script; + [FieldOffset(0x70)] public FProperty* PropertyLink; + [FieldOffset(0x78)] public FProperty* RefLink; + [FieldOffset(0x80)] public FProperty* DestructorLink; + [FieldOffset(0x88)] public FProperty* PostConstructLink; +} \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/chronos-win64-shipping/unreal.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/chronos-win64-shipping/unreal.ini index 13d35c1..99fd744 100644 --- a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/chronos-win64-shipping/unreal.ini +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/chronos-win64-shipping/unreal.ini @@ -14,7 +14,7 @@ ProcessEvent=0x268 GetCustomGuid=0x378 [UPackage] -GamePackage=/Script/SandFall +GamePackage=/Script/Chronos [UStruct] Link=0x2d0 \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_50-win64-shipping/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_50-win64-shipping/scans.ini index 9f84289..499f404 100644 --- a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_50-win64-shipping/scans.ini +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_50-win64-shipping/scans.ini @@ -47,7 +47,7 @@ FTextInspector_GetTableIdAndKey=48 89 5C 24 ?? 48 89 74 24 ?? 41 56 48 83 EC 30 GetPrivateStaticClassBody_UE4=DISABLED ;GetPrivateStaticClassBody_RESULT= -GetPrivateStaticClassBody_UE5=48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 54 41 55 41 56 41 57 48 83 EC 60 45 33 ED +GetPrivateStaticClassBody_UE5=48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 54 41 55 41 56 41 57 48 83 EC 30 4D 8B E1 ;GetPrivateStaticClassBody_RESULT= StaticConstructObject_Internal=4C 8B DC 49 89 5B ?? 49 89 73 ?? 55 57 41 54 41 56 41 57 49 8D AB ?? ?? ?? ?? diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_50-win64-shipping/unreal.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_50-win64-shipping/unreal.ini index bad97ad..071aafa 100644 --- a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_50-win64-shipping/unreal.ini +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_50-win64-shipping/unreal.ini @@ -14,7 +14,7 @@ ProcessEvent=0x268 GetCustomGuid=0x378 [UPackage] -GamePackage=/Script/SandFall +GamePackage=/Script/IOStoreTest_50 [UStruct] -Link=0x2d0 \ No newline at end of file +Link=0x2c0 \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_51-win64-shipping/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_51-win64-shipping/scans.ini index d57c0f1..dddc343 100644 --- a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_51-win64-shipping/scans.ini +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_51-win64-shipping/scans.ini @@ -46,7 +46,7 @@ FTextInspector_GetTableIdAndKey=48 89 5C 24 ?? 48 89 74 24 ?? 41 56 48 83 EC 30 GetPrivateStaticClassBody_UE4=DISABLED ;GetPrivateStaticClassBody_RESULT= -GetPrivateStaticClassBody_UE5=48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 54 41 55 41 56 41 57 48 83 EC 60 45 33 ED +GetPrivateStaticClassBody_UE5=48 89 5C 24 ?? 48 89 6C 24 ?? 56 57 41 54 41 56 41 57 48 83 EC 30 4D 8B F1 ;GetPrivateStaticClassBody_RESULT= StaticConstructObject_Internal=4C 8B DC 49 89 5B ?? 49 89 73 ?? 55 57 41 54 41 56 41 57 49 8D AB ?? ?? ?? ?? diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_51-win64-shipping/unreal.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_51-win64-shipping/unreal.ini index 94609dc..dd33289 100644 --- a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_51-win64-shipping/unreal.ini +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_51-win64-shipping/unreal.ini @@ -14,7 +14,7 @@ ProcessEvent=0x268 GetCustomGuid=0x378 [UPackage] -GamePackage=/Script/SandFall +GamePackage=/Script/IOStoreTest_51 [UStruct] -Link=0x2d0 \ No newline at end of file +Link=0x2c8 \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_52-win64-shipping/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_52-win64-shipping/scans.ini index 8911883..01f3672 100644 --- a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_52-win64-shipping/scans.ini +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_52-win64-shipping/scans.ini @@ -45,7 +45,7 @@ FTextInspector_GetTableIdAndKey=48 89 5C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 41 GetPrivateStaticClassBody_UE4=DISABLED ;GetPrivateStaticClassBody_RESULT= -GetPrivateStaticClassBody_UE5=48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 54 41 55 41 56 41 57 48 83 EC 60 45 33 ED +GetPrivateStaticClassBody_UE5=48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 56 41 57 48 83 EC 30 4D 8B F1 ;GetPrivateStaticClassBody_RESULT= StaticConstructObject_Internal=4C 8B DC 49 89 5B ?? 49 89 73 ?? 55 57 41 54 41 56 41 57 49 8D AB ?? ?? ?? ?? diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_52-win64-shipping/unreal.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_52-win64-shipping/unreal.ini index 13d35c1..1a1ed15 100644 --- a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_52-win64-shipping/unreal.ini +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_52-win64-shipping/unreal.ini @@ -14,7 +14,7 @@ ProcessEvent=0x268 GetCustomGuid=0x378 [UPackage] -GamePackage=/Script/SandFall +GamePackage=/Script/IOStoreTest_52 [UStruct] Link=0x2d0 \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_53-win64-shipping/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_53-win64-shipping/scans.ini index b0e1d81..04669a9 100644 --- a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_53-win64-shipping/scans.ini +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_53-win64-shipping/scans.ini @@ -45,7 +45,7 @@ FTextInspector_GetTableIdAndKey=48 89 5C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 41 GetPrivateStaticClassBody_UE4=DISABLED ;GetPrivateStaticClassBody_RESULT= -GetPrivateStaticClassBody_UE5=48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 54 41 55 41 56 41 57 48 83 EC 60 45 33 ED +GetPrivateStaticClassBody_UE5=48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 56 41 57 48 83 EC 30 4D 8B F1 49 8B F8 ;GetPrivateStaticClassBody_RESULT= StaticConstructObject_Internal=4C 8B DC 49 89 5B ?? 49 89 73 ?? 55 57 41 54 41 56 41 57 49 8D AB ?? ?? ?? ?? diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_53-win64-shipping/unreal.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_53-win64-shipping/unreal.ini index ccff884..ed25bce 100644 --- a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_53-win64-shipping/unreal.ini +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_53-win64-shipping/unreal.ini @@ -14,7 +14,7 @@ ProcessEvent=0x268 GetCustomGuid=0x378 [UPackage] -GamePackage=/Script/SandFall +GamePackage=/Script/IOStoreTest_53 [UStruct] Link=0x2d0 \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_54-win64-shipping/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_54-win64-shipping/scans.ini new file mode 100644 index 0000000..a4527d5 --- /dev/null +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_54-win64-shipping/scans.ini @@ -0,0 +1,61 @@ +;Based on Clair Obscur, except for GetPrivateStatiClassBody (UE 5.4.4) + +[Scans] +GFNamePool=48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 4C 8B C0 C6 05 ?? ?? ?? ?? 01 8B D3 0F B7 C3 89 44 24 +GFNamePool_RESULT=GetGlobalAddress(result + 3) + +;FNameHelper_FindOrStoreString=48 89 74 24 ?? 57 48 83 EC 60 81 79 ?? 00 04 00 00 +;FNameHelper_FindOrStoreString_RESULT= + +FName_Ctor_Wide=48 89 5C 24 ?? 57 48 83 EC 30 48 8B D9 41 8B F8 +;FName_Ctor_Wide_RESULT= + +FText_FromString=48 89 5C 24 ?? 57 48 83 EC 40 83 7A ?? 01 48 8B D9 48 89 74 24 ?? 4C 89 74 24 ?? C7 44 24 ?? 00 00 00 00 7F ?? E8 ?? ?? ?? ?? 48 8B F0 48 8B 38 48 89 7C 24 ?? 48 85 FF 74 ?? 48 8B 17 48 8B CF FF 52 ?? 8B 46 ?? 4C 8D 74 24 ?? 89 44 24 ?? BE 01 00 00 00 48 8B CF EB ?? 48 8D 4C 24 ?? E8 ?? ?? ?? ?? 48 8B 7C 24 ?? 4C 8B F0 BE 02 00 00 00 48 8B 08 48 89 0B 48 85 C9 74 ?? 48 8B 11 FF 52 ?? 41 8B 46 ?? 4C 8B 74 24 ?? 89 43 ?? 40 F6 C6 02 74 ?? 48 8B 4C 24 ?? 83 E6 FD 48 85 C9 74 ?? 48 8B 01 FF 50 ?? 40 F6 C6 01 48 8B 74 24 ?? 74 ?? 48 85 FF 74 ?? 48 8B 07 48 8B CF FF 50 ?? 83 4B ?? 12 +;FText_FromString_RESULT= + +FText_ToString=40 53 48 83 EC 20 48 8B D9 E8 ?? ?? ?? ?? 48 8B 0B 48 8B 01 48 83 C4 20 +;FText_ToString_RESULT= + +UObject_PostLoadSubobjects=40 55 53 41 56 48 8D AC 24 ?? ?? ?? ?? 48 81 EC 10 02 00 00 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 85 ?? ?? ?? ?? 48 8B 41 +;UObject_PostLoadSubobjects_RESULT= + +UObject_BeginDestroy=40 53 48 83 EC 30 8B 41 ?? 48 8B D9 C1 E8 0F +;UObject_BeginDestroy_RESULT= + +GUObjectArray=2B 05 ?? ?? ?? ?? 44 89 05 +GUObjectArray_RESULT=GetGlobalAddress(result + 2) + +UStruct_IsChildOf=48 85 D2 74 ?? 48 63 42 ?? 4C 8D 42 +;UStruct_IsChildOf_RESULT= + +UUserDefinedEnum_GetDisplayNameTextByIndex=48 89 5C 24 ?? 55 56 57 48 83 EC 30 48 8B FA +;UUserDefinedEnum_GetDisplayNameTextByIndex_RESULT= + +UDataTable_HandleDataTableChanged=40 55 53 57 48 8D 6C 24 ?? 48 81 EC C0 00 00 00 8B 41 +;UDataTable_HandleDataTableChanged_RESULT= + +GMalloc=48 8B 0D ?? ?? ?? ?? 48 85 C9 75 ?? E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? 48 8B 01 48 8B D3 FF 50 ?? 48 83 C4 20 +GMalloc_RESULT=GetGlobalAddress(result + 3) + +FTextInspector_GetTableIdAndKey=48 89 5C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 41 56 48 83 EC 30 48 8B F9 48 8D 1D + +GetPrivateStaticClassBody_UE4=DISABLED +;GetPrivateStaticClassBody_RESULT= + +GetPrivateStaticClassBody_UE5=48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 56 41 57 48 83 EC 30 4D 8B F1 49 8B F8 +;GetPrivateStaticClassBody_RESULT= + +StaticConstructObject_Internal=4C 8B DC 49 89 5B ?? 49 89 73 ?? 55 57 41 54 41 56 41 57 49 8D AB ?? ?? ?? ?? +;StaticConstructObject_Internal_RESULT= + +GetStaticStruct=48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 50 49 8B E8 48 8B DA FF D1 48 8B F0 90 48 83 7B ?? 00 48 8D 7B ?? 74 ?? 8B 43 ?? 33 C9 0F BA E0 1C 73 ?? 48 8B CB E8 ?? ?? ?? ?? 48 8B C8 48 8B D9 48 85 DB 75 ?? 48 8B 1F EB ?? 48 8B 43 ?? 48 8D 54 24 ?? 48 8D 4C 24 ?? 48 89 44 24 ?? E8 ?? ?? ?? ?? 83 7C 24 ?? 00 48 8D 0D ?? ?? ?? ?? 41 B9 02 00 00 00 48 89 74 24 ?? 48 0F 45 4C 24 ?? 45 8B C1 +;GetStaticStruct_RESULT= + +ConstructUScriptStruct=40 53 56 57 41 54 41 55 41 56 48 81 EC 98 03 00 00 +;ConstructUScriptStruct + +GEngine=48 89 05 ?? ?? ?? ?? 48 85 C9 74 ?? E8 ?? ?? ?? ?? 48 8D 4D ?? +GEngine_RESULT=GetGlobalAddress(result + 3) + +UWorld_SpawnActor=40 55 53 56 57 41 54 41 55 41 56 41 57 48 8D AC 24 ?? ?? ?? ?? 48 81 EC A8 04 00 00 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 85 ?? ?? ?? ?? 33 C0 +;UWorld_SpawnActor_RESULT= \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_54-win64-shipping/unreal.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_54-win64-shipping/unreal.ini new file mode 100644 index 0000000..77d1201 --- /dev/null +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_54-win64-shipping/unreal.ini @@ -0,0 +1,20 @@ +;Based on Clair Obscur (UE 5.4.4) + +[FMallocBinned2] +Free=0x48 +GetAllocSize=0x58 +Malloc=0x28 +Realloc=0x38 +QuantizeSize=0x50 + +[UObject] +ProcessEvent=0x268 + +[UScriptStruct] +GetCustomGuid=0x378 + +[UPackage] +GamePackage=/Script/IOStoreTest_54 + +[UStruct] +Link=0x2d0 \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_55-win64-shipping/unreal.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_55-win64-shipping/unreal.ini index 3e002b0..f0a1ad4 100644 --- a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_55-win64-shipping/unreal.ini +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_55-win64-shipping/unreal.ini @@ -14,7 +14,7 @@ ProcessEvent=0x268 GetCustomGuid=0x378 [UPackage] -GamePackage=/Script/SandFall +GamePackage=/Script/IOStoreTest_55 [UStruct] Link=0x2e0 \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_56-win64-shipping/unreal.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_56-win64-shipping/unreal.ini index 9730976..15a830b 100644 --- a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_56-win64-shipping/unreal.ini +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_56-win64-shipping/unreal.ini @@ -14,7 +14,7 @@ ProcessEvent=0x268 GetCustomGuid=0x378 [UPackage] -GamePackage=/Script/SandFall +GamePackage=/Script/IOStoreTest_56 [UStruct] Link=0x2c8 \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_57-win64-shipping/unreal.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_57-win64-shipping/unreal.ini index 623c523..887d641 100644 --- a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_57-win64-shipping/unreal.ini +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_57-win64-shipping/unreal.ini @@ -14,7 +14,7 @@ ProcessEvent=0x268 GetCustomGuid=0x378 [UPackage] -GamePackage=/Script/SandFall +GamePackage=/Script/IOStoreTest_57 [UStruct] Link=0x2c8 \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/p3r/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/p3r/scans.ini index 94bf467..730277f 100644 --- a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/p3r/scans.ini +++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/p3r/scans.ini @@ -36,6 +36,8 @@ UDataTable_HandleDataTableChanged=48 89 54 24 ?? 55 53 56 57 48 8D 6C 24 ?? 48 8 ;GMalloc= ;GMalloc_RESULT= +FTextInspector_GetTableIdAndKey=48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B D9 49 8B F8 48 8B 09 48 8B F2 48 8B 01 + GetPrivateStaticClassBody_UE4=48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 54 41 55 41 56 41 57 48 83 EC 60 45 33 ED ;GetPrivateStaticClassBody_RESULT= diff --git a/UE.Toolkit.Reloaded/Reflection/PropertyFactory.cs b/UE.Toolkit.Reloaded/Reflection/PropertyFactory.cs index 76d1b57..af15891 100644 --- a/UE.Toolkit.Reloaded/Reflection/PropertyFactory.cs +++ b/UE.Toolkit.Reloaded/Reflection/PropertyFactory.cs @@ -144,18 +144,20 @@ protected bool CreateBoolPropertyInner(out IFBoolProperty? NewProperty, protected IFProperty GetPreviousProperty(IFProperty Property, IUClass Reflect) { IFProperty? TargetProp = null; + var MinimumOffset = Reflect.SuperStruct?.PropertiesSize ?? 0; foreach (var Prop in Reflect.PropertyLink) { - if (!Prop.PropertyLinkNext.Any()) + // We're the last element in the chain + var StopConditions = !Prop.PropertyLinkNext.Any() || + // The next element will have a larger offset than our new field, so insert before them + Prop.PropertyLinkNext.First().Offset_Internal > Property.Offset_Internal || + // The next element is from the super class, stop since the property chain of a supertype + // is shared between it and all subtypes + Prop.PropertyLinkNext.First().Offset_Internal < MinimumOffset; + if (StopConditions) { - // We're the last element in the chain TargetProp = Prop; - } - else if (Prop.PropertyLinkNext.First().Offset_Internal > Property.Offset_Internal) - { - // The next element will have a larger offset than our new field, so insert before them - TargetProp = Prop; - break; + break; } } return TargetProp!; diff --git a/UE.Toolkit.Reloaded/Reflection/UE4_27_2/PropertyFactory.cs b/UE.Toolkit.Reloaded/Reflection/UE4_27_2/PropertyFactory.cs index e593680..5218a63 100644 --- a/UE.Toolkit.Reloaded/Reflection/UE4_27_2/PropertyFactory.cs +++ b/UE.Toolkit.Reloaded/Reflection/UE4_27_2/PropertyFactory.cs @@ -186,7 +186,7 @@ public override bool CreateName(out IFProperty? NewProperty, string Name => CreateCopyPropertyInner(out NewProperty, Name, Offset, "NameProperty", Visibility); public override bool CreateString(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) - => CreateStringPropertyInner(out NewProperty, Name, Offset, "StringProperty", Visibility); + => CreateStringPropertyInner(out NewProperty, Name, Offset, "StrProperty", Visibility); public override bool CreateText(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) => CreateTextPropertyInner(out NewProperty, Name, Offset, "TextProperty", Visibility); diff --git a/UE.Toolkit.Reloaded/Reflection/UE5_2_1/PropertyFactory.cs b/UE.Toolkit.Reloaded/Reflection/UE5_2_1/PropertyFactory.cs new file mode 100644 index 0000000..fbb9850 --- /dev/null +++ b/UE.Toolkit.Reloaded/Reflection/UE5_2_1/PropertyFactory.cs @@ -0,0 +1,208 @@ +using System.Runtime.InteropServices; +using UE.Toolkit.Core.Types.Interfaces; +using UE.Toolkit.Core.Types.Unreal.Factories; +using UE.Toolkit.Core.Types.Unreal.Factories.Interfaces; +using UE.Toolkit.Core.Types.Unreal.UE5_4_4; +using UE.Toolkit.Interfaces; + +using FProperty = UE.Toolkit.Core.Types.Unreal.UE4_27_2.FProperty; + +namespace UE.Toolkit.Reloaded.Reflection.UE5_2_1; + +public class PropertyFactory(IUnrealFactory factory, IUnrealMemory memory, + IUnrealClasses classes, IPropertyFlagsBuilder flags) + : BasePropertyFactory(factory, memory, classes, flags) +{ + + protected override unsafe void LinkToPropertyList(IFProperty Property, IUClass Reflect) + { + var pProperty = (FProperty*)Property.Ptr; + pProperty->prop_link_next = null; + pProperty->next_ref = null; + pProperty->dtor_link_next = null; + pProperty->post_ct_link_next = null; + + var pClass = (UClass*)Reflect.Ptr; + if (((UStruct*)pClass)->PropertyLink == null) + { + ((UStruct*)pClass)->PropertyLink = (UE.Toolkit.Core.Types.Unreal.UE5_4_4.FProperty*)pProperty; + ((UStruct*)pClass)->ChildProperties = (FField*)pProperty; + } + else + { + var TargetProp = GetPreviousProperty(Property, Reflect); + var NextProp = TargetProp.PropertyLinkNext.Any() ? TargetProp.PropertyLinkNext.First() : null; + var pTargetProp = (FProperty*)TargetProp.Ptr; + pTargetProp->prop_link_next = pProperty; + ((FField*)pTargetProp)->Next = (FField*)pProperty; + if (NextProp != null) + { + var pNextProp = (FProperty*)NextProp.Ptr; + pProperty->prop_link_next = pNextProp; + ((FField*)pProperty)->Next = (FField*)pNextProp; + } + } + } + + protected override unsafe void SetPropertySuperFields(IFField Field, string Name, IUClass ClassReflection, + FieldClassGlobal PropertyClass) + { + var pField = (FField*)Field.Ptr; + pField->VTable = PropertyClass.Vtable; + pField->ClassPrivate = (FFieldClass*)PropertyClass.Params.Ptr; + pField->Owner.Object = (UObjectBase*)ClassReflection.Ptr; // UClass* + pField->Next = null; + pField->NamePrivate = new FName(Name); + pField->FlagsPrivate = EObjectFlags.RF_Public | EObjectFlags.RF_MarkAsNative | EObjectFlags.RF_Transient; + } + + private unsafe void SetPropertyFieldDefaults(FProperty* pProperty, int Offset) + { + pProperty->rep_index = 0; + pProperty->blueprint_rep_cond = 0; + pProperty->offset_internal = Offset; + } + + private unsafe void SetPropertyFieldsInner(IFProperty Property, int Offset, + PropertyVisibility Visibility, PropertyBuilderFlags PropertyFlags) + { + var pProperty = (FProperty*)Property.Ptr; + pProperty->array_dim = 1; + pProperty->element_size = Marshal.SizeOf(); + pProperty->property_flags = Flags.CreatePropertyFlags(Visibility, PropertyFlags); + SetPropertyFieldDefaults(pProperty, Offset); + } + + protected override unsafe void SetCopyPropertyFields(IFProperty Property, int Offset, + PropertyVisibility Visibility) + { + var PropertyFlags = PropertyBuilderFlags.NoCtor | PropertyBuilderFlags.Copy | PropertyBuilderFlags.NoDtor; + SetPropertyFieldsInner(Property, Offset, Visibility, PropertyFlags); + } + + protected override void SetStringPropertyFields(IFProperty Property, int Offset, + PropertyVisibility Visibility) + => SetPropertyFieldsInner(Property, Offset, Visibility, PropertyBuilderFlags.NoCtor); + + protected override void SetTextPropertyFields(IFProperty Property, int Offset, + PropertyVisibility Visibility) + => SetPropertyFieldsInner(Property, Offset, Visibility, PropertyBuilderFlags.None); + + protected override unsafe void SetBoolPropertyFields(IFBoolProperty Property, BooleanMask Mask) + { + var pBoolProperty = (FBoolProperty*)Property.Ptr; + pBoolProperty->FieldSize = (byte)Marshal.SizeOf(); + pBoolProperty->ByteOffset = 0; + pBoolProperty->ByteMask = Mask.ByteMask; + pBoolProperty->FieldMask = Mask.FieldMask; + } + + public override bool CreateI8(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "Int8Property", Visibility); + + public override bool CreateI16(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "Int16Property", Visibility); + + public override bool CreateI32(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "IntProperty", Visibility); + + public override bool CreateI64(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "Int64Property", Visibility); + + public override bool CreateU8(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "UInt8Property", Visibility); + + public override bool CreateU16(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "UInt16Property", Visibility); + + public override bool CreateU32(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "UInt32Property", Visibility); + + public override bool CreateU64(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "UInt64Property", Visibility); + + public override bool CreateF32(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "FFloatProperty", Visibility); + + public override bool CreateF64(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "FDoubleProperty", Visibility); + + public override bool CreateStruct(out IFStructProperty? NewProperty, string Name, int Offset, + PropertyVisibility Visibility) + { + NewProperty = null; + if (!TryGetClassAndProperty("StructProperty", out var ClassReflection, out var PropertyClass) + || !Classes.GetScriptStructInfoFromType(out var ScriptStruct)) + return false; + var Alloc = Memory.Malloc(Marshal.SizeOf(), FIELD_ALIGNMENT); + NewProperty = Factory.CreateFStructProperty(Alloc); + SetPropertySuperFields(Factory.CreateFField(Alloc), Name, ClassReflection!, PropertyClass!); + unsafe + { + var pProperty = (FProperty*)Alloc; + pProperty->array_dim = 1; + pProperty->element_size = ScriptStruct!.PropertiesSize; // FExampleStruct mExampleField; + pProperty->property_flags = Flags.CreatePropertyFlags(Visibility, PropertyBuilderFlags.None); + SetPropertyFieldDefaults(pProperty, Offset); + } + LinkToPropertyList(NewProperty, ClassReflection!); + unsafe { ((FStructProperty*)NewProperty.Ptr)->Struct = (UScriptStruct*)ScriptStruct.Ptr; } + return true; + } + + public override bool CreateObject(out IFObjectProperty? NewProperty, string Name, int Offset, + PropertyVisibility Visibility) + { + NewProperty = null; + if (!TryGetClassAndProperty("ObjectProperty", out var ClassReflection, out var PropertyClass) + || !Classes.GetClassInfoFromClass(out var FieldClass)) + return false; + var Alloc = Memory.Malloc(Marshal.SizeOf(), FIELD_ALIGNMENT); + NewProperty = Factory.CreateFObjectProperty(Alloc); + SetPropertySuperFields(Factory.CreateFField(Alloc), Name, ClassReflection!, PropertyClass!); + unsafe + { + var pProperty = (FProperty*)Alloc; + pProperty->array_dim = 1; + pProperty->element_size = Marshal.SizeOf(); + // For ObjectProperty: UExampleClass* pExampleObject; + // For ClassProperty: TSubclassOf pExampleClass; + pProperty->property_flags = Flags.CreatePropertyFlags(Visibility, PropertyBuilderFlags.None); + SetPropertyFieldDefaults(pProperty, Offset); + } + LinkToPropertyList(NewProperty, ClassReflection!); + unsafe { ((FObjectProperty*)NewProperty.Ptr)->PropertyClass = (UClass*)FieldClass!.Ptr; } + return true; + } + + public override bool CreateName(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "NameProperty", Visibility); + + public override bool CreateString(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateStringPropertyInner(out NewProperty, Name, Offset, "StrProperty", Visibility); + + public override bool CreateText(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateTextPropertyInner(out NewProperty, Name, Offset, "TextProperty", Visibility); + + public override bool CreateArray(out IFArrayProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility, + IFProperty Inner) + { + NewProperty = null; + if (!TryGetClassAndProperty("ArrayProperty", out var ClassReflection, out var PropertyClass)) + return false; + var Alloc = Memory.Malloc(Marshal.SizeOf(), FIELD_ALIGNMENT); + NewProperty = Factory.CreateFArrayProperty(Alloc); + SetPropertySuperFields(Factory.CreateFField(Alloc), Name, ClassReflection!, PropertyClass!); + unsafe + { + var pProperty = (FProperty*)Alloc; + pProperty->array_dim = 1; + pProperty->element_size = 0x10; // sizeof(TArray) + pProperty->property_flags = Flags.CreatePropertyFlags(Visibility, PropertyBuilderFlags.NoCtor); + SetPropertyFieldDefaults(pProperty, Offset); + } + LinkToPropertyList(NewProperty, ClassReflection!); + unsafe { ((FArrayProperty*)Alloc)->Inner = (UE.Toolkit.Core.Types.Unreal.UE5_4_4.FProperty*)Inner.Ptr; } + return true; + } +} \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Reflection/UE5_2_1/PropertyFlagsBuilder.cs b/UE.Toolkit.Reloaded/Reflection/UE5_2_1/PropertyFlagsBuilder.cs new file mode 100644 index 0000000..1d8f551 --- /dev/null +++ b/UE.Toolkit.Reloaded/Reflection/UE5_2_1/PropertyFlagsBuilder.cs @@ -0,0 +1,23 @@ +using UE.Toolkit.Core.Types.Unreal.Factories.Interfaces; +using EPropertyFlags = UE.Toolkit.Core.Types.Unreal.UE5_4_4.EPropertyFlags; + +namespace UE.Toolkit.Reloaded.Reflection.UE5_2_1; + +public class PropertyFlagsBuilder : IPropertyFlagsBuilder +{ + public EPropertyFlags CreatePropertyFlags(PropertyVisibility Visibility, PropertyBuilderFlags InFlags) + { + var Flags = EPropertyFlags.CPF_Edit | EPropertyFlags.CPF_BlueprintVisible; + if (InFlags.HasFlag(PropertyBuilderFlags.NoCtor)) Flags |= EPropertyFlags.CPF_ZeroConstructor; + if (InFlags.HasFlag(PropertyBuilderFlags.Copy)) Flags |= EPropertyFlags.CPF_IsPlainOldData; + if (InFlags.HasFlag(PropertyBuilderFlags.NoDtor)) Flags |= EPropertyFlags.CPF_NoDestructor; + if (InFlags.HasFlag(PropertyBuilderFlags.Hash)) Flags |= EPropertyFlags.CPF_HasGetValueTypeHash; + Flags |= Visibility switch + { + PropertyVisibility.Public => EPropertyFlags.CPF_NativeAccessSpecifierPublic, + PropertyVisibility.Protected => EPropertyFlags.CPF_NativeAccessSpecifierProtected, + _ => EPropertyFlags.CPF_NativeAccessSpecifierPrivate, + }; + return Flags; + } +} \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Reflection/UE5_2_1/TypeFactory.cs b/UE.Toolkit.Reloaded/Reflection/UE5_2_1/TypeFactory.cs new file mode 100644 index 0000000..2d7231d --- /dev/null +++ b/UE.Toolkit.Reloaded/Reflection/UE5_2_1/TypeFactory.cs @@ -0,0 +1,77 @@ +using UE.Toolkit.Core.Types.Unreal.Factories; +using UE.Toolkit.Core.Types.Unreal.Factories.Interfaces; +using UE.Toolkit.Interfaces; + +namespace UE.Toolkit.Reloaded.Reflection.UE5_2_1; + +public class TypeFactory(IUnrealFactory factory, IUnrealMemory memory, + IUnrealClasses classes, IPropertyFlagsBuilder flags) + : BaseTypeFactory(factory, memory, classes, flags) +{ + public override bool CreateI8Param(string Name, int Offset, out IFGenericPropertyParams? Out) + { + Out = null; + return false; + } + + public override bool CreateI16Param(string Name, int Offset, out IFGenericPropertyParams? Out) + { + Out = null; + return false; + } + + public override bool CreateI32Param(string Name, int Offset, out IFGenericPropertyParams? Out) + { + Out = null; + return false; + } + + public override bool CreateI64Param(string Name, int Offset, out IFGenericPropertyParams? Out) + { + Out = null; + return false; + } + + public override bool CreateU8Param(string Name, int Offset, out IFGenericPropertyParams? Out) + { + Out = null; + return false; + } + + public override bool CreateU16Param(string Name, int Offset, out IFGenericPropertyParams? Out) + { + Out = null; + return false; + } + + public override bool CreateU32Param(string Name, int Offset, out IFGenericPropertyParams? Out) + { + Out = null; + return false; + } + + public override bool CreateU64Param(string Name, int Offset, out IFGenericPropertyParams? Out) + { + Out = null; + return false; + } + + public override bool CreateF32Param(string Name, int Offset, out IFGenericPropertyParams? Out) + { + Out = null; + return false; + } + + public override bool CreateF64Param(string Name, int Offset, out IFGenericPropertyParams? Out) + { + Out = null; + return false; + } + + internal override unsafe bool CreateStructParam(string Name, int Size, + List Fields, out IFStructParams? Out) + { + Out = null; + return false; + } +} \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Reflection/UE5_4_4/PropertyFactory.cs b/UE.Toolkit.Reloaded/Reflection/UE5_4_4/PropertyFactory.cs index 39629af..9b3ee32 100644 --- a/UE.Toolkit.Reloaded/Reflection/UE5_4_4/PropertyFactory.cs +++ b/UE.Toolkit.Reloaded/Reflection/UE5_4_4/PropertyFactory.cs @@ -21,6 +21,7 @@ protected override unsafe void LinkToPropertyList(IFProperty Property, IUClass R pProperty->PostConstructLinkNext = null; var pClass = (UClass*)Reflect.Ptr; + // Is this the only field? if (((UStruct*)pClass)->PropertyLink == null) { ((UStruct*)pClass)->PropertyLink = pProperty; @@ -177,7 +178,7 @@ public override bool CreateName(out IFProperty? NewProperty, string Name => CreateCopyPropertyInner(out NewProperty, Name, Offset, "NameProperty", Visibility); public override bool CreateString(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) - => CreateStringPropertyInner(out NewProperty, Name, Offset, "StringProperty", Visibility); + => CreateStringPropertyInner(out NewProperty, Name, Offset, "StrProperty", Visibility); public override bool CreateText(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) => CreateTextPropertyInner(out NewProperty, Name, Offset, "TextProperty", Visibility); diff --git a/UE.Toolkit.Reloaded/Reflection/UE5_6_1/PropertyFactory.cs b/UE.Toolkit.Reloaded/Reflection/UE5_6_1/PropertyFactory.cs new file mode 100644 index 0000000..0263442 --- /dev/null +++ b/UE.Toolkit.Reloaded/Reflection/UE5_6_1/PropertyFactory.cs @@ -0,0 +1,210 @@ +using System.Runtime.InteropServices; +using UE.Toolkit.Core.Types.Interfaces; +using UE.Toolkit.Core.Types.Unreal.Factories; +using UE.Toolkit.Core.Types.Unreal.Factories.Interfaces; +using UE.Toolkit.Core.Types.Unreal.UE5_4_4; +using UE.Toolkit.Interfaces; +using FStructProperty = UE.Toolkit.Core.Types.Unreal.UE5_6_1.FStructProperty; +using UScriptStruct = UE.Toolkit.Core.Types.Unreal.UE5_6_1.UScriptStruct; +using UStruct = UE.Toolkit.Core.Types.Unreal.UE5_6_1.UStruct; + +namespace UE.Toolkit.Reloaded.Reflection.UE5_6_1; + +public class PropertyFactory(IUnrealFactory factory, IUnrealMemory memory, + IUnrealClasses classes, IPropertyFlagsBuilder flags) + : BasePropertyFactory(factory, memory, classes, flags) +{ + + protected override unsafe void LinkToPropertyList(IFProperty Property, IUClass Reflect) + { + var pProperty = (FProperty*)Property.Ptr; + pProperty->PropertyLinkNext = null; + pProperty->NextRef = null; + pProperty->DestructorLinkNext = null; + pProperty->PostConstructLinkNext = null; + + var pClass = (UClass*)Reflect.Ptr; + // Is this the only field? + if (((UStruct*)pClass)->PropertyLink == null) + { + ((UStruct*)pClass)->PropertyLink = pProperty; + ((UStruct*)pClass)->ChildProperties = (FField*)pProperty; + } + else + { + var TargetProp = GetPreviousProperty(Property, Reflect); + var NextProp = TargetProp.PropertyLinkNext.Any() ? TargetProp.PropertyLinkNext.First() : null; + var pTargetProp = (FProperty*)TargetProp.Ptr; + pTargetProp->PropertyLinkNext = pProperty; + ((FField*)pTargetProp)->Next = (FField*)pProperty; + if (NextProp != null) + { + var pNextProp = (FProperty*)NextProp.Ptr; + pProperty->PropertyLinkNext = pNextProp; + ((FField*)pProperty)->Next = (FField*)pNextProp; + } + } + } + + protected override unsafe void SetPropertySuperFields(IFField Field, string Name, IUClass ClassReflection, + FieldClassGlobal PropertyClass) + { + var pField = (FField*)Field.Ptr; + pField->VTable = PropertyClass.Vtable; + pField->ClassPrivate = (FFieldClass*)PropertyClass.Params.Ptr; + pField->Owner.Object = (UObjectBase*)ClassReflection.Ptr; // UClass* + pField->Next = null; + pField->NamePrivate = new FName(Name); + pField->FlagsPrivate = EObjectFlags.RF_Public | EObjectFlags.RF_MarkAsNative | EObjectFlags.RF_Transient; + } + + private unsafe void SetPropertyFieldDefaults(FProperty* pProperty, int Offset) + { + pProperty->RepIndex = 0; + pProperty->BlueprintReplicationCondition = 0; + pProperty->Offset_Internal = Offset; + } + + private unsafe void SetPropertyFieldsInner(IFProperty Property, int Offset, + PropertyVisibility Visibility, PropertyBuilderFlags PropertyFlags) + { + var pProperty = (FProperty*)Property.Ptr; + pProperty->ArrayDim = 1; + pProperty->ElementSize = Marshal.SizeOf(); + pProperty->PropertyFlags = Flags.CreatePropertyFlags(Visibility, PropertyFlags); + SetPropertyFieldDefaults(pProperty, Offset); + } + + protected override unsafe void SetCopyPropertyFields(IFProperty Property, int Offset, + PropertyVisibility Visibility) + { + var PropertyFlags = PropertyBuilderFlags.NoCtor | PropertyBuilderFlags.Copy | PropertyBuilderFlags.NoDtor; + SetPropertyFieldsInner(Property, Offset, Visibility, PropertyFlags); + } + + protected override void SetStringPropertyFields(IFProperty Property, int Offset, + PropertyVisibility Visibility) + => SetPropertyFieldsInner(Property, Offset, Visibility, PropertyBuilderFlags.NoCtor); + + protected override void SetTextPropertyFields(IFProperty Property, int Offset, + PropertyVisibility Visibility) + => SetPropertyFieldsInner(Property, Offset, Visibility, PropertyBuilderFlags.None); + + protected override unsafe void SetBoolPropertyFields(IFBoolProperty Property, BooleanMask Mask) + { + var pBoolProperty = (FBoolProperty*)Property.Ptr; + pBoolProperty->FieldSize = (byte)Marshal.SizeOf(); + pBoolProperty->ByteOffset = 0; + pBoolProperty->ByteMask = Mask.ByteMask; + pBoolProperty->FieldMask = Mask.FieldMask; + } + + public override bool CreateI8(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "Int8Property", Visibility); + + public override bool CreateI16(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "Int16Property", Visibility); + + public override bool CreateI32(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "IntProperty", Visibility); + + public override bool CreateI64(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "Int64Property", Visibility); + + public override bool CreateU8(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "UInt8Property", Visibility); + + public override bool CreateU16(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "UInt16Property", Visibility); + + public override bool CreateU32(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "UInt32Property", Visibility); + + public override bool CreateU64(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "UInt64Property", Visibility); + + public override bool CreateF32(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "FFloatProperty", Visibility); + + public override bool CreateF64(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "FDoubleProperty", Visibility); + + public override bool CreateStruct(out IFStructProperty? NewProperty, string Name, int Offset, + PropertyVisibility Visibility) + { + NewProperty = null; + if (!TryGetClassAndProperty("StructProperty", out var ClassReflection, out var PropertyClass) + || !Classes.GetScriptStructInfoFromType(out var ScriptStruct)) + return false; + var Alloc = Memory.Malloc(Marshal.SizeOf(), FIELD_ALIGNMENT); + NewProperty = Factory.CreateFStructProperty(Alloc); + SetPropertySuperFields(Factory.CreateFField(Alloc), Name, ClassReflection!, PropertyClass!); + unsafe + { + var pProperty = (FProperty*)Alloc; + pProperty->ArrayDim = 1; + pProperty->ElementSize = ScriptStruct!.PropertiesSize; // FExampleStruct mExampleField; + pProperty->PropertyFlags = Flags.CreatePropertyFlags(Visibility, PropertyBuilderFlags.None); + SetPropertyFieldDefaults(pProperty, Offset); + } + LinkToPropertyList(NewProperty, ClassReflection!); + unsafe { ((FStructProperty*)NewProperty.Ptr)->Struct = (UScriptStruct*)ScriptStruct.Ptr; } + return true; + } + + public override bool CreateObject(out IFObjectProperty? NewProperty, string Name, int Offset, + PropertyVisibility Visibility) + { + NewProperty = null; + if (!TryGetClassAndProperty("ObjectProperty", out var ClassReflection, out var PropertyClass) + || !Classes.GetClassInfoFromClass(out var FieldClass)) + return false; + var Alloc = Memory.Malloc(Marshal.SizeOf(), FIELD_ALIGNMENT); + NewProperty = Factory.CreateFObjectProperty(Alloc); + SetPropertySuperFields(Factory.CreateFField(Alloc), Name, ClassReflection!, PropertyClass!); + unsafe + { + var pProperty = (FProperty*)Alloc; + pProperty->ArrayDim = 1; + pProperty->ElementSize = Marshal.SizeOf(); + // For ObjectProperty: UExampleClass* pExampleObject; + // For ClassProperty: TSubclassOf pExampleClass; + pProperty->PropertyFlags = Flags.CreatePropertyFlags(Visibility, PropertyBuilderFlags.None); + SetPropertyFieldDefaults(pProperty, Offset); + } + LinkToPropertyList(NewProperty, ClassReflection!); + unsafe { ((FObjectProperty*)NewProperty.Ptr)->PropertyClass = (UClass*)FieldClass!.Ptr; } + return true; + } + + public override bool CreateName(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "NameProperty", Visibility); + + public override bool CreateString(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateStringPropertyInner(out NewProperty, Name, Offset, "StrProperty", Visibility); + + public override bool CreateText(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateTextPropertyInner(out NewProperty, Name, Offset, "TextProperty", Visibility); + + public override bool CreateArray(out IFArrayProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility, + IFProperty Inner) + { + NewProperty = null; + if (!TryGetClassAndProperty("ArrayProperty", out var ClassReflection, out var PropertyClass)) + return false; + var Alloc = Memory.Malloc(Marshal.SizeOf(), FIELD_ALIGNMENT); + NewProperty = Factory.CreateFArrayProperty(Alloc); + SetPropertySuperFields(Factory.CreateFField(Alloc), Name, ClassReflection!, PropertyClass!); + unsafe + { + var pProperty = (FProperty*)Alloc; + pProperty->ArrayDim = 1; + pProperty->ElementSize= 0x10; // sizeof(TArray) + pProperty->PropertyFlags = Flags.CreatePropertyFlags(Visibility, PropertyBuilderFlags.NoCtor); + SetPropertyFieldDefaults(pProperty, Offset); + } + LinkToPropertyList(NewProperty, ClassReflection!); + unsafe { ((FArrayProperty*)Alloc)->Inner = (FProperty*)Inner.Ptr; } + return true; + } +} \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Reflection/UE5_6_1/PropertyFlagsBuilder.cs b/UE.Toolkit.Reloaded/Reflection/UE5_6_1/PropertyFlagsBuilder.cs new file mode 100644 index 0000000..992f5d2 --- /dev/null +++ b/UE.Toolkit.Reloaded/Reflection/UE5_6_1/PropertyFlagsBuilder.cs @@ -0,0 +1,23 @@ +using UE.Toolkit.Core.Types.Unreal.Factories.Interfaces; +using EPropertyFlags = UE.Toolkit.Core.Types.Unreal.UE5_4_4.EPropertyFlags; + +namespace UE.Toolkit.Reloaded.Reflection.UE5_6_1; + +public class PropertyFlagsBuilder : IPropertyFlagsBuilder +{ + public EPropertyFlags CreatePropertyFlags(PropertyVisibility Visibility, PropertyBuilderFlags InFlags) + { + var Flags = EPropertyFlags.CPF_Edit | EPropertyFlags.CPF_BlueprintVisible; + if (InFlags.HasFlag(PropertyBuilderFlags.NoCtor)) Flags |= EPropertyFlags.CPF_ZeroConstructor; + if (InFlags.HasFlag(PropertyBuilderFlags.Copy)) Flags |= EPropertyFlags.CPF_IsPlainOldData; + if (InFlags.HasFlag(PropertyBuilderFlags.NoDtor)) Flags |= EPropertyFlags.CPF_NoDestructor; + if (InFlags.HasFlag(PropertyBuilderFlags.Hash)) Flags |= EPropertyFlags.CPF_HasGetValueTypeHash; + Flags |= Visibility switch + { + PropertyVisibility.Public => EPropertyFlags.CPF_NativeAccessSpecifierPublic, + PropertyVisibility.Protected => EPropertyFlags.CPF_NativeAccessSpecifierProtected, + _ => EPropertyFlags.CPF_NativeAccessSpecifierPrivate, + }; + return Flags; + } +} \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Reflection/UE5_6_1/TypeFactory.cs b/UE.Toolkit.Reloaded/Reflection/UE5_6_1/TypeFactory.cs new file mode 100644 index 0000000..785ee80 --- /dev/null +++ b/UE.Toolkit.Reloaded/Reflection/UE5_6_1/TypeFactory.cs @@ -0,0 +1,77 @@ +using UE.Toolkit.Core.Types.Unreal.Factories; +using UE.Toolkit.Core.Types.Unreal.Factories.Interfaces; +using UE.Toolkit.Interfaces; + +namespace UE.Toolkit.Reloaded.Reflection.UE5_6_1; + +public class TypeFactory(IUnrealFactory factory, IUnrealMemory memory, + IUnrealClasses classes, IPropertyFlagsBuilder flags) + : BaseTypeFactory(factory, memory, classes, flags) +{ + public override bool CreateI8Param(string Name, int Offset, out IFGenericPropertyParams? Out) + { + Out = null; + return false; + } + + public override bool CreateI16Param(string Name, int Offset, out IFGenericPropertyParams? Out) + { + Out = null; + return false; + } + + public override bool CreateI32Param(string Name, int Offset, out IFGenericPropertyParams? Out) + { + Out = null; + return false; + } + + public override bool CreateI64Param(string Name, int Offset, out IFGenericPropertyParams? Out) + { + Out = null; + return false; + } + + public override bool CreateU8Param(string Name, int Offset, out IFGenericPropertyParams? Out) + { + Out = null; + return false; + } + + public override bool CreateU16Param(string Name, int Offset, out IFGenericPropertyParams? Out) + { + Out = null; + return false; + } + + public override bool CreateU32Param(string Name, int Offset, out IFGenericPropertyParams? Out) + { + Out = null; + return false; + } + + public override bool CreateU64Param(string Name, int Offset, out IFGenericPropertyParams? Out) + { + Out = null; + return false; + } + + public override bool CreateF32Param(string Name, int Offset, out IFGenericPropertyParams? Out) + { + Out = null; + return false; + } + + public override bool CreateF64Param(string Name, int Offset, out IFGenericPropertyParams? Out) + { + Out = null; + return false; + } + + internal override unsafe bool CreateStructParam(string Name, int Size, + List Fields, out IFStructParams? Out) + { + Out = null; + return false; + } +} \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Reflection/UE5_7_4/PropertyFactory.cs b/UE.Toolkit.Reloaded/Reflection/UE5_7_4/PropertyFactory.cs new file mode 100644 index 0000000..e24db84 --- /dev/null +++ b/UE.Toolkit.Reloaded/Reflection/UE5_7_4/PropertyFactory.cs @@ -0,0 +1,212 @@ +using System.Runtime.InteropServices; +using UE.Toolkit.Core.Types.Interfaces; +using UE.Toolkit.Core.Types.Unreal.Factories; +using UE.Toolkit.Core.Types.Unreal.Factories.Interfaces; +using UE.Toolkit.Core.Types.Unreal.UE5_4_4; +// using UE.Toolkit.Core.Types.Unreal.UE5_6_1; +using UE.Toolkit.Interfaces; +using FField = UE.Toolkit.Core.Types.Unreal.UE5_7_4.FField; +using FFieldClass = UE.Toolkit.Core.Types.Unreal.UE5_7_4.FFieldClass; +using FStructProperty = UE.Toolkit.Core.Types.Unreal.UE5_7_4.FStructProperty; +using UStruct = UE.Toolkit.Core.Types.Unreal.UE5_7_4.UStruct; +using UScriptStruct = UE.Toolkit.Core.Types.Unreal.UE5_7_4.UScriptStruct; + +namespace UE.Toolkit.Reloaded.Reflection.UE5_7_4; + +public class PropertyFactory(IUnrealFactory factory, IUnrealMemory memory, + IUnrealClasses classes, IPropertyFlagsBuilder flags) + : BasePropertyFactory(factory, memory, classes, flags) +{ + + protected override unsafe void LinkToPropertyList(IFProperty Property, IUClass Reflect) + { + var pProperty = (FProperty*)Property.Ptr; + pProperty->PropertyLinkNext = null; + pProperty->NextRef = null; + pProperty->DestructorLinkNext = null; + pProperty->PostConstructLinkNext = null; + + var pClass = (UClass*)Reflect.Ptr; + if (((UStruct*)pClass)->PropertyLink == null) + { + ((UStruct*)pClass)->PropertyLink = pProperty; + ((UStruct*)pClass)->ChildProperties = (FField*)pProperty; + } + else + { + var TargetProp = GetPreviousProperty(Property, Reflect); + var NextProp = TargetProp.PropertyLinkNext.Any() ? TargetProp.PropertyLinkNext.First() : null; + var pTargetProp = (FProperty*)TargetProp.Ptr; + pTargetProp->PropertyLinkNext = pProperty; + ((FField*)pTargetProp)->Next = (FField*)pProperty; + if (NextProp != null) + { + var pNextProp = (FProperty*)NextProp.Ptr; + pProperty->PropertyLinkNext = pNextProp; + ((FField*)pProperty)->Next = (FField*)pNextProp; + } + } + } + + protected override unsafe void SetPropertySuperFields(IFField Field, string Name, IUClass ClassReflection, + FieldClassGlobal PropertyClass) + { + var pField = (FField*)Field.Ptr; + pField->VTable = PropertyClass.Vtable; + pField->ClassPrivate = (FFieldClass*)PropertyClass.Params.Ptr; + pField->Owner.Object = (UObjectBase*)ClassReflection.Ptr; // UClass* + pField->Next = null; + pField->NamePrivate = new FName(Name); + pField->FlagsPrivate = EObjectFlags.RF_Public | EObjectFlags.RF_MarkAsNative | EObjectFlags.RF_Transient; + } + + private unsafe void SetPropertyFieldDefaults(FProperty* pProperty, int Offset) + { + pProperty->RepIndex = 0; + pProperty->BlueprintReplicationCondition = 0; + pProperty->Offset_Internal = Offset; + } + + private unsafe void SetPropertyFieldsInner(IFProperty Property, int Offset, + PropertyVisibility Visibility, PropertyBuilderFlags PropertyFlags) + { + var pProperty = (FProperty*)Property.Ptr; + pProperty->ArrayDim = 1; + pProperty->ElementSize = Marshal.SizeOf(); + pProperty->PropertyFlags = Flags.CreatePropertyFlags(Visibility, PropertyFlags); + SetPropertyFieldDefaults(pProperty, Offset); + } + + protected override unsafe void SetCopyPropertyFields(IFProperty Property, int Offset, + PropertyVisibility Visibility) + { + var PropertyFlags = PropertyBuilderFlags.NoCtor | PropertyBuilderFlags.Copy | PropertyBuilderFlags.NoDtor; + SetPropertyFieldsInner(Property, Offset, Visibility, PropertyFlags); + } + + protected override void SetStringPropertyFields(IFProperty Property, int Offset, + PropertyVisibility Visibility) + => SetPropertyFieldsInner(Property, Offset, Visibility, PropertyBuilderFlags.NoCtor); + + protected override void SetTextPropertyFields(IFProperty Property, int Offset, + PropertyVisibility Visibility) + => SetPropertyFieldsInner(Property, Offset, Visibility, PropertyBuilderFlags.None); + + protected override unsafe void SetBoolPropertyFields(IFBoolProperty Property, BooleanMask Mask) + { + var pBoolProperty = (FBoolProperty*)Property.Ptr; + pBoolProperty->FieldSize = (byte)Marshal.SizeOf(); + pBoolProperty->ByteOffset = 0; + pBoolProperty->ByteMask = Mask.ByteMask; + pBoolProperty->FieldMask = Mask.FieldMask; + } + + public override bool CreateI8(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "Int8Property", Visibility); + + public override bool CreateI16(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "Int16Property", Visibility); + + public override bool CreateI32(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "IntProperty", Visibility); + + public override bool CreateI64(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "Int64Property", Visibility); + + public override bool CreateU8(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "UInt8Property", Visibility); + + public override bool CreateU16(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "UInt16Property", Visibility); + + public override bool CreateU32(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "UInt32Property", Visibility); + + public override bool CreateU64(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "UInt64Property", Visibility); + + public override bool CreateF32(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "FFloatProperty", Visibility); + + public override bool CreateF64(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "FDoubleProperty", Visibility); + + public override bool CreateStruct(out IFStructProperty? NewProperty, string Name, int Offset, + PropertyVisibility Visibility) + { + NewProperty = null; + if (!TryGetClassAndProperty("StructProperty", out var ClassReflection, out var PropertyClass) + || !Classes.GetScriptStructInfoFromType(out var ScriptStruct)) + return false; + var Alloc = Memory.Malloc(Marshal.SizeOf(), FIELD_ALIGNMENT); + NewProperty = Factory.CreateFStructProperty(Alloc); + SetPropertySuperFields(Factory.CreateFField(Alloc), Name, ClassReflection!, PropertyClass!); + unsafe + { + var pProperty = (FProperty*)Alloc; + pProperty->ArrayDim = 1; + pProperty->ElementSize = ScriptStruct!.PropertiesSize; // FExampleStruct mExampleField; + pProperty->PropertyFlags = Flags.CreatePropertyFlags(Visibility, PropertyBuilderFlags.None); + SetPropertyFieldDefaults(pProperty, Offset); + } + LinkToPropertyList(NewProperty, ClassReflection!); + unsafe { ((FStructProperty*)NewProperty.Ptr)->Struct = (UScriptStruct*)ScriptStruct.Ptr; } + return true; + } + + public override bool CreateObject(out IFObjectProperty? NewProperty, string Name, int Offset, + PropertyVisibility Visibility) + { + NewProperty = null; + if (!TryGetClassAndProperty("ObjectProperty", out var ClassReflection, out var PropertyClass) + || !Classes.GetClassInfoFromClass(out var FieldClass)) + return false; + var Alloc = Memory.Malloc(Marshal.SizeOf(), FIELD_ALIGNMENT); + NewProperty = Factory.CreateFObjectProperty(Alloc); + SetPropertySuperFields(Factory.CreateFField(Alloc), Name, ClassReflection!, PropertyClass!); + unsafe + { + var pProperty = (FProperty*)Alloc; + pProperty->ArrayDim = 1; + pProperty->ElementSize = Marshal.SizeOf(); + // For ObjectProperty: UExampleClass* pExampleObject; + // For ClassProperty: TSubclassOf pExampleClass; + pProperty->PropertyFlags = Flags.CreatePropertyFlags(Visibility, PropertyBuilderFlags.None); + SetPropertyFieldDefaults(pProperty, Offset); + } + LinkToPropertyList(NewProperty, ClassReflection!); + unsafe { ((FObjectProperty*)NewProperty.Ptr)->PropertyClass = (UClass*)FieldClass!.Ptr; } + return true; + } + + public override bool CreateName(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateCopyPropertyInner(out NewProperty, Name, Offset, "NameProperty", Visibility); + + public override bool CreateString(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateStringPropertyInner(out NewProperty, Name, Offset, "StrProperty", Visibility); + + public override bool CreateText(out IFProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility) + => CreateTextPropertyInner(out NewProperty, Name, Offset, "TextProperty", Visibility); + + public override bool CreateArray(out IFArrayProperty? NewProperty, string Name, int Offset, PropertyVisibility Visibility, + IFProperty Inner) + { + NewProperty = null; + if (!TryGetClassAndProperty("ArrayProperty", out var ClassReflection, out var PropertyClass)) + return false; + var Alloc = Memory.Malloc(Marshal.SizeOf(), FIELD_ALIGNMENT); + NewProperty = Factory.CreateFArrayProperty(Alloc); + SetPropertySuperFields(Factory.CreateFField(Alloc), Name, ClassReflection!, PropertyClass!); + unsafe + { + var pProperty = (FProperty*)Alloc; + pProperty->ArrayDim = 1; + pProperty->ElementSize= 0x10; // sizeof(TArray) + pProperty->PropertyFlags = Flags.CreatePropertyFlags(Visibility, PropertyBuilderFlags.NoCtor); + SetPropertyFieldDefaults(pProperty, Offset); + } + LinkToPropertyList(NewProperty, ClassReflection!); + unsafe { ((FArrayProperty*)Alloc)->Inner = (FProperty*)Inner.Ptr; } + return true; + } +} \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Reflection/UE5_7_4/PropertyFlagsBuilder.cs b/UE.Toolkit.Reloaded/Reflection/UE5_7_4/PropertyFlagsBuilder.cs new file mode 100644 index 0000000..00be8e9 --- /dev/null +++ b/UE.Toolkit.Reloaded/Reflection/UE5_7_4/PropertyFlagsBuilder.cs @@ -0,0 +1,23 @@ +using UE.Toolkit.Core.Types.Unreal.Factories.Interfaces; +using EPropertyFlags = UE.Toolkit.Core.Types.Unreal.UE5_4_4.EPropertyFlags; + +namespace UE.Toolkit.Reloaded.Reflection.UE5_7_4; + +public class PropertyFlagsBuilder : IPropertyFlagsBuilder +{ + public EPropertyFlags CreatePropertyFlags(PropertyVisibility Visibility, PropertyBuilderFlags InFlags) + { + var Flags = EPropertyFlags.CPF_Edit | EPropertyFlags.CPF_BlueprintVisible; + if (InFlags.HasFlag(PropertyBuilderFlags.NoCtor)) Flags |= EPropertyFlags.CPF_ZeroConstructor; + if (InFlags.HasFlag(PropertyBuilderFlags.Copy)) Flags |= EPropertyFlags.CPF_IsPlainOldData; + if (InFlags.HasFlag(PropertyBuilderFlags.NoDtor)) Flags |= EPropertyFlags.CPF_NoDestructor; + if (InFlags.HasFlag(PropertyBuilderFlags.Hash)) Flags |= EPropertyFlags.CPF_HasGetValueTypeHash; + Flags |= Visibility switch + { + PropertyVisibility.Public => EPropertyFlags.CPF_NativeAccessSpecifierPublic, + PropertyVisibility.Protected => EPropertyFlags.CPF_NativeAccessSpecifierProtected, + _ => EPropertyFlags.CPF_NativeAccessSpecifierPrivate, + }; + return Flags; + } +} \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Reflection/UE5_7_4/TypeFactory.cs b/UE.Toolkit.Reloaded/Reflection/UE5_7_4/TypeFactory.cs new file mode 100644 index 0000000..bafd8b3 --- /dev/null +++ b/UE.Toolkit.Reloaded/Reflection/UE5_7_4/TypeFactory.cs @@ -0,0 +1,77 @@ +using UE.Toolkit.Core.Types.Unreal.Factories; +using UE.Toolkit.Core.Types.Unreal.Factories.Interfaces; +using UE.Toolkit.Interfaces; + +namespace UE.Toolkit.Reloaded.Reflection.UE5_7_4; + +public class TypeFactory(IUnrealFactory factory, IUnrealMemory memory, + IUnrealClasses classes, IPropertyFlagsBuilder flags) + : BaseTypeFactory(factory, memory, classes, flags) +{ + public override bool CreateI8Param(string Name, int Offset, out IFGenericPropertyParams? Out) + { + Out = null; + return false; + } + + public override bool CreateI16Param(string Name, int Offset, out IFGenericPropertyParams? Out) + { + Out = null; + return false; + } + + public override bool CreateI32Param(string Name, int Offset, out IFGenericPropertyParams? Out) + { + Out = null; + return false; + } + + public override bool CreateI64Param(string Name, int Offset, out IFGenericPropertyParams? Out) + { + Out = null; + return false; + } + + public override bool CreateU8Param(string Name, int Offset, out IFGenericPropertyParams? Out) + { + Out = null; + return false; + } + + public override bool CreateU16Param(string Name, int Offset, out IFGenericPropertyParams? Out) + { + Out = null; + return false; + } + + public override bool CreateU32Param(string Name, int Offset, out IFGenericPropertyParams? Out) + { + Out = null; + return false; + } + + public override bool CreateU64Param(string Name, int Offset, out IFGenericPropertyParams? Out) + { + Out = null; + return false; + } + + public override bool CreateF32Param(string Name, int Offset, out IFGenericPropertyParams? Out) + { + Out = null; + return false; + } + + public override bool CreateF64Param(string Name, int Offset, out IFGenericPropertyParams? Out) + { + Out = null; + return false; + } + + internal override unsafe bool CreateStructParam(string Name, int Size, + List Fields, out IFStructParams? Out) + { + Out = null; + return false; + } +} \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Unreal/UnrealClasses.cs b/UE.Toolkit.Reloaded/Unreal/UnrealClasses.cs index 3210d7c..39f5dd9 100644 --- a/UE.Toolkit.Reloaded/Unreal/UnrealClasses.cs +++ b/UE.Toolkit.Reloaded/Unreal/UnrealClasses.cs @@ -48,8 +48,7 @@ private void GetPrivateStaticClassBodyUE4( TryHookStructLink(returnClass); } - // NOTE: 5.0 has it's own signature - + // NOTE: 5.0 has it's own signature, but the parameters are identical in count and data type // Used in Engine versions 5.1+ private delegate void GetPrivateStaticClassBody_UE5(nint packageName, nint name, UClass** returnClass, nint registerNativeFunc, uint size, uint align, uint flags, ulong castFlags, nint config, nint inClassCtor, @@ -458,18 +457,27 @@ public UnrealClasses(IUnrealFactory _Factory, IUnrealMemory _Memory, IUnrealObje IPropertyFlagsBuilder FlagsBuilder = GameConfig.Instance.Id switch { "P3R" => new Reflection.UE4_27_2.PropertyFlagsBuilder(), + "UE5_2_1" => new Reflection.UE5_2_1.PropertyFlagsBuilder(), + "UE5_6_1" => new Reflection.UE5_6_1.PropertyFlagsBuilder(), + "UE5_7_4" => new Reflection.UE5_7_4.PropertyFlagsBuilder(), _ => new Reflection.UE5_4_4.PropertyFlagsBuilder(), }; PropertyFactory = GameConfig.Instance.Id switch { "P3R" => new Reflection.UE4_27_2.PropertyFactory(Factory, Memory, this, FlagsBuilder), + "UE5_2_1" => new Reflection.UE5_2_1.PropertyFactory(Factory, Memory, this, FlagsBuilder), + "UE5_6_1" => new Reflection.UE5_6_1.PropertyFactory(Factory, Memory, this, FlagsBuilder), + "UE5_7_4" => new Reflection.UE5_7_4.PropertyFactory(Factory, Memory, this, FlagsBuilder), _ => new Reflection.UE5_4_4.PropertyFactory(Factory, Memory, this, FlagsBuilder), }; TypeFactory = GameConfig.Instance.Id switch { "P3R" => new Reflection.UE4_27_2.TypeFactory(Factory, Memory, this, FlagsBuilder), + "UE5_2_1" => new Reflection.UE5_2_1.TypeFactory(Factory, Memory, this, FlagsBuilder), + "UE5_6_1" => new Reflection.UE5_6_1.TypeFactory(Factory, Memory, this, FlagsBuilder), + "UE5_7_4" => new Reflection.UE5_7_4.TypeFactory(Factory, Memory, this, FlagsBuilder), _ => new Reflection.UE5_4_4.TypeFactory(Factory, Memory, this, FlagsBuilder), }; From c91255a3bc8814e592bfa2fc380bb7d797d157ec Mon Sep 17 00:00:00 2001 From: Rirurin Date: Sat, 4 Jul 2026 17:28:28 +0800 Subject: [PATCH 4/7] Fix Add Properties for 5.0-5.2, refactor all version specific objects to retrieve from IGameConfig --- README.md | 2 +- .../Unreal/Factories/UE5_2_1/UnrealFactory.cs | 56 ++++++++++- .../Common/GameConfigs/GameConfig.cs | 22 ----- .../Common/GameConfigs/Games/UE4_27_2_P3R.cs | 13 +++ .../Common/GameConfigs/Games/UE5_2_1.cs | 13 +++ .../Common/GameConfigs/Games/UE5_3_2.cs | 21 ++++- .../GameConfigs/Games/UE5_4_4_ClairObscur.cs | 13 +++ .../Common/GameConfigs/Games/UE5_6_1.cs | 13 +++ .../Common/GameConfigs/Games/UE5_7_4.cs | 13 +++ .../Common/GameConfigs/IGameConfig.cs | 6 ++ .../ObjectWriters/Nodes/FieldNodeFactory.cs | 2 +- .../Writers/FieldWriterFactory.cs | 2 +- .../ObjectWriters/Writers/TextFieldWriter.cs | 2 +- .../Reflection/Common/FunctionPointers.cs | 19 ++++ .../Reflection/UE4_27_2/TypeFactory.cs | 92 +++++++++---------- .../Reflection/UE5_2_1/PropertyFactory.cs | 21 +++-- UE.Toolkit.Reloaded/Unreal/UnrealClasses.cs | 31 +------ UE.Toolkit.Reloaded/Unreal/UnrealObjects.cs | 2 +- UE.Toolkit.Reloaded/Unreal/UnrealStrings.cs | 2 +- 19 files changed, 223 insertions(+), 122 deletions(-) create mode 100644 UE.Toolkit.Reloaded/Reflection/Common/FunctionPointers.cs diff --git a/README.md b/README.md index a387da4..750857f 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Object XML requires game-specific support with an extension mod. Supported games | Add Map Entry (Object XML) |✅|❔|❔|❔|❔|❔|❔|❔|❔ | Type Information |✅|✅|✅|✅|✅|✅|✅|✅|✅ | Custom Constructor |✅|✅|✅|✅|✅|✅|✅|✅|✅ -| Add Properties |✅|⚠️|⚠️|⚠️|✅|✅|✅|✅|✅ +| Add Properties |✅|✅|✅|✅|✅|✅|✅|✅|✅ | Register Struct |✅|❔|❔|❔|❔|❌|❔|❔|❔ Features marked with ❔ are currently untested. diff --git a/UE.Toolkit.Core/Types/Unreal/Factories/UE5_2_1/UnrealFactory.cs b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_2_1/UnrealFactory.cs index 665d39a..0e6a0ce 100644 --- a/UE.Toolkit.Core/Types/Unreal/Factories/UE5_2_1/UnrealFactory.cs +++ b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_2_1/UnrealFactory.cs @@ -1,3 +1,4 @@ +using System.Runtime.InteropServices; using UE.Toolkit.Core.Types.Unreal.Factories.Interfaces; using UE.Toolkit.Core.Types.Unreal.Factories.UE5_4_4; using UE.Toolkit.Core.Types.Unreal.UE5_4_4; @@ -17,6 +18,9 @@ // using FOptionalProperty = UE.Toolkit.Core.Types.Unreal.UE4_27_2.FOptionalProperty; using FDelegateProperty = UE.Toolkit.Core.Types.Unreal.UE4_27_2.FDelegateProperty; +using FPropertyParamsBase = UE.Toolkit.Core.Types.Unreal.UE4_27_2.FPropertyParamsBase; +using FStructParams = UE.Toolkit.Core.Types.Unreal.UE4_27_2.FStructParams; + namespace UE.Toolkit.Core.Types.Unreal.Factories.UE5_2_1; public class UnrealFactory : BaseUnrealFactory @@ -79,9 +83,9 @@ public override nint SizeOf() public override IUFunction CreateUFunction(nint ptr) => new UFunction_UE5_4_4(ptr, this); public override IFFieldClass CreateFFieldClass(nint ptr) => new FFieldClass_UE5_4_4(ptr, this); public override IFField CreateFField(nint ptr) => new FField_UE5_4_4(ptr, this); - public override IFStructParams CreateFStructParams(nint ptr) => new FStructParams_UE5_4_4(ptr, this); - public override IFPropertyParams CreateFPropertyParams(nint ptr) => new FPropertyParams_UE5_4_4(ptr, this); - public override IFGenericPropertyParams CreateFGenericPropertyParams(nint ptr) => new FGenericPropertyParams_UE5_4_4(ptr, this); + public override IFStructParams CreateFStructParams(nint ptr) => new FStructParams_UE5_2_1(ptr, this); + public override IFPropertyParams CreateFPropertyParams(nint ptr) => new FPropertyParams_UE5_2_1(ptr, this); + public override IFGenericPropertyParams CreateFGenericPropertyParams(nint ptr) => new FGenericPropertyParams_UE5_2_1(ptr, this); public override IFWorldContext CreateFWorldContext(nint ptr) => new FWorldContext_UE5_4_4(ptr, this); public override IUEngine CreateUEngine(nint ptr) => new UEngine_UE5_4_4(ptr, this); public override IUGameInstance CreateUGameInstance(nint ptr) => new UGameInstance_UE5_4_4(ptr, this); @@ -153,4 +157,50 @@ public IUObject? ClassDefaultObject public nint Constructor => _self->ClassConstructor; public EClassFlags ClassFlags => _self->ClassFlags; +} + +public unsafe class FStructParams_UE5_2_1(nint ptr, IUnrealFactory factory) : IFStructParams +{ + private readonly FStructParams* _self = (FStructParams*)ptr; + protected readonly IUnrealFactory _factory = factory; + + public nint Ptr => (nint)_self; + + public nint OuterFunc => _self->OuterFunc; + public nint SuperFunc => _self->SuperFunc; + public nint StructOpsFunc => _self->StructOpsFunc; + public string Name => Marshal.PtrToStringUTF8(_self->NameUTF8)!; + public ulong Size => _self->SizeOf; + public ulong Alignment => _self->AlignOf; + public EObjectFlags ObjectFlags => _self->ObjectFlags; + public EStructFlags StructFlags => _self->StructFlags; + public int PropertyCount => _self->NumProperties; + public IFPropertyParams? GetProperty(int Index) + { + var Result = ((FStructParams*)Ptr)->GetProperty(Index); + return Result != null ? _factory.CreateFPropertyParams((nint)Result) : null; + } + + public IEnumerable Properties => new FPropertyParamEnumerator(this); +} + +public unsafe class FPropertyParams_UE5_2_1(nint ptr, IUnrealFactory factory) : IFPropertyParams +{ + private readonly FPropertyParamsBase* _self = (FPropertyParamsBase*)ptr; + protected readonly IUnrealFactory _factory = factory; + + public nint Ptr => (nint)_self; + public string Name => Marshal.PtrToStringUTF8(_self->NameUTF8)!; + public EPropertyFlags PropertyFlags => _self->PropertyFlags; + public EPropertyGenFlags GenFlags => _self->PropertyGenFlags; + public EObjectFlags ObjectFlags => _self->ObjectFlags; +} + +public unsafe class FGenericPropertyParams_UE5_2_1(nint ptr, IUnrealFactory factory) + : FPropertyParams_UE5_2_1(ptr, factory), IFGenericPropertyParams +{ + private readonly FGenericPropertyParams* _self = (FGenericPropertyParams*)ptr; + + public int ArrayDim => _self->Super.ArrayDim; + public int Offset => _self->Super.Offset; } \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Common/GameConfigs/GameConfig.cs b/UE.Toolkit.Reloaded/Common/GameConfigs/GameConfig.cs index 3b745c6..06449d7 100644 --- a/UE.Toolkit.Reloaded/Common/GameConfigs/GameConfig.cs +++ b/UE.Toolkit.Reloaded/Common/GameConfigs/GameConfig.cs @@ -37,26 +37,4 @@ public static void SetGame(string appId) Log.Information($"Game config set to: {Instance.Id} (App ID: {appId})"); } - - // - public static Type GetFText() - { - return Instance.Id switch - { - "P3R" or "UE5_2_1" or "UE5_3_2" => typeof(UE.Toolkit.Core.Types.Unreal.UE4_27_2.FText), - _ => typeof(UE.Toolkit.Core.Types.Unreal.UE5_4_4.FText) - }; - } - - public static int GetFTextSize() - { - unsafe - { - return Instance.Id switch - { - "P3R" or "UE5_2_1" or "UE5_3_2" => sizeof(UE.Toolkit.Core.Types.Unreal.UE4_27_2.FText), - _ => sizeof(UE.Toolkit.Core.Types.Unreal.UE5_4_4.FText) - }; - } - } } diff --git a/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE4_27_2_P3R.cs b/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE4_27_2_P3R.cs index 43bc30c..04ba7e1 100644 --- a/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE4_27_2_P3R.cs +++ b/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE4_27_2_P3R.cs @@ -1,6 +1,8 @@ using UE.Toolkit.Core.Types.Unreal.Factories; using UE.Toolkit.Core.Types.Unreal.Factories.UE4_27_2; using UE.Toolkit.Interfaces; +using UE.Toolkit.Reloaded.Reflection; +using UE.Toolkit.Reloaded.Reflection.UE4_27_2; using UE.Toolkit.Reloaded.Unreal; // ReSharper disable InconsistentNaming @@ -12,4 +14,15 @@ public class UE4_27_2_P3R : UE5_4_4_ClairObscur public override string Id => "P3R"; public override IUnrealFactory Factory { get; } = new UnrealFactory(); public override IUnrealMemory Memory { get; } = new UnrealMemory(); + public override IPropertyFlagsBuilder FlagsBuilder { get; } = new PropertyFlagsBuilder(); + + public override BasePropertyFactory PropertyFactory(IUnrealClasses classes) + => new PropertyFactory(Factory, Memory, classes, FlagsBuilder); + + public override BaseTypeFactory TypeFactory(IUnrealClasses classes) + => new TypeFactory(Factory, Memory, classes, FlagsBuilder); + + public override Type GetFText() => typeof(UE.Toolkit.Core.Types.Unreal.UE4_27_2.FText); + + public override unsafe int GetFTextSize() => sizeof(UE.Toolkit.Core.Types.Unreal.UE4_27_2.FText); } \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_2_1.cs b/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_2_1.cs index 6247200..1e338d5 100644 --- a/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_2_1.cs +++ b/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_2_1.cs @@ -1,6 +1,8 @@ using UE.Toolkit.Core.Types.Unreal.Factories; using UE.Toolkit.Core.Types.Unreal.Factories.UE5_2_1; using UE.Toolkit.Interfaces; +using UE.Toolkit.Reloaded.Reflection; +using UE.Toolkit.Reloaded.Reflection.UE5_2_1; using UE.Toolkit.Reloaded.Unreal; namespace UE.Toolkit.Reloaded.Common.GameConfigs.Games; @@ -10,4 +12,15 @@ public class UE5_2_1: UE5_4_4_ClairObscur public override string Id => "UE5_2_1"; public override IUnrealFactory Factory { get; } = new UnrealFactory(); public override IUnrealMemory Memory { get; } = new UnrealMemory(); + public override IPropertyFlagsBuilder FlagsBuilder { get; } = new PropertyFlagsBuilder(); + + public override BasePropertyFactory PropertyFactory(IUnrealClasses classes) + => new PropertyFactory(Factory, Memory, classes, FlagsBuilder); + + public override BaseTypeFactory TypeFactory(IUnrealClasses classes) + => new TypeFactory(Factory, Memory, classes, FlagsBuilder); + + public override Type GetFText() => typeof(UE.Toolkit.Core.Types.Unreal.UE4_27_2.FText); + + public override unsafe int GetFTextSize() => sizeof(UE.Toolkit.Core.Types.Unreal.UE4_27_2.FText); } \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_3_2.cs b/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_3_2.cs index 1eaa0d9..8f172bc 100644 --- a/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_3_2.cs +++ b/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_3_2.cs @@ -1,14 +1,27 @@ using UE.Toolkit.Core.Types.Unreal.Factories; using UE.Toolkit.Core.Types.Unreal.Factories.UE5_4_4; using UE.Toolkit.Interfaces; +using UE.Toolkit.Reloaded.Reflection; +using UE.Toolkit.Reloaded.Reflection.UE5_4_4; using UE.Toolkit.Reloaded.Unreal; namespace UE.Toolkit.Reloaded.Common.GameConfigs.Games; // ReSharper disable once InconsistentNaming -public class UE5_3_2 : IGameConfig +public class UE5_3_2 : UE5_4_4_ClairObscur { - public virtual string Id => "UE5_3_2"; - public virtual IUnrealFactory Factory { get; } = new UnrealFactory(); - public virtual IUnrealMemory Memory { get; } = new UnrealMemory(); + public override string Id => "UE5_3_2"; + public override IUnrealFactory Factory { get; } = new UnrealFactory(); + public override IUnrealMemory Memory { get; } = new UnrealMemory(); + public override IPropertyFlagsBuilder FlagsBuilder { get; } = new PropertyFlagsBuilder(); + + public override BasePropertyFactory PropertyFactory(IUnrealClasses classes) + => new PropertyFactory(Factory, Memory, classes, FlagsBuilder); + + public override BaseTypeFactory TypeFactory(IUnrealClasses classes) + => new TypeFactory(Factory, Memory, classes, FlagsBuilder); + + public override Type GetFText() => typeof(UE.Toolkit.Core.Types.Unreal.UE4_27_2.FText); + + public override unsafe int GetFTextSize() => sizeof(UE.Toolkit.Core.Types.Unreal.UE4_27_2.FText); } \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_4_4_ClairObscur.cs b/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_4_4_ClairObscur.cs index 3bfa78e..e4d62e4 100644 --- a/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_4_4_ClairObscur.cs +++ b/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_4_4_ClairObscur.cs @@ -1,6 +1,8 @@ using UE.Toolkit.Core.Types.Unreal.Factories; using UE.Toolkit.Core.Types.Unreal.Factories.UE5_4_4; using UE.Toolkit.Interfaces; +using UE.Toolkit.Reloaded.Reflection; +using UE.Toolkit.Reloaded.Reflection.UE5_4_4; using UE.Toolkit.Reloaded.Unreal; namespace UE.Toolkit.Reloaded.Common.GameConfigs.Games; @@ -11,4 +13,15 @@ public class UE5_4_4_ClairObscur : IGameConfig public virtual string Id => "Clair Obscur"; public virtual IUnrealFactory Factory { get; } = new UnrealFactory(); public virtual IUnrealMemory Memory { get; } = new UnrealMemory(); + public virtual IPropertyFlagsBuilder FlagsBuilder { get; } = new PropertyFlagsBuilder(); + + public virtual BasePropertyFactory PropertyFactory(IUnrealClasses classes) + => new PropertyFactory(Factory, Memory, classes, FlagsBuilder); + + public virtual BaseTypeFactory TypeFactory(IUnrealClasses classes) + => new TypeFactory(Factory, Memory, classes, FlagsBuilder); + + public virtual Type GetFText() => typeof(UE.Toolkit.Core.Types.Unreal.UE5_4_4.FText); + + public virtual unsafe int GetFTextSize() => sizeof(UE.Toolkit.Core.Types.Unreal.UE5_4_4.FText); } \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_6_1.cs b/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_6_1.cs index fad22d6..f8c5ecb 100644 --- a/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_6_1.cs +++ b/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_6_1.cs @@ -1,6 +1,8 @@ using UE.Toolkit.Core.Types.Unreal.Factories; using UE.Toolkit.Core.Types.Unreal.Factories.UE5_6_1; using UE.Toolkit.Interfaces; +using UE.Toolkit.Reloaded.Reflection; +using UE.Toolkit.Reloaded.Reflection.UE5_6_1; using UE.Toolkit.Reloaded.Unreal; namespace UE.Toolkit.Reloaded.Common.GameConfigs.Games; @@ -10,4 +12,15 @@ public class UE5_6_1: UE5_4_4_ClairObscur public override string Id => "UE5_6_1"; public override IUnrealFactory Factory { get; } = new UnrealFactory(); public override IUnrealMemory Memory { get; } = new UnrealMemory(); + public override IPropertyFlagsBuilder FlagsBuilder { get; } = new PropertyFlagsBuilder(); + + public override BasePropertyFactory PropertyFactory(IUnrealClasses classes) + => new PropertyFactory(Factory, Memory, classes, FlagsBuilder); + + public override BaseTypeFactory TypeFactory(IUnrealClasses classes) + => new TypeFactory(Factory, Memory, classes, FlagsBuilder); + + public override Type GetFText() => typeof(UE.Toolkit.Core.Types.Unreal.UE5_4_4.FText); + + public override unsafe int GetFTextSize() => sizeof(UE.Toolkit.Core.Types.Unreal.UE5_4_4.FText); } \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_7_4.cs b/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_7_4.cs index ecaef77..5c5fbfe 100644 --- a/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_7_4.cs +++ b/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_7_4.cs @@ -1,6 +1,8 @@ using UE.Toolkit.Core.Types.Unreal.Factories; using UE.Toolkit.Core.Types.Unreal.Factories.UE5_7_4; using UE.Toolkit.Interfaces; +using UE.Toolkit.Reloaded.Reflection; +using UE.Toolkit.Reloaded.Reflection.UE5_7_4; using UE.Toolkit.Reloaded.Unreal; namespace UE.Toolkit.Reloaded.Common.GameConfigs.Games; @@ -10,4 +12,15 @@ public class UE5_7_4: UE5_4_4_ClairObscur public override string Id => "UE5_7_4"; public override IUnrealFactory Factory { get; } = new UnrealFactory(); public override IUnrealMemory Memory { get; } = new UnrealMemory(); + public override IPropertyFlagsBuilder FlagsBuilder { get; } = new PropertyFlagsBuilder(); + + public override BasePropertyFactory PropertyFactory(IUnrealClasses classes) + => new PropertyFactory(Factory, Memory, classes, FlagsBuilder); + + public override BaseTypeFactory TypeFactory(IUnrealClasses classes) + => new TypeFactory(Factory, Memory, classes, FlagsBuilder); + + public override Type GetFText() => typeof(UE.Toolkit.Core.Types.Unreal.UE5_4_4.FText); + + public override unsafe int GetFTextSize() => sizeof(UE.Toolkit.Core.Types.Unreal.UE5_4_4.FText); } \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Common/GameConfigs/IGameConfig.cs b/UE.Toolkit.Reloaded/Common/GameConfigs/IGameConfig.cs index 329448c..1003112 100644 --- a/UE.Toolkit.Reloaded/Common/GameConfigs/IGameConfig.cs +++ b/UE.Toolkit.Reloaded/Common/GameConfigs/IGameConfig.cs @@ -2,6 +2,7 @@ using UE.Toolkit.Core.Types.Unreal.Factories; using UE.Toolkit.Interfaces; +using UE.Toolkit.Reloaded.Reflection; namespace UE.Toolkit.Reloaded.Common.GameConfigs; @@ -10,4 +11,9 @@ public interface IGameConfig string Id { get; } IUnrealFactory Factory { get; } IUnrealMemory Memory { get; } + IPropertyFlagsBuilder FlagsBuilder { get; } + BasePropertyFactory PropertyFactory(IUnrealClasses classes); + BaseTypeFactory TypeFactory(IUnrealClasses classes); + Type GetFText(); + int GetFTextSize(); } \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/ObjectWriters/Nodes/FieldNodeFactory.cs b/UE.Toolkit.Reloaded/ObjectWriters/Nodes/FieldNodeFactory.cs index e3a3722..486c9d6 100644 --- a/UE.Toolkit.Reloaded/ObjectWriters/Nodes/FieldNodeFactory.cs +++ b/UE.Toolkit.Reloaded/ObjectWriters/Nodes/FieldNodeFactory.cs @@ -26,7 +26,7 @@ public bool TryCreate(string fieldName, nint fieldPtr, int fieldBit, Type fieldT if (fieldType.IsPrimitive || fieldType.IsEnum || fieldType == typeof(string) - || fieldType == GameConfig.GetFText() + || fieldType == GameConfig.Instance.GetFText() || fieldType == typeof(FString) || fieldType == typeof(FName) || fieldType.Name.StartsWith("TSoftObjectPtr") diff --git a/UE.Toolkit.Reloaded/ObjectWriters/Writers/FieldWriterFactory.cs b/UE.Toolkit.Reloaded/ObjectWriters/Writers/FieldWriterFactory.cs index c30ea0c..42d27f0 100644 --- a/UE.Toolkit.Reloaded/ObjectWriters/Writers/FieldWriterFactory.cs +++ b/UE.Toolkit.Reloaded/ObjectWriters/Writers/FieldWriterFactory.cs @@ -12,7 +12,7 @@ public static class FieldWriterFactory if (fieldType.IsPrimitive || fieldType.IsEnum || fieldType.Name == nameof(String)) return new PrimitiveFieldWriter(fieldName, fieldPtr, fieldBit, fieldType); - if (fieldType == GameConfig.GetFText() || fieldType == typeof(FString) || fieldType == typeof(FName)) + if (fieldType == GameConfig.Instance.GetFText() || fieldType == typeof(FString) || fieldType == typeof(FName)) return new TextFieldWriter(fieldName, fieldPtr, fieldType, objCreator); if (fieldType.Name.StartsWith("TSoftObjectPtr") || fieldType.Name.StartsWith("TSoftClassPtr")) diff --git a/UE.Toolkit.Reloaded/ObjectWriters/Writers/TextFieldWriter.cs b/UE.Toolkit.Reloaded/ObjectWriters/Writers/TextFieldWriter.cs index e53653d..0512678 100644 --- a/UE.Toolkit.Reloaded/ObjectWriters/Writers/TextFieldWriter.cs +++ b/UE.Toolkit.Reloaded/ObjectWriters/Writers/TextFieldWriter.cs @@ -27,7 +27,7 @@ public void SetField(TValue value) where TValue : unmanaged switch (fieldType.Name) { case nameof(FText): - var allocSize = GameConfig.GetFTextSize(); + var allocSize = GameConfig.Instance.GetFTextSize(); _ogData = new byte[allocSize]; Marshal.Copy(fieldPtr, _ogData, 0, allocSize); var ftext = objCreator.CreateFText(strValue); diff --git a/UE.Toolkit.Reloaded/Reflection/Common/FunctionPointers.cs b/UE.Toolkit.Reloaded/Reflection/Common/FunctionPointers.cs new file mode 100644 index 0000000..f0d16ad --- /dev/null +++ b/UE.Toolkit.Reloaded/Reflection/Common/FunctionPointers.cs @@ -0,0 +1,19 @@ +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace UE.Toolkit.Reloaded.Reflection.Common; + +public static class FunctionPointers +{ + [UnmanagedCallersOnly(CallConvs = [typeof(CallConvStdcall)])] + internal static byte Noop_Bool_False() => 0; + + [UnmanagedCallersOnly(CallConvs = [typeof(CallConvStdcall)])] + internal static byte Noop_Bool_True() => 1; + + [UnmanagedCallersOnly(CallConvs = [typeof(CallConvStdcall)])] + internal static void Noop_Void() {} + + [UnmanagedCallersOnly(CallConvs = [typeof(CallConvStdcall)])] + internal static uint Noop_U32() => 0; +} \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Reflection/UE4_27_2/TypeFactory.cs b/UE.Toolkit.Reloaded/Reflection/UE4_27_2/TypeFactory.cs index acea6c4..ca40592 100644 --- a/UE.Toolkit.Reloaded/Reflection/UE4_27_2/TypeFactory.cs +++ b/UE.Toolkit.Reloaded/Reflection/UE4_27_2/TypeFactory.cs @@ -3,6 +3,7 @@ using UE.Toolkit.Core.Types.Unreal.Factories; using UE.Toolkit.Core.Types.Unreal.Factories.Interfaces; using UE.Toolkit.Interfaces; +using UE.Toolkit.Reloaded.Reflection.Common; using ICppStructOps = UE.Toolkit.Core.Types.Unreal.UE5_4_4.ICppStructOps; using FStructParams = UE.Toolkit.Core.Types.Unreal.UE4_27_2.FStructParams; using FPropertyParamsBase = UE.Toolkit.Core.Types.Unreal.UE4_27_2.FPropertyParamsBase; @@ -21,18 +22,6 @@ public class TypeFactory(IUnrealFactory factory, IUnrealMemory memory, private static Func? FMemory_Malloc_Static = null; private static nint Malloc_Static_Size = 0; - [UnmanagedCallersOnly(CallConvs = [typeof(CallConvStdcall)])] - private static byte Noop_Bool_False() => 0; - - [UnmanagedCallersOnly(CallConvs = [typeof(CallConvStdcall)])] - private static byte Noop_Bool_True() => 1; - - [UnmanagedCallersOnly(CallConvs = [typeof(CallConvStdcall)])] - private static void Noop_Void() {} - - [UnmanagedCallersOnly(CallConvs = [typeof(CallConvStdcall)])] - private static uint Noop_U32() => 0; - private static nint CurrentCppStructOpsVtable; private static uint CurrentCppStructOpsSize; private const uint CPP_STRUCT_OPS_ALIGNMENT = 0x8; @@ -48,48 +37,49 @@ private static unsafe nint InitializeCppStructOps() return (nint)Alloc; } + // UScriptStruct::ICppStructOps private unsafe void CreateCppStructOpsVtable() { // 0-38 - ((nint*)CurrentCppStructOpsVtable)[0] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Void); // ~ICppStructOps - ((nint*)CurrentCppStructOpsVtable)[1] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Bool_False); // HasNoopConstructor - ((nint*)CurrentCppStructOpsVtable)[2] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Bool_True); // HasZeroConstructor - ((nint*)CurrentCppStructOpsVtable)[3] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Void); // Construct - ((nint*)CurrentCppStructOpsVtable)[4] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Void); // ConstructForTests - ((nint*)CurrentCppStructOpsVtable)[5] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Bool_False); // HasDestructor - ((nint*)CurrentCppStructOpsVtable)[6] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Void); // Destruct - ((nint*)CurrentCppStructOpsVtable)[7] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Bool_False); // HasSerializer - ((nint*)CurrentCppStructOpsVtable)[8] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Bool_False); // HasStructuredSerializer - ((nint*)CurrentCppStructOpsVtable)[9] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Bool_False); // Serialize(FArchive) - ((nint*)CurrentCppStructOpsVtable)[10] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Bool_False); // Serialize(FStructedArchive::FSlot) - ((nint*)CurrentCppStructOpsVtable)[11] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Bool_False); // HasPostSerialize - ((nint*)CurrentCppStructOpsVtable)[12] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Void); // PostSerializer - ((nint*)CurrentCppStructOpsVtable)[13] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Bool_False); // HasNetSerializer - ((nint*)CurrentCppStructOpsVtable)[14] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Bool_False); // HasNetSharedSerialization - ((nint*)CurrentCppStructOpsVtable)[15] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Void); // NetSerializer - ((nint*)CurrentCppStructOpsVtable)[16] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Bool_False); // HasNetDeltaSerializer - ((nint*)CurrentCppStructOpsVtable)[17] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Void); // NetDeltaSerialize - ((nint*)CurrentCppStructOpsVtable)[18] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Bool_False); // HasPostScriptConstruct - ((nint*)CurrentCppStructOpsVtable)[19] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Void); // PostScriptConstruct - ((nint*)CurrentCppStructOpsVtable)[20] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Bool_True); // IsPlainOldData - ((nint*)CurrentCppStructOpsVtable)[21] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Bool_True); // HasCopy - ((nint*)CurrentCppStructOpsVtable)[22] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Void); // Copy - ((nint*)CurrentCppStructOpsVtable)[23] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Bool_False); // HasIdentical - ((nint*)CurrentCppStructOpsVtable)[24] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Bool_False); // Identical - ((nint*)CurrentCppStructOpsVtable)[25] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Bool_False); // HasExportTextItem - ((nint*)CurrentCppStructOpsVtable)[26] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Bool_False); // ExportTextItem - ((nint*)CurrentCppStructOpsVtable)[27] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Bool_False); // HasImportTextItem - ((nint*)CurrentCppStructOpsVtable)[28] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Bool_False); // ImportTextItem - ((nint*)CurrentCppStructOpsVtable)[29] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Bool_False); // HasAddStructReferencedObjects - ((nint*)CurrentCppStructOpsVtable)[30] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Void); // AddStructReferencedObjects - ((nint*)CurrentCppStructOpsVtable)[31] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Bool_False); // HasSerializeFromMismatchTag - ((nint*)CurrentCppStructOpsVtable)[32] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Bool_False); // HasStructuredSerializeFromMismatchedTag - ((nint*)CurrentCppStructOpsVtable)[33] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Bool_False); // SerializeFroMismatchedTag - ((nint*)CurrentCppStructOpsVtable)[34] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Bool_False); // StructuredSerializeFroMismatchedTag - ((nint*)CurrentCppStructOpsVtable)[35] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Bool_False); // HasGetTypeHash - ((nint*)CurrentCppStructOpsVtable)[36] = (nint)(delegate* unmanaged[Stdcall])(&Noop_U32); // GetStructTypeHash - ((nint*)CurrentCppStructOpsVtable)[37] = (nint)(delegate* unmanaged[Stdcall])(&Noop_U32); // GetComputedPropertyFlags - ((nint*)CurrentCppStructOpsVtable)[38] = (nint)(delegate* unmanaged[Stdcall])(&Noop_Bool_False); // IsAbstract + ((nint*)CurrentCppStructOpsVtable)[0] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // ~ICppStructOps + ((nint*)CurrentCppStructOpsVtable)[1] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // HasNoopConstructor + ((nint*)CurrentCppStructOpsVtable)[2] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_True); // HasZeroConstructor + ((nint*)CurrentCppStructOpsVtable)[3] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // Construct + ((nint*)CurrentCppStructOpsVtable)[4] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // ConstructForTests + ((nint*)CurrentCppStructOpsVtable)[5] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // HasDestructor + ((nint*)CurrentCppStructOpsVtable)[6] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // Destruct + ((nint*)CurrentCppStructOpsVtable)[7] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // HasSerializer + ((nint*)CurrentCppStructOpsVtable)[8] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // HasStructuredSerializer + ((nint*)CurrentCppStructOpsVtable)[9] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // Serialize(FArchive) + ((nint*)CurrentCppStructOpsVtable)[10] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // Serialize(FStructedArchive::FSlot) + ((nint*)CurrentCppStructOpsVtable)[11] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // HasPostSerialize + ((nint*)CurrentCppStructOpsVtable)[12] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // PostSerializer + ((nint*)CurrentCppStructOpsVtable)[13] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // HasNetSerializer + ((nint*)CurrentCppStructOpsVtable)[14] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // HasNetSharedSerialization + ((nint*)CurrentCppStructOpsVtable)[15] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // NetSerializer + ((nint*)CurrentCppStructOpsVtable)[16] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // HasNetDeltaSerializer + ((nint*)CurrentCppStructOpsVtable)[17] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // NetDeltaSerialize + ((nint*)CurrentCppStructOpsVtable)[18] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // HasPostScriptConstruct + ((nint*)CurrentCppStructOpsVtable)[19] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // PostScriptConstruct + ((nint*)CurrentCppStructOpsVtable)[20] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_True); // IsPlainOldData + ((nint*)CurrentCppStructOpsVtable)[21] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_True); // HasCopy + ((nint*)CurrentCppStructOpsVtable)[22] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // Copy + ((nint*)CurrentCppStructOpsVtable)[23] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // HasIdentical + ((nint*)CurrentCppStructOpsVtable)[24] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // Identical + ((nint*)CurrentCppStructOpsVtable)[25] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // HasExportTextItem + ((nint*)CurrentCppStructOpsVtable)[26] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // ExportTextItem + ((nint*)CurrentCppStructOpsVtable)[27] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // HasImportTextItem + ((nint*)CurrentCppStructOpsVtable)[28] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // ImportTextItem + ((nint*)CurrentCppStructOpsVtable)[29] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // HasAddStructReferencedObjects + ((nint*)CurrentCppStructOpsVtable)[30] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // AddStructReferencedObjects + ((nint*)CurrentCppStructOpsVtable)[31] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // HasSerializeFromMismatchTag + ((nint*)CurrentCppStructOpsVtable)[32] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // HasStructuredSerializeFromMismatchedTag + ((nint*)CurrentCppStructOpsVtable)[33] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // SerializeFroMismatchedTag + ((nint*)CurrentCppStructOpsVtable)[34] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // StructuredSerializeFroMismatchedTag + ((nint*)CurrentCppStructOpsVtable)[35] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // HasGetTypeHash + ((nint*)CurrentCppStructOpsVtable)[36] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_U32); // GetStructTypeHash + ((nint*)CurrentCppStructOpsVtable)[37] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_U32); // GetComputedPropertyFlags + ((nint*)CurrentCppStructOpsVtable)[38] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // IsAbstract } internal override unsafe bool CreateStructParam(string Name, int Size, diff --git a/UE.Toolkit.Reloaded/Reflection/UE5_2_1/PropertyFactory.cs b/UE.Toolkit.Reloaded/Reflection/UE5_2_1/PropertyFactory.cs index fbb9850..407c684 100644 --- a/UE.Toolkit.Reloaded/Reflection/UE5_2_1/PropertyFactory.cs +++ b/UE.Toolkit.Reloaded/Reflection/UE5_2_1/PropertyFactory.cs @@ -5,7 +5,10 @@ using UE.Toolkit.Core.Types.Unreal.UE5_4_4; using UE.Toolkit.Interfaces; +using FField = UE.Toolkit.Core.Types.Unreal.UE4_27_2.FField; +using FFieldClass = UE.Toolkit.Core.Types.Unreal.UE4_27_2.FFieldClass; using FProperty = UE.Toolkit.Core.Types.Unreal.UE4_27_2.FProperty; +using UObjectBase = UE.Toolkit.Core.Types.Unreal.UE4_27_2.UObjectBase; namespace UE.Toolkit.Reloaded.Reflection.UE5_2_1; @@ -26,7 +29,7 @@ protected override unsafe void LinkToPropertyList(IFProperty Property, IUClass R if (((UStruct*)pClass)->PropertyLink == null) { ((UStruct*)pClass)->PropertyLink = (UE.Toolkit.Core.Types.Unreal.UE5_4_4.FProperty*)pProperty; - ((UStruct*)pClass)->ChildProperties = (FField*)pProperty; + ((UStruct*)pClass)->ChildProperties = (UE.Toolkit.Core.Types.Unreal.UE5_4_4.FField*)pProperty; } else { @@ -34,12 +37,12 @@ protected override unsafe void LinkToPropertyList(IFProperty Property, IUClass R var NextProp = TargetProp.PropertyLinkNext.Any() ? TargetProp.PropertyLinkNext.First() : null; var pTargetProp = (FProperty*)TargetProp.Ptr; pTargetProp->prop_link_next = pProperty; - ((FField*)pTargetProp)->Next = (FField*)pProperty; + ((FField*)pTargetProp)->next = (FField*)pProperty; if (NextProp != null) { var pNextProp = (FProperty*)NextProp.Ptr; pProperty->prop_link_next = pNextProp; - ((FField*)pProperty)->Next = (FField*)pNextProp; + ((FField*)pProperty)->next = (FField*)pNextProp; } } } @@ -48,12 +51,12 @@ protected override unsafe void SetPropertySuperFields(IFField Field, string Name FieldClassGlobal PropertyClass) { var pField = (FField*)Field.Ptr; - pField->VTable = PropertyClass.Vtable; - pField->ClassPrivate = (FFieldClass*)PropertyClass.Params.Ptr; - pField->Owner.Object = (UObjectBase*)ClassReflection.Ptr; // UClass* - pField->Next = null; - pField->NamePrivate = new FName(Name); - pField->FlagsPrivate = EObjectFlags.RF_Public | EObjectFlags.RF_MarkAsNative | EObjectFlags.RF_Transient; + pField->_vtable = PropertyClass.Vtable; + pField->class_private = (FFieldClass*)PropertyClass.Params.Ptr; + pField->owner.Object = (UObjectBase*)ClassReflection.Ptr; // UClass* + pField->next = null; + pField->name_private = new FName(Name); + pField->flags_private = EObjectFlags.RF_Public | EObjectFlags.RF_MarkAsNative | EObjectFlags.RF_Transient; } private unsafe void SetPropertyFieldDefaults(FProperty* pProperty, int Offset) diff --git a/UE.Toolkit.Reloaded/Unreal/UnrealClasses.cs b/UE.Toolkit.Reloaded/Unreal/UnrealClasses.cs index 39f5dd9..82fc8cd 100644 --- a/UE.Toolkit.Reloaded/Unreal/UnrealClasses.cs +++ b/UE.Toolkit.Reloaded/Unreal/UnrealClasses.cs @@ -453,33 +453,10 @@ public UnrealClasses(IUnrealFactory _Factory, IUnrealMemory _Memory, IUnrealObje Objects = _Objects; Hooks = _Hooks; Address = _Address; - - IPropertyFlagsBuilder FlagsBuilder = GameConfig.Instance.Id switch - { - "P3R" => new Reflection.UE4_27_2.PropertyFlagsBuilder(), - "UE5_2_1" => new Reflection.UE5_2_1.PropertyFlagsBuilder(), - "UE5_6_1" => new Reflection.UE5_6_1.PropertyFlagsBuilder(), - "UE5_7_4" => new Reflection.UE5_7_4.PropertyFlagsBuilder(), - _ => new Reflection.UE5_4_4.PropertyFlagsBuilder(), - }; - - PropertyFactory = GameConfig.Instance.Id switch - { - "P3R" => new Reflection.UE4_27_2.PropertyFactory(Factory, Memory, this, FlagsBuilder), - "UE5_2_1" => new Reflection.UE5_2_1.PropertyFactory(Factory, Memory, this, FlagsBuilder), - "UE5_6_1" => new Reflection.UE5_6_1.PropertyFactory(Factory, Memory, this, FlagsBuilder), - "UE5_7_4" => new Reflection.UE5_7_4.PropertyFactory(Factory, Memory, this, FlagsBuilder), - _ => new Reflection.UE5_4_4.PropertyFactory(Factory, Memory, this, FlagsBuilder), - }; - - TypeFactory = GameConfig.Instance.Id switch - { - "P3R" => new Reflection.UE4_27_2.TypeFactory(Factory, Memory, this, FlagsBuilder), - "UE5_2_1" => new Reflection.UE5_2_1.TypeFactory(Factory, Memory, this, FlagsBuilder), - "UE5_6_1" => new Reflection.UE5_6_1.TypeFactory(Factory, Memory, this, FlagsBuilder), - "UE5_7_4" => new Reflection.UE5_7_4.TypeFactory(Factory, Memory, this, FlagsBuilder), - _ => new Reflection.UE5_4_4.TypeFactory(Factory, Memory, this, FlagsBuilder), - }; + + var FlagsBuilder = GameConfig.Instance.FlagsBuilder; + PropertyFactory = GameConfig.Instance.PropertyFactory(this); + TypeFactory = GameConfig.Instance.TypeFactory(this); Project.Inis.UsingSetting(Constants.UnrealIniId, "Link", nameof(UStruct), value => UStructLinkOffset = value); diff --git a/UE.Toolkit.Reloaded/Unreal/UnrealObjects.cs b/UE.Toolkit.Reloaded/Unreal/UnrealObjects.cs index 782925b..8a70b86 100644 --- a/UE.Toolkit.Reloaded/Unreal/UnrealObjects.cs +++ b/UE.Toolkit.Reloaded/Unreal/UnrealObjects.cs @@ -109,7 +109,7 @@ public void OnObjectLoadedByClass(Action> callb public FText* CreateFText(string content) { var fstring = CreateFString(content); - var ftext = (FText*)UnrealMemory._FMemory!.Malloc(GameConfig.GetFTextSize()); + var ftext = (FText*)UnrealMemory._FMemory!.Malloc(GameConfig.Instance.GetFTextSize()); _FText_FromString!.Wrapper(ftext, fstring); UnrealMemory._FMemory.Free((nint)fstring); diff --git a/UE.Toolkit.Reloaded/Unreal/UnrealStrings.cs b/UE.Toolkit.Reloaded/Unreal/UnrealStrings.cs index 4e4a6f8..216fa94 100644 --- a/UE.Toolkit.Reloaded/Unreal/UnrealStrings.cs +++ b/UE.Toolkit.Reloaded/Unreal/UnrealStrings.cs @@ -44,7 +44,7 @@ public bool FTextInspectorGetTableIdAndKey(FText* text, [NotNullWhen(true)]out s public string UEnumGetDisplayNameTextByIndex(nint userEnum, int index) { - var outText = (FText*)Marshal.AllocHGlobal(GameConfig.GetFTextSize()); + var outText = (FText*)Marshal.AllocHGlobal(GameConfig.Instance.GetFTextSize()); var dispNameFText = _getDispNameTextByIdx.Wrapper((UUserDefinedEnum*)userEnum, outText, index); From 594b8c209641969dca55a3bbf84767bbaac4f7a3 Mon Sep 17 00:00:00 2001 From: Rirurin Date: Sun, 5 Jul 2026 10:18:03 +0800 Subject: [PATCH 5/7] Added FindObject for IUnrealObjects and UScriptStruct registration for UE 5.0 - 5.7 --- README.md | 2 +- .../Factories/UE4_27_2/UnrealFactory.cs | 3 +- .../Unreal/Factories/UE5_4_4/UnrealFactory.cs | 2 +- .../Unreal/Factories/UE5_7_4/UnrealFactory.cs | 2 +- .../Types/Unreal/UE5_2_1/FPropertyParams.cs | 40 +++++ .../Types/Unreal/UE5_4_4/FCapabilities.cs | 36 +++++ UE.Toolkit.Interfaces/IUnrealClasses.cs | 12 ++ UE.Toolkit.Interfaces/IUnrealObjects.cs | 32 ++++ .../Common/GameConfigs/GameConfig.cs | 5 +- .../Common/GameConfigs/Games/UE5_0_3.cs | 26 +++ .../Reflection/Common/FunctionPointers.cs | 7 + .../Reflection/UE4_27_2/TypeFactory.cs | 6 +- .../Reflection/UE5_2_1/TypeFactory.cs | 148 ++++++++++++------ .../Reflection/UE5_4_4/TypeFactory.cs | 144 +++++++++++------ .../Reflection/UE5_6_1/TypeFactory.cs | 144 +++++++++++------ .../Reflection/UE5_7_4/TypeFactory.cs | 144 +++++++++++------ UE.Toolkit.Reloaded/Unreal/UnrealClasses.cs | 20 +++ UE.Toolkit.Reloaded/Unreal/UnrealObjects.cs | 90 +++++++++-- 18 files changed, 658 insertions(+), 205 deletions(-) create mode 100644 UE.Toolkit.Core/Types/Unreal/UE5_2_1/FPropertyParams.cs create mode 100644 UE.Toolkit.Core/Types/Unreal/UE5_4_4/FCapabilities.cs create mode 100644 UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_0_3.cs diff --git a/README.md b/README.md index 750857f..d326009 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Object XML requires game-specific support with an extension mod. Supported games | Type Information |✅|✅|✅|✅|✅|✅|✅|✅|✅ | Custom Constructor |✅|✅|✅|✅|✅|✅|✅|✅|✅ | Add Properties |✅|✅|✅|✅|✅|✅|✅|✅|✅ -| Register Struct |✅|❔|❔|❔|❔|❌|❔|❔|❔ +| Register Struct |✅|✅|✅|✅|✅|✅|✅|✅|✅ Features marked with ❔ are currently untested. diff --git a/UE.Toolkit.Core/Types/Unreal/Factories/UE4_27_2/UnrealFactory.cs b/UE.Toolkit.Core/Types/Unreal/Factories/UE4_27_2/UnrealFactory.cs index 301d685..8752a36 100644 --- a/UE.Toolkit.Core/Types/Unreal/Factories/UE4_27_2/UnrealFactory.cs +++ b/UE.Toolkit.Core/Types/Unreal/Factories/UE4_27_2/UnrealFactory.cs @@ -532,8 +532,7 @@ public unsafe class UObjectArrayUE4_27_2(nint ptr, IUnrealFactory factory) : IUO public IUObject? IndexToObject(int idx) { var objItem = _self->ObjObjects.GetItem(idx); - if (objItem == null || objItem->Object == null) return null; - + if (objItem == null || objItem->Object == null || objItem->Flags.HasFlag(EInternalObjectFlags.Unreachable)) return null; return factory.CreateUObject((nint)objItem->Object); } diff --git a/UE.Toolkit.Core/Types/Unreal/Factories/UE5_4_4/UnrealFactory.cs b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_4_4/UnrealFactory.cs index e766436..8ec04f6 100644 --- a/UE.Toolkit.Core/Types/Unreal/Factories/UE5_4_4/UnrealFactory.cs +++ b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_4_4/UnrealFactory.cs @@ -470,7 +470,7 @@ public unsafe class UObjectArray_UE5_4_4(nint ptr, IUnrealFactory factory) : IUO public IUObject? IndexToObject(int idx) { var objItem = _self->ObjObjects.GetItem(idx); - if (objItem == null || objItem->Object == null) return null; + if (objItem == null || objItem->Object == null || objItem->Flags.HasFlag(EInternalObjectFlags.Unreachable)) return null; return factory.CreateUObject((nint)objItem->Object); } diff --git a/UE.Toolkit.Core/Types/Unreal/Factories/UE5_7_4/UnrealFactory.cs b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_7_4/UnrealFactory.cs index 324e272..e61a6b2 100644 --- a/UE.Toolkit.Core/Types/Unreal/Factories/UE5_7_4/UnrealFactory.cs +++ b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_7_4/UnrealFactory.cs @@ -101,7 +101,7 @@ public unsafe class UObjectArray_UE5_7_4(nint ptr, IUnrealFactory factory) : IUO public IUObject? IndexToObject(int idx) { var objItem = _self->ObjObjects.GetItem(idx); - if (objItem == null || objItem->Object == null) return null; + if (objItem == null || objItem->Object == null || objItem->Flags.HasFlag(EInternalObjectFlags.Unreachable)) return null; return factory.CreateUObject((nint)objItem->Object); } diff --git a/UE.Toolkit.Core/Types/Unreal/UE5_2_1/FPropertyParams.cs b/UE.Toolkit.Core/Types/Unreal/UE5_2_1/FPropertyParams.cs new file mode 100644 index 0000000..02e5286 --- /dev/null +++ b/UE.Toolkit.Core/Types/Unreal/UE5_2_1/FPropertyParams.cs @@ -0,0 +1,40 @@ +using System.Runtime.InteropServices; +using EObjectFlags = UE.Toolkit.Core.Types.Unreal.UE5_4_4.EObjectFlags; +using EPropertyFlags = UE.Toolkit.Core.Types.Unreal.UE5_4_4.EPropertyFlags; +using EPropertyGenFlags = UE.Toolkit.Core.Types.Unreal.UE5_4_4.EPropertyGenFlags; + +namespace UE.Toolkit.Core.Types.Unreal.UE5_2_1; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct FPropertyParamsBase +{ + public nint NameUTF8; + public nint RepNotifyFuncUTF8; + public EPropertyFlags PropertyFlags; + public EPropertyGenFlags PropertyGenFlags; + public EObjectFlags ObjectFlags; + public int ArrayDim; + public delegate* unmanaged[Stdcall] SetterFuncPtr; + public delegate* unmanaged[Stdcall] GetterFuncPtr; +} + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct FPropertyParamsBaseWithOffset +{ + // public FPropertyParamsBase Super; + public nint NameUTF8; + public nint RepNotifyFuncUTF8; + public EPropertyFlags PropertyFlags; + public EPropertyGenFlags PropertyGenFlags; + public EObjectFlags ObjectFlags; + public int ArrayDim; + public delegate* unmanaged[Stdcall] SetterFuncPtr; + public delegate* unmanaged[Stdcall] GetterFuncPtr; + public int Offset; +} + +[StructLayout(LayoutKind.Sequential)] +public struct FGenericPropertyParams +{ + public FPropertyParamsBaseWithOffset Super; +} \ No newline at end of file diff --git a/UE.Toolkit.Core/Types/Unreal/UE5_4_4/FCapabilities.cs b/UE.Toolkit.Core/Types/Unreal/UE5_4_4/FCapabilities.cs new file mode 100644 index 0000000..1b89603 --- /dev/null +++ b/UE.Toolkit.Core/Types/Unreal/UE5_4_4/FCapabilities.cs @@ -0,0 +1,36 @@ +using System.Runtime.InteropServices; + +namespace UE.Toolkit.Core.Types.Unreal.UE5_4_4; + +public enum CapabilityFlags : uint +{ + HasNoopConstructor = 1 << 0, + HasZeroConstructor = 1 << 1, + HasDestructor = 1 << 2, + HasSerializer = 1 << 3, + HasStructuredSerializer = 1 << 4, + HasPostSerialize = 1 << 5, + HasNetSerializer = 1 << 6, + HasNetSharedSerialization = 1 << 7, + HasNetDeltaSerializer = 1 << 8, + HasPostScriptConstruct = 1 << 9, + IsPlainOldData = 1 << 10, + IsUECoreType = 1 << 11, + IsUECoreVariant = 1 << 12, + HasCopy = 1 << 13, + HasIdentical = 1 << 14, + HasExportTextItem = 1 << 15, + HasImportTextItem = 1 << 16, + HasAddStructReferencedObjects = 1 << 17, + HasSerializeFromMismatchedTag = 1 << 18, + HasStructuredSerializeFromMismatchedTag = 1 << 19, + HasGetTypeHash = 1 << 20, + IsAbstract = 1 << 21, +} + +[StructLayout(LayoutKind.Sequential)] +public struct FCapabilities +{ + public EPropertyFlags ComputedPropertyFlags; + public CapabilityFlags CapabilityFlags; +} \ No newline at end of file diff --git a/UE.Toolkit.Interfaces/IUnrealClasses.cs b/UE.Toolkit.Interfaces/IUnrealClasses.cs index ba1f90e..0c57003 100644 --- a/UE.Toolkit.Interfaces/IUnrealClasses.cs +++ b/UE.Toolkit.Interfaces/IUnrealClasses.cs @@ -276,6 +276,18 @@ public bool AddArrayProperty(string Name, int Offset, IFProperty Inner, #region New Struct Construction + /// + /// Get the package object for the engine "/Script/Engine" + /// + /// The package object for the engine if it's been initialized. + public IUObject? GetEnginePackage(); + + /// + /// Get the package object for the game + /// + /// The package object for the game if it's been initialized. + public IUObject? GetGamePackage(); + /// /// Create a Int8 param to insert into a struct param's property list. This is used when registering new /// struct types to the engine at runtime. diff --git a/UE.Toolkit.Interfaces/IUnrealObjects.cs b/UE.Toolkit.Interfaces/IUnrealObjects.cs index 17db782..299409f 100644 --- a/UE.Toolkit.Interfaces/IUnrealObjects.cs +++ b/UE.Toolkit.Interfaces/IUnrealObjects.cs @@ -65,6 +65,38 @@ void OnObjectLoadedByClass(Action> callback) /// Implemented as a post-hook on UObject::PostLoadSubobjects, allowing for editing object data before use. void OnObjectLoadedByClass(string objClass, Action> callback) where TObject : unmanaged; + + /// + /// Finds an object based on the given name. + /// + /// Object name. + /// Class name. + /// A if an object was found with a matching name. + IUObject? FindObjectByName(string objectName, string className); + + /// + /// Finds an object based on the given name. + /// + /// Object name. + /// Object type. + /// A if an object was found with a matching name. + ToolkitUObject? FindObjectByName(string objectName) + where TObject : unmanaged; + + /// + /// Finds the first object matching a specified type. + /// + /// Class name. + /// A if an object was found with the specified type. + IUObject? FindObjectByClass(string className); + + /// + /// Finds the first object matching a specified type. + /// + /// Object type. + /// A if an object was found with the specified type. + ToolkitUObject? FindObjectByClass() + where TObject : unmanaged; } /// diff --git a/UE.Toolkit.Reloaded/Common/GameConfigs/GameConfig.cs b/UE.Toolkit.Reloaded/Common/GameConfigs/GameConfig.cs index 06449d7..53d92b4 100644 --- a/UE.Toolkit.Reloaded/Common/GameConfigs/GameConfig.cs +++ b/UE.Toolkit.Reloaded/Common/GameConfigs/GameConfig.cs @@ -27,8 +27,9 @@ public static void SetGame(string appId) Instance = appId switch { "p3r.exe" or "smt5v-win64-shipping.exe" => new UE4_27_2_P3R(), - "iostoretest_50-win64-shipping.exe" or "iostoretest_51-win64-shipping.exe" - or "iostoretest_52-win64-shipping.exe" or "chronos-win64-shipping.exe" => new UE5_2_1(), + "iostoretest_50-win64-shipping.exe" => new UE5_0_3(), + "iostoretest_51-win64-shipping.exe" or "iostoretest_52-win64-shipping.exe" + or "chronos-win64-shipping.exe" => new UE5_2_1(), "iostoretest_53-win64-shipping.exe" => new UE5_3_2(), "iostoretest_56-win64-shipping.exe" => new UE5_6_1(), "iostoretest_57-win64-shipping.exe" => new UE5_7_4(), diff --git a/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_0_3.cs b/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_0_3.cs new file mode 100644 index 0000000..1c672d8 --- /dev/null +++ b/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_0_3.cs @@ -0,0 +1,26 @@ +using UE.Toolkit.Core.Types.Unreal.Factories; +using UE.Toolkit.Core.Types.Unreal.Factories.UE5_2_1; +using UE.Toolkit.Interfaces; +using UE.Toolkit.Reloaded.Reflection; +using UE.Toolkit.Reloaded.Reflection.UE5_2_1; +using UE.Toolkit.Reloaded.Unreal; + +namespace UE.Toolkit.Reloaded.Common.GameConfigs.Games; + +public class UE5_0_3 : UE5_4_4_ClairObscur +{ + public override string Id => "P3R"; + public override IUnrealFactory Factory { get; } = new UnrealFactory(); + public override IUnrealMemory Memory { get; } = new UnrealMemory(); + public override IPropertyFlagsBuilder FlagsBuilder { get; } = new PropertyFlagsBuilder(); + + public override BasePropertyFactory PropertyFactory(IUnrealClasses classes) + => new PropertyFactory(Factory, Memory, classes, FlagsBuilder); + + public override BaseTypeFactory TypeFactory(IUnrealClasses classes) + => new UE.Toolkit.Reloaded.Reflection.UE4_27_2.TypeFactory(Factory, Memory, classes, FlagsBuilder); + + public override Type GetFText() => typeof(UE.Toolkit.Core.Types.Unreal.UE4_27_2.FText); + + public override unsafe int GetFTextSize() => sizeof(UE.Toolkit.Core.Types.Unreal.UE4_27_2.FText); +} \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Reflection/Common/FunctionPointers.cs b/UE.Toolkit.Reloaded/Reflection/Common/FunctionPointers.cs index f0d16ad..09205e9 100644 --- a/UE.Toolkit.Reloaded/Reflection/Common/FunctionPointers.cs +++ b/UE.Toolkit.Reloaded/Reflection/Common/FunctionPointers.cs @@ -1,5 +1,6 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using UE.Toolkit.Core.Types.Unreal.UE5_4_4; namespace UE.Toolkit.Reloaded.Reflection.Common; @@ -16,4 +17,10 @@ internal static void Noop_Void() {} [UnmanagedCallersOnly(CallConvs = [typeof(CallConvStdcall)])] internal static uint Noop_U32() => 0; + + [UnmanagedCallersOnly(CallConvs = [typeof(CallConvStdcall)])] + internal static unsafe FCapabilities* Noop_GetCapabilities(nint self, FCapabilities* __return_storage_ptr__) + { + return __return_storage_ptr__; + } } \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Reflection/UE4_27_2/TypeFactory.cs b/UE.Toolkit.Reloaded/Reflection/UE4_27_2/TypeFactory.cs index ca40592..48e0024 100644 --- a/UE.Toolkit.Reloaded/Reflection/UE4_27_2/TypeFactory.cs +++ b/UE.Toolkit.Reloaded/Reflection/UE4_27_2/TypeFactory.cs @@ -51,7 +51,7 @@ private unsafe void CreateCppStructOpsVtable() ((nint*)CurrentCppStructOpsVtable)[7] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // HasSerializer ((nint*)CurrentCppStructOpsVtable)[8] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // HasStructuredSerializer ((nint*)CurrentCppStructOpsVtable)[9] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // Serialize(FArchive) - ((nint*)CurrentCppStructOpsVtable)[10] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // Serialize(FStructedArchive::FSlot) + ((nint*)CurrentCppStructOpsVtable)[10] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // Serialize(FStructuredArchive::FSlot) ((nint*)CurrentCppStructOpsVtable)[11] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // HasPostSerialize ((nint*)CurrentCppStructOpsVtable)[12] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // PostSerializer ((nint*)CurrentCppStructOpsVtable)[13] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // HasNetSerializer @@ -86,7 +86,9 @@ internal override unsafe bool CreateStructParam(string Name, int Size, List Fields, out IFStructParams? Out) { var pProperties = (FPropertyParamsBase**)Memory.MallocZeroed(Marshal.SizeOf() * Fields.Count); - var StructParamStatic = (FStructParams*)Memory.MallocZeroed(Marshal.SizeOf()); + var StructParamStatic = (FStructParams*)Memory.MallocZeroed(Marshal.SizeOf()); + // Retrieve the game package so the reference to it is valid when FStructProperty::OuterFunc is called + _ = Classes.GetGamePackage(); StructParamStatic->OuterFunc = (nint)(delegate* unmanaged[Stdcall])(&Unreal.UnrealClasses.FStructProperty_OuterFunc_Callback); StructParamStatic->SuperFunc = nint.Zero; StructParamStatic->StructOpsFunc = (nint)(delegate* unmanaged[Stdcall])(&InitializeCppStructOps); diff --git a/UE.Toolkit.Reloaded/Reflection/UE5_2_1/TypeFactory.cs b/UE.Toolkit.Reloaded/Reflection/UE5_2_1/TypeFactory.cs index 2d7231d..c925a88 100644 --- a/UE.Toolkit.Reloaded/Reflection/UE5_2_1/TypeFactory.cs +++ b/UE.Toolkit.Reloaded/Reflection/UE5_2_1/TypeFactory.cs @@ -1,6 +1,14 @@ -using UE.Toolkit.Core.Types.Unreal.Factories; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using UE.Toolkit.Core.Types.Unreal.Factories; using UE.Toolkit.Core.Types.Unreal.Factories.Interfaces; +using UE.Toolkit.Core.Types.Unreal.UE5_4_4; using UE.Toolkit.Interfaces; +using UE.Toolkit.Reloaded.Reflection.Common; + +using FGenericPropertyParams = UE.Toolkit.Core.Types.Unreal.UE5_2_1.FGenericPropertyParams; +using FPropertyParamsBase = UE.Toolkit.Core.Types.Unreal.UE4_27_2.FPropertyParamsBase; +using FStructParams = UE.Toolkit.Core.Types.Unreal.UE4_27_2.FStructParams; namespace UE.Toolkit.Reloaded.Reflection.UE5_2_1; @@ -8,70 +16,120 @@ public class TypeFactory(IUnrealFactory factory, IUnrealMemory memory, IUnrealClasses classes, IPropertyFlagsBuilder flags) : BaseTypeFactory(factory, memory, classes, flags) { - public override bool CreateI8Param(string Name, int Offset, out IFGenericPropertyParams? Out) + private static Func? FMemory_Malloc_Static = null; + private static nint Malloc_Static_Size = 0; + + private static nint CurrentCppStructOpsVtable; + private static uint CurrentCppStructOpsSize; + private const uint CPP_STRUCT_OPS_ALIGNMENT = 0x8; + private const nint CPP_STRUCT_OPS_VTABLE_SIZE = 20; + + [UnmanagedCallersOnly(CallConvs = [typeof(CallConvStdcall)])] + private static unsafe nint InitializeCppStructOps() { - Out = null; - return false; + var Alloc = (ICppStructOps*)FMemory_Malloc_Static!(Marshal.SizeOf(), 0); + Alloc->VTable = CurrentCppStructOpsVtable; + Alloc->Size = CurrentCppStructOpsSize; + Alloc->Alignment = CPP_STRUCT_OPS_ALIGNMENT; + return (nint)Alloc; } - public override bool CreateI16Param(string Name, int Offset, out IFGenericPropertyParams? Out) + // UScriptStruct::ICppStructOps + private unsafe void CreateCppStructOpsVtable() { - Out = null; - return false; + ((nint*)CurrentCppStructOpsVtable)[0] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // ~ICppStructOps + ((nint*)CurrentCppStructOpsVtable)[1] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_GetCapabilities); // GetCapabilities + ((nint*)CurrentCppStructOpsVtable)[2] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // Construct + ((nint*)CurrentCppStructOpsVtable)[3] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // ConstructForTests + ((nint*)CurrentCppStructOpsVtable)[4] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // Destruct + ((nint*)CurrentCppStructOpsVtable)[5] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // Serialize(FArchive) + ((nint*)CurrentCppStructOpsVtable)[6] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // Serialize(FStructuredArchive) + ((nint*)CurrentCppStructOpsVtable)[7] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // PostSerialize + ((nint*)CurrentCppStructOpsVtable)[8] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // NetSerialize + ((nint*)CurrentCppStructOpsVtable)[9] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // NetDeltaSerialize + ((nint*)CurrentCppStructOpsVtable)[10] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // PostScriptConstruct + ((nint*)CurrentCppStructOpsVtable)[11] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // GetPreloadDependencies + ((nint*)CurrentCppStructOpsVtable)[12] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // Copy + ((nint*)CurrentCppStructOpsVtable)[13] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // Identical + ((nint*)CurrentCppStructOpsVtable)[14] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // ExportTextItem + ((nint*)CurrentCppStructOpsVtable)[15] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // ImportTextItem + ((nint*)CurrentCppStructOpsVtable)[16] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // AddStructReferencedObjects + ((nint*)CurrentCppStructOpsVtable)[17] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // SerializeFromMismatchedTag + ((nint*)CurrentCppStructOpsVtable)[18] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // StructuredSerializeFromMismatchedTag + ((nint*)CurrentCppStructOpsVtable)[19] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_U32); // GetStructTypeHash } - public override bool CreateI32Param(string Name, int Offset, out IFGenericPropertyParams? Out) + internal override unsafe bool CreateStructParam(string Name, int Size, + List Fields, out IFStructParams? Out) { - Out = null; - return false; + var pProperties = (FPropertyParamsBase**)Memory.MallocZeroed(Marshal.SizeOf() * Fields.Count); + var StructParamStatic = (FStructParams*)Memory.MallocZeroed(Marshal.SizeOf()); + // Retrieve the game package so the reference to it is valid when FStructProperty::OuterFunc is called + _ = Classes.GetGamePackage(); + StructParamStatic->OuterFunc = (nint)(delegate* unmanaged[Stdcall])(&Unreal.UnrealClasses.FStructProperty_OuterFunc_Callback); + StructParamStatic->SuperFunc = nint.Zero; + StructParamStatic->StructOpsFunc = (nint)(delegate* unmanaged[Stdcall])(&InitializeCppStructOps); + StructParamStatic->NameUTF8 = Marshal.StringToHGlobalAnsi(Name); + StructParamStatic->SizeOf = (ulong)Size; + StructParamStatic->AlignOf = CPP_STRUCT_OPS_ALIGNMENT; // alignof(nint) + StructParamStatic->Properties = pProperties; + StructParamStatic->NumProperties = Fields.Count; + StructParamStatic->ObjectFlags = EObjectFlags.RF_Public | EObjectFlags.RF_MarkAsNative | EObjectFlags.RF_Transient; + StructParamStatic->StructFlags = EStructFlags.STRUCT_Native; + foreach (var (i, Field) in Fields.Select((x, i) => (i, x))) + StructParamStatic->Properties[i] = (FPropertyParamsBase*)Field.Ptr; + Out = Factory.CreateFStructParams((nint)StructParamStatic); + FMemory_Malloc_Static ??= (size, align) => Memory.MallocZeroed(size, align); + // sizeof(UScriptStruct::ICppStructOps::VTable) + CurrentCppStructOpsVtable = Memory.MallocZeroed(Marshal.SizeOf() * CPP_STRUCT_OPS_VTABLE_SIZE); + CurrentCppStructOpsSize = (uint)Size; + CreateCppStructOpsVtable(); + return true; } - public override bool CreateI64Param(string Name, int Offset, out IFGenericPropertyParams? Out) + private unsafe bool CreateGenericParam(string Name, int Offset, + EPropertyGenFlags GenFlags, out IFGenericPropertyParams? Out) { - Out = null; - return false; - } + var PropParamStatic = (FGenericPropertyParams*)Memory.Malloc(Marshal.SizeOf()); + PropParamStatic->Super.NameUTF8 = Marshal.StringToHGlobalAnsi(Name); + PropParamStatic->Super.RepNotifyFuncUTF8 = nint.Zero; + PropParamStatic->Super.PropertyFlags = Flags.CreatePropertyFlags(PropertyVisibility.Public, PropertyBuilderFlags.None); + PropParamStatic->Super.PropertyGenFlags = GenFlags; + PropParamStatic->Super.ObjectFlags = EObjectFlags.RF_Public | EObjectFlags.RF_MarkAsNative | + EObjectFlags.RF_Transient; + PropParamStatic->Super.ArrayDim = 1; + PropParamStatic->Super.Offset = Offset; + Out = Factory.CreateFGenericPropertyParams((nint)PropParamStatic); + return true; + } + + public override bool CreateI8Param(string Name, int Offset, out IFGenericPropertyParams? Out) + => CreateGenericParam(Name, Offset, EPropertyGenFlags.Int8, out Out); + + public override bool CreateI16Param(string Name, int Offset, out IFGenericPropertyParams? Out) + => CreateGenericParam(Name, Offset, EPropertyGenFlags.Int16, out Out); + + public override bool CreateI32Param(string Name, int Offset, out IFGenericPropertyParams? Out) + => CreateGenericParam(Name, Offset, EPropertyGenFlags.Int, out Out); + + public override bool CreateI64Param(string Name, int Offset, out IFGenericPropertyParams? Out) + => CreateGenericParam(Name, Offset, EPropertyGenFlags.Int64, out Out); public override bool CreateU8Param(string Name, int Offset, out IFGenericPropertyParams? Out) - { - Out = null; - return false; - } + => CreateGenericParam(Name, Offset, EPropertyGenFlags.Int8, out Out); public override bool CreateU16Param(string Name, int Offset, out IFGenericPropertyParams? Out) - { - Out = null; - return false; - } + => CreateGenericParam(Name, Offset, EPropertyGenFlags.UInt16, out Out); public override bool CreateU32Param(string Name, int Offset, out IFGenericPropertyParams? Out) - { - Out = null; - return false; - } + => CreateGenericParam(Name, Offset, EPropertyGenFlags.UInt32, out Out); public override bool CreateU64Param(string Name, int Offset, out IFGenericPropertyParams? Out) - { - Out = null; - return false; - } + => CreateGenericParam(Name, Offset, EPropertyGenFlags.UInt64, out Out); public override bool CreateF32Param(string Name, int Offset, out IFGenericPropertyParams? Out) - { - Out = null; - return false; - } + => CreateGenericParam(Name, Offset, EPropertyGenFlags.Float, out Out); public override bool CreateF64Param(string Name, int Offset, out IFGenericPropertyParams? Out) - { - Out = null; - return false; - } - - internal override unsafe bool CreateStructParam(string Name, int Size, - List Fields, out IFStructParams? Out) - { - Out = null; - return false; - } + => CreateGenericParam(Name, Offset, EPropertyGenFlags.Double, out Out); } \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Reflection/UE5_4_4/TypeFactory.cs b/UE.Toolkit.Reloaded/Reflection/UE5_4_4/TypeFactory.cs index 8da6ad5..e5d2f64 100644 --- a/UE.Toolkit.Reloaded/Reflection/UE5_4_4/TypeFactory.cs +++ b/UE.Toolkit.Reloaded/Reflection/UE5_4_4/TypeFactory.cs @@ -1,6 +1,10 @@ -using UE.Toolkit.Core.Types.Unreal.Factories; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using UE.Toolkit.Core.Types.Unreal.Factories; using UE.Toolkit.Core.Types.Unreal.Factories.Interfaces; +using UE.Toolkit.Core.Types.Unreal.UE5_4_4; using UE.Toolkit.Interfaces; +using UE.Toolkit.Reloaded.Reflection.Common; namespace UE.Toolkit.Reloaded.Reflection.UE5_4_4; @@ -8,70 +12,120 @@ public class TypeFactory(IUnrealFactory factory, IUnrealMemory memory, IUnrealClasses classes, IPropertyFlagsBuilder flags) : BaseTypeFactory(factory, memory, classes, flags) { - public override bool CreateI8Param(string Name, int Offset, out IFGenericPropertyParams? Out) + private static Func? FMemory_Malloc_Static = null; + private static nint Malloc_Static_Size = 0; + + private static nint CurrentCppStructOpsVtable; + private static uint CurrentCppStructOpsSize; + private const uint CPP_STRUCT_OPS_ALIGNMENT = 0x8; + private const nint CPP_STRUCT_OPS_VTABLE_SIZE = 20; + + [UnmanagedCallersOnly(CallConvs = [typeof(CallConvStdcall)])] + private static unsafe nint InitializeCppStructOps() { - Out = null; - return false; + var Alloc = (ICppStructOps*)FMemory_Malloc_Static!(Marshal.SizeOf(), 0); + Alloc->VTable = CurrentCppStructOpsVtable; + Alloc->Size = CurrentCppStructOpsSize; + Alloc->Alignment = CPP_STRUCT_OPS_ALIGNMENT; + return (nint)Alloc; } - public override bool CreateI16Param(string Name, int Offset, out IFGenericPropertyParams? Out) + // UScriptStruct::ICppStructOps + private unsafe void CreateCppStructOpsVtable() { - Out = null; - return false; + ((nint*)CurrentCppStructOpsVtable)[0] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // ~ICppStructOps + ((nint*)CurrentCppStructOpsVtable)[1] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_GetCapabilities); // GetCapabilities + ((nint*)CurrentCppStructOpsVtable)[2] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // Construct + ((nint*)CurrentCppStructOpsVtable)[3] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // ConstructForTests + ((nint*)CurrentCppStructOpsVtable)[4] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // Destruct + ((nint*)CurrentCppStructOpsVtable)[5] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // Serialize(FArchive) + ((nint*)CurrentCppStructOpsVtable)[6] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // Serialize(FStructuredArchive) + ((nint*)CurrentCppStructOpsVtable)[7] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // PostSerialize + ((nint*)CurrentCppStructOpsVtable)[8] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // NetSerialize + ((nint*)CurrentCppStructOpsVtable)[9] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // NetDeltaSerialize + ((nint*)CurrentCppStructOpsVtable)[10] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // PostScriptConstruct + ((nint*)CurrentCppStructOpsVtable)[11] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // GetPreloadDependencies + ((nint*)CurrentCppStructOpsVtable)[12] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // Copy + ((nint*)CurrentCppStructOpsVtable)[13] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // Identical + ((nint*)CurrentCppStructOpsVtable)[14] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // ExportTextItem + ((nint*)CurrentCppStructOpsVtable)[15] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // ImportTextItem + ((nint*)CurrentCppStructOpsVtable)[16] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // AddStructReferencedObjects + ((nint*)CurrentCppStructOpsVtable)[17] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // SerializeFromMismatchedTag + ((nint*)CurrentCppStructOpsVtable)[18] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // StructuredSerializeFromMismatchedTag + ((nint*)CurrentCppStructOpsVtable)[19] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_U32); // GetStructTypeHash } - public override bool CreateI32Param(string Name, int Offset, out IFGenericPropertyParams? Out) + internal override unsafe bool CreateStructParam(string Name, int Size, + List Fields, out IFStructParams? Out) { - Out = null; - return false; + var pProperties = (FPropertyParamsBase**)Memory.MallocZeroed(Marshal.SizeOf() * Fields.Count); + var StructParamStatic = (FStructParams*)Memory.MallocZeroed(Marshal.SizeOf()); + // Retrieve the game package so the reference to it is valid when FStructProperty::OuterFunc is called + _ = Classes.GetGamePackage(); + StructParamStatic->OuterFunc = (nint)(delegate* unmanaged[Stdcall])(&Unreal.UnrealClasses.FStructProperty_OuterFunc_Callback); + StructParamStatic->SuperFunc = nint.Zero; + StructParamStatic->StructOpsFunc = (nint)(delegate* unmanaged[Stdcall])(&InitializeCppStructOps); + StructParamStatic->NameUTF8 = Marshal.StringToHGlobalAnsi(Name); + StructParamStatic->SizeOf = (ushort)Size; + StructParamStatic->AlignOf = (byte)CPP_STRUCT_OPS_ALIGNMENT; // alignof(nint) + StructParamStatic->Properties = pProperties; + StructParamStatic->NumProperties = (ushort)Fields.Count; + StructParamStatic->ObjectFlags = EObjectFlags.RF_Public | EObjectFlags.RF_MarkAsNative | EObjectFlags.RF_Transient; + StructParamStatic->StructFlags = EStructFlags.STRUCT_Native; + foreach (var (i, Field) in Fields.Select((x, i) => (i, x))) + StructParamStatic->Properties[i] = (FPropertyParamsBase*)Field.Ptr; + Out = Factory.CreateFStructParams((nint)StructParamStatic); + FMemory_Malloc_Static ??= (size, align) => Memory.MallocZeroed(size, align); + // sizeof(UScriptStruct::ICppStructOps::VTable) + CurrentCppStructOpsVtable = Memory.MallocZeroed(Marshal.SizeOf() * CPP_STRUCT_OPS_VTABLE_SIZE); + CurrentCppStructOpsSize = (uint)Size; + CreateCppStructOpsVtable(); + return true; } - public override bool CreateI64Param(string Name, int Offset, out IFGenericPropertyParams? Out) + private unsafe bool CreateGenericParam(string Name, int Offset, + EPropertyGenFlags GenFlags, out IFGenericPropertyParams? Out) { - Out = null; - return false; - } + var PropParamStatic = (FGenericPropertyParams*)Memory.Malloc(Marshal.SizeOf()); + PropParamStatic->Super.NameUTF8 = Marshal.StringToHGlobalAnsi(Name); + PropParamStatic->Super.RepNotifyFuncUTF8 = nint.Zero; + PropParamStatic->Super.PropertyFlags = Flags.CreatePropertyFlags(PropertyVisibility.Public, PropertyBuilderFlags.None); + PropParamStatic->Super.PropertyGenFlags = GenFlags; + PropParamStatic->Super.ObjectFlags = EObjectFlags.RF_Public | EObjectFlags.RF_MarkAsNative | + EObjectFlags.RF_Transient; + PropParamStatic->Super.ArrayDim = 1; + PropParamStatic->Super.Offset = (ushort)Offset; + Out = Factory.CreateFGenericPropertyParams((nint)PropParamStatic); + return true; + } + + public override bool CreateI8Param(string Name, int Offset, out IFGenericPropertyParams? Out) + => CreateGenericParam(Name, Offset, EPropertyGenFlags.Int8, out Out); + + public override bool CreateI16Param(string Name, int Offset, out IFGenericPropertyParams? Out) + => CreateGenericParam(Name, Offset, EPropertyGenFlags.Int16, out Out); + + public override bool CreateI32Param(string Name, int Offset, out IFGenericPropertyParams? Out) + => CreateGenericParam(Name, Offset, EPropertyGenFlags.Int, out Out); + + public override bool CreateI64Param(string Name, int Offset, out IFGenericPropertyParams? Out) + => CreateGenericParam(Name, Offset, EPropertyGenFlags.Int64, out Out); public override bool CreateU8Param(string Name, int Offset, out IFGenericPropertyParams? Out) - { - Out = null; - return false; - } + => CreateGenericParam(Name, Offset, EPropertyGenFlags.Int8, out Out); public override bool CreateU16Param(string Name, int Offset, out IFGenericPropertyParams? Out) - { - Out = null; - return false; - } + => CreateGenericParam(Name, Offset, EPropertyGenFlags.UInt16, out Out); public override bool CreateU32Param(string Name, int Offset, out IFGenericPropertyParams? Out) - { - Out = null; - return false; - } + => CreateGenericParam(Name, Offset, EPropertyGenFlags.UInt32, out Out); public override bool CreateU64Param(string Name, int Offset, out IFGenericPropertyParams? Out) - { - Out = null; - return false; - } + => CreateGenericParam(Name, Offset, EPropertyGenFlags.UInt64, out Out); public override bool CreateF32Param(string Name, int Offset, out IFGenericPropertyParams? Out) - { - Out = null; - return false; - } + => CreateGenericParam(Name, Offset, EPropertyGenFlags.Float, out Out); public override bool CreateF64Param(string Name, int Offset, out IFGenericPropertyParams? Out) - { - Out = null; - return false; - } - - internal override unsafe bool CreateStructParam(string Name, int Size, - List Fields, out IFStructParams? Out) - { - Out = null; - return false; - } + => CreateGenericParam(Name, Offset, EPropertyGenFlags.Double, out Out); } \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Reflection/UE5_6_1/TypeFactory.cs b/UE.Toolkit.Reloaded/Reflection/UE5_6_1/TypeFactory.cs index 785ee80..048993f 100644 --- a/UE.Toolkit.Reloaded/Reflection/UE5_6_1/TypeFactory.cs +++ b/UE.Toolkit.Reloaded/Reflection/UE5_6_1/TypeFactory.cs @@ -1,6 +1,10 @@ -using UE.Toolkit.Core.Types.Unreal.Factories; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using UE.Toolkit.Core.Types.Unreal.Factories; using UE.Toolkit.Core.Types.Unreal.Factories.Interfaces; +using UE.Toolkit.Core.Types.Unreal.UE5_4_4; using UE.Toolkit.Interfaces; +using UE.Toolkit.Reloaded.Reflection.Common; namespace UE.Toolkit.Reloaded.Reflection.UE5_6_1; @@ -8,70 +12,120 @@ public class TypeFactory(IUnrealFactory factory, IUnrealMemory memory, IUnrealClasses classes, IPropertyFlagsBuilder flags) : BaseTypeFactory(factory, memory, classes, flags) { - public override bool CreateI8Param(string Name, int Offset, out IFGenericPropertyParams? Out) + private static Func? FMemory_Malloc_Static = null; + private static nint Malloc_Static_Size = 0; + + private static nint CurrentCppStructOpsVtable; + private static uint CurrentCppStructOpsSize; + private const uint CPP_STRUCT_OPS_ALIGNMENT = 0x8; + private const nint CPP_STRUCT_OPS_VTABLE_SIZE = 20; + + [UnmanagedCallersOnly(CallConvs = [typeof(CallConvStdcall)])] + private static unsafe nint InitializeCppStructOps() { - Out = null; - return false; + var Alloc = (ICppStructOps*)FMemory_Malloc_Static!(Marshal.SizeOf(), 0); + Alloc->VTable = CurrentCppStructOpsVtable; + Alloc->Size = CurrentCppStructOpsSize; + Alloc->Alignment = CPP_STRUCT_OPS_ALIGNMENT; + return (nint)Alloc; } - public override bool CreateI16Param(string Name, int Offset, out IFGenericPropertyParams? Out) + // UScriptStruct::ICppStructOps + private unsafe void CreateCppStructOpsVtable() { - Out = null; - return false; + ((nint*)CurrentCppStructOpsVtable)[0] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // ~ICppStructOps + ((nint*)CurrentCppStructOpsVtable)[1] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_GetCapabilities); // GetCapabilities + ((nint*)CurrentCppStructOpsVtable)[2] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // Construct + ((nint*)CurrentCppStructOpsVtable)[3] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // ConstructForTests + ((nint*)CurrentCppStructOpsVtable)[4] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // Destruct + ((nint*)CurrentCppStructOpsVtable)[5] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // Serialize(FArchive) + ((nint*)CurrentCppStructOpsVtable)[6] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // Serialize(FStructuredArchive) + ((nint*)CurrentCppStructOpsVtable)[7] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // PostSerialize + ((nint*)CurrentCppStructOpsVtable)[8] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // NetSerialize + ((nint*)CurrentCppStructOpsVtable)[9] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // NetDeltaSerialize + ((nint*)CurrentCppStructOpsVtable)[10] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // PostScriptConstruct + ((nint*)CurrentCppStructOpsVtable)[11] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // GetPreloadDependencies + ((nint*)CurrentCppStructOpsVtable)[12] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // Copy + ((nint*)CurrentCppStructOpsVtable)[13] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // Identical + ((nint*)CurrentCppStructOpsVtable)[14] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // ExportTextItem + ((nint*)CurrentCppStructOpsVtable)[15] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // ImportTextItem + ((nint*)CurrentCppStructOpsVtable)[16] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // AddStructReferencedObjects + ((nint*)CurrentCppStructOpsVtable)[17] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // SerializeFromMismatchedTag + ((nint*)CurrentCppStructOpsVtable)[18] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // StructuredSerializeFromMismatchedTag + ((nint*)CurrentCppStructOpsVtable)[19] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_U32); // GetStructTypeHash } - public override bool CreateI32Param(string Name, int Offset, out IFGenericPropertyParams? Out) + internal override unsafe bool CreateStructParam(string Name, int Size, + List Fields, out IFStructParams? Out) { - Out = null; - return false; + var pProperties = (FPropertyParamsBase**)Memory.MallocZeroed(Marshal.SizeOf() * Fields.Count); + var StructParamStatic = (FStructParams*)Memory.MallocZeroed(Marshal.SizeOf()); + // Retrieve the game package so the reference to it is valid when FStructProperty::OuterFunc is called + _ = Classes.GetGamePackage(); + StructParamStatic->OuterFunc = (nint)(delegate* unmanaged[Stdcall])(&Unreal.UnrealClasses.FStructProperty_OuterFunc_Callback); + StructParamStatic->SuperFunc = nint.Zero; + StructParamStatic->StructOpsFunc = (nint)(delegate* unmanaged[Stdcall])(&InitializeCppStructOps); + StructParamStatic->NameUTF8 = Marshal.StringToHGlobalAnsi(Name); + StructParamStatic->SizeOf = (ushort)Size; + StructParamStatic->AlignOf = (byte)CPP_STRUCT_OPS_ALIGNMENT; // alignof(nint) + StructParamStatic->Properties = pProperties; + StructParamStatic->NumProperties = (ushort)Fields.Count; + StructParamStatic->ObjectFlags = EObjectFlags.RF_Public | EObjectFlags.RF_MarkAsNative | EObjectFlags.RF_Transient; + StructParamStatic->StructFlags = EStructFlags.STRUCT_Native; + foreach (var (i, Field) in Fields.Select((x, i) => (i, x))) + StructParamStatic->Properties[i] = (FPropertyParamsBase*)Field.Ptr; + Out = Factory.CreateFStructParams((nint)StructParamStatic); + FMemory_Malloc_Static ??= (size, align) => Memory.MallocZeroed(size, align); + // sizeof(UScriptStruct::ICppStructOps::VTable) + CurrentCppStructOpsVtable = Memory.MallocZeroed(Marshal.SizeOf() * CPP_STRUCT_OPS_VTABLE_SIZE); + CurrentCppStructOpsSize = (uint)Size; + CreateCppStructOpsVtable(); + return true; } - public override bool CreateI64Param(string Name, int Offset, out IFGenericPropertyParams? Out) + private unsafe bool CreateGenericParam(string Name, int Offset, + EPropertyGenFlags GenFlags, out IFGenericPropertyParams? Out) { - Out = null; - return false; - } + var PropParamStatic = (FGenericPropertyParams*)Memory.Malloc(Marshal.SizeOf()); + PropParamStatic->Super.NameUTF8 = Marshal.StringToHGlobalAnsi(Name); + PropParamStatic->Super.RepNotifyFuncUTF8 = nint.Zero; + PropParamStatic->Super.PropertyFlags = Flags.CreatePropertyFlags(PropertyVisibility.Public, PropertyBuilderFlags.None); + PropParamStatic->Super.PropertyGenFlags = GenFlags; + PropParamStatic->Super.ObjectFlags = EObjectFlags.RF_Public | EObjectFlags.RF_MarkAsNative | + EObjectFlags.RF_Transient; + PropParamStatic->Super.ArrayDim = 1; + PropParamStatic->Super.Offset = (ushort)Offset; + Out = Factory.CreateFGenericPropertyParams((nint)PropParamStatic); + return true; + } + + public override bool CreateI8Param(string Name, int Offset, out IFGenericPropertyParams? Out) + => CreateGenericParam(Name, Offset, EPropertyGenFlags.Int8, out Out); + + public override bool CreateI16Param(string Name, int Offset, out IFGenericPropertyParams? Out) + => CreateGenericParam(Name, Offset, EPropertyGenFlags.Int16, out Out); + + public override bool CreateI32Param(string Name, int Offset, out IFGenericPropertyParams? Out) + => CreateGenericParam(Name, Offset, EPropertyGenFlags.Int, out Out); + + public override bool CreateI64Param(string Name, int Offset, out IFGenericPropertyParams? Out) + => CreateGenericParam(Name, Offset, EPropertyGenFlags.Int64, out Out); public override bool CreateU8Param(string Name, int Offset, out IFGenericPropertyParams? Out) - { - Out = null; - return false; - } + => CreateGenericParam(Name, Offset, EPropertyGenFlags.Int8, out Out); public override bool CreateU16Param(string Name, int Offset, out IFGenericPropertyParams? Out) - { - Out = null; - return false; - } + => CreateGenericParam(Name, Offset, EPropertyGenFlags.UInt16, out Out); public override bool CreateU32Param(string Name, int Offset, out IFGenericPropertyParams? Out) - { - Out = null; - return false; - } + => CreateGenericParam(Name, Offset, EPropertyGenFlags.UInt32, out Out); public override bool CreateU64Param(string Name, int Offset, out IFGenericPropertyParams? Out) - { - Out = null; - return false; - } + => CreateGenericParam(Name, Offset, EPropertyGenFlags.UInt64, out Out); public override bool CreateF32Param(string Name, int Offset, out IFGenericPropertyParams? Out) - { - Out = null; - return false; - } + => CreateGenericParam(Name, Offset, EPropertyGenFlags.Float, out Out); public override bool CreateF64Param(string Name, int Offset, out IFGenericPropertyParams? Out) - { - Out = null; - return false; - } - - internal override unsafe bool CreateStructParam(string Name, int Size, - List Fields, out IFStructParams? Out) - { - Out = null; - return false; - } + => CreateGenericParam(Name, Offset, EPropertyGenFlags.Double, out Out); } \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Reflection/UE5_7_4/TypeFactory.cs b/UE.Toolkit.Reloaded/Reflection/UE5_7_4/TypeFactory.cs index bafd8b3..24e691d 100644 --- a/UE.Toolkit.Reloaded/Reflection/UE5_7_4/TypeFactory.cs +++ b/UE.Toolkit.Reloaded/Reflection/UE5_7_4/TypeFactory.cs @@ -1,6 +1,10 @@ -using UE.Toolkit.Core.Types.Unreal.Factories; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using UE.Toolkit.Core.Types.Unreal.Factories; using UE.Toolkit.Core.Types.Unreal.Factories.Interfaces; +using UE.Toolkit.Core.Types.Unreal.UE5_4_4; using UE.Toolkit.Interfaces; +using UE.Toolkit.Reloaded.Reflection.Common; namespace UE.Toolkit.Reloaded.Reflection.UE5_7_4; @@ -8,70 +12,120 @@ public class TypeFactory(IUnrealFactory factory, IUnrealMemory memory, IUnrealClasses classes, IPropertyFlagsBuilder flags) : BaseTypeFactory(factory, memory, classes, flags) { - public override bool CreateI8Param(string Name, int Offset, out IFGenericPropertyParams? Out) + private static Func? FMemory_Malloc_Static = null; + private static nint Malloc_Static_Size = 0; + + private static nint CurrentCppStructOpsVtable; + private static uint CurrentCppStructOpsSize; + private const uint CPP_STRUCT_OPS_ALIGNMENT = 0x8; + private const nint CPP_STRUCT_OPS_VTABLE_SIZE = 20; + + [UnmanagedCallersOnly(CallConvs = [typeof(CallConvStdcall)])] + private static unsafe nint InitializeCppStructOps() { - Out = null; - return false; + var Alloc = (ICppStructOps*)FMemory_Malloc_Static!(Marshal.SizeOf(), 0); + Alloc->VTable = CurrentCppStructOpsVtable; + Alloc->Size = CurrentCppStructOpsSize; + Alloc->Alignment = CPP_STRUCT_OPS_ALIGNMENT; + return (nint)Alloc; } - public override bool CreateI16Param(string Name, int Offset, out IFGenericPropertyParams? Out) + // UScriptStruct::ICppStructOps + private unsafe void CreateCppStructOpsVtable() { - Out = null; - return false; + ((nint*)CurrentCppStructOpsVtable)[0] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // ~ICppStructOps + ((nint*)CurrentCppStructOpsVtable)[1] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_GetCapabilities); // GetCapabilities + ((nint*)CurrentCppStructOpsVtable)[2] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // Construct + ((nint*)CurrentCppStructOpsVtable)[3] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // ConstructForTests + ((nint*)CurrentCppStructOpsVtable)[4] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // Destruct + ((nint*)CurrentCppStructOpsVtable)[5] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // Serialize(FArchive) + ((nint*)CurrentCppStructOpsVtable)[6] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // Serialize(FStructuredArchive) + ((nint*)CurrentCppStructOpsVtable)[7] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // PostSerialize + ((nint*)CurrentCppStructOpsVtable)[8] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // NetSerialize + ((nint*)CurrentCppStructOpsVtable)[9] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // NetDeltaSerialize + ((nint*)CurrentCppStructOpsVtable)[10] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // PostScriptConstruct + ((nint*)CurrentCppStructOpsVtable)[11] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // GetPreloadDependencies + ((nint*)CurrentCppStructOpsVtable)[12] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // Copy + ((nint*)CurrentCppStructOpsVtable)[13] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // Identical + ((nint*)CurrentCppStructOpsVtable)[14] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // ExportTextItem + ((nint*)CurrentCppStructOpsVtable)[15] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // ImportTextItem + ((nint*)CurrentCppStructOpsVtable)[16] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Void); // AddStructReferencedObjects + ((nint*)CurrentCppStructOpsVtable)[17] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // SerializeFromMismatchedTag + ((nint*)CurrentCppStructOpsVtable)[18] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_Bool_False); // StructuredSerializeFromMismatchedTag + ((nint*)CurrentCppStructOpsVtable)[19] = (nint)(delegate* unmanaged[Stdcall])(&FunctionPointers.Noop_U32); // GetStructTypeHash } - public override bool CreateI32Param(string Name, int Offset, out IFGenericPropertyParams? Out) + internal override unsafe bool CreateStructParam(string Name, int Size, + List Fields, out IFStructParams? Out) { - Out = null; - return false; + var pProperties = (FPropertyParamsBase**)Memory.MallocZeroed(Marshal.SizeOf() * Fields.Count); + var StructParamStatic = (FStructParams*)Memory.MallocZeroed(Marshal.SizeOf()); + // Retrieve the game package so the reference to it is valid when FStructProperty::OuterFunc is called + _ = Classes.GetGamePackage(); + StructParamStatic->OuterFunc = (nint)(delegate* unmanaged[Stdcall])(&Unreal.UnrealClasses.FStructProperty_OuterFunc_Callback); + StructParamStatic->SuperFunc = nint.Zero; + StructParamStatic->StructOpsFunc = (nint)(delegate* unmanaged[Stdcall])(&InitializeCppStructOps); + StructParamStatic->NameUTF8 = Marshal.StringToHGlobalAnsi(Name); + StructParamStatic->SizeOf = (ushort)Size; + StructParamStatic->AlignOf = (byte)CPP_STRUCT_OPS_ALIGNMENT; // alignof(nint) + StructParamStatic->Properties = pProperties; + StructParamStatic->NumProperties = (ushort)Fields.Count; + StructParamStatic->ObjectFlags = EObjectFlags.RF_Public | EObjectFlags.RF_MarkAsNative | EObjectFlags.RF_Transient; + StructParamStatic->StructFlags = EStructFlags.STRUCT_Native; + foreach (var (i, Field) in Fields.Select((x, i) => (i, x))) + StructParamStatic->Properties[i] = (FPropertyParamsBase*)Field.Ptr; + Out = Factory.CreateFStructParams((nint)StructParamStatic); + FMemory_Malloc_Static ??= (size, align) => Memory.MallocZeroed(size, align); + // sizeof(UScriptStruct::ICppStructOps::VTable) + CurrentCppStructOpsVtable = Memory.MallocZeroed(Marshal.SizeOf() * CPP_STRUCT_OPS_VTABLE_SIZE); + CurrentCppStructOpsSize = (uint)Size; + CreateCppStructOpsVtable(); + return true; } - public override bool CreateI64Param(string Name, int Offset, out IFGenericPropertyParams? Out) + private unsafe bool CreateGenericParam(string Name, int Offset, + EPropertyGenFlags GenFlags, out IFGenericPropertyParams? Out) { - Out = null; - return false; - } + var PropParamStatic = (FGenericPropertyParams*)Memory.Malloc(Marshal.SizeOf()); + PropParamStatic->Super.NameUTF8 = Marshal.StringToHGlobalAnsi(Name); + PropParamStatic->Super.RepNotifyFuncUTF8 = nint.Zero; + PropParamStatic->Super.PropertyFlags = Flags.CreatePropertyFlags(PropertyVisibility.Public, PropertyBuilderFlags.None); + PropParamStatic->Super.PropertyGenFlags = GenFlags; + PropParamStatic->Super.ObjectFlags = EObjectFlags.RF_Public | EObjectFlags.RF_MarkAsNative | + EObjectFlags.RF_Transient; + PropParamStatic->Super.ArrayDim = 1; + PropParamStatic->Super.Offset = (ushort)Offset; + Out = Factory.CreateFGenericPropertyParams((nint)PropParamStatic); + return true; + } + + public override bool CreateI8Param(string Name, int Offset, out IFGenericPropertyParams? Out) + => CreateGenericParam(Name, Offset, EPropertyGenFlags.Int8, out Out); + + public override bool CreateI16Param(string Name, int Offset, out IFGenericPropertyParams? Out) + => CreateGenericParam(Name, Offset, EPropertyGenFlags.Int16, out Out); + + public override bool CreateI32Param(string Name, int Offset, out IFGenericPropertyParams? Out) + => CreateGenericParam(Name, Offset, EPropertyGenFlags.Int, out Out); + + public override bool CreateI64Param(string Name, int Offset, out IFGenericPropertyParams? Out) + => CreateGenericParam(Name, Offset, EPropertyGenFlags.Int64, out Out); public override bool CreateU8Param(string Name, int Offset, out IFGenericPropertyParams? Out) - { - Out = null; - return false; - } + => CreateGenericParam(Name, Offset, EPropertyGenFlags.Int8, out Out); public override bool CreateU16Param(string Name, int Offset, out IFGenericPropertyParams? Out) - { - Out = null; - return false; - } + => CreateGenericParam(Name, Offset, EPropertyGenFlags.UInt16, out Out); public override bool CreateU32Param(string Name, int Offset, out IFGenericPropertyParams? Out) - { - Out = null; - return false; - } + => CreateGenericParam(Name, Offset, EPropertyGenFlags.UInt32, out Out); public override bool CreateU64Param(string Name, int Offset, out IFGenericPropertyParams? Out) - { - Out = null; - return false; - } + => CreateGenericParam(Name, Offset, EPropertyGenFlags.UInt64, out Out); public override bool CreateF32Param(string Name, int Offset, out IFGenericPropertyParams? Out) - { - Out = null; - return false; - } + => CreateGenericParam(Name, Offset, EPropertyGenFlags.Float, out Out); public override bool CreateF64Param(string Name, int Offset, out IFGenericPropertyParams? Out) - { - Out = null; - return false; - } - - internal override unsafe bool CreateStructParam(string Name, int Size, - List Fields, out IFStructParams? Out) - { - Out = null; - return false; - } + => CreateGenericParam(Name, Offset, EPropertyGenFlags.Double, out Out); } \ No newline at end of file diff --git a/UE.Toolkit.Reloaded/Unreal/UnrealClasses.cs b/UE.Toolkit.Reloaded/Unreal/UnrealClasses.cs index 82fc8cd..d6cd6f6 100644 --- a/UE.Toolkit.Reloaded/Unreal/UnrealClasses.cs +++ b/UE.Toolkit.Reloaded/Unreal/UnrealClasses.cs @@ -190,14 +190,34 @@ private void UStruct_LinkImpl(UStruct* pThis, nint Ar, byte bRelinkExistingPrope private static string? PackageNameToUObjectKey; private static Func? GetStaticStructCurrentCallback = null; + public IUObject? GetEnginePackage() + { + var PackageName = "/Script/Engine"; + if (PackageNameToUObject.TryGetValue(PackageName, out var Object)) return Object; + var NewPackage = Objects.FindObjectByName(PackageName, "Package"); + PackageNameToUObject[PackageName] = NewPackage; + return NewPackage; + } + + public IUObject? GetGamePackage() + { + if (PackageNameToUObject.TryGetValue(PackageNameToUObjectKey, out var Object)) return Object; + var NewPackage = Objects.FindObjectByName(PackageNameToUObjectKey, "Package"); + PackageNameToUObject[PackageNameToUObjectKey] = NewPackage; + return NewPackage; + } + private nint GetStaticStructImpl(nint pInRegister, nint pStructOuter, nint pStructName, nint Size, int Crc) { + /* // UPackage::GamePackage var StructOuter = Factory.CreateUObject(pStructOuter); // var StructName = Marshal.PtrToStringUni(pStructName); var PackageName = StructOuter.NamePrivate.ToString(); + Log.Debug($"GetStaticStruct was called: {PackageName}"); PackageNameToUObject.TryAdd(PackageName, StructOuter); // Log.Debug($"GetStaticStruct({StructName}): (outer: {StructOuter.NamePrivate}, size: 0x{Size:x}, crc: 0x{Crc:x})"); + */ return _GetStaticStruct!.Hook!.OriginalFunction(pInRegister, pStructOuter, pStructName, Size, Crc); } diff --git a/UE.Toolkit.Reloaded/Unreal/UnrealObjects.cs b/UE.Toolkit.Reloaded/Unreal/UnrealObjects.cs index 8a70b86..d0e8038 100644 --- a/UE.Toolkit.Reloaded/Unreal/UnrealObjects.cs +++ b/UE.Toolkit.Reloaded/Unreal/UnrealObjects.cs @@ -18,24 +18,27 @@ namespace UE.Toolkit.Reloaded.Unreal; public unsafe class UnrealObjects : IUnrealObjects { private delegate FText* FText_FromString(FText* ptr, FString* str); + private readonly SHFunction? _FText_FromString = new(); private delegate FString* FText_ToString(FText* text); + private readonly SHFunction _FText_ToString = new(); - + private static IHook? _UObject_PostLoadSubobjects; private static IHook? _UObject_BeginDestroy; private static Action? _onObjectLoaded; private static Action? _onObjectDestroy; internal ConcurrentDictionary> OnCDOLoaded = new(); - + [UnmanagedCallersOnly(CallConvs = [typeof(CallConvStdcall)])] private static void UObject_PostLoadSubobjects(nint self, nint outerInstanceGraph) { if (Mod.Config.LogObjectsEnabled) - Log.Information($"{nameof(UObject_PostLoadSubobjects)} || {ToolkitUtils.GetPrivateName(self)} || {ToolkitUtils.GetPrivateName((nint)((UObjectBase*)self)->ClassPrivate)}"); - + Log.Information( + $"{nameof(UObject_PostLoadSubobjects)} || {ToolkitUtils.GetPrivateName(self)} || {ToolkitUtils.GetPrivateName((nint)((UObjectBase*)self)->ClassPrivate)}"); + _UObject_PostLoadSubobjects!.OriginalFunction.Value.Invoke(self, outerInstanceGraph); _onObjectLoaded?.Invoke(self); } @@ -44,8 +47,9 @@ private static void UObject_PostLoadSubobjects(nint self, nint outerInstanceGrap private static void UObject_BeginDestroy(nint self) { if (Mod.Config.LogObjectsEnabled) - Log.Information($"{nameof(UObject_BeginDestroy)} || {ToolkitUtils.GetPrivateName(self)} || {ToolkitUtils.GetPrivateName((nint)((UObjectBase*)self)->ClassPrivate)}"); - + Log.Information( + $"{nameof(UObject_BeginDestroy)} || {ToolkitUtils.GetPrivateName(self)} || {ToolkitUtils.GetPrivateName((nint)((UObjectBase*)self)->ClassPrivate)}"); + _UObject_BeginDestroy!.OriginalFunction.Value.Invoke(self); _onObjectDestroy?.Invoke(self); } @@ -55,27 +59,36 @@ private static void UObject_BeginDestroy(nint self) public UnrealObjects(IUnrealFactory factory) { Factory = factory; - + Project.Scans.AddScanHook(nameof(UObject_PostLoadSubobjects), - (result, hooks) => _UObject_PostLoadSubobjects = hooks.CreateHook((delegate* unmanaged[Stdcall])&UObject_PostLoadSubobjects, result).Activate()); - - Project.Scans.AddScanHook(nameof(UObject_BeginDestroy), - (result, hooks) => _UObject_BeginDestroy = hooks.CreateHook((delegate* unmanaged[Stdcall])&UObject_BeginDestroy, result).Activate()); - + (result, hooks) => _UObject_PostLoadSubobjects = hooks + .CreateHook( + (delegate* unmanaged[Stdcall])&UObject_PostLoadSubobjects, result).Activate()); + + Project.Scans.AddScanHook(nameof(UObject_BeginDestroy), + (result, hooks) => _UObject_BeginDestroy = + hooks.CreateHook((delegate* unmanaged[Stdcall])&UObject_BeginDestroy, + result).Activate()); + Project.Scans.AddScan(nameof(GUObjectArray), result => GUObjectArray = factory.CreateUObjectArray(result)); - + Project.Scans.AddScanHook(nameof(UStruct_IsChildOf), (result, hooks) => UStruct.UStruct_IsChildOf = hooks.CreateWrapper(result, out _)); - + _onObjectLoaded += objPtr => OnObjectLoaded?.Invoke(new((UObjectBase*)objPtr)); + _onObjectLoaded += objPtr => + { + var Object = Factory.CreateUObject(objPtr); + Log.Information($"Class Outer type: {Object.ClassPrivate.OuterPrivate?.NamePrivate.ToString() ?? "OUTER NULL"}"); + }; _onObjectDestroy += objPtr => OnObjectBeginDestroy?.Invoke(new((UObjectBase*)objPtr)); } public Action>? OnObjectLoaded { get; set; } public Action>? OnObjectBeginDestroy { get; set; } - + public IUObjectArray GUObjectArray { get; private set; } = null!; public void OnObjectLoadedByName(string objName, Action> callback) @@ -84,7 +97,8 @@ public void OnObjectLoadedByName(string objName, Action { - if (((UObjectBase*)objPtr)->NamePrivate.ToSpanAnsi().SequenceEqual(new((void*)ansiNameBytes, objName.Length))) + if (((UObjectBase*)objPtr)->NamePrivate.ToSpanAnsi() + .SequenceEqual(new((void*)ansiNameBytes, objName.Length))) { callback(new((TObject*)objPtr)); } @@ -105,6 +119,50 @@ public void OnObjectLoadedByClass(string objClass, Action(Action> callback) where TObject : unmanaged => OnObjectLoadedByClass(typeof(TObject).Name, callback); + + private void ForEachObject(Func Callback) + { + for (var i = 0; i < GUObjectArray.NumElements; i++) + { + var CurrentObject = GUObjectArray.IndexToObject(i); + if (CurrentObject != null && Callback(CurrentObject)) + return; + } + } + + public IUObject? FindObjectByName(string objectName, string className) + { + IUObject? FoundObject = null; + ForEachObject(x => + { + if (x.NamePrivate.ToString() == objectName) FoundObject = x; + return FoundObject != null; + }); + return FoundObject; + } + + public ToolkitUObject? FindObjectByName(string objectName) where TObject : unmanaged + { + var Object = FindObjectByName(objectName, typeof(TObject).Name); + return Object != null ? new ToolkitUObject((TObject*)Object.Ptr) : null; + } + + public IUObject? FindObjectByClass(string className) + { + IUObject? FoundObject = null; + ForEachObject(x => + { + if (x.ClassPrivate.NamePrivate.ToString() == className) FoundObject = x; + return FoundObject != null; + }); + return FoundObject; + } + + public ToolkitUObject? FindObjectByClass() where TObject : unmanaged + { + var Object = FindObjectByClass(typeof(TObject).Name); + return Object != null ? new ToolkitUObject((TObject*)Object.Ptr) : null; + } public FText* CreateFText(string content) { From 8cb81bcc2683c3690595d95a0381793e3da434d5 Mon Sep 17 00:00:00 2001 From: Rirurin Date: Sun, 5 Jul 2026 12:37:45 +0800 Subject: [PATCH 6/7] Allow Object XML files to target a specific filepath --- README.md | 16 +++++-- UE.Toolkit.Core/Common/ToolkitUtils.cs | 44 +++++++++---------- .../Unreal/Factories/Interfaces/IUObject.cs | 2 + .../Factories/UE4_27_2/UnrealFactory.cs | 2 + .../Unreal/Factories/UE5_4_4/UnrealFactory.cs | 2 + UE.Toolkit.Interfaces/IDataTables.cs | 9 ++++ UE.Toolkit.Interfaces/IUnrealObjects.cs | 10 +++++ .../DataTables/DataTablesService.cs | 14 +++++- .../ObjectWriters/ObjectWriter.cs | 9 +++- .../ObjectWriters/ObjectWriterService.cs | 15 +++++-- UE.Toolkit.Reloaded/Unreal/UnrealObjects.cs | 21 +++++---- 11 files changed, 103 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index d326009..cfa245e 100644 --- a/README.md +++ b/README.md @@ -90,9 +90,11 @@ You can easily get both using [__FModel__](https://github.com/4sval/FModel/relea #### Steps 1. Inside your chosen folder from the previous steps, create a new __text file__. 2. Name the file the same as the object's __Name__. -3. Change the file extension from `.txt` to `.obj.xml`. Your file's name should be similar to: `DT_jRPG_CharacterDefinitions.obj.xml` +3. Change the file extension from `.txt` to `.obj.xml`. For example, if the file you want to edit is named `DT_jRPG_CharacterDefinitions.uasset` in FModel, then your Object XML would be named `DT_jRPG_CharacterDefinitions.obj.xml`. 4. Open your file in a text editor. +While this is suitable for most cases, there are certain situations where there may be multiple files with the same filename but you only want to edit a file with a particular **file path**. In this case, you can name your Object XML to anything you want and specify the path inside the file, which is covered below. + ### Writing an Object XML Generally, your XML will match the "shape" of the object, starting with its __Class__. I highly recommend looking at the object in __FModel__ or going to the extension mod's source if you can read code. @@ -107,6 +109,14 @@ The first element in your XML, aka the __Root Element__, will be the object's __ ``` +To specify a file path, add a `path` property to the root element, using the same path formatting style used by UE4SS. For example, if your object's file path is `/Sandfall/Content/Levels/Goblu/DataLayers/DL_Goblu_00Entry`, then you would replace `/Sandfall/Content` with `/Game` and add a "file extension" with the same name as the filename: + +```xml + + + +``` + #### Editing Properties A `DataLayerAsset` has two properties: `DataLayerType` and `DebugColor`. We'll first edit `DataLayerType`. @@ -274,14 +284,14 @@ public unsafe struct UFldManagerSubsystem A new struct can be registered into UE's type reflection. `IUnrealClasses` contains methods `(Create[Type]Param)` to build a list of property params to pass into `CreateScriptStruct`: ```c# -TryCreateScriptStruct("AgePanelSection", 0x30, new List +CreateScriptStruct("AgePanelSection", 0x30, new List { _context._toolkitClasses.CreateF32Param("X1", 0), _context._toolkitClasses.CreateF32Param("X2", 4), _context._toolkitClasses.CreateF32Param("Y1", 8), _context._toolkitClasses.CreateF32Param("Y2", 0xc), _context._toolkitClasses.CreateF32Param("Field28", 0x28), -}); +}, out var NewStruct); ``` Much like adding new fields, this is viewable in Object XML and blueprints. diff --git a/UE.Toolkit.Core/Common/ToolkitUtils.cs b/UE.Toolkit.Core/Common/ToolkitUtils.cs index d6fbb99..3b70302 100644 --- a/UE.Toolkit.Core/Common/ToolkitUtils.cs +++ b/UE.Toolkit.Core/Common/ToolkitUtils.cs @@ -50,32 +50,30 @@ public static string GetNativeName(nint objPtr) return nameNative; } - public static string GetNativeName(IUObject uobj) + public static string GetNativeName(IUObject uobj) => GetNativeName(uobj.Ptr); + + /// + /// Returns the fully qualified pathname for this object, in the format "Outermost.[Outer:]Name" + /// + /// Pointer to the object + /// Fully qualified pathname for this object + public static string GetPathName(nint objPtr) { - if (PrivateToNativeNameMap.TryGetValue(uobj.NamePrivate, out var nameNative)) return nameNative; - - var namePrivate = uobj.NamePrivate.ToString(); - nameNative = namePrivate; + // From UObjectBaseUtility::GetPathName + var Object = (UObjectBase*)objPtr; + if (Object == null) return "None"; - if (uobj.IsChildOf()) - { - nameNative = $"U{namePrivate}"; - } - if (uobj.IsChildOf()) - { - nameNative = $"A{namePrivate}"; - } - if (uobj.IsChildOf()) + var Outer = Object->OuterPrivate; + var Result = Object->NamePrivate.ToString(); + var OuterResult = string.Empty; + if (Outer != null) { - // Already has the F struct prefix, UserDefinedStructs usually I think. - var hasStructPrefix = namePrivate[0] == 'F' && char.IsUpper(namePrivate[1]); - if (!hasStructPrefix) - { - nameNative = $"F{namePrivate}"; - } + var bIsOuterPackage = ((UObjectBase*)Outer->ClassPrivate)->NamePrivate.ToString() != "Package" + && ((UObjectBase*)Outer->OuterPrivate->ClassPrivate)->NamePrivate.ToString() == "Package"; + OuterResult = GetPathName((nint)Outer) + (bIsOuterPackage ? ":" : "."); } - - PrivateToNativeNameMap[uobj.NamePrivate] = nameNative; - return nameNative; + return OuterResult + Result; } + + public static string GetPathName(IUObject uobj) => GetPathName(uobj.Ptr); } \ No newline at end of file diff --git a/UE.Toolkit.Core/Types/Unreal/Factories/Interfaces/IUObject.cs b/UE.Toolkit.Core/Types/Unreal/Factories/Interfaces/IUObject.cs index 5b42dcd..08f7a2a 100644 --- a/UE.Toolkit.Core/Types/Unreal/Factories/Interfaces/IUObject.cs +++ b/UE.Toolkit.Core/Types/Unreal/Factories/Interfaces/IUObject.cs @@ -28,5 +28,7 @@ public interface IUObject : IPtr string GetNativeName(); + string GetPathName(); + // IUObject GetWorld(); } \ No newline at end of file diff --git a/UE.Toolkit.Core/Types/Unreal/Factories/UE4_27_2/UnrealFactory.cs b/UE.Toolkit.Core/Types/Unreal/Factories/UE4_27_2/UnrealFactory.cs index 8752a36..dd60c68 100644 --- a/UE.Toolkit.Core/Types/Unreal/Factories/UE4_27_2/UnrealFactory.cs +++ b/UE.Toolkit.Core/Types/Unreal/Factories/UE4_27_2/UnrealFactory.cs @@ -475,6 +475,8 @@ public unsafe class UObjectUE4_27_2(nint ptr, IUnrealFactory factory) : IUObject public IUObject GetOutermost() => _factory.CreateUObject((nint)_self->GetOutermost()); public string GetNativeName() => ToolkitUtils.GetNativeName(this); + + public string GetPathName() => ToolkitUtils.GetPathName(this); } public unsafe class UClassUE4_27_2(nint ptr, IUnrealFactory factory) diff --git a/UE.Toolkit.Core/Types/Unreal/Factories/UE5_4_4/UnrealFactory.cs b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_4_4/UnrealFactory.cs index 8ec04f6..6cdde5f 100644 --- a/UE.Toolkit.Core/Types/Unreal/Factories/UE5_4_4/UnrealFactory.cs +++ b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_4_4/UnrealFactory.cs @@ -414,6 +414,8 @@ public unsafe class UObject_UE5_4_4(nint ptr, IUnrealFactory factory) : IUObject public IUObject GetOutermost() => _factory.CreateUObject((nint)_self->GetOutermost()); public string GetNativeName() => ToolkitUtils.GetNativeName(this); + + public string GetPathName() => ToolkitUtils.GetPathName(this); } public unsafe class UClass_UE5_4_4(nint ptr, IUnrealFactory factory) diff --git a/UE.Toolkit.Interfaces/IDataTables.cs b/UE.Toolkit.Interfaces/IDataTables.cs index 46c6191..b128e43 100644 --- a/UE.Toolkit.Interfaces/IDataTables.cs +++ b/UE.Toolkit.Interfaces/IDataTables.cs @@ -18,6 +18,15 @@ public interface IDataTables /// row struct type. Use to handle typing yourself. void OnDataTableChanged(string name, Action> callback) where TRow : unmanaged; + + /// + /// Notify whenever a is changed, typically just when loaded, and receive it in simple wrapper. + /// + /// object path. + /// Callback function receiving the . + /// row struct type. Use to handle typing yourself. + void OnDataTableChangedByPath(string objectPath, Action> callback) + where TRow : unmanaged; } /// diff --git a/UE.Toolkit.Interfaces/IUnrealObjects.cs b/UE.Toolkit.Interfaces/IUnrealObjects.cs index 299409f..37bf34b 100644 --- a/UE.Toolkit.Interfaces/IUnrealObjects.cs +++ b/UE.Toolkit.Interfaces/IUnrealObjects.cs @@ -66,6 +66,16 @@ void OnObjectLoadedByClass(Action> callback) void OnObjectLoadedByClass(string objClass, Action> callback) where TObject : unmanaged; + /// + /// Listen for an object's creation of the given path. + /// + /// Object path. + /// Callback given each object instance. + /// Object type. + /// Implemented as a hook on UObject::PostLoadSubobjects, allowing for editing object data before use. + void OnObjectLoadedByPath(string objectPath, Action> callback) + where TObject : unmanaged; + /// /// Finds an object based on the given name. /// diff --git a/UE.Toolkit.Reloaded/DataTables/DataTablesService.cs b/UE.Toolkit.Reloaded/DataTables/DataTablesService.cs index cd9f263..7244261 100644 --- a/UE.Toolkit.Reloaded/DataTables/DataTablesService.cs +++ b/UE.Toolkit.Reloaded/DataTables/DataTablesService.cs @@ -1,3 +1,4 @@ +using UE.Toolkit.Core.Common; using UE.Toolkit.Core.Types.Unreal.UE5_4_4; using UE.Toolkit.Interfaces; @@ -22,7 +23,18 @@ public void OnDataTableChanged(string name, Action> { _onDataTableChanged += table => { - if (table.Name == name) callback(new((UDataTable*)table.Self)); + if (table.Name == name) + callback(new((UDataTable*)table.Self)); + }; + } + + public void OnDataTableChangedByPath(string objectPath, Action> callback) + where TRow : unmanaged + { + _onDataTableChanged += table => + { + if (ToolkitUtils.GetPathName((nint)table.Self) == objectPath) + callback(new((UDataTable*)table.Self)); }; } diff --git a/UE.Toolkit.Reloaded/ObjectWriters/ObjectWriter.cs b/UE.Toolkit.Reloaded/ObjectWriters/ObjectWriter.cs index 02b9a19..57d8b87 100644 --- a/UE.Toolkit.Reloaded/ObjectWriters/ObjectWriter.cs +++ b/UE.Toolkit.Reloaded/ObjectWriters/ObjectWriter.cs @@ -22,7 +22,7 @@ public unsafe class ObjectWriter private byte[] _xmlContent; private UObjectBase* _currObj; - public ObjectWriter(string objName, Type objType, string objFile, FieldNodeFactory nodeFactory) + public ObjectWriter(string objName, Type objType, string objFile, FieldNodeFactory nodeFactory, string? objectPath) { _objType = objType; _objFile = objFile; @@ -41,9 +41,12 @@ public ObjectWriter(string objName, Type objType, string objFile, FieldNodeFacto .Subscribe(_ => OnXmlChanged()); ObjectName = objName; + ObjectPath = objectPath; } public string ObjectName { get; } + + public string? ObjectPath { get; } public void WriteToObject(nint objPtr) { @@ -76,6 +79,8 @@ private void OnXmlChanged() _xmlContent = File.ReadAllBytes(_objFile); WriteToObject((nint)_currObj); - Log.Information($"{nameof(ObjectWriter)} || Object XML updated: {ObjectName}\nFile: {_objFile}"); + Log.Information($"{nameof(ObjectWriter)} || Object XML updated: {GetObjectNameOrPath()}\nFile: {_objFile}"); } + + public string GetObjectNameOrPath() => ObjectPath ?? ObjectName; } diff --git a/UE.Toolkit.Reloaded/ObjectWriters/ObjectWriterService.cs b/UE.Toolkit.Reloaded/ObjectWriters/ObjectWriterService.cs index c34f3b7..cfcfeb4 100644 --- a/UE.Toolkit.Reloaded/ObjectWriters/ObjectWriterService.cs +++ b/UE.Toolkit.Reloaded/ObjectWriters/ObjectWriterService.cs @@ -46,6 +46,7 @@ private unsafe void RegisterFile(string objFile) var rootTypeName = reader.Name; var rootTypeProvider = reader.GetAttribute("provider"); + var rootTypePath = reader.GetAttribute("path"); var typeKey = new TypeKey(rootTypeName, rootTypeProvider); if (!_types.TryGetValue(typeKey, out var objType)) @@ -64,19 +65,25 @@ private unsafe void RegisterFile(string objFile) } } - var objWriter = new ObjectWriter(objName, objType, objFile, _nodeFactory); + var objWriter = new ObjectWriter(objName, objType, objFile, _nodeFactory, rootTypePath); _objWriters.Add(objWriter); if (objType.Name.StartsWith(nameof(UDataTable))) { - dt.OnDataTableChanged(objWriter.ObjectName, table => objWriter.WriteToObject((nint)table.Self)); + if (objWriter.ObjectPath != null) + dt.OnDataTableChangedByPath(objWriter.ObjectPath, table => objWriter.WriteToObject((nint)table.Self)); + else + dt.OnDataTableChanged(objWriter.ObjectName, table => objWriter.WriteToObject((nint)table.Self)); } else { - uobjs.OnObjectLoadedByName(objWriter.ObjectName, obj => objWriter.WriteToObject((nint)obj.Self)); + if (objWriter.ObjectPath != null) + uobjs.OnObjectLoadedByPath(objWriter.ObjectPath, obj => objWriter.WriteToObject((nint)obj.Self)); + else + uobjs.OnObjectLoadedByName(objWriter.ObjectName, obj => objWriter.WriteToObject((nint)obj.Self)); } - Log.Information($"{nameof(ObjectWriterService)} || Object XML registered: {objWriter.ObjectName}\nFile: {objFile}"); + Log.Information($"{nameof(ObjectWriterService)} || Object XML registered: {objWriter.GetObjectNameOrPath()}\nFile: {objFile}"); } private readonly record struct TypeKey(string TypeName, string? TypeProvider); diff --git a/UE.Toolkit.Reloaded/Unreal/UnrealObjects.cs b/UE.Toolkit.Reloaded/Unreal/UnrealObjects.cs index d0e8038..d9eacf9 100644 --- a/UE.Toolkit.Reloaded/Unreal/UnrealObjects.cs +++ b/UE.Toolkit.Reloaded/Unreal/UnrealObjects.cs @@ -46,9 +46,9 @@ private static void UObject_PostLoadSubobjects(nint self, nint outerInstanceGrap [UnmanagedCallersOnly(CallConvs = [typeof(CallConvStdcall)])] private static void UObject_BeginDestroy(nint self) { - if (Mod.Config.LogObjectsEnabled) - Log.Information( - $"{nameof(UObject_BeginDestroy)} || {ToolkitUtils.GetPrivateName(self)} || {ToolkitUtils.GetPrivateName((nint)((UObjectBase*)self)->ClassPrivate)}"); + // if (Mod.Config.LogObjectsEnabled) + // Log.Information( + // $"{nameof(UObject_BeginDestroy)} || {ToolkitUtils.GetPrivateName(self)} || {ToolkitUtils.GetPrivateName((nint)((UObjectBase*)self)->ClassPrivate)}"); _UObject_BeginDestroy!.OriginalFunction.Value.Invoke(self); _onObjectDestroy?.Invoke(self); @@ -77,11 +77,6 @@ public UnrealObjects(IUnrealFactory factory) (result, hooks) => UStruct.UStruct_IsChildOf = hooks.CreateWrapper(result, out _)); _onObjectLoaded += objPtr => OnObjectLoaded?.Invoke(new((UObjectBase*)objPtr)); - _onObjectLoaded += objPtr => - { - var Object = Factory.CreateUObject(objPtr); - Log.Information($"Class Outer type: {Object.ClassPrivate.OuterPrivate?.NamePrivate.ToString() ?? "OUTER NULL"}"); - }; _onObjectDestroy += objPtr => OnObjectBeginDestroy?.Invoke(new((UObjectBase*)objPtr)); } @@ -120,6 +115,16 @@ public void OnObjectLoadedByClass(string objClass, Action(Action> callback) where TObject : unmanaged => OnObjectLoadedByClass(typeof(TObject).Name, callback); + public void OnObjectLoadedByPath(string objectPath, Action> callback) + where TObject : unmanaged + { + _onObjectLoaded += objPtr => + { + if (((UObjectBase*)objPtr)->NamePrivate.ToString() == objectPath) + callback(new((TObject*)objPtr)); + }; + } + private void ForEachObject(Func Callback) { for (var i = 0; i < GUObjectArray.NumElements; i++) From a9311305b98c38ee0f78c9b0dd3c15e34ae1d3be Mon Sep 17 00:00:00 2001 From: Rirurin Date: Sun, 5 Jul 2026 13:47:01 +0800 Subject: [PATCH 7/7] Added missing doc comments for interfaces --- UE.Toolkit.Interfaces/IDataTables.cs | 2 +- UE.Toolkit.Interfaces/IUnrealClasses.cs | 4 ++++ UE.Toolkit.Interfaces/IUnrealMethods.cs | 6 ++++++ UE.Toolkit.Interfaces/IUnrealObjects.cs | 6 +++--- UE.Toolkit.Interfaces/IUnrealSpawning.cs | 17 +++++++++++++++++ UE.Toolkit.Interfaces/IUnrealState.cs | 17 +++++++++++++++++ 6 files changed, 48 insertions(+), 4 deletions(-) diff --git a/UE.Toolkit.Interfaces/IDataTables.cs b/UE.Toolkit.Interfaces/IDataTables.cs index b128e43..65b834c 100644 --- a/UE.Toolkit.Interfaces/IDataTables.cs +++ b/UE.Toolkit.Interfaces/IDataTables.cs @@ -22,7 +22,7 @@ void OnDataTableChanged(string name, Action> callba /// /// Notify whenever a is changed, typically just when loaded, and receive it in simple wrapper. /// - /// object path. + /// object path. /// Callback function receiving the . /// row struct type. Use to handle typing yourself. void OnDataTableChangedByPath(string objectPath, Action> callback) diff --git a/UE.Toolkit.Interfaces/IUnrealClasses.cs b/UE.Toolkit.Interfaces/IUnrealClasses.cs index 0c57003..6cf5077 100644 --- a/UE.Toolkit.Interfaces/IUnrealClasses.cs +++ b/UE.Toolkit.Interfaces/IUnrealClasses.cs @@ -3,6 +3,9 @@ namespace UE.Toolkit.Interfaces; +/// +/// API for functionality related to Unreal classes. +/// public interface IUnrealClasses : IUnrealClassesInternal { @@ -107,6 +110,7 @@ public void AddConstructor(Action> callback) /// /// Name of the new field. /// Offset of the new field. + /// Return value. /// Object type. public bool AddI64Property(string Name, int Offset, out IFProperty? Out) where TObject : unmanaged; diff --git a/UE.Toolkit.Interfaces/IUnrealMethods.cs b/UE.Toolkit.Interfaces/IUnrealMethods.cs index 1d39476..b6e84e5 100644 --- a/UE.Toolkit.Interfaces/IUnrealMethods.cs +++ b/UE.Toolkit.Interfaces/IUnrealMethods.cs @@ -2,6 +2,9 @@ namespace UE.Toolkit.Interfaces; +/// +/// API for invoking Blueprint methods on an object. +/// public interface IUnrealMethods { @@ -115,6 +118,7 @@ public interface IUnrealMethods /// /// Object to invoke function on. /// Name of the function to invoke. + /// The list of parameters used by the function. /// Object type. public void ProcessEvent(ToolkitUObject Object, string Name, ref List Parameters) where TObject : unmanaged; @@ -125,7 +129,9 @@ public void ProcessEvent(ToolkitUObject Object, string Name, /// /// Object to invoke function on. /// Name of the function to invoke. + /// The list of parameters used by the function. /// Object type. + /// Return type. public TReturnType ProcessEvent(ToolkitUObject Object, string Name, ref List Parameters) where TObject : unmanaged diff --git a/UE.Toolkit.Interfaces/IUnrealObjects.cs b/UE.Toolkit.Interfaces/IUnrealObjects.cs index 37bf34b..74dbe4a 100644 --- a/UE.Toolkit.Interfaces/IUnrealObjects.cs +++ b/UE.Toolkit.Interfaces/IUnrealObjects.cs @@ -10,7 +10,7 @@ namespace UE.Toolkit.Interfaces; /// /// API for functionality related to Unreal objects. /// -public unsafe interface IUnrealObjects : IObjectCreator +public interface IUnrealObjects : IObjectCreator { /// /// Notify on the creation of any object. @@ -69,7 +69,7 @@ void OnObjectLoadedByClass(string objClass, Action /// Listen for an object's creation of the given path. /// - /// Object path. + /// Object path. /// Callback given each object instance. /// Object type. /// Implemented as a hook on UObject::PostLoadSubobjects, allowing for editing object data before use. @@ -96,7 +96,7 @@ void OnObjectLoadedByPath(string objectPath, Action /// Finds the first object matching a specified type. /// - /// Class name. + /// Class name. /// A if an object was found with the specified type. IUObject? FindObjectByClass(string className); diff --git a/UE.Toolkit.Interfaces/IUnrealSpawning.cs b/UE.Toolkit.Interfaces/IUnrealSpawning.cs index 3321190..d3d3873 100644 --- a/UE.Toolkit.Interfaces/IUnrealSpawning.cs +++ b/UE.Toolkit.Interfaces/IUnrealSpawning.cs @@ -2,10 +2,27 @@ namespace UE.Toolkit.Interfaces; +/// +/// API for spawning new objects. +/// public interface IUnrealSpawning { + /// + /// Spawns an object with the given name (and optionally an owner) + /// + /// Name of the object + /// The object's owner. This will bind the lifetime of this object to it's parent. + /// Object type + /// The new object if it was successfully created IUObject? SpawnObject(string Name, IUObject? Owner) where TObject : unmanaged; + /// + /// Spawns an object with the given name and class (and optionally an owner) + /// + /// Name of the object + /// Object class + /// The object's owner. This will bind the lifetime of this object to it's parent. + /// The new object if it was successfully created IUObject? SpawnObject(string Name, IUClass Class, IUObject? Owner); /* diff --git a/UE.Toolkit.Interfaces/IUnrealState.cs b/UE.Toolkit.Interfaces/IUnrealState.cs index d9c010b..840bc18 100644 --- a/UE.Toolkit.Interfaces/IUnrealState.cs +++ b/UE.Toolkit.Interfaces/IUnrealState.cs @@ -2,6 +2,9 @@ namespace UE.Toolkit.Interfaces; +/// +/// API for functions related to the game/engine state. +/// public interface IUnrealState { /// @@ -13,8 +16,22 @@ public interface IUnrealState /// If a target world could be found. public bool GetCurrentPlayWorld(out IUObject? TargetWorld); + /// + /// Retrieve a subsystem from the current game instance. + /// + /// Current Game Instance. + /// The subsystem if it was successfully retrieved. + /// The subsystem type + /// Whether a subsystem of the type TSubsystem could be retrieved. public bool GetSubsystem(IUGameInstance? GameInstance, out IUObject? Subsystem) where TSubsystem : unmanaged; + /// + /// Retrieve a subsystem from the current game instance. + /// + /// Current Game Instance. + /// The type of the subsystem. + /// The subsystem if it was successfully retrieved. + /// Whether a subsystem of the type SubsystemType could be retrieved. public bool GetSubsystem(IUGameInstance? GameInstance, IUClass? SubsystemType, out IUObject? SubsystemObj); } \ No newline at end of file