Bug fixes and improvements (#984)
* feat(KickFromInterior): improve kick from interior Fixes #968 Fixes #953 Fixes #901 Fixes #899 Fixes #813 Fixes #726 Fixes #723 Co-authored-by: Yimura <24669514+Yimura@users.noreply.github.com>
This commit is contained in:
parent
032e441753
commit
1f5a118cb9
@ -3,7 +3,7 @@ include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
gtav_classes
|
||||
GIT_REPOSITORY https://github.com/Yimura/GTAV-Classes.git
|
||||
GIT_TAG 2862a02e24ebfedc60432887e735efef56d83635
|
||||
GIT_TAG c5c72f78ffef24ea7faf8791b37fb6d61c1b5fc4
|
||||
GIT_PROGRESS TRUE
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
|
@ -37,7 +37,6 @@ namespace big
|
||||
|
||||
while (g_running)
|
||||
{
|
||||
looped::self_godmode();
|
||||
looped::self_police();
|
||||
looped::self_hud();
|
||||
looped::self_dance_mode();
|
||||
|
@ -1,8 +1,14 @@
|
||||
#include "hooking.hpp"
|
||||
#include "backend/player_command.hpp"
|
||||
#include "natives.hpp"
|
||||
#include "pointers.hpp"
|
||||
#include "gta/net_object_mgr.hpp"
|
||||
#include "core/scr_globals.hpp"
|
||||
#include "fiber_pool.hpp"
|
||||
#include "gta/script_handler.hpp"
|
||||
#include "util/scripts.hpp"
|
||||
|
||||
#include <script/globals/GPBD_FM.hpp>
|
||||
|
||||
namespace big
|
||||
{
|
||||
@ -17,15 +23,122 @@ namespace big
|
||||
|
||||
virtual void execute(player_ptr player, const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
|
||||
{
|
||||
const size_t arg_count = 8;
|
||||
int64_t args[arg_count]{
|
||||
(int64_t)eRemoteEvent::KickFromInterior,
|
||||
(int64_t)self::id,
|
||||
*scr_globals::globalplayer_bd.at(player->id(), scr_globals::size::globalplayer_bd).at(321).at(7).as<int64_t*>(),
|
||||
*scr_globals::globalplayer_bd.at(player->id(), scr_globals::size::globalplayer_bd).at(321).at(8).as<int64_t*>(),
|
||||
};
|
||||
if (scr_globals::gpbd_fm_1.as<GPBD_FM*>()->Entries[player->id()].PropertyData.Index != -1)
|
||||
{
|
||||
int id = player->id();
|
||||
g_fiber_pool->queue_job([id]
|
||||
{
|
||||
int instance = -1;
|
||||
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
if (NETWORK::NETWORK_IS_PLAYER_A_PARTICIPANT_ON_SCRIPT(id, "am_mp_property_int", i))
|
||||
{
|
||||
instance = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (instance == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
while (!SCRIPT::HAS_SCRIPT_WITH_NAME_HASH_LOADED(RAGE_JOAAT("am_mp_property_int")))
|
||||
{
|
||||
SCRIPT::REQUEST_SCRIPT_WITH_NAME_HASH(RAGE_JOAAT("am_mp_property_int"));
|
||||
script::get_current()->yield();
|
||||
}
|
||||
|
||||
auto program = gta_util::find_script_program(RAGE_JOAAT("am_mp_property_int"));
|
||||
|
||||
int count = program->m_local_count;
|
||||
program->m_local_count = 2;
|
||||
int id = SYSTEM::START_NEW_SCRIPT_WITH_NAME_HASH(RAGE_JOAAT("am_mp_property_int"), 1424);
|
||||
program->m_local_count = count;
|
||||
|
||||
auto script = gta_util::find_script_thread_by_id(id);
|
||||
|
||||
if (!script)
|
||||
return;
|
||||
|
||||
script->m_context.m_state = rage::eThreadState::unk_3;
|
||||
|
||||
|
||||
gta_util::execute_as_script(script, [instance]
|
||||
{
|
||||
if (auto hook = g_hooking->m_handler_hooks[(CGameScriptHandler*)rage::scrThread::get()->m_handler].get())
|
||||
{
|
||||
hook->disable();
|
||||
g_hooking->m_handler_hooks.erase((CGameScriptHandler*)rage::scrThread::get()->m_handler);
|
||||
}
|
||||
|
||||
NETWORK::NETWORK_SET_THIS_SCRIPT_IS_NETWORK_SCRIPT(32, true, instance);
|
||||
});
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
int status = 0;
|
||||
gta_util::execute_as_script(script, [&status] { status = NETWORK::NETWORK_GET_SCRIPT_STATUS(); });
|
||||
|
||||
if (status == 2)
|
||||
break;
|
||||
|
||||
if (status > 2)
|
||||
{
|
||||
script->kill();
|
||||
return;
|
||||
}
|
||||
|
||||
script::get_current()->yield(50ms);
|
||||
}
|
||||
|
||||
static uint64_t server_vars[1358]{};
|
||||
static uint64_t client_vars[1185]{};
|
||||
|
||||
gta_util::execute_as_script(script, []
|
||||
{
|
||||
NETWORK::NETWORK_REGISTER_HOST_BROADCAST_VARIABLES((int*)server_vars, 1358, 0);
|
||||
NETWORK::NETWORK_REGISTER_PLAYER_BROADCAST_VARIABLES((int*)client_vars, 1185, 0);
|
||||
});
|
||||
|
||||
for (int i = 0; i < 3600; i++)
|
||||
{
|
||||
bool received = false;
|
||||
gta_util::execute_as_script(script, [&received] { received = NETWORK::NETWORK_HAS_RECEIVED_HOST_BROADCAST_DATA(); });
|
||||
|
||||
if (received)
|
||||
break;
|
||||
|
||||
script::get_current()->yield();
|
||||
}
|
||||
|
||||
if (!scripts::force_host(RAGE_JOAAT("am_mp_property_int")))
|
||||
{
|
||||
script->kill();
|
||||
return;
|
||||
}
|
||||
|
||||
server_vars[717] = 1;
|
||||
script::get_current()->yield(3s);
|
||||
|
||||
script->kill();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
const size_t arg_count = 8;
|
||||
int64_t args[arg_count]{
|
||||
(int64_t)eRemoteEvent::KickFromInterior,
|
||||
(int64_t)self::id,
|
||||
*scr_globals::globalplayer_bd.at(player->id(), scr_globals::size::globalplayer_bd).at(321).at(7).as<int64_t*>(),
|
||||
*scr_globals::globalplayer_bd.at(player->id(), scr_globals::size::globalplayer_bd).at(321).at(8).as<int64_t*>(),
|
||||
};
|
||||
|
||||
g_pointers->m_trigger_script_event(1, args, arg_count, 1 << player->id());
|
||||
}
|
||||
|
||||
g_pointers->m_trigger_script_event(1, args, arg_count, 1 << player->id());
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -24,7 +24,6 @@ namespace big
|
||||
static void player_spectate();
|
||||
static void player_remote_control_vehicle();
|
||||
|
||||
static void self_godmode();
|
||||
static void self_police();
|
||||
static void self_hud();
|
||||
static void self_dance_mode();
|
||||
|
@ -18,5 +18,5 @@ namespace big
|
||||
}
|
||||
};
|
||||
|
||||
beast_jump_looped g_beast_jump_looped("beastjump", "Beast Jump", "Allows You To Jump As If You Were The Beast Like In The Beast Event", g.self.beast_jump);
|
||||
beast_jump_looped g_beast_jump_looped("beastjump", "Beast Jump", "Allows you to jump as if you were the beast like in the Hunt the Beast event", g.self.beast_jump);
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "util/scripts.hpp"
|
||||
#include "script_function.hpp"
|
||||
#include "services/script_patcher/script_patcher_service.hpp"
|
||||
#include "hooking.hpp"
|
||||
|
||||
namespace big
|
||||
{
|
||||
@ -26,7 +27,7 @@ namespace big
|
||||
if (!thread)
|
||||
return;
|
||||
|
||||
g.m_dance_thread = gta_util::find_script_thread(RAGE_JOAAT("am_mp_nightclub"));
|
||||
g.m_dance_thread = gta_util::find_script_thread_by_id(thread);
|
||||
g.m_dance_program = gta_util::find_script_program(RAGE_JOAAT("am_mp_nightclub"));
|
||||
|
||||
(*g_pointers->m_script_handler_mgr)->attach_thread(g.m_dance_thread);
|
||||
@ -34,9 +35,15 @@ namespace big
|
||||
g.m_dance_thread->m_context.m_state = rage::eThreadState::unk_3;
|
||||
|
||||
// perform initial setup
|
||||
gta_util::execute_as_script(RAGE_JOAAT("am_mp_nightclub"), []
|
||||
gta_util::execute_as_script(g.m_dance_thread, []
|
||||
{
|
||||
NETWORK::NETWORK_SET_THIS_SCRIPT_IS_NETWORK_SCRIPT(32, false, 32);
|
||||
if (auto hook = g_hooking->m_handler_hooks[(CGameScriptHandler*)rage::scrThread::get()->m_handler].get())
|
||||
{
|
||||
hook->disable();
|
||||
g_hooking->m_handler_hooks.erase((CGameScriptHandler*)rage::scrThread::get()->m_handler);
|
||||
}
|
||||
|
||||
NETWORK::NETWORK_SET_THIS_SCRIPT_IS_NETWORK_SCRIPT(32, true, 32);
|
||||
scr_functions::init_nightclub_script({});
|
||||
});
|
||||
|
||||
|
@ -1,26 +1,41 @@
|
||||
#include "backend/looped/looped.hpp"
|
||||
#include "natives.hpp"
|
||||
#include "backend/looped_command.hpp"
|
||||
|
||||
namespace big
|
||||
{
|
||||
static uint32_t last_bits = 0;
|
||||
static float last_water_collistion_strength = 0;
|
||||
|
||||
void looped::self_godmode()
|
||||
class godmode_internal : looped_command
|
||||
{
|
||||
if (g_local_player == nullptr)
|
||||
using looped_command::looped_command;
|
||||
|
||||
uint32_t last_bits = 0;
|
||||
|
||||
virtual void on_tick() override
|
||||
{
|
||||
return;
|
||||
if (g_local_player == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t bits = g.self.proof_mask;
|
||||
uint32_t changed_bits = bits ^ last_bits;
|
||||
uint32_t changed_or_enabled_bits = bits | changed_bits;
|
||||
|
||||
if (changed_or_enabled_bits)
|
||||
{
|
||||
uint32_t unchanged_bits = g_local_player->m_damage_bits & ~changed_or_enabled_bits;
|
||||
g_local_player->m_damage_bits = unchanged_bits | bits;
|
||||
last_bits = bits;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t bits = g.self.proof_mask;
|
||||
uint32_t changed_bits = bits ^ last_bits;
|
||||
uint32_t changed_or_enabled_bits = bits | changed_bits;
|
||||
|
||||
if (changed_or_enabled_bits)
|
||||
virtual void on_disable() override
|
||||
{
|
||||
uint32_t unchanged_bits = g_local_player->m_damage_bits & ~changed_or_enabled_bits;
|
||||
g_local_player->m_damage_bits = unchanged_bits | bits;
|
||||
last_bits = bits;
|
||||
g_local_player->m_damage_bits = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static bool true_ref = true;
|
||||
godmode_internal g_godmode_internal("$$godmode", "", "", true_ref);
|
||||
bool_command g_godmode("godmode", "God Mode", "Prevents you from taking any form of damage", g.self.god_mode);
|
||||
}
|
@ -3,6 +3,9 @@
|
||||
#include "natives.hpp"
|
||||
#include "backend/looped_command.hpp"
|
||||
|
||||
#include "core/scr_globals.hpp"
|
||||
#include <script/globals/GlobalPlayerBD.hpp>
|
||||
|
||||
namespace big
|
||||
{
|
||||
class invisibility : looped_command
|
||||
@ -12,16 +15,20 @@ namespace big
|
||||
virtual void on_tick() override
|
||||
{
|
||||
ENTITY::SET_ENTITY_VISIBLE(self::ped, false, 0);
|
||||
|
||||
if (g.self.local_visibility)
|
||||
NETWORK::SET_ENTITY_LOCALLY_VISIBLE(self::ped);
|
||||
|
||||
scr_globals::globalplayer_bd.as<GlobalPlayerBD*>()->Entries[self::id].IsInvisible = true;
|
||||
}
|
||||
|
||||
virtual void on_disable() override
|
||||
{
|
||||
ENTITY::SET_ENTITY_VISIBLE(self::ped, true, 0);
|
||||
scr_globals::globalplayer_bd.as<GlobalPlayerBD*>()->Entries[self::id].IsInvisible = false;
|
||||
}
|
||||
};
|
||||
|
||||
invisibility g_invisibility("invis", "Invisiblity", "Makes you invisible", g.self.invisibility);
|
||||
bool_command g_local_visibility("localvis", "Visible Locally", "Makes you visible to yourself, other players will still not be able to see you", g.self.local_visibility);
|
||||
bool_command g_local_visibility("localvis", "Visible Locally", "Makes you visible to yourself, but other players would still not be able to see you", g.self.local_visibility);
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ namespace big
|
||||
bLast = b;
|
||||
}
|
||||
|
||||
if(g.self.force_wanted_level && !b)
|
||||
if (g.self.force_wanted_level && !b)
|
||||
g_local_player->m_player_info->m_wanted_level = g.self.wanted_level;
|
||||
}
|
||||
}
|
@ -48,7 +48,7 @@ namespace big
|
||||
|
||||
virtual void on_tick() override
|
||||
{
|
||||
if(self::veh == 0)
|
||||
if (self::veh == 0)
|
||||
show_player_ptfx_effect(g.self.ptfx_effects.asset, g.self.ptfx_effects.effect);
|
||||
else
|
||||
show_vehicle_ptfx_effect(g.self.ptfx_effects.asset, g.self.ptfx_effects.effect);
|
||||
|
@ -27,5 +27,5 @@ namespace big
|
||||
}
|
||||
};
|
||||
|
||||
super_jump_looped g_super_jump_looped("superjump", "Super Jump", "Allows You To Jump Really High", g.self.super_jump);
|
||||
super_jump_looped g_super_jump_looped("superjump", "Super Jump", "Allows you to jump really high", g.self.super_jump);
|
||||
}
|
@ -37,5 +37,5 @@ namespace big
|
||||
}
|
||||
};
|
||||
|
||||
superman g_superman("superman", "Superman", "Fly like a superman..", g.self.superman);
|
||||
superman g_superman("superman", "Superman", "Fly like a superman", g.self.superman);
|
||||
}
|
||||
|
@ -10,8 +10,8 @@ namespace big
|
||||
|
||||
virtual void on_tick() override
|
||||
{
|
||||
//if (g_local_player)
|
||||
// g_local_player->m_ped_intelligence->m_oxygen_time = 0;
|
||||
if (g_local_player)
|
||||
g_local_player->m_ped_intelligence->m_oxygen_time = 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -14,9 +14,7 @@ namespace big
|
||||
if (!teleport::to_blip((int)BlipIcons::Waypoint))
|
||||
return;
|
||||
|
||||
bool temp_disable_tp = (!*g_pointers->m_is_session_started) && CUTSCENE::IS_CUTSCENE_ACTIVE();
|
||||
if (!temp_disable_tp)
|
||||
teleport::to_waypoint();
|
||||
teleport::to_waypoint();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -9,13 +9,27 @@ namespace big
|
||||
{
|
||||
using looped_command::looped_command;
|
||||
|
||||
bool last_driving = false;
|
||||
|
||||
virtual void on_tick() override
|
||||
{
|
||||
if (!PED::GET_PED_CONFIG_FLAG(self::ped, 62, false))
|
||||
{
|
||||
if (last_driving)
|
||||
{
|
||||
ENTITY::SET_ENTITY_VISIBLE(self::veh, true, 0);
|
||||
}
|
||||
|
||||
last_driving = false;
|
||||
return;
|
||||
}
|
||||
|
||||
last_driving = true;
|
||||
|
||||
ENTITY::SET_ENTITY_VISIBLE(self::veh, false, 0);
|
||||
|
||||
if (g.vehicle.localveh_visibility)
|
||||
NETWORK::SET_ENTITY_LOCALLY_VISIBLE(self::veh);
|
||||
if (g.vehicle.localped_visibility && g.vehicle.vehinvisibility)
|
||||
ENTITY::SET_ENTITY_VISIBLE(self::ped, true, 0);
|
||||
}
|
||||
|
||||
virtual void on_disable() override
|
||||
@ -26,5 +40,4 @@ namespace big
|
||||
|
||||
vehinvisibility g_vehinvisibility("invisveh", "Vehicle Invisiblity", "Makes your car invisible", g.vehicle.vehinvisibility);
|
||||
bool_command g_localveh_visibility("localinvisveh", "Visible Locally", "Makes your car visible to yourself, other players will still not be able to see it", g.vehicle.localveh_visibility);
|
||||
bool_command g_localped_visibility("localinvisped", "Self Visible", "Makes yourself visible driving the vehicle to others and yourself,\n car will still be invisible but you can be", g.vehicle.localped_visibility);
|
||||
}
|
||||
|
@ -9,7 +9,12 @@ namespace big
|
||||
|
||||
virtual void on_tick() override
|
||||
{
|
||||
VEHICLE::SET_VEHICLE_ON_GROUND_PROPERLY(self::veh, 5.0);
|
||||
auto model = ENTITY::GET_ENTITY_MODEL(self::veh);
|
||||
|
||||
if (ENTITY::IS_ENTITY_IN_AIR(self::veh) &&
|
||||
(VEHICLE::IS_THIS_MODEL_A_CAR(model) ||
|
||||
VEHICLE::IS_THIS_MODEL_A_BIKE(model)))
|
||||
VEHICLE::SET_VEHICLE_ON_GROUND_PROPERLY(self::veh, 5.0);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,10 +1,12 @@
|
||||
#include "backend/looped/looped.hpp"
|
||||
#include "util/misc.hpp"
|
||||
#include "natives.hpp"
|
||||
|
||||
namespace big
|
||||
{
|
||||
static uint32_t last_bits = 0;
|
||||
static float last_water_collistion_strength = 0;
|
||||
static bool last_driving;
|
||||
|
||||
void looped::vehicle_god_mode()
|
||||
{
|
||||
@ -13,10 +15,22 @@ namespace big
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
(g.vehicle.god_mode || g.vehicle.proof_collision) &&
|
||||
g_local_player->m_ped_task_flag & (int)ePedTask::TASK_DRIVING
|
||||
) {
|
||||
if (!PED::GET_PED_CONFIG_FLAG(self::ped, 62, false))
|
||||
{
|
||||
if (last_driving)
|
||||
{
|
||||
g_local_player->m_vehicle->m_deform_god = 0x9C;
|
||||
g_local_player->m_vehicle->m_damage_bits = 0;
|
||||
}
|
||||
|
||||
last_driving = false;
|
||||
return;
|
||||
}
|
||||
|
||||
last_driving = true;
|
||||
|
||||
if (g.vehicle.god_mode || g.vehicle.proof_collision)
|
||||
{
|
||||
g_local_player->m_vehicle->m_deform_god = 0x8C;
|
||||
}
|
||||
else
|
||||
|
@ -65,8 +65,11 @@ namespace big
|
||||
|
||||
for (auto entity : target_entities)
|
||||
{
|
||||
auto entity_coord = ENTITY::GET_ENTITY_COORDS(entity, false);
|
||||
ENTITY::APPLY_FORCE_TO_ENTITY(entity, 1, ((g.world.blackhole.pos.x - entity_coord.x) * 9.f), ((g.world.blackhole.pos.y - entity_coord.y) * 9.f), ((g.world.blackhole.pos.z - entity_coord.z) * 9.f), 0.f, 0.f, 0.f, 0, false, true, true, 0, 0);
|
||||
if (entity::take_control_of(entity, 0))
|
||||
{
|
||||
auto entity_coord = ENTITY::GET_ENTITY_COORDS(entity, false);
|
||||
ENTITY::APPLY_FORCE_TO_ENTITY(entity, 1, ((g.world.blackhole.pos.x - entity_coord.x) * 9.f), ((g.world.blackhole.pos.y - entity_coord.y) * 9.f), ((g.world.blackhole.pos.z - entity_coord.z) * 9.f), 0.f, 0.f, 0.f, 0, false, true, true, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//draw blackhole
|
||||
|
@ -8,7 +8,8 @@ namespace big
|
||||
{
|
||||
g_script_patcher_service->add_patch({ RAGE_JOAAT("freemode"), "2D 01 08 00 ? 38 00 5D ? ? ? 2A 06", 5, {0x71, 0x2E, 0x01, 0x01}, &g.session.decloak_players });
|
||||
g_script_patcher_service->add_patch({ RAGE_JOAAT("freemode"), "2D 01 04 00 ? 2C ? ? ? 5D ? ? ? 71 57 ? ? 2C", 5, { 0x2E, 0x01, 0x00 }, nullptr }); // script host kick
|
||||
g_script_patcher_service->add_patch({ RAGE_JOAAT("freemode"), "2D 00 07 00 00 5D ? ? ? 56 ? ? 71", 5, { 0x2E, 0x00, 0x00 }, &g.tunables.no_idle_kick });
|
||||
g_script_patcher_service->add_patch({ RAGE_JOAAT("freemode"), "2D 00 03 00 00 5D ? ? ? 71 08", 5, { 0x2E, 0x00, 0x00 }, &g.tunables.no_idle_kick });
|
||||
g_script_patcher_service->add_patch({ RAGE_JOAAT("freemode"), "2D 00 03 00 00 5D ? ? ? 56 ? ? 72 2E ? ? 62", 5, { 0x72, 0x2E, 0x00, 0x01 }, &g.tunables.no_idle_kick });
|
||||
g_script_patcher_service->add_patch({ RAGE_JOAAT("freemode"), "5D ? ? ? 76 57 ? ? 5D ? ? ? 76", 0, { 0x2E, 0x00, 0x00 }, nullptr }); // end session kick protection
|
||||
g_script_patcher_service->add_patch({ RAGE_JOAAT("freemode"), "2D 01 09 00 00 5D ? ? ? 56 ? ? 2E", 5, { 0x2E, 0x01, 0x00 }, nullptr }); // disable death when undermap/spectating
|
||||
g_script_patcher_service->add_patch({ RAGE_JOAAT("freemode"), "71 2E ? ? 55 ? ? 61 ? ? ? 47 ? ? 63", 0, { 0x72 }, nullptr }); // load island even if stranded animal IPL choice is not set
|
||||
|
1028
src/core/data/all_script_names.hpp
Normal file
1028
src/core/data/all_script_names.hpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -42,7 +42,7 @@ inline const static constexpr std::pair<const char*, std::uint32_t> packet_types
|
||||
{ "MsgScriptHostRequest", 0x67 },
|
||||
{ "MsgScriptHandshakeAck", 0x5B },
|
||||
{ "MsgScriptHandshake", 0x57 },
|
||||
{ "MsgScriptBotLeave", 0x2 },
|
||||
{ "MsgScriptBotLeave", 0x2B },
|
||||
{ "MsgScriptBotJoinAck", 0x63 },
|
||||
{ "MsgScriptBotJoin", 0x1C },
|
||||
{ "MsgScriptBotHandshakeAck", 0x31 },
|
||||
|
36
src/core/data/stack_sizes.hpp
Normal file
36
src/core/data/stack_sizes.hpp
Normal file
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
namespace big
|
||||
{
|
||||
constexpr inline static const std::pair<const char*, int> stack_sizes[] =
|
||||
{
|
||||
{ "MICRO", 128 },
|
||||
{ "MINI", 512 },
|
||||
{ "DEFAULT", 1424 },
|
||||
{ "SPECIAL_ABILITY", 1828 },
|
||||
{ "FRIEND", 2050 },
|
||||
{ "SHOP", 2324 },
|
||||
{ "CELLPHONE", 2552 },
|
||||
{ "VEHICLE_SPAWN", 3568 },
|
||||
{ "CAR_MOD_SHOP", 3650 },
|
||||
{ "PAUSE_MENU_SCRIPT", 3076 },
|
||||
{ "APP_INTERNET", 4592 },
|
||||
{ "MULTIPLAYER_MISSION", 5050 },
|
||||
{ "CONTACTS_APP", 4000 },
|
||||
{ "INTERACTION_MENU", 9800 },
|
||||
{ "SCRIPT_XML", 8344 },
|
||||
{ "PROPERTY_INT", 19400 },
|
||||
{ "ACTIVITY_CREATOR_INT", 15900 },
|
||||
{ "SMPL_INTERIOR", 2512 },
|
||||
{ "WAREHOUSE", 14100 },
|
||||
{ "IE_DELIVERY", 2324 },
|
||||
{ "SHOP_CONTROLLER", 3800 },
|
||||
{ "AM_MP_YACHT", 5000 },
|
||||
{ "INGAMEHUD", 4600 },
|
||||
{ "TRANSITION", 8032 },
|
||||
{ "FMMC_LAUNCHER", 24000 },
|
||||
{ "MULTIPLAYER_FREEMODE", 72500 },
|
||||
{ "MISSION", 54000 },
|
||||
{ "MP_LAUNCH_SCRIPT", 33750 },
|
||||
};
|
||||
}
|
@ -475,6 +475,8 @@ namespace big
|
||||
|
||||
struct spoofing
|
||||
{
|
||||
bool hide_from_player_list = false;
|
||||
|
||||
bool spoof_cheater = false;
|
||||
|
||||
bool spoof_hide_god = true;
|
||||
@ -493,7 +495,7 @@ namespace big
|
||||
int session_player_count = 25;
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(spoofing,
|
||||
spoof_cheater, spoof_hide_god, spoof_hide_spectate, spoof_crew_data, crew_tag, rockstar_crew,
|
||||
hide_from_player_list, spoof_cheater, spoof_hide_god, spoof_hide_spectate, spoof_crew_data, crew_tag, rockstar_crew,
|
||||
square_crew_tag, spoof_session_region_type, session_region_type, spoof_session_language,
|
||||
session_language, spoof_session_player_count, session_player_count)
|
||||
} spoofing{};
|
||||
|
@ -15,12 +15,13 @@ namespace big::scr_globals
|
||||
static inline script_global gsbd_kicking(1885209);
|
||||
static inline script_global gsbd_fm_events(1923597);
|
||||
static inline script_global gsbd_block_c(2652258);
|
||||
static inline script_global gsbd_property_instances(1943595);
|
||||
|
||||
static inline script_global globalplayer_bd(2657589);
|
||||
static inline script_global gpbd_fm_3(1894573);
|
||||
static inline script_global gpbd_fm_1(1853910);
|
||||
|
||||
static inline script_global launcher_global(2756257);
|
||||
static inline script_global launcher_global(2756259);
|
||||
|
||||
static inline script_global sp(113648);
|
||||
static inline script_global mission_definition(91469);
|
||||
|
@ -140,11 +140,7 @@ namespace rage
|
||||
virtual std::int32_t _0x70() = 0; // 14 (0x70)
|
||||
virtual void* _0x78() = 0; // 15 (0x78)
|
||||
public:
|
||||
char m_padding1[0x28]; // 0x08
|
||||
bool m_initialized; // 0x30
|
||||
bool m_initialized2; // 0x31
|
||||
char m_padding2[0x0E]; // 0x32
|
||||
rage::netLoggingInterface* m_logger; // 0x40
|
||||
char pad_0008[104];
|
||||
};
|
||||
}
|
||||
|
||||
@ -175,10 +171,6 @@ public:
|
||||
std::uint8_t m_0xAF; // 0xAF
|
||||
};
|
||||
|
||||
class CGameScriptHandlerMgr : public rage::scriptHandlerMgr
|
||||
{
|
||||
};
|
||||
|
||||
class CScriptParticipant
|
||||
{
|
||||
public:
|
||||
@ -310,6 +302,42 @@ public:
|
||||
}; //Size: 0x01B0
|
||||
static_assert(sizeof(CGameScriptHandlerNetComponent) == 0x1B0);
|
||||
|
||||
class CRemoteScriptInfo : public CGameScriptId
|
||||
{
|
||||
public:
|
||||
uint32_t m_participants; //0x0040
|
||||
char pad_0044[4]; //0x0044
|
||||
class CNetGamePlayer* m_host; //0x0048
|
||||
uint32_t m_timestamp_2; //0x0050
|
||||
uint16_t m_host_token; //0x0054
|
||||
uint8_t m_reserved_peds; //0x0056
|
||||
uint8_t m_reserved_vehicles; //0x0057
|
||||
uint8_t m_reserved_objects; //0x0058
|
||||
uint8_t m_reserved_unk1; //0x0059
|
||||
uint8_t m_reserved_unk2; //0x005A
|
||||
uint8_t m_reserved_unk3; //0x005B
|
||||
uint8_t m_reserved_unk4; //0x005C
|
||||
char pad_005D[3]; //0x005D
|
||||
}; //Size: 0x0060
|
||||
static_assert(sizeof(CRemoteScriptInfo) == 0x60);
|
||||
|
||||
class CGameScriptHandlerMgr : public rage::scriptHandlerMgr
|
||||
{
|
||||
public:
|
||||
char pad_0070[56]; //0x0070
|
||||
class CRemoteScriptInfo m_remote_script_infos[320]; //0x00A8
|
||||
char pad_78A8[4]; //0x78A8
|
||||
uint32_t m_remote_script_start_idx; //0x78AC
|
||||
uint32_t m_remote_script_count; //0x78B0
|
||||
char pad_78B4[4]; //0x78B4
|
||||
class CRemoteScriptInfo m_detached_remote_script_infos[64]; //0x78B8
|
||||
char pad_90B8[4]; //0x90B8
|
||||
uint32_t m_detached_remote_script_start_idx; //0x90BC
|
||||
uint32_t m_detached_remote_script_count; //0x90C0
|
||||
char pad_90C4[28]; //0x90C4
|
||||
}; //Size: 0x90E0
|
||||
static_assert(sizeof(CGameScriptHandlerMgr) == 0x90E0);
|
||||
|
||||
|
||||
static_assert(sizeof(rage::scriptHandler) == 0x60);
|
||||
static_assert(sizeof(CGameScriptHandler) == 0xA0);
|
||||
|
@ -55,23 +55,29 @@ namespace big::gta_util
|
||||
}
|
||||
|
||||
template <typename F, typename ...Args>
|
||||
void execute_as_script(rage::joaat_t script_hash, F &&callback, Args &&...args)
|
||||
void execute_as_script(rage::scrThread* thread, F&& callback, Args &&...args)
|
||||
{
|
||||
auto tls_ctx = rage::tlsContext::get();
|
||||
auto og_thread = tls_ctx->m_script_thread;
|
||||
|
||||
tls_ctx->m_script_thread = thread;
|
||||
tls_ctx->m_is_script_thread_active = true;
|
||||
|
||||
std::invoke(std::forward<F>(callback), std::forward<Args>(args)...);
|
||||
|
||||
tls_ctx->m_script_thread = og_thread;
|
||||
tls_ctx->m_is_script_thread_active = og_thread != nullptr;
|
||||
}
|
||||
|
||||
template <typename F, typename ...Args>
|
||||
void execute_as_script(rage::joaat_t script_hash, F &&callback, Args &&...args)
|
||||
{
|
||||
for (auto thread : *g_pointers->m_script_threads)
|
||||
{
|
||||
if (!thread || !thread->m_context.m_thread_id || thread->m_context.m_script_hash != script_hash)
|
||||
continue;
|
||||
|
||||
auto og_thread = tls_ctx->m_script_thread;
|
||||
|
||||
tls_ctx->m_script_thread = thread;
|
||||
tls_ctx->m_is_script_thread_active = true;
|
||||
|
||||
std::invoke(std::forward<F>(callback), std::forward<Args>(args)...);
|
||||
|
||||
tls_ctx->m_script_thread = og_thread;
|
||||
tls_ctx->m_is_script_thread_active = og_thread != nullptr;
|
||||
execute_as_script(thread, callback, args...);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -93,6 +99,21 @@ namespace big::gta_util
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inline GtaThread* find_script_thread_by_id(std::uint32_t id)
|
||||
{
|
||||
for (auto thread : *g_pointers->m_script_threads)
|
||||
{
|
||||
if (thread
|
||||
&& thread->m_handler
|
||||
&& thread->m_context.m_thread_id == id)
|
||||
{
|
||||
return thread;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inline rage::scrProgram* find_script_program(rage::joaat_t hash)
|
||||
{
|
||||
for (auto& script : *g_pointers->m_script_program_table)
|
||||
|
@ -102,6 +102,8 @@ namespace big
|
||||
|
||||
detour_hook_helper::add<hooks::receive_pickup>("RPI", g_pointers->m_receive_pickup);
|
||||
|
||||
detour_hook_helper::add<hooks::write_player_camera_data_node>("WPCDN", g_pointers->m_write_player_camera_data_node);
|
||||
|
||||
g_hooking = this;
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@ class CPlayerGameStateDataNode;
|
||||
class CPedInventoryDataNode;
|
||||
class CDynamicEntityGameStateDataNode;
|
||||
class CVehicleGadgetDataNode;
|
||||
class CPlayerCameraDataNode;
|
||||
class CJoinRequestContext;
|
||||
class SessionSortEntry;
|
||||
class RemoteGamerInfoMsg;
|
||||
@ -147,7 +148,9 @@ namespace big
|
||||
static bool received_array_update(rage::netArrayHandlerBase* array, CNetGamePlayer* sender, rage::datBitBuffer* buffer, int size, std::int16_t cycle);
|
||||
|
||||
static bool receive_pickup(rage::netObject* netobject, void* unk, CPed* ped);
|
||||
};
|
||||
|
||||
static bool write_player_camera_data_node(rage::netObject* player, CPlayerCameraDataNode* node);
|
||||
};
|
||||
|
||||
class minhook_keepalive
|
||||
{
|
||||
|
@ -319,10 +319,12 @@ namespace big
|
||||
|
||||
bool hooks::can_apply_data(rage::netSyncTree* tree, rage::netObject* object)
|
||||
{
|
||||
#if 0
|
||||
if (tree->m_child_node_count && check_node(tree->m_sync_node, g.m_syncing_player, object))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return g_hooking->get_original<hooks::can_apply_data>()(tree, object);
|
||||
}
|
||||
|
@ -93,36 +93,6 @@ namespace big
|
||||
if (!get_msg_type(msgType, buffer))
|
||||
return g_hooking->get_original<hooks::receive_net_message>()(netConnectionManager, a2, frame);
|
||||
|
||||
if ((msgType == rage::eNetMessage::MsgTransitionLaunchNotify && frame->m_connection_identifier != gta_util::get_network()->m_game_session.m_connection_identifier) ||
|
||||
(msgType == rage::eNetMessage::MsgTransitionLaunch && frame->m_connection_identifier != gta_util::get_network()->m_transition_session.m_connection_identifier))
|
||||
{
|
||||
if (player)
|
||||
{
|
||||
g_notification_service->push_error("PROTECTIONS"_T.data(),
|
||||
std::vformat("REMOTE_CRASH_INVALID_TRANSITION_FROM"_T, std::make_format_args(player->get_name())));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_notification_service->push_error("PROTECTIONS"_T.data(), "REMOTE_CRASH_INVALID_TRANSITION"_T.data());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (msgType == rage::eNetMessage::MsgBlacklist && frame->m_connection_identifier != gta_util::get_network()->m_game_session.m_connection_identifier)
|
||||
{
|
||||
if (player)
|
||||
{
|
||||
g_notification_service->push_error("PROTECTIONS"_T.data(),
|
||||
std::vformat("REMOTE_CRASH_INVALID_BLACKLIST_FROM"_T, std::make_format_args(player->get_name())));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_notification_service->push_error("PROTECTIONS"_T.data(), "REMOTE_CRASH_INVALID_BLACKLIST"_T.data());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (player)
|
||||
{
|
||||
switch (msgType)
|
||||
@ -251,26 +221,6 @@ namespace big
|
||||
else
|
||||
return true;
|
||||
}
|
||||
case rage::eNetMessage::MsgSessionEstablished:
|
||||
{
|
||||
#if 0
|
||||
rage::rlGamerHandle handle{ 0 };
|
||||
if (player->get_net_data())
|
||||
{
|
||||
uint64_t session_id;
|
||||
buffer.ReadQWord(&session_id, 64);
|
||||
gamer_handle_deserialize(handle, buffer);
|
||||
if (session_id == gta_util::get_network()->m_game_session_ptr->m_rline_session.m_session_id)
|
||||
{
|
||||
if (handle.m_rockstar_id != player->get_net_data()->m_gamer_handle.m_rockstar_id)
|
||||
{
|
||||
session::add_infraction(player, Infraction::SPOOFED_ROCKSTAR_ID); // TODO: store this RID
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case rage::eNetMessage::MsgNetComplaint:
|
||||
{
|
||||
uint64_t host_token{};
|
||||
|
@ -470,7 +470,7 @@ namespace big
|
||||
case eNetworkEvents::REQUEST_CONTROL_EVENT:
|
||||
{
|
||||
int net_id = buffer->Read<int>(13);
|
||||
if (g_local_player && g_local_player->m_vehicle && g_local_player->m_vehicle->m_net_object && g_local_player->m_vehicle->m_net_object->m_object_id == net_id)
|
||||
if (g_local_player && g_local_player->m_vehicle && g_local_player->m_vehicle->m_net_object && g_local_player->m_vehicle->m_net_object->m_object_id == net_id && g_local_player->m_vehicle->m_driver == g_local_player)
|
||||
{
|
||||
g_pointers->m_send_event_ack(event_manager, source_player, target_player, event_index, event_handled_bitset);
|
||||
g.reactions.request_control_event.process(plyr);
|
||||
|
@ -3,6 +3,13 @@
|
||||
|
||||
#include "services/script_patcher/script_patcher_service.hpp"
|
||||
|
||||
#include "pointers.hpp"
|
||||
#include "core/scr_globals.hpp"
|
||||
#include <script/globals/GlobalPlayerBD.hpp>
|
||||
|
||||
static int old_cayo_flags;
|
||||
static int old_shop_index;
|
||||
|
||||
namespace big
|
||||
{
|
||||
class script_vm_guard
|
||||
@ -18,11 +25,29 @@ namespace big
|
||||
|
||||
if (auto bytecode = g_script_patcher_service->get_script_bytecode(program->m_name_hash))
|
||||
program->m_code_blocks = bytecode;
|
||||
|
||||
if (g_pointers->m_script_globals[0xA])
|
||||
{
|
||||
scr_globals::globalplayer_bd.as<GlobalPlayerBD*>()->Entries[self::id].CurrentShopIndex = old_shop_index;
|
||||
scr_globals::globalplayer_bd.as<GlobalPlayerBD*>()->Entries[self::id].CayoPericoFlags = old_cayo_flags;
|
||||
}
|
||||
}
|
||||
|
||||
~script_vm_guard()
|
||||
{
|
||||
m_program->m_code_blocks = m_orig_bytecode;
|
||||
|
||||
if (g_pointers->m_script_globals[0xA])
|
||||
{
|
||||
old_shop_index = scr_globals::globalplayer_bd.as<GlobalPlayerBD*>()->Entries[self::id].CurrentShopIndex;
|
||||
old_cayo_flags = scr_globals::globalplayer_bd.as<GlobalPlayerBD*>()->Entries[self::id].CayoPericoFlags;
|
||||
|
||||
if (g.spoofing.hide_from_player_list)
|
||||
{
|
||||
scr_globals::globalplayer_bd.as<GlobalPlayerBD*>()->Entries[self::id].CurrentShopIndex = -1;
|
||||
scr_globals::globalplayer_bd.as<GlobalPlayerBD*>()->Entries[self::id].CayoPericoFlags = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
22
src/hooks/spoofing/write_player_camera_data_node.cpp
Normal file
22
src/hooks/spoofing/write_player_camera_data_node.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
#include "hooking.hpp"
|
||||
#include <datanodes/player/CPlayerGameStateDataNode.hpp>
|
||||
#include <datanodes/player/CPlayerCameraDataNode.hpp>
|
||||
#include "services/players/player_service.hpp"
|
||||
#include "util/globals.hpp"
|
||||
|
||||
namespace big
|
||||
{
|
||||
bool hooks::write_player_camera_data_node(rage::netObject* player, CPlayerCameraDataNode* node)
|
||||
{
|
||||
auto ret = g_hooking->get_original<hooks::write_player_camera_data_node>()(player, node);
|
||||
|
||||
if (g.spoofing.spoof_hide_spectate && g.player.spectating)
|
||||
{
|
||||
node->m_free_cam_pos_x += 50.0f;
|
||||
node->m_free_cam_pos_y -= 50.0f;
|
||||
node->m_camera_x -= 50.0f;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
@ -15,12 +15,12 @@ namespace big
|
||||
{
|
||||
const auto hash = src->get_arg<rage::joaat_t>(0);
|
||||
|
||||
BOOL return_value = DLC::IS_DLC_PRESENT(hash);
|
||||
bool return_value = DLC::IS_DLC_PRESENT(hash);
|
||||
|
||||
if (hash == 0x96F02EE6)
|
||||
return_value = return_value || g.settings.dev_dlc;
|
||||
|
||||
src->set_return_value<BOOL>(return_value);
|
||||
src->set_return_value<BOOL>((BOOL)return_value);
|
||||
}
|
||||
|
||||
void NETWORK_SET_THIS_SCRIPT_IS_NETWORK_SCRIPT(rage::scrNativeCallContext* src)
|
||||
@ -75,7 +75,7 @@ namespace big
|
||||
case ControllerInputs::INPUT_VEH_SELECT_PREV_WEAPON:
|
||||
case ControllerInputs::INPUT_DETONATE:
|
||||
case ControllerInputs::INPUT_PICKUP:
|
||||
case ControllerInputs::INPUT_JUMP:
|
||||
// case ControllerInputs::INPUT_JUMP: TODO: add as separate feature
|
||||
case ControllerInputs::INPUT_TALK:
|
||||
case ControllerInputs::INPUT_AIM:
|
||||
case ControllerInputs::INPUT_MELEE_ATTACK_LIGHT:
|
||||
@ -87,11 +87,24 @@ namespace big
|
||||
case ControllerInputs::INPUT_VEH_AIM:
|
||||
case ControllerInputs::INPUT_VEH_PASSENGER_ATTACK:
|
||||
case ControllerInputs::INPUT_VEH_FLY_SELECT_NEXT_WEAPON:
|
||||
case ControllerInputs::INPUT_ATTACK:
|
||||
case ControllerInputs::INPUT_NEXT_WEAPON:
|
||||
case ControllerInputs::INPUT_PREV_WEAPON:
|
||||
case ControllerInputs::INPUT_SELECT_NEXT_WEAPON:
|
||||
case ControllerInputs::INPUT_SELECT_PREV_WEAPON:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
PAD::DISABLE_CONTROL_ACTION(src->get_arg<int>(0), (int)action, src->get_arg<int>(2));
|
||||
}
|
||||
|
||||
void HUD_FORCE_WEAPON_WHEEL(rage::scrNativeCallContext* src)
|
||||
{
|
||||
if (g.weapons.interior_weapon && src->get_arg<BOOL>(0) == false)
|
||||
return;
|
||||
|
||||
HUD::HUD_FORCE_WEAPON_WHEEL(src->get_arg<BOOL>(0));
|
||||
}
|
||||
}
|
||||
}
|
@ -45,28 +45,35 @@ namespace big
|
||||
|
||||
void NETWORK_HAS_RECEIVED_HOST_BROADCAST_DATA(rage::scrNativeCallContext* src)
|
||||
{
|
||||
if (SCRIPT::GET_HASH_OF_THIS_SCRIPT_NAME() == RAGE_JOAAT("freemode") && g.session.force_script_host)
|
||||
if (NETWORK::NETWORK_IS_ACTIVITY_SESSION())
|
||||
{
|
||||
g_fiber_pool->queue_job([]
|
||||
{
|
||||
scripts::force_host(RAGE_JOAAT("freemode"));
|
||||
if (auto script = gta_util::find_script_thread(RAGE_JOAAT("freemode")); script && script->m_net_component)
|
||||
script->m_net_component->block_host_migration(true);
|
||||
});
|
||||
src->set_return_value<BOOL>(NETWORK::NETWORK_HAS_RECEIVED_HOST_BROADCAST_DATA());
|
||||
}
|
||||
|
||||
if (SCRIPT::GET_HASH_OF_THIS_SCRIPT_NAME() == RAGE_JOAAT("fmmc_launcher") && g.session.force_script_host)
|
||||
else
|
||||
{
|
||||
g_fiber_pool->queue_job([]
|
||||
if (SCRIPT::GET_HASH_OF_THIS_SCRIPT_NAME() == RAGE_JOAAT("freemode") && g.session.force_script_host)
|
||||
{
|
||||
scripts::force_host(RAGE_JOAAT("fmmc_launcher"));
|
||||
if (auto script = gta_util::find_script_thread(RAGE_JOAAT("fmmc_launcher")); script && script->m_net_component)
|
||||
script->m_net_component->block_host_migration(true);
|
||||
});
|
||||
}
|
||||
g_fiber_pool->queue_job([]
|
||||
{
|
||||
scripts::force_host(RAGE_JOAAT("freemode"));
|
||||
if (auto script = gta_util::find_script_thread(RAGE_JOAAT("freemode")); script && script->m_net_component)
|
||||
script->m_net_component->block_host_migration(true);
|
||||
});
|
||||
}
|
||||
|
||||
scr_functions::set_freemode_session_active({});
|
||||
src->set_return_value<BOOL>(TRUE);
|
||||
if (SCRIPT::GET_HASH_OF_THIS_SCRIPT_NAME() == RAGE_JOAAT("fmmc_launcher") && g.session.force_script_host)
|
||||
{
|
||||
g_fiber_pool->queue_job([]
|
||||
{
|
||||
scripts::force_host(RAGE_JOAAT("fmmc_launcher"));
|
||||
if (auto script = gta_util::find_script_thread(RAGE_JOAAT("fmmc_launcher")); script && script->m_net_component)
|
||||
script->m_net_component->block_host_migration(true);
|
||||
});
|
||||
}
|
||||
|
||||
scr_functions::set_freemode_session_active({});
|
||||
src->set_return_value<BOOL>(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -108,6 +108,7 @@ namespace big
|
||||
add_native_detour(0xD1110739EEADB592, all_scripts::NETWORK_TRY_TO_SET_THIS_SCRIPT_IS_NETWORK_SCRIPT);
|
||||
add_native_detour(0xADF692B254977C0C, all_scripts::SET_CURRENT_PED_WEAPON);
|
||||
add_native_detour(0xFE99B66D079CF6BC, all_scripts::DISABLE_CONTROL_ACTION);
|
||||
add_native_detour(0xEB354E5376BC81A7, all_scripts::HUD_FORCE_WEAPON_WHEEL);
|
||||
|
||||
add_native_detour(RAGE_JOAAT("carmod_shop"), 0x06843DA7060A026B, carmod_shop::SET_ENTITY_COORDS);
|
||||
add_native_detour(RAGE_JOAAT("carmod_shop"), 0x8E2530AA8ADA980E, carmod_shop::SET_ENTITY_HEADING);
|
||||
@ -142,6 +143,7 @@ namespace big
|
||||
add_native_detour(RAGE_JOAAT("fm_lts_creator"), 0x3D3D8B3BE5A83D35, creator::GET_USED_CREATOR_BUDGET);
|
||||
add_native_detour(RAGE_JOAAT("fm_survival_creator"), 0x3D3D8B3BE5A83D35, creator::GET_USED_CREATOR_BUDGET);
|
||||
|
||||
|
||||
for (auto& entry : *g_pointers->m_script_program_table)
|
||||
if (entry.m_program)
|
||||
hook_program(entry.m_program);
|
||||
|
@ -11,7 +11,7 @@ namespace big
|
||||
{
|
||||
if (g.session.join_queued)
|
||||
{
|
||||
g_pointers->m_join_session_by_info(*g_pointers->m_network, &g.session.info, 1, 1 | 2 | 4, nullptr, 0);
|
||||
g_pointers->m_join_session_by_info(*g_pointers->m_network, &g.session.info, 1, 1 | 2, nullptr, 0);
|
||||
g.session.join_queued = false;
|
||||
src->set_return_value<BOOL>(TRUE);
|
||||
}
|
||||
|
@ -818,6 +818,12 @@ namespace big
|
||||
m_receive_pickup = ptr.as<PVOID>();
|
||||
});
|
||||
|
||||
// Write Player Camera Data Node
|
||||
main_batch.add("WPCDN", "48 8B C4 48 89 58 20 55 56 57 41 54 41 55 41 56 41 57 48 8D 6C 24 B0 48 81 EC 50 01 00 00 4C", [this](memory::handle ptr)
|
||||
{
|
||||
m_write_player_camera_data_node = ptr.as<PVOID>();
|
||||
});
|
||||
|
||||
auto mem_region = memory::module("GTA5.exe");
|
||||
if (!main_batch.run(mem_region))
|
||||
{
|
||||
|
@ -239,6 +239,8 @@ namespace big
|
||||
PVOID m_received_array_update;
|
||||
|
||||
PVOID m_receive_pickup{};
|
||||
|
||||
PVOID m_write_player_camera_data_node{};
|
||||
};
|
||||
|
||||
inline pointers* g_pointers{};
|
||||
|
@ -65,7 +65,7 @@ namespace big
|
||||
bool ragdoll_loop = false;
|
||||
bool rotate_cam_loop = false;
|
||||
|
||||
rate_limiter m_host_migration_rate_limit{ 1s, 20 };
|
||||
rate_limiter m_host_migration_rate_limit{ 2s, 15 };
|
||||
rate_limiter m_play_sound_rate_limit{ 1s, 10 };
|
||||
rate_limiter m_invites_rate_limit{ 10s, 2 };
|
||||
int m_num_spawned_permanent_vehicles = 0;
|
||||
|
@ -131,7 +131,7 @@ namespace big
|
||||
ENTITY::SET_ENTITY_VISIBLE(vehicle_to_attach, attachment.is_visible, 0);
|
||||
ENTITY::SET_ENTITY_COLLISION(vehicle_to_attach, attachment.has_collision, true);
|
||||
ENTITY::SET_ENTITY_INVINCIBLE(vehicle_to_attach, attachment.is_invincible);
|
||||
VEHICLE::SET_VEHICLE_IS_CONSIDERED_BY_PLAYER(vehicle_to_attach, true);
|
||||
VEHICLE::SET_VEHICLE_IS_CONSIDERED_BY_PLAYER(vehicle_to_attach, false);
|
||||
}
|
||||
|
||||
return vehicle;
|
||||
|
@ -17,6 +17,7 @@ namespace big
|
||||
locals();
|
||||
script_events();
|
||||
scripts();
|
||||
threads();
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
ImGui::End();
|
||||
|
@ -8,6 +8,7 @@ namespace big::debug
|
||||
extern void misc();
|
||||
extern void script_events();
|
||||
extern void scripts();
|
||||
extern void threads();
|
||||
|
||||
extern void main();
|
||||
}
|
177
src/views/debug/view_debug_threads.cpp
Normal file
177
src/views/debug/view_debug_threads.cpp
Normal file
@ -0,0 +1,177 @@
|
||||
#include "gui/components/components.hpp"
|
||||
#include "natives.hpp"
|
||||
#include "util/system.hpp"
|
||||
#include "util/misc.hpp"
|
||||
#include "view_debug.hpp"
|
||||
#include "network/Network.hpp"
|
||||
#include "script.hpp"
|
||||
#include "gta/joaat.hpp"
|
||||
#include "script_global.hpp"
|
||||
#include "gta_util.hpp"
|
||||
|
||||
#include "core/data/all_script_names.hpp"
|
||||
#include "core/data/stack_sizes.hpp"
|
||||
|
||||
#include "fiber_pool.hpp"
|
||||
|
||||
static rage::scrThread* selected_thread;
|
||||
|
||||
static int selected_stack_size = 128;
|
||||
static int free_stacks = -1;
|
||||
static const char* selected_stack_size_str = "MULTIPLAYER_MISSION";
|
||||
static const char* selected_script = "<SELECT>";
|
||||
|
||||
static std::chrono::high_resolution_clock::time_point last_stack_update_time{};
|
||||
|
||||
namespace
|
||||
{
|
||||
static void update_free_stacks_count()
|
||||
{
|
||||
free_stacks = MISC::GET_NUMBER_OF_FREE_STACKS_OF_THIS_SIZE(selected_stack_size);
|
||||
}
|
||||
}
|
||||
|
||||
namespace big
|
||||
{
|
||||
|
||||
void debug::threads()
|
||||
{
|
||||
if (ImGui::BeginTabItem("Threads"))
|
||||
{
|
||||
if (!g_pointers->m_script_threads)
|
||||
{
|
||||
selected_thread = nullptr;
|
||||
ImGui::EndTabItem();
|
||||
return;
|
||||
}
|
||||
|
||||
components::small_text("Threads");
|
||||
|
||||
if (ImGui::BeginCombo("Thread", selected_thread ? selected_thread->m_name : "NONE"))
|
||||
{
|
||||
for (auto script : *g_pointers->m_script_threads)
|
||||
{
|
||||
if (script)
|
||||
{
|
||||
if (script->m_context.m_state != rage::eThreadState::killed && script->m_context.m_stack_size == 0)
|
||||
continue;
|
||||
|
||||
ImGui::PushID(script->m_context.m_thread_id);
|
||||
|
||||
if (script->m_context.m_state == rage::eThreadState::killed)
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.1f, 0.1f, 1.f));
|
||||
|
||||
if (ImGui::Selectable(script->m_name, selected_thread == script))
|
||||
{
|
||||
selected_thread = script;
|
||||
}
|
||||
|
||||
if (selected_thread == script)
|
||||
ImGui::SetItemDefaultFocus();
|
||||
|
||||
if (script->m_context.m_state == rage::eThreadState::killed)
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
if (selected_thread)
|
||||
{
|
||||
ImGui::Combo("State", (int*)&selected_thread->m_context.m_state, "RUNNING\0WAITING\0KILLED\0PAUSED\0STATE_4");
|
||||
|
||||
ImGui::Text("Stack Pointer / Stack Size %d/%d", selected_thread->m_context.m_stack_pointer, selected_thread->m_context.m_stack_size);
|
||||
ImGui::Text("IP: %X", selected_thread->m_context.m_instruction_pointer);
|
||||
if (selected_thread->m_context.m_state == rage::eThreadState::killed)
|
||||
ImGui::Text("Exit Reason: %s", selected_thread->m_exit_message);
|
||||
|
||||
if (ImGui::Button("Kill"))
|
||||
{
|
||||
if (selected_thread->m_context.m_stack_size != 0)
|
||||
selected_thread->kill();
|
||||
|
||||
selected_thread->m_context.m_state = rage::eThreadState::killed;
|
||||
}
|
||||
}
|
||||
|
||||
components::small_text("New");
|
||||
|
||||
if (ImGui::BeginCombo("Script", selected_script))
|
||||
{
|
||||
for (auto script : all_script_names)
|
||||
{
|
||||
if (ImGui::Selectable(script, script == selected_script))
|
||||
{
|
||||
selected_script = script;
|
||||
|
||||
}
|
||||
|
||||
if (script == selected_script)
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
if (ImGui::BeginCombo("Stack Size", selected_stack_size_str))
|
||||
{
|
||||
for (auto& p : stack_sizes)
|
||||
{
|
||||
if (ImGui::Selectable(std::format("{} ({})", p.first, p.second).data(), selected_stack_size == p.second))
|
||||
{
|
||||
selected_stack_size_str = p.first;
|
||||
selected_stack_size = p.second;
|
||||
|
||||
g_fiber_pool->queue_job([]
|
||||
{
|
||||
update_free_stacks_count();
|
||||
});
|
||||
}
|
||||
|
||||
if (p.second == selected_stack_size)
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
ImGui::Text("Free Stacks: %d", free_stacks);
|
||||
|
||||
components::button("Start", []
|
||||
{
|
||||
auto hash = rage::joaat(selected_script);
|
||||
|
||||
if (!SCRIPT::DOES_SCRIPT_WITH_NAME_HASH_EXIST(hash))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (MISC::GET_NUMBER_OF_FREE_STACKS_OF_THIS_SIZE(selected_stack_size) == 0)
|
||||
{
|
||||
g_notification_service->push_warning("Script Launcher", "No free stacks for this stack size");
|
||||
}
|
||||
|
||||
while (!SCRIPT::HAS_SCRIPT_WITH_NAME_HASH_LOADED(hash))
|
||||
{
|
||||
SCRIPT::REQUEST_SCRIPT_WITH_NAME_HASH(hash);
|
||||
script::get_current()->yield();
|
||||
}
|
||||
|
||||
SYSTEM::START_NEW_SCRIPT_WITH_NAME_HASH(hash, selected_stack_size);
|
||||
|
||||
SCRIPT::SET_SCRIPT_WITH_NAME_HASH_AS_NO_LONGER_NEEDED(hash);
|
||||
|
||||
update_free_stacks_count();
|
||||
});
|
||||
|
||||
if (*g_pointers->m_game_state != eGameState::Invalid && std::chrono::high_resolution_clock::now() - last_stack_update_time > 100ms)
|
||||
{
|
||||
last_stack_update_time = std::chrono::high_resolution_clock::now();
|
||||
g_fiber_pool->queue_job([]
|
||||
{
|
||||
update_free_stacks_count();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -11,6 +11,8 @@ namespace big
|
||||
{
|
||||
components::small_text("SPOOFING_DESCRIPTION"_T);
|
||||
|
||||
ImGui::Checkbox("Hide From Player List", &g.spoofing.hide_from_player_list);
|
||||
|
||||
components::sub_title("SPOOFING_HIDE_FEATURES"_T);
|
||||
ImGui::Checkbox("SPOOFING_HIDE_GOD_MODE"_T.data(), &g.spoofing.spoof_hide_god);
|
||||
ImGui::Checkbox("SPOOFING_HIDE_SPECTATE"_T.data(), &g.spoofing.spoof_hide_spectate);
|
||||
|
@ -106,7 +106,7 @@ namespace big
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if (auto net_player_data = g_player_service->get_selected()->get_net_data(); net_player_data != nullptr)
|
||||
if (auto net_player_data = g_player_service->get_selected()->get_net_data())
|
||||
{
|
||||
ImGui::Text("PLAYER_INFO_RID"_T.data(), net_player_data->m_gamer_handle.m_rockstar_id);
|
||||
|
||||
|
@ -26,7 +26,7 @@ namespace big
|
||||
|
||||
ImGui::BeginGroup();
|
||||
|
||||
ImGui::Checkbox("God Mode", &g.self.god_mode);
|
||||
components::command_checkbox<"godmode">();
|
||||
components::command_checkbox<"otr">();
|
||||
components::command_checkbox<"freecam">();
|
||||
components::command_checkbox<"nophone">();
|
||||
@ -52,14 +52,13 @@ namespace big
|
||||
|
||||
components::command_checkbox<"invis">();
|
||||
if (g.self.invisibility)
|
||||
components::command_checkbox<"localvis">();
|
||||
components::command_checkbox<"localvis">(); // TODO: does nothing in SP
|
||||
components::command_checkbox<"cleanloop">();
|
||||
components::command_checkbox<"nocollision">();
|
||||
components::command_checkbox<"mobileradio">();
|
||||
components::command_checkbox<"superman">();
|
||||
|
||||
// TODO: fix this, causes a crash
|
||||
// ImGui::Checkbox("DANCE_MODE"_T.data(), &g.self.dance_mode);
|
||||
ImGui::Checkbox("DANCE_MODE"_T.data(), &g.self.dance_mode);
|
||||
|
||||
ImGui::EndGroup();
|
||||
|
||||
|
@ -17,7 +17,7 @@ namespace big
|
||||
|
||||
components::command_checkbox<"infammo">();
|
||||
components::command_checkbox<"infclip">();
|
||||
ImGui::Checkbox("Interior Weapon", &g.weapons.interior_weapon);
|
||||
ImGui::Checkbox("Allow Weapons In Interiors", &g.weapons.interior_weapon);
|
||||
|
||||
ImGui::EndGroup();
|
||||
ImGui::SameLine();
|
||||
|
@ -75,7 +75,6 @@ namespace big
|
||||
if (g.vehicle.vehinvisibility)
|
||||
{
|
||||
components::command_checkbox<"localinvisveh">();
|
||||
components::command_checkbox<"localinvisped">();
|
||||
}
|
||||
|
||||
ImGui::EndGroup();
|
||||
|
Reference in New Issue
Block a user