Toxic features and improve protections (#897)

This commit is contained in:
maybegreat48 2023-01-22 21:57:32 +00:00 committed by GitHub
parent f360d7f436
commit d45d0c1ffc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
59 changed files with 8056 additions and 6801 deletions

View File

@ -107,6 +107,7 @@ namespace big
looped::session_force_thunder();
looped::session_randomize_ceo_colors();
looped::session_auto_kick_host();
looped::session_block_jobs();
script::get_current()->yield();
}
@ -176,4 +177,16 @@ namespace big
script::get_current()->yield();
}
}
void backend::world_loop()
{
LOG(INFO) << "Starting script: World";
while (g_running)
{
looped::world_spawn_ped();
script::get_current()->yield();
}
}
}

View File

@ -17,5 +17,6 @@ namespace big
static void rainbowpaint_loop();
static void vehiclefly_loop();
static void disable_control_action_loop();
static void world_loop();
};
}

View File

@ -4,6 +4,9 @@
#include "core/scr_globals.hpp"
#include "util/misc.hpp"
#include <script/globals/GlobalPlayerBD.hpp>
#include <script/globals/GPBD_FM.hpp>
namespace big
{
class enter_interior : player_command
@ -12,29 +15,30 @@ namespace big
virtual void execute(player_ptr player, const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
{
if (*scr_globals::globalplayer_bd.at(player->id(), scr_globals::size::globalplayer_bd).at(318).at(6).as<int*>() == -1)
int id = player->id();
if (scr_globals::gpbd_fm_1.as<GPBD_FM*>()->Entries[id].PropertyData.Index != -1)
{
g_notification_service->push_error("Enter Interior", "Player does not seem to be in an interior");
return;
const size_t arg_count = 9;
int64_t args[arg_count] = {
(int64_t)eRemoteEvent::Teleport,
self::id,
(int64_t)player->id(),
(int64_t)(int)-1, 1, (int64_t)scr_globals::gpbd_fm_1.as<GPBD_FM*>()->Entries[id].PropertyData.Index, 1, 0, 1
};
g_pointers->m_trigger_script_event(1, args, arg_count, 1 << self::id);
}
else if (scr_globals::globalplayer_bd.as<GlobalPlayerBD*>()->Entries[id].SimpleInteriorData.Index != eSimpleInteriorIndex::SIMPLE_INTERIOR_INVALID)
{
*script_global(1950108).at(3346).as<Player*>() = scr_globals::globalplayer_bd.as<GlobalPlayerBD*>()->Entries[id].SimpleInteriorData.Owner;
*script_global(1950108).at(3683).as<eSimpleInteriorIndex*>() = scr_globals::globalplayer_bd.as<GlobalPlayerBD*>()->Entries[id].SimpleInteriorData.Index;
*script_global(1950108).at(3682).as<bool*>() = true;
scr_globals::globalplayer_bd.as<GlobalPlayerBD*>()->Entries[self::id].SimpleInteriorData.InteriorSubtype = scr_globals::globalplayer_bd.as<GlobalPlayerBD*>()->Entries[id].SimpleInteriorData.InteriorSubtype;
}
else
{
ctx->report_error("Player does not appear to be in an interior");
}
int owner = *scr_globals::globalplayer_bd.at(player->id(), scr_globals::size::globalplayer_bd).at(318).at(9).as<int*>();
if (owner == -1)
owner = player->id();
*script_global(1950108).at(3684).as<int*>() = 0;
*script_global(1950108).at(3682).as<int*>() = 1;
*script_global(1950108).at(4780).as<int*>() = 1;
*script_global(1950108).at(3218).as<int*>() = 1; // this doesnt exists at all?
*script_global(1950108).at(3214).as<int*>() = 1; // ^
*script_global(1950108).at(3689).as<int*>() = 1;
// misc::set_bit(script_global(1950108).at(1).as<int*>(), 22);
misc::set_bit(script_global(1950108).as<int*>(), 6);
misc::clear_bit(script_global(1950108).at(1).as<int*>(), 9);
*script_global(1950108).at(3346).as<int*>() = owner;
*script_global(1950108).at(3683).as<int*>() = *scr_globals::globalplayer_bd.at(player->id(), scr_globals::size::globalplayer_bd).at(318).at(6).as<int*>();
}
};

View File

@ -20,8 +20,16 @@ namespace big
if (leader == -1)
return;
else if (leader == player->id())
{
const size_t arg_count = 2;
int64_t args[arg_count] = {
(int64_t)eRemoteEvent::CeoKick,
(int64_t)self::id
};
g_pointers->m_trigger_script_event(1, args, arg_count, 1 << player->id());
return;
}
else

View File

@ -0,0 +1,32 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "core/scr_globals.hpp"
namespace big
{
class force_into_mission : player_command
{
using player_command::player_command;
virtual CommandAccessLevel get_access_level()
{
return CommandAccessLevel::AGGRESSIVE;
}
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 = 3;
int64_t args[arg_count] =
{
(int64_t)eRemoteEvent::ForceMission,
(int64_t)self::id,
0
};
g_pointers->m_trigger_script_event(1, args, arg_count, 1 << player->id());
}
};
force_into_mission g_force_into_mission("mission", "Force Into Mission", "Forces the player into a gunrunning mission", 0);
}

View File

@ -0,0 +1,35 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "core/scr_globals.hpp"
#include <script/globals/GPBD_FM_3.hpp>
namespace big
{
class send_fake_ban_message : player_command
{
using player_command::player_command;
virtual CommandAccessLevel get_access_level()
{
return CommandAccessLevel::AGGRESSIVE;
}
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::SendTextLabelSMS,
self::id
};
strcpy((char*)&args[2], "HUD_ROSBANPERM");
g_pointers->m_trigger_script_event(1, args, arg_count, 1 << player->id());
}
};
send_fake_ban_message g_send_fake_ban_message("fakeban", "Send Fake Ban Message", "Sends a fake ban notification to the player", 0);
}

View File

@ -0,0 +1,45 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "core/scr_globals.hpp"
#include <script/globals/GPBD_FM_3.hpp>
namespace big
{
static constexpr auto strippers = std::to_array({
"HCH",
"INF",
"JUL",
"NIK",
"SAP",
"TXI"
});
static constexpr auto sext_types = std::to_array({ "1ST", "2ND", "NEED" });
class send_sext : player_command
{
using player_command::player_command;
virtual CommandAccessLevel get_access_level()
{
return CommandAccessLevel::AGGRESSIVE;
}
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::SendTextLabelSMS,
self::id
};
strcpy((char*)&args[2], (std::string("SXT_") + strippers[rand() % strippers.size()] + "_" + sext_types[rand() % sext_types.size()]).data());
g_pointers->m_trigger_script_event(1, args, arg_count, 1 << player->id());
}
};
send_sext g_send_sext("sext", "Send Sext", "Sends a random sext (with an image attachment) to the player", 0);
}

View File

@ -0,0 +1,39 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "core/scr_globals.hpp"
#include <script/globals/GPBD_FM_3.hpp>
namespace big
{
class show_transaction_error : player_command
{
using player_command::player_command;
virtual CommandAccessLevel get_access_level()
{
return CommandAccessLevel::AGGRESSIVE;
}
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::TransactionError,
(int64_t)self::id,
1,
0,
0,
scr_globals::gpbd_fm_3.as<GPBD_FM_3*>()->Entries[player->id()].ScriptEventReplayProtectionCounter,
*scr_globals::gsbd_fm_events.at(9).as<int*>(),
*scr_globals::gsbd_fm_events.at(10).as<int*>()
};
g_pointers->m_trigger_script_event(1, args, arg_count, 1 << player->id());
}
};
show_transaction_error g_show_transaction_error("error", "Show Transaction Error", "Shows a transaction error to the player", 0);
}

View File

@ -0,0 +1,64 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "script.hpp"
#include <script/globals/GPBD_FM_3.hpp>
#include "core/scr_globals.hpp"
namespace big
{
template <int scriptId, int arg19 = 0>
class start_script : player_command
{
using player_command::player_command;
virtual CommandAccessLevel get_access_level()
{
return CommandAccessLevel::AGGRESSIVE;
}
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 = 25;
int64_t args[arg_count] =
{
(int64_t)eRemoteEvent::StartScriptBegin,
(int64_t)self::id
};
args[2] = scriptId;
strcpy((char*)&args[2 + 3], "0");
args[2 + 16] = -1;
args[2 + 17] = 1337;
args[2 + 19] = arg19;
args[24] = scr_globals::gpbd_fm_3.as<GPBD_FM_3*>()->Entries[player->id()].ScriptEventReplayProtectionCounter;
g_pointers->m_trigger_script_event(1, args, arg_count, 1 << player->id());
for (int i = 0; i < 2; i++)
{
const size_t arg_count_2 = 25;
int64_t args_2[arg_count_2] =
{
(int64_t)eRemoteEvent::StartScriptProceed,
(int64_t)self::id
};
args_2[2 + 17] = 1337;
g_pointers->m_trigger_script_event(1, args_2, arg_count_2, 1 << player->id());
script::get_current()->yield(20ms);
}
}
};
start_script<20> g_start_tutorial("tutorial", "Start Tutorial", "Plays that unskippable cutscene used in the tutorial", 0);
start_script<193> g_start_golf("golf", "Start Golf", "Starts golf", 0);
start_script<196> g_start_flight_school("flightschool", "Start Flight School", "Teleports player to the airport and starts flight school", 0);
start_script<192> g_start_darts("darts", "Start Darts", "Starts darts in a Sandy Shores bar", 0);
start_script<211> g_start_badlands("badlands", "Start Badlands Revenge II", "Starts the arcade game Badlands Revenge II in fullscreen", 0);
start_script<216> g_start_space_monkey("spacemonkey", "Start Space Monkey 3", "Starts the arcade game Space Monkey 3 in fullscreen", 0);
start_script<216> g_start_wizards_ruin("wizard", "Start The Wizard's Ruin", "Starts the arcade game The Wizard's Ruin in fullscreen", 0);
start_script<217> g_start_qub3d("qub3d", "Start Qub3D", "Starts the arcade game Qub3D in fullscreen", 0);
start_script<218> g_start_camhedz("camhedz", "Start Camhedz", "Starts the arcade game Camhedz in fullscreen", 0);
}

View File

@ -0,0 +1,31 @@
#include "backend/player_command.hpp"
#include "natives.hpp"
#include "pointers.hpp"
namespace big
{
class trigger_ceo_raid : player_command
{
using player_command::player_command;
virtual CommandAccessLevel get_access_level()
{
return CommandAccessLevel::AGGRESSIVE;
}
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 = 3;
int64_t args[arg_count] =
{
(int64_t)eRemoteEvent::TriggerCEORaid,
(int64_t)self::id,
0
};
g_pointers->m_trigger_script_event(1, args, arg_count, 1 << player->id());
}
};
trigger_ceo_raid g_trigger_ceo_raid("ceoraid", "Trigger Special Cargo Raid", "The player has to be in a CEO for this to work", 0);
}

View File

@ -1,12 +1,21 @@
#pragma once
#include "common.hpp"
#include "services/players/player_service.hpp"
namespace big
{
class looped {
struct spawned_ped
{
Ped ped_handle;
Player spawned_for_player;
bool is_bodyguard;
bool is_attacker;
};
inline std::vector<spawned_ped> spawned_peds;
class looped
{
public:
static void hud_transition_state();
@ -23,6 +32,7 @@ namespace big
static void session_local_time();
static void session_pop_multiplier_areas();
static void session_force_thunder();
static void session_block_jobs();
static void session_randomize_ceo_colors();
static void session_auto_kick_host();
@ -54,5 +64,7 @@ namespace big
static void drive_train();
static void derail_train();
static void world_spawn_ped();
};
}

View File

@ -25,8 +25,8 @@ namespace big
if (entry.second->explosion_loop)
toxic::blame_explode_player(entry.second, entry.second, EXP_TAG_SUBMARINE_BIG, 9999.0f, true, false, 9999.0f);
if (entry.second->freeze_loop)
TASK::CLEAR_PED_TASKS_IMMEDIATELY(PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(entry.second->id()));
if (entry.second->freeze_loop && entry.second->get_ped()->m_net_object)
g_pointers->m_clear_ped_tasks_network(entry.second->get_ped(), true);
if (entry.second->ragdoll_loop && entry.second->get_ped()->m_net_object)
g_pointers->m_request_ragdoll(entry.second->get_ped()->m_net_object->m_object_id);

View File

@ -10,6 +10,8 @@ namespace big
virtual void on_tick() override
{
WATER::RESET_DEEP_OCEAN_SCALER();
Vector3 coords = self::pos;
float offset[] = { -4, 4 };
@ -23,7 +25,7 @@ namespace big
{
coords.y += offset[(i % 2 == 0)];
}
WATER::MODIFY_WATER(coords.x, coords.y, -500000.0f, 0.2f);
WATER::MODIFY_WATER(coords.x, coords.y, 0.0f, 300.0f);
}
}
};

View File

@ -0,0 +1,36 @@
#include "backend/looped/looped.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "gta_util.hpp"
#include "script_local.hpp"
#include "core/scr_globals.hpp"
namespace big
{
static bool bLastBlockJobsEnabled = false;
void looped::session_block_jobs()
{
bool used = g.session.block_jobs && *g_pointers->m_is_session_started;
if (!bLastBlockJobsEnabled && used)
{
if (!STREAMING::IS_PLAYER_SWITCH_IN_PROGRESS() && SCRIPT::GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(RAGE_JOAAT("maintransition")) == 0
&& NETWORK::NETWORK_GET_HOST_OF_SCRIPT("fmmc_launcher", -1, 0) == self::id)
{
auto fmmc = gta_util::find_script_thread(RAGE_JOAAT("fmmc_launcher"));
*script_local(fmmc->m_stack, scr_locals::fmmc_launcher::broadcast_idx).at(47).at(7).as<int*>() = (-1 & ~(1 << self::id));
bLastBlockJobsEnabled = true;
}
}
else if (bLastBlockJobsEnabled && !used)
{
if (*g_pointers->m_is_session_started && !STREAMING::IS_PLAYER_SWITCH_IN_PROGRESS() && gta_util::find_script_thread(RAGE_JOAAT("fmmc_launcher")))
{
auto fmmc = gta_util::find_script_thread(RAGE_JOAAT("fmmc_launcher"));
*script_local(fmmc->m_stack, scr_locals::fmmc_launcher::broadcast_idx).at(47).at(7).as<int*>() = 0;
}
bLastBlockJobsEnabled = false;
}
}
}

View File

@ -32,7 +32,7 @@ namespace big
if (g.spoofing.rockstar_id != g.spoofing.applied_spoof_rockstar_id && gta_util::get_network()->m_game_session_state == 0)
{
g.spoofing.applied_spoof_rockstar_id = g.spoofing.spoof_rockstar_id;
g.spoofing.applied_spoof_rockstar_id = g.spoofing.rockstar_id;
}
if (g.spoofing.spoof_rockstar_id != g.spoofing.should_spoof_rockstar_id && gta_util::get_network()->m_game_session_state == 0)

View File

