mirror of
https://github.com/YimMenu/YimMenuV2.git
synced 2026-10-10 11:53:14 +08:00
general fixes
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user