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:
maybegreat48 2023-02-13 20:38:30 +00:00 committed by GitHub
parent 221eea137e
commit ac508dfd61
49 changed files with 1656 additions and 155 deletions

View File

@ -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 ""

View File

@ -37,7 +37,6 @@ namespace big
while (g_running)
{
looped::self_godmode();
looped::self_police();
looped::self_hud();
looped::self_dance_mode();

View File

@ -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());
}
};

View File

@ -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();

View File

@ -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);
}

View File

@ -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({});
});

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;
}
};

View File

@ -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();
}
};

View File

@ -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);
}

View File

@ -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);
}
};

View File

@ -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

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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 },

View 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 },
};
}

View File

@ -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{};

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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;
}

View File

@ -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
{

View File

@ -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{};

View File

@ -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);

View File

@ -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;
}
}
}
};

View 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;
}
}

View File

@ -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));
}
}
}

View File

@ -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);
}
}
}
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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))
{

View File

@ -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{};

View File

@ -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;

View File

@ -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;

View File

@ -17,6 +17,7 @@ namespace big
locals();
script_events();
scripts();
threads();
ImGui::EndTabBar();
}
ImGui::End();

View File

@ -8,6 +8,7 @@ namespace big::debug
extern void misc();
extern void script_events();
extern void scripts();
extern void threads();
extern void main();
}

View 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();
});
}
}
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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();

View File

@ -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();

View File

@ -75,7 +75,6 @@ namespace big
if (g.vehicle.vehinvisibility)
{
components::command_checkbox<"localinvisveh">();
components::command_checkbox<"localinvisped">();
}
ImGui::EndGroup();