Force session host and improve protections (#593)

* Add force session host and update protections

* Remove old popgroup protection

* Harden script patcher

* Replace looped options with script patches

* Missing break

* Use enums

* Forgot to break again...

* Add tooltip for force session host

Co-authored-by: user <email@hostname>
This commit is contained in:
maybegreat48 2022-11-13 16:34:44 +00:00 committed by GitHub
parent ddc70a76e0
commit eb41c69e09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 467 additions and 250 deletions

View File

@ -3,7 +3,7 @@ include(FetchContent)
FetchContent_Declare(
gtav_classes
GIT_REPOSITORY https://github.com/Yimura/GTAV-Classes.git
GIT_TAG 5d2c9118aed8c1346c7b8cdc271954909bcf888d
GIT_TAG 0a23b823e2dd2e52004b206b7cce735d326c209f
GIT_PROGRESS TRUE
CONFIGURE_COMMAND ""
BUILD_COMMAND ""

View File

@ -17,6 +17,7 @@ namespace big
looped::system_self_globals();
looped::system_update_pointers();
looped::system_desync_kick_protection();
looped::system_force_session_host();
script::get_current()->yield();
}
@ -78,7 +79,6 @@ namespace big
{
looped::vehicle_auto_drive();
looped::vehicle_boost_behavior();
looped::vehicle_despawn_bypass();
looped::vehicle_drive_on_water();
looped::vehicle_god_mode();
looped::vehicle_horn_boost();
@ -114,7 +114,6 @@ namespace big
{
looped::hud_transition_state();
looped::tunables_disable_phone();
looped::tunables_no_idle_kick();
looped::session_local_time();
script::get_current()->yield();

View File

@ -75,6 +75,7 @@ namespace big
"Terminate Maintransition",
"Wait For Dirty Load Confirm",
"DLC Intro Bink",
"Spawn Into Personal Vehicle"
};
auto transition_state = script_global(1574991);
@ -108,7 +109,7 @@ namespace big
return;
}
if ((int)state > 0 && (int)std::size(transition_states))
if ((int)state > 0 && (int)state < std::size(transition_states))
{
HUD::BEGIN_TEXT_COMMAND_BUSYSPINNER_ON("STRING");
auto const spinner_text = std::format("{} | {}", transition_states[(int)state], static_cast<int>(state));

View File

@ -14,7 +14,6 @@ namespace big
static void hud_transition_state();
static void tunables_disable_phone();
static void tunables_no_idle_kick();
static void player_never_wanted(const player_ptr &player);
static void player_spectate();
@ -43,10 +42,10 @@ namespace big
static void system_self_globals();
static void system_update_pointers();
static void system_desync_kick_protection();
static void system_force_session_host();
static void vehicle_auto_drive();
static void vehicle_boost_behavior();
static void vehicle_despawn_bypass();
static void vehicle_drive_on_water();
static void vehicle_fly();
static void vehicle_god_mode();

View File

@ -27,8 +27,6 @@ namespace big
ENTITY::FREEZE_ENTITY_POSITION(vehicle, false);
STREAMING::SET_FOCUS_ENTITY(ped);
globals::disable_kill_trigger(false);
}
return;
@ -36,8 +34,6 @@ namespace big
const auto target = PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(g_player_service->get_selected()->id());
globals::disable_kill_trigger(true);
NETWORK::NETWORK_SET_IN_SPECTATOR_MODE(true, target);
HUD::SET_MINIMAP_IN_SPECTATOR_MODE(true, target);

View File

@ -57,7 +57,6 @@ namespace big
vecPosition = CAM::GET_GAMEPLAY_CAM_COORD();
vecRot = CAM::GET_GAMEPLAY_CAM_ROT(2);
globals::disable_kill_trigger(true);
ENTITY::FREEZE_ENTITY_POSITION(vehicle, true);
CAM::SET_CAM_COORD(cCam, vecPosition.x, vecPosition.y, vecPosition.z);
@ -75,7 +74,6 @@ namespace big
STREAMING::SET_FOCUS_ENTITY(ped);
ENTITY::FREEZE_ENTITY_POSITION(vehicle, false);
globals::disable_kill_trigger(false);
bLastFreeCam = false;

View File

@ -4,6 +4,7 @@
#include "script.hpp"
#include "services/players/player_service.hpp"
#include "gta_util.hpp"
#include <network/Network.hpp>
namespace big
{

View File

@ -0,0 +1,33 @@
#include "backend/looped/looped.hpp"
#include "gta_util.hpp"
#include <network/Network.hpp>
#include <network/CCommunications.hpp>
namespace big
{
static bool bLastForceHost = false;
void looped::system_force_session_host()
{
if (bLastForceHost != g->session.force_session_host && gta_util::get_network()->m_game_session_state == 0)
{
std::uint64_t host_token;
g_pointers->m_generate_uuid(&host_token);
host_token = g->session.force_session_host ? 1 : host_token;
*g_pointers->m_host_token = host_token;
if (gta_util::get_network()->m_game_session_ptr)
gta_util::get_network()->m_game_session_ptr->m_local_player.m_player_data.m_host_token = host_token;
g_pointers->m_profile_gamer_info->m_host_token = host_token;
g_pointers->m_player_info_gamer_info->m_host_token = host_token;
(*g_pointers->m_communications)->m_voice.m_connections[0]->m_gamer_info.m_host_token = host_token;
if (g_local_player && g_local_player->m_player_info)
g_local_player->m_player_info->m_net_player_data.m_host_token = host_token;
bLastForceHost = g->session.force_session_host;
}
}
}

View File

@ -1,28 +0,0 @@
#include "backend/looped/looped.hpp"
#include "script_global.hpp"
namespace big
{
auto idle_kick_a = script_global(1648034);
auto idle_kick_b = script_global(262145);
// ref: https://www.unknowncheats.me/forum/3487508-post22.html#post3487508
void looped::tunables_no_idle_kick()
{
if (g->tunables.no_idle_kick)
{
*idle_kick_a.at(1156).as<int*>() = 0; // idle time
*idle_kick_a.at(1172).as<int*>() = 0;
*idle_kick_b.at(87).as<int*>() = INT32_MAX; // IDLEKICK_WARNING1
*idle_kick_b.at(88).as<int*>() = INT32_MAX; // IDLEKICK_WARNING2
*idle_kick_b.at(89).as<int*>() = INT32_MAX; // IDLEKICK_WARNING3
*idle_kick_b.at(90).as<int*>() = INT32_MAX; // IDLEKICK_KICK
*idle_kick_b.at(8248).as<int*>() = INT32_MAX; // ConstrainedKick_Warning1
*idle_kick_b.at(8249).as<int*>() = INT32_MAX; // ConstrainedKick_Warning2
*idle_kick_b.at(8250).as<int*>() = INT32_MAX; // ConstrainedKick_Warning3
*idle_kick_b.at(8251).as<int*>() = INT32_MAX; // ConstrainedKick_Kick
}
}
}

View File

@ -1,11 +0,0 @@
#include "backend/looped/looped.hpp"
#include "script_global.hpp"
namespace big
{
// allows for spawning unreleased vehicles in online and online vehicles in single player
void looped::vehicle_despawn_bypass()
{
*script_global(4539659).as<bool*>() = true;
}
}

View File

@ -7,7 +7,9 @@ namespace big
{
g_script_patcher_service->add_patch({ RAGE_JOAAT("freemode"), "2D 01 08 00 ? 38 00 5D ? ? ? 2A 06", 5, {0x6E, 0x2E, 0x01, 0x01}, &g->session.decloak_players });
g_script_patcher_service->add_patch({ RAGE_JOAAT("freemode"), "2D 01 04 00 ? 2C ? ? ? 5D ? ? ? 6E 57 ? ? 2C", 5, { 0x2E, 0x01, 0x00 }, &g->protections.script_host_kick });
g_script_patcher_service->add_patch({ RAGE_JOAAT("freemode"), "2D 00 07 00 00 5D ? ? ? 56 ? ? 6E ", 5, { 0x2E, 0x00, 0x00 }, &g->tunables.no_idle_kick });
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("shop_controller"), "2D 01 04 00 00 2C ? ? ? 56 ? ? 6E ", 5, { 0x6E, 0x2E, 0x01, 0x01 }, nullptr }); // despawn bypass
for (auto& entry : *g_pointers->m_script_program_table)
{

View File

@ -111,7 +111,8 @@ namespace big
TRANSITION_STATE_WAITING_FOR_EXTERNAL_TERMINATION_CALL,
TRANSITION_STATE_TERMINATE_MAINTRANSITION,
TRANSITION_STATE_WAIT_FOR_DIRTY_LOAD_CONFIRM,
TRANSITION_STATE_DLC_INTRO_BINK
TRANSITION_STATE_DLC_INTRO_BINK,
TRANSITION_STATE_SPAWN_INTO_PERSONAL_VEHICLE
};
enum eVehicleFlags

View File

@ -143,6 +143,7 @@ namespace big
script_events script_events{};
bool script_host_kick = true;
bool rid_join = false;
};
struct self
@ -193,6 +194,7 @@ namespace big
bool log_chat_messages = false;
bool log_text_messages = false;
bool decloak_players = false;
bool force_session_host = false;
};
struct settings {
@ -563,6 +565,7 @@ namespace big
}
this->protections.script_host_kick = j["protections"]["script_host_kick"];
this->protections.rid_join = j["protections"]["rid_join"];
this->tunables.disable_phone = j["tunables"]["disable_phone"];
this->tunables.no_idle_kick = j["tunables"]["no_idle_kick"];
@ -598,6 +601,7 @@ namespace big
this->session.log_text_messages = j["session"]["log_text_messages"];
this->session.disable_chat_filter = j["session"]["disable_chat_filter"];
this->session.decloak_players = j["session"]["decloak_players"];
this->session.force_session_host = j["session"]["force_session_host"];
this->settings.dev_dlc = j["settings"]["dev_dlc"];
this->settings.hotkeys.menu_toggle = j["settings"]["hotkeys"]["menu_toggle"];
@ -846,7 +850,8 @@ namespace big
}
},
{ "script_host_kick", g->protections.script_host_kick }
{ "script_host_kick", g->protections.script_host_kick },
{ "rid_join", g->protections.rid_join }
}
},
{
@ -913,6 +918,7 @@ namespace big
{ "log_text_messages", this->session.log_text_messages },
{ "disable_chat_filter", this->session.disable_chat_filter },
{ "decloak_players", this->session.decloak_players },
{ "force_session_host", this->session.force_session_host }
}
},
{

View File

@ -65,4 +65,6 @@ namespace big::functions
using start_get_session_by_gamer_handle = bool(*)(int metric_manager, rage::rlGamerHandle* handles, int count, rage::rlSessionByGamerTaskResult* result, int unk, bool* success, int* state);
using join_session_by_info = bool(*)(Network* network, rage::rlSessionInfo* info, int unk, int flags, rage::rlGamerHandle* handles, int handlecount);
using generate_uuid = bool(*)(std::uint64_t* uuid);
}

