diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 6db4aa9b..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "GTA5.exe Attach", - "type": "cppvsdbg", - "request": "attach", - "processId": "${command:pickProcess}" - } - ] -} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index f9e4b76f..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,99 +0,0 @@ -{ - "files.associations": { - "*.c": "c", - "string_view": "cpp", - "algorithm": "cpp", - "atomic": "cpp", - "bit": "cpp", - "cctype": "cpp", - "charconv": "cpp", - "chrono": "cpp", - "clocale": "cpp", - "cmath": "cpp", - "compare": "cpp", - "concepts": "cpp", - "cstddef": "cpp", - "cstdint": "cpp", - "cstdio": "cpp", - "cstdlib": "cpp", - "cstring": "cpp", - "ctime": "cpp", - "cwchar": "cpp", - "exception": "cpp", - "format": "cpp", - "forward_list": "cpp", - "initializer_list": "cpp", - "iomanip": "cpp", - "ios": "cpp", - "iosfwd": "cpp", - "istream": "cpp", - "iterator": "cpp", - "limits": "cpp", - "locale": "cpp", - "memory": "cpp", - "mutex": "cpp", - "new": "cpp", - "optional": "cpp", - "ostream": "cpp", - "ratio": "cpp", - "sstream": "cpp", - "stdexcept": "cpp", - "stop_token": "cpp", - "streambuf": "cpp", - "string": "cpp", - "system_error": "cpp", - "thread": "cpp", - "tuple": "cpp", - "type_traits": "cpp", - "typeinfo": "cpp", - "utility": "cpp", - "vector": "cpp", - "xfacet": "cpp", - "xiosbase": "cpp", - "xlocale": "cpp", - "xlocbuf": "cpp", - "xlocinfo": "cpp", - "xlocmes": "cpp", - "xlocmon": "cpp", - "xlocnum": "cpp", - "xloctime": "cpp", - "xmemory": "cpp", - "xstddef": "cpp", - "xstring": "cpp", - "xtr1common": "cpp", - "xutility": "cpp", - "array": "cpp", - "condition_variable": "cpp", - "deque": "cpp", - "fstream": "cpp", - "functional": "cpp", - "iostream": "cpp", - "list": "cpp", - "queue": "cpp", - "ranges": "cpp", - "source_location": "cpp", - "span": "cpp", - "unordered_map": "cpp", - "xhash": "cpp", - "filesystem": "cpp", - "any": "cpp", - "csignal": "cpp", - "cstdarg": "cpp", - "future": "cpp", - "map": "cpp", - "numeric": "cpp", - "random": "cpp", - "regex": "cpp", - "set": "cpp", - "unordered_set": "cpp", - "valarray": "cpp", - "variant": "cpp", - "xtree": "cpp", - "codecvt": "cpp", - "coroutine": "cpp", - "resumable": "cpp", - "stack": "cpp" - }, - "C_Cpp.default.configurationProvider": "maxmitti.cmake-tools-fork", - "C_Cpp.errorSquiggles": "disabled" -} \ No newline at end of file diff --git a/README.md b/README.md index 6bfa1617..6c426d28 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Terminus (formerly HorseMenu) +# Terminus A mod menu for Red Dead Redemption 2 and Red Dead Online published by Rockstar Games. Strictly for educational purposes. @@ -15,6 +15,6 @@ Use a popular injector (Xenos/Extreme Injector/Etc.) and inject into rdr2.exe ## Screenshots / UI Design -![image](https://github.com/YimMenu/HorseMenu/assets/24372625/e1395e75-7feb-4c4a-9286-bd774e2aaeca) +![image](https://github.com/user-attachments/assets/789fc002-b258-40b1-a482-f188e557e2d8) diff --git a/src/game/backend/PlayerDatabase.hpp b/src/game/backend/PlayerDatabase.hpp index ff4af842..b7de6e63 100644 --- a/src/game/backend/PlayerDatabase.hpp +++ b/src/game/backend/PlayerDatabase.hpp @@ -66,9 +66,10 @@ namespace YimMenu bool is_admin = false; bool block_join = false; bool trust = false; + std::string notes = ""; std::unordered_set infractions; - NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(persistent_player, rid, name, is_modder, is_admin, block_join, trust, infractions); + NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(persistent_player, rid, name, is_modder, is_admin, block_join, trust, notes, infractions); }; diff --git a/src/game/frontend/ColorCustomization.cpp b/src/game/frontend/ColorCustomization.cpp new file mode 100644 index 00000000..6def2b8f --- /dev/null +++ b/src/game/frontend/ColorCustomization.cpp @@ -0,0 +1,87 @@ +#include "ColorCustomization.hpp" +#include + +namespace YimMenu::ColorCustomization +{ + // Default colors from Menu::SetupStyle() + ColorCommand _MenuWindowBg("menu_window_bg", "Window Background", "Changes the window background color", ImVec4{0.13f, 0.14f, 0.15f, 1.00f}); + ColorCommand _MenuChildBg("menu_child_bg", "Panel Background", "Changes the panel background color", ImVec4{0.13f, 0.14f, 0.15f, 1.00f}); + ColorCommand _MenuTextColor("menu_text_color", "Text Color", "Changes the text color", ImVec4{1.00f, 1.00f, 1.00f, 1.00f}); + ColorCommand _MenuButtonColor("menu_button_color", "Button Color", "Changes the button color", ImVec4{0.25f, 0.25f, 0.25f, 1.00f}); + ColorCommand _MenuButtonHovered("menu_button_hovered", "Button Hovered", "Changes the button hover color", ImVec4{0.38f, 0.38f, 0.38f, 1.00f}); + ColorCommand _MenuButtonActive("menu_button_active", "Button Active", "Changes the button active color", ImVec4{0.67f, 0.67f, 0.67f, 0.39f}); + ColorCommand _MenuBorderColor("menu_border_color", "Border Color", "Changes the border color", ImVec4{0.43f, 0.43f, 0.50f, 0.50f}); + + void ApplyMenuColors() + { + auto& style = ImGui::GetStyle(); + style.Colors[ImGuiCol_WindowBg] = _MenuWindowBg.GetState(); + style.Colors[ImGuiCol_ChildBg] = _MenuChildBg.GetState(); + style.Colors[ImGuiCol_Text] = _MenuTextColor.GetState(); + style.Colors[ImGuiCol_Button] = _MenuButtonColor.GetState(); + style.Colors[ImGuiCol_ButtonHovered] = _MenuButtonHovered.GetState(); + style.Colors[ImGuiCol_ButtonActive] = _MenuButtonActive.GetState(); + style.Colors[ImGuiCol_Border] = _MenuBorderColor.GetState(); + } + + void ResetToDefaultColors() + { + _MenuWindowBg.SetState(ImVec4{0.13f, 0.14f, 0.15f, 1.00f}); + _MenuChildBg.SetState(ImVec4{0.13f, 0.14f, 0.15f, 1.00f}); + _MenuTextColor.SetState(ImVec4{1.00f, 1.00f, 1.00f, 1.00f}); + _MenuButtonColor.SetState(ImVec4{0.25f, 0.25f, 0.25f, 1.00f}); + _MenuButtonHovered.SetState(ImVec4{0.38f, 0.38f, 0.38f, 1.00f}); + _MenuButtonActive.SetState(ImVec4{0.67f, 0.67f, 0.67f, 0.39f}); + _MenuBorderColor.SetState(ImVec4{0.43f, 0.43f, 0.50f, 0.50f}); + } + + void DrawColorSettings() + { + if (ImGui::Button("Reset to Default Colors", ImVec2(-1, 0))) + { + ResetToDefaultColors(); + } + + // Create two columns with headers at the same level + ImGui::Columns(2, "ColorColumns", false); + + // Left column header + ImGui::Text("Window & Background"); + + ImVec4 windowBg = _MenuWindowBg.GetState(); + if (ImGui::ColorEdit4("Window Background", &windowBg.x, ImGuiColorEditFlags_NoInputs)) + _MenuWindowBg.SetState(windowBg); + + ImVec4 childBg = _MenuChildBg.GetState(); + if (ImGui::ColorEdit4("Panel Background", &childBg.x, ImGuiColorEditFlags_NoInputs)) + _MenuChildBg.SetState(childBg); + + ImVec4 textColor = _MenuTextColor.GetState(); + if (ImGui::ColorEdit4("Text Color", &textColor.x, ImGuiColorEditFlags_NoInputs)) + _MenuTextColor.SetState(textColor); + + ImVec4 borderColor = _MenuBorderColor.GetState(); + if (ImGui::ColorEdit4("Border Color", &borderColor.x, ImGuiColorEditFlags_NoInputs)) + _MenuBorderColor.SetState(borderColor); + + // Move to right column + ImGui::NextColumn(); + + // Right column header - this will be at the same level as left header + ImGui::Text("Button Colors"); + + ImVec4 buttonColor = _MenuButtonColor.GetState(); + if (ImGui::ColorEdit4("Button Normal", &buttonColor.x, ImGuiColorEditFlags_NoInputs)) + _MenuButtonColor.SetState(buttonColor); + + ImVec4 buttonHovered = _MenuButtonHovered.GetState(); + if (ImGui::ColorEdit4("Button Hover", &buttonHovered.x, ImGuiColorEditFlags_NoInputs)) + _MenuButtonHovered.SetState(buttonHovered); + + ImVec4 buttonActive = _MenuButtonActive.GetState(); + if (ImGui::ColorEdit4("Button Active", &buttonActive.x, ImGuiColorEditFlags_NoInputs)) + _MenuButtonActive.SetState(buttonActive); + + ImGui::Columns(1); // Reset to single column + } +} \ No newline at end of file diff --git a/src/game/frontend/ColorCustomization.hpp b/src/game/frontend/ColorCustomization.hpp new file mode 100644 index 00000000..cfbce3af --- /dev/null +++ b/src/game/frontend/ColorCustomization.hpp @@ -0,0 +1,17 @@ +#pragma once +#include "core/commands/ColorCommand.hpp" + +namespace YimMenu::ColorCustomization +{ + extern ColorCommand _MenuWindowBg; + extern ColorCommand _MenuChildBg; + extern ColorCommand _MenuTextColor; + extern ColorCommand _MenuButtonColor; + extern ColorCommand _MenuButtonHovered; + extern ColorCommand _MenuButtonActive; + extern ColorCommand _MenuBorderColor; + + void ApplyMenuColors(); + void ResetToDefaultColors(); + void DrawColorSettings(); +} \ No newline at end of file diff --git a/src/game/frontend/Menu.cpp b/src/game/frontend/Menu.cpp index e9937676..9a0806c8 100644 --- a/src/game/frontend/Menu.cpp +++ b/src/game/frontend/Menu.cpp @@ -6,6 +6,7 @@ #include "game/backend/FiberPool.hpp" #include "game/backend/ScriptMgr.hpp" #include "game/frontend/fonts/Fonts.hpp" +#include "game/frontend/ColorCustomization.hpp" #include "game/pointers/Pointers.hpp" #include "submenus/Debug.hpp" #include "submenus/Network.hpp" @@ -38,7 +39,9 @@ namespace YimMenu ImGui::PushFont(Menu::Font::g_DefaultFont); ImGui::PushStyleColor(ImGuiCol_WindowBg, ImU32(ImColor(15, 15, 15))); - // Think this add HTML&PHP with no CSS. Lol just for testing. + // Apply custom menu colors each frame + YimMenu::ColorCustomization::ApplyMenuColors(); + ImGui::SetNextWindowSize(ImVec2((*Pointers.ScreenResX / 2.5), (*Pointers.ScreenResY / 2.5)), ImGuiCond_Once); if (ImGui::Begin("Terminus", nullptr, ImGuiWindowFlags_NoDecoration)) { @@ -122,6 +125,8 @@ namespace YimMenu style.Colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f); style.Colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.35f); style.GrabRounding = style.FrameRounding = style.ChildRounding = style.WindowRounding = 2.3f; + + YimMenu::ColorCustomization::ApplyMenuColors(); } void Menu::SetupFonts() diff --git a/src/game/frontend/submenus/Network.cpp b/src/game/frontend/submenus/Network.cpp index bc0b9a55..ce6abe8b 100644 --- a/src/game/frontend/submenus/Network.cpp +++ b/src/game/frontend/submenus/Network.cpp @@ -1,6 +1,8 @@ -#include "Network.hpp" +#include +#include "Network.hpp" #include "Network/Voice.hpp" +#include "Self.hpp" #include "core/commands/Commands.hpp" #include "core/commands/HotkeySystem.hpp" #include "core/commands/LoopedCommand.hpp" @@ -14,19 +16,18 @@ #include "game/pointers/Pointers.hpp" #include "game/rdr/Enums.hpp" #include "game/rdr/Natives.hpp" +#include "game/rdr/Packet.hpp" #include "util/Chat.hpp" #include "util/Storage/Spoofing.hpp" #include "util/teleport.hpp" -#include "Self.hpp" -#include "game/rdr/Packet.hpp" #include -#include +#include #include +#include +#include #include #include -#include -#include #include #include @@ -42,14 +43,14 @@ namespace rage }; uint32_t m_presence_attibute_type; //0x0140 char pad_0144[4]; //0x0144 - }; //Size: 0x0148 + }; //Size: 0x0148 static_assert(sizeof(rlQueryPresenceAttributesContext) == 0x148); struct rlScTaskStatus { - void* pad = 0; + void* pad = 0; int status = 0; - int unk = 0; + int unk = 0; }; } @@ -58,10 +59,11 @@ namespace YimMenu::Submenus std::shared_ptr current_player; static char search[64]; static char name_buf[32]; + static char notes_buf[1024]; static char new_player_name_buf[32]; static uint64_t new_player_rid; static bool show_player_editor = false; - static bool show_new_player = true; + static bool show_new_player = true; void draw_player_db_entry(std::shared_ptr player, const std::string& lower_search) { @@ -77,7 +79,8 @@ namespace YimMenu::Submenus g_PlayerDatabase->SetSelected(player); current_player = player; strncpy(name_buf, current_player->name.data(), sizeof(name_buf)); - show_new_player = false; + strncpy(notes_buf, current_player->notes.data(), sizeof(notes_buf)); + show_new_player = false; show_player_editor = true; } @@ -89,15 +92,15 @@ namespace YimMenu::Submenus Submenu::Submenu("Network") { // TODO: this needs a rework - auto session = std::make_shared("Session"); - auto spoofing = std::make_shared("Spoofing"); - auto database = std::make_shared("Player Database"); + auto session = std::make_shared("Session"); + auto spoofing = std::make_shared("Spoofing"); + auto database = std::make_shared("Player Database"); auto sessionSwitcherGroup = std::make_shared("Session Switcher"); - auto teleportGroup = std::make_shared("Teleport"); - auto toxicGroup = std::make_shared("Toxic"); - auto miscGroup = std::make_shared("Misc"); - auto infoSpoofingGroup = std::make_shared("Info Spoofing"); - auto blipSpoofingGroup = std::make_shared("Blip Spoofing"); + auto teleportGroup = std::make_shared("Teleport"); + auto toxicGroup = std::make_shared("Toxic"); + auto miscGroup = std::make_shared("Misc"); + auto infoSpoofingGroup = std::make_shared("Info Spoofing"); + auto blipSpoofingGroup = std::make_shared("Blip Spoofing"); auto sessionSpoofingGroup = std::make_shared("Session Spoofing"); sessionSwitcherGroup->AddItem(std::make_shared("newsessionpos"_J)); @@ -174,6 +177,12 @@ namespace YimMenu::Submenus g_PlayerDatabase->Save(); } + if (ImGui::InputTextMultiline("Notes", notes_buf, sizeof(notes_buf), ImVec2(0, 80))) + { + current_player->notes = notes_buf; + g_PlayerDatabase->Save(); + } + if (!current_player->infractions.empty()) { ImGui::Text("Infractions"); @@ -189,10 +198,10 @@ namespace YimMenu::Submenus { // TODO: find a better way to do this ImGui::BulletText(std::string(g_PlayerDatabase->ConvertDetectionToDescription(Detection(pair.first))) - .append(" - ") - .append("x") - .append(std::to_string(pair.second)) - .c_str()); + .append(" - ") + .append("x") + .append(std::to_string(pair.second)) + .c_str()); } } @@ -204,7 +213,7 @@ namespace YimMenu::Submenus if (ImGui::Button("Hide Editor")) { show_player_editor = false; - show_new_player = true; + show_new_player = true; } ImGui::PopID(); } @@ -219,6 +228,7 @@ namespace YimMenu::Submenus { current_player = g_PlayerDatabase->GetOrCreatePlayer(new_player_rid, new_player_name_buf); memset(new_player_name_buf, 0, sizeof(new_player_name_buf)); + memset(notes_buf, 0, sizeof(notes_buf)); } ImGui::PopID(); } @@ -262,7 +272,7 @@ namespace YimMenu::Submenus InputTextWithHint("Spoofed Name", "Enter spoofed name", &nameBuf).Draw(); if (ImGui::Button("Set Spoofed Name")) { - std::string concatName = std::string(colorBuf) + std::string(iconBuf) + nameBuf; + std::string concatName = std::string(colorBuf) + std::string(iconBuf) + nameBuf; g_SpoofingStorage.spoofedName = concatName; } if (ImGui::IsItemHovered()) diff --git a/src/game/frontend/submenus/Settings.cpp b/src/game/frontend/submenus/Settings.cpp index 114eafeb..78bd0703 100644 --- a/src/game/frontend/submenus/Settings.cpp +++ b/src/game/frontend/submenus/Settings.cpp @@ -6,6 +6,7 @@ #include "game/backend/Self.hpp" #include "game/features/Features.hpp" #include "game/frontend/items/Items.hpp" +#include "game/frontend/ColorCustomization.hpp" namespace YimMenu::Submenus { @@ -38,14 +39,16 @@ namespace YimMenu::Submenus auto hotkeys = std::make_shared("Hotkeys"); auto gui = std::make_shared("GUI"); auto protections = std::make_shared("Protection"); + auto menuCustomization = std::make_shared("Menu Customization"); auto syncGroup = std::make_shared("Sync"); auto networkEventGroup = std::make_shared("Network Events"); auto scriptEventGroup = std::make_shared("Script Events"); auto playerEsp = std::make_shared("Player ESP", 10); auto pedEsp = std::make_shared("Ped ESP", 10); - auto overlay = std::make_shared("Overlay"); + auto overlay = std::make_shared("Overlay"); auto context = std::make_shared("Context Menu"); auto misc = std::make_shared("Misc"); + auto colorSettings = std::make_shared("Color Settings"); hotkeys->AddItem(std::make_shared(Hotkeys)); @@ -120,8 +123,14 @@ namespace YimMenu::Submenus protections->AddItem(syncGroup); protections->AddItem(networkEventGroup); protections->AddItem(scriptEventGroup); + + colorSettings->AddItem(std::make_shared(YimMenu::ColorCustomization::DrawColorSettings)); + + menuCustomization->AddItem(colorSettings); + AddCategory(std::move(hotkeys)); AddCategory(std::move(gui)); AddCategory(std::move(protections)); + AddCategory(std::move(menuCustomization)); } } \ No newline at end of file