@ -0,0 +1,86 @@
#include "backend/looped/looped.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "util/entity.hpp"
namespace big
{
static bool last_online = false;
inline void cleanup_spawned_ped(spawned_ped& ped)
{
PED::DELETE_PED(&ped.ped_handle);
}
static bool bLastLoadPathNodes = false;
void looped::world_spawn_ped()
{
if (*g_pointers->m_is_session_started != last_online)
{
last_online = *g_pointers->m_is_session_started;
for (auto& ped : spawned_peds)
cleanup_spawned_ped(ped);
spawned_peds.clear();
}
if (bLastLoadPathNodes && (spawned_peds.size() == 0))
{
PATHFIND::LOAD_ALL_PATH_NODES(false);
bLastLoadPathNodes = false;
}
else if (spawned_peds.size() != 0)
{
PATHFIND::LOAD_ALL_PATH_NODES(true);
bLastLoadPathNodes = true;
}
for (auto it = spawned_peds.begin(); it != spawned_peds.end();)
{
if ((*g_pointers->m_is_session_started && !NETWORK::NETWORK_IS_PLAYER_CONNECTED(it->spawned_for_player)) || !ENTITY::DOES_ENTITY_EXIST(it->ped_handle))
{
cleanup_spawned_ped(*it);
it = spawned_peds.erase(it);
continue;
}
if (it->is_attacker || it->is_bodyguard)
{
auto pos = ENTITY::GET_ENTITY_COORDS(PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(it->spawned_for_player), false);
auto vel = NETWORK::NETWORK_GET_LAST_VEL_RECEIVED_OVER_NETWORK(PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(it->spawned_for_player));
bool is_veh = PED::IS_PED_IN_ANY_VEHICLE(PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(it->spawned_for_player), true) || PLAYER::IS_REMOTE_PLAYER_IN_NON_CLONED_VEHICLE(it->spawned_for_player);
auto ped_pos = ENTITY::GET_ENTITY_COORDS(it->ped_handle, false);
float distance = is_veh ? 170.0f : 120.0f;
float spawn_distance = is_veh ? 150.0f : 70.0f;
if (pos.x != 0.0f && SYSTEM::VDIST2(pos.x, pos.y, pos.z, ped_pos.x, ped_pos.y, ped_pos.z) > distance * distance)
{
Vector3 spawn_point;
if (MISC::FIND_SPAWN_POINT_IN_DIRECTION(pos.x, pos.y, pos.z, vel.x, vel.y, vel.z, spawn_distance, &spawn_point) && entity::take_control_of(it->ped_handle, 0))
{
PED::SET_PED_COORDS_KEEP_VEHICLE(it->ped_handle, spawn_point.x, spawn_point.y, spawn_point.z);
if (it->is_attacker)
TASK::TASK_COMBAT_PED(it->ped_handle, PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(it->spawned_for_player), 0, 16);
if (it->is_bodyguard)
TASK::TASK_FOLLOW_TO_OFFSET_OF_ENTITY(it->ped_handle, PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(it->spawned_for_player), 0.0f, 0.0f, 0.0f, 4.0f, -1, 0.0f, true);
}
}
}
if (it->is_attacker && TASK::GET_SCRIPT_TASK_STATUS(it->ped_handle, RAGE_JOAAT("SCRIPT_TASK_COMBAT")) == 7)
{
TASK::TASK_COMBAT_PED(it->ped_handle, PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(it->spawned_for_player), 0, 16);
}
else if (it->is_bodyguard && it->spawned_for_player != self::id && TASK::GET_SCRIPT_TASK_STATUS(it->ped_handle, RAGE_JOAAT("SCRIPT_TASK_FOLLOW_TO_OFFSET_OF_ENTITY")) == 7)
{
TASK::TASK_FOLLOW_TO_OFFSET_OF_ENTITY(it->ped_handle, PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(it->spawned_for_player), 0.0f, 0.0f, 0.0f, 4.0f, -1, 0.0f, true);
}
it++;
}
}
}

View File

@ -32,6 +32,13 @@ namespace big
});
}
if (notify)
{
char notification[500]{}; // I don't like using sprintf but there isn't an alternative afaik
snprintf(notification, sizeof(notification), m_notify_message, attacker->get_name(), victim->get_name());
g_notification_service->push_warning("Protections", notification);
}
process_common(attacker);
}
}

View File

@ -18,13 +18,6 @@ namespace big
void reaction::process_common(player_ptr player)
{
if (notify)
{
char notification[500]{}; // I don't like using sprintf but there isn't an alternative afaik
snprintf(notification, sizeof(notification), m_notify_message, player->get_name());
g_notification_service->push_warning("Protections", notification);
}
if (log)
{
uint64_t rockstar_id = player->get_net_data() == nullptr ? 0 : player->get_net_data()->m_gamer_handle_2.m_rockstar_id;
@ -71,6 +64,13 @@ namespace big
});
}
if (notify)
{
char notification[500]{}; // I don't like using sprintf but there isn't an alternative afaik
snprintf(notification, sizeof(notification), m_notify_message, player->get_name());
g_notification_service->push_warning("Protections", notification);
}
process_common(player);
}
}

View File

@ -13,7 +13,7 @@ namespace big
public:
bool announce_in_chat = false;
bool notify = true;
bool log = false;
bool log = true;
bool add_to_player_db = false;
bool block_joins = false;
bool kick = false;

View File

@ -13,6 +13,8 @@ namespace big
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
g_script_patcher_service->add_patch({ RAGE_JOAAT("freemode"), "2D 00 07 00 00 7B", 5, { 0x2E, 0x00, 0x00 }, nullptr }); // disable population load balancing
g_script_patcher_service->add_patch({ RAGE_JOAAT("freemode"), "2D 02 08 00 00 38 01 56", 5, { 0x2E, 0x02, 0x00 }, &g.session.block_muggers });
g_script_patcher_service->add_patch({ RAGE_JOAAT("freemode"), "2D 00 CF 00 00 ", 5, { 0x2E, 0x00, 0x00 }, &g.session.block_ceo_raids });
g_script_patcher_service->add_patch({ RAGE_JOAAT("shop_controller"), "2D 01 04 00 00 2C ? ? ? 56 ? ? 71", 5, { 0x71, 0x2E, 0x01, 0x01 }, nullptr }); // despawn bypass
g_script_patcher_service->add_patch({ RAGE_JOAAT("shop_controller"), "38 00 5D ? ? ? 38 00 5D ? ? ? 38 00 41", 0, std::vector<uint8_t>(12, 0x0), nullptr}); // godmode/invisibility detection bypass

View File

@ -0,0 +1,115 @@
#pragma once
inline const static constexpr std::pair<const char*, std::uint32_t> packet_types[] =
{
{ "MsgInvalid", -1 },
{ "MsgSessionAcceptChat", 0x62 },
{ "MsgStartMatchCmd", 0x2D },
{ "MsgSetInvitableCmd", 0x1F },
{ "MsgSessionMemberIds", 0x23 },
{ "MsgRequestGamerInfo", 0x54 },
{ "MsgRemoveGamersFromSessionCmd", 0x53 },
{ "MsgNotMigrating", 0x35 },
{ "MsgMigrateHostResponse", 0x12 },
{ "MsgMigrateHostRequest", 0x66 },
{ "MsgJoinResponse", 0x2A },
{ "MsgJoinRequest", 0x41 },
{ "MsgHostLeftWhilstJoiningCmd", 0x58 },
{ "MsgConfigResponse", 0x5F },
{ "MsgConfigRequest", 0x48 },
{ "MsgChangeSessionAttributesCmd", 0x5A },
{ "MsgAddGamerToSessionCmd", 0x6 },
{ "MsgReassignResponse", 0x10 },
{ "MsgReassignNegotiate", 0x01 },
{ "MsgReassignConfirm", 0x26 },
{ "MsgPlayerData", 0x18 },
{ "MsgPackedReliables", 0x30 },
{ "MsgPackedCloneSyncACKs", 0x3B },
{ "MsgNonPhysicalData", 0x16 },
{ "MsgNetArrayMgrUpdateAck", 0x5D },
{ "MsgNetArrayMgrUpdate", 0x60 },
{ "MsgNetArrayMgrSplitUpdateAck", 0x25 },
{ "MsgScriptVerifyHostAck", 0x0B },
{ "MsgScriptVerifyHost", 0x3E },
{ "MsgScriptNewHost", 0x0E },
{ "MsgScriptMigrateHostFailAck", 0x1A },
{ "MsgScriptMigrateHost", 0x33 },
{ "MsgScriptLeaveAck", 0x40 },
{ "MsgScriptLeave", 0x17 },
{ "MsgScriptJoinHostAck", 0x4D },
{ "MsgScriptJoinAck", 0x43 },
{ "MsgScriptJoin", 0x5C },
{ "MsgScriptHostRequest", 0x67 },
{ "MsgScriptHandshakeAck", 0x5B },
{ "MsgScriptHandshake", 0x57 },
{ "MsgScriptBotLeave", 0x2 },
{ "MsgScriptBotJoinAck", 0x63 },
{ "MsgScriptBotJoin", 0x1C },
{ "MsgScriptBotHandshakeAck", 0x31 },
{ "MsgScriptBotHandshake", 0x4B },
{ "MsgPartyLeaveGame", 0x3D },
{ "MsgPartyEnterGame", 0x1E },
{ "MsgCloneSync", 0x4E },
{ "MsgActivateNetworkBot", 0x65 },
{ "MsgRequestObjectIds", 0x29 },
{ "MsgInformObjectIds", 0x09 },
{ "MsgTextMessage", 0x24 },
{ "MsgPlayerIsTyping", 0x61 },
{ "MsgPackedEvents", 0x4F },
{ "MsgPackedEventReliablesMsgs", 0x20 },
{ "MsgRequestKickFromHost", 0x0D },
{ "MsgTransitionToGameStart", 0x50 },
{ "MsgTransitionToGameNotify", 0x02 },
{ "MsgTransitionToActivityStart", 0x06 },
{ "MsgTransitionToActivityFinish", 0x36 },
{ "MsgTransitionParameters", 0x3C },
{ "MsgTransitionParameterString", 0x37 },
{ "MsgTransitionLaunchNotify", 0x1B },
{ "MsgTransitionLaunch", 0x19 },
{ "MsgTransitionGamerInstruction", 0x14 },
{ "MsgTextMessage2", 0x0A },
{ "MsgSessionEstablishedRequest", 0x52 },
{ "MsgSessionEstablished", 0x07 },
{ "MsgRequestTransitionParameters", 0x42 },
{ "MsgRadioStationSyncRequest", 0x47 },
{ "MsgRadioStationSync", 0x46 },
{ "MsgPlayerCardSync", 0x3A },
{ "MsgPlayerCardRequest", 0x6A },
{ "MsgLostConnectionToHost", 0x81 },
{ "MsgKickPlayer", 0x34 },
{ "MsgDebugStall", 0x7E },
{ "MsgCheckQueuedJoinRequestReply", 0x59 },
{ "MsgCheckQueuedJoinRequest", 0x51 },
{ "MsgBlacklist", 0x0C },
{ "MsgRoamingRequestBubbleRequiredResponse", 0x83 },
{ "MsgRoamingRequestBubbleRequiredCheck", 0x82 },
{ "MsgRoamingRequestBubble", 0x2E },
{ "MsgRoamingJoinBubble", 0x4C },
{ "MsgRoamingJoinBubbleAck", 0x3F },
{ "MsgRoamingInitialBubble", 0x32 },
{ "MsgVoiceStatus", 0x03 },
{ "MsgTextChatStatus", 0x00 },
{ "MsgJoinResponse2", 0x08 },
{ "MsgJoinRequest2", 0x68 },
{ "MsgNetTimeSync", 0x38 },
{ "MsgNetComplaint", 0x55 },
{ "MsgNetLagPing", 0x27 },
{ "MsgSearchResponse", 0x6B },
{ "MsgSearchRequest", 0x05 },
{ "MsgQosProbeResponse", 0x2C },
{ "MsgQosProbeRequest", 0x1D },
{ "MsgCxnRelayAddressChanged", 0x49 },
{ "MsgCxnRequestRemoteTimeout", 0x2F },
{ "MsgSessionDetailRequest", 0x22 },
{ "MsgSessionDetailResponse", 0x13 },
{ "MsgKeyExchangeOffer", 0x0F },
{ "MsgKeyExchangeAnswer", 0x44 },
{ "Msg_0x87", 0x87 },
{ "Msg_0x88", 0x88 },
{ "Msg_0x80", 0x80 },
{ "Msg_0x28", 0x28 },
{ "Msg_0x11", 0x11 },
{ "Msg_0x45", 0x45 },
{ "Msg_0x89", 0x89 },
{ "Msg_0x86", 0x86 },
};

View File

