diff --git a/src/function_types.hpp b/src/function_types.hpp index 4b1bb50c..37f1d529 100644 --- a/src/function_types.hpp +++ b/src/function_types.hpp @@ -46,9 +46,13 @@ namespace big::functions //Sync signatures START using get_sync_type_info = const char*(*)(uint16_t sync_type, char a2); - using get_sync_tree_for_type = int64_t(*)(CNetworkObjectMgr* mgr, uint16_t sync_type); + using get_sync_tree_for_type = rage::netSyncTree*(*)(CNetworkObjectMgr* mgr, uint16_t sync_type); - using get_net_object = rage::netObject*(*)(CNetworkObjectMgr* mgr, int16_t id, bool unk3); + using get_net_object = rage::netObject*(*)(CNetworkObjectMgr* mgr, int16_t id, bool can_delete_be_pending); + + using get_net_object_for_player = rage::netObject*(*)(CNetworkObjectMgr*, int16_t, CNetGamePlayer*, bool); + + using read_bitbuffer_into_sync_tree = void(*)(rage::netSyncTree* tree, uint64_t flag, uint32_t flag2, rage::datBitBuffer* buffer, uint64_t netLogStub); //Sync signatures END using reset_network_complaints = void(*)(CNetComplaintMgr* mgr); diff --git a/src/gta/net_object_mgr.hpp b/src/gta/net_object_mgr.hpp index 7cc2bc2e..95c92792 100644 --- a/src/gta/net_object_mgr.hpp +++ b/src/gta/net_object_mgr.hpp @@ -1,9 +1,9 @@ +#pragma once #include "node_list.hpp" #include "enums.hpp" -#include "..\pointers.hpp" +#include "../pointers.hpp" #include "replay.hpp" -#pragma once namespace rage { @@ -15,16 +15,6 @@ namespace rage char pad_0010[256]; //0x0010 }; //Size: 0x0110 - class CPlayerAppearanceDataNode - { - public: - char pad_0000[24]; //0x0000 - CPlayerSyncTree* sync_tree; //0x0018 - char pad_0020[992]; //0x0020 - uint32_t model; //0x0400 - char pad_0404[124]; //0x0404 - }; //Size: 0x0480 - class CNetworkSyncDataULBase { public: @@ -64,149 +54,7 @@ namespace rage } }; - class netSyncTree - { - public: - char pad_0000[48]; //0x0000 - class netSyncTreeNode* m_sync_tree_node; //0x0030 - }; //Size: 0x0038 - - class netSyncTreeNode - { - public: - char pad_0000[192]; //0x0000 - uint32_t m_player_model; //0x00C0 - uint32_t m_ped_model; //0x00C4 - uint32_t m_vehicle_model; //0x00C8 - char pad_00CC[84]; //0x00CC - uint32_t m_pickup_model; //0x0120 - char pad_0124[44]; //0x0124 - uint32_t m_object_model; //0x0150 - char pad_0154[692]; //0x0154 - }; //Size: 0x0408 - - class netObject - { - public: - int16_t object_type; //0x0008 - int16_t object_id; //0x000A - char pad_000C[61]; //0x000C - int8_t owner_id; //0x0049 - int8_t control_id; //0x004A - int8_t next_owner_id; //0x004B - bool is_remote; //0x004C - bool wants_to_delete; //0x004D - char pad_004E[1]; //0x004E - bool should_not_be_deleted; //0x004F - char pad_0050[32]; //0x0050 - uint32_t players_acked; //0x0070 - char pad_0074[116]; //0x0074 - - virtual ~netObject() = 0; - - virtual void m_8() = 0; - virtual void m_10() = 0; - virtual void m_18() = 0; - virtual void* m_20() = 0; - virtual void m_28() = 0; - virtual netSyncTree* GetSyncTree() = 0; - virtual void m_38() = 0; - virtual void m_40() = 0; - virtual void m_48() = 0; - virtual void m_50() = 0; - virtual void m_58() = 0; - virtual void m_60() = 0; - virtual void m_68() = 0; - virtual void m_70() = 0; - virtual void m_78() = 0; - virtual rage::CObject* GetGameObject() = 0; - virtual void m_88() = 0; - virtual void m_90() = 0; - virtual void m_98() = 0; - virtual int GetObjectFlags() = 0; - virtual void m_A8() = 0; - virtual void m_B0() = 0; - virtual void m_B8() = 0; - virtual void m_C0() = 0; - virtual void m_C8() = 0; - virtual int GetSyncFrequency() = 0; - virtual void m_D8() = 0; - virtual void m_E0() = 0; - virtual void m_E8() = 0; - virtual void m_F0() = 0; - virtual void m_F8() = 0; - virtual void Update() = 0; - virtual bool m_108_1604() = 0; // added in 1604 - virtual void m_108() = 0; - virtual void m_110() = 0; - virtual void m_118() = 0; - virtual void m_120() = 0; - virtual void m_128() = 0; - virtual void m_130() = 0; - virtual void m_138() = 0; - virtual void m_140() = 0; - virtual void m_148() = 0; - virtual void m_150() = 0; - virtual bool m_158(void* player, int type, int* outReason) = 0; - virtual void m_160() = 0; - virtual bool m_168(int* outReason) = 0; - virtual void m_170() = 0; - virtual void m_178() = 0; - virtual void m_180() = 0; - virtual void m_188() = 0; - virtual void m_190() = 0; - virtual void m_198() = 0; - virtual void m_1A0() = 0; - virtual void m_1A8() = 0; - virtual void m_1B0() = 0; - virtual void m_1B8() = 0; - virtual void m_1C0() = 0; - virtual void m_1C8() = 0; - virtual void m_1D0() = 0; - virtual void m_1D8() = 0; - virtual void m_1E0() = 0; - virtual void m_1E8() = 0; - virtual void m_1F0() = 0; - virtual void m_1F8() = 0; - virtual void m_200() = 0; - virtual void m_208() = 0; - virtual void m_210() = 0; - virtual void m_218() = 0; - virtual void m_220() = 0; - virtual void m_228() = 0; - virtual void m_230() = 0; - virtual void m_238() = 0; - virtual void m_240() = 0; - virtual void m_248() = 0; - virtual void m_250() = 0; - virtual void m_258() = 0; - virtual void m_260() = 0; - virtual void m_268() = 0; - virtual void m_270() = 0; - virtual void m_278() = 0; - virtual void m_280() = 0; - virtual void m_288() = 0; - virtual void m_290() = 0; - virtual void m_298() = 0; - virtual void m_2A0() = 0; - virtual void m_2A8() = 0; - virtual void m_2B0() = 0; - virtual void m_2B8() = 0; - virtual void m_2C0() = 0; - virtual void m_2C8() = 0; - virtual void m_2D0() = 0; - virtual void m_2D8() = 0; - virtual void m_2E0() = 0; - virtual void m_2E8() = 0; - virtual void m_2F0() = 0; - virtual void m_2F8() = 0; - virtual void m_300() = 0; - virtual void m_308() = 0; - virtual void m_310() = 0; - virtual void m_318() = 0; - virtual void m_320() = 0; - virtual void UpdatePendingVisibilityChanges() = 0; - }; + class netObject; class CNetGamePlayer; class netObjectMgrBase @@ -265,6 +113,6 @@ class CNetworkObjectMgr : public rage::netObjectMgrBase public: rage::netObject* find_object_by_id(std::uint16_t object_id, bool can_delete_be_pending) { - return big::g_pointers->m_find_object_by_id(this, object_id, can_delete_be_pending); - }; -}; \ No newline at end of file + return big::g_pointers->m_get_net_object(this, object_id, can_delete_be_pending); + } +}; diff --git a/src/hooks/protections/received_clone_sync.cpp b/src/hooks/protections/received_clone_sync.cpp index 80649627..19bd1b92 100644 --- a/src/hooks/protections/received_clone_sync.cpp +++ b/src/hooks/protections/received_clone_sync.cpp @@ -1,9 +1,24 @@ #include "hooking.hpp" #include "core/globals.hpp" +#include "base/CObject.hpp" +#include "entities/fwEntity.hpp" +#include "rage/netSyncDataNodeBase.hpp" +#include "rage/netSyncTree.hpp" +#include "gta/net_object_mgr.hpp" +#include "datanodes/door/CDoorCreationDataNode.hpp" +#include "datanodes/object/CObjectCreationDataNode.hpp" +#include "datanodes/ped/CPedAttachDataNode.hpp" +#include "datanodes/ped/CPedCreationDataNode.hpp" +#include "datanodes/pickup/CPickupCreationDataNode.hpp" +#include "datanodes/physical/CPhysicalAttachDataNode.hpp" +#include "datanodes/player/CPlayerAppearanceDataNode.hpp" +#include "datanodes/proximity_migrateable/CSectorDataNode.hpp" +#include "datanodes/train/CTrainGameStateDataNode.hpp" +#include "datanodes/vehicle/CVehicleCreationDataNode.hpp" #include "network/netObject.hpp" +#include "natives.hpp" #include "base/CBaseModelInfo.hpp" #include "vehicle/CVehicleModelInfo.hpp" -#include "base/CObject.hpp" #include "util/model_info.hpp" namespace big @@ -21,18 +36,298 @@ namespace big SuccessfullSync = 8 }; + constexpr uint64_t operator ""_fnv1a(char const* str, std::size_t len) + { + auto const fnv_offset_basis = 14695981039346656037ULL; + auto const fnv_prime = 1099511628211ULL; + + auto value = fnv_offset_basis; + for (auto i = 0; i < len; i++) { + value ^= static_cast(str[i]); + value *= fnv_prime; + } + value ^= value >> 32; + + return value; + } + + uint32_t crash_models[] = { RAGE_JOAAT("prop_dummy_01"), RAGE_JOAAT("prop_dummy_car"), RAGE_JOAAT("prop_dummy_light"), RAGE_JOAAT("prop_dummy_plane"), RAGE_JOAAT("slod_human"), + RAGE_JOAAT("slod_small_quadped"), RAGE_JOAAT("slod_large_quadped"), RAGE_JOAAT("prop_distantcar_night"), RAGE_JOAAT("prop_distantcar_day"), RAGE_JOAAT("hei_bh1_08_details4_em_night"), + RAGE_JOAAT("dt1_18_sq_night_slod"), RAGE_JOAAT("ss1_12_night_slod"), -1288391198, RAGE_JOAAT("h4_prop_bush_bgnvla_med_01"), RAGE_JOAAT("h4_prop_bush_bgnvla_lrg_01"), + RAGE_JOAAT("h4_prop_bush_buddleia_low_01"), RAGE_JOAAT("h4_prop_bush_ear_aa"), RAGE_JOAAT("h4_prop_bush_ear_ab"), RAGE_JOAAT("h4_prop_bush_fern_low_01"), + RAGE_JOAAT("h4_prop_bush_fern_tall_cc"), RAGE_JOAAT("h4_prop_bush_mang_ad"), RAGE_JOAAT("h4_prop_bush_mang_low_aa"), RAGE_JOAAT("h4_prop_bush_mang_low_ab"), + RAGE_JOAAT("h4_prop_bush_seagrape_low_01"), RAGE_JOAAT("prop_h4_ground_cover"), RAGE_JOAAT("h4_prop_weed_groundcover_01"), RAGE_JOAAT("h4_prop_grass_med_01"), + RAGE_JOAAT("h4_prop_grass_tropical_lush_01"), RAGE_JOAAT("h4_prop_grass_wiregrass_01"), RAGE_JOAAT("h4_prop_weed_01_plant"), RAGE_JOAAT("h4_prop_weed_01_row"), + RAGE_JOAAT("urbanweeds02_l1"), RAGE_JOAAT("proc_forest_grass01"), RAGE_JOAAT("prop_small_bushyba"), RAGE_JOAAT("arbitergt"), RAGE_JOAAT("astron2"), RAGE_JOAAT("cyclone2"), + RAGE_JOAAT("ignus2"), RAGE_JOAAT("s95"), RAGE_JOAAT("hc_gunman"), RAGE_JOAAT("v_res_d_dildo_a"), RAGE_JOAAT("v_res_d_dildo_b"), RAGE_JOAAT("v_res_d_dildo_c"), + RAGE_JOAAT("v_res_d_dildo_d"), RAGE_JOAAT("v_res_d_dildo_e"), RAGE_JOAAT("v_res_d_dildo_f"), RAGE_JOAAT("v_res_skateboard"), RAGE_JOAAT("prop_battery_01"), RAGE_JOAAT("prop_barbell_01"), + RAGE_JOAAT("prop_barbell_02"), RAGE_JOAAT("prop_bandsaw_01"), RAGE_JOAAT("prop_bbq_3"), RAGE_JOAAT("v_med_curtainsnewcloth2"), RAGE_JOAAT("bh1_07_flagpoles"), + 92962485, RAGE_JOAAT("ig_wade") }; + + uint32_t cage_models[] = { RAGE_JOAAT("prop_rub_cage01a"), RAGE_JOAAT("prop_fnclink_05crnr1"), RAGE_JOAAT("prop_gold_cont_01"), RAGE_JOAAT("prop_feeder1"), RAGE_JOAAT("stt_prop_stunt_tube_s"), + RAGE_JOAAT("prop_feeder1_cr"), RAGE_JOAAT("p_cablecar_s") }; + + inline bool is_model_a_crash_model(uint32_t model) { + for (int i = 0; i < sizeof(crash_models) / sizeof(uint32_t); i++) + { + if (crash_models[i] == model) return true; + } + return false; + } + + inline bool is_model_a_cage_model(uint32_t model) { + for (int i = 0; i < sizeof(cage_models) / sizeof(uint32_t); i++) + { + if (cage_models[i] == model) return true; + } + return false; + } + +#define CLASS_TO_MANGLED_NAME(c) "?AV"#c"@@" + + template + T* get_node_from_object(rage::netSyncNodeBase* node) + { + constexpr uint64_t hash = CLASS_TO_MANGLED_NAME(T)""_fnv1a; + if (node->IsParentNode()) + { + for (auto child = node->m_first_child; child; child = child->m_next_sibling) { + T* attach_node = get_node_from_object(child); + if(attach_node != nullptr) + return attach_node; + } + } + else if (node->IsDataNode()) + { + if (typeid(*node).hash_code() == hash) + return dynamic_cast(node); + } + return nullptr; + } + + bool is_attachment_infinite(CPhysicalAttachDataNode* node, uint16_t object_id) { + if (rage::netObject* attached_object = (*g_pointers->m_network_object_mgr)->find_object_by_id(node->m_attached_to, false); attached_object) + { + if (rage::netSyncTree* tree = attached_object->GetSyncTree(); tree) + { + if (rage::netSyncNodeBase* base_node = tree->m_sync_node; base_node) { + + const auto attached_attach_node = get_node_from_object(base_node); + if (attached_attach_node && attached_attach_node->m_attached) + { + if (attached_attach_node->m_attached_to == object_id) { + return true; + } + else { + return is_attachment_infinite(attached_attach_node, object_id); + } + } + + } + } + } + + return false; + } + + bool is_ped_attachment_infinite(CPedAttachDataNode* node, uint16_t object_id) { + if (rage::netObject* attached_object = (*g_pointers->m_network_object_mgr)->find_object_by_id(node->m_attached_to, false); attached_object) + { + if (rage::netSyncTree* tree = attached_object->GetSyncTree(); tree) + { + if (rage::netSyncNodeBase* base_node = tree->m_sync_node; base_node) { + + const auto attached_attach_node = get_node_from_object(base_node); + if (attached_attach_node && attached_attach_node->m_attached) + { + if (attached_attach_node->m_attached_to == object_id) { + return true; + } + else { + return is_ped_attachment_infinite(attached_attach_node, object_id); + } + } + + } + } + } + + return false; + } + + bool check_node(rage::netSyncNodeBase* node, CNetGamePlayer* sender, uint16_t object_id) + { + if (node->IsParentNode()) + { + for (auto child = node->m_first_child; child; child = child->m_next_sibling) { + if (check_node(child, sender, object_id)) + return true; + } + } + else if (node->IsDataNode()) + { + //LOG(INFO) << typeid(*node).name() << ": " << HEX_TO_UPPER(typeid(*node).hash_code()); //Use this to get hashes for each node + switch (typeid(*node).hash_code()) { + case "?AVCDoorCreationDataNode@@"_fnv1a: //CDoorCreationDataNode + { + const auto creation_node = dynamic_cast(node); + if (is_model_a_crash_model(creation_node->m_model)) + { + if (g->notifications.invalid_sync.log) + LOG(WARNING) << "Invalid door model: " << "Model: " << HEX_TO_UPPER(creation_node->m_model) << " From : " << sender->get_name(); + if (g->notifications.invalid_sync.notify) + g_notification_service->push_warning(std::format("Invalid door model from {}", sender->get_name()), std::format("Model: 0x{:x}", creation_node->m_model)); + return true; + } + break; + } + case "?AVCPickupCreationDataNode@@"_fnv1a: //CPickupCreationDataNode + { + const auto creation_node = dynamic_cast(node); + if (is_model_a_crash_model(creation_node->m_custom_model)) + { + if (g->notifications.invalid_sync.log) + LOG(WARNING) << "Invalid pickup model: " << "Model: " << HEX_TO_UPPER(creation_node->m_custom_model) << " From : " << sender->get_name(); + if (g->notifications.invalid_sync.notify) + g_notification_service->push_warning(std::format("Invalid pickup model from {}", sender->get_name()), std::format("Model: 0x{:x}", creation_node->m_custom_model)); + return true; + } + break; + } + case "?AVCPhysicalAttachDataNode@@"_fnv1a: //CPhysicalAttachDataNode + { + const auto attach_node = dynamic_cast(node); + if (attach_node->m_attached && attach_node->m_attached_to == object_id) + { + if (g->notifications.invalid_sync.log) + LOG(WARNING) << "Infinite attachment: " << "Node: " << typeid(*node).name() << " From : " << sender->get_name(); + if (g->notifications.invalid_sync.notify) + g_notification_service->push_warning(std::format("Infinite attachment from {}", sender->get_name()), std::format("Node: {}", typeid(*node).name())); + return true; + } + else if (attach_node->m_attached && is_attachment_infinite(attach_node, object_id)) + { + if (g->notifications.invalid_sync.log) + LOG(WARNING) << "Infinite attachment v2: " << "Node: " << typeid(*node).name() << " From : " << sender->get_name(); + if (g->notifications.invalid_sync.notify) + g_notification_service->push_warning(std::format("Infinite attachment v2 from {}", sender->get_name()), std::format("Node: {}", typeid(*node).name())); + return true; + } + break; + } + case "?AVCPedCreationDataNode@@"_fnv1a: //CPedCreationDataNode + { + const auto creation_node = dynamic_cast(node); + if (is_model_a_crash_model(creation_node->m_model)) + { + if (g->notifications.invalid_sync.log) + LOG(WARNING) << "Invalid ped model: " << "Model: " << HEX_TO_UPPER(creation_node->m_model) << " From : " << sender->get_name(); + if (g->notifications.invalid_sync.notify) + g_notification_service->push_warning(std::format("Invalid ped model from {}", sender->get_name()), std::format("Model: 0x{:x}", creation_node->m_model)); + return true; + } + else if (creation_node->m_has_prop && is_model_a_crash_model(creation_node->m_prop_model)) { + if (g->notifications.invalid_sync.log) + LOG(WARNING) << "Invalid ped prop model: " << "Model: " << HEX_TO_UPPER(creation_node->m_prop_model) << " From : " << sender->get_name(); + if (g->notifications.invalid_sync.notify) + g_notification_service->push_warning(std::format("Invalid ped prop model from {}", sender->get_name()), std::format("Model: 0x{:x}", creation_node->m_prop_model)); + return true; + } + break; + } + case "?AVCPedAttachDataNode@@"_fnv1a: //CPedAttachDataNode + { + const auto attach_node = dynamic_cast(node); + if (attach_node->m_attached && attach_node->m_attached_to == object_id) + { + if (g->notifications.invalid_sync.log) + LOG(WARNING) << "Infinite ped attachment: " << "Node: " << typeid(*node).name() << " From : " << sender->get_name(); + if (g->notifications.invalid_sync.notify) + g_notification_service->push_warning(std::format("Infinite ped attachment from {}", sender->get_name()), std::format("Node: {}", typeid(*node).name())); + return true; + } + else if (attach_node->m_attached && is_ped_attachment_infinite(attach_node, object_id)) + { + if (g->notifications.invalid_sync.log) + LOG(WARNING) << "Infinite ped attachment v2: " << "Node: " << typeid(*node).name() << " From : " << sender->get_name(); + if (g->notifications.invalid_sync.notify) + g_notification_service->push_warning(std::format("Infinite ped attachment v2 from {}", sender->get_name()), std::format("Node: {}", typeid(*node).name())); + return true; + } + break; + } + case "?AVCVehicleCreationDataNode@@"_fnv1a: //CVehicleCreationDataNode + { + const auto vehicle_creation_node = dynamic_cast(node); + if (is_model_a_crash_model(vehicle_creation_node->m_model)) { + if (g->notifications.invalid_sync.log) + LOG(WARNING) << "Invalid vehicle model: " << "Model: " << HEX_TO_UPPER(vehicle_creation_node->m_model) << " From : " << sender->get_name(); + if (g->notifications.invalid_sync.notify) + g_notification_service->push_warning(std::format("Invalid vehicle model from {}", sender->get_name()), std::format("Model: 0x{:x}", vehicle_creation_node->m_model)); + return true; + } + break; + } + case "?AVCObjectCreationDataNode@@"_fnv1a: //CObjectCreationDataNode + { + const auto creation_node = dynamic_cast(node); + if (is_model_a_crash_model(creation_node->m_model)) { + if (g->notifications.invalid_sync.log) + LOG(WARNING) << "Invalid object model: " << "Model: " << HEX_TO_UPPER(creation_node->m_model) << " From : " << sender->get_name(); + if (g->notifications.invalid_sync.notify) + g_notification_service->push_warning(std::format("Invalid object model from {}", sender->get_name()), std::format("Model: 0x{:x}", creation_node->m_model)); + return true; + } + else if (is_model_a_cage_model(creation_node->m_model)) { + if (g->notifications.invalid_sync.log) + LOG(WARNING) << "Cage model: " << "Model: " << HEX_TO_UPPER(creation_node->m_model) << " From : " << sender->get_name(); + if (g->notifications.invalid_sync.notify) + g_notification_service->push_warning(std::format("Cage model from {}", sender->get_name()), std::format("Model: 0x{:x}", creation_node->m_model)); + return true; + } + break; + } + case "?AVCPlayerAppearanceDataNode@@"_fnv1a: //CPlayerAppearanceDataNode + { + const auto player_appearance_node = dynamic_cast(node); + if (is_model_a_crash_model(player_appearance_node->m_model_hash)) { + if (g->notifications.invalid_sync.log) + LOG(WARNING) << "Invalid player model: " << "Model: " << HEX_TO_UPPER(player_appearance_node->m_model_hash) << " From : " << sender->get_name(); + if (g->notifications.invalid_sync.notify) + g_notification_service->push_warning(std::format("Invalid player model from {}", sender->get_name()), std::format("Model: 0x{:x}", player_appearance_node->m_model_hash)); + return true; + } + break; + } + case "?AVCSectorDataNode@@"_fnv1a: //CSectorDataNode + { + const auto sector_node = dynamic_cast(node); + if (sector_node->m_pos_x == 712 || sector_node->m_pos_y == 712 || sector_node->m_pos_z == 712) + { + if (g->notifications.invalid_sync.log) + LOG(WARNING) << "Invalid sector position." << " From : " << sender->get_name(); + if (g->notifications.invalid_sync.notify) + g_notification_service->push_warning(std::format("Invalid sector position from {}", sender->get_name()), "Invalid sector position."); + return true; + } + break; + } + } + } + return false; + } + int64_t hooks::received_clone_sync(CNetworkObjectMgr* mgr, CNetGamePlayer* src, CNetGamePlayer* dst, eObjType sync_type, uint16_t obj_id, rage::datBitBuffer* buffer, uint16_t unk, uint32_t timestamp) { if (auto sync_tree = g_pointers->m_get_sync_tree_for_type(mgr, sync_type); sync_tree && *g_pointers->m_is_session_started) { if (auto net_obj = g_pointers->m_get_net_object(mgr, obj_id, true); net_obj) { auto tree_name = g_pointers->m_get_sync_type_info(sync_type, 0); - bool invalidsync = false; if (sync_type < eObjType::carObjType || sync_type > eObjType::unkObjType14) { if (g->notifications.out_of_allowed_range_sync_type.log) - LOG(WARNING) << "Out of range sync: " << "Type: " << sync_type << " Tree name: " << tree_name << " From: " << src->get_name(); + LOG(WARNING) << "Out of Bounds sync: " << "Type: " << sync_type << " Tree name: " << tree_name << " From: " << src->get_name(); if (g->notifications.out_of_allowed_range_sync_type.notify) g_notification_service->push_warning(std::format("Out Of Allowed Sync Range from {}", src->get_name()), std::format("Type {} in sync tree {}", std::uint16_t(sync_type), tree_name)); } @@ -60,8 +355,25 @@ namespace big { return SyncResponse::WrongOwner; } + else if ((sync_type >= eObjType::bikeObjType && sync_type <= eObjType::heliObjType) || (sync_type >= eObjType::planeObjType && sync_type <= eObjType::submarineObjType) || (sync_type >= eObjType::trailerObjType && sync_type <= eObjType::trainObjType)) + { + if(reinterpret_cast(model_info)->m_vehicle_type != model_info::get_vehicle_model(model_info->m_hash)->m_vehicle_type) + return SyncResponse::WrongOwner; + } } } + + uint32_t pos = buffer->m_bitsRead; + g_pointers->m_read_bitbuffer_into_sync_tree(sync_tree, 2, 0, buffer, 0); + buffer->Seek(pos); + + //LOG(INFO) << typeid(*tree).name() << ": " << HEX_TO_UPPER(typeid(*tree).hash_code()); //Use this to get hashes for each tree + + if (sync_tree->m_child_node_count) + { + if (check_node(sync_tree->m_sync_node, src, obj_id)) + return SyncResponse::CantApplyData; + } } else if (sync_type != eObjType::pedObjType) //We don't want to not sync a player, so we ensure it's not a ped { diff --git a/src/hooks/protections/received_event.cpp b/src/hooks/protections/received_event.cpp index f3a3c275..1d991ff4 100644 --- a/src/hooks/protections/received_event.cpp +++ b/src/hooks/protections/received_event.cpp @@ -11,7 +11,7 @@ namespace big uint16_t event_id, int event_index, int event_handled_bitset, - int unk, + int buffer_size, rage::datBitBuffer* buffer ) { @@ -178,6 +178,6 @@ namespace big break; } - return g_hooking->get_original()(event_manager, source_player, target_player, event_id, event_index, event_handled_bitset, unk, buffer); + return g_hooking->get_original()(event_manager, source_player, target_player, event_id, event_index, event_handled_bitset, buffer_size, buffer); } } diff --git a/src/pointers.cpp b/src/pointers.cpp index e498c247..0cba9a86 100644 --- a/src/pointers.cpp +++ b/src/pointers.cpp @@ -330,6 +330,12 @@ namespace big m_get_sync_type_info = ptr.add(0x8C).rip().as(); // 44 0F B7 C1 4C 8D 0D .as() }); + // Read Bitbuffer Into Sync Tree + main_batch.add("RBIST", "E8 ? ? ? ? 48 8B BC 24 B0 00 00 00", [this](memory::handle ptr) + { + m_read_bitbuffer_into_sync_tree = ptr.add(1).rip().as(); + }); + // Model Hash Table main_batch.add("MHT", "4C 03 05 ? ? ? ? EB 03", [this](memory::handle ptr) { diff --git a/src/pointers.hpp b/src/pointers.hpp index fdca2385..73dca85f 100644 --- a/src/pointers.hpp +++ b/src/pointers.hpp @@ -100,6 +100,8 @@ namespace big functions::get_sync_tree_for_type m_get_sync_tree_for_type{}; functions::get_sync_type_info m_get_sync_type_info{}; functions::get_net_object m_get_net_object{}; + functions::get_net_object_for_player m_get_net_object_for_player{}; + functions::read_bitbuffer_into_sync_tree m_read_bitbuffer_into_sync_tree{}; //Sync Signatures END PVOID m_send_net_info_to_lobby{};