From 61dd65645eb56e3eac83f785cafa150a451213c9 Mon Sep 17 00:00:00 2001 From: maybegreat48 <96936658+maybegreat48@users.noreply.github.com> Date: Thu, 16 Nov 2023 12:22:50 +0000 Subject: [PATCH] Misc stuff and code changes (#59) * fix: revert original call for ThrowFatalError * fix: fix Player::Player(CNetGamePlayer *) * feat: test commit * feat(protections): add some more * feat: commit for merge * Merge * getting ready to merge * Merge fixes * feat(spoofing): hide godmode * feat(invoker): add varargs support * refactor(ContextMenu): cleanup * fix code * fix: remove duplicate invis entry * fix: use upstream classes * fix(spectate): by @DayibBaba --------- Co-authored-by: DayibBaba <79384354+DayibBaba@users.noreply.github.com> --- cmake/rdr-classes.cmake | 2 +- src/common.hpp | 1 + src/core/commands/BoolCommand.cpp | 10 - src/core/commands/BoolCommand.hpp | 4 - src/core/commands/HotkeySystem.cpp | 5 +- src/core/commands/HotkeySystem.hpp | 2 + src/core/commands/LoopedCommand.cpp | 11 +- src/core/frontend/Notifications.cpp | 4 + src/core/hooking/Hooking.cpp | 3 +- src/game/backend/Players.hpp | 4 +- src/game/bigfeatures/ContextMenu.cpp | 168 ---------------- src/game/bigfeatures/Esp.cpp | 108 ---------- src/game/features/Features.cpp | 33 +--- src/game/features/Features.hpp | 11 +- src/game/features/mount/HorseGodmode.cpp | 4 +- src/game/features/mount/HorseNoRagdoll.cpp | 1 - .../players/toxic/ActivateDefensiveMode.cpp | 3 +- .../players/toxic/ActivateOffensiveMode.cpp | 3 +- .../features/players/toxic/ExplodePlayer.cpp | 7 +- .../features/players/toxic/MaximumHonor.cpp | 3 +- .../features/players/toxic/MinimumHonor.cpp | 3 +- src/game/features/self/AntiAfk.cpp | 13 +- src/game/features/self/ClearCrimes.cpp | 4 +- src/game/features/self/Godmode.cpp | 6 + src/game/features/self/KeepBarsFilled.cpp | 5 +- src/game/features/self/KeepCoresFilled.cpp | 3 + src/game/features/self/NoRagdoll.cpp | 2 +- src/game/features/self/Noclip.cpp | 1 - src/game/features/self/OffTheRadar.cpp | 17 +- src/game/features/self/TpMountToSelf.cpp | 4 +- src/game/features/self/TpToWaypoint.cpp | 2 +- src/game/frontend/ContextMenu.cpp | 158 +++++++++++++++ .../{bigfeatures => frontend}/ContextMenu.hpp | 68 +------ .../ContextMenus.hpp | 44 +++-- src/game/frontend/ESP.cpp | 129 ++++++++++++ .../{bigfeatures/Esp.hpp => frontend/ESP.hpp} | 2 +- src/game/frontend/GUI.cpp | 6 +- src/game/frontend/Menu.cpp | 2 + src/game/frontend/items/Items.hpp | 11 ++ src/game/frontend/items/PlayerCommandItem.cpp | 30 +++ src/game/frontend/submenus/Debug.cpp | 1 + src/game/frontend/submenus/Network.cpp | 22 +++ src/game/frontend/submenus/Network.hpp | 11 ++ src/game/frontend/submenus/Players.cpp | 186 +++++++++++++++--- src/game/frontend/submenus/Self.cpp | 1 - src/game/frontend/submenus/Settings.cpp | 14 +- src/game/frontend/submenus/Teleport.cpp | 6 +- src/game/hooks/Anticheat/SendMetric.cpp | 9 +- src/game/hooks/Hooks.hpp | 6 + src/game/hooks/Misc/ThrowFatalError.cpp | 1 + .../Protections/AddObjectToCreationQueue.cpp | 4 + .../hooks/Protections/HandleNetGameEvent.cpp | 49 +++++ .../hooks/Protections/ShouldBlockSync.cpp | 21 ++ .../hooks/Spoofing/WritePlayerHealthData.cpp | 26 +++ src/game/pointers/Pointers.cpp | 21 +- src/game/pointers/Pointers.hpp | 4 +- src/game/rdr/Entity.cpp | 72 ++++++- src/game/rdr/Entity.hpp | 21 +- src/game/rdr/Enums.hpp | 7 + src/game/rdr/Natives.hpp | 6 +- src/game/rdr/Nodes.cpp | 8 +- src/game/rdr/Ped.cpp | 16 ++ src/game/rdr/Ped.hpp | 13 ++ src/game/rdr/Player.cpp | 60 ++---- src/game/rdr/Player.hpp | 29 +-- src/game/rdr/ScriptGlobal.cpp | 7 +- src/game/rdr/ScriptGlobal.hpp | 3 +- src/game/rdr/invoker/GenerateNatives.py | 16 +- src/main.cpp | 2 - src/util/network.hpp | 2 + src/util/teleport.hpp | 15 +- 71 files changed, 949 insertions(+), 607 deletions(-) delete mode 100644 src/game/bigfeatures/ContextMenu.cpp delete mode 100644 src/game/bigfeatures/Esp.cpp create mode 100644 src/game/frontend/ContextMenu.cpp rename src/game/{bigfeatures => frontend}/ContextMenu.hpp (51%) rename src/game/{bigfeatures => frontend}/ContextMenus.hpp (55%) create mode 100644 src/game/frontend/ESP.cpp rename src/game/{bigfeatures/Esp.hpp => frontend/ESP.hpp} (94%) create mode 100644 src/game/frontend/items/PlayerCommandItem.cpp create mode 100644 src/game/frontend/submenus/Network.cpp create mode 100644 src/game/frontend/submenus/Network.hpp create mode 100644 src/game/hooks/Spoofing/WritePlayerHealthData.cpp create mode 100644 src/game/rdr/Ped.cpp create mode 100644 src/game/rdr/Ped.hpp diff --git a/cmake/rdr-classes.cmake b/cmake/rdr-classes.cmake index 623f3b93..f61e21fb 100644 --- a/cmake/rdr-classes.cmake +++ b/cmake/rdr-classes.cmake @@ -3,7 +3,7 @@ include(FetchContent) FetchContent_Declare( rdr_classes GIT_REPOSITORY https://github.com/YimMenu/RDR-Classes.git - GIT_TAG 0132075d1c6a88066ce6f6225f168a49e76a51a3 + GIT_TAG 1d566f23329b756aa3ef57be7b53525d949af14a GIT_PROGRESS TRUE CONFIGURE_COMMAND "" BUILD_COMMAND "" diff --git a/src/common.hpp b/src/common.hpp index 81b1c30a..7e8e8bdd 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -32,6 +32,7 @@ using namespace al; namespace YimMenu { using namespace std::chrono_literals; + using namespace std::string_literals; extern std::atomic g_Running; extern HINSTANCE g_DllInstance; diff --git a/src/core/commands/BoolCommand.cpp b/src/core/commands/BoolCommand.cpp index 193d9003..0d2fa911 100644 --- a/src/core/commands/BoolCommand.cpp +++ b/src/core/commands/BoolCommand.cpp @@ -43,16 +43,6 @@ namespace YimMenu MarkDirty(); } - void BoolCommand::SetDisabled(bool state) - { - m_Disabled = state; - } - - bool BoolCommand::GetDisabled() - { - return m_Disabled; - } - void BoolCommand::Shutdown() { OnDisable(); diff --git a/src/core/commands/BoolCommand.hpp b/src/core/commands/BoolCommand.hpp index 03df5dab..bfecb95b 100644 --- a/src/core/commands/BoolCommand.hpp +++ b/src/core/commands/BoolCommand.hpp @@ -13,15 +13,11 @@ namespace YimMenu virtual void LoadState(nlohmann::json& value) override; bool m_State = false; - bool m_Disabled = false; public: BoolCommand(std::string name, std::string label, std::string description); bool GetState(); void SetState(bool state); - bool GetDisabled(); - void SetDisabled(bool state); - void Shutdown(); }; } \ No newline at end of file diff --git a/src/core/commands/HotkeySystem.cpp b/src/core/commands/HotkeySystem.cpp index e1302c47..f11bcb82 100644 --- a/src/core/commands/HotkeySystem.cpp +++ b/src/core/commands/HotkeySystem.cpp @@ -106,15 +106,14 @@ namespace YimMenu } } - if (AllKeysPressed && GetForegroundWindow() == Pointers.Hwnd) + if (AllKeysPressed && GetForegroundWindow() == Pointers.Hwnd && std::chrono::system_clock::now() - m_LastHotkeyTriggerTime > 100ms) { auto Command = Commands::GetCommand(Hash); if (Command) { Command->Call(); } - - ScriptMgr::Yield(100ms); + m_LastHotkeyTriggerTime = std::chrono::system_clock::now(); } } } diff --git a/src/core/commands/HotkeySystem.hpp b/src/core/commands/HotkeySystem.hpp index 1283efd0..62d5a3b7 100644 --- a/src/core/commands/HotkeySystem.hpp +++ b/src/core/commands/HotkeySystem.hpp @@ -15,6 +15,8 @@ namespace YimMenu class HotkeySystem : private IStateSerializer { + std::chrono::system_clock::time_point m_LastHotkeyTriggerTime; + public: HotkeySystem(); diff --git a/src/core/commands/LoopedCommand.cpp b/src/core/commands/LoopedCommand.cpp index e88b602e..2ebfae7d 100644 --- a/src/core/commands/LoopedCommand.cpp +++ b/src/core/commands/LoopedCommand.cpp @@ -11,15 +11,6 @@ namespace YimMenu void LoopedCommand::Tick() { - if (LoopedCommand::GetState()) - { - LoopedCommand::SetDisabled(false); - OnTick(); - } - else if (!LoopedCommand::GetDisabled()) - { - LoopedCommand::SetDisabled(true); - OnDisable(); - } + OnTick(); } } \ No newline at end of file diff --git a/src/core/frontend/Notifications.cpp b/src/core/frontend/Notifications.cpp index dbb7128a..365be101 100644 --- a/src/core/frontend/Notifications.cpp +++ b/src/core/frontend/Notifications.cpp @@ -38,11 +38,15 @@ namespace YimMenu bool Notifications::EraseImpl(Notification notification) { for (auto& [id, n] : m_Notifications) + { if (id == notification.GetIdentifier()) { n.erasing = true; return true; } + } + + return false; } static void DrawNotification(Notification& notification, int position) diff --git a/src/core/hooking/Hooking.cpp b/src/core/hooking/Hooking.cpp index f780d27c..506f3b3d 100644 --- a/src/core/hooking/Hooking.cpp +++ b/src/core/hooking/Hooking.cpp @@ -9,7 +9,6 @@ namespace YimMenu { - Hooking::Hooking() { BaseHook::Add(new DetourHook("WndProc", Pointers.WndProc, Hooks::Window::WndProc)); @@ -51,6 +50,8 @@ namespace YimMenu BaseHook::Add(new DetourHook("NetworkReqeust", Pointers.NetworkRequest, Hooks::Info::NetworkRequest)); BaseHook::Add(new DetourHook("AssignPhysicalIndex", Pointers.AssignPhysicalIndex, Hooks::Info::AssignPhysicalIndex)); + + BaseHook::Add(new DetourHook("WritePlayerHealthData", Pointers.WritePlayerHealthData, Hooks::Spoofing::WritePlayerHealthData)); } Hooking::~Hooking() diff --git a/src/game/backend/Players.hpp b/src/game/backend/Players.hpp index 47448c70..f58d28b6 100644 --- a/src/game/backend/Players.hpp +++ b/src/game/backend/Players.hpp @@ -5,7 +5,7 @@ namespace YimMenu { class Players { - std::map m_Players{}; + std::unordered_map m_Players{}; Player m_SelectedPlayer = Player((uint8_t)0); public: @@ -24,7 +24,7 @@ namespace YimMenu GetInstance().m_SelectedPlayer = Player(idx); } - static std::map& GetPlayers() + static std::unordered_map& GetPlayers() { return GetInstance().m_Players; } diff --git a/src/game/bigfeatures/ContextMenu.cpp b/src/game/bigfeatures/ContextMenu.cpp deleted file mode 100644 index 4837855b..00000000 --- a/src/game/bigfeatures/ContextMenu.cpp +++ /dev/null @@ -1,168 +0,0 @@ -#include "ContextMenu.hpp" - -#include "ContextMenus.hpp" -#include "core/frontend/Notifications.hpp" -#include "game/backend/Players.hpp" -#include "game/backend/ScriptMgr.hpp" -#include "game/pointers/Pointers.hpp" -#include "game/rdr/Enums.hpp" -#include "game/backend/FiberPool.hpp" - -namespace YimMenu -{ - void ContextMenu::SetEntityImpl(int handle, void* pointer) - { - m_EntityHandle = handle; - m_EntityPointer = pointer; - } - - double ContextMenu::CumulativeDistanceToMiddleOfScreenImpl(rage::fvector2 screenPos) - { - double cumDist{}; - - if (screenPos.x > 0.5) - cumDist += screenPos.x - 0.5; - else - cumDist += 0.5 - screenPos.x; - - if (screenPos.y > 0.5) - cumDist += screenPos.y - 0.5; - else - cumDist += 0.5 - screenPos.y; - - return cumDist; - } - - int ContextMenu::GetEntityHandleClosestToMiddleOfScreenImpl(bool includePlayers, bool includePeds = false, bool includeVehicles = false, bool includeObjects = false) - { - int closestHandle{}; - float distance = 1; - - auto updateClosestEntity = [&](int handle) -> void { - auto worldCoords = ENTITY::GET_ENTITY_COORDS(handle, false, true); - rage::fvector2 screenPos{}; - float worldCoords_[3] = {worldCoords.x, worldCoords.y, worldCoords.z}; - Pointers.WorldToScreen(worldCoords_, &screenPos.x, &screenPos.y); - if (CumulativeDistanceToMiddleOfScreen(screenPos) < distance && handle != Self::PlayerPed) - { - closestHandle = handle; - distance = CumulativeDistanceToMiddleOfScreen(screenPos); - } - }; - - if (includePlayers) - { - for (auto [id, plyr] : YimMenu::Players::GetPlayers()) - { - if (plyr.IsValid() || plyr.GetPed().GetPointer()) - updateClosestEntity(PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(id)); - } - } - - return closestHandle; - } - - void ContextMenu::HandleEntityAndMenuImpl() - { - if (m_Enabled && g_ContextMenu) - { - auto handle = GetEntityHandleClosestToMiddleOfScreenImpl(true); - - static auto switchToMenu = [&](ContextOperationsMenu menu) -> void { - if (m_CurrentOperationsMenu != menu) - { - m_CurrentOperationsMenu = menu; - } - }; - - if (handle && ENTITY::DOES_ENTITY_EXIST(handle)) - { - m_EntityHandle = handle; - - if (ENTITY::IS_ENTITY_A_PED(m_EntityHandle)) - { - if (PED::IS_PED_A_PLAYER(m_EntityHandle)) - switchToMenu(ContextMenuPlayers); - else - switchToMenu(ContextMenuDefault); //TODO Create Ped menu - } - else if (ENTITY::IS_ENTITY_A_VEHICLE(m_EntityHandle)) - { - switchToMenu(ContextMenuDefault); //TODO Create Vehicle menu - } - else if (ENTITY::IS_ENTITY_AN_OBJECT(m_EntityHandle)) - { - switchToMenu(ContextMenuDefault); //TODO Create Object menu - } - - if (m_CurrentOperationsMenu.m_SelectedOperation.m_Name.empty()) - m_CurrentOperationsMenu.m_SelectedOperation = m_CurrentOperationsMenu.m_Operations.front(); - - auto entPos = ENTITY::GET_ENTITY_COORDS(handle, false, true); - float worldCoords_[3] = {entPos.x, entPos.y, entPos.z}; - Pointers.WorldToScreen(worldCoords_, &m_ScreenPos.x, &m_ScreenPos.y); - m_ScreenPos.x *= Pointers.ScreenResX; - m_ScreenPos.y *= Pointers.ScreenResY; - - PAD::DISABLE_CONTROL_ACTION(0, (int)eNativeInputs::INPUT_NEXT_WEAPON, true); - PAD::DISABLE_CONTROL_ACTION(0, (int)eNativeInputs::INPUT_PREV_WEAPON, true); - PAD::DISABLE_CONTROL_ACTION(0, (int)eNativeInputs::INPUT_ATTACK, true); - - if (PAD::IS_DISABLED_CONTROL_JUST_PRESSED(0, (int)eNativeInputs::INPUT_PREV_WEAPON)) - m_CurrentOperationsMenu.SelectPrevious(); - - if (PAD::IS_DISABLED_CONTROL_JUST_PRESSED(0, (int)eNativeInputs::INPUT_NEXT_WEAPON)) - m_CurrentOperationsMenu.SelectNext(); - - if (PAD::IS_DISABLED_CONTROL_JUST_PRESSED(0, (int)eNativeInputs::INPUT_ATTACK)) - FiberPool::Push([=] { - m_CurrentOperationsMenu.m_SelectedOperation.m_Operation(); - }); - - m_MenuIsInitialized = true; - } - else - { - m_EntityHandle = 0; - m_MenuIsInitialized = false; - } - } - } - - void DrawOperation(ContextMenuOperation operation, bool selected, int position, ImDrawList* drawList) - { - auto screenPos = ContextMenu::GetScreenPos(); - - //Make compatible with ESP - if (g_Esp) - screenPos.y += 20; - - if (position > 0) - screenPos.y += (m_OperationCardY * position) + 2 /*Margin between operation cards*/; - - auto cardColor = selected ? ImGui::ColorConvertFloat4ToU32(ImVec4(1, 0, 0, 0.5)) : ImGui::ColorConvertFloat4ToU32(ImVec4(1, 0, 0, 0.2)); - - ImVec2 endPos = ImVec2(screenPos.x + m_OperationCardX, screenPos.y + m_OperationCardY); - drawList->AddRectFilled(ImVec2(screenPos.x, screenPos.y), endPos, cardColor, 3.f); - - drawList->AddText(ImVec2(screenPos.x, screenPos.y), - ImGui::ColorConvertFloat4ToU32(ImVec4(1, 1, 1, 1)), - operation.m_Name.data()); - } - - void ContextMenu::DrawContextMenuImpl() - { - if (m_MenuIsInitialized && m_Enabled && g_ContextMenu) - { - if (const auto drawList = ImGui::GetBackgroundDrawList()) - { - int position = 0; - for (auto& operation : m_CurrentOperationsMenu.m_Operations) - { - DrawOperation(operation, operation == m_CurrentOperationsMenu.m_SelectedOperation, position, drawList); - position++; - } - } - } - } -} \ No newline at end of file diff --git a/src/game/bigfeatures/Esp.cpp b/src/game/bigfeatures/Esp.cpp deleted file mode 100644 index 63471994..00000000 --- a/src/game/bigfeatures/Esp.cpp +++ /dev/null @@ -1,108 +0,0 @@ -#include "Esp.hpp" - -#include "common.hpp" -#include "game/backend/Players.hpp" -#include "game/features/Features.hpp" -#include "game/pointers/Pointers.hpp" -#include "util/Math.hpp" - -namespace YimMenu -{ - static ImColor death_bg = ImColor(0.117f, 0.113f, 0.172f, .75f); - static ImColor armor_blue_bg = ImColor(0.36f, 0.71f, 0.89f, .75f); - static ImColor armor_blue = ImColor(0.36f, 0.71f, 0.89f, 1.f); - static ImColor health_green_bg = ImColor(0.29f, 0.69f, 0.34f, .75f); - static ImColor health_green = ImColor(0.29f, 0.69f, 0.34f, 1.f); - static ImColor health_yellow_bg = ImColor(0.69f, 0.49f, 0.29f, .75f); - static ImColor health_yellow = ImColor(0.69f, 0.49f, 0.29f, 1.f); - static ImColor health_red_bg = ImColor(0.69f, 0.29f, 0.29f, .75f); - static ImColor health_red = ImColor(0.69f, 0.29f, 0.29f, 1.f); - static ImColor Green = ImColor(0.29f, 0.69f, 0.34f, 1.f); - static ImColor Orange = ImColor(0.69f, 0.49f, 0.29f, 1.f); - static ImColor Red = ImColor(0.69f, 0.29f, 0.29f, 1.f); - static ImColor Blue = ImColor(0.36f, 0.71f, 0.89f, 1.f); - - static auto boneToScreen = [=](Vector3 bone) -> ImVec2 { - float screen_x, screen_y; - float boneCoords[3] = {bone.x, bone.y, bone.z}; - - Pointers.WorldToScreen(boneCoords, &screen_x, &screen_y); - - return ImVec2(screen_x * Pointers.ScreenResX, screen_y * Pointers.ScreenResY); - }; - - void DrawSkeleton(Player& plyr, ImDrawList* drawList, ImColor color) - { - const auto plyrBones = plyr.GetBoneCoords(); - - drawList->AddLine(boneToScreen(plyrBones.Head), boneToScreen(plyrBones.Neck), color); - - drawList->AddLine(boneToScreen(plyrBones.Neck), boneToScreen(plyrBones.LeftElbow), color); - drawList->AddLine(boneToScreen(plyrBones.LeftElbow), boneToScreen(plyrBones.LeftHand), color); - - drawList->AddLine(boneToScreen(plyrBones.Neck), boneToScreen(plyrBones.RightElbow), color); - drawList->AddLine(boneToScreen(plyrBones.RightElbow), boneToScreen(plyrBones.RightHand), color); - - drawList->AddLine(boneToScreen(plyrBones.Neck), boneToScreen(plyrBones.Torso), color); - - drawList->AddLine(boneToScreen(plyrBones.Torso), boneToScreen(plyrBones.LeftKnee), color); - drawList->AddLine(boneToScreen(plyrBones.LeftKnee), boneToScreen(plyrBones.LeftFoot), color); - - drawList->AddLine(boneToScreen(plyrBones.Torso), boneToScreen(plyrBones.RightKnee), color); - drawList->AddLine(boneToScreen(plyrBones.RightKnee), boneToScreen(plyrBones.RightFoot), color); - } - - //TODO : Very bare bones currently, expand and possibly refactor - void Esp::DrawPlayer(Player& plyr, ImDrawList* drawList) - { - if (!plyr.IsValid() || plyr.GetId() == Self::Id || plyr.GetBoneCoords().Torso.x == 0) - return; - - const auto plyrBones = plyr.GetBoneCoords(); - float distanceToPlayer = Math::DistanceBetweenVectors(Self::Pos, plyrBones.Torso); - int alphaBasedOnDistance = 255; - ImColor colorBasedOnDistance = Red; - - if (distanceToPlayer < 100.f) - colorBasedOnDistance = Green, alphaBasedOnDistance = 255; - else if (distanceToPlayer > 100.f && distanceToPlayer < 300.f) - colorBasedOnDistance = Orange, alphaBasedOnDistance = 200; - else if (distanceToPlayer > 300.f) - colorBasedOnDistance = Red, alphaBasedOnDistance = 125; - - const auto originalFontSize = ImGui::GetFont()->Scale; - auto* currentFont = ImGui::GetFont(); - currentFont->Scale *= 1.2; - ImGui::PushFont(ImGui::GetFont()); - //Name - drawList->AddText(boneToScreen(plyrBones.Head), plyr == Players::GetSelected() ? Blue : ImColor(255, 255, 255, alphaBasedOnDistance), plyr.GetName()); - //Distance - drawList->AddText({boneToScreen(plyrBones.Head).x, boneToScreen(plyrBones.Head).y + 20}, - colorBasedOnDistance, - std::to_string((int)Math::DistanceBetweenVectors(Self::Pos, plyrBones.Torso)).data()); - - currentFont->Scale = originalFontSize; - ImGui::PopFont(); - - //TODO Boxes, Distance colors, Friendlies, Tracers, Health bars - - //TODO Make this a setting - if (distanceToPlayer < 100.f) - DrawSkeleton(plyr, drawList, ImColor(255, 255, 255, 255)); - } - - void Esp::Draw() - { - if (!g_Esp) - return; - - if (const auto drawList = ImGui::GetBackgroundDrawList()) - { - for (auto& [id, player] : Players::GetPlayers()) - { - DrawPlayer(player, drawList); - } - } - } - -} \ No newline at end of file diff --git a/src/game/features/Features.cpp b/src/game/features/Features.cpp index 2a84da8c..e6b6c281 100644 --- a/src/game/features/Features.cpp +++ b/src/game/features/Features.cpp @@ -1,16 +1,14 @@ #include "Features.hpp" - +#include "game/rdr/Natives.hpp" #include "core/commands/Commands.hpp" #include "core/commands/HotkeySystem.hpp" #include "core/frontend/Notifications.hpp" #include "game/backend/FiberPool.hpp" -#include "game/backend/Players.hpp" #include "game/backend/ScriptMgr.hpp" -#include "game/bigfeatures/ContextMenu.hpp" -#include "game/bigfeatures/Esp.hpp" -#include "game/frontend/GUI.hpp" +#include "game/backend/Players.hpp" #include "game/rdr/Enums.hpp" -#include "game/rdr/Natives.hpp" +#include "game/frontend/GUI.hpp" +#include "game/frontend/ContextMenu.hpp" namespace YimMenu { @@ -78,7 +76,6 @@ namespace YimMenu } } - void BlockAllControls() { FiberPool::Push([] { @@ -139,31 +136,11 @@ namespace YimMenu } } - void UpdatePlayerInfo() - { - while (true) - { - for (auto& [id, player] : YimMenu::Players::GetPlayers()) - { - player.UpdateBoneCoords(); - } - ScriptMgr::Yield(); - } - } - void ContextMenuTick() { while (true) { - if (g_ContextMenu) - { - ContextMenu::HandleEntityAndMenu(); - - PAD::DISABLE_CONTROL_ACTION(0, (Hash)eNativeInputs::INPUT_SWITCH_SHOULDER, true); - if (PAD::IS_DISABLED_CONTROL_JUST_PRESSED(0, (Hash)eNativeInputs::INPUT_SWITCH_SHOULDER)) - *ContextMenu::GetEnabled() = !*ContextMenu::GetEnabled(); - } - + ContextMenu::GameTick(); ScriptMgr::Yield(); } } diff --git a/src/game/features/Features.hpp b/src/game/features/Features.hpp index cd3c84cd..29a69bf2 100644 --- a/src/game/features/Features.hpp +++ b/src/game/features/Features.hpp @@ -5,27 +5,24 @@ namespace YimMenu { namespace Self { - inline Ped PlayerPed; + // TODO + inline ::Ped PlayerPed; inline ::Player Id; inline Vector3 Pos; inline Vector3 Rot; inline Vehicle Veh; - inline Ped Mount; + inline ::Ped Mount; inline bool IsOnMount; } + // TODO: move these out inline bool g_Spectating = false; inline int g_SpectateId = -1; inline bool g_BlockControls = false; - // TODO : Move these to a better place and make seriazable - inline bool g_Esp = false; - inline bool g_ContextMenu = false; - void FeatureLoop(); void BlockControlsForUI(); void BlockAllControls(); void SpectateTick(); - void UpdatePlayerInfo(); void ContextMenuTick(); } \ No newline at end of file diff --git a/src/game/features/mount/HorseGodmode.cpp b/src/game/features/mount/HorseGodmode.cpp index 65ea857a..c71ea259 100644 --- a/src/game/features/mount/HorseGodmode.cpp +++ b/src/game/features/mount/HorseGodmode.cpp @@ -5,7 +5,7 @@ namespace YimMenu::Features { - //Doesn't work + // Doesn't work class HorseGodmode : public LoopedCommand { using LoopedCommand::LoopedCommand; @@ -17,7 +17,7 @@ namespace YimMenu::Features virtual void OnDisable() override { - PED::SET_PED_CAN_RAGDOLL(Self::Mount, false); + ENTITY::SET_ENTITY_INVINCIBLE(Self::Mount, false); } }; diff --git a/src/game/features/mount/HorseNoRagdoll.cpp b/src/game/features/mount/HorseNoRagdoll.cpp index ad928823..e9dc72fa 100644 --- a/src/game/features/mount/HorseNoRagdoll.cpp +++ b/src/game/features/mount/HorseNoRagdoll.cpp @@ -15,7 +15,6 @@ namespace YimMenu::Features PED::SET_PED_CAN_RAGDOLL(Self::Mount, false); } - //Doesn't work virtual void OnDisable() override { PED::SET_PED_CAN_RAGDOLL(Self::Mount, true); diff --git a/src/game/features/players/toxic/ActivateDefensiveMode.cpp b/src/game/features/players/toxic/ActivateDefensiveMode.cpp index a94d79fe..82bb919b 100644 --- a/src/game/features/players/toxic/ActivateDefensiveMode.cpp +++ b/src/game/features/players/toxic/ActivateDefensiveMode.cpp @@ -1,6 +1,7 @@ #include "game/commands/PlayerCommand.hpp" #include "game/features/Features.hpp" #include "game/rdr/Scripts.hpp" +#include "game/rdr/Enums.hpp" namespace YimMenu::Features { @@ -11,7 +12,7 @@ namespace YimMenu::Features virtual void OnCall(Player player) override { uint64_t data[13]{}; - data[0] = 36; + data[0] = static_cast(ScriptEvent::SCRIPT_EVENT_NOTORIETY_FORCE_PASSIVE); data[1] = Self::Id; data[8] = 2; Scripts::SendScriptEvent(data, 13, 1 << player.GetId()); diff --git a/src/game/features/players/toxic/ActivateOffensiveMode.cpp b/src/game/features/players/toxic/ActivateOffensiveMode.cpp index e5ca56a3..7cc26c53 100644 --- a/src/game/features/players/toxic/ActivateOffensiveMode.cpp +++ b/src/game/features/players/toxic/ActivateOffensiveMode.cpp @@ -1,6 +1,7 @@ #include "game/commands/PlayerCommand.hpp" #include "game/features/Features.hpp" #include "game/rdr/Scripts.hpp" +#include "game/rdr/Enums.hpp" namespace YimMenu::Features { @@ -11,7 +12,7 @@ namespace YimMenu::Features virtual void OnCall(Player player) override { uint64_t data[13]{}; - data[0] = 37; + data[0] = static_cast(ScriptEvent::SCRIPT_EVENT_NOTORIETY_FORCE_NOT_PASSIVE_HORSE); data[1] = Self::Id; Scripts::SendScriptEvent(data, 13, 1 << player.GetId()); } diff --git a/src/game/features/players/toxic/ExplodePlayer.cpp b/src/game/features/players/toxic/ExplodePlayer.cpp index 82f5d44a..c609e92c 100644 --- a/src/game/features/players/toxic/ExplodePlayer.cpp +++ b/src/game/features/players/toxic/ExplodePlayer.cpp @@ -6,17 +6,16 @@ namespace YimMenu::Features { - //TODO doesn't work class ExplodePlayer : public PlayerCommand { using PlayerCommand::PlayerCommand; virtual void OnCall(Player player) override { - auto playerCoords = ENTITY::GET_ENTITY_COORDS(PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(player.GetId()), true, true); - FIRE::ADD_EXPLOSION(playerCoords.x, playerCoords.y, playerCoords.z, (int)ExplosionTypes::UNK, 10.0f, true, false, 5.0f); + auto playerCoords = player.GetPed().GetPosition(); + FIRE::ADD_OWNED_EXPLOSION(player.GetPed().GetHandle(), playerCoords.x, playerCoords.y, playerCoords.z, (int)ExplosionTypes::UNK, 10.0f, true, false, 5.0f); } }; - static ExplodePlayer _ExplodePlayer{"explodeplayer", "Explode", "Spawns an explosion on the player", 1, false}; + static ExplodePlayer _ExplodePlayer{"explode", "Explode", "Spawns an explosion on the player"}; } \ No newline at end of file diff --git a/src/game/features/players/toxic/MaximumHonor.cpp b/src/game/features/players/toxic/MaximumHonor.cpp index fe1a2bb6..18604fd9 100644 --- a/src/game/features/players/toxic/MaximumHonor.cpp +++ b/src/game/features/players/toxic/MaximumHonor.cpp @@ -2,6 +2,7 @@ #include "game/features/Features.hpp" #include "game/rdr/Scripts.hpp" #include "game/backend/ScriptMgr.hpp" +#include "game/rdr/Enums.hpp" namespace YimMenu::Features { @@ -11,7 +12,7 @@ namespace YimMenu::Features for (int i = 0; i < 5; i++) { - data[0] = 188; + data[0] = static_cast(ScriptEvent::SCRIPT_EVENT_PERSONA_HONOR); data[1] = Self::Id; data[4] = 2; data[5] = "PERSONA_HONOR_ACTION__FME_BOUNTY_RETURNED_ALIVE"_J; diff --git a/src/game/features/players/toxic/MinimumHonor.cpp b/src/game/features/players/toxic/MinimumHonor.cpp index 70a5f746..c7d96b72 100644 --- a/src/game/features/players/toxic/MinimumHonor.cpp +++ b/src/game/features/players/toxic/MinimumHonor.cpp @@ -2,6 +2,7 @@ #include "game/commands/PlayerCommand.hpp" #include "game/features/Features.hpp" #include "game/rdr/Scripts.hpp" +#include "game/rdr/Enums.hpp" namespace YimMenu::Features { @@ -11,7 +12,7 @@ namespace YimMenu::Features for (int i = 0; i < 5; i++) { - data[0] = 188; + data[0] = static_cast(ScriptEvent::SCRIPT_EVENT_PERSONA_HONOR); data[1] = Self::Id; data[4] = 2; data[5] = "PERSONA_HONOR_ACTION__MISSION_NEG_FIFTY"_J; diff --git a/src/game/features/self/AntiAfk.cpp b/src/game/features/self/AntiAfk.cpp index dd03c98c..e456f814 100644 --- a/src/game/features/self/AntiAfk.cpp +++ b/src/game/features/self/AntiAfk.cpp @@ -10,18 +10,21 @@ namespace YimMenu::Features class AntiAfk : public LoopedCommand { using LoopedCommand::LoopedCommand; + static constexpr auto timer = ScriptGlobal(1102813).At(3919); + static constexpr auto afkSwitch = ScriptGlobal(1102813).At(3918); virtual void OnTick() override { if (*Pointers.IsSessionStarted) { - auto timer = ScriptGlobal(1102813).At(3919).As(); - auto afkswitch = ScriptGlobal(1102813).At(3918).As(); - if (timer && afkswitch) - *timer = 999999, *afkswitch = 0; + if (timer.CanAccess() && afkSwitch.CanAccess()) + { + *timer.As() = 999999; + *afkSwitch.As() = false; + } } } }; - static AntiAfk _AntiAfk{"antiafk", "Anti Afk", "Prevents your from being idle kicked"}; + static AntiAfk _AntiAfk{"antiafk", "Anti Afk", "Prevents you from being idle kicked"}; } \ No newline at end of file diff --git a/src/game/features/self/ClearCrimes.cpp b/src/game/features/self/ClearCrimes.cpp index 6fee413b..5a06706b 100644 --- a/src/game/features/self/ClearCrimes.cpp +++ b/src/game/features/self/ClearCrimes.cpp @@ -10,8 +10,8 @@ namespace YimMenu::Features virtual void OnCall() override { - DWORD test[7]; - BOUNTY::_BOUNTY_REQUEST_SERVED_FULL_JAIL_SENTENCE(&test); + char guid[0x20]; + BOUNTY::_BOUNTY_REQUEST_SERVED_FULL_JAIL_SENTENCE(guid); } }; diff --git a/src/game/features/self/Godmode.cpp b/src/game/features/self/Godmode.cpp index 80406e01..87537e1d 100644 --- a/src/game/features/self/Godmode.cpp +++ b/src/game/features/self/Godmode.cpp @@ -11,6 +11,12 @@ namespace YimMenu::Features virtual void OnTick() override { + if (!Self::PlayerPed || PED::IS_PED_DEAD_OR_DYING(Self::PlayerPed, true) || ENTITY::IS_ENTITY_DEAD(Self::PlayerPed)) + { + ENTITY::SET_ENTITY_INVINCIBLE(Self::PlayerPed, false); + return; + } + ENTITY::SET_ENTITY_INVINCIBLE(Self::PlayerPed, true); } diff --git a/src/game/features/self/KeepBarsFilled.cpp b/src/game/features/self/KeepBarsFilled.cpp index 5f2eaf85..2804c757 100644 --- a/src/game/features/self/KeepBarsFilled.cpp +++ b/src/game/features/self/KeepBarsFilled.cpp @@ -11,11 +11,14 @@ namespace YimMenu::Features virtual void OnTick() override { + if (!Self::PlayerPed || PED::IS_PED_DEAD_OR_DYING(Self::PlayerPed, true) || ENTITY::IS_ENTITY_DEAD(Self::PlayerPed)) + return; + auto health_bar = ENTITY::GET_ENTITY_HEALTH(Self::PlayerPed); auto stamina_bar = PLAYER::_GET_PLAYER_STAMINA(Self::Id); auto deadeye_bar = PLAYER::_GET_PLAYER_DEAD_EYE(Self::Id); - if (health_bar < ENTITY::GET_ENTITY_MAX_HEALTH(Self::PlayerPed, false) && !PED::IS_PED_DEAD_OR_DYING(Self::PlayerPed, true) && !ENTITY::IS_ENTITY_DEAD(Self::PlayerPed)) + if (health_bar < ENTITY::GET_ENTITY_MAX_HEALTH(Self::PlayerPed, false)) ENTITY::SET_ENTITY_HEALTH(Self::PlayerPed, ENTITY::GET_ENTITY_MAX_HEALTH(Self::PlayerPed, false), 0); if (stamina_bar < PED::_GET_PED_MAX_STAMINA(Self::PlayerPed)) PED::_CHANGE_PED_STAMINA(Self::PlayerPed, PED::_GET_PED_MAX_STAMINA(Self::PlayerPed)); diff --git a/src/game/features/self/KeepCoresFilled.cpp b/src/game/features/self/KeepCoresFilled.cpp index 4e52437d..21e72dd8 100644 --- a/src/game/features/self/KeepCoresFilled.cpp +++ b/src/game/features/self/KeepCoresFilled.cpp @@ -11,6 +11,9 @@ namespace YimMenu::Features virtual void OnTick() override { + if (!Self::PlayerPed || PED::IS_PED_DEAD_OR_DYING(Self::PlayerPed, true) || ENTITY::IS_ENTITY_DEAD(Self::PlayerPed)) + return; + auto health_core = ATTRIBUTE::_GET_ATTRIBUTE_CORE_VALUE(Self::PlayerPed, (int)eAttributeCore::ATTRIBUTE_CORE_HEALTH); auto stamina_care = ATTRIBUTE::_GET_ATTRIBUTE_CORE_VALUE(Self::PlayerPed, (int)eAttributeCore::ATTRIBUTE_CORE_STAMINA); auto deadeye_core = ATTRIBUTE::_GET_ATTRIBUTE_CORE_VALUE(Self::PlayerPed, (int)eAttributeCore::ATTRIBUTE_CORE_DEADEYE); diff --git a/src/game/features/self/NoRagdoll.cpp b/src/game/features/self/NoRagdoll.cpp index 17bf8cec..c642767c 100644 --- a/src/game/features/self/NoRagdoll.cpp +++ b/src/game/features/self/NoRagdoll.cpp @@ -11,7 +11,7 @@ namespace YimMenu::Features virtual void OnTick() override { - if(PED::CAN_PED_RAGDOLL(Self::PlayerPed)) + if (PED::CAN_PED_RAGDOLL(Self::PlayerPed)) PED::SET_PED_CAN_RAGDOLL(Self::PlayerPed, false); } diff --git a/src/game/features/self/Noclip.cpp b/src/game/features/self/Noclip.cpp index 5aa173d0..70a132d3 100644 --- a/src/game/features/self/Noclip.cpp +++ b/src/game/features/self/Noclip.cpp @@ -93,7 +93,6 @@ namespace YimMenu::Features virtual void OnDisable() override { - ScriptMgr::Yield(10ms); ENTITY::FREEZE_ENTITY_POSITION(m_Entity, false); ENTITY::SET_ENTITY_COLLISION(m_Entity, true, false); } diff --git a/src/game/features/self/OffTheRadar.cpp b/src/game/features/self/OffTheRadar.cpp index 3e2997e1..fd459dfd 100644 --- a/src/game/features/self/OffTheRadar.cpp +++ b/src/game/features/self/OffTheRadar.cpp @@ -9,25 +9,18 @@ namespace YimMenu::Features class OffTheRadar : public LoopedCommand { using LoopedCommand::LoopedCommand; + static constexpr auto offTheRadar = ScriptGlobal(1102813).At(3); virtual void OnTick() override { - if (*Pointers.IsSessionStarted) - { - auto offtheradar = ScriptGlobal(1102813).At(3).As(); - if (offtheradar) - *offtheradar = 32; - } + if (offTheRadar.CanAccess()) + *offTheRadar.As() = 32; } virtual void OnDisable() override { - if (*Pointers.IsSessionStarted) - { - auto offtheradar = ScriptGlobal(1102813).At(3).As(); - if (offtheradar) - *offtheradar = 0; - } + if (offTheRadar.CanAccess()) + *offTheRadar.As() = 0; } }; diff --git a/src/game/features/self/TpMountToSelf.cpp b/src/game/features/self/TpMountToSelf.cpp index 24e434f4..0bf1d025 100644 --- a/src/game/features/self/TpMountToSelf.cpp +++ b/src/game/features/self/TpMountToSelf.cpp @@ -11,8 +11,8 @@ namespace YimMenu::Features virtual void OnCall() override { - if(ENTITY::DOES_ENTITY_EXIST(Self::Mount)) - if(PED::GET_MOUNT(Self::PlayerPed) != Self::Mount) + if (ENTITY::DOES_ENTITY_EXIST(Self::Mount)) + if (PED::GET_MOUNT(Self::PlayerPed) != Self::Mount) ENTITY::SET_ENTITY_COORDS(Self::Mount, Self::Pos.x, Self::Pos.y, Self::Pos.z, true, false, false, true); else Notifications::Show("Teleport", "Already on mount", NotificationType::Warning); diff --git a/src/game/features/self/TpToWaypoint.cpp b/src/game/features/self/TpToWaypoint.cpp index 9b04798e..70e36e4f 100644 --- a/src/game/features/self/TpToWaypoint.cpp +++ b/src/game/features/self/TpToWaypoint.cpp @@ -17,7 +17,7 @@ namespace YimMenu::Features if (MAP::IS_WAYPOINT_ACTIVE()) { auto waypointCoords = YimMenu::Teleport::GetWaypointCoords(); - YimMenu::Teleport::TeleportEntity(Self::PlayerPed, waypointCoords, true); + YimMenu::Teleport::TeleportEntity(Self::PlayerPed, {waypointCoords.x, waypointCoords.y, 0.0f}, true); } else { diff --git a/src/game/frontend/ContextMenu.cpp b/src/game/frontend/ContextMenu.cpp new file mode 100644 index 00000000..08418cdb --- /dev/null +++ b/src/game/frontend/ContextMenu.cpp @@ -0,0 +1,158 @@ +#include "ContextMenu.hpp" + +#include "ContextMenus.hpp" +#include "game/backend/Players.hpp" +#include "game/pointers/Pointers.hpp" +#include "game/rdr/Enums.hpp" +#include "game/backend/FiberPool.hpp" +#include "core/commands/BoolCommand.hpp" +#include "core/commands/Commands.hpp" + +namespace YimMenu::Features +{ + BoolCommand _ContextMenu("ctxmenu", "Context Menu", "Enables a context menu that allows you to perform actions on nearby entities and players"); +} + +namespace YimMenu +{ + inline double CumulativeDistanceToMiddleOfScreen(rage::fvector2 screenPos) + { + return std::abs(screenPos.x - 0.5) + std::abs(screenPos.y - 0.5); + } + + inline int GetEntityHandleClosestToMiddleOfScreen(bool includePlayers, bool includePeds = false, bool includeVehicles = false, bool includeObjects = false) + { + int closestHandle{}; + float distance = 1; + + auto updateClosestEntity = [&distance, &closestHandle](int handle) -> void { + auto worldCoords = ENTITY::GET_ENTITY_COORDS(handle, false, true); + rage::fvector2 screenPos{}; + float worldCoords_[3] = {worldCoords.x, worldCoords.y, worldCoords.z}; + Pointers.WorldToScreen(worldCoords_, &screenPos.x, &screenPos.y); + if (CumulativeDistanceToMiddleOfScreen(screenPos) < distance && handle != Self::PlayerPed) + { + closestHandle = handle; + distance = CumulativeDistanceToMiddleOfScreen(screenPos); + } + }; + + if (includePlayers && *Pointers.IsSessionStarted) + { + for (auto& [id, plyr] : YimMenu::Players::GetPlayers()) + { + if (plyr.IsValid() || plyr.GetPed().GetPointer()) + updateClosestEntity(PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(id)); + } + } + + return closestHandle; + } + + void ContextMenu::GameTickImpl() + { + if (Features::_ContextMenu.GetState()) + { + PAD::DISABLE_CONTROL_ACTION(0, (Hash)eNativeInputs::INPUT_SWITCH_SHOULDER, true); + if (PAD::IS_DISABLED_CONTROL_JUST_PRESSED(0, (Hash)eNativeInputs::INPUT_SWITCH_SHOULDER)) + m_Enabled = !m_Enabled; + + if (m_Enabled) + { + auto handle = GetEntityHandleClosestToMiddleOfScreen(true); + + static auto switchToMenu = [&](ContextOperationsMenu menu) -> void { + if (m_CurrentOperationsMenu != menu) + { + m_CurrentOperationsMenu = menu; + } + }; + + if (handle && ENTITY::DOES_ENTITY_EXIST(handle)) + { + m_Entity = handle; + + if (m_Entity.IsPed()) + { + if (m_Entity.IsPlayer()) + switchToMenu(ContextMenuPlayers); + else + switchToMenu(ContextMenuDefault); // TODO: Create Ped menu + } + else if (m_Entity.IsVehicle()) + { + switchToMenu(ContextMenuDefault); // TODO: Create Vehicle menu + } + else if (m_Entity.IsObject()) + { + switchToMenu(ContextMenuDefault); // TODO: Create Object menu + } + + if (m_CurrentOperationsMenu.m_SelectedOperation.m_Name.empty()) + m_CurrentOperationsMenu.m_SelectedOperation = m_CurrentOperationsMenu.m_Operations.front(); + + auto entPos = m_Entity.GetPosition(); + float worldCoords_[3] = {entPos.x, entPos.y, entPos.z}; + Pointers.WorldToScreen(worldCoords_, &m_ScreenPos.x, &m_ScreenPos.y); + m_ScreenPos.x *= Pointers.ScreenResX; + m_ScreenPos.y *= Pointers.ScreenResY; + + PAD::DISABLE_CONTROL_ACTION(0, (int)eNativeInputs::INPUT_NEXT_WEAPON, true); + PAD::DISABLE_CONTROL_ACTION(0, (int)eNativeInputs::INPUT_PREV_WEAPON, true); + PAD::DISABLE_CONTROL_ACTION(0, (int)eNativeInputs::INPUT_ATTACK, true); + + if (PAD::IS_DISABLED_CONTROL_JUST_PRESSED(0, (int)eNativeInputs::INPUT_PREV_WEAPON)) + m_CurrentOperationsMenu.SelectPrevious(); + + if (PAD::IS_DISABLED_CONTROL_JUST_PRESSED(0, (int)eNativeInputs::INPUT_NEXT_WEAPON)) + m_CurrentOperationsMenu.SelectNext(); + + if (PAD::IS_DISABLED_CONTROL_JUST_PRESSED(0, (int)eNativeInputs::INPUT_ATTACK)) + FiberPool::Push([=] { + m_CurrentOperationsMenu.m_SelectedOperation.m_Operation(m_Entity); + }); + } + else + { + m_Entity = nullptr; + } + } + } + } + + inline void DrawOperation(const ContextMenuOperation& operation, rage::fvector2 screenPos, bool selected, int position, ImDrawList* drawList) + { + // Make compatible with ESP + static auto esp = Commands::GetCommand("esp"_J); + if (esp->GetState()) + screenPos.y += 20; + + if (position > 0) + screenPos.y += (m_OperationCardY * position) + 2 /* Margin between operation cards */; + + auto cardColor = selected ? ImGui::ColorConvertFloat4ToU32(ImVec4(1, 0, 0, 0.5)) : ImGui::ColorConvertFloat4ToU32(ImVec4(1, 0, 0, 0.2)); + + ImVec2 endPos = ImVec2(screenPos.x + m_OperationCardX, screenPos.y + m_OperationCardY); + drawList->AddRectFilled(ImVec2(screenPos.x, screenPos.y), endPos, cardColor, 3.f); + + drawList->AddText(ImVec2(screenPos.x, screenPos.y), + ImGui::ColorConvertFloat4ToU32(ImVec4(1, 1, 1, 1)), + operation.m_Name.data()); + } + + void ContextMenu::DrawContextMenuImpl() + { + if (m_Entity.IsValid() && m_Enabled && Features::_ContextMenu.GetState()) + { + if (const auto drawList = ImGui::GetBackgroundDrawList()) + { + int position = 0; + for (const auto& operation : m_CurrentOperationsMenu.m_Operations) + { + DrawOperation(operation, m_ScreenPos, operation == m_CurrentOperationsMenu.m_SelectedOperation, position, drawList); + position++; + } + } + } + } +} \ No newline at end of file diff --git a/src/game/bigfeatures/ContextMenu.hpp b/src/game/frontend/ContextMenu.hpp similarity index 51% rename from src/game/bigfeatures/ContextMenu.hpp rename to src/game/frontend/ContextMenu.hpp index 6e64b451..035211f9 100644 --- a/src/game/bigfeatures/ContextMenu.hpp +++ b/src/game/frontend/ContextMenu.hpp @@ -1,5 +1,6 @@ #pragma once -#include "game/rdr/Natives.hpp" +#include +#include "game/rdr/Entity.hpp" namespace YimMenu { @@ -9,7 +10,7 @@ namespace YimMenu struct ContextMenuOperation { std::string m_Name; - std::function m_Operation; + std::function m_Operation; bool operator==(const ContextMenuOperation& other) const { @@ -75,47 +76,18 @@ namespace YimMenu } bool m_Enabled = false; - int m_EntityHandle{}; - void* m_EntityPointer{}; + + Entity m_Entity = nullptr; ContextOperationsMenu m_CurrentOperationsMenu{}; - bool m_MenuIsInitialized = false; rage::fvector2 m_ScreenPos{}; - double CumulativeDistanceToMiddleOfScreenImpl(rage::fvector2 screenPos); - int GetEntityHandleClosestToMiddleOfScreenImpl(bool includePlayers, bool includePeds, bool includeVehicles, bool includeObjects); - void SetEntityImpl(int handle, void* pointer); - void HandleEntityAndMenuImpl(); + void GameTickImpl(); void DrawContextMenuImpl(); public: - static void Enable() - { - GetInstance().m_Enabled = true; - } - - static void Disable() - { - GetInstance().m_Enabled = false; - } - - static bool* GetEnabled() - { - return &GetInstance().m_Enabled; - } - - static double CumulativeDistanceToMiddleOfScreen(rage::fvector2 screenPos) - { - return GetInstance().CumulativeDistanceToMiddleOfScreenImpl(screenPos); - } - - static int GetEntityHandleClosestToMiddleOfScreen(bool includePlayers, bool includePeds = false, bool includeVehicles = false, bool includeObjects = false) - { - return GetInstance().GetEntityHandleClosestToMiddleOfScreenImpl(includePlayers, includePeds, includeVehicles, includeObjects); - } - - static void HandleEntityAndMenu() + static bool IsEnabled() { - GetInstance().HandleEntityAndMenuImpl(); + return GetInstance().m_Enabled; } static void DrawContextMenu() @@ -123,29 +95,9 @@ namespace YimMenu GetInstance().DrawContextMenuImpl(); } - static void SetEntity(int handle, void* pointer) - { - GetInstance().SetEntityImpl(handle, pointer); - } - - static int GetEntityHandle() - { - return GetInstance().m_EntityHandle; - } - - static void* GetEntityPointer() - { - return GetInstance().m_EntityPointer; - } - - static bool IsMenuIinitialized() - { - return GetInstance().m_MenuIsInitialized; - } - - static rage::fvector2 GetScreenPos() + static void GameTick() { - return GetInstance().m_ScreenPos; + GetInstance().GameTickImpl(); } }; } \ No newline at end of file diff --git a/src/game/bigfeatures/ContextMenus.hpp b/src/game/frontend/ContextMenus.hpp similarity index 55% rename from src/game/bigfeatures/ContextMenus.hpp rename to src/game/frontend/ContextMenus.hpp index f57e69cc..7f1485e2 100644 --- a/src/game/bigfeatures/ContextMenus.hpp +++ b/src/game/frontend/ContextMenus.hpp @@ -10,44 +10,50 @@ namespace YimMenu { - inline ContextOperationsMenu ContextMenuDefault = ContextOperationsMenu("Default", {ContextMenuOperation{"Error", [&] { + inline ContextOperationsMenu ContextMenuDefault = ContextOperationsMenu("Default", {ContextMenuOperation{"Error", [&] (Entity){ }}}); inline ContextOperationsMenu ContextMenuPlayers = ContextOperationsMenu("Players", { ContextMenuOperation{"Set Selected", - [&] { - for (auto [id, plyr] : YimMenu::Players::GetPlayers()) + [&] (Entity entity) { + for (auto& [id, plyr] : YimMenu::Players::GetPlayers()) if (plyr.IsValid() && plyr.GetPed().GetPointer()) - if (ContextMenu::GetEntityHandle() == PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(id)) + if (entity == PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(id)) { YimMenu::Players::SetSelected(id); break; } }}, {"Teleport to", - [&] { - auto playerPos = ENTITY::GET_ENTITY_COORDS(ContextMenu::GetEntityHandle(), false, true); - Teleport::TeleportEntity(Self::PlayerPed, playerPos, false); + [&] (Entity entity) { + Teleport::TeleportEntity(Self::PlayerPed, entity.GetPosition(), false); }}, {"Teleport Behind", - [&] { - auto playerCoords = ENTITY::GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(ContextMenu::GetEntityHandle(), 0, -10, 0); - if (Teleport::TeleportEntity(Self::PlayerPed, playerCoords, true)) + [&] (Entity entity) { + auto playerCoords = ENTITY::GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(entity.GetHandle(), 0, -10, 0); + if (Teleport::TeleportEntity(Self::PlayerPed, {playerCoords.x, playerCoords.y, playerCoords.z}, true)) g_Spectating = false; }}, {"Explode", - [&] { - auto playerPos = ENTITY::GET_ENTITY_COORDS(ContextMenu::GetEntityHandle(), false, true); - FIRE::ADD_EXPLOSION(playerPos.x, playerPos.y, playerPos.z, 22, 1.0f, true, false, 1.0f); + [&] (Entity entity) { + int playerId = -1; + for (auto& [id, plyr] : YimMenu::Players::GetPlayers()) + if (plyr.IsValid() && plyr.GetPed().GetPointer()) + if (entity == PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(id)) + { + playerId = id; + break; + } + Commands::GetCommand("explode"_J)->Call(playerId); }}, {"Set Defensive", - [&] { + [&] (Entity entity) { int playerId = -1; - for (auto [id, plyr] : YimMenu::Players::GetPlayers()) + for (auto& [id, plyr] : YimMenu::Players::GetPlayers()) if (plyr.IsValid() && plyr.GetPed().GetPointer()) - if (ContextMenu::GetEntityHandle() == PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(id)) + if (entity == PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(id)) { playerId = id; break; @@ -55,11 +61,11 @@ namespace YimMenu Commands::GetCommand("defensive"_J)->Call(playerId); }}, {"Set Offensive", - [&] { + [&] (Entity entity) { int playerId = -1; - for (auto [id, plyr] : YimMenu::Players::GetPlayers()) + for (auto& [id, plyr] : YimMenu::Players::GetPlayers()) if (plyr.IsValid() && plyr.GetPed().GetPointer()) - if (ContextMenu::GetEntityHandle() == PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(id)) + if (entity == PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(id)) { playerId = id; break; diff --git a/src/game/frontend/ESP.cpp b/src/game/frontend/ESP.cpp new file mode 100644 index 00000000..b40a4aa3 --- /dev/null +++ b/src/game/frontend/ESP.cpp @@ -0,0 +1,129 @@ +#include "Esp.hpp" + +#include "common.hpp" +#include "game/backend/Players.hpp" +#include "game/features/Features.hpp" +#include "game/pointers/Pointers.hpp" +#include "util/Math.hpp" +#include "core/commands/BoolCommand.hpp" + +namespace +{ + constexpr int headBone = 21030; + constexpr int neckBone = 14283; + constexpr int torsoBone = 14410; + constexpr int leftHandBone = 34606; + constexpr int rightHandBone = 22798; + constexpr int leftFootBone = 45454; + constexpr int rightFootBone = 33646; + constexpr int leftElbowBone = 22711; + constexpr int rightElbowBone = 2992; + constexpr int leftKneeBone = 22173; + constexpr int rightKneeBone = 63133; +} + +namespace YimMenu::Features +{ + BoolCommand _ESP("esp", "ESP", "Draws lines to nearby players and shows their skeleton"); +} + +namespace YimMenu +{ + static ImColor death_bg = ImColor(0.117f, 0.113f, 0.172f, .75f); + static ImColor armor_blue_bg = ImColor(0.36f, 0.71f, 0.89f, .75f); + static ImColor armor_blue = ImColor(0.36f, 0.71f, 0.89f, 1.f); + static ImColor health_green_bg = ImColor(0.29f, 0.69f, 0.34f, .75f); + static ImColor health_green = ImColor(0.29f, 0.69f, 0.34f, 1.f); + static ImColor health_yellow_bg = ImColor(0.69f, 0.49f, 0.29f, .75f); + static ImColor health_yellow = ImColor(0.69f, 0.49f, 0.29f, 1.f); + static ImColor health_red_bg = ImColor(0.69f, 0.29f, 0.29f, .75f); + static ImColor health_red = ImColor(0.69f, 0.29f, 0.29f, 1.f); + static ImColor Green = ImColor(0.29f, 0.69f, 0.34f, 1.f); + static ImColor Orange = ImColor(0.69f, 0.49f, 0.29f, 1.f); + static ImColor Red = ImColor(0.69f, 0.29f, 0.29f, 1.f); + static ImColor Blue = ImColor(0.36f, 0.71f, 0.89f, 1.f); + + static auto boneToScreen = [=](rage::fvector3 bone) -> ImVec2 { + float screen_x, screen_y; + float boneCoords[3] = {bone.x, bone.y, bone.z}; + + Pointers.WorldToScreen(boneCoords, &screen_x, &screen_y); + + return ImVec2(screen_x * Pointers.ScreenResX, screen_y * Pointers.ScreenResY); + }; + + void DrawSkeleton(Player& plyr, ImDrawList* drawList, ImColor color) + { + auto ped = plyr.GetPed(); + + drawList->AddLine(boneToScreen(ped.GetBonePosition(headBone)), boneToScreen(ped.GetBonePosition(neckBone)), color); + + drawList->AddLine(boneToScreen(ped.GetBonePosition(neckBone)), boneToScreen(ped.GetBonePosition(leftElbowBone)), color); + drawList->AddLine(boneToScreen(ped.GetBonePosition(leftElbowBone)), boneToScreen(ped.GetBonePosition(leftHandBone)), color); + + drawList->AddLine(boneToScreen(ped.GetBonePosition(neckBone)), boneToScreen(ped.GetBonePosition(rightElbowBone)), color); + drawList->AddLine(boneToScreen(ped.GetBonePosition(rightElbowBone)), boneToScreen(ped.GetBonePosition(rightHandBone)), color); + + drawList->AddLine(boneToScreen(ped.GetBonePosition(neckBone)), boneToScreen(ped.GetBonePosition(torsoBone)), color); + + drawList->AddLine(boneToScreen(ped.GetBonePosition(torsoBone)), boneToScreen(ped.GetBonePosition(leftKneeBone)), color); + drawList->AddLine(boneToScreen(ped.GetBonePosition(leftKneeBone)), boneToScreen(ped.GetBonePosition(leftFootBone)), color); + + drawList->AddLine(boneToScreen(ped.GetBonePosition(torsoBone)), boneToScreen(ped.GetBonePosition(rightKneeBone)), color); + drawList->AddLine(boneToScreen(ped.GetBonePosition(rightKneeBone)), boneToScreen(ped.GetBonePosition(rightFootBone)), color); + } + + //TODO : Very bare bones currently, expand and possibly refactor + void ESP::DrawPlayer(Player& plyr, ImDrawList* drawList) + { + if (!plyr.IsValid() || !plyr.GetPed().IsValid() || plyr.GetId() == Self::Id || boneToScreen(plyr.GetPed().GetBonePosition(torsoBone)).x == 0) + return; + + float distanceToPlayer = Math::DistanceBetweenVectors(Self::Pos, plyr.GetPed().GetBonePosition(torsoBone)); + int alphaBasedOnDistance = 255; + ImColor colorBasedOnDistance = Red; + + if (distanceToPlayer < 100.f) + colorBasedOnDistance = Green, alphaBasedOnDistance = 255; + else if (distanceToPlayer > 100.f && distanceToPlayer < 300.f) + colorBasedOnDistance = Orange, alphaBasedOnDistance = 200; + else if (distanceToPlayer > 300.f) + colorBasedOnDistance = Red, alphaBasedOnDistance = 125; + + const auto originalFontSize = ImGui::GetFont()->Scale; + auto* currentFont = ImGui::GetFont(); + currentFont->Scale *= 1.2; + ImGui::PushFont(ImGui::GetFont()); + //Name + drawList->AddText(boneToScreen(plyr.GetPed().GetBonePosition(headBone)), plyr == Players::GetSelected() ? Blue : ImColor(255, 255, 255, alphaBasedOnDistance), plyr.GetName()); + //Distance + drawList->AddText({boneToScreen(plyr.GetPed().GetBonePosition(headBone)).x, + boneToScreen(plyr.GetPed().GetBonePosition(headBone)).y + 20}, + colorBasedOnDistance, + std::to_string((int)Math::DistanceBetweenVectors(Self::Pos, plyr.GetPed().GetBonePosition(torsoBone))).data()); + + currentFont->Scale = originalFontSize; + ImGui::PopFont(); + + //TODO Boxes, Distance colors, Friendlies, Tracers, Health bars + + //TODO Make this a setting + if (distanceToPlayer < 100.f) + DrawSkeleton(plyr, drawList, ImColor(255, 255, 255, 255)); + } + + void ESP::Draw() + { + if (!Features::_ESP.GetState()) + return; + + if (const auto drawList = ImGui::GetBackgroundDrawList()) + { + for (auto& [id, player] : Players::GetPlayers()) + { + DrawPlayer(player, drawList); + } + } + } + +} \ No newline at end of file diff --git a/src/game/bigfeatures/Esp.hpp b/src/game/frontend/ESP.hpp similarity index 94% rename from src/game/bigfeatures/Esp.hpp rename to src/game/frontend/ESP.hpp index 14cc2995..7ddcbb1c 100644 --- a/src/game/bigfeatures/Esp.hpp +++ b/src/game/frontend/ESP.hpp @@ -3,7 +3,7 @@ namespace YimMenu { - class Esp + class ESP { public: static void Draw(); diff --git a/src/game/frontend/GUI.cpp b/src/game/frontend/GUI.cpp index c5f6139a..42fe9bc7 100644 --- a/src/game/frontend/GUI.cpp +++ b/src/game/frontend/GUI.cpp @@ -1,9 +1,9 @@ #include "GUI.hpp" #include "Menu.hpp" +#include "ESP.hpp" +#include "ContextMenu.hpp" #include "core/renderer/Renderer.hpp" #include "core/frontend/Notifications.hpp" -#include "game/bigfeatures/Esp.hpp" -#include "game/bigfeatures/ContextMenu.hpp" namespace YimMenu { @@ -25,7 +25,7 @@ namespace YimMenu -2); Renderer::AddRendererCallBack( [&] { - Esp::Draw(); + ESP::Draw(); }, -3); diff --git a/src/game/frontend/Menu.cpp b/src/game/frontend/Menu.cpp index e5ff731f..09d4aabe 100644 --- a/src/game/frontend/Menu.cpp +++ b/src/game/frontend/Menu.cpp @@ -12,6 +12,7 @@ #include "submenus/Debug.hpp" #include "submenus/Players.hpp" #include "submenus/Settings.hpp" +#include "submenus/Network.hpp" namespace YimMenu { @@ -20,6 +21,7 @@ namespace YimMenu // Arguably the only place this file should be edited at for more menus UIManager::AddSubmenu(std::make_shared()); UIManager::AddSubmenu(std::make_shared()); + UIManager::AddSubmenu(std::make_shared()); UIManager::AddSubmenu(std::make_shared()); UIManager::AddSubmenu(std::make_shared()); UIManager::AddSubmenu(std::make_shared()); diff --git a/src/game/frontend/items/Items.hpp b/src/game/frontend/items/Items.hpp index 35b16c40..ef817508 100644 --- a/src/game/frontend/items/Items.hpp +++ b/src/game/frontend/items/Items.hpp @@ -5,6 +5,7 @@ namespace YimMenu { class BoolCommand; + class PlayerCommand; class Command; inline ImVec2 GetListBoxDimensions() @@ -35,6 +36,16 @@ namespace YimMenu Command* m_Command; }; + class PlayerCommandItem : public UIItem + { + public: + explicit PlayerCommandItem(joaat_t id); + void Draw() override; + + private: + PlayerCommand* m_Command; + }; + class BoolCommandItem : public UIItem { public: diff --git a/src/game/frontend/items/PlayerCommandItem.cpp b/src/game/frontend/items/PlayerCommandItem.cpp new file mode 100644 index 00000000..4ac26b71 --- /dev/null +++ b/src/game/frontend/items/PlayerCommandItem.cpp @@ -0,0 +1,30 @@ +#include "Items.hpp" +#include "game/commands/PlayerCommand.hpp" +#include "core/commands/Commands.hpp" +#include "game/backend/FiberPool.hpp" +#include "game/backend/Players.hpp" + +namespace YimMenu +{ + PlayerCommandItem::PlayerCommandItem(joaat_t id) : + m_Command(Commands::GetCommand(id)) + { + } + + void PlayerCommandItem::Draw() + { + if (!m_Command) + { + ImGui::Text("Unknown!"); + return; + } + + if (ImGui::Button(m_Command->GetLabel().data())) + { + FiberPool::Push([this] { + if (Players::GetSelected().IsValid()) + m_Command->Call(Players::GetSelected()); + }); + } + } +} \ No newline at end of file diff --git a/src/game/frontend/submenus/Debug.cpp b/src/game/frontend/submenus/Debug.cpp index 18827047..aeba4889 100644 --- a/src/game/frontend/submenus/Debug.cpp +++ b/src/game/frontend/submenus/Debug.cpp @@ -270,6 +270,7 @@ namespace YimMenu::Submenus debug->AddItem(std::make_shared("logclones"_J)); debug->AddItem(std::make_shared("logevents"_J)); debug->AddItem(std::make_shared("logtses"_J)); + debug->AddItem(std::make_shared("logmetrics"_J)); AddCategory(std::move(debug)); } } \ No newline at end of file diff --git a/src/game/frontend/submenus/Network.cpp b/src/game/frontend/submenus/Network.cpp new file mode 100644 index 00000000..fb812e11 --- /dev/null +++ b/src/game/frontend/submenus/Network.cpp @@ -0,0 +1,22 @@ +#include "Network.hpp" +#include "core/commands/Commands.hpp" +#include "core/commands/HotkeySystem.hpp" +#include "core/commands/LoopedCommand.hpp" +#include "game/features/Features.hpp" +#include "game/frontend/items/Items.hpp" + +namespace YimMenu::Submenus +{ + Network::Network() : + Submenu::Submenu("Network") + { + auto session = std::make_shared("Session"); + auto spoofing = std::make_shared("Spoofing"); + session->AddItem(std::make_shared("explodeall"_J)); + session->AddItem(std::make_shared("maxhonorall"_J)); + session->AddItem(std::make_shared("minhonorall"_J)); + spoofing->AddItem(std::make_shared("hidegod"_J)); + AddCategory(std::move(session)); + AddCategory(std::move(spoofing)); + } +} \ No newline at end of file diff --git a/src/game/frontend/submenus/Network.hpp b/src/game/frontend/submenus/Network.hpp new file mode 100644 index 00000000..05fe4e80 --- /dev/null +++ b/src/game/frontend/submenus/Network.hpp @@ -0,0 +1,11 @@ +#pragma once +#include "core/frontend/manager/UIManager.hpp" + +namespace YimMenu::Submenus +{ + class Network : public Submenu + { + public: + Network(); + }; +} \ No newline at end of file diff --git a/src/game/frontend/submenus/Players.cpp b/src/game/frontend/submenus/Players.cpp index a79cd7b7..27b37aef 100644 --- a/src/game/frontend/submenus/Players.cpp +++ b/src/game/frontend/submenus/Players.cpp @@ -1,19 +1,26 @@ #include "Players.hpp" #include "core/commands/Commands.hpp" -#include "game/backend/FiberPool.hpp" #include "game/backend/Players.hpp" #include "game/commands/PlayerCommand.hpp" #include "game/features/Features.hpp" #include "game/frontend/items/Items.hpp" -#include "game/rdr/Natives.hpp" #include "util/teleport.hpp" #include "util/network.hpp" +// remove after testing +#include "game/rdr/Natives.hpp" +#include "game/backend/ScriptMgr.hpp" +#include "game/backend/FiberPool.hpp" +#include "game/rdr/ScriptGlobal.hpp" +#include "game/rdr/Scripts.hpp" +#include