@ -153,7 +153,7 @@ namespace big
{
Bounty = 1370461707, // (137, "FM_TXT_BNTY0", iVar1, PLAYER::GET_PLAYER_NAME(Var2.f_1), "", 5000, Var2.f_6);
CeoBan = 316066012, // mpply_vipgameplaydisabledtimer
CeoKick = -1831959078, // BGDISMISSED
CeoKick = 265836764,
CeoMoney = 245065909, // Goon_Paid_Large
ClearWantedLevel = 2080651008,
ForceMission = 1858712297, // ), Var0.f_2, 1))
@ -164,7 +164,7 @@ namespace big
RemoteOffradar = -162943635, // NETWORK::GET_TIME_DIFFERENCE(NETWORK::GET_NETWORK_TIME(), Var0.f_2)
SendToCutscene = 392606458, // (bVar3, bVar4, 125f, 1)
SendToCayoPerico = -910497748, // CELL_HI_INV
SendToLocation = 1214823473, // &Var222, 11); TODO this isn't updated!
SendToLocation = -93722397, // &Var222, 11);
SoundSpam = -1891171016, // CELL_APTINVYACHT
Spectate = -1903870031, // SPEC_TCK1
Teleport = -168599209, // Mission_Pass_Notify
@ -177,9 +177,11 @@ namespace big
KickFromInterior = 1454834612, // ENTITY::SET_ENTITY_HEALTH(PLAYER::PLAYER_PED_ID(), PED::GET_PED_MAX_HEALTH(PLAYER::PLAYER_PED_ID()), false)
InteriorControl = 1268038438, // eventData.f_3 != _INVALID_PLAYER_INDEX_0()
SMS = 1519903406,
SendTextLabelSMS = -1387723751,
Crash = -904555865, // SET_NO_LOADING_SCREEN, xref it
Crash2 = 1775863255,
Crash3 = 2067191610,
TSECommand = 113023613, // CnCTG_IN_BF
TSECommandRotateCam = 0x69979fea /*joaat("pats_horse_right") in script*/, // != 29) && f
@ -190,6 +192,10 @@ namespace big
NotificationMoneyStolen = -28878294, // TICK_TC_STOL
DestroyPersonalVehicle = -513394492, // CnC_PV_THEFT
TriggerCEORaid = -1322731185,
StartScriptBegin = -1127353498,
StartScriptProceed = -16793987,
BadThing1 = 1279059857,
BadThing2 = -343495611

View File

@ -66,6 +66,7 @@ namespace big
struct logs
{
bool metric_logs{};
bool packet_logs{};
bool script_hook_logs{};
@ -79,7 +80,7 @@ namespace big
NLOHMANN_DEFINE_TYPE_INTRUSIVE(script_event, logs, filter_player, player_id)
} script_event{};
NLOHMANN_DEFINE_TYPE_INTRUSIVE(logs, metric_logs, script_hook_logs, script_event)
NLOHMANN_DEFINE_TYPE_INTRUSIVE(logs, metric_logs, packet_logs, script_hook_logs, script_event)
} logs{};
NLOHMANN_DEFINE_TYPE_INTRUSIVE(debug, logs)
@ -134,13 +135,16 @@ namespace big
struct reactions
{
reaction bounty{ "Bounty", "Blocked Bounty from %s", "%s tried to set a bounty on me!" };
reaction ceo_kick{ "CEO Kick", "Blocked CEO Kick from %s", "%s tried to kick me from my CEO!" };
reaction ceo_money{ "CEO Money", "Blocked CEO Money from %s", "%s tried to drop money on me!" };
reaction clear_wanted_level{ "Clear Wanted Level", "Blocked Clear Wanted Level from %s", "%s tried to clear my wanted level!" };
reaction crash{ "Crash", "Blocked Crash from %s", "%s tried to crash me!" };
reaction end_session_kick{ "End Session Kick", "Blocked End Session Kick from %s", "%s tried to kick me out!" };
reaction fake_deposit{ "Fake Deposit", "Blocked Fake Deposit from %s", "%s tried to show me a fake money notification!" };
reaction force_mission{ "Force Mission", "Blocked Force Mission from %s", "%s tried to force me into a mission!" };
reaction force_teleport{ "Force Teleport", "Blocked Force Teleport from %s", "%s tried to teleport me!" };
reaction gta_banner{ "GTA Banner", "Blocked GTA Banner from %s", "Blocked GTA Banner from %s" }; // please don't enable this
reaction kick_from_interior{ "Kick From Interior", "Blocked Kick From Interior from %s", "%s tried to kick me from my interior!" };
reaction mc_teleport{ "MC Teleport", "Blocked MC Teleport from %s", "%s tried to teleport me!" };
reaction network_bail{ "Network Bail", "Blocked Network Bail from %s", "%s tried to kick me out!" };
reaction personal_vehicle_destroyed{ "Personal Vehicle Destroyed", "Blocked Personal Vehicle Destroyed from %s", "%s tried to show me a fake insurance notification!" };
@ -157,8 +161,13 @@ namespace big
reaction vehicle_kick{ "Vehicle Kick", "Blocked Vehicle Kick from %s", "%s tried to kick me from my vehicle!" };
reaction teleport_to_warehouse{ "Teleport To Warehouse", "Blocked Teleport To Warehouse from %s", "%s tried to teleport me to a warehouse!" };
reaction start_activity{ "Start Activity", "Blocked Start Activity from %s", "Blocked Start Activity from %s" };
reaction start_script{ "Start Script", "Blocked Start Script from %s", "Blocked Start Script from %s" };
reaction null_function_kick{ "Null Function Kick", "Blocked Null Function Kick from %s", "%s tried to kick me out!" };
reaction destroy_personal_vehicle{ "Destroy Personal Vehicle", "Blocked Destroy Personal Vehicle from %s", "%s tried to destroy my personal vehicle!" };
reaction trigger_business_raid{ "Trigger Business Raid", "Blocked Trigger Business Raid from %s", "%s tried to trigger a business raid!" };
reaction turn_into_beast{ "Turn Into Beast", "Blocked Turn Into Beast from %s", "%s tried to turn me into the beast!" };
reaction remote_wanted_level{ "Remote Wanted Level", "Blocked Remote Wanted Level from %s", "%s tried to give me a wanted level!" };
interloper_reaction remote_wanted_level_others{ "Remote Wanted Level On Other Players", "%s is attempting to give a wanted level to %s!", "%s is attempting to give a wanted level to %s!", false, false };
reaction clear_ped_tasks{ "Clear Ped Tasks", "Blocked Clear Ped Tasks from %s", "%s tried to freeze me!" };
reaction remote_ragdoll{ "Remote Ragdoll", "Blocked Remote Ragdoll from %s", "%s tried to ragdoll me!" };
@ -173,9 +182,10 @@ namespace big
reaction gamer_instruction_kick{ "Gamer Instruction Kick", "Blocked Gamer Instruction Kick from %s", "%s tried to kick me out!" };
interloper_reaction lost_connection_kick_others{ "Lost Connection Kick On Other Players", "%s is trying to lost connection kick %s!", "%s is trying to lost connection kick %s!", true, false };
NLOHMANN_DEFINE_TYPE_INTRUSIVE(reactions, bounty, ceo_money, clear_wanted_level, crash, fake_deposit, force_mission, force_teleport, gta_banner, mc_teleport, network_bail, personal_vehicle_destroyed, remote_off_radar,
rotate_cam, send_to_cutscene, send_to_location, sound_spam, spectate_notification, give_collectible, transaction_error, tse_freeze, tse_sender_mismatch, vehicle_kick, teleport_to_warehouse, start_activity,
null_function_kick, destroy_personal_vehicle, clear_ped_tasks, remote_ragdoll, kick_vote, report_cash_spawn, modder_detection, request_control_event, report, breakup_others, gamer_instruction_kick, lost_connection_kick, lost_connection_kick_others)
NLOHMANN_DEFINE_TYPE_INTRUSIVE(reactions, bounty, ceo_money, ceo_kick, clear_wanted_level, crash, end_session_kick, fake_deposit, force_mission, force_teleport, gta_banner, kick_from_interior, mc_teleport, network_bail, personal_vehicle_destroyed,
remote_off_radar, rotate_cam, send_to_cutscene, send_to_location, sound_spam, spectate_notification, give_collectible, transaction_error, tse_freeze, tse_sender_mismatch, vehicle_kick, teleport_to_warehouse, trigger_business_raid, start_activity,
start_script, null_function_kick, destroy_personal_vehicle, clear_ped_tasks, turn_into_beast, remote_wanted_level, remote_wanted_level_others, remote_ragdoll, kick_vote, report_cash_spawn, modder_detection, request_control_event, report,
breakup_others, gamer_instruction_kick, lost_connection_kick, lost_connection_kick_others)
} reactions{};
struct player
@ -319,6 +329,9 @@ namespace big
bool block_ceo_money = false;
bool randomize_ceo_colors = false;
bool block_jobs = false;
bool block_muggers = false;
bool block_ceo_raids = false;
int send_to_apartment_idx = 1;
int send_to_warehouse_idx = 1;
@ -339,8 +352,8 @@ namespace big
log_text_messages, decloak_players, force_session_host, force_script_host, player_magnet_enabled,
player_magnet_count, is_team, name_spoof_enabled, advertise_menu, spoofed_name, join_in_sctv_slots,
kick_chat_spammers, kick_host_when_forcing_host, explosion_karma, damage_karma, disable_traffic,
disable_peds, force_thunder, block_ceo_money, randomize_ceo_colors, send_to_apartment_idx, send_to_warehouse_idx,
chat_commands, chat_command_default_access_level, show_cheating_message, anonymous_bounty)
disable_peds, force_thunder, block_ceo_money, randomize_ceo_colors, block_jobs, block_muggers, block_ceo_raids,
send_to_apartment_idx, send_to_warehouse_idx, chat_commands, chat_command_default_access_level, show_cheating_message, anonymous_bounty)
} session{};
struct settings
@ -395,7 +408,7 @@ namespace big
NLOHMANN_DEFINE_TYPE_INTRUSIVE(clone_pv, preview_vehicle, spawn_inside, spawn_clone, spawn_maxed, clone_plate, plate)
} clone_pv{};
struct world
{
struct train
@ -413,8 +426,11 @@ namespace big
struct spawn_ped
{
bool preview_ped = false;
bool spawn_invincible = false;
bool spawn_invisible = false;
bool spawn_as_attacker = false;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(spawn_ped, preview_ped)
NLOHMANN_DEFINE_TYPE_INTRUSIVE(spawn_ped, preview_ped, spawn_invincible, spawn_invisible, spawn_as_attacker)
} spawn_ped{};
struct custom_time

View File

@ -45,5 +45,28 @@ namespace big::scr_locals
namespace am_hunt_the_beast
{
constexpr static auto broadcast_idx = 599;
constexpr static auto player_broadcast_idx = 2583;
}
namespace am_criminal_damage
{
constexpr static auto broadcast_idx = 110;
constexpr static auto score_idx = 105;
}
namespace am_cp_collection
{
constexpr static auto broadcast_idx = 815;
constexpr static auto player_broadcast_idx = 3456;
}
namespace am_king_of_the_castle
{
constexpr static auto broadcast_idx = 93;
}
namespace fmmc_launcher
{
constexpr static auto broadcast_idx = 11153;
}
}

View File

@ -127,4 +127,9 @@ namespace big::functions
using sync_network_time = bool(*)(rage::netConnectionManager* mgr, rage::netConnectionPeer* peer, int connection_id, rage::netTimeSyncMsg* msg, int flags);
using send_packet = bool(*)(rage::netConnectionManager* mgr, rage::netConnectionPeer* peer, int connection_id, void* data, int size, int flags);
using connect_to_peer = bool(*)(rage::netConnectionManager* mgr, rage::rlGamerInfoBase* gamer_info, rage::snConnectToPeerTaskData* data, rage::snConnectToPeerTaskResult* result, rage::rlTaskStatus* status);
using clear_ped_tasks_network = void(*)(CPed* ped, bool immediately);
using get_next_carriage = void*(*)(void* carriage);
using get_entity_attached_to = rage::CDynamicEntity*(*)(rage::CDynamicEntity* entity);
}

View File

@ -28,23 +28,5 @@ namespace rage
static_assert(consteval_joaat("test") == 0x3f75ccc1);
}
inline consteval rage::joaat_t operator""_j(const char* s, std::size_t n)
{
rage::joaat_t result = 0;
for (std::size_t i = 0; i < n; i++)
{
result += rage::joaat_to_lower(s[i]);
result += (result << 10);
result ^= (result >> 6);
}
result += (result << 3);
result ^= (result >> 11);
result += (result << 15);
return result;
}
#define RAGE_JOAAT_IMPL(str) (::rage::consteval_joaat(str))
#define RAGE_JOAAT(str) (std::integral_constant<rage::joaat_t, RAGE_JOAAT_IMPL(str)>::value)

View File

@ -102,6 +102,10 @@ namespace big
detour_hook_helper::add<hooks::fragment_physics_crash>("FPC", g_pointers->m_fragment_physics_crash);
detour_hook_helper::add<hooks::fragment_physics_crash_2>("FPC2", g_pointers->m_fragment_physics_crash_2);
detour_hook_helper::add<hooks::infinite_train_crash>("ITC", g_pointers->m_infinite_train_crash);
detour_hook_helper::add<hooks::received_array_update>("RAU", g_pointers->m_received_array_update);
g_hooking = this;
}

View File

@ -142,6 +142,10 @@ namespace big
static int nt_query_virtual_memory(void* _this, HANDLE handle, PVOID base_addr, int info_class, MEMORY_BASIC_INFORMATION* info, int size, size_t* return_len);
static void queue_dependency(void* dependency);
static void prepare_metric_for_sending(rage::datBitBuffer* bit_buffer, int unk, int time, rage::rlMetric* metric);
static void* infinite_train_crash(void* carriage);
static bool received_array_update(rage::netArrayHandlerBase* array, CNetGamePlayer* sender, rage::datBitBuffer* buffer, int size, std::int16_t cycle);
};
class minhook_keepalive

View File

@ -4,7 +4,7 @@ namespace big
{
int hooks::nt_query_virtual_memory(void* _this, HANDLE handle, PVOID base_addr, int info_class, MEMORY_BASIC_INFORMATION* info, int size, size_t* return_len)
{
LOG(INFO) << "Reached here, base addr: " << base_addr;
// LOG(INFO) << "Reached here, base addr: " << base_addr;
return 1;
}
}

View File

@ -7,8 +7,7 @@ namespace big
{
if (dependency == g_pointers->m_interval_check_func)
{
LOG(INFO) << "Prevent attempt to queue a report to R*.";
//LOG(INFO) << "Prevent attempt to queue a report to R*.";
return;
}

View File

@ -31,7 +31,7 @@ namespace big
return g_hooking->get_original<hooks::assign_physical_index>()(netPlayerMgr, player, new_index);
}
const auto result = g_hooking->get_original<hooks::assign_physical_index>()(netPlayerMgr, player, new_index);
g_player_service->player_join(player);
if (net_player_data)

View File

