From ce78dd94a43a148dd4f0b9ec3cebc9666591f147 Mon Sep 17 00:00:00 2001 From: CSY0N <134310111+CSY0N@users.noreply.github.com> Date: Wed, 23 Apr 2025 01:06:57 +0200 Subject: [PATCH 1/2] Fixed Mobile Radio (#226) * mobile_radio.cpp * Update Self.cpp * Update Self.cpp Fixed Mobile Radio now you can activate it and deactivate it * Update mobile_radio.cpp * Rename mobile_radio.cpp to MobileRadio.cpp --- src/game/features/self/{mobile_radio.cpp => MobileRadio.cpp} | 2 +- src/game/frontend/submenus/Self.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/game/features/self/{mobile_radio.cpp => MobileRadio.cpp} (77%) diff --git a/src/game/features/self/mobile_radio.cpp b/src/game/features/self/MobileRadio.cpp similarity index 77% rename from src/game/features/self/mobile_radio.cpp rename to src/game/features/self/MobileRadio.cpp index 1a2103d..8d4670e 100644 --- a/src/game/features/self/mobile_radio.cpp +++ b/src/game/features/self/MobileRadio.cpp @@ -22,5 +22,5 @@ namespace YimMenu::Features } }; - static MobileRadio _MobileRadio{"mobileradio", "listen any radio station on foot", "Allows you to listen to any radio station on foot with Hotkey Q"}; + static MobileRadio _MobileRadio{"mobileradio", "Mobile Radio", "Allows you to listen to any radio station on foot with Hotkey Q"}; } diff --git a/src/game/frontend/submenus/Self.cpp b/src/game/frontend/submenus/Self.cpp index 6b90c6a..a7b09f7 100644 --- a/src/game/frontend/submenus/Self.cpp +++ b/src/game/frontend/submenus/Self.cpp @@ -38,7 +38,7 @@ namespace YimMenu::Submenus toolsGroup->AddItem(std::make_shared("heal"_J)); toolsGroup->AddItem(std::make_shared("cleardamage"_J)); toolsGroup->AddItem(std::make_shared("fillinventory"_J)); - toolsGroup->AddItem(std::make_shared("MobileRadio"_J)); + toolsGroup->AddItem(std::make_shared("MobileRadio"_J)); movementGroup->AddItem(std::make_shared("standonvehicles"_J)); movementGroup->AddItem(std::make_shared("disableactionmode"_J)); From 0cfdf9ff3c37043fc8968ec6ab225e7ef489d5ef Mon Sep 17 00:00:00 2001 From: Arthur <121949966+ShinyWasabi@users.noreply.github.com> Date: Wed, 23 Apr 2025 23:44:56 +0300 Subject: [PATCH 2/2] feat: Open Wardrobe (#234) --- src/game/features/self/OpenWardrobe.cpp | 130 ++++++++++++++++++++++++ src/game/frontend/submenus/Self.cpp | 19 ++-- 2 files changed, 140 insertions(+), 9 deletions(-) create mode 100644 src/game/features/self/OpenWardrobe.cpp diff --git a/src/game/features/self/OpenWardrobe.cpp b/src/game/features/self/OpenWardrobe.cpp new file mode 100644 index 0000000..9f60f19 --- /dev/null +++ b/src/game/features/self/OpenWardrobe.cpp @@ -0,0 +1,130 @@ +#include "core/commands/Command.hpp" +#include "core/backend/ScriptMgr.hpp" +#include "core/frontend/Notifications.hpp" +#include "game/backend/Self.hpp" +#include "game/backend/ScriptPatches.hpp" +#include "game/backend/NativeHooks.hpp" +#include "game/gta/Natives.hpp" +#include "game/gta/Scripts.hpp" +#include "game/gta/ScriptLocal.hpp" +#include "game/pointers/Pointers.hpp" +#include "types/script/types.hpp" + +namespace YimMenu::Features +{ + struct WARDROBE_LAUNCH_DATA + { + SCR_INT Type; + SCR_VEC3 Position; + SCR_FLOAT Heading; + }; + + static bool startedByUs{}; + static ScriptPatch shouldCleanupWardrobePatch{}; + static ScriptPatch isWardrobeOpenedPatch{}; + static ScriptPatch doesPlayerOwnItemPatch{}; + static ScriptPatch isItemLockedByStatPatch1{}; + static ScriptPatch isItemLockedByStatPatch2{}; + static ScriptPatch isItemLockedByStatPatch3{}; + static void GetDistanceBetweenCoordsHook(rage::scrNativeCallContext* ctx); + + class OpenWardrobe : public Command + { + using Command::Command; + + virtual void OnCall() override + { + if (!*Pointers.IsSessionStarted || SCRIPT::GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH("wardrobe_mp"_J) > 0) + { + Notifications::Show("Wardrobe", "Not safe to open the wardrobe at the moment.", NotificationType::Error); + return; + } + + while (!SCRIPT::HAS_SCRIPT_WITH_NAME_HASH_LOADED("wardrobe_mp"_J)) + { + SCRIPT::REQUEST_SCRIPT_WITH_NAME_HASH("wardrobe_mp"_J); + ScriptMgr::Yield(); + } + + WARDROBE_LAUNCH_DATA launchData; + launchData.Type = 7; + launchData.Position = Self::GetPed().GetPosition(); + launchData.Heading = Self::GetPed().GetHeading(); + if (!BUILTIN::START_NEW_SCRIPT_WITH_NAME_HASH_AND_ARGS("wardrobe_mp"_J, &launchData, sizeof(launchData) / 8, 2324)) + { + Notifications::Show("Wardrobe", "Failed to open the wardrobe.", NotificationType::Error); + return; + } + + if (!shouldCleanupWardrobePatch) + { + shouldCleanupWardrobePatch = ScriptPatches::AddPatch("wardrobe_mp"_J, ScriptPointer("ShouldCleanupWardrobePatch", "2C 01 00 40 2C 05 02 69 06 56 1C 07"), {0x72, 0x2E, 0x05, 0x01}); + } + shouldCleanupWardrobePatch->Enable(); + + if (!isWardrobeOpenedPatch) + { + isWardrobeOpenedPatch = ScriptPatches::AddPatch("wardrobe_mp"_J, ScriptPointer("IsWardrobeOpenedPatch", "56 22 00 71"), {0x2B, 0x00, 0x00}); + } + isWardrobeOpenedPatch->Enable(); + + if (!doesPlayerOwnItemPatch) + { + doesPlayerOwnItemPatch = ScriptPatches::AddPatch("wardrobe_mp"_J, ScriptPointer("DoesPlayerOwnItemPatch", "57 D2 00 38 08"), {0x55}); + } + doesPlayerOwnItemPatch->Enable(); + + if (!isItemLockedByStatPatch1) + { + isItemLockedByStatPatch1 = ScriptPatches::AddPatch("wardrobe_mp"_J, ScriptPointer("IsItemLockedByStatPatch1", "38 00 65 02 F7 B6 C6 31 09 00 31 46 A9 B0 28 04"), {0x71, 0x2E, 0x03, 0x01}); + } + isItemLockedByStatPatch1->Enable(); + + if (!isItemLockedByStatPatch2) + { + isItemLockedByStatPatch2 = ScriptPatches::AddPatch("wardrobe_mp"_J, ScriptPointer("IsItemLockedByStatPatch2", "38 00 65 04 90 44 B3 80 15 00 CB C8 CF 72 0F 00 87 81 38 F6 1C 00 31 48 DE 94 16 00"), {0x72, 0x2E, 0x03, 0x01}); + } + isItemLockedByStatPatch2->Enable(); + + if (!isItemLockedByStatPatch3) + { + isItemLockedByStatPatch3 = ScriptPatches::AddPatch("wardrobe_mp"_J, ScriptPointer("IsItemLockedByStatPatch3", "38 00 65 01 34 ED 23 4E 03 00"), {0x72, 0x2E, 0x03, 0x01}); + } + isItemLockedByStatPatch3->Enable(); + + NativeHooks::AddHook("wardrobe_mp"_J, NativeIndex::GET_DISTANCE_BETWEEN_COORDS, &GetDistanceBetweenCoordsHook); + + SCRIPT::SET_SCRIPT_WITH_NAME_HASH_AS_NO_LONGER_NEEDED("wardrobe_mp"_J); + + startedByUs = true; + } + }; + + static OpenWardrobe _OpenWardrobe{"openwardrobe", "Open Wardrobe", "Allows you to access your wardrobe remotely."}; + + static void GetDistanceBetweenCoordsHook(rage::scrNativeCallContext* ctx) + { + auto distance = MISC::GET_DISTANCE_BETWEEN_COORDS(ctx->GetArg(0), ctx->GetArg(1), ctx->GetArg(2), ctx->GetArg(3), ctx->GetArg(4), ctx->GetArg(5), ctx->GetArg(6)); + + if (startedByUs) + { + if (auto thread = Scripts::FindScriptThread("wardrobe_mp"_J)) + { + if (*ScriptLocal(thread, 187).At(46).At(9).As() == 4) + { + shouldCleanupWardrobePatch->Disable(); + isWardrobeOpenedPatch->Disable(); + doesPlayerOwnItemPatch->Disable(); + isItemLockedByStatPatch1->Disable(); + isItemLockedByStatPatch2->Disable(); + isItemLockedByStatPatch3->Disable(); + + startedByUs = false; + distance = 9999.f; + } + } + } + + ctx->SetReturnValue((float)distance); + } +} \ No newline at end of file diff --git a/src/game/frontend/submenus/Self.cpp b/src/game/frontend/submenus/Self.cpp index a7b09f7..33e1b13 100644 --- a/src/game/frontend/submenus/Self.cpp +++ b/src/game/frontend/submenus/Self.cpp @@ -11,8 +11,8 @@ namespace YimMenu::Submenus auto main = std::make_shared("Main"); auto globalsGroup = std::make_shared("Globals"); auto movementGroup = std::make_shared("Movement"); - auto wantedGroup = std::make_shared("Wanted"); auto toolsGroup = std::make_shared("Tools", 1); + auto wantedGroup = std::make_shared("Wanted"); globalsGroup->AddItem(std::make_shared("godmode"_J)); globalsGroup->AddItem(std::make_shared("invis"_J)); @@ -22,6 +22,14 @@ namespace YimMenu::Submenus globalsGroup->AddItem(std::make_shared("noidlekick"_J)); globalsGroup->AddItem(std::make_shared("unlimitedoxygen"_J)); globalsGroup->AddItem(std::make_shared("formatmoney"_J)); + globalsGroup->AddItem(std::make_shared("mobileradio"_J)); + + toolsGroup->AddItem(std::make_shared("skipcutscene"_J)); + toolsGroup->AddItem(std::make_shared("suicide"_J)); + toolsGroup->AddItem(std::make_shared("heal"_J)); + toolsGroup->AddItem(std::make_shared("cleardamage"_J)); + toolsGroup->AddItem(std::make_shared("fillinventory"_J)); + toolsGroup->AddItem(std::make_shared("openwardrobe"_J)); auto clearWanted = std::make_shared("", 1); clearWanted->AddItem(std::make_shared("neverwanted"_J, std::make_shared("clearwanted"_J), true)); @@ -32,13 +40,6 @@ namespace YimMenu::Submenus setWanted->AddItem(std::make_shared("freezewanted"_J)); wantedGroup->AddItem(std::make_shared("freezewanted"_J, clearWanted, true)); wantedGroup->AddItem(std::make_shared("neverwanted"_J, setWanted, true)); - - toolsGroup->AddItem(std::make_shared("skipcutscene"_J)); - toolsGroup->AddItem(std::make_shared("suicide"_J)); - toolsGroup->AddItem(std::make_shared("heal"_J)); - toolsGroup->AddItem(std::make_shared("cleardamage"_J)); - toolsGroup->AddItem(std::make_shared("fillinventory"_J)); - toolsGroup->AddItem(std::make_shared("MobileRadio"_J)); movementGroup->AddItem(std::make_shared("standonvehicles"_J)); movementGroup->AddItem(std::make_shared("disableactionmode"_J)); @@ -50,8 +51,8 @@ namespace YimMenu::Submenus movementGroup->AddItem(std::make_shared("freecam"_J, std::make_shared("freecamspeed"_J))); main->AddItem(globalsGroup); - main->AddItem(wantedGroup); main->AddItem(toolsGroup); + main->AddItem(wantedGroup); main->AddItem(movementGroup); AddCategory(std::move(main));