From 4871dbd705d13fe0c7c772cd4e74491698e5ff5b Mon Sep 17 00:00:00 2001 From: Andreas Maerten <24669514+Yimura@users.noreply.github.com> Date: Tue, 29 Aug 2023 23:22:10 +0200 Subject: [PATCH] fix(GTADataService): not skipping bad dlc vehicles (#2055) --- src/hooks/protections/can_apply_data.cpp | 110 +++------------------ src/services/gta_data/gta_data_service.cpp | 37 +++---- src/services/gta_data/yim_fipackfile.cpp | 4 +- src/services/gta_data/yim_fipackfile.hpp | 1 + src/util/protection.cpp | 89 +++++++++++++++++ src/util/protection.hpp | 9 ++ 6 files changed, 123 insertions(+), 127 deletions(-) create mode 100644 src/util/protection.cpp create mode 100644 src/util/protection.hpp diff --git a/src/hooks/protections/can_apply_data.cpp b/src/hooks/protections/can_apply_data.cpp index ca968969..91c21436 100644 --- a/src/hooks/protections/can_apply_data.cpp +++ b/src/hooks/protections/can_apply_data.cpp @@ -65,103 +65,15 @@ #include "util/model_info.hpp" #include "util/notify.hpp" #include "util/pools.hpp" +#include "util/protection.hpp" #include "util/session.hpp" #include "util/sync_trees.hpp" #include "vehicle/CTrainConfig.hpp" #include "vehicle/CVehicleModelInfo.hpp" + namespace big { - constexpr uint32_t crash_peds[] = {RAGE_JOAAT("slod_human"), RAGE_JOAAT("slod_small_quadped"), RAGE_JOAAT("slod_large_quadped")}; - - constexpr uint32_t crash_vehicles[] = {RAGE_JOAAT("arbitergt"), RAGE_JOAAT("astron2"), RAGE_JOAAT("cyclone2"), RAGE_JOAAT("ignus2"), RAGE_JOAAT("s95")}; - - constexpr uint32_t crash_objects[] = {RAGE_JOAAT("prop_dummy_01"), RAGE_JOAAT("prop_dummy_car"), RAGE_JOAAT("prop_dummy_light"), RAGE_JOAAT("prop_dummy_plane"), 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("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("proc_dry_plants_01"), RAGE_JOAAT("proc_leafyplant_01"), RAGE_JOAAT("proc_grassplantmix_02"), RAGE_JOAAT("proc_dryplantsgrass_01"), RAGE_JOAAT("proc_dryplantsgrass_02"), RAGE_JOAAT("proc_dryplantsgrass_02"), RAGE_JOAAT("proc_grasses01"), RAGE_JOAAT("prop_dryweed_002_a"), RAGE_JOAAT("prop_fernba"), RAGE_JOAAT("prop_weed_001_aa"), RAGE_JOAAT("urbangrnfrnds_01"), RAGE_JOAAT("urbanweeds01"), RAGE_JOAAT("prop_dandy_b"), RAGE_JOAAT("v_proc2_temp"), RAGE_JOAAT("prop_fernbb"), RAGE_JOAAT("proc_drygrassfronds01"), RAGE_JOAAT("prop_log_ae"), RAGE_JOAAT("prop_grass_da"), RAGE_JOAAT("prop_fragtest_cnst_04")}; - - constexpr uint32_t valid_player_models[] = { - RAGE_JOAAT("mp_m_freemode_01"), - RAGE_JOAAT("mp_f_freemode_01"), - RAGE_JOAAT("u_m_m_filmdirector"), - RAGE_JOAAT("player_zero"), - RAGE_JOAAT("player_one"), - RAGE_JOAAT("player_two"), - // peyote - RAGE_JOAAT("A_C_Boar"), - RAGE_JOAAT("A_C_Cat_01"), - RAGE_JOAAT("A_C_Cow"), - RAGE_JOAAT("A_C_Coyote"), - RAGE_JOAAT("A_C_Deer"), - RAGE_JOAAT("A_C_Husky"), - RAGE_JOAAT("A_C_MtLion"), - RAGE_JOAAT("A_C_Pig"), - RAGE_JOAAT("A_C_Poodle"), - RAGE_JOAAT("A_C_Pug"), - RAGE_JOAAT("A_C_Rabbit_01"), - RAGE_JOAAT("A_C_Retriever"), - RAGE_JOAAT("A_C_Rottweiler"), - RAGE_JOAAT("A_C_shepherd"), - RAGE_JOAAT("A_C_Westy"), - RAGE_JOAAT("A_C_Chickenhawk"), - RAGE_JOAAT("A_C_Cormorant"), - RAGE_JOAAT("A_C_Crow"), - RAGE_JOAAT("A_C_Hen"), - RAGE_JOAAT("A_C_Pigeon"), - RAGE_JOAAT("A_C_Seagull"), - RAGE_JOAAT("A_C_Dolphin"), - RAGE_JOAAT("A_C_Fish"), - RAGE_JOAAT("A_C_KillerWhale"), - RAGE_JOAAT("A_C_SharkHammer"), - RAGE_JOAAT("A_C_SharkTiger"), - RAGE_JOAAT("A_C_Stingray"), - RAGE_JOAAT("IG_Orleans"), - RAGE_JOAAT("A_C_Chop"), - RAGE_JOAAT("A_C_HumpBack"), - }; - - inline bool is_crash_ped(uint32_t model) - { - if (!model_info::is_model_of_type(model, eModelType::Ped, eModelType::OnlineOnlyPed)) - return true; - for (auto iterator : crash_peds) - if (iterator == model) - return true; - return false; - } - - inline bool is_crash_vehicle(uint32_t model) - { - if (!model_info::is_model_of_type(model, eModelType::Vehicle, eModelType::Unk133)) - return true; - - for (auto iterator : crash_vehicles) - if (iterator == model) - return true; - - return false; - } - - inline bool is_crash_object(uint32_t model) - { - if (!model_info::get_model(model)) - return false; - - if (!model_info::is_model_of_type(model, eModelType::Object, eModelType::Time, eModelType::Weapon, eModelType::Destructable, eModelType::WorldObject, eModelType::Sprinkler, eModelType::Unk65, eModelType::Plant, eModelType::LOD, eModelType::Unk132, eModelType::Building)) - return true; - - for (auto iterator : crash_objects) - if (iterator == model) - return true; - return false; - } - - inline bool is_valid_player_model(uint32_t model) - { - for (auto iterator : valid_player_models) - if (iterator == model) - return true; - return false; - } - inline void check_player_model(player_ptr player, uint32_t model) { if (!player) @@ -170,7 +82,7 @@ namespace big if (NETWORK::NETWORK_IS_ACTIVITY_SESSION()) return; - if (!is_valid_player_model(model)) + if (!protection::is_valid_player_model(model)) { session::add_infraction(player, Infraction::INVALID_PLAYER_MODEL); } @@ -1250,7 +1162,7 @@ namespace big case sync_node_id("CVehicleCreationDataNode"): { const auto creation_node = (CVehicleCreationDataNode*)(node); - if (is_crash_vehicle(creation_node->m_model)) + if (protection::is_crash_vehicle(creation_node->m_model)) { notify::crash_blocked(sender, "invalid vehicle model"); return true; @@ -1268,7 +1180,7 @@ namespace big case sync_node_id("CDoorCreationDataNode"): { const auto creation_node = (CDoorCreationDataNode*)(node); - if (is_crash_object(creation_node->m_model)) + if (protection::is_crash_object(creation_node->m_model)) { notify::crash_blocked(sender, "invalid door model"); return true; @@ -1278,7 +1190,7 @@ namespace big case sync_node_id("CPickupCreationDataNode"): { const auto creation_node = (CPickupCreationDataNode*)(node); - if (creation_node->m_custom_model && is_crash_object(creation_node->m_custom_model)) + if (creation_node->m_custom_model && protection::is_crash_object(creation_node->m_custom_model)) { notify::crash_blocked(sender, "invalid pickup model"); return true; @@ -1331,12 +1243,12 @@ namespace big case sync_node_id("CPedCreationDataNode"): { const auto creation_node = (CPedCreationDataNode*)(node); - if (is_crash_ped(creation_node->m_model)) + if (protection::is_crash_ped(creation_node->m_model)) { notify::crash_blocked(sender, "invalid ped model"); return true; } - else if (creation_node->m_has_prop && is_crash_object(creation_node->m_prop_model)) + else if (creation_node->m_has_prop && protection::is_crash_object(creation_node->m_prop_model)) { notify::crash_blocked(sender, "invalid ped prop model"); return true; @@ -1365,7 +1277,7 @@ namespace big case sync_node_id("CObjectCreationDataNode"): { const auto creation_node = (CObjectCreationDataNode*)(node); - if (is_crash_object(creation_node->m_model)) + if (protection::is_crash_object(creation_node->m_model)) { notify::crash_blocked(sender, "invalid object model"); return true; @@ -1375,7 +1287,7 @@ namespace big case sync_node_id("CPlayerAppearanceDataNode"): { const auto player_appearance_node = (CPlayerAppearanceDataNode*)(node); - if (is_crash_ped(player_appearance_node->m_model_hash)) + if (protection::is_crash_ped(player_appearance_node->m_model_hash)) { notify::crash_blocked(sender, "invalid player model (appearance node)"); return true; @@ -1389,7 +1301,7 @@ namespace big case sync_node_id("CPlayerCreationDataNode"): { const auto player_creation_node = (CPlayerCreationDataNode*)(node); - if (is_crash_ped(player_creation_node->m_model)) + if (protection::is_crash_ped(player_creation_node->m_model)) { notify::crash_blocked(sender, "invalid player model (creation node)"); return true; diff --git a/src/services/gta_data/gta_data_service.cpp b/src/services/gta_data/gta_data_service.cpp index ffb2ff36..100f94c8 100644 --- a/src/services/gta_data/gta_data_service.cpp +++ b/src/services/gta_data/gta_data_service.cpp @@ -9,17 +9,14 @@ #include "thread_pool.hpp" #include "util/misc.hpp" #include "util/model_info.hpp" +#include "util/protection.hpp" #include "util/session.hpp" #include "util/vehicle.hpp" #include "yim_fipackfile.hpp" + namespace big { - inline bool is_crash_ped(rage::joaat_t hash) - { - return hash == RAGE_JOAAT("slod_human") || hash == RAGE_JOAAT("slod_small_quadped") || hash == RAGE_JOAAT("slod_large_quadped"); - } - bool add_if_not_exists(string_vec& vec, std::string str) { if (std::find(vec.begin(), vec.end(), str) != vec.end()) @@ -31,7 +28,7 @@ namespace big gta_data_service::gta_data_service() : m_peds_cache(g_file_manager.get_project_file("./cache/peds.bin"), 5), - m_vehicles_cache(g_file_manager.get_project_file("./cache/vehicles.bin"), 4), + m_vehicles_cache(g_file_manager.get_project_file("./cache/vehicles.bin"), 5), m_update_state(eGtaDataUpdateState::IDLE) { if (!is_cache_up_to_date()) @@ -226,7 +223,7 @@ namespace big const auto name = item.child("Name").text().as_string(); const auto hash = rage::joaat(name); - if (is_crash_ped(hash)) + if (protection::is_crash_ped(hash)) continue; if (std::find(mapped_peds.begin(), mapped_peds.end(), hash) != mapped_peds.end()) @@ -265,22 +262,8 @@ namespace big }; LOG(INFO) << "Rebuilding cache started..."; - yim_fipackfile::add_wrapper_call_back([&](yim_fipackfile& rpf_wrapper, std::filesystem::path path) -> void { - if (path.filename() == "setup2.xml") - { - std::string dlc_name; - rpf_wrapper.read_xml_file(path, [&dlc_name](pugi::xml_document& doc) { - const auto item = doc.select_node("/SSetupData/nameHash"); - dlc_name = item.node().text().as_string(); - }); - - if (dlc_name == "mpG9EC") - { - LOG(VERBOSE) << "Bad DLC, skipping..."; - } - } - else if (path.filename() == "vehicles.meta") + if (path.filename() == "vehicles.meta") { rpf_wrapper.read_xml_file(path, [&exists, &vehicles, &mapped_vehicles](pugi::xml_document& doc) { const auto& items = doc.select_nodes("/CVehicleModelInfo__InitDataList/InitDatas/Item"); @@ -290,6 +273,8 @@ namespace big const auto name = item.child("modelName").text().as_string(); const auto hash = rage::joaat(name); + if (protection::is_crash_vehicle(hash)) + continue; if (exists(mapped_vehicles, hash)) continue; @@ -462,7 +447,7 @@ namespace big const auto name = path.stem().string(); const auto hash = rage::joaat(name); - if (is_crash_ped(hash)) + if (protection::is_crash_ped(hash)) return; if (std::find(mapped_peds.begin(), mapped_peds.end(), hash) != mapped_peds.end()) @@ -485,7 +470,7 @@ namespace big yim_fipackfile::for_each_fipackfile(); } - static bool translate_lebel = false; + static bool translate_label = false; g_fiber_pool->queue_job([&] { for (auto& item : vehicles) @@ -518,10 +503,10 @@ namespace big peds.erase(it); } } - translate_lebel = true; + translate_label = true; }); - while (!translate_lebel) + while (!translate_label) { if (state() == eGtaDataUpdateState::UPDATING) script::get_current()->yield(); diff --git a/src/services/gta_data/yim_fipackfile.cpp b/src/services/gta_data/yim_fipackfile.cpp index b52d8561..61d18770 100644 --- a/src/services/gta_data/yim_fipackfile.cpp +++ b/src/services/gta_data/yim_fipackfile.cpp @@ -122,11 +122,11 @@ namespace big try { - LOG(INFO) << "gta_folder: " << reinterpret_cast(gta_folder.u8string().c_str()); + LOG(VERBOSE) << "GTA install directory: " << reinterpret_cast(gta_folder.u8string().c_str()); } catch (const std::exception& e) { - LOG(WARNING) << "Failed printing gta_folder: " << e.what(); + LOG(WARNING) << "Failed printing GTA install directory: " << e.what(); } for (const auto& entry : std::filesystem::recursive_directory_iterator(gta_folder, std::filesystem::directory_options::skip_permission_denied)) diff --git a/src/services/gta_data/yim_fipackfile.hpp b/src/services/gta_data/yim_fipackfile.hpp index 22a0f131..a469fdbc 100644 --- a/src/services/gta_data/yim_fipackfile.hpp +++ b/src/services/gta_data/yim_fipackfile.hpp @@ -7,6 +7,7 @@ namespace big class yim_fipackfile { + private: rage::fiPackfile* rpf; std::string mount_name; diff --git a/src/util/protection.cpp b/src/util/protection.cpp new file mode 100644 index 00000000..dd330275 --- /dev/null +++ b/src/util/protection.cpp @@ -0,0 +1,89 @@ +#include "protection.hpp" + +#include "model_info.hpp" + +namespace big::protection +{ + // compiler doesn't like type mismatch with "auto" + constexpr uint32_t crash_objects[] = {RAGE_JOAAT("prop_dummy_01"), RAGE_JOAAT("prop_dummy_car"), RAGE_JOAAT("prop_dummy_light"), RAGE_JOAAT("prop_dummy_plane"), 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("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("proc_dry_plants_01"), RAGE_JOAAT("proc_leafyplant_01"), RAGE_JOAAT("proc_grassplantmix_02"), RAGE_JOAAT("proc_dryplantsgrass_01"), RAGE_JOAAT("proc_dryplantsgrass_02"), RAGE_JOAAT("proc_dryplantsgrass_02"), RAGE_JOAAT("proc_grasses01"), RAGE_JOAAT("prop_dryweed_002_a"), RAGE_JOAAT("prop_fernba"), RAGE_JOAAT("prop_weed_001_aa"), RAGE_JOAAT("urbangrnfrnds_01"), RAGE_JOAAT("urbanweeds01"), RAGE_JOAAT("prop_dandy_b"), RAGE_JOAAT("v_proc2_temp"), RAGE_JOAAT("prop_fernbb"), RAGE_JOAAT("proc_drygrassfronds01"), RAGE_JOAAT("prop_log_ae"), RAGE_JOAAT("prop_grass_da"), RAGE_JOAAT("prop_fragtest_cnst_04")}; + bool is_crash_object(rage::joaat_t model) + { + if (!model_info::get_model(model)) + return false; + if (!model_info::is_model_of_type(model, eModelType::Object, eModelType::Time, eModelType::Weapon, eModelType::Destructable, eModelType::WorldObject, eModelType::Sprinkler, eModelType::Unk65, eModelType::Plant, eModelType::LOD, eModelType::Unk132, eModelType::Building)) + return true; + for (auto iterator : crash_objects) + if (iterator == model) + return true; + return false; + } + + constexpr auto crash_peds = {RAGE_JOAAT("slod_human"), RAGE_JOAAT("slod_small_quadped"), RAGE_JOAAT("slod_large_quadped")}; + bool is_crash_ped(rage::joaat_t model) + { + for (auto iterator : crash_peds) + if (iterator == model) + return true; + if (!model_info::is_model_of_type(model, eModelType::Ped, eModelType::OnlineOnlyPed)) + return true; + return false; + } + + constexpr auto crash_vehicles = {RAGE_JOAAT("arbitergt"), RAGE_JOAAT("astron2"), RAGE_JOAAT("cyclone2"), RAGE_JOAAT("ignus2"), RAGE_JOAAT("s95")}; + bool is_crash_vehicle(rage::joaat_t model) + { + for (auto iterator : crash_vehicles) + if (iterator == model) + return true; + if (!model_info::is_model_of_type(model, eModelType::Vehicle, eModelType::Unk133)) + return true; + return false; + } + + constexpr auto valid_player_models = { + RAGE_JOAAT("mp_m_freemode_01"), + RAGE_JOAAT("mp_f_freemode_01"), + RAGE_JOAAT("u_m_m_filmdirector"), + RAGE_JOAAT("player_zero"), + RAGE_JOAAT("player_one"), + RAGE_JOAAT("player_two"), + // peyote + RAGE_JOAAT("A_C_Boar"), + RAGE_JOAAT("A_C_Cat_01"), + RAGE_JOAAT("A_C_Cow"), + RAGE_JOAAT("A_C_Coyote"), + RAGE_JOAAT("A_C_Deer"), + RAGE_JOAAT("A_C_Husky"), + RAGE_JOAAT("A_C_MtLion"), + RAGE_JOAAT("A_C_Pig"), + RAGE_JOAAT("A_C_Poodle"), + RAGE_JOAAT("A_C_Pug"), + RAGE_JOAAT("A_C_Rabbit_01"), + RAGE_JOAAT("A_C_Retriever"), + RAGE_JOAAT("A_C_Rottweiler"), + RAGE_JOAAT("A_C_shepherd"), + RAGE_JOAAT("A_C_Westy"), + RAGE_JOAAT("A_C_Chickenhawk"), + RAGE_JOAAT("A_C_Cormorant"), + RAGE_JOAAT("A_C_Crow"), + RAGE_JOAAT("A_C_Hen"), + RAGE_JOAAT("A_C_Pigeon"), + RAGE_JOAAT("A_C_Seagull"), + RAGE_JOAAT("A_C_Dolphin"), + RAGE_JOAAT("A_C_Fish"), + RAGE_JOAAT("A_C_KillerWhale"), + RAGE_JOAAT("A_C_SharkHammer"), + RAGE_JOAAT("A_C_SharkTiger"), + RAGE_JOAAT("A_C_Stingray"), + RAGE_JOAAT("IG_Orleans"), + RAGE_JOAAT("A_C_Chop"), + RAGE_JOAAT("A_C_HumpBack"), + }; + bool is_valid_player_model(rage::joaat_t model) + { + for (auto iterator : valid_player_models) + if (iterator == model) + return true; + return false; + } +} \ No newline at end of file diff --git a/src/util/protection.hpp b/src/util/protection.hpp new file mode 100644 index 00000000..e7ac98d9 --- /dev/null +++ b/src/util/protection.hpp @@ -0,0 +1,9 @@ +#pragma once + +namespace big::protection +{ + bool is_crash_object(rage::joaat_t model); + bool is_crash_ped(rage::joaat_t model); + bool is_crash_vehicle(rage::joaat_t model); + bool is_valid_player_model(rage::joaat_t model); +}