@ -14,119 +14,102 @@
#include "datanodes/pickup/CPickupCreationDataNode.hpp"
#include "datanodes/physical/CPhysicalAttachDataNode.hpp"
#include "datanodes/player/CPlayerAppearanceDataNode.hpp"
#include "datanodes/player/CPlayerCreationDataNode.hpp"
#include "datanodes/proximity_migrateable/CSectorDataNode.hpp"
#include "datanodes/vehicle/CVehicleCreationDataNode.hpp"
#include "datanodes/vehicle/CVehicleGadgetDataNode.hpp"
#include "datanodes/train/CTrainGameStateDataNode.hpp"
#include "network/netObject.hpp"
#include "base/CBaseModelInfo.hpp"
#include "vehicle/CVehicleModelInfo.hpp"
#include "util/model_info.hpp"
#include "network/CNetGamePlayer.hpp"
#include "util/notify.hpp"
// TODO: remove as it's unused
#define CLASS_TO_MANGLED_NAME(c) "?AV"#c"@@"
namespace big
{
constexpr auto nodes = std::to_array<std::pair<Hash, uint64_t>>({
{RAGE_JOAAT("CAutomobileCreationDataNode"), 0x1b088e0},
{RAGE_JOAAT("CBikeGameStateDataNode"), 0x1b08a40},
{RAGE_JOAAT("CBoatGameStateDataNode"), 0x1b08a80},
{RAGE_JOAAT("CDoorCreationDataNode"), 0x1b08be0},
{RAGE_JOAAT("CDoorMovementDataNode"), 0x1b09000},
{RAGE_JOAAT("CDoorScriptGameStateDataNode"), 0x1b08ea0},
{RAGE_JOAAT("CDoorScriptInfoDataNode"), 0x1b08d40},
{RAGE_JOAAT("CDynamicEntityGameStateDataNode"), 0x1b06450},
{RAGE_JOAAT("CEntityOrientationDataNode"), 0x1b05df0},
{RAGE_JOAAT("CEntityScriptGameStateDataNode"), 0x1b05c90},
{RAGE_JOAAT("CEntityScriptInfoDataNode"), 0x1b05b30},
{RAGE_JOAAT("CGlobalFlagsDataNode"), 0x1b057f0},
{RAGE_JOAAT("CHeliControlDataNode"), 0x1b08180},
{RAGE_JOAAT("CHeliHealthDataNode"), 0x1b06f60},
{RAGE_JOAAT("CMigrationDataNode"), 0x1b05af0},
{RAGE_JOAAT("CObjectCreationDataNode"), 0x1b096e0},
{RAGE_JOAAT("CObjectGameStateDataNode"), 0x1b09840},
{RAGE_JOAAT("CObjectOrientationNode"), 0x1b09c60},
{RAGE_JOAAT("CObjectScriptGameStateDataNode"), 0x1b099a0},
{RAGE_JOAAT("CObjectSectorPosNode"), 0x1b09b00},
{RAGE_JOAAT("CPedAIDataNode"), 0x1b0ae80},
{RAGE_JOAAT("CPedAppearanceDataNode"), 0x1b0ad20},
{RAGE_JOAAT("CPedAttachDataNode"), 0x1b0a900},
{RAGE_JOAAT("CPedComponentReservationDataNode"), 0x1b0a380},
{RAGE_JOAAT("CPedCreationDataNode"), 0x1b09ca0},
{RAGE_JOAAT("CPedGameStateDataNode"), 0x1b09f60},
{RAGE_JOAAT("CPedHealthDataNode"), 0x1b0a7a0},
{RAGE_JOAAT("CPedInventoryDataNode"), 0x1b0b2a0},
{RAGE_JOAAT("CPedMovementDataNode"), 0x1b0abc0},
{RAGE_JOAAT("CPedMovementGroupDataNode"), 0x1b0aa60},
{RAGE_JOAAT("CPedOrientationDataNode"), 0x1b0a640},
{RAGE_JOAAT("CPedScriptCreationDataNode"), 0x1b09e00},
{RAGE_JOAAT("CPedScriptGameStateDataNode"), 0x1b0a4e0},
{RAGE_JOAAT("CPedSectorPosMapNode"), 0x1b05ab0},
{RAGE_JOAAT("CPedSectorPosNavMeshNode"), 0x1b0a220},
{RAGE_JOAAT("CPedTaskSequenceDataNode"), 0x1b0b400},
{RAGE_JOAAT("CPedTaskSpecificDataNode"), 0x1b0b140},
{RAGE_JOAAT("CPedTaskTreeDataNode"), 0x1b0afe0},
{RAGE_JOAAT("CPhysicalAngVelocityDataNode"), 0x1b06f20},
{RAGE_JOAAT("CPhysicalAttachDataNode"), 0x1b06fa0},
{RAGE_JOAAT("CPhysicalGameStateDataNode"), 0x1b06b00},
{RAGE_JOAAT("CPhysicalHealthDataNode"), 0x1b06f60},
{RAGE_JOAAT("CPhysicalMigrationDataNode"), 0x1b07100},
{RAGE_JOAAT("CPhysicalScriptGameStateDataNode"), 0x1b06c60},
{RAGE_JOAAT("CPhysicalScriptMigrationDataNode"), 0x1b07140},
{RAGE_JOAAT("CPhysicalVelocityDataNode"), 0x1b06dc0},
{RAGE_JOAAT("CPickupCreationDataNode"), 0x1b0b560},
{RAGE_JOAAT("CPickupPlacementCreationDataNode"), 0x1b0b860},
{RAGE_JOAAT("CPickupPlacementStateDataNode"), 0x1b0b9c0},
{RAGE_JOAAT("CPickupScriptGameStateNode"), 0x1b0b820},
{RAGE_JOAAT("CPickupSectorPosNode"), 0x1b0b6c0},
{RAGE_JOAAT("CPlaneControlDataNode"), 0x1b08180},
{RAGE_JOAAT("CPlaneGameStateDataNode"), 0x1b0c380},
{RAGE_JOAAT("CPlayerAmbientModelStreamingNode"), 0x1b0c040},
{RAGE_JOAAT("CPlayerAppearanceDataNode"), 0x1b0bc20},
{RAGE_JOAAT("CPlayerCameraDataNode"), 0x1b0bba0},
{RAGE_JOAAT("CPlayerCreationDataNode"), 0x1b0ba00},
{RAGE_JOAAT("CPlayerExtendedGameStateNode"), 0x1b0c300},
{RAGE_JOAAT("CPlayerGameStateDataNode"), 0x1b0bbe0},
{RAGE_JOAAT("CPlayerGamerDataNode"), 0x1b0c1a0},
{RAGE_JOAAT("CPlayerPedGroupDataNode"), 0x1b0bd80},
{RAGE_JOAAT("CPlayerSectorPosNode"), 0x1b0bb60},
{RAGE_JOAAT("CPlayerWantedAndLOSDataNode"), 0x1b0bee0},
{RAGE_JOAAT("CSectorDataNode"), 0x1b05950},
{RAGE_JOAAT("CSectorPositionDataNode"), 0x1b05ab0},
{RAGE_JOAAT("CSubmarineControlDataNode"), 0x1b08180},
{RAGE_JOAAT("CSubmarineGameStateDataNode"), 0x1b092c0},
{RAGE_JOAAT("CTrainGameStateDataNode"), 0x1b0c340},
{RAGE_JOAAT("CVehicleAngVelocityDataNode"), 0x1b06f20},
{RAGE_JOAAT("CVehicleAppearanceDataNode"), 0x1b082e0},
{RAGE_JOAAT("CVehicleComponentReservationDataNode"), 0x1b085e0},
{RAGE_JOAAT("CVehicleControlDataNode"), 0x1b08180},
{RAGE_JOAAT("CVehicleCreationDataNode"), 0x1b07940},
{RAGE_JOAAT("CVehicleDamageStatusDataNode"), 0x1b08440},
{RAGE_JOAAT("CVehicleGadgetDataNode"), 0x1b08780},
{RAGE_JOAAT("CVehicleGameStateDataNode"), 0x1b07c00},
{RAGE_JOAAT("CVehicleHealthDataNode"), 0x1b07ec0},
{RAGE_JOAAT("CVehicleProximityMigrationDataNode"), 0x1b08740},
{RAGE_JOAAT("CVehicleScriptGameStateDataNode"), 0x1b07d60},
{RAGE_JOAAT("CVehicleSteeringDataNode"), 0x1b08020},
{RAGE_JOAAT("CVehicleTaskDataNode"), 0x1b085a0}});
// TODO: remove as it's unused
constexpr uint64_t operator ""_fnv1a(char const* str, std::size_t len)
{
auto const fnv_offset_basis = 14695981039346656037ULL;
auto const fnv_prime = 1099511628211ULL;
auto value = fnv_offset_basis;
for (auto i = 0; i < len; i++)
{
value ^= static_cast<size_t>(str[i]);
value *= fnv_prime;
}
value ^= value >> 32;
return value;
}
{RAGE_JOAAT("CAutomobileCreationDataNode"), 0x1b088e0 + 64},
{RAGE_JOAAT("CBikeGameStateDataNode"), 0x1b08a40 + 64},
{RAGE_JOAAT("CBoatGameStateDataNode"), 0x1b08a80 + 64},
{RAGE_JOAAT("CDoorCreationDataNode"), 0x1b08be0 + 64},
{RAGE_JOAAT("CDoorMovementDataNode"), 0x1b09000 + 64},
{RAGE_JOAAT("CDoorScriptGameStateDataNode"), 0x1b08ea0 + 64},
{RAGE_JOAAT("CDoorScriptInfoDataNode"), 0x1b08d40 + 64},
{RAGE_JOAAT("CDynamicEntityGameStateDataNode"), 0x1b06450 + 64},
{RAGE_JOAAT("CEntityOrientationDataNode"), 0x1b05df0 + 64},
{RAGE_JOAAT("CEntityScriptGameStateDataNode"), 0x1b05c90 + 64},
{RAGE_JOAAT("CEntityScriptInfoDataNode"), 0x1b05b30 + 64},
{RAGE_JOAAT("CGlobalFlagsDataNode"), 0x1b057f0 + 64},
{RAGE_JOAAT("CHeliControlDataNode"), 0x1b08180 + 64},
{RAGE_JOAAT("CHeliHealthDataNode"), 0x1b06f60 + 64},
{RAGE_JOAAT("CMigrationDataNode"), 0x1b05af0 + 64},
{RAGE_JOAAT("CObjectCreationDataNode"), 0x1b096e0 + 64},
{RAGE_JOAAT("CObjectGameStateDataNode"), 0x1b09840 + 64},
{RAGE_JOAAT("CObjectOrientationNode"), 0x1b09c60 + 64},
{RAGE_JOAAT("CObjectScriptGameStateDataNode"), 0x1b099a0 + 64},
{RAGE_JOAAT("CObjectSectorPosNode"), 0x1b09b00 + 64},
{RAGE_JOAAT("CPedAIDataNode"), 0x1b0ae80 + 64},
{RAGE_JOAAT("CPedAppearanceDataNode"), 0x1b0ad20 + 64},
{RAGE_JOAAT("CPedAttachDataNode"), 0x1b0a900 + 64},
{RAGE_JOAAT("CPedComponentReservationDataNode"), 0x1b0a380 + 64},
{RAGE_JOAAT("CPedCreationDataNode"), 0x1b09ca0 + 64},
{RAGE_JOAAT("CPedGameStateDataNode"), 0x1b09f60 + 64},
{RAGE_JOAAT("CPedHealthDataNode"), 0x1b0a7a0 + 64},
{RAGE_JOAAT("CPedInventoryDataNode"), 0x1b0b2a0 + 64},
{RAGE_JOAAT("CPedMovementDataNode"), 0x1b0abc0 + 64},
{RAGE_JOAAT("CPedMovementGroupDataNode"), 0x1b0aa60 + 64},
{RAGE_JOAAT("CPedOrientationDataNode"), 0x1b0a640 + 64},
{RAGE_JOAAT("CPedScriptCreationDataNode"), 0x1b09e00 + 64},
{RAGE_JOAAT("CPedScriptGameStateDataNode"), 0x1b0a4e0 + 64},
{RAGE_JOAAT("CPedSectorPosMapNode"), 0x1b05ab0 + 64},
{RAGE_JOAAT("CPedSectorPosNavMeshNode"), 0x1b0a220 + 64},
{RAGE_JOAAT("CPedTaskSequenceDataNode"), 0x1b0b400 + 64},
{RAGE_JOAAT("CPedTaskSpecificDataNode"), 0x1b0b140 + 64},
{RAGE_JOAAT("CPedTaskTreeDataNode"), 0x1b0afe0 + 64},
{RAGE_JOAAT("CPhysicalAngVelocityDataNode"), 0x1b06f20 + 64},
{RAGE_JOAAT("CPhysicalAttachDataNode"), 0x1b06fa0 + 64},
{RAGE_JOAAT("CPhysicalGameStateDataNode"), 0x1b06b00 + 64},
{RAGE_JOAAT("CPhysicalHealthDataNode"), 0x1b06f60 + 64},
{RAGE_JOAAT("CPhysicalMigrationDataNode"), 0x1b07100 + 64},
{RAGE_JOAAT("CPhysicalScriptGameStateDataNode"), 0x1b06c60 + 64},
{RAGE_JOAAT("CPhysicalScriptMigrationDataNode"), 0x1b07140 + 64},
{RAGE_JOAAT("CPhysicalVelocityDataNode"), 0x1b06dc0 + 64},
{RAGE_JOAAT("CPickupCreationDataNode"), 0x1b0b560 + 64},
{RAGE_JOAAT("CPickupPlacementCreationDataNode"), 0x1b0b860 + 64},
{RAGE_JOAAT("CPickupPlacementStateDataNode"), 0x1b0b9c0 + 64},
{RAGE_JOAAT("CPickupScriptGameStateNode"), 0x1b0b820 + 64},
{RAGE_JOAAT("CPickupSectorPosNode"), 0x1b0b6c0 + 64},
{RAGE_JOAAT("CPlaneControlDataNode"), 0x1b08180 + 64},
{RAGE_JOAAT("CPlaneGameStateDataNode"), 0x1b0c380 + 64},
{RAGE_JOAAT("CPlayerAmbientModelStreamingNode"), 0x1b0c040 + 64},
{RAGE_JOAAT("CPlayerAppearanceDataNode"), 0x1b0bc20 + 64},
{RAGE_JOAAT("CPlayerCameraDataNode"), 0x1b0bba0 + 64},
{RAGE_JOAAT("CPlayerCreationDataNode"), 0x1b0ba00 + 64},
{RAGE_JOAAT("CPlayerExtendedGameStateNode"), 0x1b0c300 + 64},
{RAGE_JOAAT("CPlayerGameStateDataNode"), 0x1b0bbe0 + 64},
{RAGE_JOAAT("CPlayerGamerDataNode"), 0x1b0c1a0 + 64},
{RAGE_JOAAT("CPlayerPedGroupDataNode"), 0x1b0bd80 + 64},
{RAGE_JOAAT("CPlayerSectorPosNode"), 0x1b0bb60 + 64},
{RAGE_JOAAT("CPlayerWantedAndLOSDataNode"), 0x1b0bee0 + 64},
{RAGE_JOAAT("CSectorDataNode"), 0x1b05950 + 64},
{RAGE_JOAAT("CSectorPositionDataNode"), 0x1b05ab0 + 64},
{RAGE_JOAAT("CSubmarineControlDataNode"), 0x1b08180 + 64},
{RAGE_JOAAT("CSubmarineGameStateDataNode"), 0x1b092c0 + 64},
{RAGE_JOAAT("CTrainGameStateDataNode"), 0x1b0c340 + 64},
{RAGE_JOAAT("CVehicleAngVelocityDataNode"), 0x1b06f20 + 64},
{RAGE_JOAAT("CVehicleAppearanceDataNode"), 0x1b082e0 + 64},
{RAGE_JOAAT("CVehicleComponentReservationDataNode"), 0x1b085e0 + 64},
{RAGE_JOAAT("CVehicleControlDataNode"), 0x1b08180 + 64},
{RAGE_JOAAT("CVehicleCreationDataNode"), 0x1b07940 + 64},
{RAGE_JOAAT("CVehicleDamageStatusDataNode"), 0x1b08440 + 64},
{RAGE_JOAAT("CVehicleGadgetDataNode"), 0x1b08780 + 64},
{RAGE_JOAAT("CVehicleGameStateDataNode"), 0x1b07c00 + 64},
{RAGE_JOAAT("CVehicleHealthDataNode"), 0x1b07ec0 + 64},
{RAGE_JOAAT("CVehicleProximityMigrationDataNode"), 0x1b08740 + 64},
{RAGE_JOAAT("CVehicleScriptGameStateDataNode"), 0x1b07d60 + 64},
{RAGE_JOAAT("CVehicleSteeringDataNode"), 0x1b08020 + 64},
{RAGE_JOAAT("CVehicleTaskDataNode"), 0x1b085a0 + 64} });
constexpr uint32_t crash_peds[] = { RAGE_JOAAT("slod_human"), RAGE_JOAAT("slod_small_quadped"), RAGE_JOAAT("slod_large_quadped") };
@ -144,10 +127,15 @@ namespace big
RAGE_JOAAT("prop_barbell_02"), RAGE_JOAAT("prop_bandsaw_01"), RAGE_JOAAT("prop_bbq_3"), RAGE_JOAAT("v_med_curtainsnewcloth2"), RAGE_JOAAT("bh1_07_flagpoles"),
92962485 };
inline CObject* get_game_object(rage::netObject* object)
{
return *(CObject**)((__int64)object + 0x50);
}
inline bool is_crash_ped(uint32_t model)
{
for (auto iterator : crash_peds)
if (iterator == model)
if (iterator == model)
return true;
return false;
}
@ -168,6 +156,20 @@ namespace big
return false;
}
inline bool is_attachment_infinite(rage::CDynamicEntity* object, uint16_t attached_to_net_id)
{
if (object == nullptr)
return false;
while (object = g_pointers->m_get_entity_attached_to(object))
{
if (object->m_net_object && object->m_net_object->m_object_id == attached_to_net_id)
return true;
}
return false;
}
bool check_node(rage::netSyncNodeBase* node, CNetGamePlayer* sender, rage::netObject* object)
{
if (node->IsParentNode())
@ -187,19 +189,22 @@ namespace big
};
auto vtable = *(void**)node;
Hash node_hash;
Hash node_hash = 0;
for (const auto& n : nodes)
{
if ((void*)offset_to_address(n.second) == vtable)
{
node_hash = n.first;
break;
}
}
switch (node_hash)
{
case "CDoorCreationDataNode"_j:
case RAGE_JOAAT("CDoorCreationDataNode"):
{
const auto creation_node = dynamic_cast<CDoorCreationDataNode*>(node);
const auto creation_node = (CDoorCreationDataNode*)(node);
if (is_crash_object(creation_node->m_model))
{
notify::crash_blocked(sender, "invalid door model");
@ -207,9 +212,9 @@ namespace big
}
break;
}
case "CPickupCreationDataNode"_j:
case RAGE_JOAAT("CPickupCreationDataNode"):
{
const auto creation_node = dynamic_cast<CPickupCreationDataNode*>(node);
const auto creation_node = (CPickupCreationDataNode*)(node);
if (is_crash_object(creation_node->m_custom_model))
{
notify::crash_blocked(sender, "invalid pickup model");
@ -217,22 +222,28 @@ namespace big
}
break;
}
case "CPhysicalAttachDataNode"_j:
case RAGE_JOAAT("CPhysicalAttachDataNode"):
{
const auto attach_node = dynamic_cast<CPhysicalAttachDataNode*>(node);
const auto attach_node = (CPhysicalAttachDataNode*)(node);
// TODO: Find a better method to avoid false positives
auto model_hash = object->GetGameObject() ? object->GetGameObject()->m_model_info->m_hash : 0;
auto model_hash = get_game_object(object) ? get_game_object(object)->m_model_info->m_hash : 0;
if (attach_node->m_attached && attach_node->m_attached_to == object->m_object_id && (model_hash != RAGE_JOAAT("hauler2") && model_hash != RAGE_JOAAT("phantom3")))
{
// notify::crash_blocked(sender, "infinite physical attachment");
return true;
}
else if (attach_node->m_attached && is_attachment_infinite((rage::CDynamicEntity*)get_game_object(object), attach_node->m_attached_to))
{
// notify::crash_blocked(sender, "recursive infinite physical attachment");
return true;
}
break;
}
case "CPedCreationDataNode"_j:
case RAGE_JOAAT("CPedCreationDataNode"):
{
const auto creation_node = dynamic_cast<CPedCreationDataNode*>(node);
const auto creation_node = (CPedCreationDataNode*)(node);
if (is_crash_ped(creation_node->m_model))
{
notify::crash_blocked(sender, "invalid ped model");
@ -245,29 +256,25 @@ namespace big
}
break;
}
case "CPedAttachDataNode"_j:
case RAGE_JOAAT("CPedAttachDataNode"):
{
const auto attach_node = dynamic_cast<CPedAttachDataNode*>(node);
const auto attach_node = (CPedAttachDataNode*)(node);
if (attach_node->m_attached && attach_node->m_attached_to == object->m_object_id)
{
notify::crash_blocked(sender, "infinite ped attachment");
return true;
}
break;
}
case "CVehicleCreationDataNode"_j:
{
const auto vehicle_creation_node = dynamic_cast<CVehicleCreationDataNode*>(node);
if (is_crash_vehicle(vehicle_creation_node->m_model))
else if (attach_node->m_attached && is_attachment_infinite(get_game_object(object), attach_node->m_attached_to))
{
notify::crash_blocked(sender, "invalid vehicle model");
notify::crash_blocked(sender, "recursive infinite ped attachment");
return true;
}
break;
}
case "CObjectCreationDataNode"_j:
case RAGE_JOAAT("CObjectCreationDataNode"):
{
const auto creation_node = dynamic_cast<CObjectCreationDataNode*>(node);
const auto creation_node = (CObjectCreationDataNode*)(node);
if (is_crash_object(creation_node->m_model))
{
notify::crash_blocked(sender, "invalid object model");
@ -275,19 +282,29 @@ namespace big
}
break;
}
case "CPlayerAppearanceDataNode"_j:
case RAGE_JOAAT("CPlayerAppearanceDataNode"):
{
const auto player_appearance_node = dynamic_cast<CPlayerAppearanceDataNode*>(node);
const auto player_appearance_node = (CPlayerAppearanceDataNode*)(node);
if (is_crash_ped(player_appearance_node->m_model_hash))
{
notify::crash_blocked(sender, "invalid player model");
notify::crash_blocked(sender, "invalid player model (appearance node)");
return true;
}
break;
}
case "CSectorDataNode"_j:
case RAGE_JOAAT("CPlayerCreationDataNode"):
{
const auto sector_node = dynamic_cast<CSectorDataNode*>(node);
const auto player_creation_node = (CPlayerCreationDataNode*)(node);
if (is_crash_ped(player_creation_node->m_model))
{
notify::crash_blocked(sender, "invalid player model (creation node)");
return true;
}
break;
}
case RAGE_JOAAT("CSectorDataNode"):
{
const auto sector_node = (CSectorDataNode*)(node);
if (sector_node->m_pos_x == 712 || sector_node->m_pos_y == 712 || sector_node->m_pos_z == 712)
{
notify::crash_blocked(sender, "invalid sector position");

View File

@ -0,0 +1,21 @@
#include "hooking.hpp"
#include "pointers.hpp"
namespace big
{
void* hooks::infinite_train_crash(void* carriage)
{
void* current_carriage = carriage;
int count = 0;
while (g_pointers->m_get_next_carriage(current_carriage))
{
if (++count > 20)
return nullptr;
current_carriage = g_pointers->m_get_next_carriage(current_carriage);
}
return current_carriage;
}
}

View File

@ -9,6 +9,7 @@
#include "gta/net_game_event.hpp"
#include "gta/script_id.hpp"
#include "backend/player_command.hpp"
#include "core/data/packet_types.hpp"
#include <network/Network.hpp>
#include <network/netTime.hpp>
@ -104,6 +105,19 @@ namespace big
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", std::format("Blocked invalid blacklist crash from {}", player->get_name()));
}
else
{
g_notification_service->push_error("Protections", "Blocked invalid blacklist remote crash");
}
return true;
}
if (player)
{
switch (msgType)
@ -226,7 +240,10 @@ namespace big
}
}
break;
if (player->get_net_data() && player->get_net_data()->m_gamer_handle_2.m_rockstar_id == handle.m_rockstar_id)
break;
else
return true;
}
case rage::eNetMessage::MsgSessionEstablished:
{
@ -338,7 +355,7 @@ namespace big
}
}
break;
return true;
}
case rage::eNetMessage::MsgRemoveGamersFromSessionCmd:
{
@ -394,6 +411,25 @@ namespace big
}
}
if (g.debug.logs.packet_logs && msgType != rage::eNetMessage::MsgCloneSync && msgType != rage::eNetMessage::MsgPackedCloneSyncACKs && msgType != rage::eNetMessage::MsgPackedEvents
&& msgType != rage::eNetMessage::MsgPackedReliables && msgType != rage::eNetMessage::MsgPackedEventReliablesMsgs && msgType != rage::eNetMessage::MsgNetArrayMgrUpdate
&& msgType != rage::eNetMessage::MsgNetArrayMgrSplitUpdateAck && msgType != rage::eNetMessage::MsgNetArrayMgrUpdateAck && msgType != rage::eNetMessage::MsgScriptHandshakeAck
&& msgType != rage::eNetMessage::MsgScriptHandshake && msgType != rage::eNetMessage::MsgScriptJoin && msgType != rage::eNetMessage::MsgScriptJoinAck
&& msgType != rage::eNetMessage::MsgScriptJoinHostAck && msgType != rage::eNetMessage::MsgRequestObjectIds && msgType != rage::eNetMessage::MsgInformObjectIds && msgType != rage::eNetMessage::MsgNetTimeSync)
{
const char* packet_type = "<UNKNOWN>";
for (const auto& p : packet_types)
{
if (p.second == (int)msgType)
{
packet_type = p.first;
break;
}
}
LOG(G3LOG_DEBUG) << "RECEIVED PACKET | Type: " << packet_type << " | Length: " << frame->m_length << " | Sender: " <<
(player ? player->get_name() : std::format("<M:{}>, <C:{:X}>, <P:{}>", (int)frame->m_msg_id, frame->m_connection_identifier, frame->m_peer_id).c_str()) << " | " << HEX_TO_UPPER((int)msgType);
}
return g_hooking->get_original<hooks::receive_net_message>()(netConnectionManager, a2, frame);
}

