diff --git a/resource/common/locale/English.json b/resource/common/locale/English.json index 0fcaca1..4351835 100644 --- a/resource/common/locale/English.json +++ b/resource/common/locale/English.json @@ -112,6 +112,7 @@ "Author": "Author", "BugDisclaimer": "If you find bugs or have suggestions, let me know on discord.", "Build": "Build", + "CheatMenuNoDir" : "Failed to find CheatMenu directory!", "CheckUpdate": "Check update", "Commands": "Commands", "Config": "Config", @@ -124,6 +125,8 @@ "DiscordServer": "Discord server", "DownloadPage" : "Download page", "EnsureLatest" : "Please ensure you have the latest version from GitHub.", + "DiscordRPCInitFailed": "Failed to init discord rpc", + "DiscordRPCNoDll" : "Failed to find discord-rpc.dll", "FixVehKey": "Fix current vehicle", "FlipVehKey": "Flip current vehicle", "Frames": "Frames: %d", diff --git a/src/cheatmenu.cpp b/src/cheatmenu.cpp index caa1631..bc85613 100644 --- a/src/cheatmenu.cpp +++ b/src/cheatmenu.cpp @@ -79,7 +79,7 @@ void CheatMenu::ProcessPages() ImGuiStyle &style = ImGui::GetStyle(); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); - ImGui::PushFont(FontMgr::GetFont("header")); + ImGui::PushFont(FontMgr::Get("header")); m_nMenuPage = Updater::IsUpdateAvailable() ? eMenuPages::UPDATE : m_nMenuPage; // Check once if it's anniversary day @@ -93,7 +93,7 @@ void CheatMenu::ProcessPages() { /* * We don't want to be annoying and - * show anniversary screen on game start + * show anniversary screen on every game start */ bool flag = gConfig.GetValue("window.anniversaryShown", false); @@ -116,7 +116,9 @@ void CheatMenu::ProcessPages() if (m_headerList[i].skipHeader) { if (m_nMenuPage == m_headerList[i].page) + { pCallback = m_headerList[i].pFunc; + } continue; } @@ -161,7 +163,9 @@ void CheatMenu::ProcessPages() ImGui::RenderTextClipped(min + style.FramePadding, max - style.FramePadding, text, NULL, &size, style.ButtonTextAlign); if (i % 3 != 2) + { ImGui::SameLine(); + } } ImGui::PopFont(); ImGui::PopStyleVar(); @@ -195,6 +199,12 @@ void CheatMenu::GenHeaderList() void CheatMenu::Init() { + if (!std::filesystem::exists(PLUGIN_PATH((char*)"CheatMenu"))) + { + gLog << TEXT("Menu.CheatMenuNoDir") << std::endl; + return; + } + if (!D3dHook::InjectHook(DrawWindow)) { return; @@ -255,7 +265,7 @@ void CheatMenu::Init() } /* -* YIKES YOU AREN"T SUPPOSED TO FIND THIS YOU KNOW!!! +* YIKES YOU AREN"T SUPPOSED TO FIND THIS!!! * Probably a good easter egg for the upcoming anniversary ;) */ void CheatMenu::ShowAnniversaryPage() diff --git a/src/cheatmenu.h b/src/cheatmenu.h index 5ada8a0..c2e727e 100644 --- a/src/cheatmenu.h +++ b/src/cheatmenu.h @@ -1,16 +1,10 @@ -/* - Author: Grinch_ - Copyright Grinch_ 2019-2022. All rights reserved. - Required: - DirectX 9 SDK - Plugin SDK - Build Tools 2022 (v143) - Windows SDK -*/ - #pragma once #include "pch.h" +/* +* Main CheatMenu Class +* Handles rendering, resizing, page handling etc. +*/ class CheatMenu { private: @@ -26,17 +20,24 @@ private: bool skipHeader = false; }; - static inline eMenuPages m_nMenuPage = eMenuPages::WELCOME; + static inline eMenuPages m_nMenuPage = eMenuPages::WELCOME; // current visible menu page static inline bool m_bShowMenu = false; static inline ImVec2 m_fMenuSize = ImVec2(screen::GetScreenWidth() / 4, screen::GetScreenHeight() / 1.2); - static inline bool m_bSizeChangedExternal = false; + static inline bool m_bSizeChangedExternal = false; // Was menu size change requested static inline std::vector m_headerList; + // Applies imgui theme to the menu static void ApplyStyle(); + + // Draws the window ui each frame + // Also handles drawing overlay & command window static void DrawWindow(); + static void ShowAnniversaryPage(); static void ShowUpdatePage(); static void ShowWelcomePage(); + + // Does all the processing required to handle menu pages static void ProcessPages(); public: @@ -46,5 +47,8 @@ public: static void Init(); static bool IsMenuShown(); static void ResetMenuSize(); + + // Generates menu headers + // Needs to be called after language change or adding new headers static void GenHeaderList(); }; diff --git a/src/d3dhook.cpp b/src/d3dhook.cpp index b302ed0..781a265 100644 --- a/src/d3dhook.cpp +++ b/src/d3dhook.cpp @@ -60,7 +60,7 @@ void D3dHook::ProcessFrame(void* ptr) ImVec2 size(screen::GetScreenWidth(), screen::GetScreenHeight()); if (fScreenSize.x != size.x && fScreenSize.y != size.y) { - FontMgr::ReloadFonts(); + FontMgr::ReloadAll(); if (gRenderer == Render_DirectX9) { @@ -139,9 +139,9 @@ void D3dHook::ProcessFrame(void* ptr) ImGui_ImplWin32_EnableDpiAwareness(); // Loading fonts - io.FontDefault = FontMgr::LoadFont("text", 1.0f); - FontMgr::LoadFont("title", 2.0f); - FontMgr::LoadFont("header", 1.25f); + io.FontDefault = FontMgr::Load("text", 1.0f); + FontMgr::Load("title", 2.0f); + FontMgr::Load("header", 1.25f); io.IniFilename = nullptr; io.LogFilename = nullptr; diff --git a/src/d3dhook.h b/src/d3dhook.h index 5fefd5c..eaef9ef 100644 --- a/src/d3dhook.h +++ b/src/d3dhook.h @@ -1,6 +1,10 @@ #pragma once #include "pch.h" +/* +* DirectX Hooking Class +* Supports DX9 & DX11 +*/ class D3dHook { private: @@ -15,7 +19,6 @@ private: static inline bool mouseShown; static inline void* pCallbackFunc = nullptr; - static void CALLBACK ProcessFrame(void* ptr); static LRESULT CALLBACK hkWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); static void ProcessMouse(); diff --git a/src/fontmgr.cpp b/src/fontmgr.cpp index 1c3dce8..f91b1e3 100644 --- a/src/fontmgr.cpp +++ b/src/fontmgr.cpp @@ -1,11 +1,11 @@ #include "fontmgr.h" #include "pch.h" -ImFont* FontMgr::GetFont(const char* fontName) +ImFont* FontMgr::Get(const char* fontName) { for (auto &data : m_vecFonts) { - if (data.m_path == std::string(fontName)) + if (!strcmp(data.m_path.c_str(), fontName)) { return data.m_pFont; } @@ -14,27 +14,27 @@ ImFont* FontMgr::GetFont(const char* fontName) return nullptr; } -ImFont* FontMgr::LoadFont(const char* fontName, float fontMul) +ImFont* FontMgr::Load(const char* fontName, float fontMul) { ImGuiIO& io = ImGui::GetIO(); size_t fontSize = static_cast(screen::GetScreenHeight() / 54.85f) * fontMul; - - std::string fullPath = std::string(PLUGIN_PATH((char*)"CheatMenu/fonts/")) + fontName + ".ttf"; - m_vecFonts.push_back({io.Fonts->AddFontFromFileTTF(fullPath.c_str(), fontSize), fontSize, fontMul, - std::string(fontName)}); + std::string fullPath = std::format("{}{}.ttf", PLUGIN_PATH((char*)"CheatMenu/fonts/"), fontName); + ImFont *pFont = io.Fonts->AddFontFromFileTTF(fullPath.c_str(), fontSize); + + m_vecFonts.push_back({pFont, fontSize, fontMul, std::string(fontName)}); io.Fonts->Build(); - return m_vecFonts.back().m_pFont; + return pFont; } -void FontMgr::UnloadFonts() +void FontMgr::UnloadAll() { ImGui::GetIO().Fonts->Clear(); } -void FontMgr::ReloadFonts() +void FontMgr::ReloadAll() { - UnloadFonts(); + UnloadAll(); ImGuiIO& io = ImGui::GetIO(); for (auto &data : m_vecFonts) @@ -43,6 +43,6 @@ void FontMgr::ReloadFonts() std::string fullPath = PLUGIN_PATH((char*)"CheatMenu/fonts/") + data.m_path + ".ttf"; data.m_pFont = io.Fonts->AddFontFromFileTTF(fullPath.c_str(), data.m_nSize); } - io.FontDefault = GetFont("text"); + io.FontDefault = Get("text"); io.Fonts->Build(); } \ No newline at end of file diff --git a/src/fontmgr.h b/src/fontmgr.h index 8979f2c..6776352 100644 --- a/src/fontmgr.h +++ b/src/fontmgr.h @@ -1,7 +1,7 @@ #pragma once /* - Font Manager class + Font Manager Class Handles loading, fetching, freeing & reloading fonts */ class FontMgr @@ -20,12 +20,18 @@ public: FontMgr() = delete; FontMgr(FontMgr&) = delete; - static ImFont* GetFont(const char* fontName); - static ImFont* LoadFont(const char* fontName, float fontMul = 1.0f); + // Returns font pointer from name + static ImFont* Get(const char* fontName); + // Loads a font into memory + static ImFont* Load(const char* fontName, float fontMul = 1.0f); + + // Unloads all the loaded fonts from fontmgr // ImGui::GetIO().Default font must be loaded after unloading all fonts - static void UnloadFonts(); - static void ReloadFonts(); + static void UnloadAll(); + + // Reloads all the fonts + static void ReloadAll(); }; diff --git a/src/game.cpp b/src/game.cpp index e4a0df4..dec5578 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -290,7 +290,7 @@ void Game::FreeCam() m_Freecam::m_fTotalMouse.y = -150; } - if (KeyPressed(VK_RETURN)) + if (freeCamTeleport.Pressed()) { CPlayerPed* player = FindPlayerPed(); CVector pos = m_Freecam::m_pPed->GetPosition(); diff --git a/src/hotkeys.cpp b/src/hotkeys.cpp index 98d821d..d7cf658 100644 --- a/src/hotkeys.cpp +++ b/src/hotkeys.cpp @@ -4,6 +4,176 @@ const size_t HOTKEY_START = 3; const size_t HOTKEY_END = 135; +static std::string key_names[] +{ + "LMB", + "RMB", + "Cancel", + "MMB", + "X1MB", + "X2MB", + "Unknown1", + "Back", + "Tab", + "Reserved1", + "Reserved2", + "Clear", + "Enter", + "Unknown2", + "Unknown3", + "Shift", + "Ctrl", + "Alt", + "Pause", + "Capslock", + "IME", + "IME2", + "IME3", + "Unknown4", + "IME4", + "Unknown5", + "Esc", + "IME5" + "IME6", + "IME7", + "IME8", + "IME9", + "Space", + "Pup", + "Pdown", + "End", + "Home", + "Left", + "Up", + "Right", + "Down", + "Select", + "Print", + "Execute", + "Print Screen", + "INS", + "Del", + "Help", + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "Unknown6", + "Unknown7", + "Unknown8", + "Unknown9", + "Unknown10", + "Unknown11", + "Unknown12", + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H", + "I", + "J", + "K", + "L", + "M", + "N", + "O", + "P", + "Q", + "R", + "S", + "T", + "U", + "V", + "W", + "X", + "Y", + "Z", + "LWin", + "RWin", + "Apps", + "Unknown11", + "Sleep", + "Numpad 0", + "Numpad 1", + "Numpad 2", + "Numpad 3", + "Numpad 4", + "Numpad 5", + "Numpad 6", + "Numpad 7", + "Numpad 8", + "Numpad 9", + "Multiply", + "Add", + "Separator", + "Substract", + "Decimal", + "Divide", + "F1", + "F2", + "F3", + "F4", + "F5", + "F6", + "F7", + "F8", + "F9", + "F10", + "F11", + "F12", + "F13", + "F14", + "F15", + "F16", + "F17", + "F18", + "F19", + "F20", + "F21", + "F22", + "F23", + "F24", + "Unknown12", + "Unknown13", + "Unknown14", + "Unknown15", + "Unknown16", + "Unknown17", + "Unknown18", + "Numlock", + "Scroll", + "Unknown19", + "Unknown20", + "Unknown21", + "Unknown22", + "Unknown23", + "Unknown24", + "Unknown25", + "Unknown26", + "Unknown27", + "Unknown28", + "Unknown29", + "Unknown30", + "Unknown31", + "Unknown32", + "Unknown33", + "LShift", + "RShift", + "LCtrl", + "RCtrl", + "LMenu", + "RMenu" +}; + Hotkey::Hotkey(int key1, int key2, const std::string& configPath) : m_key1(key1), m_key2(key2), m_ConfigPath("Hotkeys." + configPath) { diff --git a/src/hotkeys.h b/src/hotkeys.h index 6ae281b..bd1de52 100644 --- a/src/hotkeys.h +++ b/src/hotkeys.h @@ -1,6 +1,44 @@ #pragma once #include +const int VK_NONE = -1; +const size_t VK_KEY_0 = 0x30; +const size_t VK_KEY_1 = 0x31; +const size_t VK_KEY_2 = 0x32; +const size_t VK_KEY_3 = 0x33; +const size_t VK_KEY_4 = 0x34; +const size_t VK_KEY_5 = 0x35; +const size_t VK_KEY_6 = 0x36; +const size_t VK_KEY_7 = 0x37; +const size_t VK_KEY_8 = 0x38; +const size_t VK_KEY_9 = 0x39; +const size_t VK_KEY_A = 0x41; +const size_t VK_KEY_B = 0x42; +const size_t VK_KEY_C = 0x43; +const size_t VK_KEY_D = 0x44; +const size_t VK_KEY_E = 0x45; +const size_t VK_KEY_F = 0x46; +const size_t VK_KEY_G = 0x47; +const size_t VK_KEY_H = 0x48; +const size_t VK_KEY_I = 0x49; +const size_t VK_KEY_J = 0x4A; +const size_t VK_KEY_K = 0x4B; +const size_t VK_KEY_L = 0x4C; +const size_t VK_KEY_M = 0x4D; +const size_t VK_KEY_N = 0x4E; +const size_t VK_KEY_O = 0x4F; +const size_t VK_KEY_P = 0x50; +const size_t VK_KEY_Q = 0x51; +const size_t VK_KEY_R = 0x52; +const size_t VK_KEY_S = 0x53; +const size_t VK_KEY_T = 0x54; +const size_t VK_KEY_U = 0x55; +const size_t VK_KEY_V = 0x56; +const size_t VK_KEY_W = 0x57; +const size_t VK_KEY_X = 0x58; +const size_t VK_KEY_Y = 0x59; +const size_t VK_KEY_Z = 0x5A; + /* HotKey Implementation Class Handles events, save-load, name-fetch, ui etc. diff --git a/src/neon.cpp b/src/neon.cpp index 16a49d1..9be0cea 100644 --- a/src/neon.cpp +++ b/src/neon.cpp @@ -259,13 +259,13 @@ void Neon::SetPulsing(CVehicle* pVeh, bool state) m_VehNeon.Get(pVeh).m_bPulsing = state; } -void Neon::Install(CVehicle* pVeh, int red, int green, int blue) +void Neon::Install(CVehicle* pVeh, int r, int g, int b) { CRGBA& color = m_VehNeon.Get(pVeh).m_Color; - color.r = red; - color.g = green; - color.b = blue; + color.r = r; + color.g = g; + color.b = b; color.a = 255; m_VehNeon.Get(pVeh).m_bNeonInstalled = true; diff --git a/src/neon.h b/src/neon.h index fe54f8f..915b67a 100644 --- a/src/neon.h +++ b/src/neon.h @@ -35,11 +35,24 @@ public: Neon() = delete; Neon(Neon&) = delete; + // Injects necessary hooks into the game static void InjectHooks(); - static void Install(CVehicle* veh, int red, int green, int blue); + + // Installs neons with color + static void Install(CVehicle* veh, int r, int g, int b); + + // Is neon installer for particular vehicle static bool IsInstalled(CVehicle* veh); + + // Is neon pulsing enabled for vehicle static bool IsPulsingEnabled(CVehicle* veh); + + // Set neon pulsing state static void SetPulsing(CVehicle* veh, bool state); + + // Removes the neon game hooks static void RemoveHooks(); + + // Removes neon from vehicle static void Remove(CVehicle* veh); }; diff --git a/src/pch.cpp b/src/pch.cpp index c7edae7..8263322 100644 --- a/src/pch.cpp +++ b/src/pch.cpp @@ -8,7 +8,8 @@ Hotkey freeCam {VK_F6, VK_F6, "Freecam.Toggle"}; Hotkey freeCamForward {VK_KEY_I, VK_KEY_I, "Freecam.Forward"};; Hotkey freeCamBackward {VK_KEY_K, VK_KEY_K, "Freecam.Backward"};; Hotkey freeCamLeft {VK_KEY_J, VK_KEY_J, "Freecam.Left"};; -Hotkey freeCamRight {VK_KEY_L, VK_KEY_L, "Freecam.Right"};; +Hotkey freeCamRight {VK_KEY_L, VK_KEY_L, "Freecam.Right"}; +Hotkey freeCamTeleport {VK_RETURN, VK_RETURN, "Freecam.Teleport"}; Hotkey commandWindow {VK_LCONTROL, VK_KEY_C, "CommandWindowToggle"};; Hotkey fixVeh {VK_NONE, VK_NONE, "Vehicle.Fix"}; Hotkey flipVeh {VK_NONE, VK_NONE, "Vehicle.Flip"}; diff --git a/src/pch.h b/src/pch.h index 0896ad0..6ba03f2 100644 --- a/src/pch.h +++ b/src/pch.h @@ -71,7 +71,6 @@ #include "json.h" #include "hotkeys.h" -#include "vkeys.h" #include "resourcestore.h" #include "fontmgr.h" #include "locale.h" @@ -114,6 +113,7 @@ extern Hotkey freeCamForward; extern Hotkey freeCamBackward; extern Hotkey freeCamLeft; extern Hotkey freeCamRight; +extern Hotkey freeCamTeleport; extern Hotkey commandWindow; extern Hotkey fixVeh; extern Hotkey flipVeh; diff --git a/src/resourcestore.cpp b/src/resourcestore.cpp index a212837..fe9f6ed 100644 --- a/src/resourcestore.cpp +++ b/src/resourcestore.cpp @@ -5,8 +5,7 @@ ResourceStore::ResourceStore(const char* text, eResourceType type, ImVec2 imageSize) : m_ImageSize(imageSize) { - if (type == eResourceType::TYPE_TEXT - || type == eResourceType::TYPE_BOTH) + if (type == eResourceType::TYPE_TEXT || type == eResourceType::TYPE_BOTH) { m_pJson = std::make_unique(text); @@ -20,12 +19,14 @@ ResourceStore::ResourceStore(const char* text, eResourceType type, ImVec2 imageS } } - if (type == eResourceType::TYPE_IMAGE - || type == eResourceType::TYPE_BOTH) + if (type == eResourceType::TYPE_IMAGE || type == eResourceType::TYPE_BOTH) { /* Textures need to be loaded from main thread Loading it directly here doesn't work + TODO: + Maybe enabling a dx9 flag fixes this? + Switch to initScriptsEvent */ Events::processScriptsEvent += [text, this]() { @@ -38,7 +39,8 @@ ResourceStore::ResourceStore(const char* text, eResourceType type, ImVec2 imageS } } -static void* GetTextureFromRaster(RwTexture* pTexture) +// Get dx9 texture object from RwTexture* +static IDirect3DTexture9** GetTextureFromRaster(RwTexture* pTexture) { RwRasterEx* raster = (RwRasterEx*)(&pTexture->raster->parent); diff --git a/src/resourcestore.h b/src/resourcestore.h index 72fd67c..ba1b06f 100644 --- a/src/resourcestore.h +++ b/src/resourcestore.h @@ -4,10 +4,6 @@ #include "../depend/imgui/imgui.h" #include "d3d9.h" -/* - Global resource handler class - Handles both image and json resources -*/ struct RwD3D9Raster { union @@ -47,10 +43,14 @@ enum eResourceType TYPE_BOTH, }; -using TextureResourceList = std::vector>; +/* + Global Resource Handler Class + Handles loading & unloading both text (json) & image files +*/ class ResourceStore { private: + // Loads a image texture from it's path void LoadTextureResource(std::string&& path); public: @@ -58,7 +58,7 @@ public: std::vector m_Categories = {"All"}; std::string m_Selected = "All"; std::unique_ptr m_pJson; - TextureResourceList m_ImagesList; + std::vector> m_ImagesList; ImVec2 m_ImageSize; bool m_bTexturesLoaded = false; diff --git a/src/rpc.cpp b/src/rpc.cpp index 5ec3dc7..1f33292 100644 --- a/src/rpc.cpp +++ b/src/rpc.cpp @@ -5,7 +5,10 @@ #include "vehicle.h" #include "cheatmenu.h" -char asciitolower(char in) +// discord server ids +const char* id = BY_GAME("951199292981403669", "951448264195059712", "951457540573655080"); + +static char asciitolower(char in) { if (in <= 'Z' && in >= 'A') { @@ -19,13 +22,20 @@ void RPC::Shutdown() { if (f_ShutDown) { - CallDyn<>(int(f_ShutDown)); + CallDyn<>(reinterpret_cast(f_ShutDown)); } } void RPC::Init() { - std::string Id = BY_GAME("951199292981403669", "951448264195059712", "951457540573655080"); + const char* dllPath = PLUGIN_PATH((char*)"CheatMenu/dlls/discord-rpc.dll"); + + // check if the dll exits + if (!std::filesystem::exists(dllPath)) + { + gLog << TEXT("Menu.DiscordRPCNoDll") << std::endl; + return; + } if (!hDll) { @@ -34,7 +44,7 @@ void RPC::Init() f_Update = NULL; f_ShutDown = NULL; - hDll = LoadLibrary(PLUGIN_PATH((char*)"CheatMenu/dlls/discord-rpc.dll")); + hDll = LoadLibrary(dllPath); if (hDll) { @@ -46,13 +56,13 @@ void RPC::Init() if (f_Init) { - CallDyn((int)f_Init, Id.c_str(), NULL, NULL, NULL); + CallDyn((int)f_Init, id, NULL, NULL, NULL); drpc.startTimestamp = time(0); bInit = true; } else { - gLog << "Failed to init discord rpc" << std::endl; + gLog << TEXT("Menu.DiscordRPCInitFailed") << std::endl; } } diff --git a/src/rpc.h b/src/rpc.h index 7028cf3..d85ad75 100644 --- a/src/rpc.h +++ b/src/rpc.h @@ -1,9 +1,13 @@ #pragma once +/* +* Discord Rich Presence Class +* Handles connection with discord +*/ class RPC { private: - typedef struct + struct DiscordRichPresence { const char* state; const char* details; @@ -20,7 +24,7 @@ private: const char* joinSecret; const char* spectateSecret; char instance; - } DiscordRichPresence; + }; static inline FARPROC f_Init, f_ShutDown, f_Update; static inline DiscordRichPresence drpc; diff --git a/src/ui.cpp b/src/ui.cpp index 12079f0..d66ba41 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -11,7 +11,7 @@ bool Ui::DrawTitleBar() ImGuiWindow* window = g.CurrentWindow; ImGuiID id = window->GetID("#CLOSE"); - ImGui::PushFont(FontMgr::GetFont("title")); + ImGui::PushFont(FontMgr::Get("title")); CenterdText(MENU_TITLE); if (!ImGui::IsWindowHovered(ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows @@ -792,10 +792,14 @@ void Ui::EditBits(const char* label, const int address, const std::vector