mirror of
https://github.com/YimMenu/YimMenuV2.git
synced 2026-10-10 20:03:17 +08:00
fix(native_hooks): fix game crashes resulting from not calling the destructor
This commit is contained in:
@@ -12,7 +12,7 @@ namespace YimMenu
|
||||
m_Program(program),
|
||||
m_Hook(std::make_unique<VMTHook>("rage::scrProgram", program, 9))
|
||||
{
|
||||
m_Hook->Hook(6, ScrProgram_Dtor);
|
||||
m_Hook->Hook(6, reinterpret_cast<void*>(&ScrProgram_Dtor));
|
||||
m_Hook->Enable();
|
||||
m_OrigHandlers = new rage::scrNativeHandler[program->m_NativeCount];
|
||||
memcpy(m_OrigHandlers, program->m_NativeEntrypoints, program->m_NativeCount * sizeof(rage::scrNativeHandler));
|
||||
@@ -36,7 +36,9 @@ namespace YimMenu
|
||||
void NativeHooks::Program::ScrProgram_Dtor(rage::scrProgram* _this, bool free_mem)
|
||||
{
|
||||
NativeHooks::UnregisterProgram(_this);
|
||||
(**reinterpret_cast<decltype(&NativeHooks::Program::ScrProgram_Dtor)**>(_this))(_this, free_mem);
|
||||
auto vtable = *reinterpret_cast<void***>(_this);
|
||||
auto destructor = *(vtable + 6);
|
||||
reinterpret_cast<decltype(&NativeHooks::Program::ScrProgram_Dtor)>(destructor)(_this, free_mem);
|
||||
}
|
||||
|
||||
NativeHooks::NativeHooks() :
|
||||
|
||||
@@ -13,9 +13,20 @@ namespace YimMenu
|
||||
|
||||
void PlayerAllCommand::OnCall()
|
||||
{
|
||||
std::vector<Player> validPlayers;
|
||||
validPlayers.reserve(Players::GetPlayers().size() - 1);
|
||||
for (auto& p : Players::GetPlayers())
|
||||
{
|
||||
if (p.second.IsValid() && (!Self::GetPlayer().IsValid() || p.second.GetId() != Self::GetPlayer().GetId()))
|
||||
m_PlayerCommand->Call(p.second);
|
||||
validPlayers.push_back(p.second);
|
||||
}
|
||||
m_PlayerCommand->Call(validPlayers);
|
||||
}
|
||||
|
||||
void PlayerCommand::OnCall(const std::vector<Player>& players)
|
||||
{
|
||||
for (auto& p : players)
|
||||
Call(p);
|
||||
}
|
||||
|
||||
PlayerCommand::PlayerCommand(std::string name, std::string label, std::string description, int num_args, bool all_version) :
|
||||
@@ -34,4 +45,9 @@ namespace YimMenu
|
||||
{
|
||||
OnCall(target);
|
||||
}
|
||||
|
||||
void PlayerCommand::Call(const std::vector<Player>& targets)
|
||||
{
|
||||
OnCall(targets);
|
||||
}
|
||||
}
|
||||
@@ -21,9 +21,11 @@ namespace YimMenu
|
||||
|
||||
protected:
|
||||
virtual void OnCall(Player) = 0;
|
||||
virtual void OnCall(const std::vector<Player>&);
|
||||
|
||||
public:
|
||||
PlayerCommand(std::string name, std::string label, std::string description, int num_args = 0, bool all_version = true);
|
||||
void Call(Player target); // TODO
|
||||
void Call(Player target);
|
||||
void Call(const std::vector<Player>& targets);
|
||||
};
|
||||
}
|
||||
@@ -37,7 +37,7 @@ namespace YimMenu::Features
|
||||
if (SCRIPT::GET_HASH_OF_THIS_SCRIPT_NAME() == "freemode"_J)
|
||||
{
|
||||
GSBD::Get()->FreemodeState = eFreemodeState::RUNNING;
|
||||
GSBD::Get()->CayoPericoStrandedAnimalChoice = 0; // unbrick cayo just in case if the script host never responds
|
||||
GSBD::Get()->CayoPericoStrandedAnimalChoice = 1; // unbrick cayo just in case if the script host never responds
|
||||
}
|
||||
return ctx->SetReturnValue(TRUE);
|
||||
}
|
||||
|
||||
@@ -17,13 +17,15 @@ namespace YimMenu::Features
|
||||
{
|
||||
NETWORK::NETWORK_SET_IN_SPECTATOR_MODE(false, 0);
|
||||
HUD::SET_MINIMAP_IN_SPECTATOR_MODE(false, 0);
|
||||
if (selected)
|
||||
{
|
||||
NETWORK::NETWORK_SET_IN_SPECTATOR_MODE(true, selected.GetPed().GetHandle());
|
||||
HUD::SET_MINIMAP_IN_SPECTATOR_MODE(true, selected.GetPed().GetHandle());
|
||||
}
|
||||
|
||||
m_SpectatingPlayer = selected;
|
||||
}
|
||||
|
||||
if (m_SpectatingPlayer)
|
||||
{
|
||||
NETWORK::NETWORK_SET_IN_SPECTATOR_MODE(true, m_SpectatingPlayer.GetPed().GetHandle());
|
||||
HUD::SET_MINIMAP_IN_SPECTATOR_MODE(true, m_SpectatingPlayer.GetPed().GetHandle());
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnDisable() override
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
#include "game/commands/PlayerCommand.hpp"
|
||||
#include "types/script/ScriptEvent.hpp"
|
||||
|
||||
namespace YimMenu::Features
|
||||
{
|
||||
class SendSext : public PlayerCommand
|
||||
{
|
||||
using PlayerCommand::PlayerCommand;
|
||||
|
||||
static constexpr auto sm_Strippers = std::to_array({"HCH", "INF", "JUL", "NIK", "SAP", "TXI"});
|
||||
static constexpr auto sm_SextTypes = std::to_array({"1ST", "2ND", "NEED"});
|
||||
|
||||
virtual void OnCall(Player player) override
|
||||
{
|
||||
OnCall(std::vector{player});
|
||||
}
|
||||
|
||||
virtual void OnCall(const std::vector<Player>& players) override
|
||||
{
|
||||
SCRIPT_EVENT_SEND_TEXT_LABEL_MESSAGE message;
|
||||
strncpy(message.Label.Data, std::format("SXT_{}_{}", sm_Strippers[rand() % sm_Strippers.size()], sm_SextTypes[rand() % sm_SextTypes.size()]).c_str(), 24);
|
||||
for (auto& player : players)
|
||||
message.SetPlayer(player.GetId());
|
||||
message.Send();
|
||||
}
|
||||
};
|
||||
|
||||
static SendSext _SendSext{"sendsext", "Send Sext", "Sends a random sext to the specified player"};
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#include "core/commands/BoolCommand.hpp"
|
||||
#include "core/commands/IntCommand.hpp"
|
||||
#include "game/commands/PlayerCommand.hpp"
|
||||
#include "types/script/ScriptEvent.hpp"
|
||||
#include "types/script/globals/GSBD_FM_Events.hpp"
|
||||
|
||||
namespace YimMenu::Features
|
||||
{
|
||||
static IntCommand _BountyAmount{"bountyamount", "Bounty Amount", "The bounty amount to set", 1, 10000, 9000};
|
||||
static BoolCommand _AnonymousBounty{"anonymousbounty", "Anonymous Bounty", "Sets the bounty as anonymous"};
|
||||
|
||||
class SetBounty : public PlayerCommand
|
||||
{
|
||||
using PlayerCommand::PlayerCommand;
|
||||
|
||||
virtual void OnCall(Player player) override
|
||||
{
|
||||
SCRIPT_EVENT_BOUNTY bounty;
|
||||
bounty.Target = player.GetId();
|
||||
bounty.FromPed = _AnonymousBounty.GetState();
|
||||
bounty.Amount = _BountyAmount.GetState();
|
||||
bounty.BountyFlags = 1;
|
||||
bounty.AntiReplayValue1 = GSBD_FM_Events::Get()->AntiReplayValue1;
|
||||
bounty.AntiReplayValue2 = GSBD_FM_Events::Get()->AntiReplayValue2;
|
||||
bounty.SetAllPlayers();
|
||||
bounty.Send();
|
||||
}
|
||||
};
|
||||
|
||||
static SetBounty _SetBounty{"setbounty", "Set Bounty", "Sets the specified bounty to the player"};
|
||||
}
|
||||
@@ -8,14 +8,24 @@ namespace YimMenu::Submenus
|
||||
{
|
||||
// TODO: this needs a rework
|
||||
auto session = std::make_shared<Category>("Session");
|
||||
auto bountyGroup = std::make_shared<Group>("Bounty", 1);
|
||||
auto toxicGroup = std::make_shared<Group>("Toxic");
|
||||
auto trollGroup = std::make_shared<Group>("Troll");
|
||||
auto enhancements = std::make_shared<Group>("Enhancements");
|
||||
|
||||
bountyGroup->AddItem(std::make_shared<IntCommandItem>("bountyamount"_J, "Amount"));
|
||||
bountyGroup->AddItem(std::make_shared<BoolCommandItem>("anonymousbounty"_J, "Anonymous"));
|
||||
bountyGroup->AddItem(std::make_shared<CommandItem>("setbountyall"_J, "Set Bounties"));
|
||||
|
||||
trollGroup->AddItem(std::make_shared<CommandItem>("sendsextall"_J, "Send Sexts"));
|
||||
|
||||
toxicGroup->AddItem(std::make_shared<CommandItem>("killall"_J, "Kill All"));
|
||||
toxicGroup->AddItem(std::make_shared<CommandItem>("explodeall"_J, "Explode All"));
|
||||
|
||||
|
||||
enhancements->AddItem(std::make_shared<BoolCommandItem>("fastjoin"_J));
|
||||
|
||||
session->AddItem(bountyGroup);
|
||||
session->AddItem(trollGroup);
|
||||
session->AddItem(toxicGroup);
|
||||
session->AddItem(enhancements);
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
#include "Troll.hpp"
|
||||
|
||||
namespace YimMenu::Submenus
|
||||
{
|
||||
std::shared_ptr<Category> BuildTrollMenu()
|
||||
{
|
||||
auto menu = std::make_shared<Category>("Troll");
|
||||
|
||||
auto general = std::make_shared<Group>("General");
|
||||
auto bounty = std::make_shared<Group>("Bounty", 1);
|
||||
|
||||
general->AddItem(std::make_shared<PlayerCommandItem>("sendsext"_J));
|
||||
|
||||
bounty->AddItem(std::make_shared<IntCommandItem>("bountyamount"_J, "Amount"));
|
||||
bounty->AddItem(std::make_shared<BoolCommandItem>("anonymousbounty"_J, "Anonymous"));
|
||||
bounty->AddItem(std::make_shared<PlayerCommandItem>("setbounty"_J));
|
||||
|
||||
menu->AddItem(general);
|
||||
menu->AddItem(bounty);
|
||||
|
||||
return menu;
|
||||
}
|
||||
}
|
||||
@@ -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> BuildTrollMenu();
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "Player/Info.hpp"
|
||||
#include "Player/Toxic.hpp"
|
||||
#include "Player/Troll.hpp"
|
||||
#include "core/frontend/widgets/imgui_colors.h"
|
||||
#include "game/backend/PlayerData.hpp"
|
||||
#include "game/backend/Players.hpp"
|
||||
@@ -115,6 +116,7 @@ namespace YimMenu::Submenus
|
||||
Submenu::Submenu("Players")
|
||||
{
|
||||
AddCategory(std::move(BuildInfoMenu()));
|
||||
AddCategory(std::move(BuildTrollMenu()));
|
||||
AddCategory(std::move(BuildToxicMenu()));
|
||||
|
||||
for (auto& category : m_Categories)
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
#include "Self.hpp"
|
||||
|
||||
#include "core/util/Joaat.hpp"
|
||||
#include "core/commands/BoolCommand.hpp"
|
||||
#include "core/commands/Commands.hpp"
|
||||
#include "core/commands/IntCommand.hpp"
|
||||
#include "game/frontend/items/Items.hpp"
|
||||
|
||||
#include <map>
|
||||
|
||||
|
||||
namespace YimMenu::Features
|
||||
{
|
||||
// BoolCommand _RecoveryEnabled("recoveryenabled", "Recovery Enabled", "Is the recovery feature enabled");
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace YimMenu
|
||||
return m_Handle && m_Handle->IsPhysical() && m_Handle->m_PlayerInfo;
|
||||
}
|
||||
|
||||
int Player::GetId()
|
||||
int Player::GetId() const
|
||||
{
|
||||
if (!IsValid())
|
||||
{
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace YimMenu
|
||||
|
||||
// object
|
||||
bool IsValid() const;
|
||||
int GetId();
|
||||
int GetId() const;
|
||||
const char* GetName();
|
||||
CNetGamePlayer* GetHandle();
|
||||
rage::rlGamerInfo* GetGamerInfo();
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "ScriptEvent.hpp"
|
||||
#include "game/gta/Natives.hpp"
|
||||
|
||||
void SCRIPT_EVENT::Send()
|
||||
{
|
||||
auto size = __SizeOfEvent;
|
||||
__SizeOfEvent = 0;
|
||||
SCRIPT::_SEND_TU_SCRIPT_EVENT_NEW(1, this, size / sizeof(std::uint32_t), PlayerBits, EventIndex);
|
||||
__SizeOfEvent = size;
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
#pragma once
|
||||
#include "types.hpp"
|
||||
|
||||
#define REGISTER_SCRIPT_EVENT(classType, indexType) \
|
||||
constexpr static auto EVENT_INDEX = ScriptEventIndex::indexType; \
|
||||
classType() \
|
||||
{ \
|
||||
memset(this, 0, sizeof(classType)); EventIndex = static_cast<int>(EVENT_INDEX); \
|
||||
__SizeOfEvent = sizeof(classType); \
|
||||
} \
|
||||
classType(const classType& other) \
|
||||
{ \
|
||||
memcpy(this, &other, sizeof(classType)); \
|
||||
EventIndex = static_cast<int>(EVENT_INDEX); \
|
||||
__SizeOfEvent = sizeof(classType); \
|
||||
}
|
||||
|
||||
// I doubt rockstar would cycle this again, but best to keep this, just in case
|
||||
enum class ScriptEventIndex
|
||||
{
|
||||
Bounty = 1517551547, // (137, "FM_TXT_BNTY0", iVar1, PLAYER::GET_PLAYER_NAME(Var2.f_1), "", 5000, Var2.f_6);
|
||||
CeoBan = 1531565154, // mpply_vipgameplaydisabledtimer
|
||||
CeoKick = -11681548,
|
||||
CeoMoney = -337848027, // Goon_Paid_Large
|
||||
ClearWantedLevel = -1704545346,
|
||||
ForceMission = 259469385, // ), Var0.f_2, 1))
|
||||
GiveCollectible = 968269233, // DLC_SUM20_HIDDEN_COLLECTIBLES xref
|
||||
GtaBanner = -330501227, // NETWORK::NETWORK_IS_SCRIPT_ACTIVE("BUSINESS_BATTLES", -1, true, 0) second one
|
||||
NetworkBail = -901348601, // NETWORK::NETWORK_BAIL(16, 0, 0); xref func
|
||||
PersonalVehicleDestroyed = 1655503526, // PLYVEH_INS_DES1
|
||||
RemoteOffradar = 57493695, // NETWORK::GET_TIME_DIFFERENCE(NETWORK::GET_NETWORK_TIME(), Var0.f_2)
|
||||
SendToCutscene = -1951335381, // (bVar3, bVar4, 125f, 1)
|
||||
SendToCayoPerico = 373376135, // CELL_HI_INV
|
||||
SendToLocation = 1669592503, // &Var222, 11);
|
||||
SoundSpam = 996099702, // CELL_APTINVYACHT
|
||||
Spectate = 1840946429, // SPEC_TCK1
|
||||
Teleport = -1321657966, // Mission_Pass_Notify
|
||||
TeleportToWarehouse = -1253241415, // .f_4 == 50
|
||||
TransactionError = -830063381, // NETWORK_RECEIVE_PLAYER_JOBSHARE_CASH
|
||||
VehicleKick = -503325966, // PIM_RFMOC
|
||||
MCTeleport = 1103127469, // NETWORK::NETWORK_HASH_FROM_PLAYER_HANDLE(PLAYER::PLAYER_ID()) == (first one)
|
||||
StartActivity = 1450115979, // (Var0.f_2, -1); first match
|
||||
MarkPlayerAsBeast = 1649541577, // GB_BOSSBST xref == PLAYER... global (sadly doesn't actually turn people into the beast)
|
||||
KickFromInterior = -1496371358, // ENTITY::SET_ENTITY_HEALTH(PLAYER::PLAYER_PED_ID(), PED::GET_PED_MAX_HEALTH(PLAYER::PLAYER_PED_ID()), false)
|
||||
InteriorControl = -1638522928, // eventData.f_3 != _INVALID_PLAYER_INDEX_0()
|
||||
SendTextLabelSMS = -1773335296,
|
||||
|
||||
Crash = -1604421397, // SET_NO_LOADING_SCREEN, xref it
|
||||
Crash2 = -375628860,
|
||||
Crash3 = 323285304,
|
||||
|
||||
TSECommand = 800157557, // CnCTG_IN_BF
|
||||
TSECommandRotateCam = 225624744, // != 29) && f
|
||||
TSECommandSound = 385726943,
|
||||
|
||||
Notification = -642704387,
|
||||
NotificationMoneyBanked = 94410750, // TICK_TC_BANK
|
||||
NotificationMoneyRemoved = -242911964, // TICK_TC_REMO
|
||||
NotificationMoneyStolen = -295926414, // TICK_TC_STOL
|
||||
NotificationCrash1 = -994541138, // AMCH_ATTEMPT2
|
||||
NotificationCrash2 = 782258655, // GBSAL_COLL
|
||||
|
||||
DestroyPersonalVehicle = 109434679, // CnC_PV_THEFT
|
||||
TriggerCEORaid = -1906536929,
|
||||
|
||||
StartScriptBegin = -366707054,
|
||||
StartScriptProceed = 1757622014
|
||||
};
|
||||
|
||||
struct SCRIPT_EVENT
|
||||
{
|
||||
protected:
|
||||
SCR_HASH EventIndex; // 0x00
|
||||
Player SenderIndex; // 0x08
|
||||
int __SizeOfEvent; // 0x0C
|
||||
SCR_INT PlayerBits; // 0x10
|
||||
|
||||
public:
|
||||
int GetSender() const
|
||||
{
|
||||
return SenderIndex;
|
||||
}
|
||||
|
||||
Hash GetEventIndex() const
|
||||
{
|
||||
return EventIndex;
|
||||
}
|
||||
|
||||
bool ShouldReceiveEvent(int player) const
|
||||
{
|
||||
return PlayerBits & (1 << player);
|
||||
}
|
||||
|
||||
void SetAllPlayers()
|
||||
{
|
||||
PlayerBits = -1;
|
||||
}
|
||||
|
||||
void SetAllPlayersExcept(int player_to_exclude)
|
||||
{
|
||||
PlayerBits = -1 & ~(1 << player_to_exclude);
|
||||
}
|
||||
|
||||
void SetPlayer(int player)
|
||||
{
|
||||
PlayerBits |= (1 << player);
|
||||
}
|
||||
|
||||
// must be called in script context
|
||||
void Send();
|
||||
|
||||
inline void Send(int player)
|
||||
{
|
||||
SetPlayer(player);
|
||||
Send();
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(SCRIPT_EVENT) == 3 * 8);
|
||||
|
||||
struct SCRIPT_EVENT_BOUNTY : public SCRIPT_EVENT
|
||||
{
|
||||
REGISTER_SCRIPT_EVENT(SCRIPT_EVENT_BOUNTY, Bounty);
|
||||
|
||||
PLAYER_INDEX Target;
|
||||
SCR_INT BountyFlags;
|
||||
SCR_INT Amount;
|
||||
SCR_INT PAD_0006;
|
||||
SCR_BOOL FromPed;
|
||||
uint64_t PAD_0008[13];
|
||||
SCR_INT AntiReplayValue1;
|
||||
SCR_INT AntiReplayValue2;
|
||||
};
|
||||
static_assert(sizeof(SCRIPT_EVENT_BOUNTY) == 23 * 8);
|
||||
|
||||
struct SCRIPT_EVENT_SEND_TEXT_LABEL_MESSAGE : public SCRIPT_EVENT
|
||||
{
|
||||
REGISTER_SCRIPT_EVENT(SCRIPT_EVENT_SEND_TEXT_LABEL_MESSAGE, SendTextLabelSMS);
|
||||
|
||||
TEXT_LABEL_23 Label;
|
||||
};
|
||||
static_assert(sizeof(SCRIPT_EVENT_SEND_TEXT_LABEL_MESSAGE) == 9 * 8);
|
||||
|
||||
#undef REGISTER_SCRIPT_EVENT
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include "../types.hpp"
|
||||
|
||||
// TODO
|
||||
struct GSBD_FM_Events
|
||||
{
|
||||
uint64_t PAD_0000[8];
|
||||
SCR_INT AntiReplayValue1;
|
||||
SCR_INT AntiReplayValue2;
|
||||
|
||||
static GSBD_FM_Events* Get();
|
||||
};
|
||||
//static_assert(sizeof(GSBD) == 1498 * 8);
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "GSBD.hpp"
|
||||
#include "GSBD_BlockB.hpp"
|
||||
#include "GSBD_FM.hpp"
|
||||
#include "GSBD_FM_Events.hpp"
|
||||
#include "GSBD_Kicking.hpp"
|
||||
#include "GSBD_PropertyInstances.hpp"
|
||||
#include "g_AMC_playerBD.hpp"
|
||||
@@ -27,6 +28,7 @@ DEFINE_GLOBAL_ACCESSOR(GPBD_MissionName, 1873815);
|
||||
DEFINE_GLOBAL_ACCESSOR(GSBD, 2648917);
|
||||
DEFINE_GLOBAL_ACCESSOR(GSBD_BlockB, 2650415);
|
||||
DEFINE_GLOBAL_ACCESSOR(GSBD_FM, 1835557);
|
||||
DEFINE_GLOBAL_ACCESSOR(GSBD_FM_Events, 1917230);
|
||||
DEFINE_GLOBAL_ACCESSOR(GSBD_Kicking, 1877529);
|
||||
DEFINE_GLOBAL_ACCESSOR(GSBD_PropertyInstances, 1937699);
|
||||
DEFINE_GLOBAL_ACCESSOR(g_AMC_playerBD, 2699624);
|
||||
Reference in New Issue
Block a user