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