diff --git a/README.md b/README.md
index a727a0f..cfa245e 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.
@@ -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 301d685..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)
@@ -532,8 +534,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_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..0e6a0ce
--- /dev/null
+++ b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_2_1/UnrealFactory.cs
@@ -0,0 +1,206 @@
+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;
+
+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;
+
+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
+{
+
+ 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_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);
+ public override IFStaticConstructObjectParameters CreateFStaticConstructObjectParameters()
+ => new FStaticConstructObjectParameters_UE5_4_4(this);
+ public override IFActorSpawnParameters CreateFActorSpawnParameters()
+ => 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;
+}
+
+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.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_4_4/UnrealFactory.cs b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_4_4/UnrealFactory.cs
index b301eef..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
@@ -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
{
@@ -440,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)
@@ -496,7 +472,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_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..fee2b12
--- /dev/null
+++ b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_6_1/UnrealFactory.cs
@@ -0,0 +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 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()
+ => new FStaticConstructObjectParameters_UE5_4_4(this);
+ public override IFActorSpawnParameters CreateFActorSpawnParameters()
+ => 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
new file mode 100644
index 0000000..e61a6b2
--- /dev/null
+++ b/UE.Toolkit.Core/Types/Unreal/Factories/UE5_7_4/UnrealFactory.cs
@@ -0,0 +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 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 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 int ObjLastNonGCIndex => _self->ObjLastNonGCIndex;
+
+ public IUObject? IndexToObject(int idx)
+ {
+ var objItem = _self->ObjObjects.GetItem(idx);
+ if (objItem == null || objItem->Object == null || objItem->Flags.HasFlag(EInternalObjectFlags.Unreachable)) return null;
+
+ return factory.CreateUObject((nint)objItem->Object);
+ }
+
+ public int NumElements => _self->ObjObjects.NumElements;
+
+ public void AddToRootSet(int idx)
+ {
+ var objItem = _self->ObjObjects.GetItem(idx);
+ if (objItem == null || objItem->Object == null) return;
+ objItem->Flags |= EInternalObjectFlags.RootSet;
+ objItem->Object->ObjectFlags |= EObjectFlags.RF_MarkAsRootSet;
+ }
+
+ public void RemoveFromRootSet(int idx)
+ {
+ var objItem = _self->ObjObjects.GetItem(idx);
+ if (objItem == null || objItem->Object == null) return;
+ objItem->Flags &= ~EInternalObjectFlags.RootSet;
+ objItem->Object->ObjectFlags &= ~EObjectFlags.RF_MarkAsRootSet;
+ }
+}
+
+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();
+
+ private TArray>? CachedNames;
+ private bool _isDisposed;
+
+ private const nint MASK_POINTER = ~1;
+
+ public TArray> Names
+ {
+ 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;
+ }
+ }
+
+ ~UEnum_UE5_7_4() => Dispose(false);
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ 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_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.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/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_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/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/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/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/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.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.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.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.Interfaces/IDataTables.cs b/UE.Toolkit.Interfaces/IDataTables.cs
index 46c6191..65b834c 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/IUnrealClasses.cs b/UE.Toolkit.Interfaces/IUnrealClasses.cs
index ba1f90e..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;
@@ -276,6 +280,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/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 2083ccc..74dbe4a 100644
--- a/UE.Toolkit.Interfaces/IUnrealObjects.cs
+++ b/UE.Toolkit.Interfaces/IUnrealObjects.cs
@@ -10,13 +10,18 @@ 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.
///
Action>? OnObjectLoaded { get; set; }
+ ///
+ /// Notify when an object will be destroyed.
+ ///
+ Action>? OnObjectBeginDestroy { get; set; }
+
///
/// Gets the global UObject array.
///
@@ -60,6 +65,48 @@ 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;
+
+ ///
+ /// 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.
+ ///
+ /// 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.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
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/Common/GameConfigs/GameConfig.cs b/UE.Toolkit.Reloaded/Common/GameConfigs/GameConfig.cs
index ed95f93..53d92b4 100644
--- a/UE.Toolkit.Reloaded/Common/GameConfigs/GameConfig.cs
+++ b/UE.Toolkit.Reloaded/Common/GameConfigs/GameConfig.cs
@@ -27,30 +27,15 @@ 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" => 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(),
_ => 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),
- _ => typeof(UE.Toolkit.Core.Types.Unreal.UE5_4_4.FText)
- };
- }
-
- public static int GetFTextSize()
- {
- unsafe
- {
- return Instance.Id switch
- {
- "P3R" => 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_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/Common/GameConfigs/Games/UE5_2_1.cs b/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_2_1.cs
new file mode 100644
index 0000000..1e338d5
--- /dev/null
+++ b/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_2_1.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_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
new file mode 100644
index 0000000..8f172bc
--- /dev/null
+++ b/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_3_2.cs
@@ -0,0 +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 : UE5_4_4_ClairObscur
+{
+ 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
new file mode 100644
index 0000000..f8c5ecb
--- /dev/null
+++ b/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_6_1.cs
@@ -0,0 +1,26 @@
+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;
+
+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
new file mode 100644
index 0000000..5c5fbfe
--- /dev/null
+++ b/UE.Toolkit.Reloaded/Common/GameConfigs/Games/UE5_7_4.cs
@@ -0,0 +1,26 @@
+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;
+
+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/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/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/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/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/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/Project/UE.Toolkit.Reloaded/SMT5V-Win64-Shipping/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/SMT5V-Win64-Shipping/scans.ini
index fb0e5a6..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
@@ -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
@@ -24,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..99fd744
--- /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/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
new file mode 100644
index 0000000..499f404
--- /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=
+
+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=
+
+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 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 ?? ?? ?? ??
+;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..071aafa
--- /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/IOStoreTest_50
+
+[UStruct]
+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
new file mode 100644
index 0000000..dddc343
--- /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=
+
+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=
+
+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 ?? 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 ?? ?? ?? ??
+;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..dd33289
--- /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/IOStoreTest_51
+
+[UStruct]
+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
new file mode 100644
index 0000000..01f3672
--- /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=
+
+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 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 ?? ?? ?? ??
+;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..1a1ed15
--- /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/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
new file mode 100644
index 0000000..04669a9
--- /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=
+
+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 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..ed25bce
--- /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/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/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_55-win64-shipping/scans.ini
new file mode 100644
index 0000000..463e21c
--- /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=
+
+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 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..f0a1ad4
--- /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/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/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_56-win64-shipping/scans.ini
new file mode 100644
index 0000000..b390c11
--- /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=
+
+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=
+
+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..15a830b
--- /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/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/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/iostoretest_57-win64-shipping/scans.ini
new file mode 100644
index 0000000..82bbc1c
--- /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=
+
+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=
+
+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..887d641
--- /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/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 747dacc..730277f 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
@@ -24,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=
@@ -33,6 +36,7 @@ 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/Project/UE.Toolkit.Reloaded/scans.ini b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/scans.ini
index 2a10aca..d688a28 100644
--- a/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/scans.ini
+++ b/UE.Toolkit.Reloaded/Project/UE.Toolkit.Reloaded/scans.ini
@@ -19,14 +19,17 @@ 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)
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/Reflection/Common/FunctionPointers.cs b/UE.Toolkit.Reloaded/Reflection/Common/FunctionPointers.cs
new file mode 100644
index 0000000..09205e9
--- /dev/null
+++ b/UE.Toolkit.Reloaded/Reflection/Common/FunctionPointers.cs
@@ -0,0 +1,26 @@
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using UE.Toolkit.Core.Types.Unreal.UE5_4_4;
+
+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;
+
+ [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/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/UE4_27_2/TypeFactory.cs b/UE.Toolkit.Reloaded/Reflection/UE4_27_2/TypeFactory.cs
index acea6c4..48e0024 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,55 +37,58 @@ 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(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
+ ((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,
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/PropertyFactory.cs b/UE.Toolkit.Reloaded/Reflection/UE5_2_1/PropertyFactory.cs
new file mode 100644
index 0000000..407c684
--- /dev/null
+++ b/UE.Toolkit.Reloaded/Reflection/UE5_2_1/PropertyFactory.cs
@@ -0,0 +1,211 @@
+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 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;
+
+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 = (UE.Toolkit.Core.Types.Unreal.UE5_4_4.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->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)
+ {
+ 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..c925a88
--- /dev/null
+++ b/UE.Toolkit.Reloaded/Reflection/UE5_2_1/TypeFactory.cs
@@ -0,0 +1,135 @@
+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;
+
+public class TypeFactory(IUnrealFactory factory, IUnrealMemory memory,
+ IUnrealClasses classes, IPropertyFlagsBuilder flags)
+ : BaseTypeFactory(factory, memory, classes, flags)
+{
+ 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()
+ {
+ var Alloc = (ICppStructOps*)FMemory_Malloc_Static!(Marshal.SizeOf(), 0);
+ Alloc->VTable = CurrentCppStructOpsVtable;
+ Alloc->Size = CurrentCppStructOpsSize;
+ Alloc->Alignment = CPP_STRUCT_OPS_ALIGNMENT;
+ return (nint)Alloc;
+ }
+
+ // UScriptStruct::ICppStructOps
+ private unsafe void CreateCppStructOpsVtable()
+ {
+ ((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
+ }
+
+ 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());
+ // 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;
+ }
+
+ private unsafe bool CreateGenericParam(string Name, int Offset,
+ EPropertyGenFlags GenFlags, out IFGenericPropertyParams? Out)
+ {
+ 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)
+ => CreateGenericParam(Name, Offset, EPropertyGenFlags.Int8, out Out);
+
+ public override bool CreateU16Param(string Name, int Offset, out IFGenericPropertyParams? Out)
+ => CreateGenericParam(Name, Offset, EPropertyGenFlags.UInt16, out Out);
+
+ public override bool CreateU32Param(string Name, int Offset, out IFGenericPropertyParams? Out)
+ => CreateGenericParam(Name, Offset, EPropertyGenFlags.UInt32, out Out);
+
+ public override bool CreateU64Param(string Name, int Offset, out IFGenericPropertyParams? Out)
+ => CreateGenericParam(Name, Offset, EPropertyGenFlags.UInt64, out Out);
+
+ public override bool CreateF32Param(string Name, int Offset, out IFGenericPropertyParams? Out)
+ => CreateGenericParam(Name, Offset, EPropertyGenFlags.Float, out Out);
+
+ public override bool CreateF64Param(string Name, int Offset, out IFGenericPropertyParams? Out)
+ => CreateGenericParam(Name, Offset, EPropertyGenFlags.Double, out Out);
+}
\ 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_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]