Skip to content

Commit d9fefd3

Browse files
authored
Merge branch 'YimMenu:enhanced' into feature/OutfitEditor
2 parents d869b6d + a5a8594 commit d9fefd3

File tree

13 files changed

+176
-21
lines changed

13 files changed

+176
-21
lines changed

src/core/memory/BytePatches.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ namespace YimMenu
44
{
55
BytePatches::Patch::~Patch()
66
{
7-
Restore();
7+
88
}
99

1010
void BytePatches::Patch::Apply()
@@ -38,6 +38,8 @@ namespace YimMenu
3838

3939
void BytePatches::Remove(std::shared_ptr<Patch>& patch)
4040
{
41+
patch->Restore();
42+
4143
if (const auto it = std::find(m_Patches.begin(), m_Patches.end(), patch.get()); it != m_Patches.end())
4244
{
4345
m_Patches.erase(it);
@@ -47,6 +49,11 @@ namespace YimMenu
4749

4850
void BytePatches::RestoreAll()
4951
{
52+
for (auto& patch : m_Patches)
53+
{
54+
patch->Restore();
55+
}
56+
5057
m_Patches.clear();
5158
}
5259
}

src/game/backend/SavedPlayers.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ namespace YimMenu
5555

5656
SavedPlayers::~SavedPlayers()
5757
{
58-
m_FetchPlayerInfoMutex.unlock();
5958
}
6059

6160
void SavedPlayers::UpdateFetchedData(SavedPlayerData& saved_data, const FetchedPlayerData& fetched_data)
@@ -141,14 +140,17 @@ namespace YimMenu
141140

142141
void SavedPlayers::FetchPlayerInfoImpl(bool tracked_only)
143142
{
144-
std::lock_guard guard(m_FetchPlayerInfoMutex);
143+
if (m_FetchingPlayerInfo)
144+
return;
145145

146146
if (!Pointers.GetPresenceAttributes)
147147
{
148148
LOG(WARNING) << "Socialclub.dll not loaded, cannot fetch player info";
149149
return;
150150
}
151151

152+
m_FetchingPlayerInfo = true;
153+
152154
std::vector<std::vector<rage::rlScGamerHandle>> player_buckets;
153155
int current_bucket_idx = 0;
154156

@@ -241,6 +243,8 @@ namespace YimMenu
241243
// failed, do something here?
242244
LOG(WARNING) << "Failed to start get presence attributes task";
243245
}
246+
247+
m_FetchingPlayerInfo = false;
244248
}
245249
}
246250

src/game/backend/SavedPlayers.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace YimMenu
1010
static constexpr auto AUTO_REFRESH_TIME = 3min;
1111

1212
std::unordered_map<std::uint64_t, SavedPlayerData> m_SavedPlayers;
13-
std::mutex m_FetchPlayerInfoMutex;
13+
bool m_FetchingPlayerInfo;
1414
std::filesystem::path m_PlayersFile;
1515
std::chrono::system_clock::time_point m_LastPlayerInfoFetch;
1616

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#include "core/commands/Command.hpp"
2+
#include "types/script/ScriptEvent.hpp"
3+
4+
namespace YimMenu::Features
5+
{
6+
class ForceLaunchHeist : public Command
7+
{
8+
using Command::Command;
9+
10+
virtual void OnCall() override
11+
{
12+
SCRIPT_EVENT_COMMAND event;
13+
event.Command = SCRIPT_EVENT_COMMAND::eCommand::LaunchHeist;
14+
event.SetAllPlayers();
15+
event.Send();
16+
}
17+
};
18+
19+
static ForceLaunchHeist _ForceLaunchHeist{"forcelaunchheist", "Force Launch Heist", "Forces the heist to launch from the setup screen"};
20+
}

src/game/features/recovery/PlayAllMissionsSolo.cpp

Lines changed: 72 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
#include "core/commands/BoolCommand.hpp"
1+
#include "core/commands/LoopedCommand.hpp"
22
#include "game/backend/ScriptPatches.hpp"
3+
#include "game/gta/Natives.hpp"
34

