#pragma once #include "UObjectGlobals.h" #include "Engine.h" // #include "World.h" #include "Class.h" #include "globals.h" /* enum class REBOOT_ERROR : uint8 { FAILED_STRINGREF = 1, FAILED_CREATE_NETDRIVER = 2, FAILED_LISTEN = 3 }; */ extern inline UObject* (*StaticLoadObjectOriginal)(UClass*, UObject*, const wchar_t* InName, const wchar_t* Filename, uint32_t LoadFlags, UObject* Sandbox, bool bAllowObjectReconciliation) = nullptr; template static inline T* FindObject(const TCHAR* Name, UClass* Class = nullptr, UObject* Outer = nullptr) { auto res = (T*)StaticFindObject/**/(Class, Outer, Name); return res; } template static inline T* LoadObject(const TCHAR* Name, UClass* Class = nullptr, UObject* Outer = nullptr) { if (!StaticLoadObjectOriginal) { std::wstring NameWStr = std::wstring(Name); LOG_WARN(LogDev, "We should load {} but static load object is null!", std::string(NameWStr.begin(), NameWStr.end())); return FindObject(Name, Class, Outer); } return (T*)StaticLoadObjectOriginal(Class, Outer, Name, nullptr, 0, nullptr, false); } template static inline T* LoadObject(const std::string& NameStr, UClass* Class = nullptr, UObject* Outer = nullptr) { auto NameCWSTR = std::wstring(NameStr.begin(), NameStr.end()).c_str(); return (T*)StaticLoadObjectOriginal(Class, Outer, NameCWSTR, nullptr, 0, nullptr, false); } template static inline T* FindObject(const std::string& NameStr, UClass* Class = nullptr, UObject* Outer = nullptr) { auto NameCWSTR = std::wstring(NameStr.begin(), NameStr.end()).c_str(); return StaticFindObject(Class, Outer, NameCWSTR); } static inline UEngine* GetEngine() { static UEngine* Engine = FindObject(L"/Engine/Transient.FortEngine_0"); if (!Engine) { __int64 starting = 2147482000; for (__int64 i = starting; i < (starting + 1000); i++) { if (Engine = FindObject("/Engine/Transient.FortEngine_" + std::to_string(i))) break; } } return Engine; } static inline class UWorld* GetWorld() { static UObject* Engine = GetEngine(); static auto GameViewportOffset = Engine->GetOffset("GameViewport"); auto GameViewport = Engine->Get(GameViewportOffset); static auto WorldOffset = GameViewport->GetOffset("World"); return GameViewport->Get(WorldOffset); } static TArray& GetLocalPlayers() { static UObject* Engine = GetEngine(); static auto GameInstanceOffset = Engine->GetOffset("GameInstance"); UObject* GameInstance = Engine->Get(GameInstanceOffset); static auto LocalPlayersOffset = GameInstance->GetOffset("LocalPlayers"); return GameInstance->Get>(LocalPlayersOffset); } static UObject* GetLocalPlayer() { auto& LocalPlayers = GetLocalPlayers(); return LocalPlayers.Num() ? LocalPlayers.At(0) : nullptr; } static inline UObject* GetLocalPlayerController() { auto LocalPlayer = GetLocalPlayer(); if (!LocalPlayer) return nullptr; static auto PlayerControllerOffset = LocalPlayer->GetOffset("PlayerController"); return LocalPlayer->Get(PlayerControllerOffset); } template static __forceinline T* Cast(UObject* Object, bool bCheckType = true) { if (bCheckType) { if (Object && Object->IsA(T::StaticClass())) { return (T*)Object; } } else { return (T*)Object; } return nullptr; } static inline int AmountOfRestarts = 0; struct PlaceholderBitfield { uint8_t First : 1; uint8_t Second : 1; uint8_t Third : 1; uint8_t Fourth : 1; uint8_t Fifth : 1; uint8_t Sixth : 1; uint8_t Seventh : 1; uint8_t Eighth : 1; }; inline uint8_t GetFieldMask(void* Property, int additional = 0) { if (!Property) return -1; // 3 = sizeof(FieldSize) + sizeof(ByteOffset) + sizeof(ByteMask) if (Engine_Version <= 420) return *(uint8_t*)(__int64(Property) + (112 + 3 + additional)); else if (Engine_Version >= 421 && Engine_Version <= 424) return *(uint8_t*)(__int64(Property) + (112 + 3 + additional)); else if (Engine_Version >= 425) return *(uint8_t*)(__int64(Property) + (120 + 3 + additional)); return -1; } inline bool ReadBitfield(void* Addr, uint8_t FieldMask) { auto Bitfield = (PlaceholderBitfield*)Addr; // niceeeee if (FieldMask == 0x1) return Bitfield->First; else if (FieldMask == 0x2) return Bitfield->Second; else if (FieldMask == 0x4) return Bitfield->Third; else if (FieldMask == 0x8) return Bitfield->Fourth; else if (FieldMask == 0x10) return Bitfield->Fifth; else if (FieldMask == 0x20) return Bitfield->Sixth; else if (FieldMask == 0x40) return Bitfield->Seventh; else if (FieldMask == 0x80) return Bitfield->Eighth; else if (FieldMask == 0xFF) return *(bool*)Bitfield; return false; } inline void SetBitfield(void* Addr, uint8_t FieldMask, bool NewVal) { auto Bitfield = (PlaceholderBitfield*)Addr; // niceeeee if (FieldMask == 0x1) Bitfield->First = NewVal; else if (FieldMask == 0x2) Bitfield->Second = NewVal; else if (FieldMask == 0x4) Bitfield->Third = NewVal; else if (FieldMask == 0x8) Bitfield->Fourth = NewVal; else if (FieldMask == 0x10) Bitfield->Fifth = NewVal; else if (FieldMask == 0x20) Bitfield->Sixth = NewVal; else if (FieldMask == 0x40) Bitfield->Seventh = NewVal; else if (FieldMask == 0x80) Bitfield->Eighth = NewVal; else if (FieldMask == 0xFF) *(bool*)Bitfield = NewVal; } inline int FindOffsetStruct(const std::string& StructName, const std::string& MemberName, bool bWarnIfNotFound = true) { UObject* Struct = FindObject(StructName); if (!Struct) { if (bWarnIfNotFound) LOG_WARN(LogFinder, "Unable to find struct {}", StructName); return 0; } // LOG_INFO(LogFinder, "Struct: {}", Struct->GetFullName()); auto getFNameOfProp = [](void* Property) -> FName* { FName* NamePrivate = nullptr; if (Engine_Version >= 425) NamePrivate = (FName*)(__int64(Property) + 0x28); else NamePrivate = &((UField*)Property)->NamePrivate; return NamePrivate; }; for (auto CurrentClass = Struct; CurrentClass; CurrentClass = *(UObject**)(__int64(CurrentClass) + Offsets::SuperStruct)) { void* Property = *(void**)(__int64(CurrentClass) + Offsets::Children); if (Property) { std::string PropName = getFNameOfProp(Property)->ToString(); if (PropName == MemberName) { return *(int*)(__int64(Property) + Offsets::Offset_Internal); } while (Property) { // LOG_INFO(LogFinder, "PropName: {}", PropName); if (PropName == MemberName) { return *(int*)(__int64(Property) + Offsets::Offset_Internal); } Property = Engine_Version >= 425 ? *(void**)(__int64(Property) + 0x20) : ((UField*)Property)->Next; PropName = Property ? getFNameOfProp(Property)->ToString() : ""; } } } if (bWarnIfNotFound) LOG_WARN(LogFinder, "Unable to find1 {}", MemberName); return 0; } static void CopyStruct(void* Dest, void* Src, size_t Size) { memcpy_s(Dest, Size, Src, Size); } template static T* Alloc(size_t Size) { return (T*)VirtualAlloc(0, Size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); } namespace MemberOffsets { namespace FortPlayerPawnAthena { extern inline int LastFallDistance = 0; } namespace FortPlayerPawn { extern inline int CorrectTags = 0; } namespace FortPlayerState { extern inline int PawnDeathLocation = 0; } namespace FortPlayerStateAthena { extern inline int DeathInfo = 0; extern inline int KillScore = 0; extern inline int TeamKillScore = 0; } namespace DeathReport { extern inline int Tags = 0, KillerPlayerState = 0, KillerPawn = 0, DamageCauser = 0; } namespace DeathInfo { extern inline int bDBNO = 0, Downer = 0, FinisherOrDowner = 0, DeathCause = 0, Distance = 0, DeathLocation = 0, bInitialized = 0, DeathTags = 0; } } static UObject* GetPlaylistToUse() { auto Playlist = FindObject("/Game/Athena/Playlists/Playlist_DefaultSolo.Playlist_DefaultSolo"); // Playlist = FindObject("/BlueCheese/Playlists/Playlist_ShowdownAlt_BlueCheese_Trios.Playlist_ShowdownAlt_BlueCheese_Trios"); /* if (Globals::bGoingToPlayEvent) { if (Fortnite_Version != 12.61) { auto EventPlaylist = GetEventPlaylist(); if (!EventPlaylist) { LOG_ERROR(LogPlaylist, "No event playlist! Turning off going to play event"); Globals::bGoingToPlayEvent = false; } else { Playlist = EventPlaylist; } } } */ // Playlist = FindObject("/Game/Athena/Playlists/Playground/Playlist_Playground.Playlist_Playground"); // Playlist = FindObject("/MoleGame/Playlists/Playlist_MoleGame.Playlist_MoleGame"); // Playlist = FindObject("/Game/Athena/Playlists/DADBRO/Playlist_DADBRO_Squads_8.Playlist_DADBRO_Squads_8"); if (Globals::bCreative) Playlist = FindObject("/Game/Athena/Playlists/Creative/Playlist_PlaygroundV2.Playlist_PlaygroundV2"); return Playlist; }