2021-05-25 12:58:33 +02:00
# include "gta/enums.hpp"
# include "gta/net_game_event.hpp"
# include "hooking.hpp"
2022-11-13 16:34:44 +00:00
# include <network/CNetGamePlayer.hpp>
# include "gta/script_id.hpp"
2022-11-19 01:49:36 +00:00
# include "util/notify.hpp"
2022-11-21 15:42:12 +00:00
# include <base/CObject.hpp>
2021-05-25 12:58:33 +02:00
namespace big
{
2022-11-13 16:34:44 +00:00
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 ) ;
}
2022-11-21 15:42:12 +00:00
void scan_explosion_event ( CNetGamePlayer * player , rage : : datBitBuffer * buffer )
{
uint16_t f186 ;
uint16_t f208 ;
int ownerNetId ;
uint16_t f214 ;
eExplosionTag explosionType ;
float damageScale ;
float posX ;
float posY ;
float posZ ;
bool f242 ;
uint16_t f104 ;
float cameraShake ;
bool isAudible ;
bool f189 ;
bool isInvisible ;
bool f126 ;
bool f241 ;
bool f243 ;
uint16_t f210 ;
float unkX ;
float unkY ;
float unkZ ;
bool f190 ;
bool f191 ;
uint32_t f164 ;
float posX224 ;
float posY224 ;
float posZ224 ;
bool f240 ;
uint16_t f218 ;
bool f216 ;
f186 = buffer - > Read < uint16_t > ( 16 ) ;
f208 = buffer - > Read < uint16_t > ( 13 ) ;
ownerNetId = buffer - > Read < uint16_t > ( 13 ) ;
f214 = buffer - > Read < uint16_t > ( 13 ) ; // 1604+
explosionType = ( eExplosionTag ) buffer - > ReadSigned < int > ( 8 ) ; // 1604+ bit size
damageScale = buffer - > Read < int > ( 8 ) / 255.0f ;
posX = buffer - > ReadSignedFloat ( 22 , 27648.0f ) ;
posY = buffer - > ReadSignedFloat ( 22 , 27648.0f ) ;
posZ = buffer - > ReadFloat ( 22 , 4416.0f ) - 1700.0f ;
f242 = buffer - > Read < uint8_t > ( 1 ) ;
f104 = buffer - > Read < uint16_t > ( 16 ) ;
cameraShake = buffer - > Read < int > ( 8 ) / 127.0f ;
isAudible = buffer - > Read < uint8_t > ( 1 ) ;
f189 = buffer - > Read < uint8_t > ( 1 ) ;
isInvisible = buffer - > Read < uint8_t > ( 1 ) ;
f126 = buffer - > Read < uint8_t > ( 1 ) ;
f241 = buffer - > Read < uint8_t > ( 1 ) ;
f243 = buffer - > Read < uint8_t > ( 1 ) ; // 1604+
f210 = buffer - > Read < uint16_t > ( 13 ) ;
unkX = buffer - > ReadSignedFloat ( 16 , 1.1f ) ;
unkY = buffer - > ReadSignedFloat ( 16 , 1.1f ) ;
unkZ = buffer - > ReadSignedFloat ( 16 , 1.1f ) ;
f190 = buffer - > Read < uint8_t > ( 1 ) ;
f191 = buffer - > Read < uint8_t > ( 1 ) ;
f164 = buffer - > Read < uint32_t > ( 32 ) ;
if ( f242 )
{
posX224 = buffer - > ReadSignedFloat ( 31 , 27648.0f ) ;
posY224 = buffer - > ReadSignedFloat ( 31 , 27648.0f ) ;
posZ224 = buffer - > ReadFloat ( 31 , 4416.0f ) - 1700.0f ;
}
else
{
posX224 = 0 ;
posY224 = 0 ;
posZ224 = 0 ;
}
auto f168 = buffer - > Read < uint32_t > ( 32 ) ; // >= 1868: f_168
f240 = buffer - > Read < uint8_t > ( 1 ) ;
if ( f240 )
{
f218 = buffer - > Read < uint16_t > ( 16 ) ;
if ( f191 )
{
f216 = buffer - > Read < uint8_t > ( 8 ) ;
}
}
buffer - > Seek ( 0 ) ;
auto object = g_pointers - > m_get_net_object ( * g_pointers - > m_network_object_mgr , ownerNetId , true ) ;
auto entity = object ? object - > GetGameObject ( ) : nullptr ;
if ( f208 = = 0 & & entity & & entity - > gap28 = = 4 & & reinterpret_cast < CPed * > ( entity ) - > m_player_info & & player - > m_player_info - > m_ped & & player - > m_player_info - > m_ped - > m_net_object & & ownerNetId ! = player - > m_player_info - > m_ped - > m_net_object - > m_object_id )
{
g_notification_service - > push_error ( " Warning! " , std : : format ( " {} blamed {} for explosion " , player - > get_name ( ) , reinterpret_cast < CPed * > ( entity ) - > m_player_info - > m_net_player_data . m_name ) ) ;
session : : add_infraction ( g_player_service - > get_by_id ( player - > m_player_id ) , Infraction : : BLAME_EXPLOSION_DETECTED ) ;
}
}
2022-05-10 21:59:03 +02:00
void hooks : : received_event (
2021-05-25 12:58:33 +02:00
rage : : netEventMgr * event_manager ,
CNetGamePlayer * source_player ,
CNetGamePlayer * target_player ,
uint16_t event_id ,
int event_index ,
int event_handled_bitset ,
2022-11-10 19:21:38 -05:00
int buffer_size ,
2022-05-08 22:00:55 +02:00
rage : : datBitBuffer * buffer
2021-05-25 12:58:33 +02:00
)
{
2022-05-08 22:00:55 +02:00
if ( event_id > 91u )
{
g_pointers - > m_send_event_ack ( event_manager , source_player , target_player , event_index , event_handled_bitset ) ;
2022-05-10 21:59:03 +02:00
return ;
2022-05-08 22:00:55 +02:00
}
2021-05-25 12:58:33 +02:00
2022-05-08 22:00:55 +02:00
const auto event_name = * ( char * * ) ( ( DWORD64 ) event_manager + 8 i64 * event_id + 243376 ) ;
2022-01-30 00:23:26 +01:00
if ( event_name = = nullptr | | source_player = = nullptr | | source_player - > m_player_id < 0 | | source_player - > m_player_id > = 32 )
2021-05-25 12:58:33 +02:00
{
g_pointers - > m_send_event_ack ( event_manager , source_player , target_player , event_index , event_handled_bitset ) ;
2022-05-10 21:59:03 +02:00
return ;
2021-05-25 12:58:33 +02:00
}
2022-07-05 16:54:45 -04:00
switch ( static_cast < eNetworkEvents > ( event_id ) )
2021-05-25 12:58:33 +02:00
{
2022-11-13 16:34:44 +00:00
case eNetworkEvents : : KICK_VOTES_EVENT :
2022-07-28 20:19:07 +02:00
{
2022-11-13 16:34:44 +00:00
std : : uint32_t player_bitfield = buffer - > Read < uint32_t > ( 32 ) ;
if ( player_bitfield & ( 1 < < target_player - > m_player_id ) )
2022-07-28 20:19:07 +02:00
{
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 )
2022-11-13 16:34:44 +00:00
g_notification_service - > push_warning ( " Kick Vote " , std : : format ( " {} is voting to kick us. " , source_player - > get_name ( ) ) ) ;
2022-07-28 20:19:07 +02:00
}
buffer - > Seek ( 0 ) ;
break ;
}
2022-11-13 16:34:44 +00:00
case eNetworkEvents : : NETWORK_INCREMENT_STAT_EVENT :
2022-07-05 18:58:12 +02:00
{
const auto increment_stat_event = std : : make_unique < CNetworkIncrementStatEvent > ( ) ;
buffer - > ReadDword ( & increment_stat_event - > m_stat , 0x20 ) ;
buffer - > ReadDword ( & increment_stat_event - > m_amount , 0x20 ) ;
if ( hooks : : increment_stat_event ( increment_stat_event . get ( ) , source_player ) )
{
g_pointers - > m_send_event_ack ( event_manager , source_player , target_player , event_index , event_handled_bitset ) ;
return ;
}
buffer - > Seek ( 0 ) ;
break ;
}
2022-11-13 16:34:44 +00:00
case eNetworkEvents : : SCRIPT_ENTITY_STATE_CHANGE_EVENT :
2022-05-10 20:23:48 +02:00
{
2022-11-13 16:34:44 +00:00
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 )
{
2022-12-02 02:37:58 +08:00
uint16_t ped_id = buffer - > Read < uint16_t > ( 13 ) ;
2022-11-13 16:34:44 +00:00
uint32_t action = buffer - > Read < uint32_t > ( 8 ) ;
2022-11-19 01:49:36 +00:00
if ( ( action > = 15 & & action < = 18 ) | | action = = 33 )
2022-11-13 16:34:44 +00:00
{
2022-05-10 20:23:48 +02:00
g_pointers - > m_send_event_ack ( event_manager , source_player , target_player , event_index , event_handled_bitset ) ;
2022-11-19 01:49:36 +00:00
notify : : crash_blocked ( source_player , " vehicle temp action " ) ;
2022-05-10 21:59:03 +02:00
return ;
2022-05-10 20:23:48 +02:00
}
}
buffer - > Seek ( 0 ) ;
break ;
}
2022-11-13 16:34:44 +00:00
case eNetworkEvents : : SCRIPTED_GAME_EVENT :
2022-05-08 22:00:55 +02:00
{
const auto scripted_game_event = std : : make_unique < CScriptedGameEvent > ( ) ;
buffer - > ReadDword ( & scripted_game_event - > m_args_size , 32 ) ;
if ( scripted_game_event - > m_args_size - 1 < = 0x1AF )
buffer - > ReadArray ( & scripted_game_event - > m_args , 8 * scripted_game_event - > m_args_size ) ;
if ( hooks : : scripted_game_event ( scripted_game_event . get ( ) , source_player ) )
{
g_pointers - > m_send_event_ack ( event_manager , source_player , target_player , event_index , event_handled_bitset ) ;
2022-05-10 21:59:03 +02:00
return ;
2022-05-08 22:00:55 +02:00
}
2022-05-10 17:06:00 +02:00
buffer - > Seek ( 0 ) ;
2022-05-08 22:00:55 +02:00
break ;
}
2022-11-13 16:34:44 +00:00
case eNetworkEvents : : NETWORK_CLEAR_PED_TASKS_EVENT :
2021-05-25 12:58:33 +02:00
{
2022-11-13 16:34:44 +00:00
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 )
2021-05-25 12:58:33 +02:00
{
g_pointers - > m_send_event_ack ( event_manager , source_player , target_player , event_index , event_handled_bitset ) ;
2022-03-21 18:10:18 +01:00
if ( g - > notifications . received_event . clear_ped_task . log )
LOG ( INFO ) < < " RECEIVED_EVENT_HANDLER : " < < source_player - > get_name ( ) < < " sent CLEAR_PED_TASKS event. " ;
2022-11-13 16:34:44 +00:00
if ( g - > notifications . received_event . clear_ped_task . notify )
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 ) ;
2022-03-21 18:10:18 +01:00
2022-11-13 16:34:44 +00:00
if ( g - > notifications . received_event . clear_ped_task . log )
LOG ( INFO ) < < " RECEIVED_EVENT_HANDLER : " < < source_player - > get_name ( ) < < " sent RAGDOLL_REQUEST event. " ;
2022-03-21 18:10:18 +01:00
if ( g - > notifications . received_event . clear_ped_task . notify )
2022-11-13 16:34:44 +00:00
g_notification_service - > push_warning ( " Protections " , std : : format ( " {} tried to ragdoll player. " , source_player - > get_name ( ) ) ) ;
2021-05-25 12:58:33 +02:00
2022-05-10 21:59:03 +02:00
return ;
2021-05-25 12:58:33 +02:00
}
2022-11-13 16:34:44 +00:00
buffer - > Seek ( 0 ) ;
2021-05-25 12:58:33 +02:00
break ;
}
// Don't block this event, we still want to report this player
// because if we still report others, our account seems less fishy
2022-11-13 16:34:44 +00:00
case eNetworkEvents : : REPORT_CASH_SPAWN_EVENT :
2021-05-25 12:58:33 +02:00
{
uint32_t money ;
buffer - > Seek ( 64 ) ;
buffer - > ReadDword ( & money , 32 ) ;
buffer - > Seek ( 0 ) ;
if ( money > = 2000 )
{
2022-03-21 18:10:18 +01:00
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 )
2022-11-13 16:34:44 +00:00
g_notification_service - > push_warning ( " Protections " , std : : format ( " {} is spawning cash. " , source_player - > get_name ( ) ) ) ;
2021-05-25 12:58:33 +02:00
}
break ;
}
2021-07-23 12:27:07 +02:00
// player sending this event is a modder
2022-11-13 16:34:44 +00:00
case eNetworkEvents : : REPORT_MYSELF_EVENT :
2021-05-25 12:58:33 +02:00
{
2022-03-21 18:10:18 +01:00
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 )
2022-11-13 16:34:44 +00:00
g_notification_service - > push_warning ( " Protections " , std : : format ( " {} sent out a modder event. " , source_player - > get_name ( ) ) ) ;
2021-05-25 12:58:33 +02:00
2022-11-19 01:49:36 +00:00
if ( auto plyr = g_player_service - > get_by_id ( source_player - > m_player_id ) )
session : : add_infraction ( plyr , Infraction : : TRIGGERED_ANTICHEAT ) ;
2021-05-25 12:58:33 +02:00
break ;
}
2022-11-13 16:34:44 +00:00
case eNetworkEvents : : REQUEST_CONTROL_EVENT :
2021-08-03 20:30:16 +02:00
{
2022-11-13 16:34:44 +00:00
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 ) ;
2021-05-25 12:58:33 +02:00
2022-11-13 16:34:44 +00:00
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 ( ) ) ) ;
2021-05-25 12:58:33 +02:00
2022-11-13 16:34:44 +00:00
return ;
}
buffer - > Seek ( 0 ) ;
break ;
}
case eNetworkEvents : : SCRIPT_WORLD_STATE_EVENT :
{
auto type = buffer - > Read < WorldStateDataType > ( 4 ) ;
2022-11-19 01:49:36 +00:00
buffer - > Read < bool > ( 1 ) ;
2022-11-13 16:34:44 +00:00
CGameScriptId id ;
script_id_deserialize ( id , * buffer ) ;
2021-05-25 12:58:33 +02:00
2022-11-13 16:34:44 +00:00
if ( type = = WorldStateDataType : : Rope )
{
2022-12-02 02:37:58 +08:00
buffer - > Read < int > ( 9 ) ; // network rope id
2022-11-13 16:34:44 +00:00
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
2022-11-19 01:49:36 +00:00
LOG ( INFO ) < < std : : hex < < std : : uppercase < < " 0x " < < id . m_hash ;
notify : : crash_blocked ( source_player , " rope " ) ;
2022-11-13 16:34:44 +00:00
g_pointers - > m_send_event_ack ( event_manager , source_player , target_player , event_index , event_handled_bitset ) ;
return ;
}
}
else if ( type = = WorldStateDataType : : PopGroupOverride )
{
2022-12-02 02:37:58 +08:00
int pop_schedule = buffer - > ReadSigned < int > ( 8 ) ; // Pop Schedule
int pop_group = buffer - > Read < int > ( 32 ) ; // Pop Group
int percentage = buffer - > Read < int > ( 7 ) ; // Percentage
2022-11-13 16:34:44 +00:00
2022-12-02 02:37:58 +08:00
if ( pop_group = = 0 & & ( percentage = = 0 | | percentage = = 103 ) )
2022-11-13 16:34:44 +00:00
{
2022-11-19 01:49:36 +00:00
notify : : crash_blocked ( source_player , " pop group override " ) ;
2022-11-13 16:34:44 +00:00
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 " ) )
{
2022-11-19 01:49:36 +00:00
notify : : crash_blocked ( source_player , " remove unarmed " ) ;
2022-11-13 16:34:44 +00:00
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 ;
2022-03-21 18:10:18 +01:00
}
2022-11-19 01:49:36 +00:00
case eNetworkEvents : : GIVE_CONTROL_EVENT :
{
uint32_t timestamp = buffer - > Read < uint32_t > ( 32 ) ;
int count = buffer - > Read < int > ( 2 ) ;
2022-12-02 02:37:58 +08:00
bool all_objects_migrate_together = buffer - > Read < bool > ( 1 ) ;
2022-11-19 01:49:36 +00:00
if ( count > 3 )
{
count = 3 ;
}
for ( int i = 0 ; i < count ; i + + )
{
int net_id = buffer - > Read < int > ( 13 ) ;
eNetObjType object_type = buffer - > Read < eNetObjType > ( 4 ) ;
2022-12-02 02:37:58 +08:00
int migration_type = buffer - > Read < int > ( 3 ) ;
2022-11-19 01:49:36 +00:00
if ( object_type < eNetObjType : : NET_OBJ_TYPE_AUTOMOBILE | | object_type > eNetObjType : : NET_OBJ_TYPE_TRAIN )
{
notify : : crash_blocked ( source_player , " out of bounds give control type " ) ;
g_pointers - > m_send_event_ack ( event_manager , source_player , target_player , event_index , event_handled_bitset ) ;
return ;
}
}
buffer - > Seek ( 0 ) ;
g - > m_syncing_player = source_player ;
break ;
}
2022-11-21 15:42:12 +00:00
case eNetworkEvents : : NETWORK_PLAY_SOUND_EVENT :
{
auto plyr = g_player_service - > get_by_id ( source_player - > m_player_id ) ;
if ( plyr - > m_play_sound_rate_limit . process ( ) )
{
if ( plyr - > m_play_sound_rate_limit . exceeded_last_process ( ) )
{
notify : : crash_blocked ( source_player , " sound spam " ) ;
}
g_pointers - > m_send_event_ack ( event_manager , source_player , target_player , event_index , event_handled_bitset ) ;
return ;
}
break ;
}
case eNetworkEvents : : EXPLOSION_EVENT :
{
scan_explosion_event ( source_player , buffer ) ;
break ;
}
2022-07-05 18:58:12 +02:00
default :
break ;
2021-05-25 12:58:33 +02:00
}
2022-11-10 19:21:38 -05:00
return g_hooking - > get_original < received_event > ( ) ( event_manager , source_player , target_player , event_id , event_index , event_handled_bitset , buffer_size , buffer ) ;
2021-05-25 12:58:33 +02:00
}
2022-10-30 19:32:51 +01:00
}