View File

@ -671,94 +671,121 @@ enum class NetObjEntityType : uint16_t
enum class eNetworkEvents : uint16_t
{
CObjectIdFreedEvent,
CObjectIdRequestEvent,
CArrayDataVerifyEvent,
CScriptArrayDataVerifyEvent,
CRequestControlEvent,
CGiveControlEvent,
CWeaponDamageEvent,
CRequestPickupEvent,
CRequestMapPickupEvent,
CGameClockEvent,
CGameWeatherEvent,
CRespawnPlayerPedEvent,
CGiveWeaponEvent,
CRemoveWeaponEvent,
CRemoveAllWeaponsEvent,
CVehicleComponentControlEvent,
CFireEvent,
CExplosionEvent,
CStartProjectileEvent,
CUpdateProjectileTargetEvent,
CRemoveProjectileEntityEvent,
CBreakProjectileTargetLockEvent,
CAlterWantedLevelEvent,
CChangeRadioStationEvent,
CRagdollRequestEvent,
CPlayerTauntEvent,
CPlayerCardStatEvent,
CDoorBreakEvent,
CScriptedGameEvent,
CRemoteScriptInfoEvent,
CRemoteScriptLeaveEvent,
CMarkAsNoLongerNeededEvent,
CConvertToScriptEntityEvent,
CScriptWorldStateEvent,
CClearAreaEvent,
CClearRectangleAreaEvent,
CNetworkRequestSyncedSceneEvent,
CNetworkStartSyncedSceneEvent,
CNetworkStopSyncedSceneEvent,
CNetworkUpdateSyncedSceneEvent,
CIncidentEntityEvent,
CGivePedScriptedTaskEvent,
CGivePedSequenceTaskEvent,
CNetworkClearPedTasksEvent,
CNetworkStartPedArrestEvent,
CNetworkStartPedUncuffEvent,
CNetworkSoundCarHornEvent,
CNetworkEntityAreaStatusEvent,
CNetworkGarageOccupiedStatusEvent,
CPedConversationLineEvent,
CScriptEntityStateChangeEvent,
CNetworkPlaySoundEvent,
CNetworkStopSoundEvent,
CNetworkPlayAirdefenseFireEvent,
CNetworkBankRequestEvent,
CNetworkAudioBarkEvent,
CRequestDoorEvent,
CNetworkTrainReportEvent,
CNetworkTrainRequestEvent,
CNetworkIncrementStatEvent,
CModifyVehicleLockWordStateData,
CModifyPtfxWordStateDataScriptedEvolveEvent,
CRequestPhoneExplosionEvent,
CRequestDetachmentEvent,
CKickVotesEvent,
CGivePickupRewardsEvent,
CNetworkCrcHashCheckEvent,
CBlowUpVehicleEvent,
CNetworkSpecialFireEquippedWeapon,
CNetworkRespondedToThreatEvent,
CNetworkShoutTargetPosition,
CVoiceDrivenMouthMovementFinishedEvent,
CPickupDestroyedEvent,
CUpdatePlayerScarsEvent,
CNetworkCheckExeSizeEvent,
CNetworkPtfxEvent,
CNetworkPedSeenDeadPedEvent,
CRemoveStickyBombEvent,
CNetworkCheckCodeCrcsEvent,
CInformSilencedGunshotEvent,
CPedPlayPainEvent,
CCachePlayerHeadBlendDataEvent,
CRemovePedFromPedgroupEvent,
CUpdateFxnEvent,
CReportCashSpawnEvent,
CActivateVehicleSpecialAbilityEvent,
CBlockWeaponSelection,
CNetworkCheckCatalogCrc
OBJECT_ID_FREED_EVENT,
OBJECT_ID_REQUEST_EVENT,
ARRAY_DATA_VERIFY_EVENT,
SCRIPT_ARRAY_DATA_VERIFY_EVENT,
REQUEST_CONTROL_EVENT,
GIVE_CONTROL_EVENT,
WEAPON_DAMAGE_EVENT,
REQUEST_PICKUP_EVENT,
REQUEST_MAP_PICKUP_EVENT,
GAME_CLOCK_EVENT,
GAME_WEATHER_EVENT,
RESPAWN_PLAYER_PED_EVENT,
GIVE_WEAPON_EVENT,
REMOVE_WEAPON_EVENT,
REMOVE_ALL_WEAPONS_EVENT,
VEHICLE_COMPONENT_CONTROL_EVENT,
FIRE_EVENT,
EXPLOSION_EVENT,
START_PROJECTILE_EVENT,
UPDATE_PROJECTILE_TARGET_EVENT,
REMOVE_PROJECTILE_ENTITY_EVENT,
BREAK_PROJECTILE_TARGET_LOCK_EVENT,
ALTER_WANTED_LEVEL_EVENT,
CHANGE_RADIO_STATION_EVENT,
RAGDOLL_REQUEST_EVENT,
PLAYER_TAUNT_EVENT,
PLAYER_CARD_STAT_EVENT,
DOOR_BREAK_EVENT,
SCRIPTED_GAME_EVENT,
REMOTE_SCRIPT_INFO_EVENT,
REMOTE_SCRIPT_LEAVE_EVENT,
MARK_AS_NO_LONGER_NEEDED_EVENT,
CONVERT_TO_SCRIPT_ENTITY_EVENT,
SCRIPT_WORLD_STATE_EVENT,
CLEAR_AREA_EVENT,
CLEAR_RECTANGLE_AREA_EVENT,
NETWORK_REQUEST_SYNCED_SCENE_EVENT,
NETWORK_START_SYNCED_SCENE_EVENT,
NETWORK_STOP_SYNCED_SCENE_EVENT,
NETWORK_UPDATE_SYNCED_SCENE_EVENT,
INCIDENT_ENTITY_EVENT,
GIVE_PED_SCRIPTED_TASK_EVENT,
GIVE_PED_SEQUENCE_TASK_EVENT,
NETWORK_CLEAR_PED_TASKS_EVENT,
NETWORK_START_PED_ARREST_EVENT,
NETWORK_START_PED_UNCUFF_EVENT,
NETWORK_SOUND_CAR_HORN_EVENT,
NETWORK_ENTITY_AREA_STATUS_EVENT,
NETWORK_GARAGE_OCCUPIED_STATUS_EVENT,
PED_CONVERSATION_LINE_EVENT,
SCRIPT_ENTITY_STATE_CHANGE_EVENT,
NETWORK_PLAY_SOUND_EVENT,
NETWORK_STOP_SOUND_EVENT,
NETWORK_PLAY_AIRDEFENSE_FIRE_EVENT,
NETWORK_BANK_REQUEST_EVENT,
NETWORK_AUDIO_BARK_EVENT,
REQUEST_DOOR_EVENT,
NETWORK_TRAIN_REPORT_EVENT,
NETWORK_TRAIN_REQUEST_EVENT,
NETWORK_INCREMENT_STAT_EVENT,
MODIFY_VEHICLE_LOCK_WORD_STATE_DATA,
MODIFY_PTFX_WORD_STATE_DATA_SCRIPTED_EVOLVE_EVENT,
REQUEST_PHONE_EXPLOSION_EVENT,
REQUEST_DETACHMENT_EVENT,
KICK_VOTES_EVENT,
GIVE_PICKUP_REWARDS_EVENT,
NETWORK_CRC_HASH_CHECK_EVENT,
BLOW_UP_VEHICLE_EVENT,
NETWORK_SPECIAL_FIRE_EQUIPPED_WEAPON,
NETWORK_RESPONDED_TO_THREAT_EVENT,
NETWORK_SHOUT_TARGET_POSITION,
VOICE_DRIVEN_MOUTH_MOVEMENT_FINISHED_EVENT,
PICKUP_DESTROYED_EVENT,
UPDATE_PLAYER_SCARS_EVENT,
NETWORK_CHECK_EXE_SIZE_EVENT,
NETWORK_PTFX_EVENT,
NETWORK_PED_SEEN_DEAD_PED_EVENT,
REMOVE_STICKY_BOMB_EVENT,
NETWORK_CHECK_CODE_CRCS_EVENT,
INFORM_SILENCED_GUNSHOT_EVENT,
PED_PLAY_PAIN_EVENT,
CACHE_PLAYER_HEAD_BLEND_DATA_EVENT,
REMOVE_PED_FROM_PEDGROUP_EVENT,
REPORT_MYSELF_EVENT,
REPORT_CASH_SPAWN_EVENT,
ACTIVATE_VEHICLE_SPECIAL_ABILITY_EVENT,
BLOCK_WEAPON_SELECTION,
NETWORK_CHECK_CATALOG_CRC
};
enum class ScriptEntityChangeType
{
BlockingOfNonTemporaryEvents,
SettingOfPedRelationshipGroupHash,
SettingOfDriveTaskCruiseSpeed,
SettingOfLookAtEntity,
SettingOfPlaneMinHeightAboveTerrain,
SetPedRagdollBlockFlag,
SettingOfTaskVehicleTempAction,
SetPedFacialIdleAnimOverride,
SetVehicleLockState,
SetVehicleExclusiveDriver
};
enum class WorldStateDataType
{
CarGen,
EntityArea,
PopGroupOverride,
PopMultiplierArea,
PTFX,
RoadNode,
Rope,
ScenarioBlockingArea,
VehiclePlayerLocking
};
enum class BlipIcons