View File

@ -0,0 +1,69 @@
#include "hooking.hpp"
#include "util/notify.hpp"
#include "gta/net_array.hpp"
#include "core/scr_globals.hpp"
#include "script_local.hpp"
#include "gta_util.hpp"
#include "gta/script_handler.hpp"
#include <script/globals/GlobalPlayerBD.hpp>
namespace big
{
bool hooks::received_array_update(rage::netArrayHandlerBase* array, CNetGamePlayer* sender, rage::datBitBuffer* buffer, int size, std::int16_t cycle)
{
int old_beast_index = -1;
int participant_id = 0;
auto beast = gta_util::find_script_thread(RAGE_JOAAT("am_hunt_the_beast"));
if (beast)
{
old_beast_index = *script_local(beast->m_stack, scr_locals::am_hunt_the_beast::broadcast_idx).at(1).at(6).as<int*>();
if (beast->m_net_component)
participant_id = beast->m_net_component->m_local_participant_index;
}
bool result = g_hooking->get_original<hooks::received_array_update>()(array, sender, buffer, size, cycle);
if (beast && array->m_array == script_local(beast->m_stack, scr_locals::am_hunt_the_beast::broadcast_idx).as<void*>() &&
old_beast_index != *script_local(beast->m_stack, scr_locals::am_hunt_the_beast::broadcast_idx).at(1).at(6).as<int*>() &&
*script_local(beast->m_stack, scr_locals::am_hunt_the_beast::broadcast_idx).at(1).at(6).as<int*>() == participant_id &&
!misc::has_bit_set(script_local(beast->m_stack, scr_locals::am_hunt_the_beast::player_broadcast_idx).at(participant_id, 4).at(3).as<int*>(), 1))
{
*script_local(beast->m_stack, scr_locals::am_hunt_the_beast::broadcast_idx).at(1).at(6).as<int*>() = -1;
*script_local(beast->m_stack, scr_locals::am_hunt_the_beast::broadcast_idx).at(1).at(7).as<Player*>() = -1;
if (auto plyr = g_player_service->get_by_id(sender->m_player_id))
g.reactions.turn_into_beast.process(plyr);
}
if ((array->m_array >= scr_globals::globalplayer_bd.as<uint8_t*>() &&
array->m_array <= scr_globals::globalplayer_bd.at(31, sizeof(GlobalPlayerBDEntry) / 8).as<uint8_t*>()) &&
scr_globals::globalplayer_bd.as<GlobalPlayerBD*>()->Entries[sender->m_player_id].RemoteWantedLevelPlayer != -1)
{
if (auto plyr = g_player_service->get_by_id(sender->m_player_id))
{
if (scr_globals::globalplayer_bd.as<GlobalPlayerBD*>()->Entries[sender->m_player_id].RemoteWantedLevelPlayer == self::id)
{
g.reactions.remote_wanted_level.process(plyr);
}
else if (auto victim = g_player_service->get_by_id(scr_globals::globalplayer_bd.as<GlobalPlayerBD*>()->Entries[sender->m_player_id].RemoteWantedLevelPlayer))
{
g.reactions.remote_wanted_level_others.process(plyr, victim);
}
}
scr_globals::globalplayer_bd.as<GlobalPlayerBD*>()->Entries[sender->m_player_id].RemoteWantedLevelPlayer = -1; // reset locally
}
if (array->m_array == scr_globals::gsbd.as<void*>() && *scr_globals::gsbd.as<eFreemodeState*>() == eFreemodeState::CLOSING)
{
*scr_globals::gsbd.as<eFreemodeState*>() = eFreemodeState::RUNNING;
if (auto plyr = g_player_service->get_by_id(sender->m_player_id))
g.reactions.end_session_kick.process(plyr);
}
return result;
}
}

View File

@ -3,10 +3,12 @@
#include "util/session.hpp"
#include "gta/net_game_event.hpp"
#include "backend/player_command.hpp"
#include "gta/script_handler.hpp"
#include <network/CNetGamePlayer.hpp>
#include <network/Network.hpp>
#include <script/globals/GPBD_FM_3.hpp>
#include <script/globals/GlobalPlayerBD.hpp>
namespace big
{
@ -67,6 +69,13 @@ namespace big
return true;
}
break;
case eRemoteEvent::CeoKick:
if (player->m_player_id != scr_globals::gpbd_fm_3.as<GPBD_FM_3*>()->Entries[self::id].BossGoon.Boss)
{
g.reactions.ceo_kick.process(plyr);
return true;
}
break;
case eRemoteEvent::CeoMoney:
if (g.protections.script_events.ceo_money && player->m_player_id != scr_globals::gpbd_fm_3.as<GPBD_FM_3*>()->Entries[self::id].BossGoon.Boss)
{
@ -91,6 +100,15 @@ namespace big
return true;
}
break;
case eRemoteEvent::Crash3:
{
if (isnan(*(float*)&args[3]) || isnan(*(float*)&args[4]))
{
g.reactions.crash.process(plyr);
return true;
}
break;
}
case eRemoteEvent::Notification:
switch (static_cast<eRemoteEvent>(args[2]))
{
@ -281,9 +299,9 @@ namespace big
g.reactions.start_activity.process(plyr);
return true;
}
else if (activity == eActivityType::DefendSpecialCargo || activity == eActivityType::GunrunningDefend || activity == eActivityType::BikerDefend)
else if (activity == eActivityType::DefendSpecialCargo || activity == eActivityType::GunrunningDefend || activity == eActivityType::BikerDefend || args[2] == 238)
{
g.reactions.start_activity.process(plyr);
g.reactions.trigger_business_raid.process(plyr);
return true;
}
}
@ -330,16 +348,40 @@ namespace big
case eRemoteEvent::DestroyPersonalVehicle:
g.reactions.destroy_personal_vehicle.process(plyr);
return true;
case eRemoteEvent::KickFromInterior:
if (scr_globals::globalplayer_bd.as<GlobalPlayerBD*>()->Entries[self::id].SimpleInteriorData.Owner != plyr->id())
{
g.reactions.kick_from_interior.process(plyr);
return true;
}
break;
case eRemoteEvent::TriggerCEORaid:
{
if (auto script = gta_util::find_script_thread(RAGE_JOAAT("freemode")))
{
if (script->m_net_component && script->m_net_component->m_host && script->m_net_component->m_host->m_net_game_player != player)
{
g.reactions.trigger_business_raid.process(plyr);
}
}
return true;
}
case eRemoteEvent::BadThing1:
case eRemoteEvent::BadThing2:
return true;
break;
case eRemoteEvent::StartScriptBegin:
{
g.reactions.start_script.process(plyr);
return true;
}
}
// detect pasted menus setting args[1] to something other than PLAYER_ID()
if (*(int*)&args[1] != player->m_player_id && player->m_player_id != -1)
{
LOG(INFO) << "Hash = " << (int)args[0];
LOG(INFO) << "Sender = " << args[1];
g.reactions.tse_sender_mismatch.process(plyr);
return true;
}

View File

