mirror of
https://github.com/YimMenu/YimMenuV2.git
synced 2026-10-10 03:43:15 +08:00
feat(net_events): net event protections (#45)
This commit is contained in:
@@ -281,6 +281,14 @@ namespace YimMenu
|
||||
return GetNetworkObject() != nullptr;
|
||||
}
|
||||
|
||||
bool Entity::IsRemote()
|
||||
{
|
||||
if (!IsNetworked())
|
||||
return false;
|
||||
|
||||
return GetNetworkObject()->m_IsRemote;
|
||||
}
|
||||
|
||||
rage::netObject* Entity::GetNetworkObject()
|
||||
{
|
||||
if (!IsValid())
|
||||
|
||||
@@ -114,6 +114,7 @@ namespace YimMenu
|
||||
|
||||
// networking
|
||||
bool IsNetworked();
|
||||
bool IsRemote();
|
||||
bool HasControl();
|
||||
rage::netObject* GetNetworkObject();
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
class CNetworkPlayerMgr;
|
||||
class CNetGamePlayer;
|
||||
class CProjectBaseSyncDataNode;
|
||||
class CScriptedGameEvent;
|
||||
namespace rage
|
||||
{
|
||||
class netConnectionManager;
|
||||
@@ -60,8 +61,8 @@ namespace YimMenu::Hooks
|
||||
namespace Network
|
||||
{
|
||||
extern void ReceiveNetMessage(void* a1, rage::netConnectionManager* mgr, rage::netEvent* event);
|
||||
extern void ReceiveEvent(YimMenu::Player& player, uint16_t event_id, uint32_t event_index, uint32_t event_handled_bitset, rage::datBitBuffer& buffer);
|
||||
extern bool HandleScriptedGameEvent(YimMenu::Player& player, int64_t* args, uint32_t args_size);
|
||||
extern void ReceiveNetGameEvent(Player player, uint16_t event_id, uint32_t event_index, uint32_t event_handled_bits, rage::datBitBuffer& buffer);
|
||||
extern bool HandleScriptedGameEvent(Player player, CScriptedGameEvent& event);
|
||||
}
|
||||
|
||||
namespace Window
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
#include "core/util/Joaat.hpp"
|
||||
#include "game/backend/Self.hpp"
|
||||
#include "game/gta/Natives.hpp"
|
||||
#include "game/hooks/Hooks.hpp"
|
||||
#include "game/pointers/Pointers.hpp"
|
||||
#include "types/network/CNetGamePlayer.hpp"
|
||||
#include "types/network/NetEventType.hpp"
|
||||
#include "types/network/netGameEvent.hpp"
|
||||
#include "types/rage/datBitBuffer.hpp"
|
||||
#include "types/script/globals/GlobalPlayerBD.hpp"
|
||||
|
||||
namespace YimMenu::Hooks
|
||||
{
|
||||
@@ -19,16 +21,118 @@ namespace YimMenu::Hooks
|
||||
*reinterpret_cast<std::uint32_t*>(0x118LL * event_index + (uint64_t)event_mgr + 4 * source_player->m_PlayerIndex + 0x458) = event_handled_bits;
|
||||
}
|
||||
|
||||
static bool HandleNetGameEvent(Player& player, uint16_t event_id, rage::datBitBuffer& buffer)
|
||||
// Returns true if bad event
|
||||
bool ScanExplosionEvent(CExplosionEvent& event, Player player)
|
||||
{
|
||||
switch (static_cast<NetEventType>(event_id))
|
||||
if (*(int16_t*)&event.m_InteriorIndex < -1)
|
||||
{
|
||||
case NetEventType::WEAPON_DAMAGE_EVENT:
|
||||
{
|
||||
uint8_t damage_type = buffer.Read<uint8_t>(2);
|
||||
uint32_t weapon_type = buffer.Read<uint32_t>(32);
|
||||
LOG(INFO) << "blocked invalid interior crash from " << player.GetName();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (weapon_type == "WEAPON_TRANQUILIZER"_J)
|
||||
if (event.m_IsInvisible)
|
||||
{
|
||||
float dist = event.m_Position.GetDistance(Self::GetPed().GetPosition());
|
||||
if (event.m_CameraShake > 0.0f && dist <= 30.0f)
|
||||
{
|
||||
// Camera shake
|
||||
return true;
|
||||
}
|
||||
|
||||
if (event.m_DamageScale > 0.0f && dist <= 10.0f)
|
||||
{
|
||||
// Ragdoll
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// more?
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ScanPlaySoundEvent(CPlaySoundEvent& event, Player player)
|
||||
{
|
||||
static constexpr std::array blocked_ref_hashes = {"Arena_Vehicle_Mod_Shop_Sounds"_J, "CELEBRATION_SOUNDSET"_J, "DLC_AW_Arena_Office_Planning_Wall_Sounds"_J, "DLC_AW_Arena_Spin_Wheel_Game_Frontend_Sounds"_J, "DLC_Biker_SYG_Sounds"_J, "DLC_BTL_SECURITY_VANS_RADAR_PING_SOUNDS"_J, "DLC_BTL_Target_Pursuit_Sounds"_J, "DLC_GR_Bunker_Door_Sounds"_J, "DLC_GR_CS2_Sounds"_J, "DLC_IO_Warehouse_Mod_Garage_Sounds"_J, "DLC_MPSUM2_HSW_Up_Sounds"_J, "DLC_sum20_Business_Battle_AC_Sounds"_J, "DLC_TG_Running_Back_Sounds"_J, "dlc_vw_table_games_frontend_sounds"_J, "dlc_xm_facility_entry_exit_sounds"_J, "Frontend"_J, "GTAO_Boss_Goons_FM_Soundset"_J, "GTAO_Exec_SecuroServ_Computer_Sounds"_J, "GTAO_Exec_SecuroServ_Warehouse_PC_Sounds"_J, "GTAO_Script_Doors_Faded_Screen_Sounds"_J, "GTAO_SMG_Hangar_Computer_Sounds"_J, "HUD_AMMO_SHOP_SOUNDSET"_J, "HUD_FRONTEND_CUSTOM_SOUNDSET"_J, "HUD_FRONTEND_DEFAULT_SOUNDSET"_J, "HUD_FRONTEND_MP_SOUNDSET"_J, "HUD_FRONTEND_MP_COLLECTABLE_SOUNDS"_J, "HUD_FRONTEND_TATTOO_SHOP_SOUNDSET"_J, "HUD_FRONTEND_CLOTHESSHOP_SOUNDSET"_J, "HUD_FRONTEND_STANDARD_PICKUPS_NPC_SOUNDSET"_J, "HUD_FRONTEND_VEHICLE_PICKUPS_NPC_SOUNDSET"_J, "HUD_FRONTEND_WEAPONS_PICKUPS_NPC_SOUNDSET"_J, "HUD_FREEMODE_SOUNDSET"_J, "HUD_MINI_GAME_SOUNDSET"_J, "HUD_AWARDS"_J, "JA16_Super_Mod_Garage_Sounds"_J, "Low2_Super_Mod_Garage_Sounds"_J, "MissionFailedSounds"_J, "MP_CCTV_SOUNDSET"_J, "MP_LOBBY_SOUNDS"_J, "MP_MISSION_COUNTDOWN_SOUNDSET"_J, "Phone_SoundSet_Default"_J, "Phone_SoundSet_Glasses_Cam"_J, "Phone_SoundSet_Prologue"_J, "Phone_SoundSet_Franklin"_J, "Phone_SoundSet_Michael"_J, "Phone_SoundSet_Trevor"_J, "PLAYER_SWITCH_CUSTOM_SOUNDSET"_J, "RESPAWN_ONLINE_SOUNDSET"_J, "TATTOOIST_SOUNDS"_J, "WastedSounds"_J, "WEB_NAVIGATION_SOUNDS_PHONE"_J};
|
||||
static constexpr std::array blocked_sound_hashes = {"Remote_Ring"_J, "COP_HELI_CAM_ZOOM"_J, "Object_Dropped_Remote"_J};
|
||||
static constexpr std::array blocked_script_hashes = {"main_persistent"_J, "shop_controller"_J};
|
||||
|
||||
if (std::ranges::contains(blocked_ref_hashes, event.m_RefHash)
|
||||
|| std::ranges::contains(blocked_sound_hashes, event.m_SoundHash)
|
||||
|| std::ranges::contains(blocked_script_hashes, event.m_ScriptId.m_Hash))
|
||||
return true;
|
||||
|
||||
switch (event.m_SoundHash)
|
||||
{
|
||||
case "DLC_XM_Explosions_Orbital_Cannon"_J:
|
||||
{
|
||||
if (event.m_IsEntity)
|
||||
return true;
|
||||
|
||||
if (event.m_ScriptId.m_Hash != "am_mp_defunct_base"_J && event.m_ScriptId.m_Hash != "am_mp_orbital_cannon"_J
|
||||
&& event.m_ScriptId.m_Hash != "fm_mission_controller_2020"_J && event.m_ScriptId.m_Hash != "fm_mission_controller"_J)
|
||||
return true;
|
||||
|
||||
if (!GlobalPlayerBD::Get()->Entries[player.GetId()].OrbitalBitset.IsSet(eOrbitalBitset::kOrbitalCannonActive))
|
||||
return true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (event.m_RefHash)
|
||||
{
|
||||
case "GTAO_Biker_Modes_Soundset"_J:
|
||||
case "DLC_Biker_Sell_Postman_Sounds"_J:
|
||||
{
|
||||
if (event.m_IsEntity)
|
||||
return true;
|
||||
|
||||
if (event.m_ScriptId.m_Hash != "gb_biker_contraband_sell"_J)
|
||||
return true;
|
||||
|
||||
break;
|
||||
}
|
||||
case "DLC_AW_General_Sounds"_J:
|
||||
{
|
||||
if (event.m_SoundHash != "Airhorn_Blast_Long"_J)
|
||||
return true;
|
||||
|
||||
if (event.m_ScriptId.m_Hash != "gb_casino_heist"_J)
|
||||
return true;
|
||||
|
||||
break;
|
||||
}
|
||||
case "GTAO_FM_Events_Soundset"_J:
|
||||
{
|
||||
if (!event.m_IsEntity)
|
||||
return true;
|
||||
|
||||
if (event.m_SoundHash != "Explosion_Countdown"_J)
|
||||
return true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ShouldAllowNetEvent(Player player, uint16_t event_id, rage::datBitBuffer& buffer)
|
||||
{
|
||||
switch (static_cast<rage::netGameEvent::Type>(event_id))
|
||||
{
|
||||
case rage::netGameEvent::Type::REQUEST_CONTROL_EVENT:
|
||||
{
|
||||
// TODO
|
||||
break;
|
||||
}
|
||||
case rage::netGameEvent::Type::WEAPON_DAMAGE_EVENT:
|
||||
{
|
||||
CWeaponDamageEvent event;
|
||||
event.Deserialize(buffer);
|
||||
|
||||
if (event.m_WeaponType == "WEAPON_TRANQUILIZER"_J)
|
||||
{
|
||||
LOG(INFO) << "blocked this thing from " << player.GetName();
|
||||
//player.AddDetection();
|
||||
@@ -37,18 +141,177 @@ namespace YimMenu::Hooks
|
||||
|
||||
break;
|
||||
}
|
||||
case NetEventType::SCRIPTED_GAME_EVENT:
|
||||
case rage::netGameEvent::Type::EXPLOSION_EVENT:
|
||||
{
|
||||
int64_t args[54]{};
|
||||
uint32_t args_size = buffer.Read<uint32_t>(32);
|
||||
CExplosionEvent event;
|
||||
event.Deserialize(buffer);
|
||||
|
||||
if (args_size > sizeof(args))
|
||||
if (ScanExplosionEvent(event, player))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case rage::netGameEvent::Type::CHANGE_RADIO_STATION_EVENT:
|
||||
{
|
||||
uint16_t veh_id = buffer.Read<uint16_t>(13);
|
||||
|
||||
Vehicle self_veh = Self::GetVehicle();
|
||||
Vehicle sender_veh = player.GetPed().GetVehicle();
|
||||
|
||||
if (self_veh && self_veh.GetNetworkObjectId() == veh_id && sender_veh && sender_veh.GetNetworkObjectId() != veh_id)
|
||||
{
|
||||
// Vehicle takeover
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case rage::netGameEvent::Type::DOOR_BREAK_EVENT:
|
||||
{
|
||||
// never used for legitimate reasons
|
||||
|
||||
return false;
|
||||
}
|
||||
case rage::netGameEvent::Type::SCRIPTED_GAME_EVENT:
|
||||
{
|
||||
CScriptedGameEvent event;
|
||||
|
||||
if (!event.Deserialize(buffer))
|
||||
return false;
|
||||
|
||||
buffer.ReadArray(args, 8 * args_size);
|
||||
|
||||
if (!Network::HandleScriptedGameEvent(player, args, args_size))
|
||||
if (!Network::HandleScriptedGameEvent(player, event))
|
||||
return false;
|
||||
|
||||
break;
|
||||
}
|
||||
case rage::netGameEvent::Type::SCRIPT_WORLD_STATE_EVENT:
|
||||
{
|
||||
auto type = buffer.Read<CScriptWorldStateEvent::Type>(4);
|
||||
buffer.Read<bool>(1);
|
||||
CGameScriptId id;
|
||||
id.Deserialize(buffer);
|
||||
|
||||
if (type == CScriptWorldStateEvent::Type::PopGroupOverride)
|
||||
{
|
||||
int pop_schedule = buffer.Read<int>(8);
|
||||
int pop_group = buffer.Read<int>(32);
|
||||
int percentage = buffer.Read<int>(7);
|
||||
|
||||
if (pop_group == 0 && (percentage == 0 || percentage == 103))
|
||||
{
|
||||
// pop group override crash
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (type == CScriptWorldStateEvent::Type::PopMultiplierArea && !NETWORK::NETWORK_IS_ACTIVITY_SESSION())
|
||||
{
|
||||
// Stop traffic
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case rage::netGameEvent::Type::SCRIPT_ENTITY_STATE_CHANGE_EVENT:
|
||||
{
|
||||
uint16_t entity = buffer.Read<uint16_t>(13);
|
||||
auto type = buffer.Read<CScriptEntityStateChangeEvent::Type>(4);
|
||||
uint32_t unk = buffer.Read<uint32_t>(32);
|
||||
|
||||
if (type == CScriptEntityStateChangeEvent::Type::SettingOfTaskVehicleTempAction)
|
||||
{
|
||||
uint16_t veh_id = buffer.Read<uint16_t>(13);
|
||||
uint32_t action = buffer.Read<uint32_t>(8);
|
||||
|
||||
if (action >= 15 && action <= 18)
|
||||
{
|
||||
// vehicle temp action crash
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Self::GetPed().GetNetworkObjectId() == entity)
|
||||
{
|
||||
// Ped takeover
|
||||
return false;
|
||||
}
|
||||
|
||||
Vehicle self_veh = Self::GetVehicle();
|
||||
if (self_veh && self_veh.GetNetworkObjectId() == veh_id)
|
||||
{
|
||||
// Vehicle takeover
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (type == CScriptEntityStateChangeEvent::Type::SetVehicleLockState)
|
||||
{
|
||||
Vehicle self_veh = Self::GetVehicle();
|
||||
if (self_veh && self_veh.GetNetworkObjectId() == entity)
|
||||
{
|
||||
LOGF(WARNING, "Blocked SCRIPT_ENTITY_STATE_CHANGE_EVENT of type SetVehicleLockState from {} on our local vehicle", player.GetName());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (type == CScriptEntityStateChangeEvent::Type::SetVehicleExclusiveDriver)
|
||||
{
|
||||
Vehicle self_veh = Self::GetVehicle();
|
||||
if (self_veh && self_veh.GetNetworkObjectId() == entity)
|
||||
{
|
||||
// Vehicle kick
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (type == CScriptEntityStateChangeEvent::Type::SetPedFacialIdleAnimOverride)
|
||||
{
|
||||
if (Self::GetPed().GetNetworkObjectId() == entity)
|
||||
{
|
||||
LOGF(WARNING, "Blocked SCRIPT_ENTITY_STATE_CHANGE_EVENT of type SetPedFacialIdleAnimOverride from {} on our local player", player.GetName());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (type > CScriptEntityStateChangeEvent::Type::SetVehicleExclusiveDriver)
|
||||
{
|
||||
// invalid script entity change type crash
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case rage::netGameEvent::Type::NETWORK_PLAY_SOUND_EVENT:
|
||||
{
|
||||
CPlaySoundEvent event;
|
||||
event.Deserialize(buffer);
|
||||
|
||||
if (ScanPlaySoundEvent(event, player))
|
||||
{
|
||||
LOGF(WARNING, "Blocked NETWORK_PLAY_SOUND_EVENT from {} with IsEntity: {}, RefHash: {:X}, SoundHash: {:X}, SoundId: {}, ScriptHash: {:X}", player.GetName(), event.m_IsEntity, event.m_RefHash, event.m_SoundHash, event.m_SoundId, event.m_ScriptId.m_Hash);
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case rage::netGameEvent::Type::REPORT_MYSELF_EVENT:
|
||||
{
|
||||
CUpdateFxnEvent event;
|
||||
event.Deserialize(buffer);
|
||||
|
||||
if (event.m_0x30 != 6) // false positives when telemetry endpoint is unreachable
|
||||
{
|
||||
// Triggered anti cheat
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case rage::netGameEvent::Type::ACTIVATE_VEHICLE_SPECIAL_ABILITY_EVENT:
|
||||
{
|
||||
CActivateVehicleSpecialAbilityEvent event;
|
||||
event.Deserialize(buffer);
|
||||
|
||||
if (Self::GetPed().GetVehicleObjectId() == event.m_VehicleId && !Self::GetVehicle().IsRemote())
|
||||
{
|
||||
// Vehicle takeover
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -59,9 +322,9 @@ namespace YimMenu::Hooks
|
||||
return true;
|
||||
}
|
||||
|
||||
void Network::ReceiveEvent(Player& player, uint16_t event_id, uint32_t event_index, uint32_t event_handled_bits, rage::datBitBuffer& buffer)
|
||||
void Network::ReceiveNetGameEvent(Player player, uint16_t event_id, uint32_t event_index, uint32_t event_handled_bits, rage::datBitBuffer& buffer)
|
||||
{
|
||||
if (!HandleNetGameEvent(player, event_id, buffer))
|
||||
if (!ShouldAllowNetEvent(player, event_id, buffer))
|
||||
SendEventAck(*Pointers.NetEventMgr, player.GetHandle(), Self::GetPlayer().GetHandle(), event_index, event_handled_bits);
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,15 @@
|
||||
#include "game/backend/Self.hpp"
|
||||
#include "game/hooks/Hooks.hpp"
|
||||
#include "game/pointers/Pointers.hpp"
|
||||
#include "types/network/netGameEvent.hpp"
|
||||
#include "types/script/globals/GPBD_FM_3.hpp"
|
||||
#include "types/script/ScriptEvent.hpp"
|
||||
|
||||
namespace YimMenu::Hooks
|
||||
{
|
||||
bool Network::HandleScriptedGameEvent(YimMenu::Player& player, int64_t* args, uint32_t args_size)
|
||||
bool Network::HandleScriptedGameEvent(Player player, CScriptedGameEvent& event)
|
||||
{
|
||||
SCRIPT_EVENT* script_event = reinterpret_cast<SCRIPT_EVENT*>(args);
|
||||
SCRIPT_EVENT* script_event = reinterpret_cast<SCRIPT_EVENT*>(event.m_Args);
|
||||
|
||||
switch (static_cast<ScriptEventIndex>(script_event->GetEventIndex()))
|
||||
{
|
||||
@@ -15,7 +17,7 @@ namespace YimMenu::Hooks
|
||||
{
|
||||
SCRIPT_EVENT_BOUNTY* bounty = static_cast<SCRIPT_EVENT_BOUNTY*>(script_event);
|
||||
|
||||
if (args_size != SCRIPT_EVENT_BOUNTY::GetSize())
|
||||
if (event.m_ArgsSize != SCRIPT_EVENT_BOUNTY::GetSize())
|
||||
{
|
||||
//player.AddDetection();
|
||||
return false;
|
||||
@@ -33,6 +35,15 @@ namespace YimMenu::Hooks
|
||||
//player.AddDetection();
|
||||
return false;
|
||||
}
|
||||
case ScriptEventIndex::CeoKick:
|
||||
{
|
||||
if (player.GetId() != GPBD_FM_3::Get()->Entries[Self::GetPlayer().GetId()].BossGoon.Boss)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ namespace YimMenu::Hooks
|
||||
rage::datBitBuffer event_buffer(event_data, sizeof(event_data), true);
|
||||
event_buffer.m_MaxBit = event_data_size + 1;
|
||||
|
||||
ReceiveEvent(player, event_id, event_index, event_handled_bits, event_buffer);
|
||||
ReceiveNetGameEvent(player, event_id, event_index, event_handled_bits, event_buffer);
|
||||
|
||||
remaining -= (int)buffer.m_BitsRead - bits_read;
|
||||
}
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
enum class NetEventType : uint16_t
|
||||
{
|
||||
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,
|
||||
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
|
||||
};
|
||||
@@ -0,0 +1,230 @@
|
||||
#include "netGameEvent.hpp"
|
||||
#include "types/fx/ExplosionType.hpp"
|
||||
#include "types/rage/datBitBuffer.hpp"
|
||||
|
||||
bool CScriptedGameEvent::Deserialize(rage::datBitBuffer& buffer)
|
||||
{
|
||||
m_ArgsSize = buffer.Read<uint32_t>(32);
|
||||
|
||||
if (m_ArgsSize > sizeof(m_Args))
|
||||
return false;
|
||||
|
||||
buffer.ReadArray(m_Args, 8 * m_ArgsSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CNetworkIncrementStatEvent::Deserialize(rage::datBitBuffer& buffer)
|
||||
{
|
||||
m_Stat = buffer.Read<uint32_t>(32);
|
||||
m_Amount = buffer.Read<uint32_t>(32, true);
|
||||
}
|
||||
|
||||
void CDoorBreakEvent::Deserialize(rage::datBitBuffer& buffer)
|
||||
{
|
||||
m_VehicleId = buffer.Read<uint16_t>(13);
|
||||
m_DoorId = buffer.Read<uint8_t>(3);
|
||||
}
|
||||
|
||||
void CPlaySoundEvent::Deserialize(rage::datBitBuffer& buffer)
|
||||
{
|
||||
m_IsEntity = buffer.Read<bool>(1);
|
||||
|
||||
if (m_IsEntity)
|
||||
{
|
||||
m_EntityId = buffer.Read<uint16_t>(13);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Position = buffer.ReadPosition(19);
|
||||
}
|
||||
|
||||
bool has_ref = buffer.Read<bool>(1);
|
||||
if (has_ref)
|
||||
{
|
||||
m_RefHash = buffer.Read<uint32_t>(32);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_RefHash = 0;
|
||||
}
|
||||
|
||||
m_SoundHash = buffer.Read<uint32_t>(32);
|
||||
m_SoundId = buffer.Read<uint8_t>(8);
|
||||
|
||||
bool has_script_hash = buffer.Read<bool>(1);
|
||||
if (has_script_hash)
|
||||
{
|
||||
m_ScriptId.Deserialize(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ScriptId.m_Hash = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CWeaponDamageEvent::Deserialize(rage::datBitBuffer& buffer)
|
||||
{
|
||||
m_DamageType = buffer.Read<uint8_t>(2);
|
||||
m_WeaponType = buffer.Read<uint32_t>(32);
|
||||
m_OverrideDefaultDamage = buffer.Read<bool>(1);
|
||||
m_HitEntityWeapon = buffer.Read<bool>(1);
|
||||
m_HitWeaponAmmoAttachment = buffer.Read<bool>(1);
|
||||
m_Silenced = buffer.Read<bool>(1);
|
||||
m_DamageFlags = buffer.Read<uint32_t>(25);
|
||||
|
||||
bool hasActionResult = buffer.Read<bool>(1);
|
||||
if (hasActionResult)
|
||||
{
|
||||
m_ActionResultName = buffer.Read<uint32_t>(32);
|
||||
m_ActionResultId = buffer.Read<uint16_t>(16);
|
||||
m_0x6C = buffer.Read<uint32_t>(32);
|
||||
}
|
||||
|
||||
if (m_OverrideDefaultDamage)
|
||||
{
|
||||
m_WeaponDamage = buffer.Read<uint32_t>(17);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_WeaponDamage = 0;
|
||||
}
|
||||
|
||||
bool _f92 = buffer.Read<uint8_t>(1);
|
||||
if (_f92)
|
||||
{
|
||||
m_0x5C = buffer.Read<uint8_t>(5);
|
||||
}
|
||||
|
||||
m_IsNetTargetPos = buffer.Read<uint8_t>(1);
|
||||
|
||||
if (m_IsNetTargetPos)
|
||||
{
|
||||
m_LocalPos.x = buffer.ReadSignedFloat(16, 90.f);
|
||||
m_LocalPos.y = buffer.ReadSignedFloat(16, 90.f);
|
||||
m_LocalPos.z = buffer.ReadSignedFloat(16, 90.f);
|
||||
}
|
||||
|
||||
if (m_DamageType == 3)
|
||||
{
|
||||
m_DamageTime = buffer.Read<uint32_t>(32);
|
||||
m_WillKill = buffer.Read<bool>(1);
|
||||
|
||||
if (hasActionResult)
|
||||
{
|
||||
m_HitGlobalId = buffer.Read<uint16_t>(13);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_HitGlobalId = 0;
|
||||
}
|
||||
|
||||
bool f112 = buffer.Read<bool>(1);
|
||||
if (f112)
|
||||
{
|
||||
m_0x74 = buffer.Read<uint16_t>(16);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_0x74 = buffer.Read<uint16_t>(11);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ParentGlobalId = buffer.Read<uint16_t>(13);
|
||||
m_HitGlobalId = buffer.Read<uint16_t>(13);
|
||||
}
|
||||
|
||||
if (m_DamageType < 2)
|
||||
{
|
||||
m_LocalPos.x = buffer.ReadSignedFloat(16, 90.f);
|
||||
m_LocalPos.y = buffer.ReadSignedFloat(16, 90.f);
|
||||
m_LocalPos.z = buffer.ReadSignedFloat(16, 90.f);
|
||||
|
||||
if (m_DamageType == 1)
|
||||
{
|
||||
bool hasVehicleData = buffer.Read<bool>(1);
|
||||
|
||||
if (hasVehicleData)
|
||||
{
|
||||
m_TyreIndex = buffer.Read<uint8_t>(4);
|
||||
m_SuspensionIndex = buffer.Read<uint8_t>(4);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_HitComponent = buffer.Read<int>(5);
|
||||
}
|
||||
|
||||
m_0x89 = buffer.Read<bool>(1);
|
||||
m_HasImpactDir = buffer.Read<bool>(1);
|
||||
|
||||
if (m_HasImpactDir)
|
||||
{
|
||||
m_ImpactDir.x = buffer.ReadSignedFloat(16, 6.2831855f);
|
||||
m_ImpactDir.y = buffer.ReadSignedFloat(16, 6.2831855f);
|
||||
m_ImpactDir.z = buffer.ReadSignedFloat(16, 6.2831855f);
|
||||
}
|
||||
}
|
||||
|
||||
void CActivateVehicleSpecialAbilityEvent::Deserialize(rage::datBitBuffer& buffer)
|
||||
{
|
||||
m_VehicleId = buffer.Read<uint16_t>(13);
|
||||
m_AbilityType = buffer.Read<uint32_t>(3);
|
||||
}
|
||||
|
||||
void CExplosionEvent::Deserialize(rage::datBitBuffer& buffer)
|
||||
{
|
||||
m_0xBA = buffer.Read<uint16_t>(16);
|
||||
m_TargetEntity = buffer.Read<uint16_t>(13);
|
||||
m_OwnerNetId = buffer.Read<uint16_t>(13);
|
||||
m_UnkNetId = buffer.Read<uint16_t>(13);
|
||||
m_ExplosionType = buffer.Read<ExplosionType>(8, true);
|
||||
m_DamageScale = buffer.ReadFloat(8, 1.0f);
|
||||
m_Position = buffer.ReadPosition(22);
|
||||
m_0xF2 = buffer.Read<bool>(1);
|
||||
m_0x68 = buffer.Read<uint32_t>(16);
|
||||
m_CameraShake = buffer.ReadSignedFloat(8, 1.0f);
|
||||
m_IsAudible = buffer.Read<bool>(1);
|
||||
m_0xBD = buffer.Read<bool>(1);
|
||||
m_IsInvisible = buffer.Read<bool>(1);
|
||||
m_0x7E = buffer.Read<bool>(1);
|
||||
m_AddOwnedExplosion = buffer.Read<bool>(1);
|
||||
m_0xF1 = buffer.Read<bool>(1);
|
||||
m_HasTargetEnt2 = buffer.Read<bool>(1);
|
||||
m_TargetEnt2 = buffer.Read<uint16_t>(13);
|
||||
m_0x80 = buffer.ReadVector3(16, 1.1f);
|
||||
m_0xBE = buffer.Read<bool>(1);
|
||||
m_0xBF = buffer.Read<bool>(1);
|
||||
m_0xA4 = buffer.Read<uint32_t>(32);
|
||||
m_InteriorIndex = buffer.Read<uint32_t>(32);
|
||||
|
||||
if (m_0xF2)
|
||||
{
|
||||
m_PositionUnk = buffer.ReadPosition(31);
|
||||
}
|
||||
|
||||
m_0xF0 = buffer.Read<bool>(1);
|
||||
|
||||
if (m_AddOwnedExplosion)
|
||||
{
|
||||
m_ScriptHash = buffer.Read<uint32_t>(32);
|
||||
m_ProgramCounter = buffer.Read<uint32_t>(32);
|
||||
}
|
||||
|
||||
if (m_0xF0)
|
||||
{
|
||||
m_0xDA = buffer.Read<uint16_t>(16);
|
||||
|
||||
if (m_0xBF)
|
||||
{
|
||||
m_0xD8 = buffer.Read<uint8_t>(8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CUpdateFxnEvent::Deserialize(rage::datBitBuffer& buffer)
|
||||
{
|
||||
m_0x30 = buffer.Read<uint32_t>(32);
|
||||
m_0x34 = buffer.Read<uint32_t>(32);
|
||||
}
|
||||
@@ -0,0 +1,343 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include "types/rage/vector.hpp"
|
||||
#include "types/script/CGameScriptId.hpp"
|
||||
|
||||
namespace rage
|
||||
{
|
||||
class datBitBuffer;
|
||||
class netPlayer;
|
||||
|
||||
class netGameEvent
|
||||
{
|
||||
public:
|
||||
enum class Type : uint16_t
|
||||
{
|
||||
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,
|
||||
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
|
||||
};
|
||||
|
||||
virtual ~netGameEvent() = default;
|
||||
|
||||
virtual const char* GetName() = 0;
|
||||
virtual bool IsInScope(netPlayer* player) = 0;
|
||||
virtual bool TimeToResend(uint32_t time) = 0;
|
||||
virtual bool CanChangeScope() = 0;
|
||||
virtual void PrepareData(datBitBuffer* buffer, netPlayer* source_player, netPlayer* target_player) {};
|
||||
virtual void HandleData(datBitBuffer* buffer, netPlayer* source_player, netPlayer* target_player) {};
|
||||
virtual bool Decide(netPlayer* source_player, netPlayer* target_player) = 0;
|
||||
virtual void PrepareReply(datBitBuffer* buffer, netPlayer* reply_player) {};
|
||||
virtual void HandleReply(datBitBuffer* buffer, netPlayer* souce_player) {};
|
||||
virtual void PrepareExtraData(datBitBuffer* buffer, bool is_reply, netPlayer* player, netPlayer* player2) {};
|
||||
virtual void HandleExtraData(datBitBuffer* buffer, bool is_reply, netPlayer* player, netPlayer* player2) {};
|
||||
|
||||
private:
|
||||
virtual void unk_0x60() {};
|
||||
virtual void unk_0x68() {};
|
||||
virtual void unk_0x70() {};
|
||||
virtual void unk_0x78() {};
|
||||
|
||||
public:
|
||||
virtual bool operator==(netGameEvent const& other) = 0;
|
||||
virtual bool operator!=(netGameEvent const& other) = 0;
|
||||
|
||||
virtual bool MustPersist() = 0;
|
||||
virtual bool MustPersistWhenOutOfScope() = 0;
|
||||
virtual bool HasTimedOut() = 0;
|
||||
|
||||
public:
|
||||
Type m_Type; // 0x08
|
||||
bool m_RequiresReply; // 0x0A
|
||||
private:
|
||||
char m_padding1[0x05]; // 0x0B
|
||||
public:
|
||||
netPlayer* m_SourcePlayer; // 0x10
|
||||
netPlayer* m_TargetPlayer; // 0x18
|
||||
uint32_t m_ResendTime; // 0x20
|
||||
private:
|
||||
uint16_t m_0x24; // 0x24
|
||||
uint8_t m_0x26; // 0x26
|
||||
uint8_t m_0x27; // 0x27
|
||||
uint32_t m_0x28; // 0x28
|
||||
};
|
||||
static_assert(sizeof(rage::netGameEvent) == 0x30);
|
||||
}
|
||||
|
||||
class CScriptedGameEvent // : public rage::netGameEvent
|
||||
{
|
||||
public:
|
||||
bool Deserialize(rage::datBitBuffer& buffer);
|
||||
|
||||
char m_padding[0x40]; // 0x30
|
||||
int64_t m_Args[54]; // 0x70
|
||||
uint32_t m_Bitset; // 0x220
|
||||
uint32_t m_ArgsSize; // 0x224
|
||||
};
|
||||
|
||||
class CNetworkIncrementStatEvent
|
||||
{
|
||||
public:
|
||||
void Deserialize(rage::datBitBuffer& buffer);
|
||||
|
||||
uint32_t m_Stat; // 0x30
|
||||
uint32_t m_Amount; // 0x34
|
||||
};
|
||||
|
||||
class CDoorBreakEvent
|
||||
{
|
||||
public:
|
||||
void Deserialize(rage::datBitBuffer& buffer);
|
||||
|
||||
uint16_t m_VehicleId; // 0x30
|
||||
uint8_t m_DoorId; // 0x32
|
||||
};
|
||||
|
||||
class CPlaySoundEvent
|
||||
{
|
||||
public:
|
||||
void Deserialize(rage::datBitBuffer& buffer);
|
||||
|
||||
bool m_IsEntity; // 0x30
|
||||
uint16_t m_EntityId; // 0x32
|
||||
rage::fvector3 m_Position; // 0x40
|
||||
uint32_t m_RefHash; // 0x50
|
||||
uint32_t m_SoundHash; // 0x54
|
||||
uint8_t m_SoundId; // 0x58
|
||||
CGameScriptId m_ScriptId; // 0x60
|
||||
int m_0xA0; // 0xA0
|
||||
};
|
||||
|
||||
class CWeaponDamageEvent
|
||||
{
|
||||
public:
|
||||
void Deserialize(rage::datBitBuffer& buffer);
|
||||
|
||||
rage::fvector3 m_LocalPos; // 0x30
|
||||
rage::fvector3 m_ImpactDir; // 0x40
|
||||
uint32_t m_DamageFlags; // 0x50
|
||||
uint32_t m_WeaponType; // 0x54
|
||||
uint32_t m_WeaponDamage; // 0x58
|
||||
uint8_t m_0x5C; // 0x5C
|
||||
uint32_t m_0x60; // 0x60
|
||||
uint32_t m_DamageTime; // 0x64
|
||||
uint32_t m_ActionResultName; // 0x68
|
||||
uint32_t m_0x6C; // 0x6C
|
||||
int m_HitComponent; // 0x70
|
||||
uint16_t m_0x74; // 0x74
|
||||
int16_t m_0x76; // 0x76
|
||||
uint16_t m_ActionResultId; // 0x78
|
||||
uint16_t m_ParentGlobalId; // 0x7A Source entity?
|
||||
uint16_t m_HitGlobalId; // 0x7C Target entity?
|
||||
uint8_t m_TyreIndex; // 0x7E
|
||||
uint8_t m_SuspensionIndex; // 0x7F
|
||||
uint8_t m_DamageType; // 0x80
|
||||
bool m_HasImpactDir; // 0x81
|
||||
bool m_HitEntityWeapon; // 0x82
|
||||
bool m_HitWeaponAmmoAttachment; // 0x83
|
||||
bool m_Silenced; // 0x84
|
||||
bool m_WillKill; // 0x85
|
||||
bool m_0x86; // 0x86
|
||||
bool m_0x87; // 0x87
|
||||
bool m_OverrideDefaultDamage; // 0x88
|
||||
bool m_0x89; // 0x89
|
||||
bool m_0x8A; // 0x8A
|
||||
bool m_IsNetTargetPos; // 0x8B
|
||||
bool m_0x8C; // 0x8C
|
||||
uint32_t m_Time; // 0x90
|
||||
uint8_t m_0x94; // 0x94
|
||||
};
|
||||
|
||||
class CActivateVehicleSpecialAbilityEvent
|
||||
{
|
||||
public:
|
||||
void Deserialize(rage::datBitBuffer& buffer);
|
||||
|
||||
uint16_t m_VehicleId; // 0x30
|
||||
uint32_t m_AbilityType; // 0x34
|
||||
uint32_t m_Time; // 0x38
|
||||
};
|
||||
|
||||
enum class ExplosionType;
|
||||
class CExplosionEvent
|
||||
{
|
||||
public:
|
||||
void Deserialize(rage::datBitBuffer& buffer);
|
||||
|
||||
struct
|
||||
{
|
||||
ExplosionType m_ExplosionType; // 0x30
|
||||
rage::fvector3 m_Position; // 0x40
|
||||
uint64_t m_0x50; // 0x50
|
||||
uint64_t m_0x58; // 0x58
|
||||
uint64_t m_0x60; // 0x60
|
||||
uint32_t m_0x68; // 0x68
|
||||
float m_DamageScale; // 0x6C
|
||||
uint32_t m_0x70; // 0x70
|
||||
float m_CameraShake; // 0x74
|
||||
float m_0x78; // 0x78
|
||||
bool m_IsAudible; // 0x7C
|
||||
bool m_IsInvisible; // 0x7D
|
||||
bool m_0x7E; // 0x7E
|
||||
rage::fvector3 m_0x80; // 0x80
|
||||
uint64_t m_0x90; // 0x90
|
||||
int m_0x98; // 0x98
|
||||
int m_0x9C; // 0x9C
|
||||
uint32_t m_0xA0; // 0xA0
|
||||
uint32_t m_0xA4; // 0xA4
|
||||
uint32_t m_InteriorIndex; // 0xA8
|
||||
uint64_t m_0xB0; // 0xB0
|
||||
uint8_t m_0xB8; // 0xB8
|
||||
uint16_t m_0xBA; // 0xBA
|
||||
bool m_0xBC; // 0xBC
|
||||
bool m_0xBD; // 0xBD
|
||||
bool m_0xBE; // 0xBE
|
||||
bool m_0xBF; // 0xBF
|
||||
bool m_0xC0; // 0xC0
|
||||
bool m_AddOwnedExplosion; // 0xC1
|
||||
bool m_Expected; // 0xC2 -- for telemetry
|
||||
uint32_t m_ScriptHash; // 0xC4 -- for telemetry
|
||||
uint32_t m_ProgramCounter; // 0xC8 -- for telemetry
|
||||
};
|
||||
uint16_t m_TargetEntity; // 0xD0
|
||||
uint16_t m_TargetEnt2; // 0xD2
|
||||
uint16_t m_OwnerNetId; // 0xD4
|
||||
uint16_t m_UnkNetId; // 0xD6
|
||||
uint8_t m_0xD8; // 0xD8
|
||||
uint16_t m_0xDA; // 0xDA
|
||||
rage::fvector3 m_PositionUnk; // 0xE0
|
||||
bool m_0xF0; // 0xF0
|
||||
bool m_0xF1; // 0xF1
|
||||
bool m_0xF2; // 0xF2
|
||||
bool m_HasTargetEnt2; // 0xF3
|
||||
bool m_0xF4; // 0xF4
|
||||
uint32_t m_Time; // 0xF8
|
||||
};
|
||||
|
||||
class CScriptEntityStateChangeEvent
|
||||
{
|
||||
public:
|
||||
enum class Type : uint32_t
|
||||
{
|
||||
BlockingOfNonTemporaryEvents,
|
||||
SettingOfPedRelationshipGroupHash,
|
||||
SettingOfDriveTaskCruiseSpeed,
|
||||
SettingOfLookAtEntity,
|
||||
SettingOfPlaneMinHeightAboveTerrain,
|
||||
SetPedRagdollBlockFlag,
|
||||
SettingOfTaskVehicleTempAction,
|
||||
SetPedFacialIdleAnimOverride,
|
||||
SetVehicleLockState,
|
||||
SetVehicleExclusiveDriver
|
||||
};
|
||||
};
|
||||
|
||||
class CScriptWorldStateEvent
|
||||
{
|
||||
public:
|
||||
enum class Type : uint32_t
|
||||
{
|
||||
CarGen,
|
||||
EntityArea,
|
||||
PopGroupOverride,
|
||||
PopMultiplierArea,
|
||||
PTFX,
|
||||
RoadNode,
|
||||
Rope,
|
||||
ScenarioBlockingArea,
|
||||
VehiclePlayerLocking
|
||||
};
|
||||
};
|
||||
|
||||
class CUpdateFxnEvent
|
||||
{
|
||||
public:
|
||||
void Deserialize(rage::datBitBuffer& buffer);
|
||||
|
||||
uint32_t m_0x30; // 0x30
|
||||
uint32_t m_0x34; // 0x34
|
||||
};
|
||||
@@ -1,45 +1,45 @@
|
||||
#pragma once
|
||||
#include "types/rage/vector.hpp"
|
||||
#include "types/network/sync/CProjectBaseSyncDataNode.hpp"
|
||||
#include "types/rage/vector.hpp"
|
||||
|
||||
struct ObjectCreationTelemetry
|
||||
{
|
||||
uint32_t unk_0000; //0x0000 "et"
|
||||
uint32_t m_ScriptHash; //0x0004 "es"
|
||||
uint32_t unk_0008; //0x0008 "ep"
|
||||
bool unk_000C; //0x000C "ec"
|
||||
bool m_HasData; //0x000D
|
||||
};
|
||||
|
||||
// TODO: verify if this is right
|
||||
class CObjectCreationDataNode : CProjectBaseSyncDataNode
|
||||
{
|
||||
public:
|
||||
uint32_t unk_00C0; //0x00C0
|
||||
uint32_t unk_00C4; //0x00C4
|
||||
uint32_t unk_00C8; //0x00C8
|
||||
bool unk_00CC;
|
||||
bool unk_00CD;
|
||||
uint16_t unk_00D0; //0x00D0
|
||||
char pad_0xC2[14]; //0x00D2
|
||||
rage::fvector4 m_ObjectOrientation; //0x00E0
|
||||
char pad_00E0[30]; //0x00F0
|
||||
rage::fvector3 m_ObjectPosition; //0x0110
|
||||
char pad_010C[4]; //0x011C
|
||||
rage::fvector3 m_DummyPosition; //0x011E
|
||||
char pad_011A[16]; //0x012C
|
||||
rage::fvector3 m_ScriptGrabPosition; //0x0140
|
||||
char pad_013C[8]; //0x013C
|
||||
float m_ScriptGrabRadius; //0x0148
|
||||
uint32_t m_CreatedBy; //0x014C
|
||||
uint32_t m_Model; //0x0150
|
||||
uint32_t m_FragGroupIndex; //0x0154
|
||||
uint32_t m_OwnershipToken; //0x0158
|
||||
uint32_t unk_015C; //0x015C
|
||||
|
||||
// everything after this is probably wrong
|
||||
bool m_NoReassign; //0x0160
|
||||
bool unk_0161; //0x0161
|
||||
bool m_PlayerWantsControl; //0x0162
|
||||
bool m_HasInitPhysics; //0x0163
|
||||
bool m_ScriptGrabbedFromWorld; //0x0164
|
||||
bool m_IsFragObject; //0x0165
|
||||
bool m_IsBroken; //0x0166
|
||||
bool m_HasExploded; //0x0167
|
||||
bool m_KeepRegistered; //0x0168
|
||||
bool unk_0169; //0x0169
|
||||
bool unk_016A; //0x016A
|
||||
bool unk_016B; //0x016B
|
||||
}; //Size: 0x016C
|
||||
ObjectCreationTelemetry m_TelemetryData; //0x00C0 -- netObject + 0x270
|
||||
uint16_t unk_00D0; //0x00D0
|
||||
char pad_0xC2[14]; //0x00D2
|
||||
rage::fvector4 m_ObjectOrientation[4]; //0x00E0
|
||||
rage::fvector3 m_DummyPosition; //0x0120
|
||||
rage::fvector3 m_ObjectPosition; //0x0130
|
||||
rage::fvector3 m_ScriptGrabPosition; //0x0140
|
||||
char pad_0150[8]; //0x0150
|
||||
float m_ScriptGrabRadius; //0x0158
|
||||
uint32_t m_CreatedBy; //0x015C
|
||||
uint32_t m_Model; //0x0160
|
||||
uint32_t m_FragGroupIndex; //0x0164
|
||||
uint32_t m_OwnershipToken; //0x0168
|
||||
uint32_t unk_016C; //0x016C
|
||||
bool m_NoReassign; //0x0170
|
||||
bool unk_0171; //0x0171
|
||||
bool m_PlayerWantsControl; //0x0172
|
||||
bool m_HasInitPhysics; //0x0173
|
||||
bool m_ScriptGrabbedFromWorld; //0x0174
|
||||
bool m_IsFragObject; //0x0175
|
||||
bool m_IsBroken; //0x0176
|
||||
bool unk_0177; //0x0177
|
||||
bool m_HasExploded; //0x0178
|
||||
bool m_KeepRegistered; //0x0179
|
||||
bool unk_017A; //0x017A
|
||||
bool unk_017B; //0x017B
|
||||
bool unk_017C; //0x017C
|
||||
}; //Size: 0x0180
|
||||
static_assert(sizeof(CObjectCreationDataNode) == 0x180);
|
||||
@@ -7,7 +7,6 @@ class CPedAttachDataNode : CSyncDataNodeInfrequent
|
||||
{
|
||||
public:
|
||||
rage::fvector3 m_Offset; //0x00C0
|
||||
char pad_00CC[4]; //0x00CC
|
||||
rage::fvector4 m_Orientation; //0x00D0
|
||||
uint16_t m_AttachedTo; //0x00E0
|
||||
uint16_t m_AttachmentBone; //0x00E2
|
||||
@@ -17,4 +16,4 @@ public:
|
||||
bool m_IsAttached; //0x00F0
|
||||
bool unk_00F1; //0x00F1
|
||||
};
|
||||
static_assert(sizeof(CPedAttachDataNode) == 0xF8);
|
||||
static_assert(sizeof(CPedAttachDataNode) == 0x100);
|
||||
@@ -23,5 +23,5 @@ public:
|
||||
bool unk_0114; //0x0114
|
||||
bool unk_0115; //0x0115
|
||||
bool m_IsCargoVehicle; //0x0116
|
||||
}; //Size: 0x0118
|
||||
static_assert(sizeof(CPhysicalAttachDataNode) == 0x118);
|
||||
}; //Size: 0x0120
|
||||
static_assert(sizeof(CPhysicalAttachDataNode) == 0x120);
|
||||
+13
-13
@@ -1,20 +1,20 @@
|
||||
#pragma once
|
||||
#include "types/rage/vector.hpp"
|
||||
#include "types/network/sync/CProjectBaseSyncDataNode.hpp"
|
||||
#include "types/script/CGameScriptObjInfo.hpp"
|
||||
|
||||
class CPickupPlacementCreationDataNode : CProjectBaseSyncDataNode
|
||||
{
|
||||
public:
|
||||
bool m_HasPickupData; //0x00C0
|
||||
char pad_00C1[15]; //0x00C1
|
||||
rage::fvector3 m_PickupPos; //0x00D0
|
||||
rage::fvector4 m_PickupOrientation; //0x00E0
|
||||
uint32_t m_PickupType; //0x00F0
|
||||
uint32_t m_PickupFlags; //0x00F4
|
||||
uint32_t m_Amount; //0x00F8
|
||||
uint32_t m_CustomModel; //0x00FC
|
||||
uint32_t m_CustomRegenerationTime; //0x0100
|
||||
uint32_t m_TeamPermits; //0x0104
|
||||
uint64_t *unk_struct_0108; //0x0108
|
||||
}; //Size: 0x0110
|
||||
static_assert(sizeof(CPickupPlacementCreationDataNode) == 0x110);
|
||||
bool m_HasPickupData; //0x00C0
|
||||
rage::fvector3 m_PickupPos; //0x00D0
|
||||
rage::fvector4 m_PickupOrientation; //0x00E0
|
||||
uint32_t m_PickupType; //0x00F0
|
||||
uint32_t m_PickupFlags; //0x00F4
|
||||
uint32_t m_Amount; //0x00F8
|
||||
uint32_t m_CustomModel; //0x00FC
|
||||
uint32_t m_CustomRegenerationTime; //0x0100
|
||||
uint32_t m_TeamPermits; //0x0104
|
||||
CGameScriptObjInfo m_ScriptObjectInfo; //0x0108
|
||||
}; //Size: 0x0160
|
||||
static_assert(sizeof(CPickupPlacementCreationDataNode) == 0x160);
|
||||
|
||||
@@ -17,7 +17,7 @@ public:
|
||||
uint16_t m_EntityStandingOn; //0x00D0
|
||||
char pad_00D2[12]; //0x00D2
|
||||
rage::fvector3 m_StandingOnEntityOffset; //0x00E0
|
||||
char pad_00EC[4]; //0x00EC
|
||||
char pad_00F0[4]; //0x00F0
|
||||
uint32_t m_StealthNoise; //0x00F4
|
||||
}; //Size: 0x00F8
|
||||
static_assert(sizeof(CPlayerSectorPosNode) == 0xF8);
|
||||
}; //Size: 0x0100
|
||||
static_assert(sizeof(CPlayerSectorPosNode) == 0x100);
|
||||
@@ -10,7 +10,7 @@ public:
|
||||
int16_t m_Occupants[16];
|
||||
char pad[16];
|
||||
bool m_OverridePosition;
|
||||
alignas(16) rage::fvector3 m_Position;
|
||||
rage::fvector3 m_Position;
|
||||
std::int32_t m_VelocityX;
|
||||
std::int32_t m_VelocityY;
|
||||
std::int32_t m_VelocityZ;
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
#pragma once
|
||||
#include "vector.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace rage
|
||||
@@ -449,6 +451,74 @@ namespace rage
|
||||
}
|
||||
}
|
||||
|
||||
float ReadFloat(int size, float divisor)
|
||||
{
|
||||
int integer = Read<int>(size);
|
||||
|
||||
float max = (1 << size) - 1;
|
||||
return ((float)integer / max) * divisor;
|
||||
}
|
||||
|
||||
void WriteFloat(int size, float divisor, float value)
|
||||
{
|
||||
float max = (1 << size) - 1;
|
||||
int integer = (int)((value / divisor) * max);
|
||||
|
||||
Write<int>(integer, size);
|
||||
}
|
||||
|
||||
float ReadSignedFloat(int size, float divisor)
|
||||
{
|
||||
int integer = Read<int>(size, true);
|
||||
|
||||
float max = (1 << (size - 1)) - 1;
|
||||
return ((float)integer / max) * divisor;
|
||||
}
|
||||
|
||||
void WriteSignedFloat(int size, float divisor, float value)
|
||||
{
|
||||
float max = (1 << (size - 1)) - 1;
|
||||
int integer = (int)((value / divisor) * max);
|
||||
|
||||
Write<int>(integer, size, true);
|
||||
}
|
||||
|
||||
rage::fvector3 ReadPosition(int size)
|
||||
{
|
||||
rage::fvector3 pos;
|
||||
|
||||
pos.x = ReadSignedFloat(size, 27648.0f);
|
||||
pos.y = ReadSignedFloat(size, 27648.0f);
|
||||
pos.z = ReadFloat(size, 4416.0f) - 1700.0f;
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
void WritePosition(int size, rage::fvector3& pos)
|
||||
{
|
||||
WriteSignedFloat(size, 27648.0f, pos.x);
|
||||
WriteSignedFloat(size, 27648.0f, pos.y);
|
||||
WriteFloat(size, 4416.0f, pos.z + 1700.0f);
|
||||
}
|
||||
|
||||
rage::fvector3 ReadVector3(int size, float divisor)
|
||||
{
|
||||
rage::fvector3 vec;
|
||||
|
||||
vec.x = ReadSignedFloat(size, divisor);
|
||||
vec.y = ReadSignedFloat(size, divisor);
|
||||
vec.z = ReadSignedFloat(size, divisor);
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
void WriteVector3(int size, float divisor, rage::fvector3& vec)
|
||||
{
|
||||
WriteSignedFloat(size, divisor, vec.x);
|
||||
WriteSignedFloat(size, divisor, vec.y);
|
||||
WriteSignedFloat(size, divisor, vec.z);
|
||||
}
|
||||
|
||||
public:
|
||||
void* m_Data; //0x0000
|
||||
uint32_t m_BitOffset; //0x0008
|
||||
|
||||
@@ -24,13 +24,11 @@ namespace rage
|
||||
};
|
||||
|
||||
// atVector<float, 3>?
|
||||
class vector3
|
||||
class alignas(16) vector3
|
||||
{
|
||||
public:
|
||||
float x, y, z;
|
||||
|
||||
private:
|
||||
int _PAD; // because alignof doesn't work
|
||||
public:
|
||||
constexpr vector3(float x, float y, float z) :
|
||||
x(x),
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#include "CGameScriptId.hpp"
|
||||
#include "types/rage/datBitBuffer.hpp"
|
||||
|
||||
void CGameScriptId::Deserialize(rage::datBitBuffer& buffer)
|
||||
{
|
||||
m_Hash = buffer.Read<uint32_t>(32);
|
||||
m_Timestamp = buffer.Read<uint32_t>(32);
|
||||
|
||||
bool has_position_hash = buffer.Read<bool>(1);
|
||||
if (has_position_hash)
|
||||
{
|
||||
m_PositionHash = buffer.Read<uint32_t>(32);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_PositionHash = 0;
|
||||
}
|
||||
|
||||
bool has_instance_id = buffer.Read<bool>(1);
|
||||
if (has_instance_id)
|
||||
{
|
||||
m_InstanceId = buffer.Read<int32_t>(8);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_InstanceId = -1;
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,8 @@
|
||||
class CGameScriptId : public rage::scriptId
|
||||
{
|
||||
public:
|
||||
void Deserialize(rage::datBitBuffer& buffer);
|
||||
|
||||
std::int32_t m_Timestamp; // 0x30
|
||||
std::int32_t m_PositionHash; // 0x34
|
||||
std::int32_t m_InstanceId; // 0x38
|
||||
|
||||
Reference in New Issue
Block a user