View File

@ -156,6 +156,17 @@ namespace rage
return T(val);
}
template<typename T>
inline T ReadSigned(int length)
{
static_assert(sizeof(T) <= 4, "maximum of 32 bit read");
int val = 0;
ReadInt32(&val, length);
return T(val);
}
public:
uint8_t* m_data; //0x0000
uint32_t m_bitOffset; //0x0008

View File

@ -15,16 +15,16 @@ namespace rage
virtual void assume_thread_identity(scrThread*) {}; // 1 (0x08)
// Returns whether the hash of the script id is valid.
virtual bool is_valid() {}; // 2 (0x10)
virtual bool is_valid() { return false; }; // 2 (0x10)
// Gets the hash of the script id.
virtual joaat_t *get_hash(joaat_t *out) {}; // 3 (0x18)
virtual joaat_t* get_hash(joaat_t* out) { return 0; }; // 3 (0x18)
// Gets an unknown value from the script id.
virtual std::uint32_t *get_hash2(std::uint32_t *out) {}; // 4 (0x20)
virtual std::uint32_t* get_hash2(std::uint32_t* out) { return 0; }; // 4 (0x20)
// Gets the name of the script id.
virtual const char *get_name() {}; // 5 (0x28)
virtual const char* get_name() { return nullptr; }; // 5 (0x28)
// Serializes the script id from the buffer.
virtual void deserialize(datBitBuffer* buffer) {}; // 6 (0x30)
@ -33,10 +33,10 @@ namespace rage
virtual void serialize(datBitBuffer* buffer) {}; // 7 (0x38)
// Calculates some information with the position hash & instance id.
virtual std::uint32_t _0x40() {}; // 8 (0x40)
virtual std::uint32_t _0x40() { return 0; }; // 8 (0x40)
// Calls _0x40 and returns it's value added to another value.
virtual std::uint32_t _0x48() {}; // 9 (0x48)
virtual std::uint32_t _0x48() { return 0; }; // 9 (0x48)
// Logs some information about the script id.
virtual void log_information(netLoggingInterface* logger) {}; // 10 (0x50)
@ -45,9 +45,9 @@ namespace rage
virtual void copy_data(scriptIdBase *other) {} // 11 (0x58)
// Returns whether the other script id is equal.
virtual bool operator==(scriptIdBase*) {}; // 12 (0x60)
virtual bool operator==(scriptIdBase*) { return false; }; // 12 (0x60)
virtual bool _0x68(void*) {}; // 13 (0x68)
virtual bool _0x68(void*) { return false; }; // 13 (0x68)
};
class scriptId : public scriptIdBase

