Added more spam messages to the filter. (#2488)
* Added more spam messages to the filter. * Removed duplicate remote control vehicle button from the player vehicle menu. * Added heuristical spam detector. * Fixed clock in spam logger. * Added date output to the chat logger. * Added a message to show the user when someone is spamming. More static text translations. * Removed redundant mobile global in scr_globals.hpp. * Added a spam reason to the spam logger. * Added team/all to the chat logger. Added a logger call for the user's chats.
This commit is contained in:
parent
b80865f34c
commit
95b9724fff
@ -10,12 +10,12 @@ namespace big
|
||||
|
||||
virtual void on_tick() override
|
||||
{
|
||||
*scr_globals::mobile.as<PBOOL>() = TRUE;
|
||||
*scr_globals::transaction_overlimit.as<PBOOL>() = TRUE;
|
||||
}
|
||||
|
||||
virtual void on_disable() override
|
||||
{
|
||||
*scr_globals::mobile.as<PBOOL>() = FALSE;
|
||||
*scr_globals::transaction_overlimit.as<PBOOL>() = FALSE;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -378,4 +378,11 @@ namespace big
|
||||
RELEASE = WM_KEYUP,
|
||||
DOWN = WM_KEYDOWN
|
||||
};
|
||||
|
||||
enum SpamReason : int
|
||||
{
|
||||
NOT_A_SPAMMER,
|
||||
STATIC_DETECTION,
|
||||
TIMER_DETECTION
|
||||
};
|
||||
}
|
||||
|
@ -41,8 +41,6 @@ namespace big::scr_globals
|
||||
|
||||
static inline const script_global dance_state(1950837);
|
||||
|
||||
static inline const script_global mobile(20483);
|
||||
|
||||
static inline const script_global transaction_overlimit(20483);
|
||||
|
||||
static inline const script_global stats(2359296);
|
||||
|
@ -402,6 +402,9 @@ namespace big
|
||||
bool allow_friends_into_locked_session = false;
|
||||
bool trust_friends = false;
|
||||
bool trust_session = false;
|
||||
bool use_spam_timer = true;
|
||||
float spam_timer = 2.5f;
|
||||
int spam_length = 55;
|
||||
|
||||
const char chat_command_prefix = '/';
|
||||
const char chat_output_prefix = '>';
|
||||
@ -442,7 +445,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, trust_friends)
|
||||
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, use_spam_timer, spam_timer, spam_length)
|
||||
} session{};
|
||||
|
||||
struct settings
|
||||
|
@ -83,17 +83,17 @@ namespace rage
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool WriteBool(bool integer)
|
||||
bool WriteBool(bool boolean)
|
||||
{
|
||||
return big::g_pointers->m_gta.m_write_bitbuf_bool(this, integer, 1);
|
||||
return big::g_pointers->m_gta.m_write_bitbuf_bool(this, boolean, 1);
|
||||
}
|
||||
bool ReadBool(bool* integer)
|
||||
bool ReadBool(bool* boolean)
|
||||
{
|
||||
return big::g_pointers->m_gta.m_read_bitbuf_bool(this, integer, 1);
|
||||
return big::g_pointers->m_gta.m_read_bitbuf_bool(this, boolean, 1);
|
||||
}
|
||||
bool ReadPeerId(uint64_t* integer)
|
||||
bool ReadPeerId(uint64_t* peer_id)
|
||||
{
|
||||
return this->ReadQWord(integer, 0x40);
|
||||
return this->ReadQWord(peer_id, 0x40);
|
||||
}
|
||||
uint64_t ReadBits(size_t numBits)
|
||||
{
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "hooking.hpp"
|
||||
#include "packet.hpp"
|
||||
#include "services/players/player_service.hpp"
|
||||
#include "util/spam.hpp"
|
||||
|
||||
namespace big
|
||||
{
|
||||
@ -27,6 +28,9 @@ namespace big
|
||||
gamer_handle_serialize(g_player_service->get_self()->get_net_data()->m_gamer_handle, msg.m_buffer);
|
||||
msg.write<bool>(is_team, 1);
|
||||
|
||||
if (g.session.log_chat_messages)
|
||||
spam::log_chat(message, g_player_service->get_self(), SpamReason::NOT_A_SPAMMER, is_team);
|
||||
|
||||
if (*g_pointers->m_gta.m_is_session_started)
|
||||
for (auto& player : g_player_service->players())
|
||||
if (player.second && player.second->is_valid())
|
||||
|
@ -107,14 +107,18 @@ namespace big
|
||||
{
|
||||
char message[256];
|
||||
buffer.ReadString(message, 256);
|
||||
bool is_team;
|
||||
buffer.ReadBool(&is_team);
|
||||
|
||||
if (player->is_spammer)
|
||||
return true;
|
||||
|
||||
if (spam::is_text_spam(message))
|
||||
if (auto spam_reason = spam::is_text_spam(message, player))
|
||||
{
|
||||
if (g.session.log_chat_messages)
|
||||
spam::log_chat(message, player, true);
|
||||
spam::log_chat(message, player, spam_reason, is_team);
|
||||
g_notification_service->push("PROTECTIONS"_T.data(),
|
||||
std::format("{} {}", player->get_name(), "IS_A_SPAMMER"_T.data()));
|
||||
player->is_spammer = true;
|
||||
if (g.session.kick_chat_spammers
|
||||
&& !(player->is_trusted || (player->is_friend() && g.session.trust_friends) || g.session.trust_session))
|
||||
@ -131,7 +135,7 @@ namespace big
|
||||
else
|
||||
{
|
||||
if (g.session.log_chat_messages)
|
||||
spam::log_chat(message, player, false);
|
||||
spam::log_chat(message, player, SpamReason::NOT_A_SPAMMER, is_team);
|
||||
|
||||
if (g.session.chat_commands && message[0] == g.session.chat_command_prefix)
|
||||
command::process(std::string(message + 1), std::make_shared<chat_command_context>(player));
|
||||
@ -204,7 +208,7 @@ namespace big
|
||||
|
||||
if (reason == KickReason::VOTED_OUT)
|
||||
{
|
||||
g_notification_service->push_warning("Protections", "You have been kicked by the host");
|
||||
g_notification_service->push_warning("PROTECTIONS"_T.data(), "YOU_HAVE_BEEN_KICKED"_T.data());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ namespace big
|
||||
if (g.notifications.transaction_rate_limit.log)
|
||||
LOG(WARNING) << "Received transaction rate limit";
|
||||
if (g.notifications.transaction_rate_limit.notify)
|
||||
g_notification_service->push_warning("Transaction Rate Limit", "You're receiving transaction rate limits, whatever you're doing do it less.");
|
||||
g_notification_service->push_warning("TRANSACTION_RATE_LIMIT"_T.data(), "TRANSACTION_RATE_LIMIT_MESSAGE"_T.data());
|
||||
|
||||
*scr_globals::transaction_overlimit.as<PBOOL>() = FALSE;
|
||||
|
||||
|
@ -71,7 +71,7 @@ namespace big
|
||||
VEHICLE::SET_VEHICLE_ENGINE_ON(m_handle, false, true, false);
|
||||
}
|
||||
else
|
||||
g_notification_service->push_warning("Toxic", "Failed to take control of vehicle.");
|
||||
g_notification_service->push_warning("TOXIC"_T.data(), "VEHICLE_FAILED_CONTROL"_T.data());
|
||||
}},
|
||||
{"FIX VEHICLE",
|
||||
[this] {
|
||||
@ -83,7 +83,7 @@ namespace big
|
||||
VEHICLE::SET_VEHICLE_DIRT_LEVEL(m_handle, 0.f);
|
||||
}
|
||||
else
|
||||
g_notification_service->push_warning("Warning", "Failed to take control of vehicle.");
|
||||
g_notification_service->push_warning("WARNING"_T.data(), "VEHICLE_FAILED_CONTROL"_T.data());
|
||||
}},
|
||||
{"BURST TIRES",
|
||||
[this] {
|
||||
@ -97,7 +97,7 @@ namespace big
|
||||
}
|
||||
}
|
||||
else
|
||||
g_notification_service->push_warning("Toxic", "Failed to take control of vehicle.");
|
||||
g_notification_service->push_warning("TOXIC"_T.data(), "VEHICLE_FAILED_CONTROL"_T.data());
|
||||
}},
|
||||
{"HALT",
|
||||
[this] {
|
||||
@ -106,7 +106,7 @@ namespace big
|
||||
VEHICLE::BRING_VEHICLE_TO_HALT(m_handle, 1, 5, true);
|
||||
}
|
||||
else
|
||||
g_notification_service->push_warning("Toxic", "Failed to take control of vehicle.");
|
||||
g_notification_service->push_warning("TOXIC"_T.data(), "VEHICLE_FAILED_CONTROL"_T.data());
|
||||
}},
|
||||
{"COPY VEHICLE",
|
||||
[this] {
|
||||
@ -119,14 +119,14 @@ namespace big
|
||||
if (entity::take_control_of(m_handle))
|
||||
VEHICLE::SET_VEHICLE_FORWARD_SPEED(m_handle, 79);
|
||||
else
|
||||
g_notification_service->push_warning("Toxic", "Failed to take control of vehicle.");
|
||||
g_notification_service->push_warning("TOXIC"_T.data(), "VEHICLE_FAILED_CONTROL"_T.data());
|
||||
}},
|
||||
{"LAUNCH",
|
||||
[this] {
|
||||
if (entity::take_control_of(m_handle))
|
||||
ENTITY::APPLY_FORCE_TO_ENTITY(m_handle, 1, 0.f, 0.f, 50000.f, 0.f, 0.f, 0.f, 0, 0, 1, 1, 0, 1);
|
||||
else
|
||||
g_notification_service->push_warning("Toxic", "Failed to take control of vehicle.");
|
||||
g_notification_service->push_warning("TOXIC"_T.data(), "VEHICLE_FAILED_CONTROL"_T.data());
|
||||
}},
|
||||
{"EJECT",
|
||||
[this] {
|
||||
|
@ -88,6 +88,7 @@ namespace big
|
||||
std::optional<uint32_t> player_time_value;
|
||||
std::optional<std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>> player_time_value_received_time;
|
||||
std::optional<uint32_t> time_difference;
|
||||
std::optional<std::chrono::time_point<std::chrono::steady_clock>> last_message_time;
|
||||
uint32_t num_time_syncs_sent = 9999;
|
||||
|
||||
bool block_explosions = false;
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include "file_manager/file.hpp"
|
||||
#include "services/players/player_service.hpp"
|
||||
#include "core/enums.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -59,32 +60,66 @@ namespace
|
||||
"LevelLifters",
|
||||
". com",
|
||||
"$1,000,000,000",
|
||||
"Instant Delivery",
|
||||
"0 Ban Risk",
|
||||
"Discord For Cheap Money",
|
||||
};
|
||||
}
|
||||
|
||||
namespace big::spam
|
||||
{
|
||||
inline bool is_text_spam(const char* text)
|
||||
inline SpamReason is_text_spam(const char* text, player_ptr player)
|
||||
{
|
||||
if (g.session.use_spam_timer)
|
||||
{
|
||||
if (player->last_message_time.has_value())
|
||||
{
|
||||
auto currentTime = std::chrono::steady_clock::now();
|
||||
auto diff = std::chrono::duration_cast<std::chrono::seconds>(currentTime - player->last_message_time.value());
|
||||
player->last_message_time.emplace(currentTime);
|
||||
|
||||
if (strlen(text) > g.session.spam_length && diff.count() <= g.session.spam_timer)
|
||||
return SpamReason::TIMER_DETECTION;
|
||||
}
|
||||
else
|
||||
{
|
||||
player->last_message_time.emplace(std::chrono::steady_clock::now());
|
||||
}
|
||||
}
|
||||
for (auto e : spam_texts)
|
||||
if (strstr(text, e) != 0)
|
||||
return true;
|
||||
return SpamReason::STATIC_DETECTION;
|
||||
|
||||
return false;
|
||||
return SpamReason::NOT_A_SPAMMER;
|
||||
}
|
||||
|
||||
inline void log_chat(char* msg, player_ptr player, bool is_spam)
|
||||
inline void log_chat(char* msg, player_ptr player, SpamReason spam_reason, bool is_team)
|
||||
{
|
||||
std::ofstream log(g_file_manager.get_project_file(is_spam ? "./spam.log" : "./chat.log").get_path(), std::ios::app);
|
||||
std::ofstream log(g_file_manager.get_project_file(spam_reason != SpamReason::NOT_A_SPAMMER ? "./spam.log" : "./chat.log").get_path(), std::ios::app);
|
||||
|
||||
auto& data = *player->get_net_data();
|
||||
auto ip = player->get_ip_address();
|
||||
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;
|
||||
auto timer = std::chrono::system_clock::to_time_t(now);
|
||||
auto local_time = *std::localtime(&timer);
|
||||
|
||||
std::string spam_reason_str = "";
|
||||
|
||||
switch (spam_reason)
|
||||
{
|
||||
case SpamReason::STATIC_DETECTION: spam_reason_str = "(Static Detection) "; break;
|
||||
case SpamReason::TIMER_DETECTION: spam_reason_str = "(Timer Detection) "; break;
|
||||
}
|
||||
|
||||
log << spam_reason_str << "[" << std::put_time(&local_time, "%m/%d/%Y %I:%M:%S") << ":" << std::setfill('0') << std::setw(3) << ms.count() << " " << std::put_time(&local_time, "%p") << "] ";
|
||||
|
||||
if (ip)
|
||||
log << player->get_name() << " (" << data.m_gamer_handle.m_rockstar_id << ") <" << (int)ip.value().m_field1 << "."
|
||||
<< (int)ip.value().m_field2 << "." << (int)ip.value().m_field3 << "." << (int)ip.value().m_field4 << ">: " << msg << std::endl;
|
||||
<< (int)ip.value().m_field2 << "." << (int)ip.value().m_field3 << "." << (int)ip.value().m_field4 << "> " << ((is_team == true) ? "[TEAM]: " : "[ALL]: ") << msg << std::endl;
|
||||
else
|
||||
log << player->get_name() << " (" << data.m_gamer_handle.m_rockstar_id << ") <UNKNOWN>: " << msg << std::endl;
|
||||
log << player->get_name() << " (" << data.m_gamer_handle.m_rockstar_id << ") <UNKNOWN> " << ((is_team == true) ? "[TEAM]: " : "[ALL]: ") << msg << std::endl;
|
||||
|
||||
log.close();
|
||||
}
|
||||
|
@ -196,6 +196,12 @@ namespace big
|
||||
if (ImGui::BeginListBox("##chat", get_listbox_dimensions()))
|
||||
{
|
||||
static char msg[256];
|
||||
ImGui::Checkbox("USE_SPAM_TIMER"_T.data(), &g.session.use_spam_timer);
|
||||
if (g.session.use_spam_timer)
|
||||
{
|
||||
ImGui::SliderFloat("SPAM_TIMER"_T.data(), &g.session.spam_timer, 0.5f, 5.0f);
|
||||
ImGui::SliderInt("SPAM_LENGTH"_T.data(), &g.session.spam_length, 1, 256);
|
||||
}
|
||||
ImGui::Checkbox("AUTO_KICK_CHAT_SPAMMERS"_T.data(), &g.session.kick_chat_spammers);
|
||||
ImGui::Checkbox("LOG_CHAT_MSG"_T.data(), &g.session.log_chat_messages);
|
||||
ImGui::Checkbox("LOG_TXT_MSG"_T.data(), &g.session.log_text_messages);
|
||||
|
@ -50,8 +50,6 @@ namespace big
|
||||
ImGui::SameLine();
|
||||
components::player_command_button<"sshuntright">(g_player_service->get_selected(), {});
|
||||
|
||||
components::player_command_button<"rcplayer">(g_player_service->get_selected());
|
||||
|
||||
ImGui::EndListBox();
|
||||
}
|
||||
ImGui::EndGroup();
|
||||
|
Reference in New Issue
Block a user