mirror of
https://github.com/Milxnor/Project-Reboot-3.0.git
synced 2026-01-13 02:42:22 +01:00
fix pickup notifications, fix 1.11 crash, remove pickup notifications (to fix restarting and random crashes), fix s7 crash, add delay before switching level, fix some issues with gadgets, fix character parts being buggy.
898 lines
26 KiB
C++
898 lines
26 KiB
C++
#pragma once
|
|
|
|
// TODO: Update ImGUI
|
|
|
|
#pragma comment(lib, "d3d9.lib")
|
|
|
|
#include <Windows.h>
|
|
#include <dxgi.h>
|
|
#include <d3d11.h>
|
|
#include <d3d9.h>
|
|
|
|
#include <ImGui/imgui.h>
|
|
#include <ImGui/imgui_impl_dx9.h>
|
|
|
|
#include <string>
|
|
#include <imgui/imgui_impl_win32.h>
|
|
#include <imgui/imgui_stdlib.h>
|
|
#include <vector>
|
|
#include <format>
|
|
#include <imgui/imgui_internal.h>
|
|
#include <set>
|
|
#include <fstream>
|
|
#include <olectl.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 <Images/reboot_icon.h>
|
|
#include "FortGadgetItemDefinition.h"
|
|
#include "FortWeaponItemDefinition.h"
|
|
#include "events.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 SETTINGS_TAB 9
|
|
#define CREDITS_TAB 10
|
|
|
|
#define MAIN_PLAYERTAB 1
|
|
#define INVENTORY_PLAYERTAB 2
|
|
#define LOADOUT_PLAYERTAB 4
|
|
#define FUN_PLAYERTAB 5
|
|
|
|
static inline int SecondsUntilTravel = 5;
|
|
|
|
// THE BASE CODE IS FROM IMGUI GITHUB
|
|
|
|
static LPDIRECT3D9 g_pD3D = NULL;
|
|
static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;
|
|
static D3DPRESENT_PARAMETERS g_d3dpp = {};
|
|
|
|
// Forward declarations of helper functions
|
|
bool CreateDeviceD3D(HWND hWnd);
|
|
void CleanupDeviceD3D();
|
|
void ResetDevice();
|
|
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
|
|
|
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<int>(str.size()), nullptr, 0, nullptr, nullptr);
|
|
std::string str_to(size_needed, 0);
|
|
WideCharToMultiByte(CP_UTF8, 0, &str[0], static_cast<int>(str.size()), &str_to[0], size_needed, nullptr, nullptr);
|
|
return str_to;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
class Playera
|
|
{
|
|
public:
|
|
std::string Name;
|
|
int Kills = 0;
|
|
|
|
Playera(const std::string& _Name, int _Kills) : Name(_Name), Kills(_Kills) {}
|
|
|
|
Playera() {}
|
|
};
|
|
|
|
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();
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
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;
|
|
|
|
void StaticUI()
|
|
{
|
|
ImGui::Checkbox("No MCP (Don't change unless you know what this is)", &Globals::bNoMCP);
|
|
|
|
if (Addresses::ApplyGadgetData && Addresses::RemoveGadgetData)
|
|
{
|
|
ImGui::Checkbox("Enable AGIDs (Don't change unless you know what this is)", &Globals::bEnableAGIDs);
|
|
}
|
|
}
|
|
|
|
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?
|
|
|
|
if (false && ImGui::BeginTabItem(("Credits")))
|
|
{
|
|
Tab = CREDITS_TAB;
|
|
PlayerTab = -1;
|
|
bInformationTab = false;
|
|
ImGui::EndTabItem();
|
|
}
|
|
|
|
ImGui::EndTabBar();
|
|
}
|
|
}
|
|
|
|
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();
|
|
}
|
|
}
|
|
|
|
void MainUI()
|
|
{
|
|
bool bLoaded = true;
|
|
|
|
if (PlayerTab == -1)
|
|
{
|
|
MainTabs();
|
|
|
|
if (Tab == GAME_TAB)
|
|
{
|
|
if (bLoaded)
|
|
{
|
|
StaticUI();
|
|
#ifndef PROD
|
|
ImGui::Checkbox("Log ProcessEvent", &Globals::bLogProcessEvent);
|
|
#endif
|
|
ImGui::Text(std::format("Listening {}", 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("Restart"))
|
|
{
|
|
if (Engine_Version < 424)
|
|
{
|
|
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<UClass>(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();
|
|
|
|
LOG_INFO(LogDev, "Switching!");
|
|
((AGameMode*)GetWorld()->GetGameMode())->RestartGame();
|
|
// UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), LevelA, nullptr);
|
|
// UGameplayStatics::OpenLevel(GetWorld(), UKismetStringLibrary::Conv_StringToName(LevelA), true, FString());
|
|
LOG_INFO(LogGame, "Restarting!");
|
|
Globals::bInitializedPlaylist = false;
|
|
Globals::bStartedListening = false;
|
|
Globals::bHitReadyToStartMatch = false;
|
|
AmountOfRestarts++;
|
|
}
|
|
else
|
|
{
|
|
LOG_ERROR(LogGame, "Restarting is not supported on chapter 2 and above!");
|
|
}
|
|
}
|
|
|
|
if (ImGui::Button("Start Bus Countdown"))
|
|
{
|
|
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<UClass>("/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<AActor*>(SpawnedCosmeticActorOffset);
|
|
|
|
if (SpawnedCosmeticActor)
|
|
{
|
|
static auto ActiveSkinOffset = SpawnedCosmeticActor->GetOffset("ActiveSkin");
|
|
SpawnedCosmeticActor->Get(ActiveSkinOffset) = OverrideBattleBusSkin;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
GameState->Get<float>("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();
|
|
}
|
|
}
|
|
|
|
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<UClass>("/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<FText>(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<UClass>("/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<FText>(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<UClass>("/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<FText>(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 == SETTINGS_TAB)
|
|
{
|
|
// ImGui::Checkbox("Use custom lootpool (from Win64/lootpool.txt)", &Defines::bCustomLootpool);
|
|
}
|
|
}
|
|
}
|
|
|
|
void PregameUI()
|
|
{
|
|
StaticUI();
|
|
|
|
if (Engine_Version >= 422 && Engine_Version < 424)
|
|
{
|
|
ImGui::Checkbox("Creative", &Globals::bCreative);
|
|
}
|
|
|
|
ImGui::Checkbox("Lategame", &Globals::bLateGame);
|
|
|
|
if (HasEvent())
|
|
{
|
|
ImGui::Checkbox("Play Event", &Globals::bGoingToPlayEvent);
|
|
}
|
|
|
|
ImGui::SliderInt("Seconds until load into map", &SecondsUntilTravel, 1, 100);
|
|
ImGui::InputText("Playlist", &PlaylistName);
|
|
}
|
|
|
|
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
|
|
|
|
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;
|
|
}
|
|
|
|
void CleanupDeviceD3D()
|
|
{
|
|
if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; }
|
|
if (g_pD3D) { g_pD3D->Release(); g_pD3D = NULL; }
|
|
}
|
|
|
|
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);
|
|
|
|
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);
|
|
} |