@ -6,6 +6,8 @@
#include "util/scripts.hpp"
#include "services/players/player_service.hpp"
#include <script/globals/GlobalPlayerBD.hpp>
namespace big
{
unsigned int hooks::broadcast_net_array(rage::netArrayHandlerBase* _this, CNetGamePlayer* target, rage::datBitBuffer* bit_buffer, uint16_t counter, uint32_t* elem_start, bool silent)
@ -19,7 +21,7 @@ namespace big
target->m_player_id == g_player_service->m_player_to_use_end_session_kick->get()->id() && _this->m_array == scr_globals::gsbd.as<void*>();
bool need_to_modify_wanted_level = g.session.wanted_level_all && (_this->m_array >= scr_globals::globalplayer_bd.as<uint8_t*>() &&
_this->m_array <= scr_globals::globalplayer_bd.at(31, scr_globals::size::globalplayer_bd).as<uint8_t*>());
_this->m_array <= scr_globals::globalplayer_bd.at(31, sizeof(GlobalPlayerBDEntry) / 8).as<uint8_t*>());
bool need_to_turn_player_into_beast = g.m_hunt_the_beast_thread && g.m_hunt_the_beast_thread->m_stack && g.m_hunt_the_beast_thread->m_net_component &&
_this->m_array == script_local(g.m_hunt_the_beast_thread->m_stack, scr_locals::am_hunt_the_beast::broadcast_idx).as<void*>();
@ -35,7 +37,7 @@ namespace big
if (need_to_modify_wanted_level)
{
*scr_globals::globalplayer_bd.at(self::id, scr_globals::size::globalplayer_bd).at(212).as<Player*>() = target->m_player_id;
scr_globals::globalplayer_bd.as<GlobalPlayerBD*>()->Entries[self::id].RemoteWantedLevelPlayer = target->m_player_id;
g_pointers->m_broadcast_patch->apply();
}

View File

@ -109,6 +109,7 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID)
g_script_mgr.add_script(std::make_unique<script>(&backend::vehiclefly_loop, "Vehicle Fly"));
g_script_mgr.add_script(std::make_unique<script>(&backend::turnsignal_loop, "Turn Signals"));
g_script_mgr.add_script(std::make_unique<script>(&backend::disable_control_action_loop, "Disable Controls"));
g_script_mgr.add_script(std::make_unique<script>(&backend::world_loop, "World"));
g_script_mgr.add_script(std::make_unique<script>(&context_menu_service::context_menu, "Context Menu"));
LOG(INFO) << "Scripts registered.";

View File

@ -55,6 +55,16 @@ namespace big
});
}
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);
}

File diff suppressed because it is too large Load Diff

View File

@ -810,6 +810,31 @@ namespace big
m_fragment_physics_crash_2 = ptr.add(1).rip().as<PVOID>();
});
// Clear Ped Tasks Network
main_batch.add("CPTN", "E8 ? ? ? ? EB 28 48 8B 8F A0 10 00 00", [this](memory::handle ptr)
{
m_clear_ped_tasks_network = ptr.add(1).rip().as<functions::clear_ped_tasks_network>();
});
// Infinite Train Crash
main_batch.add("ITC", "E8 ? ? ? ? F3 44 0F 10 93 90 03 00 00", [this](memory::handle ptr)
{
m_infinite_train_crash = ptr.add(1).rip().as<PVOID>();
m_get_next_carriage = ptr.add(1).rip().add(0xF).rip().as<functions::get_next_carriage>();
});
// Get Entity Attached To
main_batch.add("GEAT", "48 83 EC 28 48 8B 51 50 48 85 D2 74 04", [this](memory::handle ptr)
{
m_get_entity_attached_to = ptr.as<functions::get_entity_attached_to>();
});
// Received Array Update
main_batch.add("RAU", "48 89 5C 24 10 55 56 57 41 54 41 55 41 56 41 57 48 8B EC 48 83 EC 30 48 8B 05", [this](memory::handle ptr)
{
m_received_array_update = ptr.as<PVOID>();
});
auto mem_region = memory::module("GTA5.exe");
if (!main_batch.run(mem_region))
{

View File

@ -235,6 +235,15 @@ namespace big
PVOID m_fragment_physics_crash;
PVOID m_fragment_physics_crash_2;
functions::clear_ped_tasks_network m_clear_ped_tasks_network;
PVOID m_infinite_train_crash;
functions::get_next_carriage m_get_next_carriage;
functions::get_entity_attached_to m_get_entity_attached_to;
PVOID m_received_array_update;
};
inline pointers* g_pointers{};

View File

@ -23,7 +23,7 @@ namespace big
gta_data_service::gta_data_service() :
m_peds_cache(g_file_manager->get_project_file("./cache/peds.bin"), 1),
m_vehicles_cache(g_file_manager->get_project_file("./cache/vehicles.bin"), 1),
m_weapons_cache(g_file_manager->get_project_file("./cache/weapons.bin"), 1),
m_weapons_cache(g_file_manager->get_project_file("./cache/weapons.bin"), 2),
m_update_state(eGtaDataUpdateState::IDLE)
{
if (!is_cache_up_to_date())
@ -194,6 +194,33 @@ namespace big
m_weapons_cache.free();
}
inline void parse_ped(std::vector<ped_item>& peds, std::vector<std::uint32_t>& mapped_peds, pugi::xml_document& doc)
{
const auto& items = doc.select_nodes("/CPedModelInfo__InitDataList/InitDatas/Item");
for (const auto& item_node : items)
{
const auto& item = item_node.node();
const auto name = item.child("Name").text().as_string();
const auto hash = rage::joaat(name);
if (std::find(mapped_peds.begin(), mapped_peds.end(), hash) != mapped_peds.end())
continue;
mapped_peds.emplace_back(hash);
auto ped = ped_item{};
std::strncpy(ped.m_name, name, sizeof(ped.m_name));
const auto ped_type = item.child("Pedtype").text().as_string();
std::strncpy(ped.m_ped_type, ped_type, sizeof(ped.m_ped_type));
ped.m_hash = hash;
peds.emplace_back(std::move(ped));
}
}
void gta_data_service::rebuild_cache()
{
m_update_state = eGtaDataUpdateState::UPDATING;
@ -287,12 +314,15 @@ namespace big
const auto name = item.child("Name").text().as_string();
const auto hash = rage::joaat(name);
if (hash == RAGE_JOAAT("WEAPON_BIRD_CRAP"))
continue;
if (exists(mapped_weapons, hash))
continue;
mapped_weapons.emplace_back(hash);
const auto human_name_hash = item.child("HumanNameHash").text().as_string();
if (std::strcmp(human_name_hash, "WT_INVALID") == 0)
if (std::strcmp(human_name_hash, "WT_INVALID") == 0 || std::strcmp(human_name_hash, "WT_VEHMINE") == 0)
continue;
auto weapon = weapon_item{};
@ -309,8 +339,11 @@ namespace big
bool is_gun = false;
bool is_rechargable = false;
const char* category = "";
std::size_t pos;
while ((pos = weapon_flags.find(' ')) != std::string::npos) {
while ((pos = weapon_flags.find(' ')) != std::string::npos)
{
const auto flag = weapon_flags.substr(0, pos);
if (flag == "Thrown")
{
@ -324,11 +357,19 @@ namespace big
{
is_rechargable = true;
}
else if (flag == "Vehicle" || flag == "HiddenFromWeaponWheel" || flag == "NotAWeapon")
{
goto skip;
}
weapon_flags.erase(0, pos + 1);
}
const auto category = item.child("Group").text().as_string();
category = item.child("Group").text().as_string();
if (std::strlen(category) == 0 || std::strcmp(category, "GROUP_DIGISCANNER") == 0)
continue;
if (std::strlen(category) > 6)
{
std::strncpy(weapon.m_weapon_type, category + 6, sizeof(weapon.m_weapon_type));
@ -349,35 +390,16 @@ namespace big
weapon.m_hash = hash;
weapons.emplace_back(std::move(weapon));
skip:
continue;
}
});
}
else if (file.filename() == "peds.meta" || file.filename() == "peds.ymt")
else if (file.filename() == "peds.meta")
{
rpf_wrapper.read_xml_file(file, [&exists, &peds, &mapped_peds](pugi::xml_document& doc)
{
const auto& items = doc.select_nodes("/CPedModelInfo__InitDataList/InitDatas/Item");
for (const auto& item_node : items)
{
const auto& item = item_node.node();
const auto name = item.child("Name").text().as_string();
const auto hash = rage::joaat(name);
if (exists(mapped_peds, hash))
continue;
mapped_peds.emplace_back(hash);
auto ped = ped_item{};
std::strncpy(ped.m_name, name, sizeof(ped.m_name));
const auto ped_type = item.child("Pedtype").text().as_string();
std::strncpy(ped.m_ped_type, ped_type, sizeof(ped.m_ped_type));
ped.m_hash = hash;
peds.emplace_back(std::move(ped));
}
parse_ped(peds, mapped_peds, doc);
});
}
}

View File

@ -32,6 +32,7 @@ namespace big
NETWORK,
SESSION,
MISSIONS,
SPOOFING,
PLAYER_DATABASE,
SESSION_BROWSER,
@ -87,6 +88,7 @@ namespace big
{tabs::NETWORK, { "Network", nullptr, {
{ tabs::SPOOFING, { "Spoofing", view::spoofing }},
{ tabs::SESSION, { "Session", view::session }},
{ tabs::MISSIONS, { "Missions", view::missions }},
{ tabs::PLAYER_DATABASE, { "Player Database", view::player_database }},
{ tabs::SESSION_BROWSER, { "Session Browser", view::session_browser }},
}}},

View File

@ -5,6 +5,7 @@
#include "network/ChatData.hpp"
#include "pointers.hpp"
#include "gui.hpp"
namespace big
{
@ -70,6 +71,9 @@ namespace big
if (const auto chat_data = *g_pointers->m_chat_data; chat_data && (chat_data->m_chat_open || chat_data->m_timer_two))
return;
if (g_gui->is_open())
return;
if (state == eKeyState::RELEASE || state == eKeyState::DOWN)
{
auto &hotkey_map = m_hotkeys[state == eKeyState::RELEASE];

View File

@ -66,6 +66,9 @@ namespace big
rate_limiter m_host_migration_rate_limit{ 1s, 20 };
rate_limiter m_play_sound_rate_limit{ 1s, 10 };
rate_limiter m_invites_rate_limit{ 10s, 2 };
int m_num_spawned_permanent_vehicles = 0;
bool m_block_permanent_vehicles = false;
bool exposed_desync_protection = false;
bool is_modder = false;

View File

@ -56,7 +56,7 @@ namespace big::entity
return (bool)hit;
}
inline bool take_control_of(Entity ent, int timeout = 1000)
inline bool take_control_of(Entity ent, int timeout = 300)
{
if (NETWORK::NETWORK_HAS_CONTROL_OF_ENTITY(ent) || !*g_pointers->m_is_session_started)
return true;
@ -64,7 +64,9 @@ namespace big::entity
for (int i = 0; !NETWORK::NETWORK_HAS_CONTROL_OF_ENTITY(ent) && i < timeout; i++)
{
NETWORK::NETWORK_REQUEST_CONTROL_OF_ENTITY(ent);
script::get_current()->yield();
if (timeout != 0)
script::get_current()->yield();
}
if (!NETWORK::NETWORK_HAS_CONTROL_OF_ENTITY(ent))

View File

@ -17,6 +17,7 @@ namespace big::ped
return false;
}
PLAYER::SET_PLAYER_MODEL(self::id, hash);
self::ped = PLAYER::PLAYER_PED_ID();
script::get_current()->yield();
STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(hash);

View File

@ -297,10 +297,4 @@ namespace big::session
g_pointers->m_trigger_script_event(1, args, arg_count, 1 << target);
}
// TODO this is really broken
inline void enter_player_interior(player_ptr player)
{
}
}

View File

