mirror of
https://github.com/ApfelTeeSaft/F4Menu.git
synced 2026-08-26 19:23:28 +00:00
attempt at fly logic
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
|
||||
#include "UE4.hpp"
|
||||
|
||||
#include "Classes.hpp"
|
||||
|
||||
namespace UE4
|
||||
{
|
||||
class UObject* UObject::FindObjectFastImpl(const std::string& Name, EClassCastFlags RequiredType)
|
||||
{
|
||||
int ObjectNum = GObjects ? GObjects->Num() : GObjectsNew->Num();
|
||||
bool bOldGObj = GObjects ? true : false;
|
||||
|
||||
for (int i = 0; i < ObjectNum; ++i)
|
||||
{
|
||||
UObject* Object = nullptr;
|
||||
if (bOldGObj)
|
||||
Object = GObjects->GetByIndex(i);
|
||||
else
|
||||
Object = GObjectsNew->GetByIndex(i);
|
||||
|
||||
if (!Object)
|
||||
continue;
|
||||
|
||||
if (Object->HasTypeFlag(RequiredType) && Object->GetName() == Name)
|
||||
return Object;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
class UObject* UObject::FindObjectImpl(const std::string& FullName, EClassCastFlags RequiredType)
|
||||
{
|
||||
int ObjectNum = GObjects.GetTypedPtr()->GetByIndex(0) ? GObjects->Num() : GObjectsNew->Num();
|
||||
bool bOldGObj = GObjects.GetTypedPtr()->GetByIndex(0) ? true : false;
|
||||
|
||||
for (int i = 0; i < ObjectNum; ++i)
|
||||
{
|
||||
UObject* Object = nullptr;
|
||||
|
||||
if (bOldGObj)
|
||||
Object = GObjects->GetByIndex(i);
|
||||
else
|
||||
Object = GObjectsNew->GetByIndex(i);
|
||||
|
||||
if (!Object)
|
||||
continue;
|
||||
|
||||
if (Object->HasTypeFlag(RequiredType) && Object->GetFullName() == FullName)
|
||||
return Object;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string UObject::GetFullName() const
|
||||
{
|
||||
if (this && Class)
|
||||
{
|
||||
std::string Temp;
|
||||
|
||||
for (UObject* NextOuter = Outer; NextOuter; NextOuter = NextOuter->Outer)
|
||||
{
|
||||
Temp = NextOuter->GetName() + "." + Temp;
|
||||
}
|
||||
|
||||
std::string Name = Class->GetName();
|
||||
Name += " ";
|
||||
Name += Temp;
|
||||
Name += GetName();
|
||||
|
||||
return Name;
|
||||
}
|
||||
|
||||
return "None";
|
||||
}
|
||||
|
||||
std::string UObject::GetName() const
|
||||
{
|
||||
return this ? Name.ToString() : "None";
|
||||
}
|
||||
|
||||
bool UObject::HasTypeFlag(EClassCastFlags TypeFlags) const
|
||||
{
|
||||
return (Class->CastFlags & TypeFlags);
|
||||
}
|
||||
|
||||
bool UObject::IsA(EClassCastFlags TypeFlags) const
|
||||
{
|
||||
return (Class->CastFlags & TypeFlags);
|
||||
}
|
||||
|
||||
bool UObject::IsA(class UClass* TypeClass) const
|
||||
{
|
||||
return Class->IsSubclassOf(TypeClass);
|
||||
}
|
||||
|
||||
bool UObject::IsDefaultObject() const
|
||||
{
|
||||
return (Flags & EObjectFlags::ClassDefaultObject);
|
||||
}
|
||||
|
||||
bool UStruct::IsSubclassOf(const UStruct* Base) const
|
||||
{
|
||||
if (!Base)
|
||||
return false;
|
||||
|
||||
for (const UStruct* Struct = this; Struct; Struct = Struct->Super)
|
||||
{
|
||||
if (Struct == Base)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
class UFunction* UClass::GetFunction(const std::string& ClassName, const std::string& FuncName) const
|
||||
{
|
||||
for (const UStruct* Clss = this; Clss; Clss = Clss->Super)
|
||||
{
|
||||
if (Clss->GetName() != ClassName)
|
||||
continue;
|
||||
|
||||
for (UField* Field = Clss->Children; Field; Field = Field->Next)
|
||||
{
|
||||
if (Field->HasTypeFlag(EClassCastFlags::Function) && Field->GetName() == FuncName)
|
||||
return static_cast<class UFunction*>(Field);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
#pragma once
|
||||
#include "UE4.hpp"
|
||||
#include "Containers.h"
|
||||
|
||||
namespace UE4
|
||||
{
|
||||
class UObject
|
||||
{
|
||||
public:
|
||||
static inline class TUObjectArrayWrapper GObjects;
|
||||
static inline class TUObjectArrayNew* GObjectsNew;
|
||||
|
||||
void* VTable;
|
||||
EObjectFlags Flags;
|
||||
int32 Index;
|
||||
class UClass* Class;
|
||||
class FName Name;
|
||||
class UObject* Outer;
|
||||
|
||||
public:
|
||||
static class UObject* FindObjectFastImpl(const std::string& Name, EClassCastFlags RequiredType = EClassCastFlags::None);
|
||||
static class UObject* FindObjectImpl(const std::string& FullName, EClassCastFlags RequiredType = EClassCastFlags::None);
|
||||
|
||||
std::string GetFullName() const;
|
||||
std::string GetName() const;
|
||||
bool HasTypeFlag(EClassCastFlags TypeFlags) const;
|
||||
bool IsA(EClassCastFlags TypeFlags) const;
|
||||
bool IsA(class UClass* TypeClass) const;
|
||||
bool IsDefaultObject() const;
|
||||
|
||||
public:
|
||||
static class UClass* FindClass(const std::string& ClassFullName)
|
||||
{
|
||||
return FindObject<class UClass>(ClassFullName, EClassCastFlags::Class);
|
||||
}
|
||||
static class UClass* FindClassFast(const std::string& ClassName)
|
||||
{
|
||||
return FindObjectFast<class UClass>(ClassName, EClassCastFlags::Class);
|
||||
}
|
||||
|
||||
template<typename UEType = UObject>
|
||||
static UEType* FindObject(const std::string& Name, EClassCastFlags RequiredType = EClassCastFlags::None)
|
||||
{
|
||||
return static_cast<UEType*>(FindObjectImpl(Name, RequiredType));
|
||||
}
|
||||
template<typename UEType = UObject>
|
||||
static UEType* FindObjectFast(const std::string& Name, EClassCastFlags RequiredType = EClassCastFlags::None)
|
||||
{
|
||||
return static_cast<UEType*>(FindObjectFastImpl(Name, RequiredType));
|
||||
}
|
||||
|
||||
void ProcessEvent(class UFunction* Function, void* Parms) const
|
||||
{
|
||||
InSDKUtils::CallGameFunction(InSDKUtils::GetVirtualFunction<void(*)(const UObject*, class UFunction*, void*)>(this, Offsets::ProcessEventIdx), this, Function, Parms);
|
||||
}
|
||||
|
||||
static class UClass* StaticClass()
|
||||
{
|
||||
return StaticClassImpl<"Object">();
|
||||
}
|
||||
static class UObject* GetDefaultObj()
|
||||
{
|
||||
return GetDefaultObjImpl<UObject>();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class UField : public UObject
|
||||
{
|
||||
public:
|
||||
class UField* Next;
|
||||
|
||||
public:
|
||||
static class UClass* StaticClass()
|
||||
{
|
||||
return StaticClassImpl<"Field">();
|
||||
}
|
||||
static class UField* GetDefaultObj()
|
||||
{
|
||||
return GetDefaultObjImpl<UField>();
|
||||
}
|
||||
};
|
||||
|
||||
class UProperty : public UField
|
||||
{
|
||||
public:
|
||||
int32 ArrayDim;
|
||||
int32 ElementSize;
|
||||
uint64 PropertyFlags;
|
||||
uint8 Pad_20[0x4];
|
||||
int32 Offset;
|
||||
uint8 Pad_21[0x28];
|
||||
|
||||
public:
|
||||
static class UClass* StaticClass()
|
||||
{
|
||||
return StaticClassImpl<"Property">();
|
||||
}
|
||||
static class UProperty* GetDefaultObj()
|
||||
{
|
||||
return GetDefaultObjImpl<UProperty>();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class UStruct : public UField
|
||||
{
|
||||
public:
|
||||
class UStruct* Super;
|
||||
class UField* Children;
|
||||
int32 Size;
|
||||
int32 MinAlignemnt;
|
||||
uint8 Pad_1D[0x40];
|
||||
|
||||
public:
|
||||
bool IsSubclassOf(const UStruct* Base) const;
|
||||
|
||||
public:
|
||||
static class UClass* StaticClass()
|
||||
{
|
||||
return StaticClassImpl<"Struct">();
|
||||
}
|
||||
static class UStruct* GetDefaultObj()
|
||||
{
|
||||
return GetDefaultObjImpl<UStruct>();
|
||||
}
|
||||
};
|
||||
|
||||
class UClass : public UStruct
|
||||
{
|
||||
public:
|
||||
uint8 Pad_24[0x30];
|
||||
enum class EClassCastFlags CastFlags;
|
||||
uint8 Pad_25[0x38];
|
||||
class UObject* DefaultObject;
|
||||
uint8 Pad_26[0xF8];
|
||||
public:
|
||||
class UFunction* GetFunction(const std::string& ClassName, const std::string& FuncName) const;
|
||||
|
||||
public:
|
||||
static class UClass* StaticClass()
|
||||
{
|
||||
return StaticClassImpl<"Class">();
|
||||
}
|
||||
static class UClass* GetDefaultObj()
|
||||
{
|
||||
return GetDefaultObjImpl<UClass>();
|
||||
}
|
||||
};
|
||||
|
||||
class UFunction : public UStruct
|
||||
{
|
||||
public:
|
||||
using FNativeFuncPtr = void (*)(void* Context, void* TheStack, void* Result);
|
||||
|
||||
uint32 FunctionFlags;
|
||||
uint8 Pad_27[0x20];
|
||||
FNativeFuncPtr ExecFunction;
|
||||
|
||||
public:
|
||||
static class UClass* StaticClass()
|
||||
{
|
||||
return StaticClassImpl<"Function">();
|
||||
}
|
||||
static class UFunction* GetDefaultObj()
|
||||
{
|
||||
return GetDefaultObjImpl<UFunction>();
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,925 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <cmath>
|
||||
#include <Windows.h>
|
||||
|
||||
namespace UE4
|
||||
{
|
||||
namespace Containers
|
||||
{
|
||||
typedef int8_t int8;
|
||||
typedef int16_t int16;
|
||||
typedef int32_t int32;
|
||||
typedef int64_t int64;
|
||||
|
||||
typedef uint8_t uint8;
|
||||
typedef uint16_t uint16;
|
||||
typedef uint32_t uint32;
|
||||
typedef uint64_t uint64;
|
||||
|
||||
|
||||
namespace FMemory
|
||||
{
|
||||
inline void* (*Realloc)(void* Memory, int64_t NewSize, uint32_t Alignment);
|
||||
inline void* (*Free)(void* Memory);
|
||||
}
|
||||
|
||||
template<typename ArrayElementType>
|
||||
class TArray;
|
||||
|
||||
template<typename SparseArrayElementType>
|
||||
class TSparseArray;
|
||||
|
||||
template<typename SetElementType>
|
||||
class TSet;
|
||||
|
||||
template<typename KeyElementType, typename ValueElementType>
|
||||
class TMap;
|
||||
|
||||
template<typename KeyElementType, typename ValueElementType>
|
||||
class TPair;
|
||||
|
||||
namespace Iterators
|
||||
{
|
||||
class FSetBitIterator;
|
||||
|
||||
template<typename ArrayType>
|
||||
class TArrayIterator;
|
||||
|
||||
template<class ContainerType>
|
||||
class TContainerIterator;
|
||||
|
||||
template<typename SparseArrayElementType>
|
||||
using TSparseArrayIterator = TContainerIterator<TSparseArray<SparseArrayElementType>>;
|
||||
|
||||
template<typename SetElementType>
|
||||
using TSetIterator = TContainerIterator<TSet<SetElementType>>;
|
||||
|
||||
template<typename KeyElementType, typename ValueElementType>
|
||||
using TMapIterator = TContainerIterator<TMap<KeyElementType, ValueElementType>>;
|
||||
}
|
||||
|
||||
|
||||
namespace ContainerImpl
|
||||
{
|
||||
namespace HelperFunctions
|
||||
{
|
||||
inline uint32 FloorLog2(uint32 Value)
|
||||
{
|
||||
uint32 pos = 0;
|
||||
if (Value >= 1 << 16) { Value >>= 16; pos += 16; }
|
||||
if (Value >= 1 << 8) { Value >>= 8; pos += 8; }
|
||||
if (Value >= 1 << 4) { Value >>= 4; pos += 4; }
|
||||
if (Value >= 1 << 2) { Value >>= 2; pos += 2; }
|
||||
if (Value >= 1 << 1) { pos += 1; }
|
||||
return pos;
|
||||
}
|
||||
|
||||
inline uint32 CountLeadingZeros(uint32 Value)
|
||||
{
|
||||
if (Value == 0)
|
||||
return 32;
|
||||
|
||||
return 31 - FloorLog2(Value);
|
||||
}
|
||||
}
|
||||
|
||||
template<int32 Size, uint32 Alignment>
|
||||
struct TAlignedBytes
|
||||
{
|
||||
alignas(Alignment) uint8 Pad[Size];
|
||||
};
|
||||
|
||||
template<uint32 NumInlineElements>
|
||||
class TInlineAllocator
|
||||
{
|
||||
public:
|
||||
template<typename ElementType>
|
||||
class ForElementType
|
||||
{
|
||||
private:
|
||||
static constexpr int32 ElementSize = sizeof(ElementType);
|
||||
static constexpr int32 ElementAlign = alignof(ElementType);
|
||||
|
||||
static constexpr int32 InlineDataSizeBytes = NumInlineElements * ElementSize;
|
||||
|
||||
private:
|
||||
TAlignedBytes<ElementSize, ElementAlign> InlineData[NumInlineElements];
|
||||
ElementType* SecondaryData;
|
||||
|
||||
public:
|
||||
ForElementType()
|
||||
: InlineData{ 0x0 }, SecondaryData(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
ForElementType(ForElementType&&) = default;
|
||||
ForElementType(const ForElementType&) = default;
|
||||
|
||||
public:
|
||||
ForElementType& operator=(ForElementType&&) = default;
|
||||
ForElementType& operator=(const ForElementType&) = default;
|
||||
|
||||
public:
|
||||
inline const ElementType* GetAllocation() const { return SecondaryData ? SecondaryData : reinterpret_cast<const ElementType*>(&InlineData); }
|
||||
|
||||
inline uint32 GetNumInlineBytes() const { return NumInlineElements; }
|
||||
};
|
||||
};
|
||||
|
||||
class FBitArray
|
||||
{
|
||||
protected:
|
||||
static constexpr int32 NumBitsPerDWORD = 32;
|
||||
static constexpr int32 NumBitsPerDWORDLogTwo = 5;
|
||||
|
||||
private:
|
||||
TInlineAllocator<4>::ForElementType<int32> Data;
|
||||
int32 NumBits;
|
||||
int32 MaxBits;
|
||||
|
||||
public:
|
||||
FBitArray()
|
||||
: NumBits(0), MaxBits(Data.GetNumInlineBytes()* NumBitsPerDWORD)
|
||||
{
|
||||
}
|
||||
|
||||
FBitArray(const FBitArray&) = default;
|
||||
|
||||
FBitArray(FBitArray&&) = default;
|
||||
|
||||
public:
|
||||
FBitArray& operator=(FBitArray&&) = default;
|
||||
|
||||
FBitArray& operator=(const FBitArray& Other) = default;
|
||||
|
||||
private:
|
||||
inline void VerifyIndex(int32 Index) const { if (!IsValidIndex(Index)) throw std::out_of_range("Index was out of range!"); }
|
||||
|
||||
public:
|
||||
inline int32 Num() const { return NumBits; }
|
||||
inline int32 Max() const { return MaxBits; }
|
||||
|
||||
inline const uint32* GetData() const { return reinterpret_cast<const uint32*>(Data.GetAllocation()); }
|
||||
|
||||
inline bool IsValidIndex(int32 Index) const { return Index >= 0 && Index < NumBits; }
|
||||
|
||||
inline bool IsValid() const { return GetData() && NumBits > 0; }
|
||||
|
||||
public:
|
||||
inline bool operator[](int32 Index) const { VerifyIndex(Index); return GetData()[Index / NumBitsPerDWORD] & (1 << (Index & (NumBitsPerDWORD - 1))); }
|
||||
|
||||
inline bool operator==(const FBitArray& Other) const { return NumBits == Other.NumBits && GetData() == Other.GetData(); }
|
||||
inline bool operator!=(const FBitArray& Other) const { return NumBits != Other.NumBits || GetData() != Other.GetData(); }
|
||||
|
||||
public:
|
||||
friend Iterators::FSetBitIterator begin(const FBitArray& Array);
|
||||
friend Iterators::FSetBitIterator end(const FBitArray& Array);
|
||||
};
|
||||
|
||||
template<typename SparseArrayType>
|
||||
union TSparseArrayElementOrFreeListLink
|
||||
{
|
||||
SparseArrayType ElementData;
|
||||
|
||||
struct
|
||||
{
|
||||
int32 PrevFreeIndex;
|
||||
int32 NextFreeIndex;
|
||||
};
|
||||
};
|
||||
|
||||
template<typename SetType>
|
||||
class SetElement
|
||||
{
|
||||
private:
|
||||
template<typename SetDataType>
|
||||
friend class TSet;
|
||||
|
||||
private:
|
||||
SetType Value;
|
||||
int32 HashNextId;
|
||||
int32 HashIndex;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
template <typename KeyType, typename ValueType>
|
||||
class TPair
|
||||
{
|
||||
private:
|
||||
KeyType First;
|
||||
ValueType Second;
|
||||
|
||||
public:
|
||||
TPair(KeyType Key, ValueType Value)
|
||||
: First(Key), Second(Value)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
inline KeyType& Key() { return First; }
|
||||
inline const KeyType& Key() const { return First; }
|
||||
|
||||
inline ValueType& Value() { return Second; }
|
||||
inline const ValueType& Value() const { return Second; }
|
||||
};
|
||||
|
||||
template<typename ArrayElementType>
|
||||
class TArray
|
||||
{
|
||||
private:
|
||||
template<typename ArrayElementType>
|
||||
friend class TAllocatedArray;
|
||||
|
||||
template<typename SparseArrayElementType>
|
||||
friend class TSparseArray;
|
||||
|
||||
protected:
|
||||
static constexpr uint64 ElementAlign = alignof(ArrayElementType);
|
||||
static constexpr uint64 ElementSize = sizeof(ArrayElementType);
|
||||
|
||||
public:
|
||||
ArrayElementType* Data;
|
||||
int32 NumElements;
|
||||
int32 MaxElements;
|
||||
|
||||
TArray()
|
||||
: Data(nullptr), NumElements(0), MaxElements(0)
|
||||
{
|
||||
}
|
||||
|
||||
TArray(const TArray&) = default;
|
||||
|
||||
TArray(TArray&&) = default;
|
||||
|
||||
public:
|
||||
TArray& operator=(TArray&&) = default;
|
||||
TArray& operator=(const TArray&) = default;
|
||||
|
||||
private:
|
||||
inline int32 GetSlack() const { return MaxElements - NumElements; }
|
||||
|
||||
inline void VerifyIndex(int32 Index) const { if (!IsValidIndex(Index)) throw std::out_of_range("Index was out of range!"); }
|
||||
|
||||
inline ArrayElementType& GetUnsafe(int32 Index) { return Data[Index]; }
|
||||
inline const ArrayElementType& GetUnsafe(int32 Index) const { return Data[Index]; }
|
||||
|
||||
public:
|
||||
inline void Reserve(const int Num)
|
||||
{
|
||||
Data = (ArrayElementType*)FMemory::Realloc(Data, (MaxElements = Num + NumElements) * sizeof(ArrayElementType), 0);
|
||||
}
|
||||
|
||||
inline void Free()
|
||||
{
|
||||
if (Data)
|
||||
FMemory::Free(Data);
|
||||
|
||||
MaxElements = 0;
|
||||
NumElements = 0;
|
||||
}
|
||||
|
||||
inline ArrayElementType& Add(const ArrayElementType& InData)
|
||||
{
|
||||
Reserve(1);
|
||||
|
||||
Data[NumElements] = InData;
|
||||
++NumElements;
|
||||
|
||||
return Data[NumElements - 1];
|
||||
}
|
||||
|
||||
void AddWithSize(size_t SizeOfElement, void* ElementPointer)
|
||||
{
|
||||
Data = (ArrayElementType*)FMemory::Realloc(Data, SizeOfElement * (NumElements + 1), 0);
|
||||
|
||||
memcpy((Data + ((SizeOfElement - sizeof(ArrayElementType)) * NumElements) + NumElements++), ElementPointer, SizeOfElement);
|
||||
|
||||
MaxElements = NumElements;
|
||||
}
|
||||
|
||||
inline bool Remove(int Index)
|
||||
{
|
||||
if (Index < NumElements)
|
||||
{
|
||||
if (Index != NumElements - 1)
|
||||
{
|
||||
Data[Index] = Data[NumElements - 1];
|
||||
}
|
||||
|
||||
--NumElements;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline void Clear()
|
||||
{
|
||||
NumElements = 0;
|
||||
|
||||
if (!Data)
|
||||
memset(Data, 0, NumElements * ElementSize);
|
||||
}
|
||||
|
||||
public:
|
||||
inline int32 Num() const { return NumElements; }
|
||||
inline int32 Max() const { return MaxElements; }
|
||||
|
||||
inline bool IsValidIndex(int32 Index) const { return Data && Index >= 0 && Index < NumElements; }
|
||||
|
||||
inline bool IsValid() const { return Data && NumElements > 0 && MaxElements >= NumElements; }
|
||||
|
||||
public:
|
||||
inline ArrayElementType& operator[](int32 Index) { VerifyIndex(Index); return Data[Index]; }
|
||||
inline const ArrayElementType& operator[](int32 Index) const { VerifyIndex(Index); return Data[Index]; }
|
||||
|
||||
inline bool operator==(const TArray<ArrayElementType>& Other) const { return Data == Other.Data; }
|
||||
inline bool operator!=(const TArray<ArrayElementType>& Other) const { return Data != Other.Data; }
|
||||
|
||||
inline explicit operator bool() const { return IsValid(); };
|
||||
|
||||
public:
|
||||
template<typename T> friend Iterators::TArrayIterator<T> begin(const TArray& Array);
|
||||
template<typename T> friend Iterators::TArrayIterator<T> end(const TArray& Array);
|
||||
};
|
||||
|
||||
class FString : public TArray<wchar_t>
|
||||
{
|
||||
public:
|
||||
using TArray::TArray;
|
||||
|
||||
FString(const wchar_t* Str)
|
||||
{
|
||||
const uint32 NullTerminatedLength = static_cast<uint32>(wcslen(Str) + 0x1);
|
||||
|
||||
Data = const_cast<wchar_t*>(Str);
|
||||
NumElements = NullTerminatedLength;
|
||||
MaxElements = NullTerminatedLength;
|
||||
}
|
||||
|
||||
public:
|
||||
inline std::string ToString() const
|
||||
{
|
||||
if (*this)
|
||||
{
|
||||
std::wstring WData(Data);
|
||||
#pragma warning(suppress: 4244)
|
||||
return std::string(WData.begin(), WData.end());
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
inline std::wstring ToWString() const
|
||||
{
|
||||
if (*this)
|
||||
return std::wstring(Data);
|
||||
|
||||
return L"";
|
||||
}
|
||||
|
||||
public:
|
||||
inline wchar_t* CStr() { return Data; }
|
||||
inline const wchar_t* CStr() const { return Data; }
|
||||
|
||||
public:
|
||||
inline bool operator==(const FString& Other) const { return Other ? NumElements == Other.NumElements && wcscmp(Data, Other.Data) == 0 : false; }
|
||||
inline bool operator!=(const FString& Other) const { return Other ? NumElements != Other.NumElements || wcscmp(Data, Other.Data) != 0 : true; }
|
||||
};
|
||||
template<typename ArrayElementType>
|
||||
class TAllocatedArray : public TArray<ArrayElementType>
|
||||
{
|
||||
public:
|
||||
TAllocatedArray() = delete;
|
||||
|
||||
public:
|
||||
TAllocatedArray(int32 Size)
|
||||
{
|
||||
this->Data = static_cast<ArrayElementType*>(malloc(Size * sizeof(ArrayElementType)));
|
||||
this->NumElements = 0x0;
|
||||
this->MaxElements = Size;
|
||||
}
|
||||
|
||||
~TAllocatedArray()
|
||||
{
|
||||
if (this->Data)
|
||||
free(this->Data);
|
||||
|
||||
this->NumElements = 0x0;
|
||||
this->MaxElements = 0x0;
|
||||
}
|
||||
|
||||
public:
|
||||
inline operator TArray<ArrayElementType>() { return *reinterpret_cast<TArray<ArrayElementType>*>(this); }
|
||||
inline operator const TArray<ArrayElementType>() const { return *reinterpret_cast<const TArray<ArrayElementType>*>(this); }
|
||||
};
|
||||
class FAllocatedString : public FString
|
||||
{
|
||||
public:
|
||||
FAllocatedString() = delete;
|
||||
|
||||
public:
|
||||
FAllocatedString(int32 Size)
|
||||
{
|
||||
Data = static_cast<wchar_t*>(malloc(Size * sizeof(wchar_t)));
|
||||
NumElements = 0x0;
|
||||
MaxElements = Size;
|
||||
}
|
||||
|
||||
~FAllocatedString()
|
||||
{
|
||||
if (Data)
|
||||
free(Data);
|
||||
|
||||
NumElements = 0x0;
|
||||
MaxElements = 0x0;
|
||||
}
|
||||
|
||||
public:
|
||||
inline operator FString() { return *reinterpret_cast<FString*>(this); }
|
||||
inline operator const FString() const { return *reinterpret_cast<const FString*>(this); }
|
||||
};
|
||||
template<typename SparseArrayElementType>
|
||||
class TSparseArray
|
||||
{
|
||||
private:
|
||||
static constexpr uint32 ElementAlign = alignof(SparseArrayElementType);
|
||||
static constexpr uint32 ElementSize = sizeof(SparseArrayElementType);
|
||||
|
||||
private:
|
||||
using FElementOrFreeListLink = ContainerImpl::TSparseArrayElementOrFreeListLink<ContainerImpl::TAlignedBytes<ElementSize, ElementAlign>>;
|
||||
|
||||
private:
|
||||
TArray<FElementOrFreeListLink> Data;
|
||||
ContainerImpl::FBitArray AllocationFlags;
|
||||
int32 FirstFreeIndex;
|
||||
int32 NumFreeIndices;
|
||||
|
||||
public:
|
||||
TSparseArray()
|
||||
: FirstFreeIndex(-1), NumFreeIndices(0)
|
||||
{
|
||||
}
|
||||
|
||||
TSparseArray(TSparseArray&&) = default;
|
||||
TSparseArray(const TSparseArray&) = default;
|
||||
|
||||
public:
|
||||
TSparseArray& operator=(TSparseArray&&) = default;
|
||||
TSparseArray& operator=(const TSparseArray&) = default;
|
||||
|
||||
private:
|
||||
inline void VerifyIndex(int32 Index) const { if (!IsValidIndex(Index)) throw std::out_of_range("Index was out of range!"); }
|
||||
|
||||
public:
|
||||
inline int32 NumAllocated() const { return Data.Num(); }
|
||||
|
||||
inline int32 Num() const { return NumAllocated() - NumFreeIndices; }
|
||||
inline int32 Max() const { return Data.Max(); }
|
||||
|
||||
inline bool IsValidIndex(int32 Index) const { return Data.IsValidIndex(Index) && AllocationFlags[Index]; }
|
||||
|
||||
inline bool IsValid() const { return Data.IsValid() && AllocationFlags.IsValid(); }
|
||||
|
||||
public:
|
||||
const ContainerImpl::FBitArray& GetAllocationFlags() const { return AllocationFlags; }
|
||||
|
||||
public:
|
||||
inline SparseArrayElementType& operator[](int32 Index) { VerifyIndex(Index); return *reinterpret_cast<SparseArrayElementType*>(&Data.GetUnsafe(Index).ElementData); }
|
||||
inline const SparseArrayElementType& operator[](int32 Index) const { VerifyIndex(Index); return *reinterpret_cast<SparseArrayElementType*>(&Data.GetUnsafe(Index).ElementData); }
|
||||
|
||||
inline bool operator==(const TSparseArray<SparseArrayElementType>& Other) const { return Data == Other.Data; }
|
||||
inline bool operator!=(const TSparseArray<SparseArrayElementType>& Other) const { return Data != Other.Data; }
|
||||
|
||||
public:
|
||||
template<typename T> friend Iterators::TSparseArrayIterator<T> begin(const TSparseArray& Array);
|
||||
template<typename T> friend Iterators::TSparseArrayIterator<T> end(const TSparseArray& Array);
|
||||
};
|
||||
|
||||
template<typename SetElementType>
|
||||
class TSet
|
||||
{
|
||||
private:
|
||||
static constexpr uint32 ElementAlign = alignof(SetElementType);
|
||||
static constexpr uint32 ElementSize = sizeof(SetElementType);
|
||||
|
||||
private:
|
||||
using SetDataType = ContainerImpl::SetElement<SetElementType>;
|
||||
using HashType = ContainerImpl::TInlineAllocator<1>::ForElementType<int32>;
|
||||
|
||||
private:
|
||||
TSparseArray<SetDataType> Elements;
|
||||
HashType Hash;
|
||||
int32 HashSize;
|
||||
|
||||
public:
|
||||
TSet()
|
||||
: HashSize(0)
|
||||
{
|
||||
}
|
||||
|
||||
TSet(TSet&&) = default;
|
||||
TSet(const TSet&) = default;
|
||||
|
||||
public:
|
||||
TSet& operator=(TSet&&) = default;
|
||||
TSet& operator=(const TSet&) = default;
|
||||
|
||||
private:
|
||||
inline void VerifyIndex(int32 Index) const { if (!IsValidIndex(Index)) throw std::out_of_range("Index was out of range!"); }
|
||||
|
||||
public:
|
||||
inline int32 NumAllocated() const { return Elements.NumAllocated(); }
|
||||
|
||||
inline int32 Num() const { return Elements.Num(); }
|
||||
inline int32 Max() const { return Elements.Max(); }
|
||||
|
||||
inline bool IsValidIndex(int32 Index) const { return Elements.IsValidIndex(Index); }
|
||||
|
||||
inline bool IsValid() const { return Elements.IsValid(); }
|
||||
|
||||
public:
|
||||
const ContainerImpl::FBitArray& GetAllocationFlags() const { return Elements.GetAllocationFlags(); }
|
||||
|
||||
public:
|
||||
inline SetElementType& operator[] (int32 Index) { return Elements[Index].Value; }
|
||||
inline const SetElementType& operator[] (int32 Index) const { return Elements[Index].Value; }
|
||||
|
||||
inline bool operator==(const TSet<SetElementType>& Other) const { return Elements == Other.Elements; }
|
||||
inline bool operator!=(const TSet<SetElementType>& Other) const { return Elements != Other.Elements; }
|
||||
|
||||
public:
|
||||
template<typename T> friend Iterators::TSetIterator<T> begin(const TSet& Set);
|
||||
template<typename T> friend Iterators::TSetIterator<T> end(const TSet& Set);
|
||||
};
|
||||
|
||||
template<typename KeyElementType, typename ValueElementType>
|
||||
class TMap
|
||||
{
|
||||
public:
|
||||
using ElementType = TPair<KeyElementType, ValueElementType>;
|
||||
|
||||
private:
|
||||
TSet<ElementType> Elements;
|
||||
|
||||
private:
|
||||
inline void VerifyIndex(int32 Index) const { if (!IsValidIndex(Index)) throw std::out_of_range("Index was out of range!"); }
|
||||
|
||||
public:
|
||||
inline int32 NumAllocated() const { return Elements.NumAllocated(); }
|
||||
|
||||
inline int32 Num() const { return Elements.Num(); }
|
||||
inline int32 Max() const { return Elements.Max(); }
|
||||
|
||||
inline bool IsValidIndex(int32 Index) const { return Elements.IsValidIndex(Index); }
|
||||
|
||||
inline bool IsValid() const { return Elements.IsValid(); }
|
||||
|
||||
public:
|
||||
const ContainerImpl::FBitArray& GetAllocationFlags() const { return Elements.GetAllocationFlags(); }
|
||||
|
||||
public:
|
||||
inline decltype(auto) Find(const KeyElementType& Key, bool(*Equals)(const KeyElementType& LeftKey, const KeyElementType& RightKey))
|
||||
{
|
||||
for (auto It = begin(*this); It != end(*this); ++It)
|
||||
{
|
||||
if (Equals(It->Key(), Key))
|
||||
return It;
|
||||
}
|
||||
|
||||
return end(*this);
|
||||
}
|
||||
|
||||
public:
|
||||
inline ElementType& operator[] (int32 Index) { return Elements[Index]; }
|
||||
inline const ElementType& operator[] (int32 Index) const { return Elements[Index]; }
|
||||
|
||||
inline bool operator==(const TMap<KeyElementType, ValueElementType>& Other) const { return Elements == Other.Elements; }
|
||||
inline bool operator!=(const TMap<KeyElementType, ValueElementType>& Other) const { return Elements != Other.Elements; }
|
||||
|
||||
public:
|
||||
template<typename KeyType, typename ValueType> friend Iterators::TMapIterator<KeyType, ValueType> begin(const TMap& Map);
|
||||
template<typename KeyType, typename ValueType> friend Iterators::TMapIterator<KeyType, ValueType> end(const TMap& Map);
|
||||
};
|
||||
|
||||
namespace Iterators
|
||||
{
|
||||
class FRelativeBitReference
|
||||
{
|
||||
protected:
|
||||
static constexpr int32 NumBitsPerDWORD = 32;
|
||||
static constexpr int32 NumBitsPerDWORDLogTwo = 5;
|
||||
|
||||
public:
|
||||
inline explicit FRelativeBitReference(int32 BitIndex)
|
||||
: WordIndex(BitIndex >> NumBitsPerDWORDLogTwo)
|
||||
, Mask(1 << (BitIndex & (NumBitsPerDWORD - 1)))
|
||||
{
|
||||
}
|
||||
|
||||
int32 WordIndex;
|
||||
uint32 Mask;
|
||||
};
|
||||
|
||||
class FSetBitIterator : public FRelativeBitReference
|
||||
{
|
||||
private:
|
||||
const ContainerImpl::FBitArray& Array;
|
||||
|
||||
uint32 UnvisitedBitMask;
|
||||
int32 CurrentBitIndex;
|
||||
int32 BaseBitIndex;
|
||||
|
||||
public:
|
||||
explicit FSetBitIterator(const ContainerImpl::FBitArray& InArray, int32 StartIndex = 0)
|
||||
: FRelativeBitReference(StartIndex)
|
||||
, Array(InArray)
|
||||
, UnvisitedBitMask((~0U) << (StartIndex & (NumBitsPerDWORD - 1)))
|
||||
, CurrentBitIndex(StartIndex)
|
||||
, BaseBitIndex(StartIndex & ~(NumBitsPerDWORD - 1))
|
||||
{
|
||||
if (StartIndex != Array.Num())
|
||||
FindFirstSetBit();
|
||||
}
|
||||
|
||||
public:
|
||||
inline FSetBitIterator& operator++()
|
||||
{
|
||||
UnvisitedBitMask &= ~this->Mask;
|
||||
|
||||
FindFirstSetBit();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline explicit operator bool() const { return CurrentBitIndex < Array.Num(); }
|
||||
|
||||
inline bool operator==(const FSetBitIterator& Rhs) const { return CurrentBitIndex == Rhs.CurrentBitIndex && &Array == &Rhs.Array; }
|
||||
inline bool operator!=(const FSetBitIterator& Rhs) const { return CurrentBitIndex != Rhs.CurrentBitIndex || &Array != &Rhs.Array; }
|
||||
|
||||
public:
|
||||
inline int32 GetIndex() { return CurrentBitIndex; }
|
||||
|
||||
void FindFirstSetBit()
|
||||
{
|
||||
const uint32* ArrayData = Array.GetData();
|
||||
const int32 ArrayNum = Array.Num();
|
||||
const int32 LastWordIndex = (ArrayNum - 1) / NumBitsPerDWORD;
|
||||
|
||||
uint32 RemainingBitMask = ArrayData[this->WordIndex] & UnvisitedBitMask;
|
||||
while (!RemainingBitMask)
|
||||
{
|
||||
++this->WordIndex;
|
||||
BaseBitIndex += NumBitsPerDWORD;
|
||||
if (this->WordIndex > LastWordIndex)
|
||||
{
|
||||
CurrentBitIndex = ArrayNum;
|
||||
return;
|
||||
}
|
||||
|
||||
RemainingBitMask = ArrayData[this->WordIndex];
|
||||
UnvisitedBitMask = ~0;
|
||||
}
|
||||
|
||||
const uint32 NewRemainingBitMask = RemainingBitMask & (RemainingBitMask - 1);
|
||||
|
||||
this->Mask = NewRemainingBitMask ^ RemainingBitMask;
|
||||
|
||||
CurrentBitIndex = BaseBitIndex + NumBitsPerDWORD - 1 - ContainerImpl::HelperFunctions::CountLeadingZeros(this->Mask);
|
||||
|
||||
if (CurrentBitIndex > ArrayNum)
|
||||
CurrentBitIndex = ArrayNum;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ArrayType>
|
||||
class TArrayIterator
|
||||
{
|
||||
private:
|
||||
TArray<ArrayType>& IteratedArray;
|
||||
int32 Index;
|
||||
|
||||
public:
|
||||
TArrayIterator(const TArray<ArrayType>& Array, int32 StartIndex = 0x0)
|
||||
: IteratedArray(const_cast<TArray<ArrayType>&>(Array)), Index(StartIndex)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
inline int32 GetIndex() { return Index; }
|
||||
|
||||
inline int32 IsValid() { return IteratedArray.IsValidIndex(GetIndex()); }
|
||||
|
||||
public:
|
||||
inline TArrayIterator& operator++() { ++Index; return *this; }
|
||||
inline TArrayIterator& operator--() { --Index; return *this; }
|
||||
|
||||
inline ArrayType& operator*() { return IteratedArray[GetIndex()]; }
|
||||
inline const ArrayType& operator*() const { return IteratedArray[GetIndex()]; }
|
||||
|
||||
inline ArrayType* operator->() { return &IteratedArray[GetIndex()]; }
|
||||
inline const ArrayType* operator->() const { return &IteratedArray[GetIndex()]; }
|
||||
|
||||
inline bool operator==(const TArrayIterator& Other) const { return &IteratedArray == &Other.IteratedArray && Index == Other.Index; }
|
||||
inline bool operator!=(const TArrayIterator& Other) const { return &IteratedArray != &Other.IteratedArray || Index != Other.Index; }
|
||||
};
|
||||
|
||||
template<class ContainerType>
|
||||
class TContainerIterator
|
||||
{
|
||||
private:
|
||||
ContainerType& IteratedContainer;
|
||||
FSetBitIterator BitIterator;
|
||||
|
||||
public:
|
||||
TContainerIterator(const ContainerType& Container, const ContainerImpl::FBitArray& BitArray, int32 StartIndex = 0x0)
|
||||
: IteratedContainer(const_cast<ContainerType&>(Container)), BitIterator(BitArray, StartIndex)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
inline int32 GetIndex() { return BitIterator.GetIndex(); }
|
||||
|
||||
inline int32 IsValid() { return IteratedContainer.IsValidIndex(GetIndex()); }
|
||||
|
||||
public:
|
||||
inline TContainerIterator& operator++() { ++BitIterator; return *this; }
|
||||
inline TContainerIterator& operator--() { --BitIterator; return *this; }
|
||||
|
||||
inline auto& operator*() { return IteratedContainer[GetIndex()]; }
|
||||
inline const auto& operator*() const { return IteratedContainer[GetIndex()]; }
|
||||
|
||||
inline auto* operator->() { return &IteratedContainer[GetIndex()]; }
|
||||
inline const auto* operator->() const { return &IteratedContainer[GetIndex()]; }
|
||||
|
||||
inline bool operator==(const TContainerIterator& Other) const { return &IteratedContainer == &Other.IteratedContainer && BitIterator == Other.BitIterator; }
|
||||
inline bool operator!=(const TContainerIterator& Other) const { return &IteratedContainer != &Other.IteratedContainer || BitIterator != Other.BitIterator; }
|
||||
};
|
||||
}
|
||||
|
||||
inline Iterators::FSetBitIterator begin(const ContainerImpl::FBitArray& Array) { return Iterators::FSetBitIterator(Array, 0); }
|
||||
inline Iterators::FSetBitIterator end(const ContainerImpl::FBitArray& Array) { return Iterators::FSetBitIterator(Array, Array.Num()); }
|
||||
|
||||
template<typename T> inline Iterators::TArrayIterator<T> begin(const TArray<T>& Array) { return Iterators::TArrayIterator<T>(Array, 0); }
|
||||
template<typename T> inline Iterators::TArrayIterator<T> end(const TArray<T>& Array) { return Iterators::TArrayIterator<T>(Array, Array.Num()); }
|
||||
|
||||
template<typename T> inline Iterators::TSparseArrayIterator<T> begin(const TSparseArray<T>& Array) { return Iterators::TSparseArrayIterator<T>(Array, Array.GetAllocationFlags(), 0); }
|
||||
template<typename T> inline Iterators::TSparseArrayIterator<T> end(const TSparseArray<T>& Array) { return Iterators::TSparseArrayIterator<T>(Array, Array.GetAllocationFlags(), Array.NumAllocated()); }
|
||||
|
||||
template<typename T> inline Iterators::TSetIterator<T> begin(const TSet<T>& Set) { return Iterators::TSetIterator<T>(Set, Set.GetAllocationFlags(), 0); }
|
||||
template<typename T> inline Iterators::TSetIterator<T> end(const TSet<T>& Set) { return Iterators::TSetIterator<T>(Set, Set.GetAllocationFlags(), Set.NumAllocated()); }
|
||||
|
||||
template<typename T0, typename T1> inline Iterators::TMapIterator<T0, T1> begin(const TMap<T0, T1>& Map) { return Iterators::TMapIterator<T0, T1>(Map, Map.GetAllocationFlags(), 0); }
|
||||
template<typename T0, typename T1> inline Iterators::TMapIterator<T0, T1> end(const TMap<T0, T1>& Map) { return Iterators::TMapIterator<T0, T1>(Map, Map.GetAllocationFlags(), Map.NumAllocated()); }
|
||||
|
||||
|
||||
struct FVector
|
||||
{
|
||||
public:
|
||||
using UnderlayingType = float;
|
||||
|
||||
float X;
|
||||
float Y;
|
||||
float Z;
|
||||
|
||||
public:
|
||||
FVector& Normalize()
|
||||
{
|
||||
*this /= Magnitude();
|
||||
return *this;
|
||||
}
|
||||
FVector& operator*=(const FVector& Other)
|
||||
{
|
||||
*this = *this * Other;
|
||||
return *this;
|
||||
}
|
||||
FVector& operator*=(float Scalar)
|
||||
{
|
||||
*this = *this * Scalar;
|
||||
return *this;
|
||||
}
|
||||
FVector& operator+=(const FVector& Other)
|
||||
{
|
||||
*this = *this + Other;
|
||||
return *this;
|
||||
}
|
||||
FVector& operator-=(const FVector& Other)
|
||||
{
|
||||
*this = *this - Other;
|
||||
return *this;
|
||||
}
|
||||
FVector& operator/=(const FVector& Other)
|
||||
{
|
||||
*this = *this / Other;
|
||||
return *this;
|
||||
}
|
||||
FVector& operator/=(float Scalar)
|
||||
{
|
||||
*this = *this / Scalar;
|
||||
return *this;
|
||||
}
|
||||
|
||||
UnderlayingType Dot(const FVector& Other) const
|
||||
{
|
||||
return (X * Other.X) + (Y * Other.Y) + (Z * Other.Z);
|
||||
}
|
||||
UnderlayingType GetDistanceTo(const FVector& Other) const
|
||||
{
|
||||
FVector DiffVector = Other - *this;
|
||||
return DiffVector.Magnitude();
|
||||
}
|
||||
UnderlayingType GetDistanceToInMeters(const FVector& Other) const
|
||||
{
|
||||
return GetDistanceTo(Other) * 0.01;
|
||||
}
|
||||
FVector GetNormalized() const
|
||||
{
|
||||
return *this / Magnitude();
|
||||
}
|
||||
bool IsZero() const
|
||||
{
|
||||
return X == 0.0 && Y == 0.0 && Z == 0.0;
|
||||
}
|
||||
UnderlayingType Magnitude() const
|
||||
{
|
||||
return std::sqrt((X * X) + (Y * Y) + (Z * Z));
|
||||
}
|
||||
bool operator!=(const FVector& Other) const
|
||||
{
|
||||
return X != Other.X || Y != Other.Y || Z != Other.Z;
|
||||
}
|
||||
FVector operator*(const FVector& Other) const
|
||||
{
|
||||
return { X * Other.X, Y * Other.Y, Z * Other.Z };
|
||||
}
|
||||
FVector operator*(float Scalar) const
|
||||
{
|
||||
return { X * Scalar, Y * Scalar, Z * Scalar };
|
||||
}
|
||||
FVector operator+(const FVector& Other) const
|
||||
{
|
||||
return { X + Other.X, Y + Other.Y, Z + Other.Z };
|
||||
}
|
||||
FVector operator-(const FVector& Other) const
|
||||
{
|
||||
return { X - Other.X, Y - Other.Y, Z - Other.Z };
|
||||
}
|
||||
FVector operator/(const FVector& Other) const
|
||||
{
|
||||
if (Other.X == 0.0f || Other.Y == 0.0f || Other.Z == 0.0f)
|
||||
return *this;
|
||||
|
||||
return { X / Other.X, Y / Other.Y, Z / Other.Z };
|
||||
}
|
||||
FVector operator/(float Scalar) const
|
||||
{
|
||||
if (Scalar == 0.0f)
|
||||
return *this;
|
||||
|
||||
return { X / Scalar, Y / Scalar, Z / Scalar };
|
||||
}
|
||||
bool operator==(const FVector& Other) const
|
||||
{
|
||||
return X == Other.X && Y == Other.Y && Z == Other.Z;
|
||||
}
|
||||
};
|
||||
|
||||
struct FRotator final
|
||||
{
|
||||
public:
|
||||
float Pitch;
|
||||
float Yaw;
|
||||
float Roll;
|
||||
};
|
||||
|
||||
struct FQuat final
|
||||
{
|
||||
public:
|
||||
float X; // 0x0000(0x0004)(Edit, BlueprintVisible, ZeroConstructor, SaveGame, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
float Y; // 0x0004(0x0004)(Edit, BlueprintVisible, ZeroConstructor, SaveGame, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
float Z; // 0x0008(0x0004)(Edit, BlueprintVisible, ZeroConstructor, SaveGame, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
float W; // 0x000C(0x0004)(Edit, BlueprintVisible, ZeroConstructor, SaveGame, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
};
|
||||
|
||||
struct FTransform final
|
||||
{
|
||||
public:
|
||||
struct FQuat Rotation; // 0x0000(0x0010)(Edit, BlueprintVisible, SaveGame, IsPlainOldData, NoDestructor, NativeAccessSpecifierPublic)
|
||||
struct FVector Translation; // 0x0010(0x000C)(Edit, BlueprintVisible, SaveGame, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
uint8 Pad_16[0x4]; // 0x001C(0x0004)(Fixing Size After Last Property [ Dumper-7 ])
|
||||
struct FVector Scale3D; // 0x0020(0x000C)(Edit, BlueprintVisible, SaveGame, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
uint8 Pad_17[0x4]; // 0x002C(0x0004)(Fixing Struct Size After Last Property [ Dumper-7 ])
|
||||
};
|
||||
|
||||
struct FGuid final
|
||||
{
|
||||
public:
|
||||
int32 A; // 0x0000(0x0004)(Edit, ZeroConstructor, SaveGame, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
int32 B; // 0x0004(0x0004)(Edit, ZeroConstructor, SaveGame, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
int32 C; // 0x0008(0x0004)(Edit, ZeroConstructor, SaveGame, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
int32 D; // 0x000C(0x0004)(Edit, ZeroConstructor, SaveGame, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -149,11 +149,15 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Classes.hpp" />
|
||||
<ClInclude Include="Containers.h" />
|
||||
<ClInclude Include="Engine\Helper.hpp" />
|
||||
<ClInclude Include="Engine\memcury.h" />
|
||||
<ClInclude Include="framework.h" />
|
||||
<ClInclude Include="Game.h" />
|
||||
<ClInclude Include="GuiManager.hpp" />
|
||||
<ClInclude Include="Hooks.hpp" />
|
||||
<ClInclude Include="Logic.hpp" />
|
||||
<ClInclude Include="SDK\PropertyFixup.hpp" />
|
||||
<ClInclude Include="SDK\SDK.hpp" />
|
||||
<ClInclude Include="SDK\SDK\ActorLayerUtilities_classes.hpp" />
|
||||
@@ -817,11 +821,15 @@
|
||||
<ClInclude Include="ThirdParty\MinHook\include\hde\table64.h" />
|
||||
<ClInclude Include="ThirdParty\MinHook\include\MinHook.h" />
|
||||
<ClInclude Include="ThirdParty\MinHook\include\trampoline.h" />
|
||||
<ClInclude Include="UE4.hpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Classes.cpp" />
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
<ClCompile Include="Game.cpp" />
|
||||
<ClCompile Include="GuiManager.cpp" />
|
||||
<ClCompile Include="Hooks.cpp" />
|
||||
<ClCompile Include="Logic.cpp" />
|
||||
<ClCompile Include="SDK\SDK\ActorLayerUtilities_functions.cpp" />
|
||||
<ClCompile Include="SDK\SDK\AdvancedSessions_functions.cpp" />
|
||||
<ClCompile Include="SDK\SDK\AdvancedSteamSessions_functions.cpp" />
|
||||
@@ -1077,6 +1085,7 @@
|
||||
<ClCompile Include="ThirdParty\MinHook\include\hde\hde64.c" />
|
||||
<ClCompile Include="ThirdParty\MinHook\include\hook.c" />
|
||||
<ClCompile Include="ThirdParty\MinHook\include\trampoline.c" />
|
||||
<ClCompile Include="UE4.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="SDK\NameCollisions.inl" />
|
||||
|
||||
@@ -37,6 +37,9 @@
|
||||
<Filter Include="ThirdParty\imgui">
|
||||
<UniqueIdentifier>{e26e9c40-97ed-4b77-ab53-dec94227c35c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="ALTF4_F">
|
||||
<UniqueIdentifier>{68d198a5-d4b1-416f-9e54-86c4dbbb69d9}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="framework.h">
|
||||
@@ -2043,6 +2046,21 @@
|
||||
<ClInclude Include="ThirdParty\imgui\imgui_internal.h">
|
||||
<Filter>ThirdParty\imgui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Logic.hpp">
|
||||
<Filter>ALTF4_F</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Game.h">
|
||||
<Filter>ALTF4_F</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Classes.hpp">
|
||||
<Filter>SDK</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="UE4.hpp">
|
||||
<Filter>Engine</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Containers.h">
|
||||
<Filter>Engine</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
@@ -2819,6 +2837,18 @@
|
||||
<ClCompile Include="ThirdParty\imgui\imgui_impl_win32.cpp">
|
||||
<Filter>ThirdParty\imgui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Logic.cpp">
|
||||
<Filter>ALTF4_F</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Classes.cpp">
|
||||
<Filter>SDK</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="UE4.cpp">
|
||||
<Filter>Engine</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Game.cpp">
|
||||
<Filter>ALTF4_F</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="SDK\NameCollisions.inl">
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
#include "Game.h"
|
||||
#include "Classes.hpp"
|
||||
#include "UE4.hpp"
|
||||
#include "SDK/SDK/Engine_classes.hpp"
|
||||
#include "SDK/SDK/CoreUObject_classes.hpp"
|
||||
|
||||
namespace Game {
|
||||
UE4::UObject* GetEngine() {
|
||||
// Assuming there is a method to get the engine instance
|
||||
return UE4::UObject::FindObject<UE4::UObject>("EngineName");
|
||||
}
|
||||
|
||||
UE4::UObject* GetWorld() {
|
||||
auto GameViewport = GetChild(GetEngine(), "GameViewport");
|
||||
auto World = GetChild(GameViewport, "World");
|
||||
return World;
|
||||
}
|
||||
|
||||
UE4::UObject* GetPlayerController() {
|
||||
auto OwningGameInstance = GetChild(GetWorld(), "OwningGameInstance");
|
||||
std::vector<UE4::UObject*> LocalPlayers = GetChildAsTArray<UE4::UObject>(OwningGameInstance, "LocalPlayers");
|
||||
auto PlayerController = GetChild(LocalPlayers[0], "PlayerController");
|
||||
return PlayerController;
|
||||
}
|
||||
|
||||
UE4::UObject* GetPlayerState() {
|
||||
auto PlayerState = GetChild(GetPlayerController(), "PlayerState");
|
||||
return PlayerState;
|
||||
}
|
||||
|
||||
UE4::UObject* GetPawn() {
|
||||
auto Pawn = GetChild(GetPlayerController(), "Pawn");
|
||||
return Pawn;
|
||||
}
|
||||
|
||||
UE4::UObject* GetGameMode() {
|
||||
auto AuthorityGameMode = GetChild(GetWorld(), "AuthorityGameMode");
|
||||
return AuthorityGameMode;
|
||||
}
|
||||
|
||||
UE4::UObject* GetGameState() {
|
||||
auto GameState = GetChild(GetGameMode(), "GameState");
|
||||
return GameState;
|
||||
}
|
||||
|
||||
// Utility function implementations
|
||||
UE4::UObject* GetChild(UE4::UObject* parent, const std::string& name) {
|
||||
if (parent) {
|
||||
// Assuming parent->GetChildren() returns a list of child objects
|
||||
for (auto& child : parent->GetChildren()) {
|
||||
if (child->GetName() == name) {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::vector<T*> GetChildAsTArray(UE4::UObject* parent, const std::string& name) {
|
||||
std::vector<T*> children;
|
||||
if (parent) {
|
||||
for (auto& child : parent->GetChildren()) {
|
||||
if (child->GetName() == name) {
|
||||
if (auto castedChild = dynamic_cast<T*>(child)) {
|
||||
children.push_back(castedChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return children;
|
||||
}
|
||||
|
||||
UE4::UClass* StaticClassImpl(const std::string& className) {
|
||||
return UE4::UObject::FindClass(className);
|
||||
}
|
||||
}
|
||||
|
||||
template std::vector<UE4::UObject*> Game::GetChildAsTArray<UE4::UObject>(UE4::UObject* parent, const std::string& name);
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef GAME_H
|
||||
#define GAME_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace UE4 {
|
||||
class UObject;
|
||||
class UClass;
|
||||
}
|
||||
|
||||
namespace Game {
|
||||
UE4::UObject* GetEngine();
|
||||
UE4::UObject* GetWorld();
|
||||
UE4::UObject* GetPlayerController();
|
||||
UE4::UObject* GetPlayerState();
|
||||
UE4::UObject* GetPawn();
|
||||
UE4::UObject* GetGameMode();
|
||||
UE4::UObject* GetGameState();
|
||||
|
||||
// Utility functions
|
||||
UE4::UObject* GetChild(UE4::UObject* parent, const std::string& name);
|
||||
template<typename T>
|
||||
std::vector<T*> GetChildAsTArray(UE4::UObject* parent, const std::string& name);
|
||||
UE4::UClass* StaticClassImpl(const std::string& className);
|
||||
}
|
||||
|
||||
#endif // GAME_H
|
||||
+3
-13
@@ -4,6 +4,7 @@
|
||||
#include "ThirdParty/imgui/imgui_impl_dx11.h"
|
||||
#include <Windows.h>
|
||||
#include <d3d11.h>
|
||||
#include "Logic.hpp"
|
||||
|
||||
extern ID3D11Device* g_pd3dDevice;
|
||||
extern ID3D11DeviceContext* g_pd3dDeviceContext;
|
||||
@@ -18,9 +19,8 @@ namespace {
|
||||
void ShowGui() {
|
||||
ImGui::Begin("Menu");
|
||||
|
||||
if (ImGui::Button("Flying")) {
|
||||
flyingEnabled = !flyingEnabled;
|
||||
// Add logic to enable/disable flying
|
||||
if (ImGui::Checkbox("Flying", &flyingEnabled)) {
|
||||
Logic::ToggleFlyingMode(flyingEnabled);
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
@@ -75,17 +75,7 @@ namespace GuiManager {
|
||||
|
||||
// Rendering
|
||||
ImGui::Render();
|
||||
g_pd3dDeviceContext->OMSetRenderTargets(1, &g_mainRenderTargetView, nullptr);
|
||||
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
|
||||
}
|
||||
}
|
||||
|
||||
bool IsGuiVisible() {
|
||||
return guiVisible;
|
||||
}
|
||||
|
||||
void SetupGui() {
|
||||
// Initialize ImGui
|
||||
InitImGui();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#include "Logic.hpp"
|
||||
#include "Game.h"
|
||||
#include "Classes.hpp" // Include to ensure UE4::UObject is defined
|
||||
|
||||
namespace Logic {
|
||||
void ToggleFlyingMode(bool enableFlying) {
|
||||
auto PlayerController = Game::GetPlayerController();
|
||||
if (PlayerController) {
|
||||
auto Pawn = Game::GetPawn();
|
||||
if (Pawn) {
|
||||
constexpr int MOVE_Flying = 2;
|
||||
constexpr int MOVE_Walking = 0;
|
||||
|
||||
if (enableFlying) {
|
||||
Pawn->SetMovementMode(MOVE_Flying);
|
||||
}
|
||||
else {
|
||||
Pawn->SetMovementMode(MOVE_Walking);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
#ifndef LOGIC_HPP
|
||||
#define LOGIC_HPP
|
||||
|
||||
namespace Logic {
|
||||
void ToggleFlyingMode(bool enableFlying);
|
||||
}
|
||||
|
||||
#endif // LOGIC_HPP
|
||||
@@ -0,0 +1,47 @@
|
||||
#include "UE4.hpp"
|
||||
|
||||
#include "Classes.hpp"
|
||||
|
||||
namespace UE4
|
||||
{
|
||||
class UClass* BasicFilesImpleUtils::FindClassByName(const std::string& Name)
|
||||
{
|
||||
return UObject::FindClassFast(Name);
|
||||
}
|
||||
|
||||
class UClass* BasicFilesImpleUtils::FindClassByFullName(const std::string& Name)
|
||||
{
|
||||
return UObject::FindClass(Name);
|
||||
}
|
||||
|
||||
std::string BasicFilesImpleUtils::GetObjectName(class UClass* Class)
|
||||
{
|
||||
return Class->GetName();
|
||||
}
|
||||
|
||||
int32 BasicFilesImpleUtils::GetObjectIndex(class UClass* Class)
|
||||
{
|
||||
return Class->Index;
|
||||
}
|
||||
|
||||
class UObject* BasicFilesImpleUtils::GetObjectByIndex(int32 Index)
|
||||
{
|
||||
return UObject::GObjects->GetByIndex(Index);
|
||||
}
|
||||
|
||||
UFunction* BasicFilesImpleUtils::FindFunctionByFName(const FName* Name)
|
||||
{
|
||||
for (int i = 0; i < UObject::GObjects->Num(); ++i)
|
||||
{
|
||||
UObject* Object = UObject::GObjects->GetByIndex(i);
|
||||
|
||||
if (!Object)
|
||||
continue;
|
||||
|
||||
if (Object->Name == *Name)
|
||||
return static_cast<UFunction*>(Object);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
+875
@@ -0,0 +1,875 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <Windows.h>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
|
||||
#include "Containers.h"
|
||||
|
||||
namespace UE4
|
||||
{
|
||||
using namespace Containers;
|
||||
|
||||
|
||||
namespace Offsets
|
||||
{
|
||||
static uintptr_t GObjects = 0;
|
||||
static uintptr_t AppendString = 0;
|
||||
static uintptr_t ProcessEvent = 0;
|
||||
static uintptr_t ProcessEventIdx = 0;
|
||||
static uintptr_t GWorld = 0;
|
||||
}
|
||||
|
||||
namespace InSDKUtils
|
||||
{
|
||||
inline uintptr_t GetImageBase()
|
||||
{
|
||||
return reinterpret_cast<uintptr_t>(GetModuleHandle(0));
|
||||
}
|
||||
|
||||
template<typename FuncType>
|
||||
inline FuncType GetVirtualFunction(const void* ObjectInstance, int32 Index)
|
||||
{
|
||||
void** VTable = *reinterpret_cast<void***>(const_cast<void*>(ObjectInstance));
|
||||
|
||||
return reinterpret_cast<FuncType>(VTable[Index]);
|
||||
}
|
||||
|
||||
template<typename FuncType, typename... ParamTypes>
|
||||
requires std::invocable<FuncType, ParamTypes...>
|
||||
inline auto CallGameFunction(FuncType Function, ParamTypes&&... Args)
|
||||
{
|
||||
return Function(std::forward<ParamTypes>(Args)...);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<int32 Len>
|
||||
struct StringLiteral
|
||||
{
|
||||
char Chars[Len];
|
||||
|
||||
consteval StringLiteral(const char(&String)[Len])
|
||||
{
|
||||
std::copy_n(String, Len, Chars);
|
||||
}
|
||||
|
||||
operator std::string() const
|
||||
{
|
||||
return static_cast<const char*>(Chars);
|
||||
}
|
||||
};
|
||||
class UClass;
|
||||
class UObject;
|
||||
class UFunction;
|
||||
|
||||
struct FName;
|
||||
|
||||
namespace BasicFilesImpleUtils
|
||||
{
|
||||
UClass* FindClassByName(const std::string& Name);
|
||||
UClass* FindClassByFullName(const std::string& Name);
|
||||
|
||||
std::string GetObjectName(class UClass* Class);
|
||||
int32 GetObjectIndex(class UClass* Class);
|
||||
|
||||
UObject* GetObjectByIndex(int32 Index);
|
||||
|
||||
UFunction* FindFunctionByFName(const FName* Name);
|
||||
}
|
||||
|
||||
template<StringLiteral Name, bool bIsFullName = false>
|
||||
class UClass* StaticClassImpl()
|
||||
{
|
||||
static class UClass* Clss = nullptr;
|
||||
|
||||
if (Clss == nullptr)
|
||||
{
|
||||
if constexpr (bIsFullName) {
|
||||
Clss = BasicFilesImpleUtils::FindClassByFullName(Name);
|
||||
}
|
||||
else {
|
||||
Clss = BasicFilesImpleUtils::FindClassByName(Name);
|
||||
}
|
||||
}
|
||||
|
||||
return Clss;
|
||||
}
|
||||
|
||||
template<StringLiteral Name, bool bIsFullName = false, StringLiteral NonFullName = "">
|
||||
class UClass* StaticBPGeneratedClassImpl()
|
||||
{
|
||||
static auto SetClassIndex = [](UClass* Class, int32& Index) -> UClass*
|
||||
{
|
||||
if (Class)
|
||||
Index = BasicFilesImpleUtils::GetObjectIndex(Class);
|
||||
|
||||
return Class;
|
||||
};
|
||||
|
||||
static int32 ClassIdx = 0x0;
|
||||
if constexpr (bIsFullName)
|
||||
{
|
||||
if (ClassIdx == 0x0)
|
||||
return SetClassIndex(BasicFilesImpleUtils::FindClassByFullName(Name), ClassIdx);
|
||||
|
||||
UClass* ClassObj = static_cast<UClass*>(BasicFilesImpleUtils::GetObjectByIndex(ClassIdx));
|
||||
if (!ClassObj || BasicFilesImpleUtils::GetObjectName(ClassObj) != static_cast<std::string>(Name))
|
||||
return SetClassIndex(BasicFilesImpleUtils::FindClassByFullName(Name), ClassIdx);
|
||||
|
||||
return ClassObj;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ClassIdx == 0x0)
|
||||
return SetClassIndex(BasicFilesImpleUtils::FindClassByName(Name), ClassIdx);
|
||||
|
||||
UClass* ClassObj = static_cast<UClass*>(BasicFilesImpleUtils::GetObjectByIndex(ClassIdx));
|
||||
if (!ClassObj || BasicFilesImpleUtils::GetObjectName(ClassObj) != static_cast<std::string>(Name))
|
||||
return SetClassIndex(BasicFilesImpleUtils::FindClassByName(Name), ClassIdx);
|
||||
|
||||
return ClassObj;
|
||||
}
|
||||
}
|
||||
|
||||
template<class ClassType>
|
||||
ClassType* GetDefaultObjImpl()
|
||||
{
|
||||
return static_cast<ClassType*>(ClassType::StaticClass()->DefaultObject);
|
||||
}
|
||||
struct FUObjectItem final
|
||||
{
|
||||
public:
|
||||
class UObject* Object;
|
||||
uint8 Pad_0[0x10];
|
||||
};
|
||||
static_assert(alignof(FUObjectItem) == 0x000008, "Wrong alignment on FUObjectItem");
|
||||
static_assert(sizeof(FUObjectItem) == 0x000018, "Wrong size on FUObjectItem");
|
||||
static_assert(offsetof(FUObjectItem, Object) == 0x000000, "Member 'FUObjectItem::Object' has a wrong offset!");
|
||||
|
||||
class TUObjectArrayNew
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
ElementsPerChunk = 0x10000,
|
||||
};
|
||||
|
||||
public:
|
||||
static inline auto DecryptPtr = [](void* ObjPtr) -> uint8*
|
||||
{
|
||||
return reinterpret_cast<uint8*>(ObjPtr);
|
||||
};
|
||||
|
||||
FUObjectItem** Objects;
|
||||
uint8 Pad_0[0x08];
|
||||
int32 MaxElements;
|
||||
int32 NumElements;
|
||||
int32 MaxChunks;
|
||||
int32 NumChunks;
|
||||
|
||||
|
||||
public:
|
||||
// Call InitGObjects() before using these functions
|
||||
inline int32 Num() const
|
||||
{
|
||||
return NumElements;
|
||||
}
|
||||
|
||||
inline FUObjectItem** GetDecrytedObjPtr() const
|
||||
{
|
||||
return reinterpret_cast<FUObjectItem**>(DecryptPtr(Objects));
|
||||
}
|
||||
|
||||
inline class UObject* GetByIndex(const int32 Index) const
|
||||
{
|
||||
if (Index < 0 || Index > NumElements)
|
||||
return nullptr;
|
||||
|
||||
const int32 ChunkIndex = Index / ElementsPerChunk;
|
||||
const int32 InChunkIdx = Index % ElementsPerChunk;
|
||||
|
||||
return GetDecrytedObjPtr()[ChunkIndex][InChunkIdx].Object;
|
||||
}
|
||||
};
|
||||
|
||||
class TUObjectArray
|
||||
{
|
||||
private:
|
||||
static inline auto DecryptPtr = [](void* ObjPtr) -> uint8*
|
||||
{
|
||||
return reinterpret_cast<uint8*>(ObjPtr);
|
||||
};
|
||||
|
||||
public:
|
||||
FUObjectItem* Objects;
|
||||
int32 MaxElements;
|
||||
int32 NumElements;
|
||||
|
||||
public:
|
||||
inline int Num() const
|
||||
{
|
||||
return NumElements;
|
||||
}
|
||||
|
||||
inline FUObjectItem* GetDecrytedObjPtr() const
|
||||
{
|
||||
return reinterpret_cast<FUObjectItem*>(DecryptPtr(Objects));
|
||||
}
|
||||
|
||||
inline class UObject* GetByIndex(const int32 Index) const
|
||||
{
|
||||
if (Index < 0 || Index > NumElements)
|
||||
return nullptr;
|
||||
|
||||
return GetDecrytedObjPtr()[Index].Object;
|
||||
}
|
||||
};
|
||||
|
||||
class TUObjectArrayWrapper
|
||||
{
|
||||
private:
|
||||
friend class UObject;
|
||||
|
||||
public:
|
||||
void* GObjectsAddress = nullptr;
|
||||
|
||||
private:
|
||||
TUObjectArrayWrapper() = default;
|
||||
|
||||
public:
|
||||
TUObjectArrayWrapper(TUObjectArrayWrapper&&) = delete;
|
||||
TUObjectArrayWrapper(const TUObjectArrayWrapper&) = delete;
|
||||
|
||||
TUObjectArrayWrapper& operator=(TUObjectArrayWrapper&&) = delete;
|
||||
TUObjectArrayWrapper& operator=(const TUObjectArrayWrapper&) = delete;
|
||||
|
||||
public:
|
||||
inline void InitGObjects()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public:
|
||||
inline class TUObjectArray* operator->()
|
||||
{
|
||||
if (!GObjectsAddress) [[unlikely]]
|
||||
InitGObjects();
|
||||
|
||||
return reinterpret_cast<class TUObjectArray*>(GObjectsAddress);
|
||||
}
|
||||
|
||||
inline operator const void* ()
|
||||
{
|
||||
if (!GObjectsAddress) [[unlikely]]
|
||||
InitGObjects();
|
||||
|
||||
return GObjectsAddress;
|
||||
}
|
||||
|
||||
inline class TUObjectArray* GetTypedPtr()
|
||||
{
|
||||
if (!GObjectsAddress) [[unlikely]]
|
||||
InitGObjects();
|
||||
|
||||
return reinterpret_cast<class TUObjectArray*>(GObjectsAddress);
|
||||
}
|
||||
};
|
||||
class FName final
|
||||
{
|
||||
public:
|
||||
static inline void* AppendString = nullptr;
|
||||
|
||||
int32 ComparisonIndex;
|
||||
int32 Number;
|
||||
|
||||
public:
|
||||
static void InitInternal()
|
||||
{
|
||||
AppendString = reinterpret_cast<void*>((uintptr_t)GetModuleHandle(0) + Offsets::AppendString);
|
||||
}
|
||||
|
||||
int32 GetDisplayIndex() const
|
||||
{
|
||||
return ComparisonIndex;
|
||||
}
|
||||
|
||||
std::string GetRawString() const
|
||||
{
|
||||
thread_local FAllocatedString TempString(1024);
|
||||
|
||||
if (!AppendString)
|
||||
InitInternal();
|
||||
|
||||
InSDKUtils::CallGameFunction(reinterpret_cast<void(*)(const FName*, FString&)>(AppendString), this, TempString);
|
||||
|
||||
std::string OutputString = TempString.ToString();
|
||||
TempString.Clear();
|
||||
|
||||
return OutputString;
|
||||
}
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
std::string OutputString = GetRawString();
|
||||
|
||||
size_t pos = OutputString.rfind('/');
|
||||
|
||||
if (pos == std::string::npos)
|
||||
return OutputString;
|
||||
|
||||
return OutputString.substr(pos + 1);
|
||||
}
|
||||
|
||||
bool operator==(const FName& Other) const
|
||||
{
|
||||
return ComparisonIndex == Other.ComparisonIndex && Number == Other.Number;
|
||||
}
|
||||
bool operator!=(const FName& Other) const
|
||||
{
|
||||
return ComparisonIndex != Other.ComparisonIndex || Number != Other.Number;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ClassType>
|
||||
class TSubclassOf
|
||||
{
|
||||
class UClass* ClassPtr;
|
||||
|
||||
public:
|
||||
TSubclassOf() = default;
|
||||
|
||||
inline TSubclassOf(UClass* Class)
|
||||
: ClassPtr(Class)
|
||||
{
|
||||
}
|
||||
|
||||
inline UClass* Get()
|
||||
{
|
||||
return ClassPtr;
|
||||
}
|
||||
|
||||
inline operator UClass* () const
|
||||
{
|
||||
return ClassPtr;
|
||||
}
|
||||
|
||||
template<typename Target, typename = std::enable_if<std::is_base_of_v<Target, ClassType>, bool>::type>
|
||||
inline operator TSubclassOf<Target>() const
|
||||
{
|
||||
return ClassPtr;
|
||||
}
|
||||
|
||||
inline UClass* operator->()
|
||||
{
|
||||
return ClassPtr;
|
||||
}
|
||||
|
||||
inline TSubclassOf& operator=(UClass* Class)
|
||||
{
|
||||
ClassPtr = Class;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool operator==(const TSubclassOf& Other) const
|
||||
{
|
||||
return ClassPtr == Other.ClassPtr;
|
||||
}
|
||||
|
||||
inline bool operator!=(const TSubclassOf& Other) const
|
||||
{
|
||||
return ClassPtr != Other.ClassPtr;
|
||||
}
|
||||
|
||||
inline bool operator==(UClass* Other) const
|
||||
{
|
||||
return ClassPtr == Other;
|
||||
}
|
||||
|
||||
inline bool operator!=(UClass* Other) const
|
||||
{
|
||||
return ClassPtr != Other;
|
||||
}
|
||||
};
|
||||
class FTextData final
|
||||
{
|
||||
public:
|
||||
uint8 Pad_1[0x28];
|
||||
class FString TextSource;
|
||||
};
|
||||
static_assert(alignof(FTextData) == 0x000008, "Wrong alignment on FTextData");
|
||||
static_assert(sizeof(FTextData) == 0x000038, "Wrong size on FTextData");
|
||||
static_assert(offsetof(FTextData, TextSource) == 0x000028, "Member 'FTextData::TextSource' has a wrong offset!");
|
||||
class FText final
|
||||
{
|
||||
public:
|
||||
class FTextData* TextData;
|
||||
uint8 Pad_2[0x10];
|
||||
|
||||
public:
|
||||
const class FString& GetStringRef() const
|
||||
{
|
||||
return TextData->TextSource;
|
||||
}
|
||||
std::string ToString() const
|
||||
{
|
||||
return TextData->TextSource.ToString();
|
||||
}
|
||||
};
|
||||
static_assert(alignof(FText) == 0x000008, "Wrong alignment on FText");
|
||||
static_assert(sizeof(FText) == 0x000018, "Wrong size on FText");
|
||||
static_assert(offsetof(FText, TextData) == 0x000000, "Member 'FText::TextData' has a wrong offset!");
|
||||
class FWeakObjectPtr
|
||||
{
|
||||
public:
|
||||
int32 ObjectIndex;
|
||||
int32 ObjectSerialNumber;
|
||||
|
||||
public:
|
||||
class UObject* Get() const;
|
||||
class UObject* operator->() const;
|
||||
bool operator==(const FWeakObjectPtr& Other) const;
|
||||
bool operator!=(const FWeakObjectPtr& Other) const;
|
||||
bool operator==(const class UObject* Other) const;
|
||||
bool operator!=(const class UObject* Other) const;
|
||||
};
|
||||
static_assert(alignof(FWeakObjectPtr) == 0x000004, "Wrong alignment on FWeakObjectPtr");
|
||||
static_assert(sizeof(FWeakObjectPtr) == 0x000008, "Wrong size on FWeakObjectPtr");
|
||||
static_assert(offsetof(FWeakObjectPtr, ObjectIndex) == 0x000000, "Member 'FWeakObjectPtr::ObjectIndex' has a wrong offset!");
|
||||
static_assert(offsetof(FWeakObjectPtr, ObjectSerialNumber) == 0x000004, "Member 'FWeakObjectPtr::ObjectSerialNumber' has a wrong offset!");
|
||||
|
||||
template<typename UEType>
|
||||
class TWeakObjectPtr : public FWeakObjectPtr
|
||||
{
|
||||
public:
|
||||
UEType* Get() const
|
||||
{
|
||||
return static_cast<UEType*>(FWeakObjectPtr::Get());
|
||||
}
|
||||
|
||||
UEType* operator->() const
|
||||
{
|
||||
return static_cast<UEType*>(FWeakObjectPtr::Get());
|
||||
}
|
||||
};
|
||||
class FUniqueObjectGuid final
|
||||
{
|
||||
public:
|
||||
uint32 A;
|
||||
uint32 B;
|
||||
uint32 C;
|
||||
uint32 D;
|
||||
};
|
||||
static_assert(alignof(FUniqueObjectGuid) == 0x000004, "Wrong alignment on FUniqueObjectGuid");
|
||||
static_assert(sizeof(FUniqueObjectGuid) == 0x000010, "Wrong size on FUniqueObjectGuid");
|
||||
static_assert(offsetof(FUniqueObjectGuid, A) == 0x000000, "Member 'FUniqueObjectGuid::A' has a wrong offset!");
|
||||
static_assert(offsetof(FUniqueObjectGuid, B) == 0x000004, "Member 'FUniqueObjectGuid::B' has a wrong offset!");
|
||||
static_assert(offsetof(FUniqueObjectGuid, C) == 0x000008, "Member 'FUniqueObjectGuid::C' has a wrong offset!");
|
||||
static_assert(offsetof(FUniqueObjectGuid, D) == 0x00000C, "Member 'FUniqueObjectGuid::D' has a wrong offset!");
|
||||
template<typename TObjectID>
|
||||
class TPersistentObjectPtr
|
||||
{
|
||||
public:
|
||||
FWeakObjectPtr WeakPtr;
|
||||
int32 TagAtLastTest;
|
||||
TObjectID ObjectID;
|
||||
|
||||
public:
|
||||
class UObject* Get() const
|
||||
{
|
||||
return WeakPtr.Get();
|
||||
}
|
||||
class UObject* operator->() const
|
||||
{
|
||||
return WeakPtr.Get();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename UEType>
|
||||
class TLazyObjectPtr : public TPersistentObjectPtr<FUniqueObjectGuid>
|
||||
{
|
||||
public:
|
||||
UEType* Get() const
|
||||
{
|
||||
return static_cast<UEType*>(TPersistentObjectPtr::Get());
|
||||
}
|
||||
UEType* operator->() const
|
||||
{
|
||||
return static_cast<UEType*>(TPersistentObjectPtr::Get());
|
||||
}
|
||||
};
|
||||
|
||||
namespace FakeSoftObjectPtr
|
||||
{
|
||||
struct FSoftObjectPath
|
||||
{
|
||||
public:
|
||||
class FName AssetPathName;
|
||||
class FString SubPathString;
|
||||
};
|
||||
static_assert(alignof(FSoftObjectPath) == 0x000008, "Wrong alignment on FSoftObjectPath");
|
||||
static_assert(sizeof(FSoftObjectPath) == 0x000018, "Wrong size on FSoftObjectPath");
|
||||
static_assert(offsetof(FSoftObjectPath, AssetPathName) == 0x000000, "Member 'FSoftObjectPath::AssetPathName' has a wrong offset!");
|
||||
static_assert(offsetof(FSoftObjectPath, SubPathString) == 0x000008, "Member 'FSoftObjectPath::SubPathString' has a wrong offset!");
|
||||
|
||||
}
|
||||
|
||||
class FSoftObjectPtr : public TPersistentObjectPtr<FakeSoftObjectPtr::FSoftObjectPath>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename UEType>
|
||||
class TSoftObjectPtr : public FSoftObjectPtr
|
||||
{
|
||||
public:
|
||||
UEType* Get() const
|
||||
{
|
||||
return static_cast<UEType*>(TPersistentObjectPtr::Get());
|
||||
}
|
||||
UEType* operator->() const
|
||||
{
|
||||
return static_cast<UEType*>(TPersistentObjectPtr::Get());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename UEType>
|
||||
class TSoftClassPtr : public FSoftObjectPtr
|
||||
{
|
||||
public:
|
||||
UEType* Get() const
|
||||
{
|
||||
return static_cast<UEType*>(TPersistentObjectPtr::Get());
|
||||
}
|
||||
UEType* operator->() const
|
||||
{
|
||||
return static_cast<UEType*>(TPersistentObjectPtr::Get());
|
||||
}
|
||||
};
|
||||
class FScriptInterface
|
||||
{
|
||||
public:
|
||||
UObject* ObjectPointer;
|
||||
void* InterfacePointer;
|
||||
|
||||
public:
|
||||
class UObject* GetObjectRef() const
|
||||
{
|
||||
return ObjectPointer;
|
||||
}
|
||||
|
||||
void* GetInterfaceRef() const
|
||||
{
|
||||
return InterfacePointer;
|
||||
}
|
||||
|
||||
};
|
||||
static_assert(alignof(FScriptInterface) == 0x000008, "Wrong alignment on FScriptInterface");
|
||||
static_assert(sizeof(FScriptInterface) == 0x000010, "Wrong size on FScriptInterface");
|
||||
static_assert(offsetof(FScriptInterface, ObjectPointer) == 0x000000, "Member 'FScriptInterface::ObjectPointer' has a wrong offset!");
|
||||
static_assert(offsetof(FScriptInterface, InterfacePointer) == 0x000008, "Member 'FScriptInterface::InterfacePointer' has a wrong offset!");
|
||||
template<class InterfaceType>
|
||||
class TScriptInterface final : public FScriptInterface
|
||||
{
|
||||
};
|
||||
template<typename FunctionSignature>
|
||||
class TDelegate
|
||||
{
|
||||
public:
|
||||
struct InvalidUseOfTDelegate TemplateParamIsNotAFunctionSignature;
|
||||
};
|
||||
template<typename Ret, typename... Args>
|
||||
class TDelegate<Ret(Args...)>
|
||||
{
|
||||
public:
|
||||
FWeakObjectPtr Object;
|
||||
FName FunctionName;
|
||||
};
|
||||
|
||||
#define UE_ENUM_OPERATORS(EEnumClass) \
|
||||
\
|
||||
inline constexpr EEnumClass operator|(EEnumClass Left, EEnumClass Right) \
|
||||
{ \
|
||||
return (EEnumClass)((std::underlying_type<EEnumClass>::type)(Left) | (std::underlying_type<EEnumClass>::type)(Right)); \
|
||||
} \
|
||||
\
|
||||
inline constexpr EEnumClass& operator|=(EEnumClass& Left, EEnumClass Right) \
|
||||
{ \
|
||||
return (EEnumClass&)((std::underlying_type<EEnumClass>::type&)(Left) |= (std::underlying_type<EEnumClass>::type)(Right)); \
|
||||
} \
|
||||
\
|
||||
inline bool operator&(EEnumClass Left, EEnumClass Right) \
|
||||
{ \
|
||||
return (((std::underlying_type<EEnumClass>::type)(Left) & (std::underlying_type<EEnumClass>::type)(Right)) == (std::underlying_type<EEnumClass>::type)(Right)); \
|
||||
}
|
||||
|
||||
enum class EObjectFlags : int32
|
||||
{
|
||||
NoFlags = 0x00000000,
|
||||
|
||||
Public = 0x00000001,
|
||||
Standalone = 0x00000002,
|
||||
MarkAsNative = 0x00000004,
|
||||
Transactional = 0x00000008,
|
||||
ClassDefaultObject = 0x00000010,
|
||||
ArchetypeObject = 0x00000020,
|
||||
Transient = 0x00000040,
|
||||
|
||||
MarkAsRootSet = 0x00000080,
|
||||
TagGarbageTemp = 0x00000100,
|
||||
|
||||
NeedInitialization = 0x00000200,
|
||||
NeedLoad = 0x00000400,
|
||||
KeepForCooker = 0x00000800,
|
||||
NeedPostLoad = 0x00001000,
|
||||
NeedPostLoadSubobjects = 0x00002000,
|
||||
NewerVersionExists = 0x00004000,
|
||||
BeginDestroyed = 0x00008000,
|
||||
FinishDestroyed = 0x00010000,
|
||||
|
||||
BeingRegenerated = 0x00020000,
|
||||
DefaultSubObject = 0x00040000,
|
||||
WasLoaded = 0x00080000,
|
||||
TextExportTransient = 0x00100000,
|
||||
LoadCompleted = 0x00200000,
|
||||
InheritableComponentTemplate = 0x00400000,
|
||||
DuplicateTransient = 0x00800000,
|
||||
StrongRefOnFrame = 0x01000000,
|
||||
NonPIEDuplicateTransient = 0x02000000,
|
||||
Dynamic = 0x04000000,
|
||||
WillBeLoaded = 0x08000000,
|
||||
};
|
||||
|
||||
enum class EFunctionFlags : uint32
|
||||
{
|
||||
None = 0x00000000,
|
||||
|
||||
Final = 0x00000001,
|
||||
RequiredAPI = 0x00000002,
|
||||
BlueprintAuthorityOnly = 0x00000004,
|
||||
BlueprintCosmetic = 0x00000008,
|
||||
Net = 0x00000040,
|
||||
NetReliable = 0x00000080,
|
||||
NetRequest = 0x00000100,
|
||||
Exec = 0x00000200,
|
||||
Native = 0x00000400,
|
||||
Event = 0x00000800,
|
||||
NetResponse = 0x00001000,
|
||||
Static = 0x00002000,
|
||||
NetMulticast = 0x00004000,
|
||||
UbergraphFunction = 0x00008000,
|
||||
MulticastDelegate = 0x00010000,
|
||||
Public = 0x00020000,
|
||||
Private = 0x00040000,
|
||||
Protected = 0x00080000,
|
||||
Delegate = 0x00100000,
|
||||
NetServer = 0x00200000,
|
||||
HasOutParms = 0x00400000,
|
||||
HasDefaults = 0x00800000,
|
||||
NetClient = 0x01000000,
|
||||
DLLImport = 0x02000000,
|
||||
BlueprintCallable = 0x04000000,
|
||||
BlueprintEvent = 0x08000000,
|
||||
BlueprintPure = 0x10000000,
|
||||
EditorOnly = 0x20000000,
|
||||
Const = 0x40000000,
|
||||
NetValidate = 0x80000000,
|
||||
|
||||
AllFlags = 0xFFFFFFFF,
|
||||
};
|
||||
|
||||
enum class EClassFlags : int32
|
||||
{
|
||||
CLASS_None = 0x00000000u,
|
||||
Abstract = 0x00000001u,
|
||||
DefaultConfig = 0x00000002u,
|
||||
Config = 0x00000004u,
|
||||
Transient = 0x00000008u,
|
||||
Parsed = 0x00000010u,
|
||||
MatchedSerializers = 0x00000020u,
|
||||
ProjectUserConfig = 0x00000040u,
|
||||
Native = 0x00000080u,
|
||||
NoExport = 0x00000100u,
|
||||
NotPlaceable = 0x00000200u,
|
||||
PerObjectConfig = 0x00000400u,
|
||||
ReplicationDataIsSetUp = 0x00000800u,
|
||||
EditInlineNew = 0x00001000u,
|
||||
CollapseCategories = 0x00002000u,
|
||||
Interface = 0x00004000u,
|
||||
CustomConstructor = 0x00008000u,
|
||||
Const = 0x00010000u,
|
||||
LayoutChanging = 0x00020000u,
|
||||
CompiledFromBlueprint = 0x00040000u,
|
||||
MinimalAPI = 0x00080000u,
|
||||
RequiredAPI = 0x00100000u,
|
||||
DefaultToInstanced = 0x00200000u,
|
||||
TokenStreamAssembled = 0x00400000u,
|
||||
HasInstancedReference = 0x00800000u,
|
||||
Hidden = 0x01000000u,
|
||||
Deprecated = 0x02000000u,
|
||||
HideDropDown = 0x04000000u,
|
||||
GlobalUserConfig = 0x08000000u,
|
||||
Intrinsic = 0x10000000u,
|
||||
Constructed = 0x20000000u,
|
||||
ConfigDoNotCheckDefaults = 0x40000000u,
|
||||
NewerVersionExists = 0x80000000u,
|
||||
};
|
||||
|
||||
enum class EClassCastFlags : uint64
|
||||
{
|
||||
None = 0x0000000000000000,
|
||||
|
||||
Field = 0x0000000000000001,
|
||||
Int8Property = 0x0000000000000002,
|
||||
Enum = 0x0000000000000004,
|
||||
Struct = 0x0000000000000008,
|
||||
ScriptStruct = 0x0000000000000010,
|
||||
Class = 0x0000000000000020,
|
||||
ByteProperty = 0x0000000000000040,
|
||||
IntProperty = 0x0000000000000080,
|
||||
FloatProperty = 0x0000000000000100,
|
||||
UInt64Property = 0x0000000000000200,
|
||||
ClassProperty = 0x0000000000000400,
|
||||
UInt32Property = 0x0000000000000800,
|
||||
InterfaceProperty = 0x0000000000001000,
|
||||
NameProperty = 0x0000000000002000,
|
||||
StrProperty = 0x0000000000004000,
|
||||
Property = 0x0000000000008000,
|
||||
ObjectProperty = 0x0000000000010000,
|
||||
BoolProperty = 0x0000000000020000,
|
||||
UInt16Property = 0x0000000000040000,
|
||||
Function = 0x0000000000080000,
|
||||
StructProperty = 0x0000000000100000,
|
||||
ArrayProperty = 0x0000000000200000,
|
||||
Int64Property = 0x0000000000400000,
|
||||
DelegateProperty = 0x0000000000800000,
|
||||
NumericProperty = 0x0000000001000000,
|
||||
MulticastDelegateProperty = 0x0000000002000000,
|
||||
ObjectPropertyBase = 0x0000000004000000,
|
||||
WeakObjectProperty = 0x0000000008000000,
|
||||
LazyObjectProperty = 0x0000000010000000,
|
||||
SoftObjectProperty = 0x0000000020000000,
|
||||
TextProperty = 0x0000000040000000,
|
||||
Int16Property = 0x0000000080000000,
|
||||
DoubleProperty = 0x0000000100000000,
|
||||
SoftClassProperty = 0x0000000200000000,
|
||||
Package = 0x0000000400000000,
|
||||
Level = 0x0000000800000000,
|
||||
Actor = 0x0000001000000000,
|
||||
PlayerController = 0x0000002000000000,
|
||||
Pawn = 0x0000004000000000,
|
||||
SceneComponent = 0x0000008000000000,
|
||||
PrimitiveComponent = 0x0000010000000000,
|
||||
SkinnedMeshComponent = 0x0000020000000000,
|
||||
SkeletalMeshComponent = 0x0000040000000000,
|
||||
Blueprint = 0x0000080000000000,
|
||||
DelegateFunction = 0x0000100000000000,
|
||||
StaticMeshComponent = 0x0000200000000000,
|
||||
MapProperty = 0x0000400000000000,
|
||||
SetProperty = 0x0000800000000000,
|
||||
EnumProperty = 0x0001000000000000,
|
||||
USparseDelegateFunction = 0x0002000000000000,
|
||||
FMulticastInlineDelegateProperty = 0x0004000000000000,
|
||||
FMulticastSparseDelegateProperty = 0x0008000000000000,
|
||||
FFieldPathProperty = 0x0010000000000000,
|
||||
FLargeWorldCoordinatesRealProperty = 0x0080000000000000,
|
||||
FOptionalProperty = 0x0100000000000000,
|
||||
FVValueProperty = 0x0200000000000000,
|
||||
UVerseVMClass = 0x0400000000000000,
|
||||
FVRestValueProperty = 0x0800000000000000,
|
||||
};
|
||||
|
||||
enum class EPropertyFlags : uint64
|
||||
{
|
||||
None = 0x0000000000000000,
|
||||
|
||||
Edit = 0x0000000000000001,
|
||||
ConstParm = 0x0000000000000002,
|
||||
BlueprintVisible = 0x0000000000000004,
|
||||
ExportObject = 0x0000000000000008,
|
||||
BlueprintReadOnly = 0x0000000000000010,
|
||||
Net = 0x0000000000000020,
|
||||
EditFixedSize = 0x0000000000000040,
|
||||
Parm = 0x0000000000000080,
|
||||
OutParm = 0x0000000000000100,
|
||||
ZeroConstructor = 0x0000000000000200,
|
||||
ReturnParm = 0x0000000000000400,
|
||||
DisableEditOnTemplate = 0x0000000000000800,
|
||||
|
||||
Transient = 0x0000000000002000,
|
||||
Config = 0x0000000000004000,
|
||||
|
||||
DisableEditOnInstance = 0x0000000000010000,
|
||||
EditConst = 0x0000000000020000,
|
||||
GlobalConfig = 0x0000000000040000,
|
||||
InstancedReference = 0x0000000000080000,
|
||||
|
||||
DuplicateTransient = 0x0000000000200000,
|
||||
SubobjectReference = 0x0000000000400000,
|
||||
|
||||
SaveGame = 0x0000000001000000,
|
||||
NoClear = 0x0000000002000000,
|
||||
|
||||
ReferenceParm = 0x0000000008000000,
|
||||
BlueprintAssignable = 0x0000000010000000,
|
||||
Deprecated = 0x0000000020000000,
|
||||
IsPlainOldData = 0x0000000040000000,
|
||||
RepSkip = 0x0000000080000000,
|
||||
RepNotify = 0x0000000100000000,
|
||||
Interp = 0x0000000200000000,
|
||||
NonTransactional = 0x0000000400000000,
|
||||
EditorOnly = 0x0000000800000000,
|
||||
NoDestructor = 0x0000001000000000,
|
||||
|
||||
AutoWeak = 0x0000004000000000,
|
||||
ContainsInstancedReference = 0x0000008000000000,
|
||||
AssetRegistrySearchable = 0x0000010000000000,
|
||||
SimpleDisplay = 0x0000020000000000,
|
||||
AdvancedDisplay = 0x0000040000000000,
|
||||
Protected = 0x0000080000000000,
|
||||
BlueprintCallable = 0x0000100000000000,
|
||||
BlueprintAuthorityOnly = 0x0000200000000000,
|
||||
TextExportTransient = 0x0000400000000000,
|
||||
NonPIEDuplicateTransient = 0x0000800000000000,
|
||||
ExposeOnSpawn = 0x0001000000000000,
|
||||
PersistentInstance = 0x0002000000000000,
|
||||
UObjectWrapper = 0x0004000000000000,
|
||||
HasGetValueTypeHash = 0x0008000000000000,
|
||||
NativeAccessSpecifierPublic = 0x0010000000000000,
|
||||
NativeAccessSpecifierProtected = 0x0020000000000000,
|
||||
NativeAccessSpecifierPrivate = 0x0040000000000000,
|
||||
SkipSerialization = 0x0080000000000000,
|
||||
};
|
||||
|
||||
UE_ENUM_OPERATORS(EObjectFlags);
|
||||
UE_ENUM_OPERATORS(EFunctionFlags);
|
||||
UE_ENUM_OPERATORS(EClassFlags);
|
||||
UE_ENUM_OPERATORS(EClassCastFlags);
|
||||
UE_ENUM_OPERATORS(EPropertyFlags);
|
||||
|
||||
namespace CyclicDependencyFixupImpl
|
||||
{
|
||||
template<typename UnderlayingStructType, int32 Size, int32 Align>
|
||||
struct alignas(Align) TCylicStructFixup
|
||||
{
|
||||
private:
|
||||
uint8 Pad[Size];
|
||||
|
||||
public:
|
||||
UnderlayingStructType& GetTyped() { return reinterpret_cast<UnderlayingStructType&>(*this); }
|
||||
const UnderlayingStructType& GetTyped() const { return reinterpret_cast<const UnderlayingStructType&>(*this); }
|
||||
};
|
||||
template<typename UnderlayingClassType, int32 Size, int32 Align = 0x8, class BaseClassType = class UObject>
|
||||
struct alignas(Align) TCyclicClassFixup : public BaseClassType
|
||||
{
|
||||
private:
|
||||
uint8 Pad[Size];
|
||||
|
||||
public:
|
||||
UnderlayingClassType* GetTyped() { return reinterpret_cast<UnderlayingClassType*>(this); }
|
||||
const UnderlayingClassType* GetTyped() const { return reinterpret_cast<const UnderlayingClassType*>(this); }
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -3,3 +3,6 @@
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
// Windows Header Files
|
||||
#include <windows.h>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <format>
|
||||
|
||||
Reference in New Issue
Block a user