general fixes

This commit is contained in:
maybegreat48
2025-04-11 14:35:15 -04:00
parent 629572cabe
commit f130c126e6
11 changed files with 167 additions and 18 deletions
+6 -2
View File
@@ -55,7 +55,6 @@ namespace YimMenu
SavedPlayers::~SavedPlayers()
{
m_FetchPlayerInfoMutex.unlock();
}
void SavedPlayers::UpdateFetchedData(SavedPlayerData& saved_data, const FetchedPlayerData& fetched_data)
@@ -141,7 +140,8 @@ namespace YimMenu
void SavedPlayers::FetchPlayerInfoImpl(bool tracked_only)
{
std::lock_guard guard(m_FetchPlayerInfoMutex);
if (m_FetchingPlayerInfo)
return;
if (!Pointers.GetPresenceAttributes)
{
@@ -149,6 +149,8 @@ namespace YimMenu
return;
}
m_FetchingPlayerInfo = true;
std::vector<std::vector<rage::rlScGamerHandle>> player_buckets;
int current_bucket_idx = 0;
@@ -241,6 +243,8 @@ namespace YimMenu
// failed, do something here?
LOG(WARNING) << "Failed to start get presence attributes task";
}
m_FetchingPlayerInfo = false;
}
}
+1 -1
View File
@@ -10,7 +10,7 @@ namespace YimMenu
static constexpr auto AUTO_REFRESH_TIME = 3min;
std::unordered_map<std::uint64_t, SavedPlayerData> m_SavedPlayers;
std::mutex m_FetchPlayerInfoMutex;
bool m_FetchingPlayerInfo;
std::filesystem::path m_PlayersFile;
std::chrono::system_clock::time_point m_LastPlayerInfoFetch;
@@ -0,0 +1,20 @@
#include "core/commands/Command.hpp"
#include "types/script/ScriptEvent.hpp"
namespace YimMenu::Features
{
class ForceLaunchHeist : public Command
{
using Command::Command;
virtual void OnCall() override
{
SCRIPT_EVENT_COMMAND event;
event.Command = SCRIPT_EVENT_COMMAND::eCommand::LaunchHeist;
event.SetAllPlayers();
event.Send();
}
};
static ForceLaunchHeist _ForceLaunchHeist{"forcelaunchheist", "Force Launch Heist", "Forces the heist to launch from the setup screen"};
}
@@ -1,11 +1,12 @@
#include "core/commands/BoolCommand.hpp"
#include "core/commands/LoopedCommand.hpp"
#include "game/backend/ScriptPatches.hpp"
#include "game/gta/Natives.hpp"
namespace YimMenu::Features
{
class PlayAllMissionsSolo : public BoolCommand
class PlayAllMissionsSolo : public LoopedCommand
{
using BoolCommand::BoolCommand;
using LoopedCommand::LoopedCommand;
ScriptPatch m_CanLaunchJobPatch{};
ScriptPatch m_MissionRequestPatch1{}; // TODO: do we need these patches?
@@ -19,16 +20,21 @@ namespace YimMenu::Features
ScriptPatch m_ShouldFailMissionPatch1{}; // god I hate this function
std::vector<ScriptPatch> m_ShouldFailMissionPatches{};
ScriptPatch m_ShouldFailMissionPatch2{};
ScriptPatch m_EnsureMissionPassedPatch{};
ScriptPatch m_ShouldFailMissionPatch3{};
ScriptPatch m_NotEnoughTeamsPatch{};
ScriptPatch m_IsTeamValidPatch{}; // TODO: probably has many unintended side effects
ScriptPatch m_EnsureMissionPassedPatch{};
ScriptPatch m_ProcessPhoneHackingPatch{};
virtual void OnEnable() override
{
if (!m_CanLaunchJobPatch)
{
m_CanLaunchJobPatch = ScriptPatches::AddPatch("fmmc_launcher"_J, "2D 05 0C 00 00 71", 5, {0x72, 0x2E, 0x05, 0x01});
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
}
m_CanLaunchJobPatch->Enable();
// these patches allow the mission request system to launch fm_mission_controller with insufficent players
if (!m_MissionRequestPatch1)
{
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
if (!m_PlayerCountWatchdogPatch1)
{
m_PlayerCountWatchdogPatch1 = ScriptPatches::AddPatch("fmmc_launcher"_J, "2D 02 09 00 00 25 A4", 5, {0x71, 0x2E, 0x02, 0x01});
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
}
m_PlayerCountWatchdogPatch1->Enable();
@@ -67,10 +73,10 @@ namespace YimMenu::Features
if (!m_HeistTeamsPatch1)
{
m_HeistTeamsPatch1 = ScriptPatches::AddPatch("fmmc_launcher"_J, "47 ? ? 5B 7B 00 38 04", 0, {0x2B, 0x2B, 0x00, 0x55});
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
}
m_HeistTeamsPatch1->Enable();
if (!m_HeistTeamsPatch2)
{
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
if (m_ShouldFailMissionPatches.empty())
{
// TODO: this is a very bad idea that can break anytime
// for some reason, Rockstar thought it's a good idea to copy-paste the same failure check in four different branches, "just in case"
for (int i = 0; i < 4; i++)
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}));
}
@@ -95,15 +102,50 @@ namespace YimMenu::Features
if (!m_ShouldFailMissionPatch2)
{
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});
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
}
m_ShouldFailMissionPatch2->Enable();
if (!m_ShouldFailMissionPatch3)
{
m_ShouldFailMissionPatch3 = ScriptPatches::AddPatch("fm_mission_controller"_J, "50 ? ? 78 82 06 1F 56 2E 01", 0, {0x00, 0x00, 0x00, 0x00, 0x72});
}
m_ShouldFailMissionPatch3->Enable();
if (!m_NotEnoughTeamsPatch)
{
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});
}
m_NotEnoughTeamsPatch->Enable();
if (!m_IsTeamValidPatch)
{
m_IsTeamValidPatch = ScriptPatches::AddPatch("fm_mission_controller"_J, "2D 01 03 00 00 38 00 71 57 1D 00", 5, {0x72, 0x2E, 0x01, 0x01});
}
m_IsTeamValidPatch->Enable();
if (!m_EnsureMissionPassedPatch)
{
m_EnsureMissionPassedPatch = ScriptPatches::AddPatch("fm_mission_controller"_J, "55 C8 FF 61", 3, {0x2E, 0x00, 0x00});
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
}
m_EnsureMissionPassedPatch->Enable();
if (!m_ProcessPhoneHackingPatch)
{
m_ProcessPhoneHackingPatch = ScriptPatches::AddPatch("fm_mission_controller"_J, "58 13 00 38 00 4F ? ? 48", 0, {0x2B, 0x00, 0x00});
}
}
virtual void OnTick() override
{
if (m_ProcessPhoneHackingPatch)
{
// the patch transfers the hacking minigame from the passenger to the driver, so we only want it applied when we're playing solo
if (SCRIPT::GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH("fm_mission_controller"_J) && NETWORK::NETWORK_GET_TOTAL_NUM_PLAYERS() == 1)
m_ProcessPhoneHackingPatch->Enable();
else
m_ProcessPhoneHackingPatch->Disable();
}
}
virtual void OnDisable() override
@@ -166,10 +208,30 @@ namespace YimMenu::Features
m_ShouldFailMissionPatch2->Disable();
}
if (m_ShouldFailMissionPatch3)
{
m_ShouldFailMissionPatch3->Disable();
}
if (m_NotEnoughTeamsPatch)
{
m_NotEnoughTeamsPatch->Disable();
}
if (m_IsTeamValidPatch)
{
m_IsTeamValidPatch->Disable();
}
if (m_EnsureMissionPassedPatch)
{
m_EnsureMissionPassedPatch->Disable();
}
if (m_ProcessPhoneHackingPatch)
{
m_ProcessPhoneHackingPatch->Disable();
}
}
};
+2
View File
@@ -3,6 +3,7 @@
#include "Debug/Globals.hpp"
#include "Debug/Locals.hpp"
//#include "Debug/Scripts.hpp"
#include "Debug/Misc.hpp"
#include "game/frontend/items/Items.hpp"
@@ -15,5 +16,6 @@ namespace YimMenu::Submenus
{
AddCategory(BuildGlobalsMenu());
AddCategory(BuildLocalsMenu());
AddCategory(BuildMiscMenu());
}
}
+29
View File
@@ -0,0 +1,29 @@
#include "DrawVariable.hpp"
#include "Locals.hpp"
#include "core/filemgr/FileMgr.hpp"
#include "game/backend/Self.hpp"
#include "game/pointers/Pointers.hpp"
#include "core/backend/FiberPool.hpp"
#include "game/gta/ScriptFunction.hpp"
namespace YimMenu::Submenus
{
std::shared_ptr<Category> BuildMiscMenu()
{
auto misc = std::make_unique<Category>("Misc");
misc->AddItem(std::make_unique<ImGuiItem>([] {
static int team;
ImGui::InputInt("Team", &team);
if (ImGui::Button("fm_mission_controller DoTeamSwap"))
{
FiberPool::Push([] {
static ScriptFunction DoTeamSwap("DoTeamSwap", "fm_mission_controller"_J, "2D 02 04 00 00 38 00 50");
DoTeamSwap.Call<void>(team, true);
});
}
}));
return misc;
}
}
@@ -0,0 +1,8 @@
#pragma once
#include "core/frontend/manager/Category.hpp"
#include "game/frontend/items/Items.hpp"
namespace YimMenu::Submenus
{
std::shared_ptr<Category> BuildMiscMenu();
}
+2 -1
View File
@@ -27,7 +27,8 @@ namespace YimMenu::Submenus
}
}));
generalGroup->AddItem(std::make_shared<CommandItem>("playallmissionssolo"_J));
generalGroup->AddItem(std::make_shared<BoolCommandItem>("playallmissionssolo"_J));
generalGroup->AddItem(std::make_shared<CommandItem>("forcelaunchheist"_J));
cayoPericoGroup->AddItem(std::make_shared<CommandItem>("skipcayosetup"_J));
cayoPericoGroup->AddItem(std::make_shared<CommandItem>("skipcayocooldown"_J));
+12 -3
View File
@@ -36,12 +36,14 @@ namespace YimMenu::Hooks
if (event.m_CameraShake > 0.0f && dist <= 30.0f)
{
// Camera shake
LOGF(WARNING, "Blocked EXPLOSION_EVENT from {} since m_CameraShake > 0.0f", player.GetName());
return true;
}
if (event.m_DamageScale > 0.0f && dist <= 10.0f)
{
// Ragdoll
LOGF(WARNING, "Blocked EXPLOSION_EVENT from {} since m_DamageScale > 0.0f", player.GetName());
return true;
}
}
@@ -134,8 +136,7 @@ namespace YimMenu::Hooks
if (event.m_WeaponType == "WEAPON_TRANQUILIZER"_J)
{
LOG(INFO) << "blocked this thing from " << player.GetName();
//player.AddDetection();
LOGF(WARNING, "Blocked WEAPON_DAMAGE_EVENT from {} with m_WeaponType == WEAPON_TRANQUILIZER", player.GetName());
return false;
}
@@ -163,6 +164,7 @@ namespace YimMenu::Hooks
if (self_veh && self_veh.GetNetworkObjectId() == veh_id && sender_veh && sender_veh.GetNetworkObjectId() != veh_id)
{
// Vehicle takeover
LOGF(WARNING, "Blocked CHANGE_RADIO_STATION_EVENT on our local vehicle from {}", player.GetName());
return false;
}
@@ -171,7 +173,7 @@ namespace YimMenu::Hooks
case rage::netGameEvent::Type::DOOR_BREAK_EVENT:
{
// never used for legitimate reasons
LOGF(WARNING, "Blocked DOOR_BREAK_EVENT from {}", player.GetName());
return false;
}
case rage::netGameEvent::Type::SCRIPTED_GAME_EVENT:
@@ -202,12 +204,14 @@ namespace YimMenu::Hooks
if (pop_group == 0 && (percentage == 0 || percentage == 103))
{
// pop group override crash
LOGF(WARNING, "Blocked SCRIPT_WORLD_STATE_EVENT of type PopGroupOverride with invalid params from {}", player.GetName());
return false;
}
}
else if (type == CScriptWorldStateEvent::Type::PopMultiplierArea && !NETWORK::NETWORK_IS_ACTIVITY_SESSION())
{
// Stop traffic
LOGF(WARNING, "Blocked SCRIPT_WORLD_STATE_EVENT of type PopMultiplierArea from {}", player.GetName());
return false;
}
@@ -227,12 +231,14 @@ namespace YimMenu::Hooks
if (action >= 15 && action <= 18)
{
// vehicle temp action crash
LOGF(WARNING, "Blocked SCRIPT_ENTITY_STATE_CHANGE_EVENT of type SettingOfTaskVehicleTempAction with invalid params from {}", player.GetName());
return false;
}
if (Self::GetPed().GetNetworkObjectId() == entity)
{
// Ped takeover
LOGF(WARNING, "Blocked SCRIPT_ENTITY_STATE_CHANGE_EVENT of type SettingOfTaskVehicleTempAction on our local ped from {}", player.GetName());
return false;
}
@@ -240,6 +246,7 @@ namespace YimMenu::Hooks
if (self_veh && self_veh.GetNetworkObjectId() == veh_id)
{
// Vehicle takeover
LOGF(WARNING, "Blocked SCRIPT_ENTITY_STATE_CHANGE_EVENT of type SettingOfTaskVehicleTempAction on our local vehicle from {}", player.GetName());
return false;
}
}
@@ -311,6 +318,7 @@ namespace YimMenu::Hooks
if (Self::GetPed().GetVehicleObjectId() == event.m_VehicleId && !Self::GetVehicle().IsRemote())
{
// Vehicle takeover
LOGF(WARNING, "Blocked ACTIVATE_VEHICLE_SPECIAL_ABILITY_EVENT on our local vehicle from {}", player.GetName());
return false;
}
@@ -324,6 +332,7 @@ namespace YimMenu::Hooks
if (Self::GetPed().GetNetworkObjectId() == event.m_PedToRagdoll)
{
// is sometimes used legit, beware
LOGF(WARNING, "Blocked RAGDOLL_REQUEST_EVENT on our local ped from {}", player.GetName());
return false;
}
+1 -1
View File
@@ -9,7 +9,7 @@ bool CScriptedGameEvent::Deserialize(rage::datBitBuffer& buffer)
if (m_ArgsSize > sizeof(m_Args))
return false;
buffer.ReadArray(m_Args, 8 * m_ArgsSize);
buffer.ReadArrayBytes(m_Args, m_ArgsSize);
return true;
}
+14
View File
@@ -64,6 +64,7 @@ enum class ScriptEventIndex
TSECommand = 800157557, // CnCTG_IN_BF
TSECommandRotateCam = 225624744, // != 29) && f
TSECommandSound = 385726943,
TSECommandLaunchHeist = 1733306780, // HEIST_NOTE_3 in fmmc_launcher
Notification = -642704387,
NotificationMoneyBanked = 94410750, // TICK_TC_BANK
@@ -182,4 +183,17 @@ struct SCRIPT_EVENT_REQUEST_RANDOM_EVENT : public SCRIPT_EVENT
};
static_assert(sizeof(SCRIPT_EVENT_REQUEST_RANDOM_EVENT) == 7 * 8);
struct SCRIPT_EVENT_COMMAND : public SCRIPT_EVENT
{
enum class eCommand
{
LaunchHeist = 1733306780
};
REGISTER_SCRIPT_EVENT(SCRIPT_EVENT_COMMAND, TSECommand);
eCommand Command;
SCR_INT RandomNumber; // it's fine if we don't set this
};
#undef REGISTER_SCRIPT_EVENT