diff --git a/src/hooks/protections/script_event_handler.cpp b/src/hooks/protections/script_event_handler.cpp index 34f532ac..fe5a4705 100644 --- a/src/hooks/protections/script_event_handler.cpp +++ b/src/hooks/protections/script_event_handler.cpp @@ -5,7 +5,7 @@ #include "hooking/hooking.hpp" #include "lua/lua_manager.hpp" #include "util/math.hpp" -#include "util/script_database.hpp" +#include "util/protection.hpp" #include "util/session.hpp" #include @@ -16,8 +16,6 @@ namespace big { - static const script_protection_DB script_database; - void format_string(std::string_view player_name, std::string_view protection_type, bool should_log, bool should_notify) { if (should_log) @@ -381,7 +379,7 @@ namespace big case eRemoteEvent::InteriorControl: { int interior = (int)args[3]; - if (interior < 0 || interior > 166) // the upper bound will change after an update + if (interior < 0 || interior > 171) // the upper bound will change after an update { if (auto plyr = g_player_service->get_by_id(player->m_player_id)) session::add_infraction(plyr, Infraction::TRIED_KICK_PLAYER); @@ -448,23 +446,15 @@ namespace big { auto script_id = args[3]; - protection_status protection_status = script_database.get_protection_status(script_id); - - if (protection_status == protection_status::BLOCK_ALWAYS) + if (!protection::should_allow_script_launch(script_id)) { + LOGF(stream::script_events, WARNING, "Blocked StartScriptBegin from {} with script ID {}", plyr->get_name(), script_id); g.reactions.start_script.process(plyr); return true; } - - if (!NETWORK::NETWORK_IS_ACTIVITY_SESSION() && protection_status == protection_status::BLOCK_IN_FREEMODE) + else { - g.reactions.start_script.process(plyr); - return true; - } - - if (protection_status == protection_status::ALLOWED_NOTIFY) - { - g.reactions.start_script.only_notify(plyr); + LOGF(stream::script_events, INFO, "Allowed StartScriptBegin from {} with script ID {}", plyr->get_name(), script_id); } } } diff --git a/src/logger/logger.hpp b/src/logger/logger.hpp index 8373ffc6..5415d749 100644 --- a/src/logger/logger.hpp +++ b/src/logger/logger.hpp @@ -7,7 +7,8 @@ namespace stream { inline auto net_events = std::make_shared("net_events"); inline auto net_messages = std::make_shared("net_messages"); - inline auto net_sync = std::make_shared("net_sync"); + inline auto net_sync = std::make_shared("net_sync"); + inline auto script_events = std::make_shared("script_events"); } namespace big diff --git a/src/util/protection.cpp b/src/util/protection.cpp index 575495f6..7ffe2ea0 100644 --- a/src/util/protection.cpp +++ b/src/util/protection.cpp @@ -1,6 +1,6 @@ #include "protection.hpp" - #include "model_info.hpp" +#include "scripts.hpp" namespace big::protection { @@ -75,8 +75,59 @@ namespace big::protection "A_C_Chop"_J, "A_C_HumpBack"_J, }; + + enum class script_block_state + { + BLOCK_ALWAYS, + BLOCK_IN_FREEMODE + }; + + static std::unordered_map script_block_states = + {{ + {"AM_Darts"_J, script_block_state::BLOCK_ALWAYS}, + {"AM_PI_MENU"_J, script_block_state::BLOCK_ALWAYS}, + {"fm_intro"_J, script_block_state::BLOCK_ALWAYS}, + {"golf_mp"_J, script_block_state::BLOCK_IN_FREEMODE}, + {"tennis_network_mp"_J, script_block_state::BLOCK_IN_FREEMODE}, + {"Pilot_School_MP"_J, script_block_state::BLOCK_ALWAYS}, + {"FM_Impromptu_DM_Controler"_J, script_block_state::BLOCK_IN_FREEMODE}, + {"fm_deathmatch_controler"_J, script_block_state::BLOCK_IN_FREEMODE}, + {"FM_Race_Controler"_J, script_block_state::BLOCK_IN_FREEMODE}, + {"FM_Horde_Controler"_J, script_block_state::BLOCK_IN_FREEMODE}, + {"am_darts_apartment"_J, script_block_state::BLOCK_ALWAYS}, + {"grid_arcade_cabinet"_J, script_block_state::BLOCK_ALWAYS}, + {"scroll_arcade_cabinet"_J, script_block_state::BLOCK_ALWAYS}, + {"example_arcade"_J, script_block_state::BLOCK_ALWAYS}, + {"road_arcade"_J, script_block_state::BLOCK_ALWAYS}, + {"gunslinger_arcade"_J, script_block_state::BLOCK_ALWAYS}, // Badlands Revenge II? + {"wizard_arcade"_J, script_block_state::BLOCK_ALWAYS}, + {"ggsm_arcade"_J, script_block_state::BLOCK_ALWAYS}, // Space Monkey? + {"puzzle"_J, script_block_state::BLOCK_ALWAYS}, // Qub3d? + {"camhedz_arcade"_J, script_block_state::BLOCK_ALWAYS}, + {"SCTV"_J, script_block_state::BLOCK_ALWAYS}} + }; + bool is_valid_player_model(rage::joaat_t model) { return valid_player_models.contains(model); } + + bool should_allow_script_launch(int launcher_script) + { + if (launcher_script >= launcher_scripts.size()) + return false; + + auto script = launcher_scripts[launcher_script]; + + if (auto it = script_block_states.find(script); it != script_block_states.end()) + { + if (it->second == script_block_state::BLOCK_ALWAYS) + return false; + + if (it->second == script_block_state::BLOCK_IN_FREEMODE && !NETWORK::NETWORK_IS_ACTIVITY_SESSION()) + return false; + } + + return true; + } } diff --git a/src/util/protection.hpp b/src/util/protection.hpp index e7ac98d9..cb390ea2 100644 --- a/src/util/protection.hpp +++ b/src/util/protection.hpp @@ -6,4 +6,5 @@ namespace big::protection 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); + bool should_allow_script_launch(int launcher_script); } diff --git a/src/util/script_database.hpp b/src/util/script_database.hpp deleted file mode 100644 index c1c0d27f..00000000 --- a/src/util/script_database.hpp +++ /dev/null @@ -1,78 +0,0 @@ -#include -#include - -namespace big -{ - enum class protection_status - { - ALLOWED_NOTIFY, - BLOCK_ALWAYS, - BLOCK_IN_FREEMODE - }; - - struct script_info - { - std::string name; - protection_status status; - }; - - class script_protection_DB - { - public: - script_protection_DB() - { - initialize_script_DB(); - } - - protection_status get_protection_status(int scriptId) const - { - auto it = m_script_map.find(scriptId); - if (it != m_script_map.end()) - { - return it->second.status; - } - return protection_status::ALLOWED_NOTIFY; - } - - // Could be useful for debugging someday... - std::string get_script_name(int scriptId) const - { - auto it = m_script_map.find(scriptId); - if (it != m_script_map.end()) - { - return it->second.name; - } - return ""; - } - - private: - std::unordered_map m_script_map; - - void initialize_script_DB() - { - // Please try to keep this in numerical order for code readability - // Last script ID update 5/5/2024 - m_script_map = {{9, {"AM_Darts", protection_status::BLOCK_ALWAYS}}, - {17, {"AM_PI_MENU", protection_status::BLOCK_ALWAYS}}, - {20, {"fm_intro", protection_status::BLOCK_ALWAYS}}, - {212, {"golf_mp", protection_status::BLOCK_IN_FREEMODE}}, - {214, {"tennis_network_mp", protection_status::BLOCK_IN_FREEMODE}}, - {215, {"Pilot_School_MP", protection_status::BLOCK_ALWAYS}}, - {216, {"FM_Impromptu_DM_Controler", protection_status::BLOCK_IN_FREEMODE}}, - {218, {"fm_deathmatch_controler", protection_status::BLOCK_IN_FREEMODE}}, - {221, {"FM_Race_Controler", protection_status::BLOCK_IN_FREEMODE}}, - {222, {"FM_Horde_Controler", protection_status::BLOCK_IN_FREEMODE}}, - {224, {"am_darts_apartment", protection_status::BLOCK_ALWAYS}}, - {226, {"grid_arcade_cabinet", protection_status::BLOCK_ALWAYS}}, - {227, {"scroll_arcade_cabinet", protection_status::BLOCK_ALWAYS}}, - {228, {"example_arcade", protection_status::BLOCK_ALWAYS}}, - {229, {"road_arcade", protection_status::BLOCK_ALWAYS}}, - {230, {"gunslinger_arcade", protection_status::BLOCK_ALWAYS}}, // Badlands Revenge II? - {231, {"wizard_arcade", protection_status::BLOCK_ALWAYS}}, - {235, {"ggsm_arcade", protection_status::BLOCK_ALWAYS}}, // Space Monkey? - {236, {"puzzle", protection_status::BLOCK_ALWAYS}}, // Qub3d? - {237, {"camhedz_arcade", protection_status::BLOCK_ALWAYS}}, - {238, {"SCTV", protection_status::BLOCK_ALWAYS}}}; - } - }; -}