View File

@ -46,8 +46,6 @@ namespace big
detour_hook_helper::add<hooks::network_player_mgr_init>("NPMI", g_pointers->m_network_player_mgr_init);
detour_hook_helper::add<hooks::network_player_mgr_shutdown>("NPMS", g_pointers->m_network_player_mgr_shutdown);
detour_hook_helper::add<hooks::network_group_override>("NGO", g_pointers->m_network_group_override);
detour_hook_helper::add<hooks::received_event>("RE", g_pointers->m_received_event);
detour_hook_helper::add<hooks::send_net_info_to_lobby>("SNITL", g_pointers->m_send_net_info_to_lobby);
@ -64,6 +62,9 @@ namespace big
detour_hook_helper::add<hooks::invalid_mods_crash_detour>("IMCD", g_pointers->m_invalid_mods_crash_detour);
detour_hook_helper::add<hooks::update_presence_attribute_int>("UPAI", g_pointers->m_update_presence_attribute_int);
detour_hook_helper::add<hooks::update_presence_attribute_string>("UPAS", g_pointers->m_update_presence_attribute_string);
g_hooking = this;
}

View File

@ -37,8 +37,6 @@ namespace big
static void network_player_mgr_init(CNetworkPlayerMgr* _this, std::uint64_t a2, std::uint32_t a3, std::uint32_t a4[4]);
static void network_player_mgr_shutdown(CNetworkPlayerMgr* _this);
static void network_group_override(std::int64_t a1, std::int64_t a2, std::int64_t a3);
static void received_event(
rage::netEventMgr* event_manager,
CNetGamePlayer* source_player,
@ -69,6 +67,9 @@ namespace big
static bool write_player_game_state_data_node(rage::netObject* player, CPlayerGameStateDataNode* node);
static void invalid_mods_crash_detour(int64_t a1, int64_t a2, int a3, char a4);
static bool update_presence_attribute_int(void* presence_data, int profile_index, char* attr, std::uint64_t value);
static bool update_presence_attribute_string(void* presence_data, int profile_index, char* attr, char* value);
};
class minhook_keepalive

