attempt at fly logic

This commit is contained in:
ApfelTeeSaft
2024-07-18 15:31:51 +02:00
parent 38a9f4a8a5
commit 809d23d545
13 changed files with 2332 additions and 13 deletions
+132
View File
@@ -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;
}
}
+170
View File
@@ -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>();
}
};
}
+925
View File
@@ -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)
};
}
}
+9
View File
@@ -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" />
+30
View File
@@ -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">
+79
View File
@@ -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);
+28
View File
@@ -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
View File
@@ -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();
}
}
+23
View File
@@ -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);
}
}
}
}
}
+8
View File
@@ -0,0 +1,8 @@
#ifndef LOGIC_HPP
#define LOGIC_HPP
namespace Logic {
void ToggleFlyingMode(bool enableFlying);
}
#endif // LOGIC_HPP
+47
View File
@@ -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
View File
@@ -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
View File
@@ -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>