@ -9,7 +9,7 @@ namespace big
if (ImGui::BeginTabItem("Logs"))
{
ImGui::Checkbox("Log Metrics", &g.debug.logs.metric_logs);
ImGui::Checkbox("Log Packets", &g.debug.logs.packet_logs);
ImGui::Checkbox("Native Script Hooks", &g.debug.logs.script_hook_logs);
if (ImGui::TreeNode("Script Event Logging"))

View File

@ -0,0 +1,208 @@
#include "views/view.hpp"
#include "fiber_pool.hpp"
#include "gta_util.hpp"
#include "core/scr_globals.hpp"
#include "script_local.hpp"
#include "util/scripts.hpp"
namespace big
{
static bool mission_found = false;
inline rage::scrThread* check_script(rage::joaat_t hash)
{
if (auto thread = gta_util::find_script_thread(hash))
{
mission_found = true;
return thread;
}
return nullptr;
}
void view::missions()
{
mission_found = false;
components::sub_title("Event Starter");
ImGui::BeginGroup();
components::button("Hot Target", [] { scripts::start_launcher_script(36); });
components::button("Kill List", [] { scripts::start_launcher_script(37); });
components::button("Checkpoints", [] { scripts::start_launcher_script(39); });
components::button("Challenges", [] { scripts::start_launcher_script(40); });
components::button("Penned In", [] { scripts::start_launcher_script(41); });
ImGui::EndGroup();
ImGui::SameLine();
ImGui::BeginGroup();
components::button("Hot Property", [] { scripts::start_launcher_script(43); });
components::button("King Of The Castle", [] { scripts::start_launcher_script(45); });
components::button("Criminal Damage", [] { scripts::start_launcher_script(46); });
components::button("Hunt The Beast", [] { scripts::start_launcher_script(47); });
components::button("Business Battles", [] { scripts::start_launcher_script(114); });
ImGui::EndGroup();
ImGui::SameLine();
ImGui::BeginGroup();
components::button("One-On-One Deathmatch", [] { scripts::start_launcher_script(197); });
components::button("Impromptu Race", [] { scripts::start_launcher_script(16); });
components::button("Flight School", [] { scripts::start_launcher_script(196); });
components::button("Golf", [] { scripts::start_launcher_script(193); });
components::button("Tutorial", [] { scripts::start_launcher_script(20); });
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Only works on joining players");
ImGui::EndGroup();
ImGui::SameLine();
ImGui::BeginGroup();
components::button("Gunslinger", [] { scripts::start_launcher_script(211); });
components::button("Space Monkey", [] { scripts::start_launcher_script(216); });
components::button("Wizard", [] { scripts::start_launcher_script(212); });
components::button("QUB3D", [] { scripts::start_launcher_script(217); });
components::button("Camhedz", [] { scripts::start_launcher_script(218); });
ImGui::EndGroup();
ImGui::Separator();
if (check_script(RAGE_JOAAT("am_criminal_damage")))
{
components::sub_title("Criminal Damage");
components::button("Start Event##criminal_damage", [] {
if (scripts::force_host(RAGE_JOAAT("am_criminal_damage")))
if (auto script = gta_util::find_script_thread(RAGE_JOAAT("am_criminal_damage")))
*script_local(script->m_stack, scr_locals::am_criminal_damage::broadcast_idx).at(43).as<int*>() = 0;
});
ImGui::SameLine();
components::button("Finish Event##criminal_damage", []
{
if (scripts::force_host(RAGE_JOAAT("am_criminal_damage")))
if (auto script = gta_util::find_script_thread(RAGE_JOAAT("am_criminal_damage")))
*script_local(script->m_stack, scr_locals::am_criminal_damage::broadcast_idx).at(39).as<int*>() = 0;
});
components::button("Max Score", []
{
if (auto criminal_damage = gta_util::find_script_thread(RAGE_JOAAT("am_criminal_damage")))
*script_local(criminal_damage->m_stack, scr_locals::am_criminal_damage::score_idx).as<int*>() = 999'999'999;
});
}
if (check_script(RAGE_JOAAT("am_cp_collection")))
{
components::sub_title("Checkpoints");
components::button("Start Event##cp_collection", []
{
if (scripts::force_host(RAGE_JOAAT("am_cp_collection")))
if (auto script = gta_util::find_script_thread(RAGE_JOAAT("am_cp_collection")))
*script_local(script->m_stack, scr_locals::am_cp_collection::broadcast_idx).at(667).as<int*>() = 0;
});
ImGui::SameLine();
components::button("Finish Event##cp_collection", []
{
if (scripts::force_host(RAGE_JOAAT("am_cp_collection")))
if (auto script = gta_util::find_script_thread(RAGE_JOAAT("am_cp_collection")))
*script_local(script->m_stack, scr_locals::am_cp_collection::broadcast_idx).at(661).as<int*>() = 0;
});
components::button("Win Event", []
{
if (auto checkpoints = gta_util::find_script_thread(RAGE_JOAAT("am_cp_collection")))
*script_local(checkpoints->m_stack, scr_locals::am_cp_collection::player_broadcast_idx).at(checkpoints->m_net_component->m_local_participant_index, 5).at(4).as<int*>() = 999'999'999;
script::get_current()->yield(1s);
if (scripts::force_host(RAGE_JOAAT("am_cp_collection")))
{
if (auto checkpoints = gta_util::find_script_thread(RAGE_JOAAT("am_cp_collection")))
{
*script_local(checkpoints->m_stack, scr_locals::am_cp_collection::broadcast_idx).at(708).as<int*>() = 0;
}
}
});
ImGui::SameLine();
components::button("Scramble Checkpoints", []
{
std::vector<Vector3> active_player_positions;
for (auto& plyr : g_player_service->players())
{
if (plyr.second->is_valid() && NETWORK::NETWORK_IS_PLAYER_A_PARTICIPANT_ON_SCRIPT(plyr.second->id(), "am_cp_collection", -1))
{
active_player_positions.push_back(ENTITY::GET_ENTITY_COORDS(PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(plyr.second->id()), false));
}
}
if (scripts::force_host(RAGE_JOAAT("am_cp_collection")))
{
if (auto checkpoints = gta_util::find_script_thread(RAGE_JOAAT("am_cp_collection")))
{
for (int i = 0; i < 100; i++)
{
*script_local(checkpoints->m_stack, scr_locals::am_cp_collection::broadcast_idx).at(10).at(i, 5).as<Vector3*>() = active_player_positions[i % active_player_positions.size()];
}
}
}
});
}
if (check_script(RAGE_JOAAT("am_king_of_the_castle")))
{
components::sub_title("King Of The Castle");
components::button("Complete Event##kotc", []
{
if (scripts::force_host(RAGE_JOAAT("am_king_of_the_castle")))
if (auto script = gta_util::find_script_thread(RAGE_JOAAT("am_king_of_the_castle")))
*script_local(script->m_stack, scr_locals::am_king_of_the_castle::broadcast_idx).at(1).at(1).as<int*>() = 0;
});
ImGui::SameLine();
components::button("Expire Event (if possible)##kotc", []
{
if (scripts::force_host(RAGE_JOAAT("am_king_of_the_castle")))
if (auto script = gta_util::find_script_thread(RAGE_JOAAT("am_king_of_the_castle")))
*script_local(script->m_stack, scr_locals::am_king_of_the_castle::broadcast_idx).at(1).at(3).as<int*>() = 0;
});
components::button("Become The King##kotc", []
{
if (scripts::force_host(RAGE_JOAAT("am_king_of_the_castle")))
{
if (auto kotc = gta_util::find_script_thread(RAGE_JOAAT("am_king_of_the_castle")))
{
*script_local(kotc->m_stack, scr_locals::am_king_of_the_castle::broadcast_idx).at(6).at(0, 204).at(74).at(0, 4).as<int*>() = 0;
*script_local(kotc->m_stack, scr_locals::am_king_of_the_castle::broadcast_idx).at(6).at(0, 204).at(74).at(0, 4).at(1).as<int*>() = self::id;
*script_local(kotc->m_stack, scr_locals::am_king_of_the_castle::broadcast_idx).at(6).at(0, 204).at(74).at(0, 4).at(2).as<int*>() = self::id;
*script_local(kotc->m_stack, scr_locals::am_king_of_the_castle::broadcast_idx).at(6).at(0, 204).at(74).at(0, 4).at(3).as<float*>() = 999999999.0f;
}
}
});
ImGui::SameLine();
components::button("Dethrone Everyone##kotc", []
{
if (scripts::force_host(RAGE_JOAAT("am_king_of_the_castle")))
{
if (auto kotc = gta_util::find_script_thread(RAGE_JOAAT("am_king_of_the_castle")))
{
for (int i = 0; i < *script_local(kotc->m_stack, scr_locals::am_king_of_the_castle::broadcast_idx).at(6).at(0, 204).at(74).as<int*>(); i++)
{
*script_local(kotc->m_stack, scr_locals::am_king_of_the_castle::broadcast_idx).at(6).at(0, 204).at(74).at(i, 4).as<int*>() = -1;
*script_local(kotc->m_stack, scr_locals::am_king_of_the_castle::broadcast_idx).at(6).at(0, 204).at(74).at(i, 4).at(1).as<int*>() = -1;
*script_local(kotc->m_stack, scr_locals::am_king_of_the_castle::broadcast_idx).at(6).at(0, 204).at(74).at(i, 4).at(2).as<int*>() = -1;
*script_local(kotc->m_stack, scr_locals::am_king_of_the_castle::broadcast_idx).at(6).at(0, 204).at(74).at(i, 4).at(3).as<float*>() = -1.0f;
}
}
}
});
}
if (!mission_found)
{
ImGui::Text("No active mission");
}
}
}

View File

@ -160,6 +160,10 @@ namespace big
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);
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);
});
}
@ -219,7 +223,6 @@ namespace big
ImGui::SameLine();
components::command_button<"beastall">({ });
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Including you");
@ -233,8 +236,23 @@ namespace big
components::command_button<"vehkickall">({ });
components::command_button<"ragdollall">({ }, "Ragdoll Players");
ImGui::SameLine();
components::command_button<"intkickall">({ }, "Kick Everyone From Interiors");
components::command_button<"missionall">({ });
ImGui::SameLine();
components::command_button<"errorall">({ });
components::command_button<"ceoraidall">({ });
ImGui::SameLine();
components::button("Trigger MC Raid", [] { g_player_service->iterate([](auto& plyr) { toxic::start_activity(plyr.second, eActivityType::BikerDefend); }); });
ImGui::SameLine();
components::button("Trigger Bunker Raid", [] { g_player_service->iterate([](auto& plyr) { toxic::start_activity(plyr.second, eActivityType::GunrunningDefend); }); });
components::command_button<"sextall">({ }, "Send Sexts");
ImGui::SameLine();
components::command_button<"fakebanall">({ }, "Send Fake Ban Messages");
components::small_text("Teleports");
if (ImGui::BeginCombo("##apartment", apartment_names[g.session.send_to_apartment_idx]))
@ -311,47 +329,23 @@ namespace big
ImGui::SameLine();
components::command_button<"interiortpall">({ 161 }, "TP All To Multi Floor Garage");
components::sub_title("Event Starter");
ImGui::BeginGroup();
components::button("Hot Target", [] { scripts::start_launcher_script(36); });
components::button("Kill List", [] { scripts::start_launcher_script(37); });
components::button("Checkpoints", [] { scripts::start_launcher_script(39); });
components::button("Challenges", [] { scripts::start_launcher_script(40); });
components::button("Penned In", [] { scripts::start_launcher_script(41); });
ImGui::EndGroup();
components::command_button<"tutorialall">();
ImGui::SameLine();
ImGui::BeginGroup();
components::button("Hot Property", [] { scripts::start_launcher_script(43); });
components::button("King Of The Castle", [] { scripts::start_launcher_script(45); });
components::button("Criminal Damage", [] { scripts::start_launcher_script(46); });
components::button("Hunt The Beast", [] { scripts::start_launcher_script(47); });
components::button("Business Battles", [] { scripts::start_launcher_script(114); });
ImGui::EndGroup();
components::command_button<"golfall">();
ImGui::SameLine();
ImGui::BeginGroup();
components::button("One-On-One Deathmatch", [] { scripts::start_launcher_script(197); });
components::button("Impromptu Race", [] { scripts::start_launcher_script(16); });
components::button("Flight School", [] { scripts::start_launcher_script(196); });
components::button("Golf", [] { scripts::start_launcher_script(193); });
components::button("Tutorial", [] { scripts::start_launcher_script(20); });
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Only works on joining players");
ImGui::EndGroup();
components::command_button<"flightschoolall">();
ImGui::SameLine();
components::command_button<"dartsall">();
ImGui::BeginGroup();
components::button("Gunslinger", [] { scripts::start_launcher_script(211); });
components::button("Space Monkey", [] { scripts::start_launcher_script(216); });
components::button("Wizard", [] { scripts::start_launcher_script(212); });
components::button("QUB3D", [] { scripts::start_launcher_script(217); });
components::button("Camhedz", [] { scripts::start_launcher_script(218); });
ImGui::EndGroup();
components::command_button<"badlandsall">();
ImGui::SameLine();
components::command_button<"spacemonkeyall">();
ImGui::SameLine();
components::command_button<"wizardall">();
components::command_button<"qub3dall">();
ImGui::SameLine();
components::command_button<"camhedzall">();
ImGui::Checkbox("Disable Pedestrians", &g.session.disable_peds);
ImGui::SameLine();
@ -381,5 +375,12 @@ namespace big
ImGui::SetTooltip("Blocks CEO money drops across the entire session. This can also break other stuff, use with caution");
ImGui::SameLine();
ImGui::Checkbox("Randomize CEO Colors", &g.session.randomize_ceo_colors);
ImGui::Checkbox("Block Jobs", &g.session.block_jobs);
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Prevents remote players from starting jobs while in your session");
ImGui::SameLine();
components::script_patch_checkbox("Block Muggers", &g.session.block_muggers, "For the entire session");
ImGui::SameLine();
components::script_patch_checkbox("Block CEO Raids", &g.session.block_ceo_raids, "For the entire session");
}
}

View File

@ -137,7 +137,7 @@ namespace big
ImGui::Text("Language: %s", languages[boss_goon.Language].name);
ImGui::Text("CEO Name: %s", boss_goon.GangName);
ImGui::Text("MC Name: %s", boss_goon.MCName);
ImGui::Text("MC Name: %s", boss_goon.ClubhouseName);
ImGui::Text("Money In Wallet: %d", stats.WalletBalance);
ImGui::Text("Money In Bank: %d", stats.Money - stats.WalletBalance);
ImGui::Text("Total Money: %d", stats.Money);

View File

@ -18,10 +18,13 @@ namespace big
components::player_command_button<"lckick">(g_player_service->get_selected());
});
components::player_command_button<"bailkick">(g_player_service->get_selected());
ImGui::SameLine();
components::player_command_button<"nfkick">(g_player_service->get_selected());
components::player_command_button<"oomkick">(g_player_service->get_selected());
ImGui::SameLine();
components::player_command_button<"gikick">(g_player_service->get_selected());
components::player_command_button<"shkick">(g_player_service->get_selected());
ImGui::SameLine();
components::player_command_button<"endkick">(g_player_service->get_selected());
components::player_command_button<"desync">(g_player_service->get_selected());

View File

@ -1,4 +1,5 @@
#include "views/view.hpp"
#include "util/scripts.hpp"
namespace big
{
@ -22,6 +23,13 @@ namespace big
ImGui::Checkbox("Off The Radar", &g_player_service->get_selected()->off_radar);
ImGui::Checkbox("Never Wanted", &g_player_service->get_selected()->never_wanted);
ImGui::Checkbox("Semi Godmode", &g_player_service->get_selected()->semi_godmode);
components::button("Gooch Test", []
{
*script_global(1890140).at(244).at(1).as<Player*>() = g_player_service->get_selected()->id();
scripts::start_launcher_script(171);
});
ImGui::TreePop();
}
}

View File

@ -19,10 +19,25 @@ namespace big
components::player_command_button<"vehkick">(g_player_service->get_selected(), {});
components::player_command_button<"ragdoll">(g_player_service->get_selected(), {});
ImGui::SameLine();
components::player_command_button<"intkick">(g_player_service->get_selected(), {});
ImGui::SameLine();
components::player_command_button<"beast">(g_player_service->get_selected(), {});
components::player_command_button<"mission">(g_player_service->get_selected(), {});
ImGui::SameLine();
components::player_command_button<"error">(g_player_service->get_selected(), {});
components::player_command_button<"ceoraid">(g_player_service->get_selected(), {});
ImGui::SameLine();
components::button("Trigger MC Raid", [] { toxic::start_activity(g_player_service->get_selected(), eActivityType::BikerDefend); });
ImGui::SameLine();
components::button("Trigger Bunker Raid", [] { toxic::start_activity(g_player_service->get_selected(), eActivityType::GunrunningDefend); });
components::player_command_button<"sext">(g_player_service->get_selected(), {});
ImGui::SameLine();
components::player_command_button<"fakeban">(g_player_service->get_selected(), {});
static int wanted_level;
ImGui::SliderInt("Wanted Level", &wanted_level, 0, 5);
ImGui::SameLine();
@ -109,6 +124,24 @@ namespace big
ImGui::SameLine();
components::player_command_button<"remweaps">(g_player_service->get_selected(), { });
components::player_command_button<"tutorial">(g_player_service->get_selected(), { });
ImGui::SameLine();
components::player_command_button<"golf">(g_player_service->get_selected(), { });
ImGui::SameLine();
components::player_command_button<"flightschool">(g_player_service->get_selected(), { });
ImGui::SameLine();
components::player_command_button<"darts">(g_player_service->get_selected(), { });
components::player_command_button<"badlands">(g_player_service->get_selected(), { });
ImGui::SameLine();
components::player_command_button<"spacemonkey">(g_player_service->get_selected(), { });
ImGui::SameLine();
components::player_command_button<"wizard">(g_player_service->get_selected(), { });
components::player_command_button<"qub3d">(g_player_service->get_selected(), { });
ImGui::SameLine();
components::player_command_button<"camhedz">(g_player_service->get_selected(), { });
components::small_text("Warp Time (requires session host)");
components::button("+1 Minute", [] { toxic::warp_time_forward(g_player_service->get_selected(), 60 * 1000); });

View File

