From 7aad4c5860ace1ce93e2c218de4054ed2805af34 Mon Sep 17 00:00:00 2001 From: HCR-750F <54973190+sch-lda@users.noreply.github.com> Date: Sat, 4 Nov 2023 21:54:32 +0800 Subject: [PATCH] refactor(reaction): rework reaction code (#2331) 1. Allow interloper_reaction to use timeout. 2. Fix crash reaction(except TSE) cannot use announce in chat. 3. Allow all friends to bypass auto kick spammers, modder flag and reactions. Provides an alternative for users who experience this weird bug https://github.com/YimMenu/YimMenu/issues/2266 . They can just trust their friends until someone provides valuable information for developers to fix. 4. Allow trusting specific players (bypass auto kick spammers, modder flag and reactions). 5. Trust the whole session temporarily (Avoid team members being kicked when in mission). 6. Remove duplicate logs when blocking crash (except for TSE crash) 7. remove unused gamer_instruction_kick in reaction list 8. Allow announce in team only chat --- src/backend/reactions/interloper_reaction.cpp | 12 ++- src/backend/reactions/interloper_reaction.hpp | 2 +- src/backend/reactions/reaction.cpp | 20 +++-- src/backend/reactions/reaction.hpp | 3 +- src/core/settings.hpp | 8 +- .../assign_physical_index.cpp | 22 +++-- .../player_management/network_player_mgr.cpp | 2 + src/hooks/protections/receive_net_message.cpp | 3 +- .../protections/script_event_handler.cpp | 4 +- .../player_database/persistent_player.hpp | 3 +- src/services/players/player.hpp | 1 + src/util/notify.hpp | 86 ++++++++++++------- src/util/session.hpp | 2 + src/views/network/view_network.cpp | 7 ++ src/views/network/view_player_database.cpp | 1 + src/views/players/player/player_info.cpp | 6 ++ src/views/players/view_player.cpp | 4 + src/views/players/view_players.cpp | 4 +- src/views/settings/view_reaction_settings.cpp | 7 +- 19 files changed, 135 insertions(+), 62 deletions(-) diff --git a/src/backend/reactions/interloper_reaction.cpp b/src/backend/reactions/interloper_reaction.cpp index ecf2cadf..b51dd332 100644 --- a/src/backend/reactions/interloper_reaction.cpp +++ b/src/backend/reactions/interloper_reaction.cpp @@ -20,6 +20,14 @@ namespace big { if (!attacker->is_valid() || !victim->is_valid()) return; + if ((attacker->is_friend() && g.session.trust_friends) || attacker->is_trusted || g.session.trust_session) + return; + + if (log) + { + uint64_t rockstar_id = attacker->get_net_data() == nullptr ? 0 : attacker->get_net_data()->m_gamer_handle.m_rockstar_id; + LOGF(WARNING, "Received {} from {} ({}), victim is {}", m_event_name, attacker->get_name(), rockstar_id, victim->get_name()); + } if (announce_in_chat) { @@ -34,8 +42,8 @@ namespace big if (g_hooking->get_original()(*g_pointers->m_gta.m_send_chat_ptr, g_player_service->get_self()->get_net_data(), chat, - false)) - notify::draw_chat(chat, g_player_service->get_self()->get_name(), false); + is_team_only)) + notify::draw_chat(chat, g_player_service->get_self()->get_name(), is_team_only); }); } diff --git a/src/backend/reactions/interloper_reaction.hpp b/src/backend/reactions/interloper_reaction.hpp index 431eee1f..d20c640e 100644 --- a/src/backend/reactions/interloper_reaction.hpp +++ b/src/backend/reactions/interloper_reaction.hpp @@ -14,7 +14,7 @@ namespace big bool m_blockable; bool m_karmaable; - NLOHMANN_DEFINE_TYPE_INTRUSIVE(interloper_reaction, announce_in_chat, notify, log, add_to_player_db, block_joins, kick, block, karma, timeout)// json doesn't serialize parent fields automatically + NLOHMANN_DEFINE_TYPE_INTRUSIVE(interloper_reaction, announce_in_chat, is_team_only, notify, log, add_to_player_db, block_joins, kick, block, karma, timeout) // json doesn't serialize parent fields automatically virtual void process(player_ptr attacker, player_ptr victim); }; diff --git a/src/backend/reactions/reaction.cpp b/src/backend/reactions/reaction.cpp index 0ab3ac0b..54a9fc2b 100644 --- a/src/backend/reactions/reaction.cpp +++ b/src/backend/reactions/reaction.cpp @@ -19,12 +19,6 @@ namespace big void reaction::process_common(player_ptr player) { - if (log) - { - uint64_t rockstar_id = player->get_net_data() == nullptr ? 0 : player->get_net_data()->m_gamer_handle.m_rockstar_id; - LOG(WARNING) << std::format("Received {} from {} ({})", m_event_name, player->get_name(), rockstar_id); - } - if (add_to_player_db) { auto entry = g_player_database_service->get_or_create_player(player); @@ -49,7 +43,7 @@ namespace big player->block_net_events = true; player->block_clone_sync = true; player->block_clone_create = true; - LOG(WARNING) << std::format("{} has been timed out", player->get_name()); + LOGF(WARNING, "{} has been timed out", player->get_name()); } } @@ -58,6 +52,14 @@ namespace big { if (!player->is_valid()) return; + if ((player->is_friend() && g.session.trust_friends) || player->is_trusted || g.session.trust_session) + return; + + if (log) + { + uint64_t rockstar_id = player->get_net_data() == nullptr ? 0 : player->get_net_data()->m_gamer_handle.m_rockstar_id; + LOGF(WARNING, "Received {} from {} ({})", m_event_name, player->get_name(), rockstar_id); + } if (announce_in_chat) { @@ -71,8 +73,8 @@ namespace big if (g_hooking->get_original()(*g_pointers->m_gta.m_send_chat_ptr, g_player_service->get_self()->get_net_data(), chat, - false)) - notify::draw_chat(chat, g_player_service->get_self()->get_name(), false); + is_team_only)) + notify::draw_chat(chat, g_player_service->get_self()->get_name(), is_team_only); }); } diff --git a/src/backend/reactions/reaction.hpp b/src/backend/reactions/reaction.hpp index 9bb2dd21..7d2d6583 100644 --- a/src/backend/reactions/reaction.hpp +++ b/src/backend/reactions/reaction.hpp @@ -9,6 +9,7 @@ namespace big { public: bool announce_in_chat = false; + bool is_team_only = false; bool notify = true; bool log = true; bool add_to_player_db = false; @@ -20,7 +21,7 @@ namespace big const char* m_notify_message; const char* m_announce_message; - NLOHMANN_DEFINE_TYPE_INTRUSIVE(reaction, announce_in_chat, notify, log, add_to_player_db, block_joins, kick, timeout) + NLOHMANN_DEFINE_TYPE_INTRUSIVE(reaction, announce_in_chat, is_team_only, notify, log, add_to_player_db, block_joins, kick, timeout) reaction(const char* event_name, const char* notify_message, const char* announce_message); virtual void process(player_ptr player); diff --git a/src/core/settings.hpp b/src/core/settings.hpp index 74e65a23..1db78c72 100644 --- a/src/core/settings.hpp +++ b/src/core/settings.hpp @@ -220,9 +220,7 @@ namespace big reaction spectate{"Spectate", "%s is spectating you", "%s is spectating me!"}; interloper_reaction spectate_others{"Spectate Others", "%s is spectating %s!", "%s is spectating %s!", false, false}; - reaction gamer_instruction_kick{"Gamer Instruction Kick", "Blocked Gamer Instruction Kick from %s", "%s tried to kick me out!"}; - - NLOHMANN_DEFINE_TYPE_INTRUSIVE(reactions, bounty, ceo_money, ceo_kick, clear_wanted_level, crash, end_session_kick, fake_deposit, force_mission, force_teleport, gta_banner, kick_from_interior, mc_teleport, network_bail, personal_vehicle_destroyed, remote_off_radar, rotate_cam, send_to_cutscene, send_to_location, sound_spam, spectate_notification, give_collectible, transaction_error, tse_freeze, tse_sender_mismatch, vehicle_kick, teleport_to_warehouse, trigger_business_raid, start_activity, start_script, null_function_kick, destroy_personal_vehicle, clear_ped_tasks, turn_into_beast, remote_wanted_level, remote_wanted_level_others, remote_ragdoll, kick_vote, report_cash_spawn, modder_detection, game_anti_cheat_modder_detection, request_control_event, report, gamer_instruction_kick, send_to_interior, spectate, spectate_others) + NLOHMANN_DEFINE_TYPE_INTRUSIVE(reactions, bounty, ceo_money, ceo_kick, clear_wanted_level, crash, end_session_kick, fake_deposit, force_mission, force_teleport, gta_banner, kick_from_interior, mc_teleport, network_bail, personal_vehicle_destroyed, remote_off_radar, rotate_cam, send_to_cutscene, send_to_location, sound_spam, spectate_notification, give_collectible, transaction_error, tse_freeze, tse_sender_mismatch, vehicle_kick, teleport_to_warehouse, trigger_business_raid, start_activity, start_script, null_function_kick, destroy_personal_vehicle, clear_ped_tasks, turn_into_beast, remote_wanted_level, remote_wanted_level_others, remote_ragdoll, kick_vote, report_cash_spawn, modder_detection, game_anti_cheat_modder_detection, request_control_event, report, send_to_interior, spectate, spectate_others) } reactions{}; struct player @@ -398,6 +396,8 @@ namespace big bool join_in_sctv_slots = false; bool lock_session = false; bool allow_friends_into_locked_session = false; + bool trust_friends = false; + bool trust_session = false; const char chat_command_prefix = '/'; const char chat_output_prefix = '>'; @@ -438,7 +438,7 @@ namespace big bool fast_join = false; - NLOHMANN_DEFINE_TYPE_INTRUSIVE(session, log_chat_messages, log_text_messages, decloak_players, force_session_host, force_script_host, player_magnet_enabled, player_magnet_count, is_team, join_in_sctv_slots, kick_chat_spammers, kick_host_when_forcing_host, explosion_karma, damage_karma, disable_traffic, disable_peds, force_thunder, block_ceo_money, randomize_ceo_colors, block_jobs, block_muggers, block_ceo_raids, send_to_apartment_idx, send_to_warehouse_idx, chat_commands, chat_command_default_access_level, show_cheating_message, anonymous_bounty, lock_session, fast_join, unhide_players_from_player_list, allow_friends_into_locked_session) + NLOHMANN_DEFINE_TYPE_INTRUSIVE(session, log_chat_messages, log_text_messages, decloak_players, force_session_host, force_script_host, player_magnet_enabled, player_magnet_count, is_team, join_in_sctv_slots, kick_chat_spammers, kick_host_when_forcing_host, explosion_karma, damage_karma, disable_traffic, disable_peds, force_thunder, block_ceo_money, randomize_ceo_colors, block_jobs, block_muggers, block_ceo_raids, send_to_apartment_idx, send_to_warehouse_idx, chat_commands, chat_command_default_access_level, show_cheating_message, anonymous_bounty, lock_session, fast_join, unhide_players_from_player_list, allow_friends_into_locked_session, trust_friends) } session{}; struct settings diff --git a/src/hooks/player_management/assign_physical_index.cpp b/src/hooks/player_management/assign_physical_index.cpp index 2c6dda39..c2f7e612 100644 --- a/src/hooks/player_management/assign_physical_index.cpp +++ b/src/hooks/player_management/assign_physical_index.cpp @@ -99,9 +99,13 @@ namespace big if (auto entry = g_player_database_service->get_player_by_rockstar_id( plyr->get_net_data()->m_gamer_handle.m_rockstar_id)) { - plyr->is_modder = entry->is_modder; - plyr->block_join = entry->block_join; - plyr->block_join_reason = entry->block_join_reason; + plyr->is_trusted = entry->is_trusted; + if (!(plyr->is_friend() && g.session.trust_friends)) + { + plyr->is_modder = entry->is_modder; + plyr->block_join = entry->block_join; + plyr->block_join_reason = entry->block_join_reason; + } if (strcmp(plyr->get_name(), entry->name.data())) { @@ -127,17 +131,17 @@ namespace big if (g.session.lock_session && g_player_service->get_self()->is_host() && *g_pointers->m_gta.m_is_session_started) { - if (plyr->is_friend() && g.session.allow_friends_into_locked_session) + if ((plyr->is_friend() && g.session.allow_friends_into_locked_session) || plyr->is_trusted) { - g_notification_service->push_success("Lock Session", - std::format("A friend with the name of {} has been allowed to join the locked session", - plyr->get_net_data()->m_name)); + g_notification_service->push_success("LOBBY_LOCK"_T.data(), + std::vformat("LOBBY_LOCK_ALLOWED"_T.data(), + std::make_format_args(plyr->get_net_data()->m_name))); } else { dynamic_cast(command::get(RAGE_JOAAT("multikick")))->call(plyr, {}); - g_notification_service->push_warning("Lock Session", - std::format("A player with the name of {} has been denied entry", plyr->get_net_data()->m_name)); + g_notification_service->push_warning("LOBBY_LOCK"_T.data(), + std::vformat("LOBBY_LOCK_DENIED"_T.data(), std::make_format_args(plyr->get_net_data()->m_name))); } } diff --git a/src/hooks/player_management/network_player_mgr.cpp b/src/hooks/player_management/network_player_mgr.cpp index a8b37711..7e0e0119 100644 --- a/src/hooks/player_management/network_player_mgr.cpp +++ b/src/hooks/player_management/network_player_mgr.cpp @@ -17,6 +17,7 @@ namespace big bool result = g_hooking->get_original()(_this, a2, a3, a4); + g.session.trust_session = false; g_player_service->player_join(_this->m_local_net_player); g_lua_manager->trigger_event(); @@ -33,6 +34,7 @@ namespace big if (g.notifications.network_player_mgr_shutdown.notify) g_notification_service->push("NETWORK_PLAYER_MGR"_T.data(), "NETWORK_PLAYER_MGR_DESTROY"_T.data()); + g.session.trust_session = false; g_hooking->get_original()(_this); g_lua_manager->trigger_event(); } diff --git a/src/hooks/protections/receive_net_message.cpp b/src/hooks/protections/receive_net_message.cpp index ae919892..b5d65ca0 100644 --- a/src/hooks/protections/receive_net_message.cpp +++ b/src/hooks/protections/receive_net_message.cpp @@ -116,7 +116,8 @@ namespace big if (g.session.log_chat_messages) spam::log_chat(message, player, true); player->is_spammer = true; - if (g.session.kick_chat_spammers) + if (g.session.kick_chat_spammers + && !(player->is_trusted || (player->is_friend() && g.session.trust_friends) || g.session.trust_session)) { if (g_player_service->get_self()->is_host()) dynamic_cast(command::get(RAGE_JOAAT("breakup")))->call(player, {}), diff --git a/src/hooks/protections/script_event_handler.cpp b/src/hooks/protections/script_event_handler.cpp index 8eeb394d..af1ce6d1 100644 --- a/src/hooks/protections/script_event_handler.cpp +++ b/src/hooks/protections/script_event_handler.cpp @@ -379,7 +379,9 @@ namespace big break; } - case eRemoteEvent::DestroyPersonalVehicle: g.reactions.destroy_personal_vehicle.process(plyr); return true; + case eRemoteEvent::DestroyPersonalVehicle: + g.reactions.destroy_personal_vehicle.process(plyr); + return true; case eRemoteEvent::KickFromInterior: if (scr_globals::globalplayer_bd.as()->Entries[self::id].SimpleInteriorData.Owner != plyr->id()) { diff --git a/src/services/player_database/persistent_player.hpp b/src/services/player_database/persistent_player.hpp index 0132cc83..89a0699e 100644 --- a/src/services/player_database/persistent_player.hpp +++ b/src/services/player_database/persistent_player.hpp @@ -46,6 +46,7 @@ namespace big bool block_join = false; int block_join_reason = 1; bool is_modder = false; + bool is_trusted = false; bool notify_online = false; std::unordered_set infractions; std::string custom_infraction_reason = ""; @@ -66,7 +67,7 @@ namespace big std::string game_mode_id = ""; rage::rlSessionInfo redirect_info{}; - NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(persistent_player, name, rockstar_id, block_join, block_join_reason, is_modder, notify_online, infractions, custom_infraction_reason, notes, command_access_level, join_redirect, join_redirect_preference) + NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(persistent_player, name, rockstar_id, block_join, block_join_reason, is_modder, is_trusted, notify_online, infractions, custom_infraction_reason, notes, command_access_level, join_redirect, join_redirect_preference) const char* get_infraction_description(int infraction); std::string get_all_infraction_descriptions(); diff --git a/src/services/players/player.hpp b/src/services/players/player.hpp index 0d8fd1f0..2b3ed80d 100644 --- a/src/services/players/player.hpp +++ b/src/services/players/player.hpp @@ -80,6 +80,7 @@ namespace big bool m_block_permanent_vehicles = false; bool is_modder = false; + bool is_trusted = false; bool block_join = false; int block_join_reason = 0; bool is_spammer = false; diff --git a/src/util/notify.hpp b/src/util/notify.hpp index 86dd5884..c78b8d10 100644 --- a/src/util/notify.hpp +++ b/src/util/notify.hpp @@ -6,6 +6,8 @@ #include "pointers.hpp" #include "script.hpp" #include "services/players/player_service.hpp" +#include "fiber_pool.hpp" +#include "hooking.hpp" #include