45
namespace YimMenu::Features
56
{
6-
class PlayAllMissionsSolo : public BoolCommand
7+
class PlayAllMissionsSolo : public LoopedCommand
78
{
8-
using BoolCommand::BoolCommand;
9+
using LoopedCommand::LoopedCommand;
910

1011
ScriptPatch m_CanLaunchJobPatch{};
1112
ScriptPatch m_MissionRequestPatch1{}; // TODO: do we need these patches?
@@ -19,16 +20,21 @@ namespace YimMenu::Features
1920
ScriptPatch m_ShouldFailMissionPatch1{}; // god I hate this function
2021
std::vector<ScriptPatch> m_ShouldFailMissionPatches{};
2122
ScriptPatch m_ShouldFailMissionPatch2{};
22-
ScriptPatch m_EnsureMissionPassedPatch{};
23+
ScriptPatch m_ShouldFailMissionPatch3{};
24+
ScriptPatch m_NotEnoughTeamsPatch{};
25+
ScriptPatch m_IsTeamValidPatch{}; // TODO: probably has many unintended side effects
26+
ScriptPatch m_EnsureMissionPassedPatch{};
27+
ScriptPatch m_ProcessPhoneHackingPatch{};
2328

2429
virtual void OnEnable() override
2530
{
2631
if (!m_CanLaunchJobPatch)
2732
{
28-
m_CanLaunchJobPatch = ScriptPatches::AddPatch("fmmc_launcher"_J, "2D 05 0C 00 00 71", 5, {0x72, 0x2E, 0x05, 0x01});
33+
m_CanLaunchJobPatch = ScriptPatches::AddPatch("fmmc_launcher"_J, "2D 05 0C 00 00 71", 5, {0x72, 0x2E, 0x05, 0x01}); // the main patch that bypasses the not enough players alert
2934
}
3035
m_CanLaunchJobPatch->Enable();
3136

37+
// these patches allow the mission request system to launch fm_mission_controller with insufficent players
3238
if (!m_MissionRequestPatch1)
3339
{
3440
m_MissionRequestPatch1 = ScriptPatches::AddPatch("freemode"_J, "38 00 72 5D ? ? ? 38 00 5D ? ? ? 2E 02 00 38 00 38 01", 0, std::vector<std::uint8_t>(14, 0x0));
@@ -55,7 +61,7 @@ namespace YimMenu::Features
5561

5662
if (!m_PlayerCountWatchdogPatch1)
5763
{
58-
m_PlayerCountWatchdogPatch1 = ScriptPatches::AddPatch("fmmc_launcher"_J, "2D 02 09 00 00 25 A4", 5, {0x71, 0x2E, 0x02, 0x01});
64+
m_PlayerCountWatchdogPatch1 = ScriptPatches::AddPatch("fmmc_launcher"_J, "2D 02 09 00 00 25 A4", 5, {0x71, 0x2E, 0x02, 0x01}); // instant kick if this check fails
5965
}
6066
m_PlayerCountWatchdogPatch1->Enable();
6167

@@ -67,10 +73,10 @@ namespace YimMenu::Features
6773

6874
if (!m_HeistTeamsPatch1)
6975
{
70-
m_HeistTeamsPatch1 = ScriptPatches::AddPatch("fmmc_launcher"_J, "47 ? ? 5B 7B 00 38 04", 0, {0x2B, 0x2B, 0x00, 0x55});
76+
m_HeistTeamsPatch1 = ScriptPatches::AddPatch("fmmc_launcher"_J, "47 ? ? 5B 7B 00 38 04", 0, {0x2B, 0x2B, 0x00, 0x55}); // TODO: doesn't work for doomsday heist
7177
}
7278
m_HeistTeamsPatch1->Enable();
73-
79+
7480
if (!m_HeistTeamsPatch2)
7581
{
7682
m_HeistTeamsPatch2 = ScriptPatches::AddPatch("fmmc_launcher"_J, "2D 01 05 00 00 25 5D", 5, {0x72, 0x2E, 0x01, 0x01});
@@ -86,6 +92,7 @@ namespace YimMenu::Features
8692
if (m_ShouldFailMissionPatches.empty())
8793
{
8894
// TODO: this is a very bad idea that can break anytime
95+
// for some reason, Rockstar thought it's a good idea to copy-paste the same failure check in four different branches, "just in case"
8996
for (int i = 0; i < 4; i++)
9097
m_ShouldFailMissionPatches.push_back(ScriptPatches::AddPatch("fm_mission_controller"_J, "38 02 5D ? ? ? 71 09 2A 56 07 00 71 5D ? ? ? 06 1F 56", 0, {0x71, 0x00, 0x00, 0x00, 0x00, 0x00}));
9198
}
@@ -95,15 +102,50 @@ namespace YimMenu::Features
95102

96103
if (!m_ShouldFailMissionPatch2)
97104
{
98-
m_ShouldFailMissionPatch2 = ScriptPatches::AddPatch("fm_mission_controller"_J, "56 07 00 38 02 5D ? ? ? 20 56 BC 01", 0, {0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x71});
105+
m_ShouldFailMissionPatch2 = ScriptPatches::AddPatch("fm_mission_controller"_J, "56 07 00 38 02 5D ? ? ? 20 56 BC 01", 0, {0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x71}); // some heist check, more or less same as above
99106
}
100107
m_ShouldFailMissionPatch2->Enable();
108+
109+
if (!m_ShouldFailMissionPatch3)
110+
{
111+
m_ShouldFailMissionPatch3 = ScriptPatches::AddPatch("fm_mission_controller"_J, "50 ? ? 78 82 06 1F 56 2E 01", 0, {0x00, 0x00, 0x00, 0x00, 0x72});
112+
}
113+
m_ShouldFailMissionPatch3->Enable();
114+
115+
if (!m_NotEnoughTeamsPatch)
116+
{
117+
m_NotEnoughTeamsPatch = ScriptPatches::AddPatch("fm_mission_controller"_J, "2D 00 02 00 00 61 ? ? ? 47 ? ? 72 57 04 00 72 2E 00 01 4F", 5, {0x71, 0x2E, 0x00, 0x01});
118+
}
119+
m_NotEnoughTeamsPatch->Enable();
120+
121+
if (!m_IsTeamValidPatch)
122+
{
123+
m_IsTeamValidPatch = ScriptPatches::AddPatch("fm_mission_controller"_J, "2D 01 03 00 00 38 00 71 57 1D 00", 5, {0x72, 0x2E, 0x01, 0x01});
124+
}
125+
m_IsTeamValidPatch->Enable();
101126

102127
if (!m_EnsureMissionPassedPatch)
103128
{
104-
m_EnsureMissionPassedPatch = ScriptPatches::AddPatch("fm_mission_controller"_J, "55 C8 FF 61", 3, {0x2E, 0x00, 0x00});
129+
m_EnsureMissionPassedPatch = ScriptPatches::AddPatch("fm_mission_controller"_J, "55 C8 FF 61", 3, {0x2E, 0x00, 0x00}); // the game does one final check to ensure all players exist before the mission is passed
105130
}
106131
m_EnsureMissionPassedPatch->Enable();
132+
133+
if (!m_ProcessPhoneHackingPatch)
134+
{
135+
m_ProcessPhoneHackingPatch = ScriptPatches::AddPatch("fm_mission_controller"_J, "58 13 00 38 00 4F ? ? 48", 0, {0x2B, 0x00, 0x00});
136+
}
137+
}
138+
139+
virtual void OnTick() override
140+
{
141+
if (m_ProcessPhoneHackingPatch)
142+
{
143+
// the patch transfers the hacking minigame from the passenger to the driver, so we only want it applied when we're playing solo
144+
if (SCRIPT::GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH("fm_mission_controller"_J) && NETWORK::NETWORK_GET_TOTAL_NUM_PLAYERS() == 1)
145+
m_ProcessPhoneHackingPatch->Enable();
146+
else
147+
m_ProcessPhoneHackingPatch->Disable();
148+
}
107149
}
108150

109151
virtual void OnDisable() override
@@ -166,10 +208,30 @@ namespace YimMenu::Features
166208
m_ShouldFailMissionPatch2->Disable();
167209
}
168210

211+
if (m_ShouldFailMissionPatch3)
212+
{
213+
m_ShouldFailMissionPatch3->Disable();
214+
}
215+
216+
if (m_NotEnoughTeamsPatch)
217+
{
218+
m_NotEnoughTeamsPatch->Disable();
219+
}
220+
221+
if (m_IsTeamValidPatch)
222+
{
223+
m_IsTeamValidPatch->Disable();
224+
}
225+
169226
if (m_EnsureMissionPassedPatch)
170227
{
171228
m_EnsureMissionPassedPatch->Disable();
172229
}
230+
231+
if (m_ProcessPhoneHackingPatch)
232+
{
233+
m_ProcessPhoneHackingPatch->Disable();
234+
}
173235
}
174236
};
175237

src/game/frontend/submenus/Debug.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "Debug/Globals.hpp"
44
#include "Debug/Locals.hpp"
55
//#include "Debug/Scripts.hpp"
6+
#include "Debug/Misc.hpp"
67

78
#include "game/frontend/items/Items.hpp"
89

@@ -15,5 +16,6 @@ namespace YimMenu::Submenus
1516
{
1617
AddCategory(BuildGlobalsMenu());
1718
AddCategory(BuildLocalsMenu());
19+
AddCategory(BuildMiscMenu());
1820
}
1921
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#include "DrawVariable.hpp"
2+
#include "Locals.hpp"
3+
#include "core/filemgr/FileMgr.hpp"
4+
#include "game/backend/Self.hpp"
5+
#include "game/pointers/Pointers.hpp"
6+
#include "core/backend/FiberPool.hpp"
7+
#include "game/gta/ScriptFunction.hpp"
8+
9+
namespace YimMenu::Submenus
10+
{
11+
std::shared_ptr<Category> BuildMiscMenu()
12+
{
13+
auto misc = std::make_unique<Category>("Misc");
14+
15+
misc->AddItem(std::make_unique<ImGuiItem>([] {
16+
static int team;
17+
ImGui::InputInt("Team", &team);
18+
if (ImGui::Button("fm_mission_controller DoTeamSwap"))
19+
{
20+
FiberPool::Push([] {
21+
static ScriptFunction DoTeamSwap("DoTeamSwap", "fm_mission_controller"_J, "2D 02 04 00 00 38 00 50");
22+
DoTeamSwap.Call<void>(team, true);
23+
});
24+
}
25+
}));
26+
27+
return misc;
28+
}
29+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#pragma once
2+
#include "core/frontend/manager/Category.hpp"
3+
#include "game/frontend/items/Items.hpp"
4+
5+
namespace YimMenu::Submenus
6+
{
7+
std::shared_ptr<Category> BuildMiscMenu();
8+
}

src/game/frontend/submenus/Network/SavedPlayers.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,8 @@ namespace YimMenu::Submenus
167167
g_SelectedPlayer = nullptr;
168168
g_SelectedRid = 0;
169169
}
170-
171-
ImGui::EndChild();
172170
}
171+
ImGui::EndChild();
173172
}
174173

175174
static void RenderSavedPlayers()

src/game/frontend/submenus/Recovery.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ namespace YimMenu::Submenus
2727
}
2828
}));
2929

30-
generalGroup->AddItem(std::make_shared<CommandItem>("playallmissionssolo"_J));
30+
generalGroup->AddItem(std::make_shared<BoolCommandItem>("playallmissionssolo"_J));
31+
generalGroup->AddItem(std::make_shared<CommandItem>("forcelaunchheist"_J));
3132

3233
cayoPericoGroup->AddItem(std::make_shared<CommandItem>("skipcayosetup"_J));
3334
cayoPericoGroup->AddItem(std::make_shared<CommandItem>("skipcayocooldown"_J));

0 commit comments

Comments
 (0)