@ -57,15 +57,18 @@ namespace big
{
components::title("Reactions");
draw_reaction(g.reactions.bounty);
draw_reaction(g.reactions.ceo_kick);
draw_reaction(g.reactions.ceo_money);
draw_reaction(g.reactions.clear_wanted_level);
draw_reaction(g.reactions.crash);
draw_reaction(g.reactions.end_session_kick);
draw_reaction(g.reactions.destroy_personal_vehicle);
draw_reaction(g.reactions.fake_deposit);
draw_reaction(g.reactions.force_mission);
draw_reaction(g.reactions.force_teleport);
draw_reaction(g.reactions.give_collectible);
draw_reaction(g.reactions.gta_banner);
draw_reaction(g.reactions.kick_from_interior);
draw_reaction(g.reactions.mc_teleport);
draw_reaction(g.reactions.network_bail);
draw_reaction(g.reactions.null_function_kick);
@ -77,11 +80,16 @@ namespace big
draw_reaction(g.reactions.sound_spam);
draw_reaction(g.reactions.spectate_notification);
draw_reaction(g.reactions.start_activity);
draw_reaction(g.reactions.start_script);
draw_reaction(g.reactions.teleport_to_warehouse);
draw_reaction(g.reactions.transaction_error);
draw_reaction(g.reactions.trigger_business_raid);
draw_reaction(g.reactions.tse_freeze);
draw_reaction(g.reactions.tse_sender_mismatch);
draw_reaction(g.reactions.vehicle_kick);
draw_reaction(g.reactions.turn_into_beast);
draw_reaction(g.reactions.remote_wanted_level);
draw_interloper_reaction(g.reactions.remote_wanted_level_others);
ImGui::Separator();
draw_reaction(g.reactions.clear_ped_tasks);
draw_reaction(g.reactions.remote_ragdoll);

View File

@ -29,6 +29,7 @@ namespace big
static void root();
static void self();
static void session();
static void missions();
static void player_database();
static void session_browser();
static void settings();

View File

@ -7,6 +7,7 @@
#include "services/gta_data/gta_data_service.hpp"
#include "services/model_preview/model_preview_service.hpp"
#include "services/players/player_service.hpp"
#include "backend/looped/looped.hpp"
#include <imgui_internal.h>
@ -14,8 +15,43 @@
#define SPAWN_PED_ALL_WEAPONS -1
#define SPAWN_PED_NO_WEAPONS -2
#define SPAWN_PED_FOR_SELF -1
#define SPAWN_PED_FOR_EVERYONE -2
static int selected_ped_weapon_type = SPAWN_PED_ALL_WEAPONS;
static Hash selected_ped_weapon_hash = 0;
namespace big
{
void spawn_ped_give_weapon(
const Ped ped
)
{
if (selected_ped_weapon_type == SPAWN_PED_NO_WEAPONS)
{
return;
}
const auto& weapon_type_arr = g_gta_data_service->weapon_types();
for (auto& [_, weapon] : g_gta_data_service->weapons())
{
if (
selected_ped_weapon_type == SPAWN_PED_ALL_WEAPONS ||
weapon.m_weapon_type == weapon_type_arr[selected_ped_weapon_type]
)
{
if (
(selected_ped_weapon_hash == 0 ||
weapon.m_hash == selected_ped_weapon_hash)
&& weapon.m_hash != RAGE_JOAAT("WEAPON_UNARMED")
)
{
WEAPON::GIVE_WEAPON_TO_PED(ped, weapon.m_hash, 9999, false, selected_ped_weapon_hash != 0);
}
}
}
}
Ped spawn_ped_at_location(
const int selected_ped_type,
const char* ped_model_buf,
@ -55,7 +91,7 @@ namespace big
}
if (selected_ped_for_player_id == -1)
if (selected_ped_for_player_id == SPAWN_PED_FOR_SELF)
{
location = self::pos;
player = self::id;
@ -89,56 +125,77 @@ namespace big
return 0;
}
PED::SET_PED_ARMOUR(ped, 100);
ENTITY::SET_ENTITY_MAX_HEALTH(ped, 1000);
ENTITY::SET_ENTITY_HEALTH(ped, 1000, 0);
PED::SET_PED_COMBAT_ABILITY(ped, 100);
PED::SET_PED_ACCURACY(ped, 100);
PED::SET_PED_COMBAT_ATTRIBUTES(ped, 1, 1);
PED::SET_PED_COMBAT_ATTRIBUTES(ped, 3, 1);
PED::SET_PED_COMBAT_ATTRIBUTES(ped, 5, 1);
PED::SET_PED_COMBAT_ATTRIBUTES(ped, 13, 1);
PED::SET_PED_COMBAT_ATTRIBUTES(ped, 21, 1);
PED::SET_PED_COMBAT_ATTRIBUTES(ped, 27, 1);
PED::SET_PED_COMBAT_ATTRIBUTES(ped, 41, 1);
PED::SET_PED_COMBAT_ATTRIBUTES(ped, 46, 1);
PED::SET_PED_COMBAT_ATTRIBUTES(ped, 63, 0);
PED::SET_PED_COMBAT_ABILITY(ped, 2);
PED::SET_PED_COMBAT_MOVEMENT(ped, 2);
PED::SET_PED_COMBAT_RANGE(ped, 0);
PED::SET_PED_HIGHLY_PERCEPTIVE(ped, true);
PED::SET_PED_SEEING_RANGE(ped, 200.0f);
PED::SET_PED_HEARING_RANGE(ped, 200.0f);
PED::SET_PED_ID_RANGE(ped, 200.0f);
PED::SET_PED_FIRING_PATTERN(ped, RAGE_JOAAT("FIRING_PATTERN_FULL_AUTO"));
PED::SET_PED_SHOOT_RATE(ped, 150);
PED::SET_PED_RANDOM_COMPONENT_VARIATION(ped, 0);
if (is_bodyguard)
{
int player_group = PLAYER::GET_PLAYER_GROUP(player);
int player_group = PED::GET_PED_GROUP_INDEX(player_ped);
if (!PED::DOES_GROUP_EXIST(player_group))
player_group = PED::CREATE_GROUP(0);
PED::SET_PED_AS_GROUP_MEMBER(ped, player_group);
PED::SET_PED_RELATIONSHIP_GROUP_HASH(ped, PED::GET_PED_RELATIONSHIP_GROUP_HASH(player_ped));
PED::SET_PED_AS_GROUP_LEADER(player_ped, player_group);
PED::SET_PED_AS_GROUP_MEMBER(ped, player_group);
PED::SET_PED_CAN_TELEPORT_TO_GROUP_LEADER(ped, player_group, true);
PED::SET_PED_NEVER_LEAVES_GROUP(ped, true);
PED::SET_PED_RELATIONSHIP_GROUP_HASH(ped, PED::GET_PED_RELATIONSHIP_GROUP_HASH(player_ped));
PED::SET_PED_CAN_BE_TARGETTED_BY_PLAYER(ped, player, true);
PED::SET_PED_ARMOUR(ped, 100);
ENTITY::SET_ENTITY_MAX_HEALTH(ped, 1000);
ENTITY::SET_ENTITY_HEALTH(ped, 1000, 0);
PED::SET_PED_COMBAT_ABILITY(ped, 100);
PED::SET_PED_COMBAT_ATTRIBUTES(ped, 46, 1);
PED::SET_PED_COMBAT_ATTRIBUTES(ped, 63, 0);
TASK::CLEAR_PED_TASKS_IMMEDIATELY(ped);
TASK::TASK_COMBAT_HATED_TARGETS_AROUND_PED(ped, 100.f, 0);
PED::SET_PED_KEEP_TASK(ped, true);
}
return ped;
}
void spawn_ped_give_weapon(
const Ped ped,
const int selected_ped_weapon_type,
const Hash selected_ped_weapon_hash
) {
if (selected_ped_weapon_type == SPAWN_PED_NO_WEAPONS)
{
return;
}
const auto& weapon_type_arr = g_gta_data_service->weapon_types();
for (auto& [_, weapon] : g_gta_data_service->weapons())
{
if (
selected_ped_weapon_type == SPAWN_PED_ALL_WEAPONS ||
weapon.m_weapon_type == weapon_type_arr[selected_ped_weapon_type]
) {
if (
(selected_ped_weapon_hash == 0 ||
weapon.m_hash == selected_ped_weapon_hash)
&& weapon.m_hash != RAGE_JOAAT("WEAPON_UNARMED")
) {
WEAPON::GIVE_WEAPON_TO_PED(ped, weapon.m_hash, 9999, false, selected_ped_weapon_hash != 0);
}
if (player != self::id)
{
PED::SET_PED_KEEP_TASK(ped, true);
PED::SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(ped, true);
TASK::TASK_SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(ped, true);
TASK::TASK_FOLLOW_TO_OFFSET_OF_ENTITY(ped, player, 0.0f, 0.0f, 0.0f, 4.0f, -1, 0.0f, true);
}
}
if (g.world.spawn_ped.spawn_invincible)
{
ENTITY::SET_ENTITY_INVINCIBLE(ped, true);
}
if (g.world.spawn_ped.spawn_invisible)
{
ENTITY::SET_ENTITY_VISIBLE(ped, false, false);
}
if (g.world.spawn_ped.spawn_as_attacker)
{
PED::SET_PED_AS_ENEMY(ped, true);
PED::SET_PED_KEEP_TASK(ped, true);
PED::SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(ped, true);
TASK::TASK_COMBAT_PED(ped, player_ped, 0, 16);
PED::SET_PED_RELATIONSHIP_GROUP_HASH(ped, RAGE_JOAAT("HATES_PLAYER"));
PED::SET_PED_ALERTNESS(ped, 3);
}
spawn_ped_give_weapon(ped);
spawned_peds.push_back({ ped, selected_ped_for_player_id == SPAWN_PED_FOR_SELF ? self::id : selected_ped_for_player_id, is_bodyguard, g.world.spawn_ped.spawn_as_attacker });
return ped;
}
void view::spawn_ped()
@ -148,22 +205,21 @@ namespace big
static char ped_model_buf[64];
static Player selected_ped_player_id = -1;
auto ped_type_arr = g_gta_data_service->ped_types();
auto ped_arr = g_gta_data_service->peds();
auto& ped_type_arr = g_gta_data_service->ped_types();
auto& ped_arr = g_gta_data_service->peds();
static int selected_ped_weapon_type = SPAWN_PED_ALL_WEAPONS;
static Hash selected_ped_weapon_hash = 0;
auto weapon_type_arr = g_gta_data_service->weapon_types();
auto weapon_arr = g_gta_data_service->weapons();
auto& weapon_type_arr = g_gta_data_service->weapon_types();
auto& weapon_arr = g_gta_data_service->weapons();
static Player selected_ped_for_player_id = -1;
auto player_arr = g_player_service->players();
auto& player_arr = g_player_service->players();
if (!*g_pointers->m_is_session_started)
{
selected_ped_player_id = -1;
selected_ped_for_player_id = -1;
if (selected_ped_for_player_id != SPAWN_PED_FOR_SELF && selected_ped_for_player_id != SPAWN_PED_FOR_EVERYONE)
selected_ped_for_player_id = SPAWN_PED_FOR_SELF;
}
else
{
@ -172,13 +228,12 @@ namespace big
selected_ped_player_id = -1;
}
if (g_player_service->get_by_id(selected_ped_for_player_id) == nullptr)
if (selected_ped_for_player_id != SPAWN_PED_FOR_SELF && selected_ped_for_player_id != SPAWN_PED_FOR_EVERYONE && g_player_service->get_by_id(selected_ped_for_player_id) == nullptr)
{
selected_ped_for_player_id = -1;
selected_ped_for_player_id = SPAWN_PED_FOR_SELF;
}
}
components::sub_title("Ped Model");
{
ImGui::BeginGroup();
@ -511,16 +566,29 @@ namespace big
{
if (ImGui::BeginCombo(
"##ped_for",
selected_ped_for_player_id == -1 ?
(selected_ped_for_player_id == SPAWN_PED_FOR_SELF ?
"Self" :
g_player_service->get_by_id(selected_ped_for_player_id)->get_name()
)) {
if (ImGui::Selectable("Self", selected_ped_for_player_id == -1))
(selected_ped_for_player_id == SPAWN_PED_FOR_EVERYONE ?
"Everyone" :
g_player_service->get_by_id(selected_ped_for_player_id)->get_name()))
))
{
if (ImGui::Selectable("Self", selected_ped_for_player_id == SPAWN_PED_FOR_SELF))
{
selected_ped_for_player_id = -1;
selected_ped_for_player_id = SPAWN_PED_FOR_SELF;
}
if (selected_ped_for_player_id == -1)
if (selected_ped_for_player_id == SPAWN_PED_FOR_SELF)
{
ImGui::SetItemDefaultFocus();
}
if (ImGui::Selectable("Everyone", selected_ped_for_player_id == SPAWN_PED_FOR_EVERYONE))
{
selected_ped_for_player_id = SPAWN_PED_FOR_EVERYONE;
}
if (selected_ped_for_player_id == SPAWN_PED_FOR_EVERYONE)
{
ImGui::SetItemDefaultFocus();
}
@ -559,7 +627,12 @@ namespace big
}
}
components::button("Change Player Model", [] {
ImGui::Checkbox("Invincible", &g.world.spawn_ped.spawn_invincible);
ImGui::Checkbox("Invisible", &g.world.spawn_ped.spawn_invisible);
ImGui::Checkbox("Attacker", &g.world.spawn_ped.spawn_as_attacker);
components::button("Change Player Model", []
{
if (selected_ped_type == -2)
{
if (selected_ped_player_id != -1)
@ -571,39 +644,61 @@ namespace big
ped::steal_identity(ped);
}
}
}
}
else
{
if (!ped::change_player_model(rage::joaat(ped_model_buf)))
{
g_notification_service->push_error("Ped", "Failed to spawn model, did you give an incorrect model ? ");
g_notification_service->push_error("Ped", "Failed to spawn model, did you give an incorrect model?");
return;
}
}
spawn_ped_give_weapon(self::ped, selected_ped_weapon_type, selected_ped_weapon_hash);
});
ImGui::SameLine();
components::button("Spawn Ped", [] {
Ped ped = spawn_ped_at_location(selected_ped_type, ped_model_buf, selected_ped_player_id, selected_ped_for_player_id, false);
if (ped)
{
spawn_ped_give_weapon(ped, selected_ped_weapon_type, selected_ped_weapon_hash);
PED::SET_PED_RANDOM_COMPONENT_VARIATION(self::ped, 0);
}
});
ImGui::SameLine();
components::button("Spawn Bodyguard", [] {
Ped ped = spawn_ped_at_location(selected_ped_type, ped_model_buf, selected_ped_player_id, selected_ped_for_player_id, true);
if (ped)
components::button("Spawn Ped", []
{
if (selected_ped_for_player_id == SPAWN_PED_FOR_EVERYONE)
{
spawn_ped_give_weapon(ped, selected_ped_weapon_type, selected_ped_weapon_hash);
g_player_service->iterate([](const big::player_entry& entry)
{
spawn_ped_at_location(selected_ped_type, ped_model_buf, selected_ped_player_id, entry.second->id(), false);
});
}
else
{
spawn_ped_at_location(selected_ped_type, ped_model_buf, selected_ped_player_id, selected_ped_for_player_id, false);
}
});
ImGui::SameLine();
components::button("Spawn Bodyguard", []
{
if (selected_ped_for_player_id == SPAWN_PED_FOR_EVERYONE)
{
g_player_service->iterate([](const big::player_entry& entry)
{
spawn_ped_at_location(selected_ped_type, ped_model_buf, selected_ped_player_id, entry.second->id(), true);
});
}
else
{
spawn_ped_at_location(selected_ped_type, ped_model_buf, selected_ped_player_id, selected_ped_for_player_id, true);
}
});
components::button("Cleanup Spawned Peds", []
{
for (auto& ped : spawned_peds)
{
PED::DELETE_PED(&ped.ped_handle);
}
spawned_peds.clear();
});
}
}