View File

@ -1,5 +1,6 @@
#include "hooking.hpp"
#include "services/players/player_service.hpp"
#include <network/CNetworkPlayerMgr.hpp>
namespace big
{

View File

@ -1,4 +1,5 @@
#include "hooking.hpp"
#include <network/CNetGamePlayer.hpp>
namespace big
{

View File

@ -1,18 +0,0 @@
#include "hooking.hpp"
namespace big
{
// thanks ellisdudes :P
void hooks::network_group_override(std::int64_t a1, std::int64_t a2, std::int64_t a3)
{
if (a2 == 0 && (a3 == 103 || a3 == 0))
{
LOG(WARNING) << "Received SCRIPT_WORLD_STATE_EVENT crash from unknown attacker...";
return;
}
// original
return g_hooking->get_original<network_group_override>()(a1, a2, a3);
}
}

View File

@ -1,7 +1,8 @@
#include "hooking.hpp"
#include "services/players/player_service.hpp"
#include <natives.hpp>
#include "natives.hpp"
#include "gta_util.hpp"
#include <network/Network.hpp>
namespace big
{

View File

@ -21,6 +21,7 @@
#include "base/CBaseModelInfo.hpp"
#include "vehicle/CVehicleModelInfo.hpp"
#include "util/model_info.hpp"
#include "network/CNetGamePlayer.hpp"
#define CLASS_TO_MANGLED_NAME(c) "?AV"#c"@@"
namespace big

View File

@ -1,9 +1,23 @@
#include "gta/enums.hpp"
#include "gta/net_game_event.hpp"
#include "hooking.hpp"
#include <network/CNetGamePlayer.hpp>
#include "gta/script_id.hpp"
namespace big
{
static void script_id_deserialize(CGameScriptId& id, rage::datBitBuffer& buffer)
{
id.m_hash = buffer.Read<uint32_t>(32);
id.m_timestamp = buffer.Read<uint32_t>(32);
if (buffer.Read<bool>(1))
id.m_position_hash = buffer.Read<uint32_t>(32);
if (buffer.Read<bool>(1))
id.m_instance_id = buffer.Read<int32_t>(8);
}
void hooks::received_event(
rage::netEventMgr* event_manager,
CNetGamePlayer* source_player,
@ -31,22 +45,20 @@ namespace big
switch (static_cast<eNetworkEvents>(event_id))
{
case eNetworkEvents::CKickVotesEvent:
case eNetworkEvents::KICK_VOTES_EVENT:
{
std::uint32_t player_bitfield;
buffer->ReadDword(&player_bitfield, 32);
if (player_bitfield & 1 << target_player->m_player_id)
std::uint32_t player_bitfield = buffer->Read<uint32_t>(32);
if (player_bitfield & (1 << target_player->m_player_id))
{
if (g->notifications.received_event.kick_vote.log)
LOG(INFO) << "RECEIVED_EVENT_HANDLER : " << source_player->get_name() << " is voting to kick us.";
if (g->notifications.received_event.kick_vote.notify)
g_notification_service->push_warning("Kick Vote",
std::format("{} is voting to kick us.", source_player->get_name()));
g_notification_service->push_warning("Kick Vote", std::format("{} is voting to kick us.", source_player->get_name()));
}
buffer->Seek(0);
break;
}
case eNetworkEvents::CNetworkIncrementStatEvent:
case eNetworkEvents::NETWORK_INCREMENT_STAT_EVENT:
{
const auto increment_stat_event = std::make_unique<CNetworkIncrementStatEvent>();
buffer->ReadDword(&increment_stat_event->m_stat, 0x20);
@ -59,26 +71,24 @@ namespace big
buffer->Seek(0);
break;
}
case eNetworkEvents::CScriptEntityStateChangeEvent:
case eNetworkEvents::SCRIPT_ENTITY_STATE_CHANGE_EVENT:
{
uint16_t entity;
buffer->ReadWord(&entity, 13);
uint32_t type;
buffer->ReadDword(&type, 4);
uint32_t unk;
buffer->ReadDword(&unk, 32);
if (type == 6) {
uint16_t unk2;
buffer->ReadWord(&unk2, 13);
uint32_t action;
buffer->ReadDword(&action, 8);
if (action >= 15 && action <= 18) {
uint16_t entity = buffer->Read<uint16_t>(13);
auto type = buffer->Read<ScriptEntityChangeType>(4);
uint32_t unk = buffer->Read<uint32_t>(32);
if (type == ScriptEntityChangeType::SettingOfTaskVehicleTempAction)
{
uint16_t unk2 = buffer->Read<uint16_t>(13);
uint32_t action = buffer->Read<uint32_t>(8);
if (action >= 15 && action <= 18)
{
g_pointers->m_send_event_ack(event_manager, source_player, target_player, event_index, event_handled_bitset);
if (g->notifications.received_event.vehicle_temp_action.log)
LOG(INFO) << "RECEIVED_EVENT_HANDLER : " << source_player->get_name() << " sent TASK_VEHICLE_TEMP_ACTION crash.";
if (g->notifications.received_event.vehicle_temp_action.notify)
g_notification_service->push_warning("Protection",
std::format("{} sent TASK_VEHICLE_TEMP_ACTION crash.", source_player->get_name()));
g_notification_service->push_error("Protections", std::format("{} sent TASK_VEHICLE_TEMP_ACTION crash.", source_player->get_name()));
return;
}
@ -86,7 +96,7 @@ namespace big
buffer->Seek(0);
break;
}
case eNetworkEvents::CScriptedGameEvent:
case eNetworkEvents::SCRIPTED_GAME_EVENT:
{
const auto scripted_game_event = std::make_unique<CScriptedGameEvent>();
buffer->ReadDword(&scripted_game_event->m_args_size, 32);
@ -103,28 +113,47 @@ namespace big
break;
}
case eNetworkEvents::CNetworkClearPedTasksEvent:
case eNetworkEvents::NETWORK_CLEAR_PED_TASKS_EVENT:
{
if (source_player->m_player_id < 32)
int net_id = buffer->Read<int>(13);
if (g_local_player && g_local_player->m_net_object && g_local_player->m_net_object->m_object_id == net_id)
{
g_pointers->m_send_event_ack(event_manager, source_player, target_player, event_index, event_handled_bitset);
if (g->notifications.received_event.clear_ped_task.log)
LOG(INFO) << "RECEIVED_EVENT_HANDLER : " << source_player->get_name() << " sent CLEAR_PED_TASKS event.";
if (g->notifications.received_event.clear_ped_task.notify)
g_notification_service->push_warning("Protection",
std::format("{} possible attempt at freezing entity.", source_player->get_name())
);
g_notification_service->push_warning("Protections", std::format("{} tried to freeze player.", source_player->get_name()));
return;
}
buffer->Seek(0);
break;
}
case eNetworkEvents::RAGDOLL_REQUEST_EVENT:
{
int net_id = buffer->Read<int>(13);
if (g_local_player && g_local_player->m_net_object && g_local_player->m_net_object->m_object_id == net_id)
{
g_pointers->m_send_event_ack(event_manager, source_player, target_player, event_index, event_handled_bitset);
if (g->notifications.received_event.clear_ped_task.log)
LOG(INFO) << "RECEIVED_EVENT_HANDLER : " << source_player->get_name() << " sent RAGDOLL_REQUEST event.";
if (g->notifications.received_event.clear_ped_task.notify)
g_notification_service->push_warning("Protections", std::format("{} tried to ragdoll player.", source_player->get_name()));
return;
}
buffer->Seek(0);
break;
}
// Don't block this event, we still want to report this player
// because if we still report others, our account seems less fishy
case eNetworkEvents::CReportCashSpawnEvent:
case eNetworkEvents::REPORT_CASH_SPAWN_EVENT:
{
uint32_t money;
@ -136,42 +165,118 @@ namespace big
{
if (g->notifications.received_event.report_cash_spawn.log)
LOG(INFO) << "RECEIVED_EVENT_HANDLER : " << source_player->get_name() << " sent REPORT_CASH_SPAWN event.";
if (g->notifications.received_event.report_cash_spawn.notify)
g_notification_service->push_warning("Protection",
std::format("{} is spawning cash.", source_player->get_name())
);
g_notification_service->push_warning("Protections", std::format("{} is spawning cash.", source_player->get_name()));
}
break;
}
// player sending this event is a modder
case eNetworkEvents::CNetworkCheckCodeCrcsEvent:
case eNetworkEvents::CUpdateFxnEvent:
case eNetworkEvents::NETWORK_CHECK_CODE_CRCS_EVENT:
case eNetworkEvents::REPORT_MYSELF_EVENT:
{
if (g->notifications.received_event.modder_detect.log)
LOG(INFO) << "RECEIVED_EVENT_HANDLER : " << source_player->get_name() << " sent modder event.";
if (g->notifications.received_event.modder_detect.notify)
g_notification_service->push_warning("Protection",
std::format("{} sent out a modder event.", source_player->get_name())
);
g_notification_service->push_warning("Protections", std::format("{} sent out a modder event.", source_player->get_name()));
break;
}
case eNetworkEvents::CRequestControlEvent:
case eNetworkEvents::REQUEST_CONTROL_EVENT:
{
g_pointers->m_send_event_ack(event_manager, source_player, target_player, event_index, event_handled_bitset);
int net_id = buffer->Read<int>(13);
if (g_local_player && g_local_player->m_vehicle && g_local_player->m_vehicle->m_net_object && g_local_player->m_vehicle->m_net_object->m_object_id == net_id)
{
g_pointers->m_send_event_ack(event_manager, source_player, target_player, event_index, event_handled_bitset);
if (g->notifications.received_event.request_control_event.log)
LOG(INFO) << "RECEIVED_EVENT_HANDLER : " << source_player->get_name() << " sent modder event.";
if (g->notifications.received_event.request_control_event.log)
LOG(INFO) << "RECEIVED_EVENT_HANDLER : " << source_player->get_name() << " requested control of player vehicle.";
if (g->notifications.received_event.request_control_event.notify)
g_notification_service->push_warning("Protections", std::format("Denied player control request from {}", source_player->get_name()));
if (g->notifications.received_event.request_control_event.notify)
g_notification_service->push_warning("Protection",
std::format("Denied player control request from {}", source_player->get_name())
);
return;
}
buffer->Seek(0);
break;
}
case eNetworkEvents::SCRIPT_WORLD_STATE_EVENT:
{
auto type = buffer->Read<WorldStateDataType>(4);
(void)buffer->Read<bool>(1);
CGameScriptId id;
script_id_deserialize(id, *buffer);
return;
if (type == WorldStateDataType::Rope)
{
buffer->Read<int>(9); // unk
buffer->Read<float>(19); // pos x
buffer->Read<float>(19); // pos y
buffer->Read<float>(19); // pos z
buffer->Read<float>(19); // rot x
buffer->Read<float>(19); // rot y
buffer->Read<float>(19); // rot z
buffer->Read<float>(16); // length
int type = buffer->Read<int>(4);
if (type != 7)
{
// most definitely a crash
g_notification_service->push_error("Protections", std::format("{} sent rope crash.", source_player->get_name()));
g_pointers->m_send_event_ack(event_manager, source_player, target_player, event_index, event_handled_bitset);
return;
}
}
else if (type == WorldStateDataType::PopGroupOverride)
{
int unk = buffer->ReadSigned<int>(8);
int unk2 = buffer->Read<int>(32);
int unk3 = buffer->Read<int>(7);
if (unk2 == 0 && (unk3 == 0 || unk3 == 103))
{
g_notification_service->push_error("Protections", std::format("{} sent SCRIPT_WORLD_STATE_EVENT crash.", source_player->get_name()));
g_pointers->m_send_event_ack(event_manager, source_player, target_player, event_index, event_handled_bitset);
return;
}
}
buffer->Seek(0);
break;
}
case eNetworkEvents::REMOVE_WEAPON_EVENT:
{
int net_id = buffer->Read<int>(13);
uint32_t hash = buffer->Read<uint32_t>(32);
if (hash == RAGE_JOAAT("WEAPON_UNARMED"))
{
g_pointers->m_send_event_ack(event_manager, source_player, target_player, event_index, event_handled_bitset);
return;
}
if (g_local_player && g_local_player->m_net_object && g_local_player->m_net_object->m_object_id == net_id)
{
g_notification_service->push_warning("Protections", std::format("{} tried to remove a weapon.", source_player->get_name()));
g_pointers->m_send_event_ack(event_manager, source_player, target_player, event_index, event_handled_bitset);
return;
}
buffer->Seek(0);
break;
}
case eNetworkEvents::REMOVE_ALL_WEAPONS_EVENT:
{
int net_id = buffer->Read<int>(13);
if (g_local_player && g_local_player->m_net_object && g_local_player->m_net_object->m_object_id == net_id)
{
g_notification_service->push_warning("Protections", std::format("{} tried to remove all weapons.", source_player->get_name()));
g_pointers->m_send_event_ack(event_manager, source_player, target_player, event_index, event_handled_bitset);
return;
}
buffer->Seek(0);
break;
}
default:
break;

View File

@ -1,5 +1,6 @@
#include "hooking.hpp"
#include "gta_util.hpp"
#include <network/CNetGamePlayer.hpp>
namespace big
{
@ -333,7 +334,6 @@ namespace big
break;
}
if (g->debug.logs.script_event.logs && (!g->debug.logs.script_event.filter_player || g->debug.logs.script_event.player_id == player->m_player_id))
{
std::string script_args = "{ ";

View File

@ -0,0 +1,27 @@
#include "hooking.hpp"
namespace big
{
bool hooks::update_presence_attribute_int(void* presence_data, int profile_index, char* attr, std::uint64_t value)
{
auto hash = rage::joaat(attr);
if (g->protections.rid_join &&
(hash == RAGE_JOAAT("gstok") || hash == RAGE_JOAAT("gsid") || hash == RAGE_JOAAT("gstype") || hash == RAGE_JOAAT("gshost") || hash == RAGE_JOAAT("gsjoin")))
{
return true;
}
return g_hooking->get_original<hooks::update_presence_attribute_int>()(presence_data, profile_index, attr, value);
}
bool hooks::update_presence_attribute_string(void* presence_data, int profile_index, char* attr, char* value)
{
auto hash = rage::joaat(attr);
if (g->protections.rid_join && hash == RAGE_JOAAT("gsinfo"))
{
return true;
}
return g_hooking->get_original<hooks::update_presence_attribute_string>()(presence_data, profile_index, attr, value);
}
}

View File

@ -134,7 +134,7 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID)
LOG(INFO) << "Thread pool uninitialized.";
script_patcher_service_instance.reset();
LOG(INFO) << "Script patcher service reset.";
LOG(INFO) << "Script Patcher Service reset.";
gui_service_instance.reset();
LOG(INFO) << "Gui Service reset.";
gta_data_service_instance.reset();

View File

@ -296,12 +296,6 @@ namespace big
m_write_player_gamer_data_node = ptr.as<PVOID>();
});
// Network Group Override
main_batch.add("NGO", "44 89 81 ? ? ? ? 89 91 ? ? ? ? C6 05", [this](memory::handle ptr)
{
m_network_group_override = ptr.as<PVOID>();
});
// Receive Net Message
main_batch.add("RNM", "48 83 EC 20 4C 8B 71 50 33 ED", [this](memory::handle ptr)
{
@ -446,9 +440,51 @@ namespace big
m_script_vm = ptr.add(1).rip().as<PVOID>();
});
// Generate UUID
main_batch.add("GU", "E8 ? ? ? ? 84 C0 74 0C 48 8B 44 24 ? 48 89 03", [this](memory::handle ptr)
{
m_generate_uuid = ptr.add(1).rip().as<functions::generate_uuid>();
});
// Host Token
main_batch.add("HT", "48 8B 05 ? ? ? ? 48 83 F8 FF", [this](memory::handle ptr)
{
m_host_token = ptr.add(3).rip().as<std::uint64_t*>();
});
// Profile Gamer Info
main_batch.add("PGI", "48 8D 05 ? ? ? ? 48 8B FE", [this](memory::handle ptr)
{
m_profile_gamer_info = ptr.add(3).rip().as<rage::rlGamerInfo*>();
});
// Player Info Gamer Info
main_batch.add("PIGI", "E8 ? ? ? ? 48 8D 4D 20 48 8B D0 E8 ? ? ? ? 41 8A CF", [this](memory::handle ptr)
{
m_player_info_gamer_info = ptr.add(1).rip().add(3).rip().as<rage::rlGamerInfo*>();
});
// Communications
main_batch.add("C", "48 8B 1D ? ? ? ? 48 8D 4C 24 30", [this](memory::handle ptr)
{
m_communications = ptr.add(3).rip().as<CCommunications**>();
});
auto mem_region = memory::module(nullptr);
main_batch.run(mem_region);
memory::batch socialclub_batch;
// Presence Data
socialclub_batch.add("PD", "48 8D 05 ? ? ? ? 48 8B F1 48 89 01 48 8D 99 88 02", [this](memory::handle ptr)
{
auto presence_data_vft = ptr.add(3).rip().as<PVOID*>();
m_update_presence_attribute_int = presence_data_vft[1];
m_update_presence_attribute_string = presence_data_vft[3];
});
socialclub_batch.run(memory::module("socialclub.dll"));
if (auto pat = mem_region.scan("41 80 78 28 ? 0F 85 F5 01 00 00"))
{
m_bypass_max_count_of_active_sticky_bombs = pat.add(4).as<uint8_t*>();

View File

@ -4,11 +4,13 @@
#include "function_types.hpp"
#include "gta/fwddec.hpp"
#include "gta/replay.hpp"
#include "network/CNetworkPlayerMgr.hpp"
#include "socialclub/FriendRegistry.hpp"
#include "network/Network.hpp"
#include "memory/byte_patch.hpp"
class CCommunications;
class FriendRegistry;
class CNetworkPlayerMgr;
class Network;
namespace big
{
class pointers
@ -54,7 +56,6 @@ namespace big
PVOID m_model_spawn_bypass;
PVOID m_world_model_spawn_bypass;
PVOID m_native_return;
PVOID m_network_group_override;
PVOID m_get_label_text;
functions::multiplayer_chat_filter* m_multiplayer_chat_filter{};
functions::write_player_game_state_data_node m_write_player_game_state_data_node{};
@ -139,6 +140,15 @@ namespace big
PVOID m_init_native_tables{};
PVOID m_script_vm{};
functions::generate_uuid m_generate_uuid{};
std::uint64_t* m_host_token{};
rage::rlGamerInfo* m_profile_gamer_info{}; // per profile gamer info
rage::rlGamerInfo* m_player_info_gamer_info{}; // the gamer info that is applied to CPlayerInfo
CCommunications** m_communications{};
PVOID m_update_presence_attribute_int;
PVOID m_update_presence_attribute_string;
};
inline pointers* g_pointers{};

View File

@ -1,5 +1,7 @@
#include "friends_service.hpp"
#include "pointers.hpp"
#include <network/CNetGamePlayer.hpp>
#include <socialclub/FriendRegistry.hpp>
namespace big
{

View File

@ -2,6 +2,7 @@
#include "network/CNetGamePlayer.hpp"
#include "services/friends/friends_service.hpp"
#include "gta_util.hpp"
#include <network/Network.hpp>
namespace big
{

View File

@ -1,5 +1,6 @@
#include "gta_util.hpp"
#include "player_service.hpp"
#include <network/CNetworkPlayerMgr.hpp>
namespace big
{

View File

@ -17,6 +17,9 @@ namespace big
{
}
script_data(const script_data& that) = delete;
script_data& operator=(const script_data& that) = delete;
~script_data()
{
for (auto i = 0u; i < m_num_pages; i++)
@ -25,6 +28,7 @@ namespace big
}
delete[] m_bytecode;
m_bytecode = nullptr;
}
};
}

View File

@ -5,6 +5,18 @@
namespace big
{
script_patcher_service::script_patcher_service()
{
g_script_patcher_service = this;
}
script_patcher_service::~script_patcher_service()
{
m_script_data.clear();
m_script_patches.clear();
g_script_patcher_service = nullptr;
}
script_data* script_patcher_service::get_data_for_script(rage::joaat_t script)
{
for (auto& p : m_script_data)
@ -31,7 +43,7 @@ namespace big
void script_patcher_service::create_data_for_script(rage::scrProgram* program)
{
auto pages = new std::uint8_t * [program->get_num_code_pages()];
auto pages = new std::uint8_t *[program->get_num_code_pages()];
for (auto i = 0u; i < program->get_num_code_pages(); i++)
{
@ -51,16 +63,6 @@ namespace big
p.update(data);
}
script_patcher_service::script_patcher_service()
{
g_script_patcher_service = this;
}
script_patcher_service::~script_patcher_service()
{
g_script_patcher_service = nullptr;
}
void script_patcher_service::add_patch(script_patch&& patch)
{
m_script_patches.push_back(std::move(patch));

View File

@ -25,9 +25,4 @@ namespace big::globals
g_pointers->m_trigger_script_event(1, args, arg_count, 1 << target);
}
inline void disable_kill_trigger(bool toggle)
{
*script_global(2815059).at(6753).as<int*>() = toggle; // "TRI_WARP" 2nd nested if statement below this text in freemode.c
}
}

View File

@ -18,7 +18,7 @@ namespace big
static ImColor health_red = ImColor(0.69f, 0.29f, 0.29f, 1.f);
void esp::draw_player(const player_ptr& plyr, ImDrawList* const draw_list) {
if (g->esp.hide_self && plyr->is_valid() && plyr->id() == gta_util::get_network_player_mgr()->m_local_net_player->m_player_id ||
if (g->esp.hide_self && plyr->is_valid() && plyr->id() == g_player_service->get_self()->id() ||
!plyr->is_valid() ||
!plyr->get_ped() ||
!plyr->get_ped()->m_navigation) return;

View File

@ -47,5 +47,10 @@ namespace big
components::sub_title("Decloak");
components::script_patch_checkbox("Reveal OTR Players", &g->session.decloak_players);
components::sub_title("Force Host");
ImGui::Checkbox("Force Session Host", &g->session.force_session_host);
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Join another session to apply changes. The original host of the session must leave or be kicked. This feature is easily detectable by other mod menus, use with caution");
}
}

View File

@ -1,6 +1,7 @@
#include "views/view.hpp"
#include "fiber_pool.hpp"
#include "util/teleport.hpp"
#include <network/ClanData.hpp>
namespace big
{

View File

@ -44,6 +44,9 @@ namespace big
ImGui::Checkbox("Teleport To Warehouse", &g->protections.script_events.teleport_to_warehouse);
ImGui::Checkbox("Start Activity", &g->protections.script_events.start_activity);
components::script_patch_checkbox("Script Host Kick", &g->protections.script_host_kick);
ImGui::Checkbox("RID Join", &g->protections.rid_join);
if (ImGui::IsItemHovered())
ImGui::SetTooltip("This will block anyone trying to join you through Rockstar ID, including your friends");
ImGui::EndGroup();
}