#pragma once // TODO: Update ImGUI #pragma comment(lib, "d3d9.lib") #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "FortAthenaMutator_Disco.h" #include "globals.h" #include "Fonts/ruda-bold.h" #include "Vector.h" #include "reboot.h" #include "FortGameModeAthena.h" #include "UnrealString.h" #include "KismetTextLibrary.h" #include "KismetSystemLibrary.h" #include "GameplayStatics.h" #include "Text.h" #include #include "FortGadgetItemDefinition.h" #include "FortWeaponItemDefinition.h" #include "events.h" #include "FortAthenaMutator_Heist.h" #define GAME_TAB 1 #define PLAYERS_TAB 2 #define GAMEMODE_TAB 3 #define THANOS_TAB 4 #define EVENT_TAB 5 #define LATEGAME_TAB 6 #define DUMP_TAB 7 #define UNBAN_TAB 8 #define DEVELOPER_TAB 9 #define SETTINGS_TAB 10 #define CREDITS_TAB 11 #define MAIN_PLAYERTAB 1 #define INVENTORY_PLAYERTAB 2 #define LOADOUT_PLAYERTAB 4 #define FUN_PLAYERTAB 5 static inline int SecondsUntilTravel = 5; static inline bool bSwitchedInitialLevel = false; extern inline bool bIsInAutoRestart = false; // THE BASE CODE IS FROM IMGUI GITHUB static inline LPDIRECT3D9 g_pD3D = NULL; static inline LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; static inline D3DPRESENT_PARAMETERS g_d3dpp = {}; // Forward declarations of helper functions static inline bool CreateDeviceD3D(HWND hWnd); static inline void CleanupDeviceD3D(); static inline void ResetDevice(); static inline LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); extern inline bool bStartedBus = false; static inline void Restart() // todo move? { FString LevelA = Engine_Version < 424 ? L"open Athena_Terrain" : Engine_Version >= 500 ? Engine_Version >= 501 ? L"open Asteria_Terrain" : Globals::bCreative ? L"open Creative_NoApollo_Terrain" : L"open Artemis_Terrain" : Globals::bCreative ? L"open Creative_NoApollo_Terrain" : L"open Apollo_Terrain"; static auto BeaconClass = FindObject(L"/Script/FortniteGame.FortOnlineBeaconHost"); auto AllFortBeacons = UGameplayStatics::GetAllActorsOfClass(GetWorld(), BeaconClass); for (int i = 0; i < AllFortBeacons.Num(); i++) { AllFortBeacons.at(i)->K2_DestroyActor(); } AllFortBeacons.Free(); Globals::bInitializedPlaylist = false; Globals::bStartedListening = false; Globals::bHitReadyToStartMatch = false; bStartedBus = false; AmountOfRestarts++; LOG_INFO(LogDev, "Switching!"); if (Fortnite_Version >= 3) // idk what ver { ((AGameMode*)GetWorld()->GetGameMode())->RestartGame(); } else { UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), LevelA, nullptr); } /* auto& LevelCollections = GetWorld()->Get>("LevelCollections"); int LevelCollectionSize = FindObject("/Script/Engine.LevelCollection")->GetPropertiesSize(); *(UNetDriver**)(__int64(LevelCollections.AtPtr(0, LevelCollectionSize)) + 0x10) = nullptr; *(UNetDriver**)(__int64(LevelCollections.AtPtr(1, LevelCollectionSize)) + 0x10) = nullptr; */ // UGameplayStatics::OpenLevel(GetWorld(), UKismetStringLibrary::Conv_StringToName(LevelA), true, FString()); } static inline std::string wstring_to_utf8(const std::wstring& str) { if (str.empty()) return {}; const auto size_needed = WideCharToMultiByte(CP_UTF8, 0, &str[0], static_cast(str.size()), nullptr, 0, nullptr, nullptr); std::string str_to(size_needed, 0); WideCharToMultiByte(CP_UTF8, 0, &str[0], static_cast(str.size()), &str_to[0], size_needed, nullptr, nullptr); return str_to; } static inline void InitStyle() { ImFontConfig FontConfig; FontConfig.FontDataOwnedByAtlas = false; ImGui::GetIO().Fonts->AddFontFromMemoryTTF((void*)ruda_bold_data, sizeof(ruda_bold_data), 17.f, &FontConfig); // ImGui::GetIO().Fonts->AddFontFromFileTTF("Reboot Resources/fonts/ruda-bold.ttf", 17); auto& mStyle = ImGui::GetStyle(); mStyle.FramePadding = ImVec2(4, 2); mStyle.ItemSpacing = ImVec2(6, 2); mStyle.ItemInnerSpacing = ImVec2(6, 4); mStyle.Alpha = 0.95f; mStyle.WindowRounding = 4.0f; mStyle.FrameRounding = 2.0f; mStyle.IndentSpacing = 6.0f; mStyle.ItemInnerSpacing = ImVec2(2, 4); mStyle.ColumnsMinSpacing = 50.0f; mStyle.GrabMinSize = 14.0f; mStyle.GrabRounding = 16.0f; mStyle.ScrollbarSize = 12.0f; mStyle.ScrollbarRounding = 16.0f; ImGuiStyle& style = mStyle; style.Colors[ImGuiCol_Text] = ImVec4(0.86f, 0.93f, 0.89f, 0.78f); style.Colors[ImGuiCol_TextDisabled] = ImVec4(0.86f, 0.93f, 0.89f, 0.28f); style.Colors[ImGuiCol_WindowBg] = ImVec4(0.13f, 0.14f, 0.17f, 1.00f); style.Colors[ImGuiCol_Border] = ImVec4(0.31f, 0.31f, 1.00f, 0.00f); style.Colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); style.Colors[ImGuiCol_FrameBg] = ImVec4(0.20f, 0.22f, 0.27f, 1.00f); style.Colors[ImGuiCol_FrameBgHovered] = ImVec4(0.92f, 0.18f, 0.29f, 0.78f); style.Colors[ImGuiCol_FrameBgActive] = ImVec4(0.92f, 0.18f, 0.29f, 1.00f); style.Colors[ImGuiCol_TitleBg] = ImVec4(0.20f, 0.22f, 0.27f, 1.00f); style.Colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.20f, 0.22f, 0.27f, 0.75f); style.Colors[ImGuiCol_TitleBgActive] = ImVec4(0.92f, 0.18f, 0.29f, 1.00f); style.Colors[ImGuiCol_MenuBarBg] = ImVec4(0.20f, 0.22f, 0.27f, 0.47f); style.Colors[ImGuiCol_ScrollbarBg] = ImVec4(0.20f, 0.22f, 0.27f, 1.00f); style.Colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.09f, 0.15f, 0.16f, 1.00f); style.Colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.92f, 0.18f, 0.29f, 0.78f); style.Colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.92f, 0.18f, 0.29f, 1.00f); style.Colors[ImGuiCol_CheckMark] = ImVec4(0.71f, 0.22f, 0.27f, 1.00f); style.Colors[ImGuiCol_SliderGrab] = ImVec4(0.47f, 0.77f, 0.83f, 0.14f); style.Colors[ImGuiCol_SliderGrabActive] = ImVec4(0.92f, 0.18f, 0.29f, 1.00f); style.Colors[ImGuiCol_Button] = ImVec4(0.47f, 0.77f, 0.83f, 0.14f); style.Colors[ImGuiCol_ButtonHovered] = ImVec4(0.92f, 0.18f, 0.29f, 0.86f); style.Colors[ImGuiCol_ButtonActive] = ImVec4(0.92f, 0.18f, 0.29f, 1.00f); style.Colors[ImGuiCol_Header] = ImVec4(0.92f, 0.18f, 0.29f, 0.76f); style.Colors[ImGuiCol_HeaderHovered] = ImVec4(0.92f, 0.18f, 0.29f, 0.86f); style.Colors[ImGuiCol_HeaderActive] = ImVec4(0.92f, 0.18f, 0.29f, 1.00f); style.Colors[ImGuiCol_Separator] = ImVec4(0.14f, 0.16f, 0.19f, 1.00f); style.Colors[ImGuiCol_SeparatorHovered] = ImVec4(0.92f, 0.18f, 0.29f, 0.78f); style.Colors[ImGuiCol_SeparatorActive] = ImVec4(0.92f, 0.18f, 0.29f, 1.00f); style.Colors[ImGuiCol_ResizeGrip] = ImVec4(0.47f, 0.77f, 0.83f, 0.04f); style.Colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.92f, 0.18f, 0.29f, 0.78f); style.Colors[ImGuiCol_ResizeGripActive] = ImVec4(0.92f, 0.18f, 0.29f, 1.00f); style.Colors[ImGuiCol_PlotLines] = ImVec4(0.86f, 0.93f, 0.89f, 0.63f); style.Colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.92f, 0.18f, 0.29f, 1.00f); style.Colors[ImGuiCol_PlotHistogram] = ImVec4(0.86f, 0.93f, 0.89f, 0.63f); style.Colors[ImGuiCol_PlotHistogramHovered] = ImVec4(0.92f, 0.18f, 0.29f, 1.00f); style.Colors[ImGuiCol_TextSelectedBg] = ImVec4(0.92f, 0.18f, 0.29f, 0.43f); style.Colors[ImGuiCol_PopupBg] = ImVec4(0.20f, 0.22f, 0.27f, 0.9f); } static inline void TextCentered(std::string text, bool bNewLine = true) { if (bNewLine) ImGui::NewLine(); float win_width = ImGui::GetWindowSize().x; float text_width = ImGui::CalcTextSize(text.c_str()).x; // calculate the indentation that centers the text on one line, relative // to window left, regardless of the `ImGuiStyleVar_WindowPadding` value float text_indentation = (win_width - text_width) * 0.5f; // if text is too long to be drawn on one line, `text_indentation` can // become too small or even negative, so we check a minimum indentation float min_indentation = 20.0f; if (text_indentation <= min_indentation) { text_indentation = min_indentation; } ImGui::SameLine(text_indentation); ImGui::PushTextWrapPos(win_width - text_indentation); ImGui::TextWrapped(text.c_str()); ImGui::PopTextWrapPos(); } static inline bool ButtonCentered(std::string text, bool bNewLine = true) { if (bNewLine) ImGui::NewLine(); float win_width = ImGui::GetWindowSize().x; float text_width = ImGui::CalcTextSize(text.c_str()).x; // calculate the indentation that centers the text on one line, relative // to window left, regardless of the `ImGuiStyleVar_WindowPadding` value float text_indentation = (win_width - text_width) * 0.5f; // if text is too long to be drawn on one line, `text_indentation` can // become too small or even negative, so we check a minimum indentation float min_indentation = 20.0f; if (text_indentation <= min_indentation) { text_indentation = min_indentation; } ImGui::SameLine(text_indentation); ImGui::PushTextWrapPos(win_width - text_indentation); auto res = ImGui::Button(text.c_str()); ImGui::PopTextWrapPos(); return res; } static inline void InputVector(const std::string& baseText, FVector* vec) { ImGui::InputFloat((baseText + " X").c_str(), &vec->X); ImGui::InputFloat((baseText + " Y").c_str(), &vec->Y); ImGui::InputFloat((baseText + " Z").c_str(), &vec->Z); } static int Width = 640; static int Height = 480; static int Tab = 1; static int PlayerTab = -1; static bool bIsEditingInventory = false; static bool bInformationTab = false; static int playerTabTab = MAIN_PLAYERTAB; static inline void StaticUI() { if (IsRestartingSupported()) { ImGui::Checkbox("Auto Restart", &Globals::bAutoRestart); } #ifndef PROD ImGui::Checkbox("Log ProcessEvent", &Globals::bLogProcessEvent); #endif ImGui::Checkbox("Infinite Ammo", &Globals::bInfiniteAmmo); ImGui::Checkbox("Infinite Materials", &Globals::bInfiniteMaterials); ImGui::Checkbox("No MCP (Don't change unless you know what this is)", &Globals::bNoMCP); if (Addresses::ApplyGadgetData && Addresses::RemoveGadgetData && Engine_Version < 424) { ImGui::Checkbox("Enable AGIDs (Don't change unless you know what this is)", &Globals::bEnableAGIDs); } } static inline void MainTabs() { // std::ofstream bannedStream(Moderation::Banning::GetFilePath()); if (ImGui::BeginTabBar("")) { if (ImGui::BeginTabItem("Game")) { Tab = GAME_TAB; PlayerTab = -1; bInformationTab = false; ImGui::EndTabItem(); } // if (serverStatus == EServerStatus::Up) { /* if (ImGui::BeginTabItem("Players")) { Tab = PLAYERS_TAB; ImGui::EndTabItem(); } */ } if (false && ImGui::BeginTabItem("Gamemode")) { Tab = GAMEMODE_TAB; PlayerTab = -1; bInformationTab = false; ImGui::EndTabItem(); } // if (Events::HasEvent()) if (Globals::bGoingToPlayEvent) { if (ImGui::BeginTabItem(("Event"))) { Tab = EVENT_TAB; PlayerTab = -1; bInformationTab = false; ImGui::EndTabItem(); } } if (false && Globals::bLateGame && ImGui::BeginTabItem(("Lategame"))) { Tab = LATEGAME_TAB; PlayerTab = -1; bInformationTab = false; ImGui::EndTabItem(); } if (ImGui::BeginTabItem("Dump")) { Tab = DUMP_TAB; PlayerTab = -1; bInformationTab = false; ImGui::EndTabItem(); } #if 0 if (bannedStream.is_open() && ImGui::BeginTabItem("Unban")) // skunked { Tab = UNBAN_TAB; PlayerTab = -1; bInformationTab = false; ImGui::EndTabItem(); } #endif /* if (ImGui::BeginTabItem(("Settings"))) { Tab = SETTINGS_TAB; PlayerTab = -1; bInformationTab = false; ImGui::EndTabItem(); } */ // maybe a Replication Stats for >3.3? #ifndef PROD if (ImGui::BeginTabItem("Developer")) { Tab = DEVELOPER_TAB; PlayerTab = -1; bInformationTab = false; ImGui::EndTabItem(); } #endif if (false && ImGui::BeginTabItem(("Credits"))) { Tab = CREDITS_TAB; PlayerTab = -1; bInformationTab = false; ImGui::EndTabItem(); } ImGui::EndTabBar(); } } static inline void PlayerTabs() { if (ImGui::BeginTabBar("")) { if (ImGui::BeginTabItem("Main")) { playerTabTab = MAIN_PLAYERTAB; ImGui::EndTabItem(); } if (ImGui::BeginTabItem(("Inventory"))) { playerTabTab = INVENTORY_PLAYERTAB; ImGui::EndTabItem(); } if (ImGui::BeginTabItem(("Cosmetics"))) { playerTabTab = LOADOUT_PLAYERTAB; ImGui::EndTabItem(); } if (ImGui::BeginTabItem(("Fun"))) { playerTabTab = FUN_PLAYERTAB; ImGui::EndTabItem(); } ImGui::EndTabBar(); } } static inline void MainUI() { bool bLoaded = true; if (PlayerTab == -1) { MainTabs(); if (Tab == GAME_TAB) { if (bLoaded) { StaticUI(); if (!bStartedBus) { bool bWillBeLategame = Globals::bLateGame.load(); ImGui::Checkbox("Lategame", &bWillBeLategame); Globals::bLateGame.store(bWillBeLategame); } ImGui::Text(std::format("Joinable {}", Globals::bStartedListening).c_str()); static std::string ConsoleCommand; ImGui::InputText("Console command", &ConsoleCommand); if (ImGui::Button("Execute console command")) { auto wstr = std::wstring(ConsoleCommand.begin(), ConsoleCommand.end()); auto aa = wstr.c_str(); FString cmd = aa; UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), cmd, nullptr); } /* if (ImGui::Button("New")) { static auto NextFn = FindObject("/Game/Athena/Prototype/Blueprints/Cube/CUBE.CUBE_C.Next"); static auto NewFn = FindObject("/Game/Athena/Prototype/Blueprints/Cube/CUBE.CUBE_C.New"); auto Loader = GetEventLoader("/Game/Athena/Prototype/Blueprints/Cube/CUBE.CUBE_C"); LOG_INFO(LogDev, "Loader: {}", __int64(Loader)); if (Loader) { int32 NewParam = 1; // Loader->ProcessEvent(NextFn, &NewParam); Loader->ProcessEvent(NewFn, &NewParam); } } if (ImGui::Button("Next")) { static auto NextFn = FindObject("/Game/Athena/Prototype/Blueprints/Cube/CUBE.CUBE_C.Next"); static auto NewFn = FindObject("/Game/Athena/Prototype/Blueprints/Cube/CUBE.CUBE_C.New"); auto Loader = GetEventLoader("/Game/Athena/Prototype/Blueprints/Cube/CUBE.CUBE_C"); LOG_INFO(LogDev, "Loader: {}", __int64(Loader)); if (Loader) { int32 NewParam = 1; Loader->ProcessEvent(NextFn, &NewParam); // Loader->ProcessEvent(NewFn, &NewParam); } } */ if (!bIsInAutoRestart && (Engine_Version < 424 && ImGui::Button("Restart"))) { if (Engine_Version < 424) { Restart(); LOG_INFO(LogGame, "Restarting!"); } else { LOG_ERROR(LogGame, "Restarting is not supported on chapter 2 and above!"); } } /* if (ImGui::Button("TEST")) { auto GameMode = (AFortGameMode*)GetWorld()->GetGameMode(); auto GameState = GameMode->GetGameState(); static auto mutatorClass = FindObject("/Script/FortniteGame.FortAthenaMutator"); auto AllMutators = UGameplayStatics::GetAllActorsOfClass(GetWorld(), mutatorClass); for (int i = 0; i < AllMutators.Num(); i++) { auto Mutator = AllMutators.at(i); LOG_INFO(LogDev, "[{}] Mutator: {}", i, Mutator->GetFullName()); if (auto DiscoMutator = Cast(Mutator)) { auto& ControlPointSpawnData = DiscoMutator->GetControlPointSpawnData(); LOG_INFO(LogDev, "ControlPointSpawnData.Num(): {}", ControlPointSpawnData.Num()); } else if (auto HeistMutator = Cast(Mutator)) { auto& HeistExitCraftSpawnData = HeistMutator->GetHeistExitCraftSpawnData(); LOG_INFO(LogDev, "HeistExitCraftSpawnData.Num(): {}", HeistExitCraftSpawnData.Num()); for (int j = 0; j < HeistExitCraftSpawnData.Num(); j++) { auto& CurrentHeistExitCraftSpawnData = HeistExitCraftSpawnData.at(j); auto CurveTable = CurrentHeistExitCraftSpawnData.SpawnDelayTime.GetCurve().CurveTable; // LOG_INFO(LogDev, "{} {}", CurveTable ? CurveTable->GetFullName() : "InvalidTable", // CurrentHeistExitCraftSpawnData.SpawnDelayTime.GetCurve().RowName.IsValid() ? CurrentHeistExitCraftSpawnData.SpawnDelayTime.GetCurve().RowName.ToString() : "InvalidName"); } } } } */ if (!bStartedBus) { if (Globals::bLateGame.load()) { if (ImGui::Button("Start Bus")) { bStartedBus = true; auto GameMode = (AFortGameMode*)GetWorld()->GetGameMode(); auto GameState = GameMode->GetGameState(); static auto AircraftsOffset = GameState->GetOffset("Aircrafts"); UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"startaircraft", nullptr); while (GameState->GetPtr>(AircraftsOffset)->Num() <= 0) // hmm { Sleep(500); } UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"startsafezone", nullptr); static auto SafeZoneLocationsOffset = GameMode->GetOffset("SafeZoneLocations"); auto& SafeZoneLocations = GameMode->Get>(SafeZoneLocationsOffset); LOG_INFO(LogDev, "SafeZoneLocations.Num(): {}", SafeZoneLocations.Num()); static auto SafeZoneIndicatorOffset = GameState->GetOffset("SafeZoneIndicator"); static auto SafeZonesStartTimeOffset = GameState->GetOffset("SafeZonesStartTime"); GameState->Get(SafeZonesStartTimeOffset) = 0; while (!GameState->Get(SafeZoneIndicatorOffset)) { Sleep(500); } while (GameState->GetPtr>(AircraftsOffset)->Num() <= 0) // hmm { Sleep(500); } static auto NextNextCenterOffset = GameState->Get(SafeZoneIndicatorOffset)->GetOffset("NextNextCenter"); static auto NextCenterOffset = GameState->Get(SafeZoneIndicatorOffset)->GetOffset("NextCenter"); FVector LocationToStartAircraft = GameState->Get(SafeZoneIndicatorOffset)->Get(NextNextCenterOffset); // SafeZoneLocations.at(4); LocationToStartAircraft.Z += 10000; for (int i = 0; i < GameState->GetPtr>(AircraftsOffset)->Num(); i++) { GameState->GetPtr>(AircraftsOffset)->at(i)->TeleportTo(LocationToStartAircraft, FRotator()); static auto FlightInfoOffset = GameState->GetPtr>(AircraftsOffset)->at(i)->GetOffset("FlightInfo"); auto FlightInfo = GameState->GetPtr>(AircraftsOffset)->at(i)->GetPtr(FlightInfoOffset); FlightInfo->GetFlightSpeed() = 0; FlightInfo->GetFlightStartLocation() = LocationToStartAircraft; FlightInfo->GetTimeTillDropStart() = 0.0f; } static auto MapInfoOffset = GameState->GetOffset("MapInfo"); auto MapInfo = GameState->Get(MapInfoOffset); if (MapInfo) { static auto FlightInfosOffset = MapInfo->GetOffset("FlightInfos"); auto& FlightInfos = MapInfo->Get>(FlightInfosOffset); LOG_INFO(LogDev, "FlightInfos.Num(): {}", FlightInfos.Num()); for (int i = 0; i < FlightInfos.Num(); i++) { auto FlightInfo = FlightInfos.AtPtr(i, FAircraftFlightInfo::GetStructSize()); FlightInfo->GetFlightSpeed() = 0; FlightInfo->GetFlightStartLocation() = LocationToStartAircraft; FlightInfo->GetTimeTillDropStart() = 0.0f; } } static auto bAircraftIsLockedOffset = GameState->GetOffset("bAircraftIsLocked"); static auto bAircraftIsLockedFieldMask = GetFieldMask(GameState->GetProperty("bAircraftIsLocked")); GameState->SetBitfieldValue(bAircraftIsLockedOffset, bAircraftIsLockedFieldMask, false); } } else { if (ImGui::Button("Start Bus Countdown")) { bStartedBus = true; auto GameMode = (AFortGameMode*)GetWorld()->GetGameMode(); auto GameState = GameMode->GetGameState(); if (Fortnite_Version == 1.11) { static auto OverrideBattleBusSkin = FindObject("/Game/Athena/Items/Cosmetics/BattleBuses/BBID_WinterBus.BBID_WinterBus"); LOG_INFO(LogDev, "OverrideBattleBusSkin: {}", __int64(OverrideBattleBusSkin)); if (OverrideBattleBusSkin) { static auto AssetManagerOffset = GetEngine()->GetOffset("AssetManager"); auto AssetManager = GetEngine()->Get(AssetManagerOffset); if (AssetManager) { static auto AthenaGameDataOffset = AssetManager->GetOffset("AthenaGameData"); auto AthenaGameData = AssetManager->Get(AthenaGameDataOffset); if (AthenaGameData) { static auto DefaultBattleBusSkinOffset = AthenaGameData->GetOffset("DefaultBattleBusSkin"); AthenaGameData->Get(DefaultBattleBusSkinOffset) = OverrideBattleBusSkin; } } static auto DefaultBattleBusOffset = GameState->GetOffset("DefaultBattleBus"); GameState->Get(DefaultBattleBusOffset) = OverrideBattleBusSkin; static auto FortAthenaAircraftClass = FindObject("/Script/FortniteGame.FortAthenaAircraft"); auto AllAircrafts = UGameplayStatics::GetAllActorsOfClass(GetWorld(), FortAthenaAircraftClass); for (int i = 0; i < AllAircrafts.Num(); i++) { auto Aircraft = AllAircrafts.at(i); static auto DefaultBusSkinOffset = Aircraft->GetOffset("DefaultBusSkin"); Aircraft->Get(DefaultBusSkinOffset) = OverrideBattleBusSkin; static auto SpawnedCosmeticActorOffset = Aircraft->GetOffset("SpawnedCosmeticActor"); auto SpawnedCosmeticActor = Aircraft->Get(SpawnedCosmeticActorOffset); if (SpawnedCosmeticActor) { static auto ActiveSkinOffset = SpawnedCosmeticActor->GetOffset("ActiveSkin"); SpawnedCosmeticActor->Get(ActiveSkinOffset) = OverrideBattleBusSkin; } } } } GameState->Get("WarmupCountdownEndTime") = UGameplayStatics::GetTimeSeconds(GetWorld()) + 10; } } } } } else if (Tab == PLAYERS_TAB) { } else if (Tab == EVENT_TAB) { if (ImGui::Button(std::format("Start {}", GetEventName()).c_str())) { StartEvent(); } if (Fortnite_Version == 8.51) { if (ImGui::Button("Unvault DrumGun")) { static auto SetUnvaultItemNameFn = FindObject("/Game/Athena/Prototype/Blueprints/White/BP_SnowScripting.BP_SnowScripting_C.SetUnvaultItemName"); auto EventScripting = GetEventScripting(); if (EventScripting) { FName Name = UKismetStringLibrary::Conv_StringToName(L"DrumGun"); EventScripting->ProcessEvent(SetUnvaultItemNameFn, &Name); static auto PillarsConcludedFn = FindObject("/Game/Athena/Prototype/Blueprints/White/BP_SnowScripting.BP_SnowScripting_C.PillarsConcluded"); EventScripting->ProcessEvent(PillarsConcludedFn, &Name); } } } } else if (Tab == DUMP_TAB) { ImGui::Text("These will all be in your Win64 folder!"); static std::string FortniteVersionStr = std::format("Fortnite Version {}\n\n", std::to_string(Fortnite_Version)); if (ImGui::Button("Dump Objects")) { auto ObjectNum = ChunkedObjects ? ChunkedObjects->Num() : UnchunkedObjects ? UnchunkedObjects->Num() : 0; std::ofstream obj("ObjectsDump.txt"); obj << FortniteVersionStr; for (int i = 0; i < ObjectNum; i++) { auto CurrentObject = GetObjectByIndex(i); if (!CurrentObject) continue; obj << CurrentObject->GetFullName() << '\n'; } } if (ImGui::Button("Dump Skins (Skins.txt)")) { std::ofstream SkinsFile("Skins.txt"); if (SkinsFile.is_open()) { SkinsFile << FortniteVersionStr; static auto CIDClass = FindObject("/Script/FortniteGame.AthenaCharacterItemDefinition"); auto AllObjects = GetAllObjectsOfClass(CIDClass); for (int i = 0; i < AllObjects.size(); i++) { auto CurrentCID = AllObjects.at(i); static auto DisplayNameOffset = CurrentCID->GetOffset("DisplayName"); FString DisplayNameFStr = UKismetTextLibrary::Conv_TextToString(CurrentCID->Get(DisplayNameOffset)); if (!DisplayNameFStr.Data.Data) continue; SkinsFile << std::format("[{}] {}\n", DisplayNameFStr.ToString(), CurrentCID->GetPathName()); } } } if (ImGui::Button("Dump Playlists (Playlists.txt)")) { std::ofstream PlaylistsFile("Playlists.txt"); if (PlaylistsFile.is_open()) { PlaylistsFile << FortniteVersionStr; static auto FortPlaylistClass = FindObject("/Script/FortniteGame.FortPlaylist"); // static auto FortPlaylistClass = FindObject("Class /Script/FortniteGame.FortPlaylistAthena"); auto AllObjects = GetAllObjectsOfClass(FortPlaylistClass); for (int i = 0; i < AllObjects.size(); i++) { auto Object = AllObjects.at(i); static auto UIDisplayNameOffset = Object->GetOffset("UIDisplayName"); FString PlaylistNameFStr = UKismetTextLibrary::Conv_TextToString(Object->Get(UIDisplayNameOffset)); if (!PlaylistNameFStr.Data.Data) continue; std::string PlaylistName = PlaylistNameFStr.ToString(); PlaylistsFile << std::format("[{}] {}\n", PlaylistName, Object->GetPathName()); } } else std::cout << "Failed to open playlist file!\n"; } if (ImGui::Button("Dump Weapons (Weapons.txt)")) { std::ofstream WeaponsFile("Weapons.txt"); if (WeaponsFile.is_open()) { WeaponsFile << FortniteVersionStr; static auto FortWeaponItemDefinitionClass = FindObject("/Script/FortniteGame.FortWeaponItemDefinition"); auto DumpItemDefinitionClass = [&WeaponsFile](UClass* Class) { auto AllObjects = GetAllObjectsOfClass(Class); for (int i = 0; i < AllObjects.size(); i++) { auto Object = AllObjects.at(i); static auto DisplayNameOffset = Object->GetOffset("DisplayName"); FString ItemDefinitionFStr = UKismetTextLibrary::Conv_TextToString(Object->Get(DisplayNameOffset)); if (!ItemDefinitionFStr.Data.Data) continue; std::string ItemDefinitionName = ItemDefinitionFStr.ToString(); // check if it contains gallery or playset and just ignore? WeaponsFile << std::format("[{}] {}\n", ItemDefinitionName, Object->GetPathName()); } }; DumpItemDefinitionClass(UFortWeaponItemDefinition::StaticClass()); DumpItemDefinitionClass(UFortGadgetItemDefinition::StaticClass()); } else std::cout << "Failed to open playlist file!\n"; } } else if (Tab == UNBAN_TAB) { } else if (Tab == DEVELOPER_TAB) { static std::string ClassNameToDump; static std::string FunctionNameToDump; ImGui::InputText("Class Name to mess with", &ClassNameToDump); ImGui::InputText("Function Name to mess with", &FunctionNameToDump); if (ImGui::Button("Print Class VFT")) { auto Class = FindObject(ClassNameToDump); if (Class) { auto ClassToDump = Class->CreateDefaultObject(); if (ClassToDump) { LOG_INFO(LogDev, "{} VFT: 0x{:x}", ClassToDump->GetName(), __int64(ClassToDump->VFTable) - __int64(GetModuleHandleW(0))); } } } if (ImGui::Button("Print Function Exec Addy")) { auto Function = FindObject(FunctionNameToDump); if (Function) { LOG_INFO(LogDev, "{} Exec: 0x{:x}", Function->GetName(), __int64(Function->GetFunc()) - __int64(GetModuleHandleW(0))); } } /* if (ImGui::Button("Load BGA Class (and spawn so no GC)")) { static auto BGAClass = FindObject("/Script/Engine.BlueprintGeneratedClass"); auto Class = LoadObject(ClassNameToDump, BGAClass); if (Class) { GetWorld()->SpawnActor(Class, FVector()); } } */ /* ImGui::Text(std::format("Amount of hooks {}", AllFunctionHooks.size()).c_str()); for (auto& FunctionHook : AllFunctionHooks) { if (ImGui::Button(std::format("{} {} (0x{:x})", (FunctionHook.IsHooked ? "Unhook" : "Hook"), FunctionHook.Name, (__int64(FunctionHook.Original) - __int64(GetModuleHandleW(0)))).c_str())) { if (FunctionHook.IsHooked) { if (!FunctionHook.VFT || FunctionHook.Index == -1) { Hooking::MinHook::Unhook(FunctionHook.Original); } else { VirtualSwap(FunctionHook.VFT, FunctionHook.Index, FunctionHook.Original); } } else { Hooking::MinHook::Hook(FunctionHook.Original, FunctionHook.Detour, nullptr, FunctionHook.Name); } FunctionHook.IsHooked = !FunctionHook.IsHooked; } } */ } else if (Tab == SETTINGS_TAB) { // ImGui::Checkbox("Use custom lootpool (from Win64/lootpool.txt)", &Defines::bCustomLootpool); } } } static inline void PregameUI() { StaticUI(); if (Engine_Version >= 422 && Engine_Version < 424) { ImGui::Checkbox("Creative", &Globals::bCreative); } bool bWillBeLategame = Globals::bLateGame.load(); ImGui::Checkbox("Lategame", &bWillBeLategame); Globals::bLateGame.store(bWillBeLategame); if (HasEvent()) { ImGui::Checkbox("Play Event", &Globals::bGoingToPlayEvent); } if (!bSwitchedInitialLevel) ImGui::SliderInt("Seconds until load into map", &SecondsUntilTravel, 1, 100); ImGui::InputText("Playlist", &PlaylistName); } static inline DWORD WINAPI GuiThread(LPVOID) { WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, L"RebootClass", NULL }; ::RegisterClassEx(&wc); HWND hwnd = ::CreateWindowExW(0L, wc.lpszClassName, L"Project Reboot", (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX), 100, 100, Width, Height, NULL, NULL, wc.hInstance, NULL); HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, sizeof(reboot_icon_data)); if (!hGlobal) { LOG_WARN(LogDev, "Failed to allocate global icon data!"); } else { void* data = GlobalLock(hGlobal); memcpy(data, reboot_icon_data, sizeof(reboot_icon_data)); GlobalUnlock(hGlobal); IStream* stream; HRESULT hr = CreateStreamOnHGlobal(hGlobal, FALSE, &stream); if (hr != S_OK) { // Handle error } HBITMAP hBitmap{}; HRESULT hr1 = CoInitialize(NULL); hr1 = OleLoadPicture(stream, sizeof(reboot_icon_data), FALSE, IID_IPicture, (void**)&hBitmap); stream->Release(); GlobalFree(hGlobal); CoUninitialize(); if (hr1 != S_OK) { // Handle error } // Create the icon from the bitmap ICONINFO iconInfo{}; iconInfo.fIcon = TRUE; iconInfo.xHotspot = 0; iconInfo.yHotspot = 0; iconInfo.hbmMask = NULL; iconInfo.hbmColor = hBitmap; HICON hIcon = CreateIconIndirect(&iconInfo); SendMessageW(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon); SendMessageW(hwnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon); // Cleanup the resources DeleteObject(iconInfo.hbmColor); } // HANDLE hIcon = LoadImageW(wc.hInstance, L"Reboot Resources/images/reboot.ico", IMAGE_ICON, 48, 48, LR_LOADFROMFILE); // SendMessageW(hwnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon); // SetWindowLongPtrW(hwnd, GWL_STYLE, WS_POPUP); // Disables windows title bar at the cost of dragging and some quality // Initialize Direct3D if (!CreateDeviceD3D(hwnd)) { CleanupDeviceD3D(); ::UnregisterClass(wc.lpszClassName, wc.hInstance); return 1; } // Show the window ::ShowWindow(hwnd, SW_SHOWDEFAULT); ::UpdateWindow(hwnd); // Setup Dear ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; io.IniFilename = NULL; // Disable imgui.ini generation. io.DisplaySize = ImGui::GetMainViewport()->Size; io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls // io.Fonts->AddFontFromFileTTF("../vendor/fonts/Aller_Bd.ttf", 17); // Setup Dear ImGui style InitStyle(); // Setup Platform/Renderer backends ImGui_ImplWin32_Init(hwnd); ImGui_ImplDX9_Init(g_pd3dDevice); // Our state bool show_demo_window = true; bool show_another_window = false; ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); ImFontConfig config; config.MergeMode = true; config.GlyphMinAdvanceX = 13.0f; // Use if you want to make the icon monospaced // static const ImWchar icon_ranges[] = { ICON_MIN_FA, ICON_MAX_FA, 0 }; // io.Fonts->AddFontFromFileTTF("Reboot Resources/fonts/fontawesome-webfont.ttf", 13.0f, &config, icon_ranges); bool done = false; while (!done) { MSG msg; while (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); if (msg.message == WM_QUIT) { // done = true; break; } } ImGui_ImplDX9_NewFrame(); ImGui_ImplWin32_NewFrame(); ImGui::NewFrame(); auto WindowSize = ImGui::GetMainViewport()->Size; // ImGui::SetNextWindowPos(ImVec2(WindowSize.x * 0.5f, WindowSize.y * 0.5f), ImGuiCond_Always, ImVec2(0.5f, 0.5f)); // Center ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always); tagRECT rect; if (GetWindowRect(hwnd, &rect)) { int width = rect.right - rect.left; int height = rect.bottom - rect.top; ImGui::SetNextWindowSize(ImVec2(width, height), ImGuiCond_Always); } if (!ImGui::IsWindowCollapsed()) { ImGui::Begin("Project Reboot 3.0", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoTitleBar); Globals::bInitializedPlaylist ? MainUI() : PregameUI(); ImGui::End(); } // Rendering ImGui::EndFrame(); g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE); g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); D3DCOLOR clear_col_dx = D3DCOLOR_RGBA((int)(clear_color.x * clear_color.w * 255.0f), (int)(clear_color.y * clear_color.w * 255.0f), (int)(clear_color.z * clear_color.w * 255.0f), (int)(clear_color.w * 255.0f)); g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, clear_col_dx, 1.0f, 0); if (g_pd3dDevice->BeginScene() >= 0) { ImGui::Render(); ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData()); g_pd3dDevice->EndScene(); } HRESULT result = g_pd3dDevice->Present(NULL, NULL, NULL, NULL); // Handle loss of D3D9 device if (result == D3DERR_DEVICELOST && g_pd3dDevice->TestCooperativeLevel() == D3DERR_DEVICENOTRESET) ResetDevice(); } ImGui_ImplDX9_Shutdown(); ImGui_ImplWin32_Shutdown(); ImGui::DestroyContext(); CleanupDeviceD3D(); ::DestroyWindow(hwnd); ::UnregisterClass(wc.lpszClassName, wc.hInstance); return 0; } // Helper functions static inline bool CreateDeviceD3D(HWND hWnd) { if ((g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)) == NULL) return false; // Create the D3DDevice ZeroMemory(&g_d3dpp, sizeof(g_d3dpp)); g_d3dpp.Windowed = TRUE; g_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; g_d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; // Need to use an explicit format with alpha if needing per-pixel alpha composition. g_d3dpp.EnableAutoDepthStencil = TRUE; g_d3dpp.AutoDepthStencilFormat = D3DFMT_D16; g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; // Present with vsync //g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; // Present without vsync, maximum unthrottled framerate if (g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &g_d3dpp, &g_pd3dDevice) < 0) return false; return true; } static inline void CleanupDeviceD3D() { if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } if (g_pD3D) { g_pD3D->Release(); g_pD3D = NULL; } } static inline void ResetDevice() { ImGui_ImplDX9_InvalidateDeviceObjects(); HRESULT hr = g_pd3dDevice->Reset(&g_d3dpp); if (hr == D3DERR_INVALIDCALL) IM_ASSERT(0); ImGui_ImplDX9_CreateDeviceObjects(); } extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); static inline LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { // my implementation of window dragging.. /* { static int dababy = 0; if (dababy > 100) // wait until gui is initialized ig? { if (ImGui::IsMouseDragging(ImGuiMouseButton(0))) { // if (LOWORD(lParam) > 255 && HIWORD(lParam) > 255) { POINT p; GetCursorPos(&p); SetWindowPos(hWnd, nullptr, p.x, p.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER); } } } dababy++; } */ if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) { case WM_SIZE: if (g_pd3dDevice != NULL && wParam != SIZE_MINIMIZED) { g_d3dpp.BackBufferWidth = LOWORD(lParam); g_d3dpp.BackBufferHeight = HIWORD(lParam); ResetDevice(); } return 0; case WM_SYSCOMMAND: if ((wParam & 0xfff0) == SC_KEYMENU) // Disable ALT application menu return 0; break; case WM_DESTROY: ::PostQuitMessage(0); return 0; } return ::DefWindowProc(hWnd, msg, wParam, lParam); }