├── Changelog.hpp ├── Engine ├── Engine.cpp ├── Engine.hpp └── Template │ ├── Configuration.cpp │ ├── Configuration.hpp │ ├── GameDefines.cpp │ ├── GameDefines.hpp │ ├── PiecesOfCode.cpp │ └── PiecesOfCode.hpp ├── LICENSE ├── Printer.cpp ├── Printer.hpp ├── README.md ├── UE3SDKGenerator.sln ├── UE3SDKGenerator.vcxproj ├── UE3SDKGenerator.vcxproj.filters ├── UE3SDKGenerator.vcxproj.user ├── dllmain.cpp ├── dllmain.hpp ├── pch.cpp └── pch.hpp /Changelog.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | Changes in v2.3.0 5 | - Enums now generate with their actual enum names in class fields and functions instead of "uint8_t"! This option only works if you have "UsingEnumClasses" set to TRUE in "Configuration.cpp", just make sure you have the right "EnumClassType" set. 6 | - Enums generated with "UsingEnumClasses" set to FALSE will now add the objects name in front of the property value, this is to prevent duplicate name errors. 7 | - Added a new option "RemoveNativeFlags" in "Configuration.cpp", this will determine if you want to remove the "FUNC_Native" flag or not on functions. 8 | - Added a new option "NO_LOGGING", if defined in the "Configuration.hpp" file a log file will not be generated. 9 | - Added a new templated "IsA" function for UObject. 10 | - Bit fields now generate as "uint32_t" instead of "unsigned long". 11 | - Changed how "FinalAlignment" works in combination with "UsingEnumClasses", please read the new "Configuration.cpp" file for more info! 12 | - Other changes are optimization and redundancy improvements. 13 | 14 | Changes in v2.2.9: 15 | - Added a new enum cache system, which auto-renames enums in the final generated sdk. This fixes enums sometimes being generated with the same name. 16 | - Additional changes are just some code refracturing and optimization improvements. 17 | 18 | Changes in v2.2.8: 19 | - Added a special check before generating to make sure you set an output path in "Configuration.cpp", also added another check for the process event index. 20 | - Improved/organized various classes and structs in "GameDefines.hpp", as well in "PiecesOfCode.cpp" to match this. 21 | 22 | Changes in v2.2.7: 23 | - Fixed params labeled both "CPF_Parm" and "CPF_OutParm" incorrectly initializing before process event. 24 | - Changed some of the cast types in "GameDefines.cpp", as well as in "PiecesOfCode.cpp" to match that. 25 | 26 | Changes in v2.2.6: 27 | - Changed/cleaned up some of the fields in "GameDefines.hpp", as well as in "PiecesOfCode.cpp". 28 | - Added default constructors and deconstructors for FNameEntry. 29 | 30 | Changes in v2.2.5: 31 | - Fixed a comment issue in the generated "GameDefines.cpp" file. 32 | - Changed the "EClassTypes", "EFieldIds", "EPropertyTypes", enums so their values are assigned by the compiler instead; this is for easier modifying in the future if needed. 33 | - Changed the constuctors for the "ClassField" class in "GameDefines.cpp", along with slightly modifying some of the members in the "Fields" namespace. 34 | - Changed the commenting for "iNative". 35 | 36 | Changes in v2.2.4: 37 | - Added the "FinalAlignment" option in "Configuration.hpp/cpp", this lets you set a custom byte alignment for classes/structs in the final sdk. 38 | - Added an option/comment in "Configuration.hpp" for the "EAlignment" enum. 39 | 40 | Changes in v2.2.3: 41 | - Changed the format for some of the constructors in "GameDefines.hpp" as well in "PiecesOfCode.cpp". 42 | - Fixed the "IsValid" function for FNames in the generated sdk. 43 | 44 | Changes in v2.2.2: 45 | - Changed some cast types from reinterpret _cast to safer ones in some places. 46 | - Fixed the wrong "correctElementSize" value being set if there was an array of objects for generated structs, this is the same fix as the one in v2.1.9 I just forgot to make it apply to script structs. 47 | - Fixed UInterfaceProperty's being generated wrong in structs, again same fix as the one in v2.1.9 but applied to script structs. (not tested) 48 | - Fixed a spacing issue with the includes in the generated "GameDefines.hpp" file as well as in generated script structs. 49 | 50 | Changes in v2.2.1: 51 | - Added a message box popup to tell the user if generating virtual functions did not work correctly. 52 | - Fixed functions being static if "FUNC_AllFlags" was set, it's not suppose to be static if that's the case. Thanks tim sweeney. 53 | - Fixed not properly clearing the iNative bitflags and setting them back for functions. 54 | 55 | Changes in v2.2.0: 56 | - Fixed the interface name being wrong if there was an array of them. 57 | - Replaced the "dumpObjects" parameter with just "dumpObjectsFull" internally, because why would you even need that option? 58 | - Increased the loop size for virtual functions from 256 to 512. 59 | 60 | Changes in v2.1.9: 61 | - Fixed the UInterfaceProperty being generated wrong in the final sdk, it no longer says wrong size of previous property. 62 | - Fixed the math for "correctElementSize" being wrong if there was an array of objects, it now takes into account the array dimensions. 63 | - Fixed the iNative flags being wrong after going through process event. 64 | - Added support for generating static functions in classes. 65 | - Added an option to print the flag enums to the final sdk in "Configuration.cpp". 66 | - Added the "EObjectFlags" enum in GameDefines. 67 | - Added an extra safety check for validating globals. 68 | - Changed how the "AreGNamesValid" function works. 69 | 70 | Changes in v2.1.8: 71 | - Fixed the start offset for UObjectProperty being wrong. 72 | - Fixed there not being a proper ";" for the generated "FScriptDelegate" struct. 73 | - Fixed the return string for the "GetName" functions in PiecesOfCode being const by mistake in the teamplate. 74 | - Fixed the TPair members being private by default in PiecesOfCode in the template. 75 | - Fixed the generated UObject_Functions being in the wrong order in the generated sdk. 76 | - Fixed the UDelegateProperty offsets being wrong in the template for the generated sdk. 77 | 78 | Changes in v2.1.7: 79 | - I forgot to make FNameEntry's fields dynamically generate (whoops), added field register ids for them now in "GameDefines.hpp". 80 | - Added the GetEntryPoint and GetOffset functions. 81 | - Added extra "std::filesystem::exists" safety checks, along with more null pointer checks. 82 | - Added more detailed messagebox information. 83 | - Added a WIDTH_FIELD size to the EWidthTypes enum. 84 | - Remade the entire "Printers" namespace along with adding some extra functions. 85 | - Changed where the validation of globals happens, it has now been moved to the Initialize function. 86 | - Everything now uses direct std::ofstream's now. 87 | - Added the offset for globals when dumping instances now. 88 | - Dumping instances alone no longer creates an "empty" log file. 89 | - Adjusted how the start and end time are calculated. 90 | - Adjusted the "PiecesOfCode.cpp" structs to remove some new lines. 91 | - Organized some namespaces. 92 | 93 | Changes in v2.1.6: 94 | - Added some safety/null checks for class fields. 95 | - Changed the AreGObjectsValid check to support a wider range of games. 96 | - You no longer need to comment out returning the offsetof in "GameDefines.cpp" for the class fields. 97 | 98 | (This is a major update for the generator, please read the new information in the README file in the repository as well as the comments/examples in the "Template" folder!) 99 | Changes in v2.1.5: 100 | - Remade the "Template" engine classes to include all classes that are required for generation. 101 | - Added an offset macro for fields in "GameDefines.hpp", this you'll never have to update the fields in "PiecesOfCode.cpp" again! It's now all dynamically generated. 102 | - Added CHARACTER_UTF16 and CHARACTER_UTF8 defines in "Configuration.cpp", which changes everything on the fly including the generated structs. 103 | - Added dynamic generation of the FScriptDelegate struct (original class still has to be reversed). 104 | - Added an option to set the underlying type of enums if UsingEnumClasses is set to true in "Configuration.cpp". 105 | - Added the TMap class, along with printing it to "GameDefines.hpp" in the generated sdk. 106 | - Moved the changelog from "dllmain.hpp" to this current file. 107 | - Moved the GeneratorDirectory field from "Engine.hpp" to "Configuration.hpp" and also made it a std::filesystem::path instead of a string. 108 | - Turned some structs into classes, like TIterator, TArray, and FString. 109 | 110 | Changes in v2.1.4: 111 | - Fixed not correctly setting input values if the parameter was a bitfield. 112 | 113 | Changes in v2.1.3 114 | - Fixed parameters not correctly being copied if they were BOTH a CPF_Parm and CPF_OutParm. 115 | - Fixed not properly returning an out parameter they they were BOTH a CPF_Parm and CPF_OutParm. 116 | - Included some links in "GameDefines.hpp" for the function/enum flags, along with some extra comments. 117 | - Added some extra saftey checks for structs in "GameDefines.hpp" and fixed some spelling mistakes. 118 | - Added UDelegateProperty to PiecesOfCode and the generator. 119 | 120 | Changes in v2.1.2: 121 | - Added "SendMessage" to the MakeWindowsFunction function, and also redid the function itself. 122 | 123 | Changes in v2.1.1: 124 | - Moved the windows include headers and shit to "pch.hpp". 125 | - Added PiecesOfCode.cpp and made the ones in the header file externs. 126 | - Added Engine.hpp and Engine.cpp, generator info will be in here from now on as well as the includes for your engine files. 127 | - Got rid of ObjectFunctions and moved everything to GameDefines.cpp, this also means I had to move the static template functions in the GameDefines.hpp file. 128 | - Made the alignment value in Configuration.hpp/cpp an enum. 129 | - Fixed the version number being wrong in the last update. 130 | - Renamed h files to hpp cuz SEEE PLUS PLUSS!!!! 131 | 132 | Changes in v2.... 133 | I erased my commit history and sadly I don't have any copies of the changelog from previous versions. 134 | */ -------------------------------------------------------------------------------- /Engine/Engine.cpp: -------------------------------------------------------------------------------- 1 | #include "Engine.hpp" 2 | 3 | /* 4 | # ========================================================================================= # 5 | # Engine 6 | # ========================================================================================= # 7 | */ 8 | 9 | namespace Engine 10 | { 11 | std::string GeneratorVersion = "v2.3.0"; 12 | std::string GeneratorCredits = "TheFeckless, ItsBranK"; 13 | std::string GeneratorLinks = "www.github.com/itsbrank/UE3SDKGenerator, www.twitter.com/itsbrank"; 14 | std::string GeneratorDirectory = "UE3SDKGenerator"; 15 | } 16 | 17 | /* 18 | # ========================================================================================= # 19 | # 20 | # ========================================================================================= # 21 | */ -------------------------------------------------------------------------------- /Engine/Engine.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "Template/GameDefines.hpp" 4 | #include "Template/PiecesOfCode.hpp" 5 | 6 | /* 7 | # ========================================================================================= # 8 | # Engine 9 | # ========================================================================================= # 10 | */ 11 | 12 | // These are global variables for the generator, please do not change them! 13 | 14 | namespace Engine 15 | { 16 | extern std::string GeneratorVersion; 17 | extern std::string GeneratorCredits; 18 | extern std::string GeneratorLinks; 19 | } 20 | 21 | /* 22 | # ========================================================================================= # 23 | # 24 | # ========================================================================================= # 25 | */ -------------------------------------------------------------------------------- /Engine/Template/Configuration.cpp: -------------------------------------------------------------------------------- 1 | #include "Configuration.hpp" 2 | 3 | /* 4 | # ========================================================================================= # 5 | # Configuration 6 | # ========================================================================================= # 7 | */ 8 | 9 | namespace Configuration 10 | { 11 | const bool UsingConstants = false; // If you want to use constant variables for everything, instead of FindClass (very efficient, but need to generate new sdk everytime the game updates), 12 | const bool UsingOffsets = false; // If you're using offsets or FindPattern to find GObjects & GNames, 13 | const bool UsingDetours = true; // If you're goning to be detouring/using the VfTable for process event change this to true, if you're using virtual voids change this to false, 14 | const bool UsingEnumClasses = true; // If you want to use enum classes over just normal enums. 15 | const bool PrintFlagEnums = true; // If you want the EFunctionFlags, EPropertyFlags, and EObjectFlags enum so be generated in the final sdk. 16 | const bool RemoveNativeFlags = false; // If you want to remove the FUNC_Native flags on functions before going through process event. 17 | const std::string EnumClassType = "uint8_t"; // Underlying field type if you set UsingEnumClasses to true. 18 | 19 | const int32_t CommentSpacer = 30; 20 | const int32_t ConstSpacer = 50; 21 | const int32_t EnumSpacer = 50; 22 | const int32_t StructSpacer = 50; 23 | const int32_t FunctionSpacer = 50; 24 | const int32_t ClassSpacer = 50; 25 | const EAlignment Alignment = EAlignment::X32BIT; // If you're using enum classes, it's recommended you set this to EAlignment::NONE unless you know what you're doing! 26 | 27 | // Alignment used in the final generated sdk, this defines class/structs field byte alignment. 28 | // Keep in mind when using "UsingEnumClasses" enum sizes will be defined by their underlying type, which is dependent on this final alignment! 29 | const int32_t FinalAlignment = 0x4; 30 | 31 | const int32_t ProcessEventIndex = -1; // Position where the Process Event function is in UObject's VfTable. 32 | const std::string ProcessEventString = "null"; 33 | const uint8_t* ProcessEventPattern = (uint8_t*)"null"; 34 | const char* ProcessEventMask = (char*)"null"; 35 | 36 | const std::string GObjectsString = "null"; 37 | const uint8_t* GObjectsPattern = (uint8_t*)"null"; 38 | const char* GObjectsMask = (char*)"null"; 39 | const uintptr_t GObjectsOffset = NULL; 40 | 41 | const std::string GNamesString = "null"; 42 | const uint8_t* GNamesPattern = (uint8_t*)"null"; 43 | const char* GNamesMask = (char*)"null"; 44 | const uintptr_t GNamesOffset = NULL; 45 | 46 | const std::string GameName = "Template"; 47 | const std::string GameNameShort = "TSDK"; 48 | const std::string GameVersion = "1.0.0.0"; 49 | const std::filesystem::path GeneratorDirectory = "I_FORGOT_TO_SET_A_PATH"; 50 | } 51 | 52 | /* 53 | # ========================================================================================= # 54 | # 55 | # ========================================================================================= # 56 | */ -------------------------------------------------------------------------------- /Engine/Template/Configuration.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | /* 6 | # ========================================================================================= # 7 | # Configuration 8 | # ========================================================================================= # 9 | */ 10 | 11 | // Comment & uncomment these depending on what your game uses! 12 | #define CHARACTER_UTF16 13 | //#define CHARACTER_UTF8 14 | //#define NO_LOGGING // Uncomment if you want to disable logging to the log file. 15 | 16 | // This CAN be customized to anything you want really, just remember "FinalAlignment" only applies to the generated sdk. 17 | enum class EAlignment : int32_t 18 | { 19 | NONE = 0x1, 20 | X32BIT = 0x4, 21 | X64BIT = 0x8 22 | }; 23 | 24 | // These are global variables below, make changes in the cpp file only! 25 | 26 | namespace Configuration 27 | { 28 | extern const bool UsingConstants; 29 | extern const bool UsingOffsets; 30 | extern const bool UsingDetours; 31 | extern const bool UsingEnumClasses; 32 | extern const bool PrintFlagEnums; 33 | extern const bool RemoveNativeFlags; 34 | extern const std::string EnumClassType; 35 | 36 | extern const int32_t CommentSpacer; 37 | extern const int32_t ConstSpacer; 38 | extern const int32_t EnumSpacer; 39 | extern const int32_t StructSpacer; 40 | extern const int32_t FunctionSpacer; 41 | extern const int32_t ClassSpacer; 42 | extern const EAlignment Alignment; 43 | extern const int32_t FinalAlignment; 44 | 45 | extern const int32_t ProcessEventIndex; 46 | extern const std::string ProcessEventString; 47 | extern const uint8_t* ProcessEventPattern; 48 | extern const char* ProcessEventMask; 49 | 50 | extern const std::string GObjectsString; 51 | extern const uint8_t* GObjectsPattern; 52 | extern const char* GObjectsMask; 53 | extern const uintptr_t GObjectsOffset; 54 | 55 | extern const std::string GNamesString; 56 | extern const uint8_t* GNamesPattern; 57 | extern const char* GNamesMask; 58 | extern const uintptr_t GNamesOffset; 59 | 60 | extern const std::string GameName; 61 | extern const std::string GameNameShort; 62 | extern const std::string GameVersion; 63 | extern const std::filesystem::path GeneratorDirectory; 64 | } 65 | 66 | /* 67 | # ========================================================================================= # 68 | # 69 | # ========================================================================================= # 70 | */ -------------------------------------------------------------------------------- /Engine/Template/GameDefines.cpp: -------------------------------------------------------------------------------- 1 | #include "GameDefines.hpp" 2 | 3 | /* 4 | # ========================================================================================= # 5 | # Fields 6 | # ========================================================================================= # 7 | */ 8 | 9 | ClassField::ClassField() : 10 | Id(EFieldIds::UNKNOWN), 11 | Type("uint8_t UNKNOWN_CLASS_FIELD[0x1];"), 12 | Offset(0x0), 13 | Size(1) 14 | { 15 | 16 | } 17 | 18 | ClassField::ClassField(EFieldIds id, size_t sizeOverride) : 19 | Id(id), 20 | Type(Fields::IdToType[id]), 21 | Offset(Fields::GetOffset(id)), 22 | Size(sizeOverride) 23 | { 24 | 25 | } 26 | 27 | ClassField::~ClassField() { } 28 | 29 | ClassField ClassField::operator=(const ClassField& other) 30 | { 31 | Id = other.Id; 32 | Type = other.Type; 33 | Offset = other.Offset; 34 | Size = other.Size; 35 | return *this; 36 | } 37 | 38 | namespace Fields 39 | { 40 | std::vector> FieldMethods{}; 41 | 42 | std::map IdToType = 43 | { 44 | { EFieldIds::FNAMEENTRY_INDEX, "int32_t Index;" }, 45 | { EFieldIds::FNAMEENTRY_NAME_UTF16, "wchar_t Name[0x400];" }, 46 | { EFieldIds::FNAMEENTRY_NAME_UTF8, "char Name[0x400];" }, 47 | { EFieldIds::UOBJECT_VFTABLE, "struct FPointer VfTableObject;" }, 48 | { EFieldIds::UOBJECT_INDEX, "int32_t ObjectInternalInteger;" }, 49 | { EFieldIds::UOBJECT_OUTER, "class UObject* Outer;" }, 50 | { EFieldIds::UOBJECT_NAME, "struct FName Name;" }, 51 | { EFieldIds::UOBJECT_CLASS, "class UClass* Class;" }, 52 | { EFieldIds::UFIELD_NEXT, "class UField* Next;" }, 53 | { EFieldIds::UFIELD_SUPERFIELD, "class UField* SuperField;" }, 54 | { EFieldIds::UENUM_NAMES, "TArray Names;" }, 55 | { EFieldIds::UCONST_VALUE, "class FString Value;" }, 56 | { EFieldIds::UPROPERTY_DIMENSION, "unsigned long ArrayDim;" }, 57 | { EFieldIds::UPROPERTY_SIZE, "unsigned long ElementSize;" }, 58 | { EFieldIds::UPROPERTY_FLAGS, "uint64_t PropertyFlags;" }, 59 | { EFieldIds::UPROPERTY_OFFSET, "unsigned long Offset;" }, 60 | { EFieldIds::USTRUCT_SUPERFIELD, "class UField* SuperField;" }, 61 | { EFieldIds::USTRUCT_CHILDREN, "class UField* Children;" }, 62 | { EFieldIds::USTRUCT_SIZE, "unsigned long PropertySize;" }, 63 | { EFieldIds::UFUNCTION_FLAGS, "uint64_t FunctionFlags;" }, 64 | { EFieldIds::UFUNCTION_NATIVE, "uint16_t iNative;" }, 65 | { EFieldIds::USTRUCTPROPERTY_STRUCT, "class UStruct* Struct;" }, 66 | { EFieldIds::UOBJECTPROPERTY_PROPERTY, "class UClass* PropertyClass;" }, 67 | { EFieldIds::UCLASSPROPERTY_METACLASS, "class UClass* MetaClass;" }, 68 | { EFieldIds::UMAPPROPERTY_KEY, "class UProperty* Key;" }, 69 | { EFieldIds::UMAPPROPERTY_VALUE, "class UProperty* Value;" }, 70 | { EFieldIds::UINTERFACEPROPERTY_CLASS, "class UClass* InterfaceClass;" }, 71 | { EFieldIds::UDELEGATEPROPERTY_FUNCTION, "class UFuncton* Function;" }, 72 | { EFieldIds::UDELEGATEPROPERTY_NAME, "struct FName Name;" }, 73 | { EFieldIds::UBYTEPROPERTY_ENUM, "class UEnum* Enum;" }, 74 | { EFieldIds::UBOOLPROPERTY_BITMASK, "uint64_t BitMask;" }, 75 | { EFieldIds::UARRAYPROPERTY_INNTER, "class UProperty* Inner;" } 76 | }; 77 | 78 | std::map GlobalFields{}; 79 | 80 | std::uintptr_t GetOffset(EFieldIds fieldId) 81 | { 82 | switch (fieldId) 83 | { 84 | case EFieldIds::FNAMEENTRY_INDEX: 85 | return offsetof(FNameEntry, Index); 86 | case EFieldIds::FNAMEENTRY_NAME_UTF16: 87 | return offsetof(FNameEntry, Name); 88 | case EFieldIds::FNAMEENTRY_NAME_UTF8: 89 | return offsetof(FNameEntry, Name); 90 | case EFieldIds::UOBJECT_VFTABLE: 91 | return offsetof(UObject, VfTableObject); 92 | case EFieldIds::UOBJECT_INDEX: 93 | return offsetof(UObject, ObjectInternalInteger); 94 | case EFieldIds::UOBJECT_OUTER: 95 | return offsetof(UObject, Outer); 96 | case EFieldIds::UOBJECT_NAME: 97 | return offsetof(UObject, Name); 98 | case EFieldIds::UOBJECT_CLASS: 99 | return offsetof(UObject, Class); 100 | case EFieldIds::UFIELD_NEXT: 101 | return offsetof(UField, Next); 102 | case EFieldIds::UFIELD_SUPERFIELD: 103 | return offsetof(UStruct, SuperField); 104 | case EFieldIds::UENUM_NAMES: 105 | return offsetof(UEnum, Names); 106 | case EFieldIds::UCONST_VALUE: 107 | return offsetof(UConst, Value); 108 | case EFieldIds::UPROPERTY_DIMENSION: 109 | return offsetof(UProperty, ArrayDim); 110 | case EFieldIds::UPROPERTY_SIZE: 111 | return offsetof(UProperty, ElementSize); 112 | case EFieldIds::UPROPERTY_FLAGS: 113 | return offsetof(UProperty, PropertyFlags); 114 | case EFieldIds::UPROPERTY_OFFSET: 115 | return offsetof(UProperty, Offset); 116 | case EFieldIds::USTRUCT_SUPERFIELD: 117 | return offsetof(UStruct, SuperField); 118 | case EFieldIds::USTRUCT_CHILDREN: 119 | return offsetof(UStruct, Children); 120 | case EFieldIds::USTRUCT_SIZE: 121 | return offsetof(UStruct, PropertySize); 122 | case EFieldIds::UFUNCTION_FLAGS: 123 | return offsetof(UFunction, FunctionFlags); 124 | case EFieldIds::UFUNCTION_NATIVE: 125 | return offsetof(UFunction, iNative); 126 | case EFieldIds::USTRUCTPROPERTY_STRUCT: 127 | return offsetof(UStructProperty, Struct); 128 | case EFieldIds::UOBJECTPROPERTY_PROPERTY: 129 | return offsetof(UObjectProperty, PropertyClass); 130 | case EFieldIds::UCLASSPROPERTY_METACLASS: 131 | return offsetof(UClassProperty, MetaClass); 132 | case EFieldIds::UMAPPROPERTY_KEY: 133 | return offsetof(UMapProperty, Key); 134 | case EFieldIds::UMAPPROPERTY_VALUE: 135 | return offsetof(UMapProperty, Value); 136 | case EFieldIds::UINTERFACEPROPERTY_CLASS: 137 | return offsetof(UInterfaceProperty, InterfaceClass); 138 | case EFieldIds::UDELEGATEPROPERTY_FUNCTION: 139 | return offsetof(UDelegateProperty, Function); 140 | case EFieldIds::UDELEGATEPROPERTY_NAME: 141 | return offsetof(UDelegateProperty, DelegateName); 142 | case EFieldIds::UBYTEPROPERTY_ENUM: 143 | return offsetof(UByteProperty, Enum); 144 | case EFieldIds::UBOOLPROPERTY_BITMASK: 145 | return offsetof(UBoolProperty, BitMask); 146 | case EFieldIds::UARRAYPROPERTY_INNTER: 147 | return offsetof(UArrayProperty, Inner); 148 | default: 149 | return 0x0; 150 | } 151 | } 152 | 153 | std::map GetOrderedFields(EClassTypes classType, size_t& classSize, size_t& startOffset) 154 | { 155 | std::map returnMap; 156 | 157 | switch (classType) 158 | { 159 | case EClassTypes::CLASS_FNAMEENTRY: 160 | returnMap.emplace(GlobalFields[EFieldIds::FNAMEENTRY_INDEX].Offset, GlobalFields[EFieldIds::FNAMEENTRY_INDEX]); 161 | 162 | #ifdef CHARACTER_UTF16 163 | returnMap.emplace(GlobalFields[EFieldIds::FNAMEENTRY_NAME_UTF16].Offset, GlobalFields[EFieldIds::FNAMEENTRY_NAME_UTF16]); 164 | #endif 165 | #ifdef CHARACTER_UTF8 166 | returnMap.emplace(GlobalFields[EFieldIds::FNAMEENTRY_NAME_UTF8].Offset, GlobalFields[EFieldIds::FNAMEENTRY_NAME_UTF8]); 167 | #endif 168 | classSize = sizeof(FNameEntry); 169 | startOffset = 0; 170 | break; 171 | case EClassTypes::CLASS_UOBJECT: 172 | returnMap.emplace(GlobalFields[EFieldIds::UOBJECT_VFTABLE].Offset, GlobalFields[EFieldIds::UOBJECT_VFTABLE]); 173 | returnMap.emplace(GlobalFields[EFieldIds::UOBJECT_INDEX].Offset, GlobalFields[EFieldIds::UOBJECT_INDEX]); 174 | returnMap.emplace(GlobalFields[EFieldIds::UOBJECT_OUTER].Offset, GlobalFields[EFieldIds::UOBJECT_OUTER]); 175 | returnMap.emplace(GlobalFields[EFieldIds::UOBJECT_NAME].Offset, GlobalFields[EFieldIds::UOBJECT_NAME]); 176 | returnMap.emplace(GlobalFields[EFieldIds::UOBJECT_CLASS].Offset, GlobalFields[EFieldIds::UOBJECT_CLASS]); 177 | classSize = sizeof(UObject); 178 | startOffset = 0; 179 | break; 180 | case EClassTypes::CLASS_UFIELD: 181 | returnMap.emplace(GlobalFields[EFieldIds::UFIELD_NEXT].Offset, GlobalFields[EFieldIds::UFIELD_NEXT]); 182 | if (GlobalFields.find(EFieldIds::UFIELD_SUPERFIELD) != GlobalFields.end()) { returnMap.emplace(GlobalFields[EFieldIds::UFIELD_SUPERFIELD].Offset, GlobalFields[EFieldIds::UFIELD_SUPERFIELD]); } 183 | classSize = sizeof(UField); 184 | startOffset = sizeof(UObject); 185 | break; 186 | case EClassTypes::CLASS_UENUM: 187 | returnMap.emplace(GlobalFields[EFieldIds::UENUM_NAMES].Offset, GlobalFields[EFieldIds::UENUM_NAMES]); 188 | classSize = sizeof(UEnum); 189 | startOffset = sizeof(UField); 190 | break; 191 | case EClassTypes::CLASS_UCONST: 192 | returnMap.emplace(GlobalFields[EFieldIds::UCONST_VALUE].Offset, GlobalFields[EFieldIds::UCONST_VALUE]); 193 | classSize = sizeof(UConst); 194 | startOffset = sizeof(UField); 195 | break; 196 | case EClassTypes::CLASS_UPROPERTY: 197 | returnMap.emplace(GlobalFields[EFieldIds::UPROPERTY_DIMENSION].Offset, GlobalFields[EFieldIds::UPROPERTY_DIMENSION]); 198 | returnMap.emplace(GlobalFields[EFieldIds::UPROPERTY_SIZE].Offset, GlobalFields[EFieldIds::UPROPERTY_SIZE]); 199 | returnMap.emplace(GlobalFields[EFieldIds::UPROPERTY_FLAGS].Offset, GlobalFields[EFieldIds::UPROPERTY_FLAGS]); 200 | returnMap.emplace(GlobalFields[EFieldIds::UPROPERTY_OFFSET].Offset, GlobalFields[EFieldIds::UPROPERTY_OFFSET]); 201 | classSize = sizeof(UProperty); 202 | startOffset = sizeof(UField); 203 | break; 204 | case EClassTypes::CLASS_USTRUCT: 205 | if (GlobalFields.find(EFieldIds::USTRUCT_SUPERFIELD) != GlobalFields.end()) { returnMap.emplace(GlobalFields[EFieldIds::USTRUCT_SUPERFIELD].Offset, GlobalFields[EFieldIds::USTRUCT_SUPERFIELD]); } 206 | returnMap.emplace(GlobalFields[EFieldIds::USTRUCT_CHILDREN].Offset, GlobalFields[EFieldIds::USTRUCT_CHILDREN]); 207 | returnMap.emplace(GlobalFields[EFieldIds::USTRUCT_SIZE].Offset, GlobalFields[EFieldIds::USTRUCT_SIZE]); 208 | classSize = sizeof(UStruct); 209 | startOffset = sizeof(UField); 210 | break; 211 | case EClassTypes::CLASS_UFUNCTION: 212 | returnMap.emplace(GlobalFields[EFieldIds::UFUNCTION_FLAGS].Offset, GlobalFields[EFieldIds::UFUNCTION_FLAGS]); 213 | returnMap.emplace(GlobalFields[EFieldIds::UFUNCTION_NATIVE].Offset, GlobalFields[EFieldIds::UFUNCTION_NATIVE]); 214 | classSize = sizeof(UFunction); 215 | startOffset = sizeof(UStruct); 216 | break; 217 | case EClassTypes::CLASS_USTRUCTPROPERTY: 218 | returnMap.emplace(GlobalFields[EFieldIds::USTRUCTPROPERTY_STRUCT].Offset, GlobalFields[EFieldIds::USTRUCTPROPERTY_STRUCT]); 219 | classSize = sizeof(UStructProperty); 220 | startOffset = sizeof(UProperty); 221 | break; 222 | case EClassTypes::CLASS_UOBJECTPROPERTY: 223 | returnMap.emplace(GlobalFields[EFieldIds::UOBJECTPROPERTY_PROPERTY].Offset, GlobalFields[EFieldIds::UOBJECTPROPERTY_PROPERTY]); 224 | classSize = sizeof(UObjectProperty); 225 | startOffset = sizeof(UObject); 226 | break; 227 | case EClassTypes::CLASS_UCLASSPROPERTY: 228 | returnMap.emplace(GlobalFields[EFieldIds::UCLASSPROPERTY_METACLASS].Offset, GlobalFields[EFieldIds::UCLASSPROPERTY_METACLASS]); 229 | classSize = sizeof(UClassProperty); 230 | startOffset = sizeof(UProperty); 231 | break; 232 | case EClassTypes::CLASS_UMAPPROPERTY: 233 | returnMap.emplace(GlobalFields[EFieldIds::UMAPPROPERTY_KEY].Offset, GlobalFields[EFieldIds::UMAPPROPERTY_KEY]); 234 | returnMap.emplace(GlobalFields[EFieldIds::UMAPPROPERTY_VALUE].Offset, GlobalFields[EFieldIds::UMAPPROPERTY_VALUE]); 235 | classSize = sizeof(UMapProperty); 236 | startOffset = sizeof(UProperty); 237 | break; 238 | case EClassTypes::CLASS_UINTERFACEPROPERTY: 239 | returnMap.emplace(GlobalFields[EFieldIds::UINTERFACEPROPERTY_CLASS].Offset, GlobalFields[EFieldIds::UINTERFACEPROPERTY_CLASS]); 240 | classSize = sizeof(UInterfaceProperty); 241 | startOffset = sizeof(UProperty); 242 | break; 243 | case EClassTypes::CLASS_UDELEGATEPROPERTY: 244 | returnMap.emplace(GlobalFields[EFieldIds::UDELEGATEPROPERTY_FUNCTION].Offset, GlobalFields[EFieldIds::UDELEGATEPROPERTY_FUNCTION]); 245 | returnMap.emplace(GlobalFields[EFieldIds::UDELEGATEPROPERTY_NAME].Offset, GlobalFields[EFieldIds::UDELEGATEPROPERTY_NAME]); 246 | classSize = sizeof(UDelegateProperty); 247 | startOffset = sizeof(UProperty); 248 | break; 249 | case EClassTypes::CLASS_UBYTEPROPERTY: 250 | returnMap.emplace(GlobalFields[EFieldIds::UBYTEPROPERTY_ENUM].Offset, GlobalFields[EFieldIds::UBYTEPROPERTY_ENUM]); 251 | classSize = sizeof(UByteProperty); 252 | startOffset = sizeof(UProperty); 253 | break; 254 | case EClassTypes::CLASS_UBOOLPROPERTY: 255 | returnMap.emplace(GlobalFields[EFieldIds::UBOOLPROPERTY_BITMASK].Offset, GlobalFields[EFieldIds::UBOOLPROPERTY_BITMASK]); 256 | classSize = sizeof(UBoolProperty); 257 | startOffset = sizeof(UProperty); 258 | break; 259 | case EClassTypes::CLASS_UARRAYPROPERTY: 260 | returnMap.emplace(GlobalFields[EFieldIds::UARRAYPROPERTY_INNTER].Offset, GlobalFields[EFieldIds::UARRAYPROPERTY_INNTER]); 261 | classSize = sizeof(UArrayProperty); 262 | startOffset = sizeof(UProperty); 263 | break; 264 | } 265 | 266 | return returnMap; 267 | } 268 | 269 | void AssertField(const ClassField& classField) 270 | { 271 | GlobalFields[classField.Id] = classField; 272 | } 273 | } 274 | 275 | /* 276 | # ========================================================================================= # 277 | # Initialize Globals 278 | # ========================================================================================= # 279 | */ 280 | 281 | TArray* GObjects{}; 282 | TArray* GNames{}; 283 | 284 | /* 285 | # ========================================================================================= # 286 | # Class Functions 287 | # ========================================================================================= # 288 | */ 289 | 290 | TArray* UObject::GObjObjects() 291 | { 292 | TArray* objectArray = reinterpret_cast*>(GObjects); 293 | return objectArray; 294 | } 295 | 296 | std::string UObject::GetName() 297 | { 298 | return this->Name.ToString(); 299 | } 300 | 301 | std::string UObject::GetNameCPP() 302 | { 303 | std::string nameCPP; 304 | 305 | if (this->IsA(UClass::StaticClass())) 306 | { 307 | UClass* uClass = static_cast(this); 308 | 309 | while (uClass) 310 | { 311 | std::string className = uClass->GetName(); 312 | 313 | if (className == "Actor") 314 | { 315 | nameCPP += "A"; 316 | break; 317 | } 318 | else if (className == "Object") 319 | { 320 | nameCPP += "U"; 321 | break; 322 | } 323 | 324 | uClass = static_cast(uClass->SuperField); 325 | } 326 | } 327 | else 328 | { 329 | nameCPP += "F"; 330 | } 331 | 332 | nameCPP += this->GetName(); 333 | 334 | return nameCPP; 335 | } 336 | 337 | std::string UObject::GetFullName() 338 | { 339 | std::string fullName = this->GetName(); 340 | 341 | for (UObject* uOuter = this->Outer; uOuter; uOuter = uOuter->Outer) 342 | { 343 | fullName = uOuter->GetName() + "." + fullName; 344 | } 345 | 346 | fullName = this->Class->GetName() + " " + fullName; 347 | 348 | return fullName; 349 | } 350 | 351 | std::string UObject::GetPackageName() 352 | { 353 | UObject* uPackageObj = this->GetPackageObj(); 354 | 355 | if (uPackageObj) 356 | { 357 | static std::string packageName = uPackageObj->GetName(); 358 | 359 | return packageName; 360 | } 361 | 362 | return "null"; 363 | } 364 | 365 | UObject* UObject::GetPackageObj() 366 | { 367 | UObject* uPackage = nullptr; 368 | 369 | for (UObject* uOuter = this->Outer; uOuter; uOuter = uOuter->Outer) 370 | { 371 | uPackage = uOuter; 372 | } 373 | 374 | return uPackage; 375 | } 376 | 377 | class UClass* UObject::FindClass(const std::string& classFullName) 378 | { 379 | static bool initialized = false; 380 | static std::map foundClasses{}; 381 | 382 | if (!initialized) 383 | { 384 | for (UObject* uObject : *UObject::GObjObjects()) 385 | { 386 | if (uObject) 387 | { 388 | std::string objectFullName = uObject->GetFullName(); 389 | 390 | if (objectFullName.find("Class") == 0) 391 | { 392 | foundClasses[objectFullName] = static_cast(uObject); 393 | } 394 | } 395 | } 396 | 397 | initialized = true; 398 | } 399 | 400 | if (foundClasses.find(classFullName) != foundClasses.end()) 401 | { 402 | return foundClasses[classFullName]; 403 | } 404 | 405 | return nullptr; 406 | } 407 | 408 | bool UObject::IsA(class UClass* uClass) 409 | { 410 | for (UClass* uSuperClass = this->Class; uSuperClass; uSuperClass = static_cast(uSuperClass->SuperField)) 411 | { 412 | if (uSuperClass == uClass) 413 | { 414 | return true; 415 | } 416 | } 417 | 418 | return false; 419 | } 420 | 421 | bool UObject::IsA(int32_t objInternalInteger) 422 | { 423 | UClass* uClass = UObject::GObjObjects()->At(objInternalInteger)->Class; 424 | 425 | if (uClass) 426 | { 427 | return this->IsA(uClass); 428 | } 429 | 430 | return false; 431 | } 432 | 433 | class UFunction* UFunction::FindFunction(const std::string& functionFullName) 434 | { 435 | static bool initialized = false; 436 | static std::map foundFunctions{}; 437 | 438 | if (!initialized) 439 | { 440 | for (UObject* uObject : *UObject::GObjObjects()) 441 | { 442 | if (uObject) 443 | { 444 | std::string objectFullName = uObject->GetFullName(); 445 | 446 | if (objectFullName.find("Function") == 0) 447 | { 448 | foundFunctions[objectFullName] = static_cast(uObject); 449 | } 450 | } 451 | } 452 | 453 | initialized = true; 454 | } 455 | 456 | if (foundFunctions.find(functionFullName) != foundFunctions.end()) 457 | { 458 | return foundFunctions[functionFullName]; 459 | } 460 | 461 | return nullptr; 462 | } 463 | 464 | /* 465 | # ========================================================================================= # 466 | # 467 | # ========================================================================================= # 468 | */ -------------------------------------------------------------------------------- /Engine/Template/GameDefines.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "Configuration.hpp" 13 | 14 | /* 15 | # ========================================================================================= # 16 | # Game Defines 17 | # ========================================================================================= # 18 | */ 19 | 20 | // Function Flags 21 | // https://docs.unrealengine.com/en-US/API/Runtime/CoreUObject/UObject/EFunctionFlags/index.html 22 | enum EFunctionFlags 23 | { 24 | FUNC_None = 0x00000000, 25 | FUNC_Final = 0x00000001, 26 | FUNC_RequiredAPI = 0x00000002, 27 | FUNC_BlueprintAuthorityOnly = 0x00000004, 28 | FUNC_BlueprintCosmetic = 0x00000008, 29 | FUNC_Net = 0x00000040, 30 | FUNC_NetReliable = 0x00000080, 31 | FUNC_NetRequest = 0x00000100, 32 | FUNC_Exec = 0x00000200, 33 | FUNC_Native = 0x00000400, 34 | FUNC_Event = 0x00000800, 35 | FUNC_NetResponse = 0x00001000, 36 | FUNC_Static = 0x00002000, 37 | FUNC_NetMulticast = 0x00004000, 38 | FUNC_UbergraphFunction = 0x00008000, 39 | FUNC_MulticastDelegate = 0x00010000, 40 | FUNC_Public = 0x00020000, 41 | FUNC_Private = 0x00040000, 42 | FUNC_Protected = 0x00080000, 43 | FUNC_Delegate = 0x00100000, 44 | FUNC_NetServer = 0x00200000, 45 | FUNC_HasOutParms = 0x00400000, 46 | FUNC_HasDefaults = 0x00800000, 47 | FUNC_NetClient = 0x01000000, 48 | FUNC_DLLImport = 0x02000000, 49 | FUNC_BlueprintCallable = 0x04000000, 50 | FUNC_BlueprintEvent = 0x08000000, 51 | FUNC_BlueprintPure = 0x10000000, 52 | FUNC_EditorOnly = 0x20000000, 53 | FUNC_Const = 0x40000000, 54 | FUNC_NetValidate = 0x80000000, 55 | FUNC_AllFlags = 0xFFFFFFFF 56 | }; 57 | 58 | // Proprerty Flags 59 | // https://docs.unrealengine.com/en-US/API/Runtime/CoreUObject/UObject/EPropertyFlags/index.html (The ones in this link are UE4 specific, so I had to modify accordingly here.) 60 | enum EPropertyFlags 61 | { 62 | CPF_Edit = 0x0000000000000001, // Property is user-settable in the editor. 63 | CPF_Const = 0x0000000000000002, // Actor's property always matches class's default actor property. 64 | CPF_Input = 0x0000000000000004, // Variable is writable by the input system. 65 | CPF_ExportObject = 0x0000000000000008, // Object can be exported with actor. 66 | CPF_OptionalParm = 0x0000000000000010, // Optional parameter (if CPF_Param is set). 67 | CPF_Net = 0x0000000000000020, // Property is relevant to network replication. 68 | CPF_EditConstArray = 0x0000000000000040, // Prevent adding/removing of items from dynamic a array in the editor. 69 | CPF_Parm = 0x0000000000000080, // Function/When call parameter. 70 | CPF_OutParm = 0x0000000000000100, // Value is copied out after function call. 71 | CPF_SkipParm = 0x0000000000000200, // Property is a short-circuitable evaluation function parm. 72 | CPF_ReturnParm = 0x0000000000000400, // Return value. 73 | CPF_CoerceParm = 0x0000000000000800, // Coerce args into this function parameter. 74 | CPF_Native = 0x0000000000001000, // Property is native: C++ code is responsible for serializing it. 75 | CPF_Transient = 0x0000000000002000, // Property is transient: shouldn't be saved, zero-filled at load time. 76 | CPF_Config = 0x0000000000004000, // Property should be loaded/saved as permanent profile. 77 | CPF_Localized = 0x0000000000008000, // Property should be loaded as localizable text. 78 | CPF_Travel = 0x0000000000010000, // Property travels across levels/servers. 79 | CPF_EditConst = 0x0000000000020000, // Property is uneditable in the editor. 80 | CPF_GlobalConfig = 0x0000000000040000, // Load config from base class, not subclass. 81 | CPF_Component = 0x0000000000080000, // Property containts component references. 82 | CPF_NeedCtorLink = 0x0000000000400000, // Fields need construction/destruction. 83 | CPF_NoExport = 0x0000000000800000, // Property should not be exported to the native class header file. 84 | CPF_NoClear = 0x0000000002000000, // Hide clear (and browse) button. 85 | CPF_EditInline = 0x0000000004000000, // Edit this object reference inline. 86 | CPF_EdFindable = 0x0000000008000000, // References are set by clicking on actors in the editor viewports. 87 | CPF_EditInlineUse = 0x0000000010000000, // EditInline with Use button. 88 | CPF_Deprecated = 0x0000000020000000, // Property is deprecated. Read it from an archive, but don't save it. 89 | CPF_EditInlineNotify = 0x0000000040000000, // EditInline, notify outer object on editor change. 90 | CPF_RepNotify = 0x0000000100000000, // Notify actors when a property is replicated 91 | CPF_Interp = 0x0000000200000000, // interpolatable property for use with matinee 92 | CPF_NonTransactional = 0x0000000400000000, // Property isn't transacted 93 | CPF_EditorOnly = 0x0000000800000000, // Property should only be loaded in the editor. 94 | CPF_NoDestructor = 0x0000001000000000, // No destructor. 95 | CPF_AutoWeak = 0x0000004000000000, // CPF_ = 0x0000002000000000, ///<. 96 | CPF_ContainsInstancedReference = 0x0000008000000000, // Property contains component refuerences. 97 | CPF_AssetRegistrySearchable = 0x0000010000000000, // Asset instances will add properties with this flag to the asset registry automatically 98 | CPF_SimpleDisplay = 0x0000020000000000, // The property is visible by default in the editor details view. 99 | CPF_AdvancedDisplay = 0x0000040000000000, // The property is advanced and not visible by default in the editor details view. 100 | CPF_Protected = 0x0000080000000000, // Property is protected from the perspective of scrip 101 | CPF_BlueprintCallable = 0x0000100000000000, // MC Delegates only. Property should be exposed for calling in blueprint code. 102 | CPF_BlueprintAuthorityOnly = 0x0000200000000000, // MC Delegates only. This delegate accepts (only in blueprint) only events with BlueprintAuthorityOnly. 103 | CPF_TextExportTransient = 0x0000400000000000, // Property shouldn't be exported to text format (e.g. copy/paste) 104 | CPF_NonPIEDuplicateTransient = 0x0000800000000000, // Property should only be copied in PIE. 105 | CPF_ExposeOnSpawn = 0x0001000000000000, // Property is exposed on spawn. 106 | CPF_PersistentInstance = 0x0002000000000000, // A object referenced by the property is duplicated like a component. (Each actor should have an own instance.) 107 | CPF_UObjectWrapper = 0x0004000000000000, // Property was parsed as a wrapper class like TSubclassOf , FScriptInterface etc., rather than a USomething*. 108 | CPF_HasGetValueTypeHash = 0x0008000000000000, // This property can generate a meaningful hash value. 109 | CPF_NativeAccessSpecifierPublic = 0x0010000000000000, // Public native access specifier. 110 | CPF_NativeAccessSpecifierProtected = 0x0020000000000000, // Protected native access specifier. 111 | CPF_NativeAccessSpecifierPrivate = 0x0040000000000000, // Private native access specifier. 112 | CPF_SkipSerialization = 0x0080000000000000 // Property shouldn't be serialized, can still be exported to text. 113 | }; 114 | 115 | // Object Flags 116 | // https://docs.unrealengine.com/4.26/en-US/API/Runtime/CoreUObject/UObject/EObjectFlags/ 117 | enum EObjectFlags 118 | { 119 | RF_NoFlags = 0x00000000, 120 | RF_Public = 0x00000001, 121 | RF_Standalone = 0x00000002, 122 | RF_MarkAsNative = 0x00000004, 123 | RF_Transactional = 0x00000008, 124 | RF_ClassDefaultObject = 0x00000010, 125 | RF_ArchetypeObject = 0x00000020, 126 | RF_Transient = 0x00000040, 127 | RF_MarkAsRootSet = 0x00000080, 128 | RF_TagGarbageTemp = 0x00000100, 129 | RF_NeedInitialization = 0x00000200, 130 | RF_NeedLoad = 0x00000400, 131 | RF_KeepForCooker = 0x00000800, 132 | RF_NeedPostLoad = 0x00001000, 133 | RF_NeedPostLoadSubobjects = 0x00002000, 134 | RF_NewerVersionExists = 0x00004000, 135 | RF_BeginDestroyed = 0x00008000, 136 | RF_FinishDestroyed = 0x00010000, 137 | RF_BeingRegenerated = 0x00020000, 138 | RF_DefaultSubObject = 0x00040000, 139 | RF_WasLoaded = 0x00080000, 140 | RF_TextExportTransient = 0x00100000, 141 | RF_LoadCompleted = 0x00200000, 142 | RF_InheritableComponentTemplate = 0x00400000, 143 | RF_DuplicateTransient = 0x00800000, 144 | RF_StrongRefOnFrame = 0x01000000, 145 | RF_NonPIEDuplicateTransient = 0x02000000, 146 | RF_Dynamic = 0x04000000, 147 | RF_WillBeLoaded = 0x08000000, 148 | }; 149 | 150 | // Class Types 151 | enum class EClassTypes : uint8_t 152 | { 153 | CLASS_UNKNOWN, 154 | CLASS_FNAMEENTRY, 155 | CLASS_UOBJECT, 156 | CLASS_UFIELD, 157 | CLASS_UENUM, 158 | CLASS_UCONST, 159 | CLASS_UPROPERTY, 160 | CLASS_USTRUCT, 161 | CLASS_UFUNCTION, 162 | CLASS_USCRIPTSTRUCT, 163 | CLASS_USTATE, 164 | CLASS_UCLASS, 165 | CLASS_USTRUCTPROPERTY, 166 | CLASS_USTRPROPERTY, 167 | CLASS_UQWORDPROPERTY, 168 | CLASS_UOBJECTPROPERTY, 169 | CLASS_UCOMPONENTPROPERTY, 170 | CLASS_UCLASSPROPERTY, 171 | CLASS_UNAMEPROPERTY, 172 | CLASS_UMAPPROPERTY, 173 | CLASS_UINTPROPERTY, 174 | CLASS_UINTERFACEPROPERTY, 175 | CLASS_UFLOATPROPERTY, 176 | CLASS_UDELEGATEPROPERTY, 177 | CLASS_UBYTEPROPERTY, 178 | CLASS_UBOOLPROPERTY, 179 | CLASS_UARRAYPROPERTY 180 | }; 181 | 182 | // Field Identifiers 183 | enum class EFieldIds : uint8_t 184 | { 185 | UNKNOWN, 186 | FNAMEENTRY_INDEX, 187 | FNAMEENTRY_NAME_UTF16, 188 | FNAMEENTRY_NAME_UTF8, 189 | UOBJECT_VFTABLE, 190 | UOBJECT_INDEX, 191 | UOBJECT_OUTER, 192 | UOBJECT_NAME, 193 | UOBJECT_CLASS, 194 | UFIELD_NEXT, 195 | UFIELD_SUPERFIELD, 196 | UENUM_NAMES, 197 | UCONST_VALUE, 198 | UPROPERTY_DIMENSION, 199 | UPROPERTY_SIZE, 200 | UPROPERTY_FLAGS, 201 | UPROPERTY_OFFSET, 202 | USTRUCT_SUPERFIELD, 203 | USTRUCT_CHILDREN, 204 | USTRUCT_SIZE, 205 | UFUNCTION_FLAGS, 206 | UFUNCTION_NATIVE, 207 | USTRUCTPROPERTY_STRUCT, 208 | UOBJECTPROPERTY_PROPERTY, 209 | UCLASSPROPERTY_METACLASS, 210 | UMAPPROPERTY_KEY, 211 | UMAPPROPERTY_VALUE, 212 | UINTERFACEPROPERTY_CLASS, 213 | UDELEGATEPROPERTY_FUNCTION, 214 | UDELEGATEPROPERTY_NAME, 215 | UBYTEPROPERTY_ENUM, 216 | UBOOLPROPERTY_BITMASK, 217 | UARRAYPROPERTY_INNTER 218 | }; 219 | 220 | // Property Types 221 | enum class EPropertyTypes : uint16_t 222 | { 223 | TYPE_UNKNOWN, 224 | TYPE_INT8, 225 | TYPE_INT16, 226 | TYPE_INT32, 227 | TYPE_INT64, 228 | TYPE_UINT8, 229 | TYPE_UINT16, 230 | TYPE_UINT32, 231 | TYPE_UINT64, 232 | TYPE_LONG, 233 | TYPE_ULONG, 234 | TYPE_DOUBLE, 235 | TYPE_FLOAT, 236 | TYPE_BOOL, 237 | TYPE_TARRAY, 238 | TYPE_TMAP, 239 | TYPE_FNAMEENTRY, 240 | TYPE_FNAME, 241 | TYPE_FSTRING, 242 | TYPE_FSCRIPTDELEGATE, 243 | TYPE_FPOINTER, 244 | TYPE_FSTRUCT, 245 | TYPE_UPOINTER 246 | }; 247 | 248 | // Width Types 249 | enum class EWidthTypes : uint64_t 250 | { 251 | WIDTH_NONE = 0, 252 | WIDTH_BYTE = 2, 253 | WIDTH_SIZE = 4, 254 | WIDTH_BITMASK = 8, 255 | WIDTH_FUNCTION = 8, 256 | WIDTH_FIELD = 14, 257 | WIDTH_PROPERTY = 16 258 | }; 259 | 260 | /* 261 | # ========================================================================================= # 262 | # Structs 263 | # ========================================================================================= # 264 | */ 265 | 266 | template 267 | class TIterator 268 | { 269 | public: 270 | using ElementType = typename TArray::ElementType; 271 | using ElementPointer = ElementType*; 272 | using ElementReference = ElementType&; 273 | using ElementConstReference = const ElementType&; 274 | 275 | private: 276 | ElementPointer IteratorData; 277 | 278 | public: 279 | TIterator(ElementPointer inElementPointer) 280 | { 281 | IteratorData = inElementPointer; 282 | } 283 | 284 | public: 285 | TIterator& operator++() 286 | { 287 | IteratorData++; 288 | return *this; 289 | } 290 | 291 | TIterator operator++(int32_t) 292 | { 293 | TIterator iteratorCopy = *this; 294 | ++(*this); 295 | return iteratorCopy; 296 | } 297 | 298 | TIterator& operator--() 299 | { 300 | IteratorData--; 301 | return *this; 302 | } 303 | 304 | TIterator operator--(int32_t) 305 | { 306 | TIterator iteratorCopy = *this; 307 | --(*this); 308 | return iteratorCopy; 309 | } 310 | 311 | ElementReference operator[](int32_t index) 312 | { 313 | return *(IteratorData[index]); 314 | } 315 | 316 | ElementPointer operator->() 317 | { 318 | return IteratorData; 319 | } 320 | 321 | ElementReference operator*() 322 | { 323 | return *IteratorData; 324 | } 325 | 326 | public: 327 | bool operator==(const TIterator& other) const 328 | { 329 | return (IteratorData == other.IteratorData); 330 | } 331 | 332 | bool operator!=(const TIterator& other) const 333 | { 334 | return !(*this == other); 335 | } 336 | }; 337 | 338 | template 339 | class TArray 340 | { 341 | public: 342 | using ElementType = InElementType; 343 | using ElementPointer = ElementType*; 344 | using ElementReference = ElementType&; 345 | using ElementConstReference = const ElementType&; 346 | using Iterator = TIterator>; 347 | 348 | private: 349 | ElementPointer ArrayData; 350 | int32_t ArrayCount; 351 | int32_t ArrayMax; 352 | 353 | public: 354 | TArray() : ArrayData(nullptr), ArrayCount(0), ArrayMax(0) 355 | { 356 | //ReAllocate(sizeof(ElementType)); 357 | } 358 | 359 | ~TArray() 360 | { 361 | //Clear(); 362 | //::operator delete(ArrayData, ArrayMax * sizeof(ElementType)); 363 | } 364 | 365 | public: 366 | ElementConstReference operator[](int32_t index) const 367 | { 368 | return ArrayData[index]; 369 | } 370 | 371 | ElementReference operator[](int32_t index) 372 | { 373 | return ArrayData[index]; 374 | } 375 | 376 | ElementConstReference At(int32_t index) const 377 | { 378 | return ArrayData[index]; 379 | } 380 | 381 | ElementReference At(int32_t index) 382 | { 383 | return ArrayData[index]; 384 | } 385 | 386 | void Add(ElementConstReference newElement) 387 | { 388 | if (ArrayCount >= ArrayMax) 389 | { 390 | ReAllocate(sizeof(ElementType) * (ArrayCount + 1)); 391 | } 392 | 393 | new(&ArrayData[ArrayCount]) ElementType(newElement); 394 | ArrayCount++; 395 | } 396 | 397 | void Add(ElementReference& newElement) 398 | { 399 | if (ArrayCount >= ArrayMax) 400 | { 401 | ReAllocate(sizeof(ElementType) * (ArrayCount + 1)); 402 | } 403 | 404 | new(&ArrayData[ArrayCount]) ElementType(newElement); 405 | ArrayCount++; 406 | } 407 | 408 | void PopBack() 409 | { 410 | if (ArrayCount > 0) 411 | { 412 | ArrayCount--; 413 | ArrayData[ArrayCount].~ElementType(); 414 | } 415 | } 416 | 417 | void Clear() 418 | { 419 | for (int32_t i = 0; i < ArrayCount; i++) 420 | { 421 | ArrayData[i].~ElementType(); 422 | } 423 | 424 | ArrayCount = 0; 425 | } 426 | 427 | int32_t Num() const 428 | { 429 | return ArrayCount; 430 | } 431 | 432 | int32_t Max() const 433 | { 434 | return ArrayMax; 435 | } 436 | 437 | Iterator begin() 438 | { 439 | return Iterator(ArrayData); 440 | } 441 | 442 | Iterator end() 443 | { 444 | return Iterator(ArrayData + ArrayCount); 445 | } 446 | 447 | private: 448 | void ReAllocate(int32_t newArrayMax) 449 | { 450 | ElementPointer newArrayData = (ElementPointer)::operator new(newArrayMax * sizeof(ElementType)); 451 | int32_t newNum = ArrayCount; 452 | 453 | if (newArrayMax < newNum) 454 | { 455 | newNum = newArrayMax; 456 | } 457 | 458 | for (int32_t i = 0; i < newNum; i++) 459 | { 460 | new(newArrayData + i) ElementType(std::move(ArrayData[i])); 461 | } 462 | 463 | for (int32_t i = 0; i < ArrayCount; i++) 464 | { 465 | ArrayData[i].~ElementType(); 466 | } 467 | 468 | ::operator delete(ArrayData, ArrayMax * sizeof(ElementType)); 469 | ArrayData = newArrayData; 470 | ArrayMax = newArrayMax; 471 | } 472 | }; 473 | 474 | // THIS CLASS CAN BE GAME SPECIFIC, MOST GAMES WILL GENERATE A STRUCT MIRROR; JUST PASTE THE FIELDS HERE IF SO. 475 | template 476 | class TMap 477 | { 478 | private: 479 | class TPair 480 | { 481 | public: 482 | TKey Key; 483 | TValue Value; 484 | int32_t* HashNext; 485 | }; 486 | 487 | public: 488 | using ElementType = TPair; 489 | using ElementPointer = ElementType*; 490 | using ElementReference = ElementType&; 491 | using ElementConstReference = const ElementType&; 492 | using Iterator = TIterator>; 493 | 494 | public: 495 | ElementPointer ElementData; // 0x0000 (0x0008) 496 | int32_t ElementCount; // 0x0008 (0x0004) 497 | int32_t ElementMax; // 0x000C (0x0004) 498 | uintptr_t IndirectData; // 0x0010 (0x0008) 499 | int32_t InlineData[0x4]; // 0x0018 (0x0010) 500 | int32_t NumBits; // 0x0028 (0x0004) 501 | int32_t MaxBits; // 0x002C (0x0004) 502 | int32_t FirstFreeIndex; // 0x0030 (0x0004) 503 | int32_t NumFreeIndices; // 0x0034 (0x0004) 504 | int64_t InlineHash; // 0x0038 (0x0008) 505 | int32_t* Hash; // 0x0040 (0x0008) 506 | int32_t HashCount; // 0x0048 (0x0004) 507 | 508 | public: 509 | TMap() 510 | { 511 | ElementData = nullptr; 512 | ElementCount = 0; 513 | ElementMax = 0; 514 | IndirectData = NULL; 515 | NumBits = 0; 516 | MaxBits = 0; 517 | FirstFreeIndex = 0; 518 | NumFreeIndices = 0; 519 | InlineHash = 0; 520 | Hash = nullptr; 521 | HashCount = 0; 522 | } 523 | 524 | TMap(struct FMap_Mirror& fMap) 525 | { 526 | *this = *reinterpret_cast*>(&fMap); 527 | } 528 | 529 | ~TMap() {} 530 | 531 | public: 532 | ElementConstReference operator[](int32_t index) const 533 | { 534 | return ElementData[index]; 535 | } 536 | 537 | ElementReference operator[](int32_t index) 538 | { 539 | return ElementData[index]; 540 | } 541 | 542 | const TValue& operator[](const TKey& key) const 543 | { 544 | for (int32_t i = 0; i < Num(); i++) 545 | { 546 | const TPair& pair = ElementData[i]; 547 | 548 | if (pair.Key == key) 549 | { 550 | return pair.Value; 551 | } 552 | } 553 | } 554 | 555 | TValue& operator[](const TKey& key) 556 | { 557 | for (int32_t i = 0; i < Num(); i++) 558 | { 559 | TPair& pair = ElementData[i]; 560 | 561 | if (pair.Key == key) 562 | { 563 | return pair.Value; 564 | } 565 | } 566 | } 567 | 568 | TMap& operator=(const struct FMap_Mirror& fMap) 569 | { 570 | *this = *reinterpret_cast*>(&fMap); 571 | return *this; 572 | } 573 | 574 | ElementConstReference At(int32_t index) const 575 | { 576 | return ElementData[index]; 577 | } 578 | 579 | ElementReference At(int32_t index) 580 | { 581 | return ElementData[index]; 582 | } 583 | 584 | int32_t Num() const 585 | { 586 | return ElementCount; 587 | } 588 | 589 | int32_t Max() const 590 | { 591 | return ElementMax; 592 | } 593 | 594 | Iterator begin() 595 | { 596 | return Iterator(ElementData); 597 | } 598 | 599 | Iterator end() 600 | { 601 | return Iterator(ElementData + ElementCount); 602 | } 603 | }; 604 | 605 | /* 606 | # ========================================================================================= # 607 | # Globals 608 | # ========================================================================================= # 609 | */ 610 | 611 | extern TArray* GObjects; 612 | extern TArray* GNames; 613 | 614 | /* 615 | # ========================================================================================= # 616 | # Fields 617 | # ========================================================================================= # 618 | */ 619 | 620 | class ClassField 621 | { 622 | public: 623 | EFieldIds Id; 624 | std::string Type; 625 | uintptr_t Offset; 626 | size_t Size; 627 | 628 | public: 629 | ClassField(); 630 | ClassField(EFieldIds id, size_t size); 631 | ~ClassField(); 632 | 633 | public: 634 | ClassField operator=(const ClassField& other); 635 | }; 636 | 637 | namespace Fields 638 | { 639 | extern std::vector> FieldMethods; 640 | extern std::map IdToType; 641 | extern std::map GlobalFields; 642 | 643 | uintptr_t GetOffset(EFieldIds fieldId); 644 | std::map GetOrderedFields(EClassTypes classType, size_t& classSize, size_t& startOffset); 645 | void AssertField(const ClassField& classField); 646 | } 647 | 648 | #define REGISTER_FIELD(type, method, id) static void Reg##method(){ Fields::AssertField(ClassField(id, sizeof(type))); } 649 | 650 | /* 651 | # ========================================================================================= # 652 | # Structs 653 | # ========================================================================================= # 654 | */ 655 | 656 | // FNameEntry 657 | // (0x0000 - 0x000C) 658 | struct FNameEntry 659 | { 660 | public: 661 | uint64_t Flags; // 0x0000 (0x08) 662 | int32_t Index; REGISTER_FIELD(int32_t, Index, EFieldIds::FNAMEENTRY_INDEX) // 0x0008 (0x04) 663 | 664 | #ifdef CHARACTER_UTF16 665 | wchar_t Name[0x400]; REGISTER_FIELD(wchar_t, Name, EFieldIds::FNAMEENTRY_NAME_UTF16) // 0x000C (0x00) 666 | #endif 667 | #ifdef CHARACTER_UTF8 668 | char Name[0x400]; REGISTER_FIELD(wchar_t, Name, EFieldIds::FNAMEENTRY_NAME_UTF8) // 0x000C (0x00) 669 | #endif 670 | 671 | public: 672 | FNameEntry() : Flags(0), Index(-1) {} 673 | ~FNameEntry() {} 674 | 675 | public: 676 | int32_t GetIndex() const 677 | { 678 | return Index; 679 | } 680 | 681 | #ifdef CHARACTER_UTF16 682 | std::string ToString() const 683 | { 684 | std::wstring ws(Name); 685 | std::string str(ws.begin(), ws.end()); 686 | return str; 687 | } 688 | #endif 689 | 690 | #ifdef CHARACTER_UTF8 691 | std::string ToString() const 692 | { 693 | return std::string(Name); 694 | } 695 | #endif 696 | 697 | #ifdef CHARACTER_UTF16 698 | const wchar_t* GetWideName() const 699 | { 700 | return Name; 701 | } 702 | #endif 703 | 704 | #ifdef CHARACTER_UTF8 705 | const char* GetAnsiName() const 706 | { 707 | return Name; 708 | } 709 | #endif 710 | }; 711 | 712 | // FName 713 | // (0x0000 - 0x0008) 714 | struct FName 715 | { 716 | public: 717 | #ifdef CHARACTER_UTF16 718 | using ElementType = const wchar_t; 719 | #endif 720 | #ifdef CHARACTER_UTF8 721 | using ElementType = const char; 722 | #endif 723 | using ElementPointer = ElementType*; 724 | 725 | private: 726 | int32_t FNameEntryId; // 0x0000 (0x04) 727 | int32_t InstanceNumber; // 0x0004 (0x04) 728 | 729 | public: 730 | FName() : FNameEntryId(-1), InstanceNumber(0) {} 731 | 732 | FName(int32_t id) : FNameEntryId(id), InstanceNumber(0) {} 733 | 734 | #ifdef CHARACTER_UTF16 735 | FName(const ElementPointer nameToFind) : FNameEntryId(0), InstanceNumber(0) 736 | { 737 | static std::vector nameCache{}; 738 | 739 | for (int32_t entryId : nameCache) 740 | { 741 | if (Names()->At(entryId)) 742 | { 743 | if (!wcscmp(Names()->At(entryId)->Name, nameToFind)) 744 | { 745 | FNameEntryId = entryId; 746 | return; 747 | } 748 | } 749 | } 750 | 751 | for (int32_t i = 0; i < Names()->Num(); i++) 752 | { 753 | if (Names()->At(i)) 754 | { 755 | if (!wcscmp(Names()->At(i)->Name, nameToFind)) 756 | { 757 | nameCache.push_back(i); 758 | FNameEntryId = i; 759 | } 760 | } 761 | } 762 | } 763 | #endif 764 | 765 | #ifdef CHARACTER_UTF8 766 | FName(ElementPointer nameToFind) : FNameEntryId(0), InstanceNumber(0) 767 | { 768 | static std::vector nameCache{}; 769 | 770 | for (int32_t entryId : nameCache) 771 | { 772 | if (Names()->At(entryId)) 773 | { 774 | if (!strcmp(Names()->At(entryId)->Name, nameToFind)) 775 | { 776 | FNameEntryId = entryId; 777 | return; 778 | } 779 | } 780 | } 781 | 782 | for (int32_t i = 0; i < Names()->Num(); i++) 783 | { 784 | if (Names()->At(i)) 785 | { 786 | if (!strcmp(Names()->At(i)->Name, nameToFind)) 787 | { 788 | nameCache.push_back(i); 789 | FNameEntryId = i; 790 | } 791 | } 792 | } 793 | } 794 | #endif 795 | 796 | ~FName() {} 797 | 798 | public: 799 | static class TArray* Names() 800 | { 801 | TArray* GNamesArray = reinterpret_cast*>(GNames); 802 | return GNamesArray; 803 | } 804 | 805 | int32_t GetDisplayIndex() const 806 | { 807 | return FNameEntryId; 808 | } 809 | 810 | const struct FNameEntry GetDisplayNameEntry() const 811 | { 812 | if (IsValid()) 813 | { 814 | return *Names()->At(FNameEntryId); 815 | } 816 | 817 | return FNameEntry(); 818 | } 819 | 820 | struct FNameEntry* GetEntry() 821 | { 822 | if (IsValid()) 823 | { 824 | return Names()->At(FNameEntryId); 825 | } 826 | 827 | return nullptr; 828 | } 829 | 830 | int32_t GetNumber() const 831 | { 832 | return InstanceNumber; 833 | } 834 | 835 | void SetNumber(int32_t newNumber) 836 | { 837 | InstanceNumber = newNumber; 838 | } 839 | 840 | std::string ToString() const 841 | { 842 | if (IsValid()) 843 | { 844 | return GetDisplayNameEntry().ToString(); 845 | } 846 | 847 | return std::string("UnknownName"); 848 | } 849 | 850 | bool IsValid() const 851 | { 852 | if (FNameEntryId < 0 || FNameEntryId > Names()->Num()) 853 | { 854 | return false; 855 | } 856 | 857 | return true; 858 | } 859 | 860 | public: 861 | struct FName& operator=(const struct FName& other) 862 | { 863 | FNameEntryId = other.FNameEntryId; 864 | InstanceNumber = other.InstanceNumber; 865 | return *this; 866 | } 867 | 868 | bool operator==(const struct FName& other) const 869 | { 870 | return (FNameEntryId == other.FNameEntryId); 871 | } 872 | 873 | bool operator!=(const struct FName& other) const 874 | { 875 | return (FNameEntryId != other.FNameEntryId); 876 | } 877 | }; 878 | 879 | // FString 880 | // (0x0000 - 0x0010) 881 | class FString 882 | { 883 | public: 884 | #ifdef CHARACTER_UTF16 885 | using ElementType = const wchar_t; 886 | #endif 887 | #ifdef CHARACTER_UTF8 888 | using ElementType = const char; 889 | #endif 890 | using ElementPointer = ElementType*; 891 | 892 | private: 893 | ElementPointer ArrayData; // 0x0000 (0x08) 894 | int32_t ArrayCount; // 0x0008 (0x04) 895 | int32_t ArrayMax; // 0x000C (0x04) 896 | 897 | public: 898 | FString() : ArrayData(nullptr), ArrayCount(0), ArrayMax(0) {} 899 | 900 | #ifdef CHARACTER_UTF16 901 | FString(ElementPointer other) : ArrayData(nullptr), ArrayCount(0), ArrayMax(0) 902 | { 903 | ArrayMax = ArrayCount = *other ? (wcslen(other) + 1) : 0; 904 | 905 | if (ArrayCount > 0) 906 | { 907 | ArrayData = other; 908 | } 909 | } 910 | #endif 911 | 912 | #ifdef CHARACTER_UTF8 913 | FString(ElementPointer other) : ArrayData(nullptr), ArrayCount(0), ArrayMax(0) 914 | { 915 | ArrayMax = ArrayCount = *other ? (strlen(other) + 1) : 0; 916 | 917 | if (ArrayCount > 0) 918 | { 919 | ArrayData = other; 920 | } 921 | } 922 | #endif 923 | 924 | ~FString() {} 925 | 926 | public: 927 | #ifdef CHARACTER_UTF16 928 | std::string ToString() const 929 | { 930 | if (IsValid()) 931 | { 932 | std::wstring wideStr(ArrayData); 933 | std::string str(wideStr.begin(), wideStr.end()); 934 | return str; 935 | } 936 | 937 | return "null"; 938 | } 939 | #endif 940 | 941 | #ifdef CHARACTER_UTF8 942 | std::string ToString() const 943 | { 944 | if (IsValid()) 945 | { 946 | return std::string(ArrayData); 947 | } 948 | 949 | return "null"; 950 | } 951 | #endif 952 | 953 | bool IsValid() const 954 | { 955 | return (!!ArrayData); 956 | } 957 | 958 | #ifdef CHARACTER_UTF16 959 | class FString& operator=(ElementPointer other) 960 | { 961 | if (ArrayData != other) 962 | { 963 | ArrayMax = ArrayCount = *other ? (wcslen(other) + 1) : 0; 964 | 965 | if (ArrayCount > 0) 966 | { 967 | ArrayData = other; 968 | } 969 | } 970 | 971 | return *this; 972 | } 973 | #endif 974 | 975 | #ifdef CHARACTER_UTF8 976 | class FString& operator=(ElementPointer other) 977 | { 978 | if (ArrayData != other) 979 | { 980 | ArrayMax = ArrayCount = *other ? (strlen(other) + 1) : 0; 981 | 982 | if (ArrayCount > 0) 983 | { 984 | ArrayData = other; 985 | } 986 | } 987 | 988 | return *this; 989 | } 990 | #endif 991 | 992 | public: 993 | #ifdef CHARACTER_UTF16 994 | bool operator==(const FString& other) 995 | { 996 | return (!wcscmp(ArrayData, other.ArrayData)); 997 | } 998 | 999 | bool operator!=(const FString& other) 1000 | { 1001 | return (wcscmp(ArrayData, other.ArrayData)); 1002 | } 1003 | #endif 1004 | 1005 | #ifdef CHARACTER_UTF8 1006 | bool operator==(const FString& other) 1007 | { 1008 | return (!strcmp(ArrayData, other.ArrayData)); 1009 | } 1010 | 1011 | bool operator!=(const FString& other) 1012 | { 1013 | return (strcmp(ArrayData, other.ArrayData)); 1014 | } 1015 | #endif 1016 | }; 1017 | 1018 | // FScriptDelegate [This struct is game dependent, don't forget to reverse its contents or just its size!] 1019 | // (0x0000 - 0x0009) 1020 | struct FScriptDelegate 1021 | { 1022 | class UObject* Object; // 0x0000 (0x08) 1023 | uint8_t UnknownData[0x1]; // 0x0008 (0x01) 1024 | }; 1025 | 1026 | struct FPointer 1027 | { 1028 | uintptr_t Dummy; 1029 | }; 1030 | 1031 | struct FQWord 1032 | { 1033 | int32_t A; 1034 | int32_t B; 1035 | }; 1036 | 1037 | /* 1038 | # ========================================================================================= # 1039 | # Classes 1040 | # ========================================================================================= # 1041 | */ 1042 | 1043 | // Class Core.Object 1044 | // (0x0000 - 0x0034) 1045 | class UObject 1046 | { 1047 | public: 1048 | struct FPointer VfTableObject; REGISTER_FIELD(FPointer, VfTableObject, EFieldIds::UOBJECT_VFTABLE) // 0x0000 (0x08) 1049 | uint8_t UnknownData00[0x10]; // Example of padding, you do not need to register this because offsets are all automatically calculated. 1050 | int32_t ObjectInternalInteger; REGISTER_FIELD(int32_t, ObjectInternalInteger, EFieldIds::UOBJECT_INDEX) // 0x0018 (0x04) 1051 | class UObject* Outer; REGISTER_FIELD(class UObject*, Outer, EFieldIds::UOBJECT_OUTER) // 0x001C (0x08) 1052 | struct FName Name; REGISTER_FIELD(FName, Name, EFieldIds::UOBJECT_NAME) // 0x0024 (0x08) 1053 | class UClass* Class; REGISTER_FIELD(class UClass*, Class, EFieldIds::UOBJECT_CLASS) // 0x002C (0x08) 1054 | 1055 | public: 1056 | static UClass* StaticClass() 1057 | { 1058 | static UClass* uClassPointer = nullptr; 1059 | 1060 | if (!uClassPointer) 1061 | { 1062 | uClassPointer = UObject::FindClass("Class Core.Object"); 1063 | } 1064 | 1065 | return uClassPointer; 1066 | } 1067 | 1068 | static TArray* GObjObjects(); 1069 | 1070 | std::string GetName(); 1071 | std::string GetNameCPP(); 1072 | std::string GetFullName(); 1073 | std::string GetPackageName(); 1074 | class UObject* GetPackageObj(); 1075 | template static T* FindObject(const std::string& objectFullName) 1076 | { 1077 | for (UObject* uObject : *UObject::GObjObjects()) 1078 | { 1079 | if (uObject && uObject->IsA(T::StaticClass())) 1080 | { 1081 | if (uObject->GetFullName() == objectFullName) 1082 | { 1083 | return static_cast(uObject); 1084 | } 1085 | } 1086 | } 1087 | 1088 | return nullptr; 1089 | } 1090 | template static uint32_t CountObject(const std::string& objectName) 1091 | { 1092 | static std::map countCache; 1093 | 1094 | if (countCache.find(objectName) == countCache.end()) 1095 | { 1096 | countCache[objectName] = 0; 1097 | 1098 | for (UObject* uObject : *UObject::GObjObjects()) 1099 | { 1100 | if (uObject && uObject->IsA(T::StaticClass())) 1101 | { 1102 | if (uObject->GetName() == objectName) 1103 | { 1104 | countCache[uObject->GetName()]++; 1105 | } 1106 | } 1107 | } 1108 | } 1109 | 1110 | return countCache[objectName]; 1111 | } 1112 | static class UClass* FindClass(const std::string& classFullName); 1113 | template bool IsA() 1114 | { 1115 | if (std::is_base_of::value) 1116 | { 1117 | return IsA(T::StaticClass()); 1118 | } 1119 | } 1120 | bool IsA(class UClass* uClass); 1121 | bool IsA(int32_t objInternalInteger); 1122 | }; 1123 | 1124 | //Class Core.Field 1125 | // 0x0010 (0x0034 - 0x0044) 1126 | class UField : public UObject 1127 | { 1128 | public: 1129 | class UField* Next; REGISTER_FIELD(class UField*, Next, EFieldIds::UFIELD_NEXT) // 0x0034 (0x08) 1130 | class UField* SuperField; REGISTER_FIELD(class UField*, SuperField, EFieldIds::UFIELD_SUPERFIELD) // 0x003C (0x08) [SUPERFIELD CAN EITHER BE HERE, OR IN USTRUCT DPENDING ON THE GAME. COMMENT OUT ACCORDINGLY!] 1131 | 1132 | public: 1133 | static UClass* StaticClass() 1134 | { 1135 | static UClass* uClassPointer = nullptr; 1136 | 1137 | if (!uClassPointer) 1138 | { 1139 | uClassPointer = UObject::FindClass("Class Core.Field"); 1140 | } 1141 | 1142 | return uClassPointer; 1143 | }; 1144 | }; 1145 | 1146 | // Class Core.Enum 1147 | // 0x0010 (0x0044 - 0x0054) 1148 | class UEnum : public UField 1149 | { 1150 | public: 1151 | TArray Names; REGISTER_FIELD(TArray, Names, EFieldIds::UENUM_NAMES) // 0x0044 (0x10) 1152 | 1153 | public: 1154 | static UClass* StaticClass() 1155 | { 1156 | static UClass* uClassPointer = nullptr; 1157 | 1158 | if (!uClassPointer) 1159 | { 1160 | uClassPointer = UObject::FindClass("Class Core.Enum"); 1161 | } 1162 | 1163 | return uClassPointer; 1164 | }; 1165 | }; 1166 | 1167 | // Class Core.Const 1168 | // 0x0010 (0x0044 - 0x0054) 1169 | class UConst : public UField 1170 | { 1171 | public: 1172 | class FString Value; REGISTER_FIELD(FString, Value, EFieldIds::UCONST_VALUE) // 0x0044 (0x10) 1173 | 1174 | public: 1175 | static UClass* StaticClass() 1176 | { 1177 | static UClass* uClassPointer = nullptr; 1178 | 1179 | if (!uClassPointer) 1180 | { 1181 | uClassPointer = UObject::FindClass("Class Core.Const"); 1182 | } 1183 | 1184 | return uClassPointer; 1185 | }; 1186 | }; 1187 | 1188 | // Class Core.Property 1189 | // 0x0014 (0x0044 - 0x0058) 1190 | class UProperty : public UField 1191 | { 1192 | public: 1193 | unsigned long ArrayDim; REGISTER_FIELD(unsigned long, ArrayDim, EFieldIds::UPROPERTY_DIMENSION) // 0x0044 (0x04) 1194 | unsigned long ElementSize; REGISTER_FIELD(unsigned long, ElementSize, EFieldIds::UPROPERTY_SIZE) // 0x0048 (0x04) 1195 | uint64_t PropertyFlags; REGISTER_FIELD(unsigned long, PropertyFlags, EFieldIds::UPROPERTY_FLAGS) // 0x004C (0x08) 1196 | unsigned long Offset; REGISTER_FIELD(unsigned long, Offset, EFieldIds::UPROPERTY_OFFSET) // 0x0054 (0x04) 1197 | 1198 | public: 1199 | static UClass* StaticClass() 1200 | { 1201 | static UClass* uClassPointer = nullptr; 1202 | 1203 | if (!uClassPointer) 1204 | { 1205 | uClassPointer = UObject::FindClass("Class Core.Property"); 1206 | } 1207 | 1208 | return uClassPointer; 1209 | }; 1210 | }; 1211 | 1212 | // Class Core.Struct 1213 | // 0x0014 (0x0044 - 0x0058) 1214 | class UStruct : public UField 1215 | { 1216 | public: 1217 | //class UField* SuperField; REGISTER_FIELD(class UField*, SuperField, EFieldIds::USTRUCT_SUPERFIELD) // 0x0044 (0x08) [SUPERFIELD CAN EITHER BE HERE, OR IN UFIELD DPENDING ON THE GAME. COMMENT OUT ACCORDINGLY!] 1218 | class UField* Children; REGISTER_FIELD(class UField*, Children, EFieldIds::USTRUCT_CHILDREN) // 0x004C (0x08) 1219 | unsigned long PropertySize; REGISTER_FIELD(unsigned long, PropertySize, EFieldIds::USTRUCT_SIZE) // 0x0054 (0x04) 1220 | 1221 | public: 1222 | static UClass* StaticClass() 1223 | { 1224 | static UClass* uClassPointer = nullptr; 1225 | 1226 | if (!uClassPointer) 1227 | { 1228 | uClassPointer = UObject::FindClass("Class Core.Struct"); 1229 | } 1230 | 1231 | return uClassPointer; 1232 | }; 1233 | }; 1234 | 1235 | // Class Core.Function 1236 | // 0x000A (0x0058 - 0x0062) 1237 | class UFunction : public UStruct 1238 | { 1239 | public: 1240 | uint64_t FunctionFlags; REGISTER_FIELD(uint64_t, FunctionFlags, EFieldIds::UFUNCTION_FLAGS) // 0x0058 (0x08) 1241 | uint16_t iNative; REGISTER_FIELD(uint16_t, iNative, EFieldIds::UFUNCTION_NATIVE) // 0x0060 (0x02) 1242 | 1243 | public: 1244 | static UClass* StaticClass() 1245 | { 1246 | static UClass* uClassPointer = nullptr; 1247 | 1248 | if (!uClassPointer) 1249 | { 1250 | uClassPointer = UObject::FindClass("Class Core.Function"); 1251 | } 1252 | 1253 | return uClassPointer; 1254 | }; 1255 | 1256 | static UFunction* FindFunction(const std::string& functionFullName); 1257 | }; 1258 | 1259 | // Class Core.ScriptStruct 1260 | // 0x0001 (0x0058 - 0x0059) 1261 | class UScriptStruct : public UStruct 1262 | { 1263 | public: 1264 | uint8_t UnknownData00[0x01]; // 0x0058 (0x01) [USE THIS CLASSES PROPERTYSIZE IN RECLASS TO DETERMINE THE SIZE OF THE UNKNOWNDATA] 1265 | public: 1266 | static UClass* StaticClass() 1267 | { 1268 | static UClass* uClassPointer = nullptr; 1269 | 1270 | if (!uClassPointer) 1271 | { 1272 | uClassPointer = UObject::FindClass("Class Core.ScriptStruct"); 1273 | } 1274 | 1275 | return uClassPointer; 1276 | }; 1277 | }; 1278 | 1279 | // Class Core.State 1280 | // 0x0001 (0x0058 - 0x0059) 1281 | class UState : public UStruct 1282 | { 1283 | public: 1284 | uint8_t UnknownData00[0x01]; // 0x0058 (0x01) [USE THIS CLASSES PROPERTYSIZE IN RECLASS TO DETERMINE THE SIZE OF THE UNKNOWNDATA] 1285 | public: 1286 | static UClass* StaticClass() 1287 | { 1288 | static UClass* uClassPointer = nullptr; 1289 | 1290 | if (!uClassPointer) 1291 | { 1292 | uClassPointer = UObject::FindClass("Class Core.State"); 1293 | } 1294 | 1295 | return uClassPointer; 1296 | }; 1297 | }; 1298 | 1299 | // Class Core.Class 1300 | // 0x0001 (0x0058 - 0x0059) 1301 | class UClass : public UState 1302 | { 1303 | public: 1304 | uint8_t UnknownData00[0x01]; // 0x0058 (0x00) [USE THIS CLASSES PROPERTYSIZE IN RECLASS TO DETERMINE THE SIZE OF THE UNKNOWNDATA] 1305 | public: 1306 | static UClass* StaticClass() 1307 | { 1308 | static UClass* uClassPointer = nullptr; 1309 | 1310 | if (!uClassPointer) 1311 | { 1312 | uClassPointer = UObject::FindClass("Class Core.Class"); 1313 | } 1314 | 1315 | return uClassPointer; 1316 | }; 1317 | }; 1318 | 1319 | /* 1320 | # ========================================================================================= # 1321 | # Property Sub Classes 1322 | # ========================================================================================= # 1323 | */ 1324 | 1325 | //Class Core.StructProperty 1326 | // 0x0008 (0x0058 - 0x0060) 1327 | class UStructProperty : public UProperty 1328 | { 1329 | public: 1330 | class UStruct* Struct; REGISTER_FIELD(class UStruct*, Struct, EFieldIds::USTRUCTPROPERTY_STRUCT) // 0x0058 (0x08) 1331 | 1332 | public: 1333 | static UClass* StaticClass() 1334 | { 1335 | static UClass* uClassPointer = nullptr; 1336 | 1337 | if (!uClassPointer) 1338 | { 1339 | uClassPointer = UObject::FindClass("Class Core.StructProperty"); 1340 | } 1341 | 1342 | return uClassPointer; 1343 | }; 1344 | }; 1345 | 1346 | // Class Core.StrProperty 1347 | // 0x0000 (0x0058 - 0x0058) 1348 | class UStrProperty : public UProperty 1349 | { 1350 | public: 1351 | public: 1352 | static UClass* StaticClass() 1353 | { 1354 | static UClass* uClassPointer = nullptr; 1355 | 1356 | if (!uClassPointer) 1357 | { 1358 | uClassPointer = UObject::FindClass("Class Core.StrProperty"); 1359 | } 1360 | 1361 | return uClassPointer; 1362 | }; 1363 | }; 1364 | 1365 | // Class Core.QWordProperty 1366 | // 0x0000 (0x0058 - 0x0058) 1367 | class UQWordProperty : public UProperty 1368 | { 1369 | public: 1370 | public: 1371 | static UClass* StaticClass() 1372 | { 1373 | static UClass* uClassPointer = nullptr; 1374 | 1375 | if (!uClassPointer) 1376 | { 1377 | uClassPointer = UObject::FindClass("Class Core.QWordProperty"); 1378 | } 1379 | 1380 | return uClassPointer; 1381 | }; 1382 | }; 1383 | 1384 | // Class Core.ObjectProperty 1385 | // 0x0008 (0x0058 - 0x0060) 1386 | class UObjectProperty : public UProperty 1387 | { 1388 | public: 1389 | class UClass* PropertyClass; REGISTER_FIELD(class UClass*, PropertyClass, EFieldIds::UOBJECTPROPERTY_PROPERTY) // 0x0058 (0x08) 1390 | 1391 | public: 1392 | static UClass* StaticClass() 1393 | { 1394 | static UClass* uClassPointer = nullptr; 1395 | 1396 | if (!uClassPointer) 1397 | { 1398 | uClassPointer = UObject::FindClass("Class Core.ObjectProperty"); 1399 | } 1400 | 1401 | return uClassPointer; 1402 | }; 1403 | }; 1404 | 1405 | // Class Core.ComponentProperty 1406 | // 0x0000 (0x0058 - 0x0058) 1407 | class UComponentProperty : public UObjectProperty 1408 | { 1409 | public: 1410 | public: 1411 | static UClass* StaticClass() 1412 | { 1413 | static UClass* uClassPointer = nullptr; 1414 | 1415 | if (!uClassPointer) 1416 | { 1417 | uClassPointer = UObject::FindClass("Class Core.ComponentProperty"); 1418 | } 1419 | 1420 | return uClassPointer; 1421 | }; 1422 | }; 1423 | 1424 | // Class Core.ClassProperty 1425 | // 0x0008 (0x0058 - 0x0060) 1426 | class UClassProperty : public UObjectProperty 1427 | { 1428 | public: 1429 | class UClass* MetaClass; REGISTER_FIELD(class UClass*, MetaClass, EFieldIds::UCLASSPROPERTY_METACLASS) // 0x0058 (0x08) 1430 | 1431 | public: 1432 | static UClass* StaticClass() 1433 | { 1434 | static UClass* uClassPointer = nullptr; 1435 | 1436 | if (!uClassPointer) 1437 | { 1438 | uClassPointer = UObject::FindClass("Class Core.ClassProperty"); 1439 | } 1440 | 1441 | return uClassPointer; 1442 | }; 1443 | }; 1444 | 1445 | // Class Core.NameProperty 1446 | // 0x0000 (0x0058 - 0x0000) 1447 | class UNameProperty : public UProperty 1448 | { 1449 | public: 1450 | public: 1451 | static UClass* StaticClass() 1452 | { 1453 | static UClass* uClassPointer = nullptr; 1454 | 1455 | if (!uClassPointer) 1456 | { 1457 | uClassPointer = UObject::FindClass("Class Core.NameProperty"); 1458 | } 1459 | 1460 | return uClassPointer; 1461 | }; 1462 | }; 1463 | 1464 | // Class Core.MapProperty 1465 | // 0x0010 (0x0058 - 0x0068) 1466 | class UMapProperty : public UProperty 1467 | { 1468 | public: 1469 | class UProperty* Key; REGISTER_FIELD(class UProperty*, Key, EFieldIds::UMAPPROPERTY_KEY) // 0x0058 (0x08) 1470 | class UProperty* Value; REGISTER_FIELD(class UProperty*, Value, EFieldIds::UMAPPROPERTY_VALUE) // 0x0060 (0x08) 1471 | 1472 | public: 1473 | static UClass* StaticClass() 1474 | { 1475 | static UClass* uClassPointer = nullptr; 1476 | 1477 | if (!uClassPointer) 1478 | { 1479 | uClassPointer = UObject::FindClass("Class Core.MapProperty"); 1480 | } 1481 | 1482 | return uClassPointer; 1483 | }; 1484 | }; 1485 | 1486 | // Class Core.IntProperty 1487 | // 0x0000 (0x0058 - 0x0058) 1488 | class UIntProperty : public UProperty 1489 | { 1490 | public: 1491 | public: 1492 | static UClass* StaticClass() 1493 | { 1494 | static UClass* uClassPointer = nullptr; 1495 | 1496 | if (!uClassPointer) 1497 | { 1498 | uClassPointer = UObject::FindClass("Class Core.IntProperty"); 1499 | } 1500 | 1501 | return uClassPointer; 1502 | }; 1503 | }; 1504 | 1505 | // Class Core.InterfaceProperty 1506 | // 0x0008 (0x0058 - 0x0060) 1507 | class UInterfaceProperty : public UProperty 1508 | { 1509 | public: 1510 | class UClass* InterfaceClass; REGISTER_FIELD(class UClass*, InterfaceClass, EFieldIds::UINTERFACEPROPERTY_CLASS) // 0x0058 (0x08) 1511 | 1512 | public: 1513 | static UClass* StaticClass() 1514 | { 1515 | static UClass* uClassPointer = nullptr; 1516 | 1517 | if (!uClassPointer) 1518 | { 1519 | uClassPointer = UObject::FindClass("Class Core.InterfaceProperty"); 1520 | } 1521 | 1522 | return uClassPointer; 1523 | }; 1524 | }; 1525 | 1526 | // Class Core.FloatProperty 1527 | // 0x0000 (0x0058 - 0x0058) 1528 | class UFloatProperty : public UProperty 1529 | { 1530 | public: 1531 | public: 1532 | static UClass* StaticClass() 1533 | { 1534 | static UClass* uClassPointer = nullptr; 1535 | 1536 | if (!uClassPointer) 1537 | { 1538 | uClassPointer = UObject::FindClass("Class Core.FloatProperty"); 1539 | } 1540 | 1541 | return uClassPointer; 1542 | }; 1543 | }; 1544 | 1545 | // Class Core.DelegateProperty 1546 | // 0x0010 (0x0058 - 0x0068) 1547 | class UDelegateProperty : public UProperty 1548 | { 1549 | public: 1550 | class UFuncton* Function; REGISTER_FIELD(class UFuncton*, Function, EFieldIds::UDELEGATEPROPERTY_FUNCTION) // 0x0058 (0x08) 1551 | struct FName DelegateName; REGISTER_FIELD(FName, DelegateName, EFieldIds::UDELEGATEPROPERTY_NAME) // 0x0060 (0x08) 1552 | 1553 | public: 1554 | static UClass* StaticClass() 1555 | { 1556 | static UClass* uClassPointer = nullptr; 1557 | 1558 | if (!uClassPointer) 1559 | { 1560 | uClassPointer = UObject::FindClass("Class Core.DelegateProperty"); 1561 | } 1562 | 1563 | return uClassPointer; 1564 | }; 1565 | }; 1566 | 1567 | // Class Core.ByteProperty 1568 | // 0x0008 (0x0058 - 0x0060) 1569 | class UByteProperty : public UProperty 1570 | { 1571 | public: 1572 | class UEnum* Enum; REGISTER_FIELD(class UEnum*, Enum, EFieldIds::UBYTEPROPERTY_ENUM) // 0x0058 (0x08) 1573 | 1574 | public: 1575 | static UClass* StaticClass() 1576 | { 1577 | static UClass* uClassPointer = nullptr; 1578 | 1579 | if (!uClassPointer) 1580 | { 1581 | uClassPointer = UObject::FindClass("Class Core.ByteProperty"); 1582 | } 1583 | 1584 | return uClassPointer; 1585 | }; 1586 | }; 1587 | 1588 | // Class Core.BoolProperty 1589 | // 0x0008 (0x0058 - 0x0060) 1590 | class UBoolProperty : public UProperty 1591 | { 1592 | public: 1593 | uint64_t BitMask; REGISTER_FIELD(uint64_t, BitMask, EFieldIds::UBOOLPROPERTY_BITMASK) // 0x0058 (0x08) 1594 | 1595 | public: 1596 | static UClass* StaticClass() 1597 | { 1598 | static UClass* uClassPointer = nullptr; 1599 | 1600 | if (!uClassPointer) 1601 | { 1602 | uClassPointer = UObject::FindClass("Class Core.BoolProperty"); 1603 | } 1604 | 1605 | return uClassPointer; 1606 | }; 1607 | }; 1608 | 1609 | // Class Core.ArrayProperty 1610 | // 0x0008 (0x0058 - 0x0060) 1611 | class UArrayProperty : public UProperty 1612 | { 1613 | public: 1614 | class UProperty* Inner; REGISTER_FIELD(class UProperty*, Inner, EFieldIds::UARRAYPROPERTY_INNTER) // 0x0058 (0x08) 1615 | 1616 | public: 1617 | static UClass* StaticClass() 1618 | { 1619 | static UClass* uClassPointer = nullptr; 1620 | 1621 | if (!uClassPointer) 1622 | { 1623 | uClassPointer = UObject::FindClass("Class Core.ArrayProperty"); 1624 | } 1625 | 1626 | return uClassPointer; 1627 | }; 1628 | }; 1629 | 1630 | /* 1631 | # ========================================================================================= # 1632 | # 1633 | # ========================================================================================= # 1634 | */ -------------------------------------------------------------------------------- /Engine/Template/PiecesOfCode.cpp: -------------------------------------------------------------------------------- 1 | #include "PiecesOfCode.hpp" 2 | 3 | /* 4 | # ========================================================================================= # 5 | # Pieces Of Code 6 | # ========================================================================================= # 7 | */ 8 | 9 | namespace PiecesOfCode 10 | { 11 | const std::string TArray_Iterator = 12 | "template\n" 13 | "class TIterator\n" 14 | "{\n" 15 | "public:\n" 16 | "\tusing ElementType = typename TArray::ElementType;\n" 17 | "\tusing ElementPointer = ElementType*;\n" 18 | "\tusing ElementReference = ElementType&;\n" 19 | "\tusing ElementConstReference = const ElementType&;\n" 20 | "\n" 21 | "private:\n" 22 | "\tElementPointer IteratorData;\n" 23 | "\n" 24 | "public:\n" 25 | "\tTIterator(ElementPointer inElementPointer)\n" 26 | "\t{\n" 27 | "\t\tIteratorData = inElementPointer;\n" 28 | "\t}\n" 29 | "\n" 30 | "public:\n" 31 | "\tTIterator& operator++()\n" 32 | "\t{\n" 33 | "\t\tIteratorData++;\n" 34 | "\t\treturn *this;\n" 35 | "\t}\n" 36 | "\n" 37 | "\tTIterator operator++(int32_t)\n" 38 | "\t{\n" 39 | "\t\tTIterator iteratorCopy = *this;\n" 40 | "\t\t++(*this);\n" 41 | "\t\treturn iteratorCopy;\n" 42 | "\t}\n" 43 | "\n" 44 | "\tTIterator& operator--()\n" 45 | "\t{\n" 46 | "\t\tIteratorData--;\n" 47 | "\t\treturn *this;\n" 48 | "\t}\n" 49 | "\n" 50 | "\tTIterator operator--(int32_t)\n" 51 | "\t{\n" 52 | "\t\tTIterator iteratorCopy = *this;\n" 53 | "\t\t--(*this);\n" 54 | "\t\treturn iteratorCopy;\n" 55 | "\t}\n" 56 | "\n" 57 | "\tElementReference operator[](int32_t index)\n" 58 | "\t{\n" 59 | "\t\treturn *(IteratorData[index]);\n" 60 | "\t}\n" 61 | "\n" 62 | "\tElementPointer operator->()\n" 63 | "\t{\n" 64 | "\t\treturn IteratorData;\n" 65 | "\t}\n" 66 | "\n" 67 | "\tElementReference operator*()\n" 68 | "\t{\n" 69 | "\t\treturn *IteratorData;\n" 70 | "\t}\n" 71 | "\n" 72 | "public:\n" 73 | "\tbool operator==(const TIterator& other) const\n" 74 | "\t{\n" 75 | "\t\treturn (IteratorData == other.IteratorData);\n" 76 | "\t}\n" 77 | "\n" 78 | "\tbool operator!=(const TIterator& other) const\n" 79 | "\t{\n" 80 | "\t\treturn !(*this == other);\n" 81 | "\t}\n" 82 | "};\n"; 83 | 84 | const std::string TArray_Class = 85 | "template\n" 86 | "class TArray\n" 87 | "{\n" 88 | "public:\n" 89 | "\tusing ElementType = InElementType;\n" 90 | "\tusing ElementPointer = ElementType*;\n" 91 | "\tusing ElementReference = ElementType&;\n" 92 | "\tusing ElementConstReference = const ElementType&;\n" 93 | "\tusing Iterator = TIterator>;\n" 94 | "\n" 95 | "private:\n" 96 | "\tElementPointer ArrayData;\n" 97 | "\tint32_t ArrayCount;\n" 98 | "\tint32_t ArrayMax;\n" 99 | "\n" 100 | "public:\n" 101 | "\tTArray() : ArrayData(nullptr), ArrayCount(0), ArrayMax(0)\n" 102 | "\t{\n" 103 | "\t\t//ReAllocate(sizeof(ElementType));\n" 104 | "\t}\n" 105 | "\n" 106 | "\t~TArray()\n" 107 | "\t{\n" 108 | "\t\t//Clear();\n" 109 | "\t\t//::operator delete(ArrayData, ArrayMax * sizeof(ElementType));\n" 110 | "\t}\n" 111 | "\n" 112 | "public:\n" 113 | "\tElementConstReference operator[](int32_t index) const\n" 114 | "\t{\n" 115 | "\t\treturn ArrayData[index];\n" 116 | "\t}\n" 117 | "\n" 118 | "\tElementReference operator[](int32_t index)\n" 119 | "\t{\n" 120 | "\t\treturn ArrayData[index];\n" 121 | "\t}\n" 122 | "\n" 123 | "\tElementConstReference At(int32_t index) const\n" 124 | "\t{\n" 125 | "\t\treturn ArrayData[index];\n" 126 | "\t}\n" 127 | "\n" 128 | "\tElementReference At(int32_t index)\n" 129 | "\t{\n" 130 | "\t\treturn ArrayData[index];\n" 131 | "\t}\n" 132 | "\n" 133 | "\tvoid Add(ElementConstReference newElement)\n" 134 | "\t{\n" 135 | "\t\tif (ArrayCount >= ArrayMax)\n" 136 | "\t\t{\n" 137 | "\t\t\tReAllocate(sizeof(ElementType) * (ArrayCount + 1));\n" 138 | "\t\t}\n" 139 | "\n" 140 | "\t\tnew(&ArrayData[ArrayCount]) ElementType(newElement);\n" 141 | "\t\tArrayCount++;\n" 142 | "\t}\n" 143 | "\n" 144 | "\tvoid Add(ElementReference& newElement)\n" 145 | "\t{\n" 146 | "\t\tif (ArrayCount >= ArrayMax)\n" 147 | "\t\t{\n" 148 | "\t\t\tReAllocate(sizeof(ElementType) * (ArrayCount + 1));\n" 149 | "\t\t}\n" 150 | "\n" 151 | "\t\tnew(&ArrayData[ArrayCount]) ElementType(newElement);\n" 152 | "\t\tArrayCount++;\n" 153 | "\t}\n" 154 | "\n" 155 | "\tvoid PopBack()\n" 156 | "\t{\n" 157 | "\t\tif (ArrayCount > 0)\n" 158 | "\t\t{\n" 159 | "\t\t\tArrayCount--;\n" 160 | "\t\t\tArrayData[ArrayCount].~ElementType();\n" 161 | "\t\t}\n" 162 | "\t}\n" 163 | "\n" 164 | "\tvoid Clear()\n" 165 | "\t{\n" 166 | "\t\tfor (int32_t i = 0; i < ArrayCount; i++)\n" 167 | "\t\t{\n" 168 | "\t\t\tArrayData[i].~ElementType();\n" 169 | "\t\t}\n" 170 | "\n" 171 | "\t\tArrayCount = 0;\n" 172 | "\t}\n" 173 | "\n" 174 | "\tint32_t Num() const\n" 175 | "\t{\n" 176 | "\t\treturn ArrayCount;\n" 177 | "\t}\n" 178 | "\n" 179 | "\tint32_t Max() const\n" 180 | "\t{\n" 181 | "\t\treturn ArrayMax;\n" 182 | "\t}\n" 183 | "\n" 184 | "\tIterator begin()\n" 185 | "\t{\n" 186 | "\t\treturn Iterator(ArrayData);\n" 187 | "\t}\n" 188 | "\n" 189 | "\tIterator end()\n" 190 | "\t{\n" 191 | "\t\treturn Iterator(ArrayData + ArrayCount);\n" 192 | "\t}\n" 193 | "\n" 194 | "private:\n" 195 | "\tvoid ReAllocate(int32_t newArrayMax)\n" 196 | "\t{\n" 197 | "\t\tElementPointer newArrayData = (ElementPointer)::operator new(newArrayMax * sizeof(ElementType));\n" 198 | "\t\tint32_t newNum = ArrayCount;\n" 199 | "\n" 200 | "\t\tif (newArrayMax < newNum)\n" 201 | "\t\t{\n" 202 | "\t\t\tnewNum = newArrayMax;\n" 203 | "\t\t}\n" 204 | "\n" 205 | "\t\tfor (int32_t i = 0; i < newNum; i++)\n" 206 | "\t\t{\n" 207 | "\t\t\tnew(newArrayData + i) ElementType(std::move(ArrayData[i]));\n" 208 | "\t\t}\n" 209 | "\n" 210 | "\t\tfor (int32_t i = 0; i < ArrayCount; i++)\n" 211 | "\t\t{\n" 212 | "\t\t\tArrayData[i].~ElementType();\n" 213 | "\t\t}\n" 214 | "\n" 215 | "\t\t::operator delete(ArrayData, ArrayMax * sizeof(ElementType));\n" 216 | "\t\tArrayData = newArrayData;\n" 217 | "\t\tArrayMax = newArrayMax;\n" 218 | "\t}\n" 219 | "};\n"; 220 | 221 | const std::string TMap_Class = 222 | "template\n" 223 | "class TMap\n" 224 | "{\n" 225 | "private:\n" 226 | "\tstruct TPair\n" 227 | "\t{\n" 228 | "\t\tTKey Key;\n" 229 | "\t\tTValue Value;\n" 230 | "\t};\n" 231 | "\n" 232 | "public:\n" 233 | "\tusing ElementType = TPair;\n" 234 | "\tusing ElementPointer = ElementType*;\n" 235 | "\tusing ElementReference = ElementType&;\n" 236 | "\tusing ElementConstReference = const ElementType&;\n" 237 | "\tusing Iterator = TIterator>;\n" 238 | "\n" 239 | "public:\n" 240 | "\tTArray Elements;\t\t\t\t\t\t\t\t\t// 0x0000 (0x0010)\n" 241 | "\tuintptr_t IndirectData;\t\t\t\t\t\t\t\t\t\t\t// 0x0010 (0x0008)\n" 242 | "\tint32_t InlineData[0x4];\t\t\t\t\t\t\t\t\t\t// 0x0018 (0x0010)\n" 243 | "\tint32_t NumBits;\t\t\t\t\t\t\t\t\t\t\t\t// 0x0028 (0x0004)\n" 244 | "\tint32_t MaxBits;\t\t\t\t\t\t\t\t\t\t\t\t// 0x002C (0x0004)\n" 245 | "\tint32_t FirstFreeIndex;\t\t\t\t\t\t\t\t\t\t\t// 0x0030 (0x0004)\n" 246 | "\tint32_t NumFreeIndices;\t\t\t\t\t\t\t\t\t\t\t// 0x0034 (0x0004)\n" 247 | "\tint64_t InlineHash;\t\t\t\t\t\t\t\t\t\t\t\t// 0x0038 (0x0008)\n" 248 | "\tint32_t* Hash;\t\t\t\t\t\t\t\t\t\t\t\t\t// 0x0040 (0x0008)\n" 249 | "\tint32_t HashCount;\t\t\t\t\t\t\t\t\t\t\t\t// 0x0048 (0x0004)\n" 250 | "\n" 251 | "public:\n" 252 | "\tTMap() :\n" 253 | "\t\tIndirectData(NULL),\n" 254 | "\t\tNumBits(0),\n" 255 | "\t\tMaxBits(0),\n" 256 | "\t\tFirstFreeIndex(0),\n" 257 | "\t\tNumFreeIndices(0),\n" 258 | "\t\tInlineHash(0),\n" 259 | "\t\tHash(nullptr),\n" 260 | "\t\tHashCount(0)\n" 261 | "\t{\n" 262 | "\n" 263 | "\t}\n" 264 | "\n" 265 | "\tTMap(struct FMap_Mirror& unrealMap) :\n" 266 | "\t\tIndirectData(NULL),\n" 267 | "\t\tNumBits(0),\n" 268 | "\t\tMaxBits(0),\n" 269 | "\t\tFirstFreeIndex(0),\n" 270 | "\t\tNumFreeIndices(0),\n" 271 | "\t\tInlineHash(0),\n" 272 | "\t\tHash(nullptr),\n" 273 | "\t\tHashCount(0)\n" 274 | "\t{\n" 275 | "\t\t*this = *reinterpret_cast*>(&unrealMap);\n" 276 | "\t}\n" 277 | "\n" 278 | "\t~TMap() {}\n" 279 | "\n" 280 | "public:\n" 281 | "\tint32_t Num() const\n" 282 | "\t{\n" 283 | "\t\treturn Elements.Num();\n" 284 | "\t}\n" 285 | "\n" 286 | "\tint32_t Max() const\n" 287 | "\t{\n" 288 | "\t\treturn Elements.Max();\n" 289 | "\t}\n" 290 | "\n" 291 | "\tElementConstReference At(int32_t index) const\n" 292 | "\t{\n" 293 | "\t\treturn Elements[index];\n" 294 | "\t}\n" 295 | "\n" 296 | "\tElementReference At(int32_t index)\n" 297 | "\t{\n" 298 | "\t\treturn Elements[index];\n" 299 | "\t}\n" 300 | "\n" 301 | "\tIterator begin()\n" 302 | "\t{\n" 303 | "\t\treturn Elements.begin();\n" 304 | "\t}\n" 305 | "\n" 306 | "\tIterator end()\n" 307 | "\t{\n" 308 | "\t\treturn Elements.end();\n" 309 | "\t}\n" 310 | "\n" 311 | "public:\n" 312 | "\tElementConstReference operator[](int32_t index) const\n" 313 | "\t{\n" 314 | "\t\treturn Elements[index];\n" 315 | "\t}\n" 316 | "\n" 317 | "\tElementReference operator[](int32_t index)\n" 318 | "\t{\n" 319 | "\t\treturn Elements[index];\n" 320 | "\t}\n" 321 | "\n" 322 | "\tconst TValue& operator[](const TKey& key) const\n" 323 | "\t{\n" 324 | "\t\tfor (const TPair& pair : Elements)\n" 325 | "\t\t{\n" 326 | "\t\t\tif (pair.Key == key)\n" 327 | "\t\t\t{\n" 328 | "\t\t\t\treturn pair.Value;\n" 329 | "\t\t\t}\n" 330 | "\t\t}\n" 331 | "\t}\n" 332 | "\n" 333 | "\tTValue& operator[](const TKey& key)\n" 334 | "\t{\n" 335 | "\t\tfor (TPair& pair : Elements)\n" 336 | "\t\t{\n" 337 | "\t\t\tif (pair.Key == key)\n" 338 | "\t\t\t{\n" 339 | "\t\t\t\treturn pair.Value;\n" 340 | "\t\t\t}\n" 341 | "\t\t}\n" 342 | "\t}\n" 343 | "\n" 344 | "\tTMap& operator=(const struct FMap_Mirror& fMap)\n" 345 | "\t{\n" 346 | "\t\t*this = *reinterpret_cast*>(&fMap);\n" 347 | "\t\treturn *this;\n" 348 | "\t}\n" 349 | "};\n"; 350 | 351 | const std::string FNameEntry_UPPER = 352 | "struct FNameEntry\n" 353 | "{\n" 354 | "public:\n"; 355 | 356 | const std::string FNameEntry_UTF16 = 357 | "\n" 358 | "public:\n" 359 | "\tFNameEntry() : Index(-1) {}\n" 360 | "\t~FNameEntry() {}\n\n" 361 | "public:\n" 362 | "\tint32_t GetIndex() const\n" 363 | "\t{\n" 364 | "\t\treturn Index;\n" 365 | "\t}\n" 366 | "\n" 367 | "\tstd::string ToString() const\n" 368 | "\t{\n" 369 | "\t\tstd::wstring ws(Name);\n" 370 | "\t\tstd::string str(ws.begin(), ws.end());\n" 371 | "\t\treturn str;\n" 372 | "\t}\n" 373 | "\n" 374 | "\tconst wchar_t* GetWideName() const\n" 375 | "\t{\n" 376 | "\t\treturn Name;\n" 377 | "\t}\n" 378 | "};\n"; 379 | 380 | const std::string FNameEntry_UTF8 = 381 | "\n" 382 | "public:\n" 383 | "\tFNameEntry() : Index(-1) {}\n" 384 | "\t~FNameEntry() {}\n\n" 385 | "public:\n" 386 | "\tint32_t GetIndex() const\n" 387 | "\t{\n" 388 | "\t\treturn Index;\n" 389 | "\t}\n" 390 | "\n" 391 | "\tstd::string ToString() const\n" 392 | "\t{\n" 393 | "\t\treturn std::string(Name);\n" 394 | "\t}\n" 395 | "\n" 396 | "\tconst char* GetAnsiName() const\n" 397 | "\t{\n" 398 | "\t\treturn Name;\n" 399 | "\t}\n"; 400 | 401 | const std::string FName_UTF16 = 402 | "struct FName\n" 403 | "{\n" 404 | "public:\n" 405 | "\tusing ElementType = const wchar_t;\n" 406 | "\tusing ElementPointer = ElementType*;\n" 407 | "\n" 408 | "private:\n" 409 | "\tint32_t\t\t\tFNameEntryId;\t\t\t\t\t\t\t\t\t// 0x0000 (0x04)\n" 410 | "\tint32_t\t\t\tInstanceNumber;\t\t\t\t\t\t\t\t\t// 0x0004 (0x04)\n" 411 | "\n" 412 | "public:\n" 413 | "\tFName() : FNameEntryId(0), InstanceNumber(0) {}\n" 414 | "\n" 415 | "\tFName(int32_t id) : FNameEntryId(id), InstanceNumber(0) {}\n" 416 | "\n" 417 | "\tFName(const ElementPointer nameToFind) : FNameEntryId(0), InstanceNumber(0)\n" 418 | "\t{\n" 419 | "\t\tstatic std::vector nameCache{};\n" 420 | "\n" 421 | "\t\tfor (int32_t entryId : nameCache)\n" 422 | "\t\t{\n" 423 | "\t\t\tif (Names()->At(entryId))\n" 424 | "\t\t\t{\n" 425 | "\t\t\t\tif (!wcscmp(Names()->At(entryId)->Name, nameToFind))\n" 426 | "\t\t\t\t{\n" 427 | "\t\t\t\t\tFNameEntryId = entryId;\n" 428 | "\t\t\t\t\treturn;\n" 429 | "\t\t\t\t}\n" 430 | "\t\t\t}\n" 431 | "\t\t}\n" 432 | "\n" 433 | "\t\tfor (int32_t i = 0; i < Names()->Num(); i++)\n" 434 | "\t\t{\n" 435 | "\t\t\tif (Names()->At(i))\n" 436 | "\t\t\t{\n" 437 | "\t\t\t\tif (!wcscmp(Names()->At(i)->Name, nameToFind))\n" 438 | "\t\t\t\t{\n" 439 | "\t\t\t\t\tnameCache.push_back(i);\n" 440 | "\t\t\t\t\tFNameEntryId = i;\n" 441 | "\t\t\t\t}\n" 442 | "\t\t\t}\n" 443 | "\t\t}\n" 444 | "\t}\n" 445 | "\n" 446 | "\t~FName() {}\n" 447 | "\n" 448 | "public:\n" 449 | "\tstatic class TArray* Names()\n" 450 | "\t{\n" 451 | "\t\tTArray* GNamesArray = reinterpret_cast*>(GNames);\n" 452 | "\t\treturn GNamesArray;\n" 453 | "\t}\n" 454 | "\n" 455 | "\tint32_t GetDisplayIndex() const\n" 456 | "\t{\n" 457 | "\t\treturn FNameEntryId;\n" 458 | "\t}\n" 459 | "\n" 460 | "\tconst struct FNameEntry GetDisplayNameEntry() const\n" 461 | "\t{\n" 462 | "\t\tif (IsValid())\n" 463 | "\t\t{\n" 464 | "\t\t\treturn *Names()->At(FNameEntryId);\n" 465 | "\t\t}\n" 466 | "\n" 467 | "\t\treturn FNameEntry();\n" 468 | "\t}\n" 469 | "\n" 470 | "\tstruct FNameEntry* GetEntry()\n" 471 | "\t{\n" 472 | "\t\tif (IsValid())\n" 473 | "\t\t{\n" 474 | "\t\t\treturn Names()->At(FNameEntryId);\n" 475 | "\t\t}\n" 476 | "\n" 477 | "\t\treturn nullptr;\n" 478 | "\t}\n" 479 | "\n" 480 | "\tint32_t GetNumber() const\n" 481 | "\t{\n" 482 | "\t\treturn InstanceNumber;\n" 483 | "\t}\n" 484 | "\n" 485 | "\tvoid SetNumber(int32_t newNumber)\n" 486 | "\t{\n" 487 | "\t\tInstanceNumber = newNumber;\n" 488 | "\t}\n" 489 | "\n" 490 | "\tstd::string ToString() const\n" 491 | "\t{\n" 492 | "\t\tif (IsValid())\n" 493 | "\t\t{\n" 494 | "\t\t\treturn GetDisplayNameEntry().ToString();\n" 495 | "\t\t}\n" 496 | "\n" 497 | "\t\treturn std::string(\"UnknownName\");\n" 498 | "\t}\n" 499 | "\n" 500 | "\tbool IsValid() const\n" 501 | "\t{\n" 502 | "\t\tif (FNameEntryId < 0 || FNameEntryId > Names()->Num())\n" 503 | "\t\t{\n" 504 | "\t\t\treturn false;\n" 505 | "\t\t}\n" 506 | "\n" 507 | "\t\treturn true;\n" 508 | "\t}\n" 509 | "\n" 510 | "public:\n" 511 | "\tstruct FName& operator=(const struct FName& other)\n" 512 | "\t{\n" 513 | "\t\tFNameEntryId = other.FNameEntryId;\n" 514 | "\t\tInstanceNumber = other.InstanceNumber;\n" 515 | "\t\treturn *this;\n" 516 | "\t}\n" 517 | "\n" 518 | "\tbool operator==(const struct FName& other) const\n" 519 | "\t{\n" 520 | "\t\treturn (FNameEntryId == other.FNameEntryId);\n" 521 | "\t}\n" 522 | "\n" 523 | "\tbool operator!=(const struct FName& other) const\n" 524 | "\t{\n" 525 | "\t\treturn (FNameEntryId != other.FNameEntryId);\n" 526 | "\t}\n" 527 | "};\n"; 528 | 529 | const std::string FName_UTF8 = 530 | "struct FName\n" 531 | "{\n" 532 | "public:\n" 533 | "\tusing ElementType = const char;\n" 534 | "\tusing ElementPointer = ElementType*;\n" 535 | "\n" 536 | "private:\n" 537 | "\tint32_t\t\t\tFNameEntryId;\t\t\t\t\t\t\t\t\t// 0x0000 (0x04)\n" 538 | "\tint32_t\t\t\tInstanceNumber;\t\t\t\t\t\t\t\t\t// 0x0004 (0x04)\n" 539 | "\n" 540 | "public:\n" 541 | "\tFName() : FNameEntryId(-1), InstanceNumber(0) {}\n" 542 | "\n" 543 | "\tFName(int32_t id) : FNameEntryId(id), InstanceNumber(0) {}\n" 544 | "\n" 545 | "\tFName(ElementPointer nameToFind) : FNameEntryId(0), InstanceNumber(0)\n" 546 | "\t{\n" 547 | "\t\tstatic std::vector nameCache{};\n" 548 | "\n" 549 | "\t\tfor (int32_t entryId : nameCache)\n" 550 | "\t\t{\n" 551 | "\t\t\tif (Names()->At(entryId))\n" 552 | "\t\t\t{\n" 553 | "\t\t\t\tif (!strcmp(Names()->At(entryId)->Name, nameToFind))\n" 554 | "\t\t\t\t{\n" 555 | "\t\t\t\t\tFNameEntryId = entryId;\n" 556 | "\t\t\t\t\treturn;\n" 557 | "\t\t\t\t}\n" 558 | "\t\t\t}\n" 559 | "\t\t}\n" 560 | "\n" 561 | "\t\tfor (int32_t i = 0; i < Names()->Num(); i++)\n" 562 | "\t\t{\n" 563 | "\t\t\tif (Names()->At(i))\n" 564 | "\t\t\t{\n" 565 | "\t\t\t\tif (!strcmp(Names()->At(i)->Name, nameToFind))\n" 566 | "\t\t\t\t{\n" 567 | "\t\t\t\t\tnameCache.push_back(i);\n" 568 | "\t\t\t\t\tFNameEntryId = i;\n" 569 | "\t\t\t\t}\n" 570 | "\t\t\t}\n" 571 | "\t\t}\n" 572 | "\t}\n" 573 | "\n" 574 | "\t~FName() {}\n" 575 | "\n" 576 | "public:\n" 577 | "\tstatic class TArray* Names()\n" 578 | "\t{\n" 579 | "\t\tTArray* GNamesArray = reinterpret_cast*>(GNames);\n" 580 | "\t\treturn GNamesArray;\n" 581 | "\t}\n" 582 | "\n" 583 | "\tint32_t GetDisplayIndex() const\n" 584 | "\t{\n" 585 | "\t\treturn FNameEntryId;\n" 586 | "\t}\n" 587 | "\n" 588 | "\tconst struct FNameEntry GetDisplayNameEntry() const\n" 589 | "\t{\n" 590 | "\t\tif (IsValid())\n" 591 | "\t\t{\n" 592 | "\t\t\treturn *Names()->At(FNameEntryId);\n" 593 | "\t\t}\n" 594 | "\n" 595 | "\t\treturn FNameEntry();\n" 596 | "\t}\n" 597 | "\n" 598 | "\tstruct FNameEntry* GetEntry()\n" 599 | "\t{\n" 600 | "\t\tif (IsValid())\n" 601 | "\t\t{\n" 602 | "\t\t\treturn Names()->At(FNameEntryId);\n" 603 | "\t\t}\n" 604 | "\n" 605 | "\t\treturn nullptr;\n" 606 | "\t}\n" 607 | "\n" 608 | "\tint32_t GetNumber() const\n" 609 | "\t{\n" 610 | "\t\treturn InstanceNumber;\n" 611 | "\t}\n" 612 | "\n" 613 | "\tvoid SetNumber(int32_t newNumber)\n" 614 | "\t{\n" 615 | "\t\tInstanceNumber = newNumber;\n" 616 | "\t}\n" 617 | "\n" 618 | "\tstd::string ToString() const\n" 619 | "\t{\n" 620 | "\t\tif (IsValid())\n" 621 | "\t\t{\n" 622 | "\t\t\treturn GetDisplayNameEntry().ToString();\n" 623 | "\t\t}\n" 624 | "\n" 625 | "\t\treturn std::string(\"UnknownName\");\n" 626 | "\t}\n" 627 | "\n" 628 | "\tbool IsValid() const\n" 629 | "\t{\n" 630 | "\t\tif (FNameEntryId < 0 || FNameEntryId > Names()->Num())\n" 631 | "\t\t{\n" 632 | "\t\t\treturn false;\n" 633 | "\t\t}\n" 634 | "\n" 635 | "\t\treturn true;\n" 636 | "\t}\n" 637 | "\n" 638 | "public:\n" 639 | "\tstruct FName& operator=(const struct FName& other)\n" 640 | "\t{\n" 641 | "\t\tFNameEntryId = other.FNameEntryId;\n" 642 | "\t\tInstanceNumber = other.InstanceNumber;\n" 643 | "\t\treturn *this;\n" 644 | "\t}\n" 645 | "\n" 646 | "\tbool operator==(const struct FName& other) const\n" 647 | "\t{\n" 648 | "\t\treturn (FNameEntryId == other.FNameEntryId);\n" 649 | "\t}\n" 650 | "\n" 651 | "\tbool operator!=(const struct FName& other) const\n" 652 | "\t{\n" 653 | "\t\treturn (FNameEntryId != other.FNameEntryId);\n" 654 | "\t}\n" 655 | "};\n"; 656 | 657 | const std::string FString_UTF16 = 658 | "class FString\n" 659 | "{\n" 660 | "public:\n" 661 | "\tusing ElementType = const wchar_t;\n" 662 | "\tusing ElementPointer = ElementType*;\n" 663 | "\n" 664 | "private:\n" 665 | "\tElementPointer\tArrayData;\t\t\t\t\t\t\t\t\t\t// 0x0000 (0x08)\n" 666 | "\tint32_t\t\t\tArrayCount;\t\t\t\t\t\t\t\t\t\t// 0x0008 (0x04)\n" 667 | "\tint32_t\t\t\tArrayMax;\t\t\t\t\t\t\t\t\t\t// 0x000C (0x04)\n" 668 | "\n" 669 | "public:\n" 670 | "\tFString() : ArrayData(nullptr), ArrayCount(0), ArrayMax(0) {}\n" 671 | "\n" 672 | "\tFString(ElementPointer other) : ArrayData(nullptr), ArrayCount(0), ArrayMax(0)\n" 673 | "\t{\n" 674 | "\t\tArrayMax = ArrayCount = *other ? (wcslen(other) + 1) : 0;\n" 675 | "\n" 676 | "\t\tif (ArrayCount > 0)\n" 677 | "\t\t{\n" 678 | "\t\t\tArrayData = other;\n" 679 | "\t\t}\n" 680 | "\t}\n" 681 | "\n" 682 | "\t~FString() {}\n" 683 | "\n" 684 | "public:\n" 685 | "\tstd::string ToString() const\n" 686 | "\t{\n" 687 | "\t\tif (IsValid())\n" 688 | "\t\t{\n" 689 | "\t\t\tstd::wstring wideStr(ArrayData);\n" 690 | "\t\t\tstd::string str(wideStr.begin(), wideStr.end());\n" 691 | "\t\t\treturn str;\n" 692 | "\t\t}\n" 693 | "\n" 694 | "\t\treturn std::string(\"null\");\n" 695 | "\t}\n" 696 | "\n" 697 | "\tbool IsValid() const\n" 698 | "\t{\n" 699 | "\t\treturn (!!ArrayData);\n" 700 | "\t}\n" 701 | "\n" 702 | "\tclass FString& operator=(ElementPointer other)\n" 703 | "\t{\n" 704 | "\t\tif (ArrayData != other)\n" 705 | "\t\t{\n" 706 | "\t\t\tArrayMax = ArrayCount = *other ? (wcslen(other) + 1) : 0;\n" 707 | "\n" 708 | "\t\t\tif (ArrayCount > 0)\n" 709 | "\t\t\t{\n" 710 | "\t\t\t\tArrayData = other;\n" 711 | "\t\t\t}\n" 712 | "\t\t}\n" 713 | "\n" 714 | "\t\treturn *this;\n" 715 | "\t}\n" 716 | "\n" 717 | "public:\n" 718 | "\tbool operator==(const class FString& other)\n" 719 | "\t{\n" 720 | "\t\treturn (!wcscmp(ArrayData, other.ArrayData));\n" 721 | "\t}\n" 722 | "\n" 723 | "\tbool operator!=(const class FString& other)\n" 724 | "\t{\n" 725 | "\t\treturn (wcscmp(ArrayData, other.ArrayData));\n" 726 | "\t}\n" 727 | "};\n"; 728 | 729 | const std::string FString_UTF8 = 730 | "class FString\n" 731 | "{\n" 732 | "public:\n" 733 | "\tusing ElementType = const char;\n" 734 | "\tusing ElementPointer = ElementType*;\n" 735 | "\n" 736 | "private:\n" 737 | "\tElementPointer\tArrayData;\t\t\t\t\t\t\t\t\t\t// 0x0000 (0x08)\n" 738 | "\tint32_t\t\t\tArrayCount;\t\t\t\t\t\t\t\t\t\t// 0x0008 (0x04)\n" 739 | "\tint32_t\t\t\tArrayMax;\t\t\t\t\t\t\t\t\t\t// 0x000C (0x04)\n" 740 | "\n" 741 | "public:\n" 742 | "\tFString() : ArrayData(nullptr), ArrayCount(0), ArrayMax(0) {}\n" 743 | "\n" 744 | "\tFString(ElementPointer other) : ArrayData(nullptr), ArrayCount(0), ArrayMax(0)\n" 745 | "\t{\n" 746 | "\t\tArrayMax = ArrayCount = *other ? (strlen(other) + 1) : 0;\n" 747 | "\n" 748 | "\t\tif (ArrayCount > 0)\n" 749 | "\t\t{\n" 750 | "\t\t\tArrayData = other;\n" 751 | "\t\t}\n" 752 | "\t}\n" 753 | "\n" 754 | "\t~FString() {}\n" 755 | "\n" 756 | "public:\n" 757 | "\tstd::string ToString() const\n" 758 | "\t{\n" 759 | "\t\tif (IsValid())\n" 760 | "\t\t{\n" 761 | "\t\t\treturn std::string(ArrayData);\n" 762 | "\t\t}\n" 763 | "\n" 764 | "\t\treturn std::string(\"null\");\n" 765 | "\t}\n" 766 | "\n" 767 | "\tbool IsValid() const\n" 768 | "\t{\n" 769 | "\t\treturn (!!ArrayData);\n" 770 | "\t}\n" 771 | "\n" 772 | "\tclass FString& operator=(ElementPointer other)\n" 773 | "\t{\n" 774 | "\t\tif (ArrayData != other)\n" 775 | "\t\t{\n" 776 | "\t\t\tArrayMax = ArrayCount = *other ? (strlen(other) + 1) : 0;\n" 777 | "\n" 778 | "\t\t\tif (ArrayCount > 0)\n" 779 | "\t\t\t{\n" 780 | "\t\t\t\tArrayData = other;\n" 781 | "\t\t\t}\n" 782 | "\t\t}\n" 783 | "\n" 784 | "\t\treturn *this;\n" 785 | "\t}\n" 786 | "\n" 787 | "public:\n" 788 | "\tbool operator==(const class FString& other)\n" 789 | "\t{\n" 790 | "\t\treturn (!strcmp(ArrayData, other.ArrayData));\n" 791 | "\t}\n" 792 | "\n" 793 | "\tbool operator!=(const class FString& other)\n" 794 | "\t{\n" 795 | "\t\treturn (strcmp(ArrayData, other.ArrayData));\n" 796 | "\t}\n" 797 | "};\n"; 798 | 799 | const std::string FPointer_Struct = 800 | "struct FPointer\n" 801 | "{\n" 802 | "\tuintptr_t Dummy;\n" 803 | "};\n"; 804 | 805 | const std::string FQWord_Struct = 806 | "struct FQWord\n" 807 | "{\n" 808 | "\tint32_t A;\n" 809 | "\tint32_t B;\n" 810 | "};\n"; 811 | 812 | const std::string UObject_FunctionDescriptions = 813 | "\tstatic TArray* GObjObjects();\n" 814 | "\n" 815 | "\tstd::string GetName();\n" 816 | "\tstd::string GetNameCPP();\n" 817 | "\tstd::string GetFullName();\n" 818 | "\tclass UObject* GetPackageObj();\n" 819 | "\ttemplate static T* FindObject(const std::string& objectFullName)\n" 820 | "\t{\n" 821 | "\t\tfor (UObject* uObject : *UObject::GObjObjects())\n" 822 | "\t\t{\n" 823 | "\t\t\tif (uObject && uObject->IsA(T::StaticClass()))\n" 824 | "\t\t\t{\n" 825 | "\t\t\t\tif (uObject->GetFullName() == objectFullName)\n" 826 | "\t\t\t\t{\n" 827 | "\t\t\t\t\treturn static_cast(uObject);\n" 828 | "\t\t\t\t}\n" 829 | "\t\t\t}\n" 830 | "\t\t}\n" 831 | "\n" 832 | "\t\treturn nullptr;\n" 833 | "\t}\n" 834 | "\ttemplate static uint32_t CountObject(const std::string& objectName)\n" 835 | "\t{\n" 836 | "\t\tstatic std::map countCache;\n" 837 | "\n" 838 | "\t\tif (countCache.find(objectName) == countCache.end())\n" 839 | "\t\t{\n" 840 | "\t\t\tcountCache[objectName] = 0;\n" 841 | "\n" 842 | "\t\t\tfor (UObject* uObject : *UObject::GObjObjects())\n" 843 | "\t\t\t{\n" 844 | "\t\t\t\tif (uObject && uObject->IsA(T::StaticClass()))\n" 845 | "\t\t\t\t{\n" 846 | "\t\t\t\t\tif (uObject->GetName() == objectName)\n" 847 | "\t\t\t\t\t{\n" 848 | "\t\t\t\t\t\tcountCache[uObject->GetName()]++;\n" 849 | "\t\t\t\t\t}\n" 850 | "\t\t\t\t}\n" 851 | "\t\t\t}\n" 852 | "\t\t}\n" 853 | "\n" 854 | "\t\treturn countCache[objectName];\n" 855 | "\t}\n" 856 | "\tstatic class UClass* FindClass(const std::string& classFullName);\n" 857 | "\ttemplate bool IsA()\n" 858 | "\t{\n" 859 | "\t\tif (std::is_base_of::value)\n" 860 | "\t\t{\n" 861 | "\t\t\treturn IsA(T::StaticClass());\n" 862 | "\t\t}\n" 863 | "\t}\n" 864 | "\tbool IsA(class UClass* uClass);\n" 865 | "\tbool IsA(int32_t objInternalInteger);\n\n"; 866 | 867 | const std::string UObject_Functions = 868 | "TArray* UObject::GObjObjects()\n" 869 | "{\n" 870 | "\tTArray* objectArray = reinterpret_cast*>(GObjects);\n" 871 | "\treturn objectArray;\n" 872 | "}\n" 873 | "\n" 874 | "std::string UObject::GetName()\n" 875 | "{\n" 876 | "\treturn this->Name.ToString();\n" 877 | "}\n" 878 | "\n" 879 | "std::string UObject::GetNameCPP()\n" 880 | "{\n" 881 | "\tstd::string nameCPP;\n" 882 | "\n" 883 | "\tif (this->IsA(UClass::StaticClass()))\n" 884 | "\t{\n" 885 | "\t\tUClass* uClass = static_cast(this);\n" 886 | "\n" 887 | "\t\twhile (uClass)\n" 888 | "\t\t{\n" 889 | "\t\t\tstd::string className = uClass->GetName();\n" 890 | "\n" 891 | "\t\t\tif (className == \"Actor\")\n" 892 | "\t\t\t{\n" 893 | "\t\t\t\tnameCPP += \"A\";\n" 894 | "\t\t\t\tbreak;\n" 895 | "\t\t\t}\n" 896 | "\t\t\telse if (className == \"Object\")\n" 897 | "\t\t\t{\n" 898 | "\t\t\t\tnameCPP += \"U\";\n" 899 | "\t\t\t\tbreak;\n" 900 | "\t\t\t}\n" 901 | "\n" 902 | "\t\t\tuClass = static_cast(uClass->SuperField);\n" 903 | "\t\t}\n" 904 | "\t}\n" 905 | "\telse\n" 906 | "\t{\n" 907 | "\t\tnameCPP += \"F\";\n" 908 | "\t}\n" 909 | "\n" 910 | "\tnameCPP += this->GetName();\n" 911 | "\n" 912 | "\treturn nameCPP;\n" 913 | "}\n" 914 | "\n" 915 | "std::string UObject::GetFullName()\n" 916 | "{\n" 917 | "\tstd::string fullName = this->GetName();\n" 918 | "\n" 919 | "\tfor (UObject* uOuter = this->Outer; uOuter; uOuter = uOuter->Outer)\n" 920 | "\t{\n" 921 | "\t\tfullName = uOuter->GetName() + \".\" + fullName;\n" 922 | "\t}\n" 923 | "\n" 924 | "\tfullName = this->Class->GetName() + \" \" + fullName;\n" 925 | "\n" 926 | "\treturn fullName;\n" 927 | "}\n" 928 | "\n" 929 | "UObject* UObject::GetPackageObj()\n" 930 | "{\n" 931 | "\tUObject* uPackage = nullptr;\n" 932 | "\n" 933 | "\tfor (UObject* uOuter = this->Outer; uOuter; uOuter = uOuter->Outer)\n" 934 | "\t{\n" 935 | "\t\tuPackage = uOuter;\n" 936 | "\t}\n" 937 | "\n" 938 | "\treturn uPackage;\n" 939 | "}\n" 940 | "\n" 941 | "UClass* UObject::FindClass(const const std::string& classFullName)\n" 942 | "{\n" 943 | "\tstatic bool initialized = false;\n" 944 | "\tstatic std::map foundClasses{};\n" 945 | "\n" 946 | "\tif (!initialized)\n" 947 | "\t{\n" 948 | "\t\tfor (UObject* uObject : *UObject::GObjObjects())\n" 949 | "\t\t{\n" 950 | "\t\t\tif (uObject)\n" 951 | "\t\t\t{\n" 952 | "\t\t\t\tconst std::string objectFullName = uObject->GetFullName();\n" 953 | "\n" 954 | "\t\t\t\tif (objectFullName.find(\"Class\") == 0)\n" 955 | "\t\t\t\t{\n" 956 | "\t\t\t\t\tfoundClasses[objectFullName] = static_cast(uObject);\n" 957 | "\t\t\t\t}\n" 958 | "\t\t\t}\n" 959 | "\t\t}\n" 960 | "\n" 961 | "\t\tinitialized = true;\n" 962 | "\t}\n" 963 | "\n" 964 | "\tif (foundClasses.find(classFullName) != foundClasses.end())\n" 965 | "\t{\n" 966 | "\t\treturn foundClasses[classFullName];\n" 967 | "\t}\n" 968 | "\n" 969 | "\treturn nullptr;\n" 970 | "}\n" 971 | "\n" 972 | "bool UObject::IsA(class UClass* uClass)\n" 973 | "{\n" 974 | "\tfor (UClass* uSuperClass = this->Class; uSuperClass; uSuperClass = static_cast(uSuperClass->SuperField))\n" 975 | "\t{\n" 976 | "\t\tif (uSuperClass == uClass)\n" 977 | "\t\t{\n" 978 | "\t\t\treturn true;\n" 979 | "\t\t}\n" 980 | "\t}\n" 981 | "\n" 982 | "\treturn false;\n" 983 | "}\n" 984 | "\n" 985 | "bool UObject::IsA(int32_t objInternalInteger)\n" 986 | "{\n" 987 | "\tUClass* uClass = UObject::GObjObjects()->At(objInternalInteger)->Class;\n" 988 | "\n" 989 | "\tif (uClass)\n" 990 | "\t{\n" 991 | "\t\treturn this->IsA(uClass);\n" 992 | "\t}\n" 993 | "\n" 994 | "\treturn false;\n" 995 | "}\n\n"; 996 | 997 | const std::string UFunction_Functions = 998 | "UFunction* UFunction::FindFunction(const const std::string& functionFullName)\n" 999 | "{\n" 1000 | "\tstatic bool initialized = false;\n" 1001 | "\tstatic std::map foundFunctions{};\n" 1002 | "\n" 1003 | "\tif (!initialized)\n" 1004 | "\t{\n" 1005 | "\t\tfor (UObject* uObject : *UObject::GObjObjects())\n" 1006 | "\t\t{\n" 1007 | "\t\t\tif (uObject)\n" 1008 | "\t\t\t{\n" 1009 | "\t\t\t\tconst std::string objectFullName = uObject->GetFullName();\n" 1010 | "\n" 1011 | "\t\t\t\tif (objectFullName.find(\"Function\") == 0)\n" 1012 | "\t\t\t\t{\n" 1013 | "\t\t\t\t\tfoundFunctions[objectFullName] = static_cast(uObject);\n" 1014 | "\t\t\t\t}\n" 1015 | "\t\t\t}\n" 1016 | "\t\t}\n" 1017 | "\n" 1018 | "\t\tinitialized = true;\n" 1019 | "\t}\n" 1020 | "\n" 1021 | "\tif (foundFunctions.find(functionFullName) != foundFunctions.end())\n" 1022 | "\t{\n" 1023 | "\t\treturn foundFunctions[functionFullName];\n" 1024 | "\t}\n" 1025 | "\n" 1026 | "\treturn nullptr;\n" 1027 | "}\n\n"; 1028 | 1029 | const std::string EEnumFlags = 1030 | "// Function Flags\n" 1031 | "// https://docs.unrealengine.com/en-US/API/Runtime/CoreUObject/UObject/EFunctionFlags/index.html\n" 1032 | "enum EFunctionFlags\n" 1033 | "{\n" 1034 | "\tFUNC_None = 0x00000000,\n" 1035 | "\tFUNC_Final = 0x00000001,\n" 1036 | "\tFUNC_RequiredAPI = 0x00000002,\n" 1037 | "\tFUNC_BlueprintAuthorityOnly = 0x00000004,\n" 1038 | "\tFUNC_BlueprintCosmetic = 0x00000008,\n" 1039 | "\tFUNC_Net = 0x00000040,\n" 1040 | "\tFUNC_NetReliable = 0x00000080,\n" 1041 | "\tFUNC_NetRequest = 0x00000100,\n" 1042 | "\tFUNC_Exec = 0x00000200,\n" 1043 | "\tFUNC_Native = 0x00000400,\n" 1044 | "\tFUNC_Event = 0x00000800,\n" 1045 | "\tFUNC_NetResponse = 0x00001000,\n" 1046 | "\tFUNC_Static = 0x00002000,\n" 1047 | "\tFUNC_NetMulticast = 0x00004000,\n" 1048 | "\tFUNC_UbergraphFunction = 0x00008000,\n" 1049 | "\tFUNC_MulticastDelegate = 0x00010000,\n" 1050 | "\tFUNC_Public = 0x00020000,\n" 1051 | "\tFUNC_Private = 0x00040000,\n" 1052 | "\tFUNC_Protected = 0x00080000,\n" 1053 | "\tFUNC_Delegate = 0x00100000,\n" 1054 | "\tFUNC_NetServer = 0x00200000,\n" 1055 | "\tFUNC_HasOutParms = 0x00400000,\n" 1056 | "\tFUNC_HasDefaults = 0x00800000,\n" 1057 | "\tFUNC_NetClient = 0x01000000,\n" 1058 | "\tFUNC_DLLImport = 0x02000000,\n" 1059 | "\tFUNC_BlueprintCallable = 0x04000000,\n" 1060 | "\tFUNC_BlueprintEvent = 0x08000000,\n" 1061 | "\tFUNC_BlueprintPure = 0x10000000,\n" 1062 | "\tFUNC_EditorOnly = 0x20000000,\n" 1063 | "\tFUNC_Const = 0x40000000,\n" 1064 | "\tFUNC_NetValidate = 0x80000000,\n" 1065 | "\tFUNC_AllFlags = 0xFFFFFFFF\n" 1066 | "};\n" 1067 | "\n" 1068 | "// Proprerty Flags\n" 1069 | "// https://docs.unrealengine.com/en-US/API/Runtime/CoreUObject/UObject/EPropertyFlags/index.html (The ones in this link are UE4 specific, so I had to modify accordingly here.)\n" 1070 | "enum EPropertyFlags\n" 1071 | "{\n" 1072 | "\tCPF_Edit =\t\t\t\t\t\t\t\t0x0000000000000001,\t// Property is user-settable in the editor.\n" 1073 | "\tCPF_Const =\t\t\t\t\t\t\t\t0x0000000000000002,\t// Actor\'s property always matches class\'s default actor property.\n" 1074 | "\tCPF_Input =\t\t\t\t\t\t\t 0x0000000000000004,\t// Variable is writable by the input system.\n" 1075 | "\tCPF_ExportObject =\t\t\t\t\t\t0x0000000000000008,\t// Object can be exported with actor.\n" 1076 | "\tCPF_OptionalParm =\t\t\t\t\t\t0x0000000000000010,\t// Optional parameter (if CPF_Param is set).\n" 1077 | "\tCPF_Net =\t\t\t\t\t\t\t\t0x0000000000000020,\t// Property is relevant to network replication.\n" 1078 | "\tCPF_EditConstArray =\t\t\t\t\t0x0000000000000040,\t// Prevent adding/removing of items from dynamic a array in the editor.\n" 1079 | "\tCPF_Parm =\t\t\t\t\t\t\t\t0x0000000000000080,\t// Function/When call parameter.\n" 1080 | "\tCPF_OutParm =\t\t\t\t\t\t\t0x0000000000000100,\t// Value is copied out after function call.\n" 1081 | "\tCPF_SkipParm =\t\t\t\t\t\t\t0x0000000000000200,\t// Property is a short-circuitable evaluation function parm.\n" 1082 | "\tCPF_ReturnParm =\t\t\t\t\t\t0x0000000000000400,\t// Return value.\n" 1083 | "\tCPF_CoerceParm =\t\t\t\t\t\t0x0000000000000800,\t// Coerce args into this function parameter.\n" 1084 | "\tCPF_Native =\t\t\t\t\t\t\t0x0000000000001000,\t// Property is native: C++ code is responsible for serializing it.\n" 1085 | "\tCPF_Transient =\t\t\t\t\t\t\t0x0000000000002000,\t// Property is transient: shouldn\'t be saved, zero-filled at load time.\n" 1086 | "\tCPF_Config =\t\t\t\t\t\t\t0x0000000000004000,\t// Property should be loaded/saved as permanent profile.\n" 1087 | "\tCPF_Localized =\t\t\t\t\t\t\t0x0000000000008000,\t// Property should be loaded as localizable text.\n" 1088 | "\tCPF_Travel =\t\t\t\t\t\t\t0x0000000000010000,\t// Property travels across levels/servers.\n" 1089 | "\tCPF_EditConst =\t\t\t\t\t\t\t0x0000000000020000,\t// Property is uneditable in the editor.\n" 1090 | "\tCPF_GlobalConfig =\t\t\t\t\t\t0x0000000000040000,\t// Load config from base class, not subclass.\n" 1091 | "\tCPF_Component =\t\t\t\t\t\t\t0x0000000000080000,\t// Property containts component references.\n" 1092 | "\tCPF_NeedCtorLink =\t\t\t\t\t\t0x0000000000400000,\t// Fields need construction/destruction.\n" 1093 | "\tCPF_NoExport =\t\t\t\t\t\t\t0x0000000000800000,\t// Property should not be exported to the native class header file.\n" 1094 | "\tCPF_NoClear =\t\t\t\t\t\t\t0x0000000002000000,\t// Hide clear (and browse) button.\n" 1095 | "\tCPF_EditInline =\t\t\t\t\t\t0x0000000004000000,\t// Edit this object reference inline.\n" 1096 | "\tCPF_EdFindable =\t\t\t\t\t\t0x0000000008000000,\t// References are set by clicking on actors in the editor viewports.\n" 1097 | "\tCPF_EditInlineUse =\t\t\t\t\t\t0x0000000010000000,\t// EditInline with Use button.\n" 1098 | "\tCPF_Deprecated =\t\t\t\t\t\t0x0000000020000000,\t// Property is deprecated. Read it from an archive, but don\'t save it.\n" 1099 | "\tCPF_EditInlineNotify =\t\t\t\t\t0x0000000040000000,\t// EditInline, notify outer object on editor change.\n" 1100 | "\tCPF_RepNotify =\t\t\t\t\t\t\t0x0000000100000000,\t// Notify actors when a property is replicated\n" 1101 | "\tCPF_Interp =\t\t\t\t\t\t\t0x0000000200000000,\t// interpolatable property for use with matinee\n" 1102 | "\tCPF_NonTransactional =\t\t\t\t\t0x0000000400000000,\t// Property isn\'t transacted\n" 1103 | "\tCPF_EditorOnly =\t\t\t\t\t\t0x0000000800000000,\t// Property should only be loaded in the editor.\n" 1104 | "\tCPF_NoDestructor =\t\t\t\t\t\t0x0000001000000000,\t// No destructor.\n" 1105 | "\tCPF_AutoWeak =\t\t\t\t\t\t\t0x0000004000000000,\t// CPF_ = 0x0000002000000000, ///<.\n" 1106 | "\tCPF_ContainsInstancedReference = 0x0000008000000000,\t// Property contains component refuerences.\n" 1107 | "\tCPF_AssetRegistrySearchable = 0x0000010000000000,\t// Asset instances will add properties with this flag to the asset registry automatically\n" 1108 | "\tCPF_SimpleDisplay =\t\t\t\t\t\t0x0000020000000000,\t// The property is visible by default in the editor details view.\n" 1109 | "\tCPF_AdvancedDisplay =\t\t\t\t\t0x0000040000000000,\t// The property is advanced and not visible by default in the editor details view.\n" 1110 | "\tCPF_Protected =\t\t\t\t\t\t\t0x0000080000000000,\t// Property is protected from the perspective of scrip\n" 1111 | "\tCPF_BlueprintCallable =\t\t\t\t\t0x0000100000000000,\t// MC Delegates only. Property should be exposed for calling in blueprint code.\n" 1112 | "\tCPF_BlueprintAuthorityOnly =\t\t\t0x0000200000000000,\t// MC Delegates only. This delegate accepts (only in blueprint) only events with BlueprintAuthorityOnly.\n" 1113 | "\tCPF_TextExportTransient =\t\t\t\t0x0000400000000000,\t// Property shouldn\'t be exported to text format (e.g. copy/paste)\n" 1114 | "\tCPF_NonPIEDuplicateTransient =\t\t\t0x0000800000000000,\t// Property should only be copied in PIE.\n" 1115 | "\tCPF_ExposeOnSpawn =\t\t\t\t\t\t0x0001000000000000,\t// Property is exposed on spawn.\n" 1116 | "\tCPF_PersistentInstance =\t\t\t\t0x0002000000000000,\t// A object referenced by the property is duplicated like a component. (Each actor should have an own instance.)\n" 1117 | "\tCPF_UObjectWrapper =\t\t\t\t\t0x0004000000000000,\t// Property was parsed as a wrapper class like TSubclassOf , FScriptInterface etc., rather than a USomething*.\n" 1118 | "\tCPF_HasGetValueTypeHash =\t\t\t\t0x0008000000000000,\t// This property can generate a meaningful hash value.\n" 1119 | "\tCPF_NativeAccessSpecifierPublic =\t\t0x0010000000000000,\t// Public native access specifier.\n" 1120 | "\tCPF_NativeAccessSpecifierProtected =\t0x0020000000000000,\t// Protected native access specifier.\n" 1121 | "\tCPF_NativeAccessSpecifierPrivate =\t\t0x0040000000000000,\t// Private native access specifier.\n" 1122 | "\tCPF_SkipSerialization =\t\t\t\t\t0x0080000000000000\t// Property shouldn\'t be serialized, can still be exported to text.\n" 1123 | "};\n" 1124 | "\n" 1125 | "// https://docs.unrealengine.com/4.26/en-US/API/Runtime/CoreUObject/UObject/EObjectFlags/\n" 1126 | "// Object Flags\n" 1127 | "enum EObjectFlags\n" 1128 | "{\n" 1129 | "\tRF_NoFlags = 0x00000000,\n" 1130 | "\tRF_Public = 0x00000001,\n" 1131 | "\tRF_Standalone = 0x00000002,\n" 1132 | "\tRF_MarkAsNative = 0x00000004,\n" 1133 | "\tRF_Transactional = 0x00000008,\n" 1134 | "\tRF_ClassDefaultObject = 0x00000010,\n" 1135 | "\tRF_ArchetypeObject = 0x00000020,\n" 1136 | "\tRF_Transient = 0x00000040,\n" 1137 | "\tRF_MarkAsRootSet = 0x00000080,\n" 1138 | "\tRF_TagGarbageTemp = 0x00000100,\n" 1139 | "\tRF_NeedInitialization = 0x00000200,\n" 1140 | "\tRF_NeedLoad = 0x00000400,\n" 1141 | "\tRF_KeepForCooker = 0x00000800,\n" 1142 | "\tRF_NeedPostLoad = 0x00001000,\n" 1143 | "\tRF_NeedPostLoadSubobjects = 0x00002000,\n" 1144 | "\tRF_NewerVersionExists = 0x00004000,\n" 1145 | "\tRF_BeginDestroyed = 0x00008000,\n" 1146 | "\tRF_FinishDestroyed = 0x00010000,\n" 1147 | "\tRF_BeingRegenerated = 0x00020000,\n" 1148 | "\tRF_DefaultSubObject = 0x00040000,\n" 1149 | "\tRF_WasLoaded = 0x00080000,\n" 1150 | "\tRF_TextExportTransient = 0x00100000,\n" 1151 | "\tRF_LoadCompleted = 0x00200000,\n" 1152 | "\tRF_InheritableComponentTemplate = 0x00400000,\n" 1153 | "\tRF_DuplicateTransient = 0x00800000,\n" 1154 | "\tRF_StrongRefOnFrame = 0x01000000,\n" 1155 | "\tRF_NonPIEDuplicateTransient = 0x02000000,\n" 1156 | "\tRF_Dynamic = 0x04000000,\n" 1157 | "\tRF_WillBeLoaded = 0x08000000,\n" 1158 | "};\n"; 1159 | } 1160 | 1161 | /* 1162 | # ========================================================================================= # 1163 | # 1164 | # ========================================================================================= # 1165 | */ -------------------------------------------------------------------------------- /Engine/Template/PiecesOfCode.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | /* 5 | # ========================================================================================= # 6 | # Pieces Of Code 7 | # ========================================================================================= # 8 | */ 9 | 10 | // These are global variables for the generator, only change them if you know what you're doing! 11 | 12 | namespace PiecesOfCode 13 | { 14 | extern const std::string TArray_Iterator; 15 | extern const std::string TArray_Class; 16 | extern const std::string TMap_Class; 17 | extern const std::string FNameEntry_UPPER; 18 | extern const std::string FNameEntry_UTF16; 19 | extern const std::string FNameEntry_UTF8; 20 | extern const std::string FName_UTF16; 21 | extern const std::string FName_UTF8; 22 | extern const std::string FString_UTF16; 23 | extern const std::string FString_UTF8; 24 | extern const std::string FPointer_Struct; 25 | extern const std::string FQWord_Struct; 26 | extern const std::string UObject_FunctionDescriptions; 27 | extern const std::string UObject_Functions; 28 | extern const std::string UFunction_Functions; 29 | extern const std::string EEnumFlags; 30 | } 31 | 32 | /* 33 | # ========================================================================================= # 34 | # 35 | # ========================================================================================= # 36 | */ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 BranK 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Printer.cpp: -------------------------------------------------------------------------------- 1 | #include "Printer.hpp" 2 | #include "Engine/Engine.hpp" 3 | 4 | namespace Printer 5 | { 6 | void Empty(std::ostringstream& stream) 7 | { 8 | stream.str(std::string()); 9 | } 10 | 11 | void FillRight(std::ostringstream& stream, char fill, uint64_t width) 12 | { 13 | stream << std::setfill(fill) << std::setw(width) << std::right; 14 | } 15 | 16 | void FillLeft(std::ostringstream& stream, char fill, uint64_t width) 17 | { 18 | stream << std::setfill(fill) << std::setw(width) << std::left; 19 | } 20 | 21 | void FillRight(std::ofstream& stream, char fill, uint64_t width) 22 | { 23 | stream << std::setfill(fill) << std::setw(width) << std::right; 24 | } 25 | 26 | void FillLeft(std::ofstream& stream, char fill, uint64_t width) 27 | { 28 | stream << std::setfill(fill) << std::setw(width) << std::left; 29 | } 30 | 31 | std::string Hex(uintptr_t address, uint64_t width) 32 | { 33 | std::ostringstream stream; 34 | stream << "0x" << std::setfill('0') << std::setw(width) << std::right << std::uppercase << std::hex << address; 35 | return stream.str(); 36 | } 37 | 38 | std::string Decimal(uintptr_t address, uint64_t width) 39 | { 40 | std::ostringstream stream; 41 | stream << std::setfill('0') << std::setw(width) << std::right << std::uppercase << std::dec << address; 42 | return stream.str(); 43 | } 44 | 45 | std::string Precision(float value, uint64_t precision) 46 | { 47 | std::ostringstream stream; 48 | stream << std::setprecision(precision) << value; 49 | return stream.str(); 50 | } 51 | 52 | void Header(std::ostringstream& stream, const std::string& fileName, const std::string& fileExtension, bool pragmaPush) 53 | { 54 | stream << "/*\n"; 55 | stream << "#############################################################################################\n"; 56 | stream << "# " << Configuration::GameName << " (" << Configuration::GameVersion + ") SDK\n"; 57 | stream << "# Generated with the UE3SDKGenerator " << Engine::GeneratorVersion << "\n"; 58 | stream << "# ========================================================================================= #\n"; 59 | stream << "# File: " << fileName << "." << fileExtension << "\n"; 60 | stream << "# ========================================================================================= #\n"; 61 | stream << "# Credits: " << Engine::GeneratorCredits << "\n"; 62 | stream << "# Links: " << Engine::GeneratorLinks << "\n"; 63 | stream << "#############################################################################################\n"; 64 | stream << "*/\n"; 65 | 66 | if (fileName != "SdkHeaders") 67 | { 68 | if (fileExtension == "hpp" && fileName != "GameDefines") 69 | { 70 | stream << "#pragma once\n"; 71 | 72 | if (Configuration::UsingConstants) 73 | { 74 | stream << "#include \"../SdkConstants.hpp\"\n"; 75 | } 76 | } 77 | else if (fileExtension == "cpp" && fileName != "GameDefines") 78 | { 79 | stream << "#include \"../SdkHeaders.hpp\"\n"; 80 | } 81 | } 82 | 83 | if (pragmaPush) 84 | { 85 | stream << "\n#ifdef _MSC_VER\n"; 86 | stream << "\t#pragma pack(push, 0x" + std::to_string(Configuration::FinalAlignment) + ")\n"; 87 | stream << "#endif\n"; 88 | } 89 | } 90 | 91 | void Header(std::ofstream& stream, const std::string& fileName, const std::string& fileExtension, bool pragmaPush) 92 | { 93 | std::ostringstream sStream; 94 | Header(sStream, fileName, fileExtension, pragmaPush); 95 | stream << sStream.str(); 96 | } 97 | 98 | void Section(std::ostringstream& stream, const std::string& sectionName) 99 | { 100 | stream << "\n/*\n"; 101 | stream << "# ========================================================================================= #\n"; 102 | stream << "# " << sectionName << "\n"; 103 | stream << "# ========================================================================================= #\n"; 104 | stream << "*/\n\n"; 105 | } 106 | 107 | void Section(std::ofstream& stream, const std::string& sectionName) 108 | { 109 | std::ostringstream sStream; 110 | Section(sStream, sectionName); 111 | stream << sStream.str(); 112 | } 113 | 114 | void Footer(std::ostringstream& stream, bool pragmaPop) 115 | { 116 | stream << "/*\n"; 117 | stream << "# ========================================================================================= #\n"; 118 | stream << "#\n"; 119 | stream << "# ========================================================================================= #\n"; 120 | stream << "*/\n"; 121 | 122 | if (pragmaPop) 123 | { 124 | stream << "\n#ifdef _MSC_VER\n"; 125 | stream << "\t#pragma pack(pop)\n"; 126 | stream << "#endif\n"; 127 | } 128 | } 129 | 130 | void Footer(std::ofstream& stream, bool pragmaPop) 131 | { 132 | std::ostringstream sStream; 133 | Footer(sStream, pragmaPop); 134 | stream << sStream.str(); 135 | } 136 | } -------------------------------------------------------------------------------- /Printer.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace Printer 11 | { 12 | void Empty(std::ostringstream& stream); 13 | void FillRight(std::ostringstream& stream, char fill, uint64_t width); 14 | void FillLeft(std::ostringstream& stream, char fill, uint64_t width); 15 | void FillRight(std::ofstream& stream, char fill, uint64_t width); 16 | void FillLeft(std::ofstream& stream, char fill, uint64_t width); 17 | std::string Hex(uintptr_t address, uint64_t width); 18 | std::string Decimal(uintptr_t address, uint64_t width); 19 | std::string Precision(float value, uint64_t precision); 20 | 21 | void Header(std::ostringstream& stream, const std::string& fileName, const std::string& fileExtension, bool pragmaPush); 22 | void Header(std::ofstream& stream, const std::string& fileName, const std::string& fileExtension, bool pragmaPush); 23 | void Section(std::ostringstream& stream, const std::string& sectionName); 24 | void Section(std::ofstream& stream, const std::string& sectionName); 25 | void Footer(std::ostringstream& stream, bool pragmaPop); 26 | void Footer(std::ofstream& stream, bool pragmaPop); 27 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UE3SDKGenerator v2.3.0 2 | 3 | ### About 4 | 5 | A modern C++17 Unreal Engine 3 SDK generator, originally based off of TheFeckless's UE3 SDK Generator. 6 | 7 | **This project is now deprecated and is no longer being maintained, this repository now only exists for archival purposes! For an updated and maintained version I have created a [separate project here](https://github.com/CodeRedModding/CodeRed-Generator/)! 8 | 9 | ### Features 10 | 11 | - **Accessibility** 12 | Generated sdk is plug and play, just `#include "SdkHeaders.hpp"` in your project, initialize globals, and you're ready to go. 13 | 14 | - **Global offsets** 15 | Generate an sdk using either offsets or patterns for GObjects and GNames. 16 | 17 | - **Constant variables** 18 | Have the option to use constant variables for classes and functions instead of FindClass/FindObject. 19 | 20 | - **Process Event options** 21 | Have the option of using virtual voids for Process Event, or just use an index number for UObject's VfTable instead. 22 | 23 | - **Custom class alignment** 24 | Full support for both x32 bit and x64 bit games, just change the `Alignment` value in `Configuration.cpp`. 25 | 26 | - **Enum classes** 27 | Have the option to generate normal enums or enum classes as well as their underlying type. 28 | 29 | - **Custom spacer widths** 30 | Customize the spacing for comments, constants, structs, enums, functions, classes, and even the log file. 31 | 32 | ### Requirements 33 | 34 | - ISO C++17 Standard. 35 | - Visual Studio or another Windows based compiler (For Windows header files, along with the PSAPI library). 36 | 37 | ### Configuration 38 | 39 | To get started in generating an sdk, copy and paste the `Template` folder included in the Engine folder and rename it to the game you would like to use. The `GameDefines.hpp` file will need to be reversed by hand because every game is different, there is no way to automate this process. In `Configuration.hpp` uncomment which character type your game uses, it will either be wide char (UTF16) or const char (UTF8). 40 | 41 | ![](https://i.imgur.com/gbIfB3R.png) 42 | 43 | Hard coded fields in `GameDefines.hpp` are dynamically generated in the final sdk, along with their offsets. In order for the offsets to be correct you must properly "register" the field, the template includes all fields needed for sdk generation; anything other than that you do NOT need to register as long as it's not part of the `EFieldIds` enum. 44 | 45 | Here is an example of how to register fields, there are more examples in the `Template` folder, as well as comments throughout to help you if you encounter any errors with the template. 46 | 47 | ![](https://i.imgur.com/qbTOPWd.png) 48 | 49 | Once you have the necessary classes filled out all that's left to do is make the desired changes in the `Configuration.cpp` file (don't forget to set the GeneratorDirectory path) and make sure you have the right files included for your game in `Engine.hpp`. When you inject the compiled dll into your game you will be prompted with a message saying that sdk generation has started, do not close your game until you recieve another message confirming generation is completed. 50 | 51 | ### Finalization 52 | 53 | Once your sdk has been generated you might need to make a minor change to it. Depending on the game the header files in `SdkHeaders.hpp` could be placed out of order, if they are make sure to swap it out in the order of `Core` first, then `Engine`; here is an example: 54 | 55 | ```cpp 56 | #include "GameDefines.hpp" 57 | #include "SDK_HEADERS\Core_structs.hpp" 58 | #include "SDK_HEADERS\Core_classes.hpp" 59 | #include "SDK_HEADERS\Core_parameters.hpp" 60 | #include "SDK_HEADERS\Engine_structs.hpp" 61 | #include "SDK_HEADERS\Engine_classes.hpp" 62 | #include "SDK_HEADERS\Engine_parameters.hpp" 63 | ``` 64 | -------------------------------------------------------------------------------- /UE3SDKGenerator.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30128.74 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UE3SDKGenerator", "UE3SDKGenerator.vcxproj", "{9FD89A8E-8FFE-4F2A-991A-AE822668FA13}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {9FD89A8E-8FFE-4F2A-991A-AE822668FA13}.Debug|x64.ActiveCfg = Debug|x64 17 | {9FD89A8E-8FFE-4F2A-991A-AE822668FA13}.Debug|x64.Build.0 = Debug|x64 18 | {9FD89A8E-8FFE-4F2A-991A-AE822668FA13}.Debug|x86.ActiveCfg = Debug|Win32 19 | {9FD89A8E-8FFE-4F2A-991A-AE822668FA13}.Debug|x86.Build.0 = Debug|Win32 20 | {9FD89A8E-8FFE-4F2A-991A-AE822668FA13}.Release|x64.ActiveCfg = Release|x64 21 | {9FD89A8E-8FFE-4F2A-991A-AE822668FA13}.Release|x64.Build.0 = Release|x64 22 | {9FD89A8E-8FFE-4F2A-991A-AE822668FA13}.Release|x86.ActiveCfg = Release|Win32 23 | {9FD89A8E-8FFE-4F2A-991A-AE822668FA13}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {1A233A51-EF94-4B14-83D0-7BF0A08C22A7} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /UE3SDKGenerator.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | Win32Proj 24 | {9fd89a8e-8ffe-4f2a-991a-ae822668fa13} 25 | UE3SDKGenerator 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v143 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v143 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v143 46 | Unicode 47 | 48 | 49 | DynamicLibrary 50 | false 51 | v143 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | false 78 | 79 | 80 | true 81 | 82 | 83 | false 84 | 85 | 86 | 87 | Level3 88 | true 89 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 90 | true 91 | 92 | 93 | Console 94 | true 95 | 96 | 97 | 98 | 99 | Level3 100 | true 101 | true 102 | true 103 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 104 | true 105 | 106 | 107 | Console 108 | true 109 | true 110 | true 111 | 112 | 113 | 114 | 115 | Level3 116 | true 117 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 118 | true 119 | stdcpp17 120 | 121 | 122 | Console 123 | true 124 | 125 | 126 | 127 | 128 | Level3 129 | true 130 | true 131 | true 132 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 133 | true 134 | stdcpp17 135 | 136 | 137 | Console 138 | true 139 | true 140 | true 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | -------------------------------------------------------------------------------- /UE3SDKGenerator.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {c2909db8-7df0-479c-9864-696d3e87ee8f} 14 | 15 | 16 | {1d65af18-016c-4ade-aef3-1e2d4a7383c0} 17 | 18 | 19 | 20 | 21 | Source Files 22 | 23 | 24 | Source Files 25 | 26 | 27 | Engine 28 | 29 | 30 | Source Files 31 | 32 | 33 | Engine\Template 34 | 35 | 36 | Engine\Template 37 | 38 | 39 | Engine\Template 40 | 41 | 42 | 43 | 44 | Header Files 45 | 46 | 47 | Header Files 48 | 49 | 50 | Header Files 51 | 52 | 53 | Engine 54 | 55 | 56 | Header Files 57 | 58 | 59 | Engine\Template 60 | 61 | 62 | Engine\Template 63 | 64 | 65 | Engine\Template 66 | 67 | 68 | -------------------------------------------------------------------------------- /UE3SDKGenerator.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /dllmain.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "pch.hpp" 3 | #include "Printer.hpp" 4 | #include "Engine/Engine.hpp" 5 | 6 | namespace Utils 7 | { 8 | void Messagebox(const std::string& message, const std::string& title, uint32_t flags); 9 | uintptr_t FindPattern(HMODULE hModule, const uint8_t* pattern, const char* mask); 10 | bool MapExists(std::multimap& map, const std::string& key, const std::string& value); 11 | bool SortProperty(class UProperty* uPropertyA, class UProperty* uPropertyB); 12 | bool SortPropertyPair(const std::pair& pairA, const std::pair& pairB); 13 | bool IsStructProperty(EPropertyTypes propertyType); 14 | bool IsBitField(EPropertyTypes propertyType); 15 | bool IsBitField(unsigned long dimension); 16 | bool AreGObjectsValid(); 17 | bool AreGNamesValid(); 18 | } 19 | 20 | namespace Retrievers 21 | { 22 | void GetAllPropertyFlags(std::ostringstream& stream, uint64_t propertyFlags); 23 | void GetAllFunctionFlags(std::ostringstream& stream, uint64_t functionFlags); 24 | EPropertyTypes GetPropertyTypeInternal(class UProperty* uProperty, std::string& outPropertyType, bool ignoreEnum, bool isBitField = false); 25 | EPropertyTypes GetPropertyType(class UProperty* uProperty, std::string& outPropertyType, bool isBitField = false); 26 | size_t GetPropertySize(class UProperty* uProperty, bool isBitField = true); 27 | uintptr_t GetEntryPoint(); 28 | uintptr_t GetOffset(uintptr_t address); 29 | } 30 | 31 | namespace ConstGenerator 32 | { 33 | void GenerateConst(std::ofstream& file, class UConst* constant); 34 | void ProcessConsts(std::ofstream& file, class UObject* packageObj); 35 | } 36 | 37 | namespace EnumGenerator 38 | { 39 | extern std::unordered_map> mEnumCache; 40 | extern std::unordered_map mGeneratedNames; 41 | std::string GenerateEnumName(class UEnum* uEnum); 42 | void GenerateEnum(std::ofstream& file, class UEnum* uEnum); 43 | void ProcessEnums(std::ofstream& file, class UObject* packageObj); 44 | } 45 | 46 | namespace StructGenerator 47 | { 48 | extern std::vector vGeneratedStructs; 49 | class UScriptStruct* FindLargestStruct(const std::string& structFullName); 50 | void GenerateStructFields(std::ofstream& structStream, EClassTypes structType); 51 | void GenerateStruct(std::ofstream& file, class UScriptStruct* scriptStruct); 52 | void GenerateStructProperties(std::ofstream& file, class UScriptStruct* scriptStruct, class UObject* packageObj); 53 | void ProcessStructs(std::ofstream& file, class UObject* packageObj); 54 | } 55 | 56 | namespace ClassGenerator 57 | { 58 | extern std::unordered_map mGeneratedClasses; 59 | void GenerateClassFields(std::ostringstream& classStream, class UClass* uClass, EClassTypes classType); 60 | void GenerateClass(std::ofstream& file, class UClass* uClass); 61 | void GenerateClassProperties(std::ofstream& file, class UClass* uClass, class UObject* packageObj); 62 | void ProcessClasses(std::ofstream& file, class UObject* packageObj); 63 | } 64 | 65 | namespace ParameterGenerator 66 | { 67 | void GenerateParameter(std::ofstream& file, class UClass* uClass); 68 | void ProcessParameters(std::ofstream& file, class UObject* packageObj); 69 | } 70 | 71 | namespace FunctionGenerator 72 | { 73 | void GenerateVirtualFunctions(std::ofstream& file); 74 | void GenerateFunctionCode(std::ofstream& file, class UClass* uClass); 75 | void GenerateFunctionDescription(std::ofstream& file, class UClass* uClass); 76 | void ProcessFunctions(std::ofstream& file, class UObject* packageObj); 77 | } 78 | 79 | namespace Generator 80 | { 81 | extern bool GlobalsInitialized; 82 | extern std::ofstream LogFile; 83 | extern std::vector vPackages; 84 | extern std::vector vIncludes; 85 | extern std::vector> vConstants; 86 | 87 | std::string CreateValidName(std::string name); 88 | std::string CreateUniqueName(class UClass* uClass); 89 | std::string CreateUniqueName(class UFunction* uFunction, class UClass* uClass); 90 | std::string CreateIndexName(class UObject* uObject, bool pushBack); 91 | void MakeWindowsFunction(std::string& functionName); 92 | 93 | void GenerateConstants(); 94 | void GenerateHeaders(); 95 | void GenerateDefines(); 96 | void ProcessPackages(const std::filesystem::path& directory); 97 | void GenerateSDK(); 98 | void DumpInstances(bool dumpNames, bool dumpObjects); 99 | void DumpObjects(); 100 | void DumpNames(); 101 | bool Initialize(bool createLogFile); 102 | } -------------------------------------------------------------------------------- /pch.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.hpp" -------------------------------------------------------------------------------- /pch.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #pragma comment(lib, "Psapi.lib") --------------------------------------------------------------------------------