diff --git a/src/core/hooking/Hooking.cpp b/src/core/hooking/Hooking.cpp index 2d0f63c..c512ad7 100644 --- a/src/core/hooking/Hooking.cpp +++ b/src/core/hooking/Hooking.cpp @@ -22,6 +22,7 @@ namespace YimMenu BaseHook::Add(new DetourHook("AssignPhysicalIndex", Pointers.AssignPhysicalIndex, Hooks::Info::AssignPhysicalIndex)); BaseHook::Add(new DetourHook("ReceiveNetMessage", Pointers.ReceiveNetMessage, Hooks::Network::ReceiveNetMessage)); + BaseHook::Add(new DetourHook("ReceiveNetGameEvent", Pointers.ReceiveNetGameEvent, Hooks::Network::ReceiveNetGameEvent)); BaseHook::Add(new DetourHook("IsNodeInScope", Pointers.IsNodeInScope, Hooks::Spoofing::IsNodeInScope)); BaseHook::Add(new DetourHook("ShouldUseNodeCache", Pointers.ShouldUseNodeCache, Hooks::Spoofing::ShouldUseNodeCache)); diff --git a/src/game/hooks/Hooks.hpp b/src/game/hooks/Hooks.hpp index c11d3ec..0346e2b 100644 --- a/src/game/hooks/Hooks.hpp +++ b/src/game/hooks/Hooks.hpp @@ -8,9 +8,11 @@ namespace rage { class netConnectionManager; class netEvent; + class netEventMgr; class scrProgram; class netObject; class datBitBuffer; + class netGameEvent; } namespace YimMenu @@ -50,8 +52,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(rage::netEventMgr* mgr, rage::netGameEvent* event, rage::datBitBuffer* buffer, CNetGamePlayer* src, CNetGamePlayer* dst, std::uint16_t seq_id, std::uint32_t a7, int a8); + extern bool HandleScriptedGameEvent(Player player, int64_t* args, uint32_t args_size); // this is not a real hooked func } namespace Window diff --git a/src/game/hooks/Network/HandleNetGameEvent.cpp b/src/game/hooks/Network/HandleNetGameEvent.cpp deleted file mode 100644 index 65e9520..0000000 --- a/src/game/hooks/Network/HandleNetGameEvent.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include "core/util/Joaat.hpp" -#include "game/backend/Self.hpp" -#include "game/hooks/Hooks.hpp" -#include "game/pointers/Pointers.hpp" -#include "types/network/CNetGamePlayer.hpp" -#include "types/network/NetEventType.hpp" -#include "types/rage/datBitBuffer.hpp" - -namespace YimMenu::Hooks -{ - static void SendEventAck(rage::netEventMgr* event_mgr, CNetGamePlayer* source_player, CNetGamePlayer* target_player, uint32_t event_index, uint32_t event_handled_bits) - { - if (source_player->m_PlayerIndex != 255 && !Pointers.EventAck(0x778LL * source_player->m_PlayerIndex + (intptr_t)event_mgr + 0x2C408, target_player, event_index, event_handled_bits)) - { - Pointers.SendEventAck(event_mgr, source_player); - Pointers.EventAck((intptr_t)event_mgr + 0x2C408 + 0x778LL * source_player->m_PlayerIndex, target_player, event_index, event_handled_bits); - } - } - - static bool HandleNetGameEvent(Player& player, uint16_t event_id, rage::datBitBuffer& buffer) - { - switch (static_cast(event_id)) - { - case NetEventType::WEAPON_DAMAGE_EVENT: - { - uint8_t damage_type = buffer.Read(2); - uint32_t weapon_type = buffer.Read(32); - - if (weapon_type == "WEAPON_TRANQUILIZER"_J) - { - //player.AddDetection(); - return false; - } - - break; - } - case NetEventType::SCRIPTED_GAME_EVENT: - { - int64_t args[54]{}; - uint32_t args_size = buffer.Read(32); - - if (args_size > sizeof(args)) - return false; - - buffer.ReadArray(args, 8 * args_size); - - if (!Network::HandleScriptedGameEvent(player, args, args_size)) - return false; - - break; - } - } - - return true; - } - - void Network::ReceiveEvent(Player& player, uint16_t event_id, uint32_t event_index, uint32_t event_handled_bits, rage::datBitBuffer& buffer) - { - if (!HandleNetGameEvent(player, event_id, buffer)) - SendEventAck(*Pointers.NetEventMgr, player.GetHandle(), Self::GetPlayer().GetHandle(), event_index, event_handled_bits); - } -} \ No newline at end of file diff --git a/src/game/hooks/Network/HandleScriptedGameEvent.cpp b/src/game/hooks/Network/HandleScriptedGameEvent.cpp index 21de86a..819b01f 100644 --- a/src/game/hooks/Network/HandleScriptedGameEvent.cpp +++ b/src/game/hooks/Network/HandleScriptedGameEvent.cpp @@ -5,10 +5,11 @@ namespace YimMenu::Hooks { - bool Network::HandleScriptedGameEvent(YimMenu::Player& player, int64_t* args, uint32_t args_size) + bool Network::HandleScriptedGameEvent(Player player, int64_t* args, uint32_t args_size) { SCRIPT_EVENT* script_event = reinterpret_cast(args); + switch (static_cast(script_event->GetEventIndex())) { case ScriptEventIndex::Bounty: @@ -33,6 +34,8 @@ namespace YimMenu::Hooks //player.AddDetection(); return true; } + default: + break; } return true; diff --git a/src/game/hooks/Network/ReceiveNetGameEvent.cpp b/src/game/hooks/Network/ReceiveNetGameEvent.cpp new file mode 100644 index 0000000..87a43a1 --- /dev/null +++ b/src/game/hooks/Network/ReceiveNetGameEvent.cpp @@ -0,0 +1,68 @@ +#include "core/util/Joaat.hpp" +#include "game/backend/Self.hpp" +#include "game/hooks/Hooks.hpp" +#include "core/hooking/DetourHook.hpp" +#include "game/pointers/Pointers.hpp" +#include "types/network/CNetGamePlayer.hpp" +#include "types/network/netGameEvent.hpp" +#include "types/rage/datBitBuffer.hpp" + +namespace YimMenu::Hooks +{ + static void SendEventAck(rage::netEventMgr* event_mgr, CNetGamePlayer* source_player, CNetGamePlayer* target_player, uint16_t seq_id, uint32_t event_index, uint32_t event_handled_bits, rage::netGameEvent::Type type) + { + if (source_player->m_PlayerIndex != 255 && !Pointers.EventAck(0x778LL * source_player->m_PlayerIndex + (intptr_t)event_mgr + 0x2C408, target_player, event_index, event_handled_bits)) + { + Pointers.SendEventAck(event_mgr, source_player); + Pointers.EventAck((intptr_t)event_mgr + 0x2C408 + 0x778LL * source_player->m_PlayerIndex, target_player, event_index, event_handled_bits); + } + *reinterpret_cast(0x118LL * (uint64_t)type + (uint64_t)event_mgr + 4 * source_player->m_PlayerIndex + 0x458) = seq_id; + } + + bool ShouldAllowNetEvent(Player source, rage::netGameEvent::Type type, rage::datBitBuffer& buffer) + { + switch (type) + { + case rage::netGameEvent::Type::WEAPON_DAMAGE_EVENT: + { + uint8_t damage_type = buffer.Read(2); + uint32_t weapon_type = buffer.Read(32); + + if (weapon_type == "WEAPON_TRANQUILIZER"_J) + { + LOG(INFO) << "this has been blocked from " << source.GetName(); + //player.AddDetection(); + return false; + } + + break; + } + case rage::netGameEvent::Type::SCRIPTED_GAME_EVENT: + { + int64_t args[54]{}; + uint32_t args_size = buffer.Read(32); + + if (args_size > sizeof(args)) + return false; + + buffer.ReadArray(args, 8 * args_size); + + if (!Network::HandleScriptedGameEvent(source, args, args_size)) + return false; + + break; + } + default: break; + } + + return true; + } + + void Network::ReceiveNetGameEvent(rage::netEventMgr* mgr, rage::netGameEvent* event, rage::datBitBuffer* buffer, CNetGamePlayer* src, CNetGamePlayer* dst, std::uint16_t seq_id, std::uint32_t a7, int a8) + { + if (!ShouldAllowNetEvent(src, event->m_Type, *buffer)) + return SendEventAck(mgr, src, dst, seq_id, a7, a8, event->m_Type); + + BaseHook::Get>()->Original()(mgr, event, buffer, src, dst, seq_id, a7, a8); + } +} \ No newline at end of file diff --git a/src/game/hooks/Network/ReceiveNetMessage.cpp b/src/game/hooks/Network/ReceiveNetMessage.cpp index 9c79004..b717c73 100644 --- a/src/game/hooks/Network/ReceiveNetMessage.cpp +++ b/src/game/hooks/Network/ReceiveNetMessage.cpp @@ -45,49 +45,6 @@ namespace YimMenu::Hooks } break; } - case rage::netMessage::Type::PackedEvents: - { - auto player = Players::GetByMessageId(fr_evt->m_MsgId); - - if (!player) - break; - - uint32_t count = buffer.Read(5); - uint32_t buffer_size = buffer.Read(15); - - if (buffer_size > 7296) - buffer_size = 7296; - - int remaining = buffer_size; - - while (remaining >= 39) - { - int bits_read = buffer.m_BitsRead; - - uint16_t event_id = buffer.Read(7); - uint32_t event_index = buffer.Read(9); - uint32_t event_handled_bits = buffer.Read(8); - uint32_t event_data_size = buffer.Read(15); - - if (buffer.Read(1)) - buffer.Read(16); - - char event_data[4096 + 1]; - if (event_data_size) - { - buffer.ReadArray(event_data, event_data_size); - } - - 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); - - remaining -= (int)buffer.m_BitsRead - bits_read; - } - - break; - } default: break; } diff --git a/src/game/pointers/Pointers.cpp b/src/game/pointers/Pointers.cpp index e05a8f3..2c28788 100644 --- a/src/game/pointers/Pointers.cpp +++ b/src/game/pointers/Pointers.cpp @@ -164,9 +164,9 @@ namespace YimMenu ReceiveNetMessage = ptr.Add(0xD).Add(1).Rip().As(); }); - constexpr auto netEventMgrPtrn = Pattern<"4C 8B 05 ? ? ? ? 44 0F B7 CA">("NetEventMgr"); + constexpr auto netEventMgrPtrn = Pattern<"81 BC 24 B0 00 00 00 FF 01 00 00">("ReceiveNetGameEvent"); scanner.Add(netEventMgrPtrn, [this](PointerCalculator ptr) { - NetEventMgr = ptr.Add(3).Rip().As(); + ReceiveNetGameEvent = ptr.Sub(0x10).As(); }); constexpr auto sendEventAckPtrn = Pattern<"84 C0 75 ? 89 EE 49 8D AD">("SendEventAck"); diff --git a/src/game/pointers/Pointers.hpp b/src/game/pointers/Pointers.hpp index 7ed3a2b..b23f8ce 100644 --- a/src/game/pointers/Pointers.hpp +++ b/src/game/pointers/Pointers.hpp @@ -72,7 +72,7 @@ namespace YimMenu Functions::RequestControl RequestControl; std::uint8_t* SpectatePatch; // used to patch the code that prevents you from spawning network objects when spectating PVOID ReceiveNetMessage; - rage::netEventMgr** NetEventMgr; + PVOID ReceiveNetGameEvent; Functions::EventAck EventAck; Functions::SendEventAck SendEventAck; }; diff --git a/src/types/network/NetEventType.hpp b/src/types/network/NetEventType.hpp deleted file mode 100644 index 0841e19..0000000 --- a/src/types/network/NetEventType.hpp +++ /dev/null @@ -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 -}; \ No newline at end of file diff --git a/src/types/network/netGameEvent.hpp b/src/types/network/netGameEvent.hpp new file mode 100644 index 0000000..c992929 --- /dev/null +++ b/src/types/network/netGameEvent.hpp @@ -0,0 +1,146 @@ +#pragma once + +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); +} \ No newline at end of file