From a870845a71dbe1879d6d316f0726c3f75e38249c Mon Sep 17 00:00:00 2001 From: Dennis Friis Date: Thu, 10 Apr 2008 01:04:30 +0000 Subject: Add configurable anti spam system, with possible auto ban. --- src/map/battle.c | 33 ++++++++++++++++++++++++++++++++- src/map/battle.h | 5 +++++ src/map/clif.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- src/map/map.h | 7 ++++++- src/map/pc.c | 3 +++ 5 files changed, 96 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/map/battle.c b/src/map/battle.c index 7a6dd47..8577a29 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -5016,6 +5016,11 @@ int battle_config_read(const char *cfgName) battle_config.area_size = 14; + battle_config.spam_ban = 6; + battle_config.spam_time = 3000; + battle_config.spam_threshold = 10; + battle_config.chat_maxline = 255; + //SQL-only options start #ifndef TXT_ONLY battle_config.mail_system = 0; @@ -5238,7 +5243,11 @@ int battle_config_read(const char *cfgName) { "max_cloth_color", &battle_config.max_cloth_color }, // added by [MouseJstr] { "castrate_dex_scale", &battle_config.castrate_dex_scale }, // added by [MouseJstr] { "area_size", &battle_config.area_size }, // added by [MouseJstr] - { "muting_players", &battle_config.muting_players}, // added by [Apple] + { "muting_players", &battle_config.muting_players}, // added by [Apple] + { "spam_ban", &battle_config.spam_ban }, + { "spam_time", &battle_config.spam_time }, + { "spam_threshold", &battle_config.spam_threshold }, + { "chat_maxline", &battle_config.chat_maxline }, //SQL-only options start #ifndef TXT_ONLY { "mail_system", &battle_config.mail_system }, // added by [Valaris] @@ -5363,6 +5372,28 @@ int battle_config_read(const char *cfgName) else if (battle_config.any_warp_GM_min_level > 100) battle_config.any_warp_GM_min_level = 100; + + if (battle_config.spam_ban < 0) + battle_config.spam_ban = 0; + else if (battle_config.spam_ban > 32767) + battle_config.spam_ban = 32767; + + if (battle_config.spam_time < 0) + battle_config.spam_time = 0; + else if (battle_config.spam_time > 32767) + battle_config.spam_time = 32767; + + if (battle_config.spam_threshold < 0) + battle_config.spam_threshold = 0; + else if (battle_config.spam_threshold > 32767) + battle_config.spam_threshold = 32767; + + if (battle_config.chat_maxline < 1) + battle_config.chat_maxline = 1; + else if (battle_config.chat_maxline > 512) + battle_config.chat_maxline = 512; + + // at least 1 client must be accepted if ((battle_config.packet_ver_flag & 63) == 0) // added by [Yor] battle_config.packet_ver_flag = 63; // accept all clients diff --git a/src/map/battle.h b/src/map/battle.h index 8f09d22..27e1e6f 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -331,6 +331,11 @@ extern struct Battle_Config { int castrate_dex_scale; // added by [MouseJstr] int area_size; // added by [MouseJstr] + int spam_ban; + int spam_time; + int spam_threshold; + int chat_maxline; + #ifndef TXT_ONLY /* SQL-only options */ int mail_system; // [Valaris] #endif diff --git a/src/map/clif.c b/src/map/clif.c index f847a56..0a6559c 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -7397,7 +7397,7 @@ void clif_parse_GetCharNameRequest(int fd, struct map_session_data *sd) { void clif_parse_GlobalMessage(int fd, struct map_session_data *sd) { // S 008c .w .?B char *message = (char *) malloc(RFIFOW(fd,2) + 128); char *buf = (char *) malloc(RFIFOW(fd,2) + 4); - + int tick,elapsed = 0; nullpo_retv(sd); memset(message, '\0', RFIFOW(fd,2) + 128); @@ -7413,6 +7413,55 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data *sd) { // S 008c < return; } + if (!pc_isGM(sd)) + { + tick = gettick(); + elapsed = tick - sd->chat_lastmsg_time; + sd->chat_lastmsg_time = tick; + + if (elapsed < battle_config.spam_time) + sd->chat_threshold++; + + sd->chat_threshold -= (int)(elapsed / (battle_config.spam_time/2)); + + if (sd->chat_threshold < 0) + sd->chat_threshold = 0; + + if (strncmp(sd->chat_lastmsg, RFIFOP(fd,4), battle_config.chat_maxline) == 0) + sd->chat_repeatmsg++; + else + sd->chat_repeatmsg--; + + if (sd->chat_repeatmsg < 0) + sd->chat_repeatmsg = 0; + + strncpy((char*)sd->chat_lastmsg, RFIFOP(fd,4), battle_config.chat_maxline); + + if (sd->chat_threshold > battle_config.spam_threshold || sd->chat_repeatmsg > battle_config.spam_threshold) { + sprintf(message, "Spam detected from character '%s' (account: %d), threshold was exceeded.", sd->status.name, sd->status.account_id); + printf("%s\n", message); + intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, message, strlen(message) + 1); + + if (battle_config.spam_ban > 0) + sprintf(message, " This player has been banned for %d hours(s).", battle_config.spam_ban); + else + sprintf(message, " This player hasn't been banned (Ban option is disabled)."); + printf("%s\n", message); + intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, message, strlen(message) + 1); + + if (battle_config.spam_ban > 0) + { + chrif_char_ask_name(-1, sd->status.name, 2, 0, 0, 0, battle_config.spam_ban, 0, 0); // type: 2 - ban (year, month, day, hour, minute, second) + clif_setwaitclose(fd); // forced to disconnect + } + else + return; // just ignore, dont ban. + } + + if (strlen(RFIFOP(fd,4)) >= battle_config.chat_maxline) + return; // ignore lines exceeding the max length in config. + } + //printf("clif_parse_GlobalMessage: message: '%s'.\n", RFIFOP(fd,4)); if (strncmp(RFIFOP(fd,4), sd->status.name, strlen(sd->status.name)) != 0) { printf("Hack on global message: character '%s' (account: %d), use an other name to send a (normal) message.\n", sd->status.name, sd->status.account_id); diff --git a/src/map/map.h b/src/map/map.h index 703bbb6..3c7e2de 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -308,7 +308,12 @@ struct map_session_data { } ignore[80]; int ignoreAll; short sg_count; - + + unsigned int chat_lastmsg_time; + char chat_lastmsg[513]; + int chat_threshold; + int chat_repeatmsg; + #ifndef TXT_ONLY int mail_counter; // mail counter for mail system [Valaris] #endif diff --git a/src/map/pc.c b/src/map/pc.c index 790fc32..9a96008 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -836,6 +836,9 @@ int pc_authok(int id, int login_id2, time_t connect_until_time, struct mmo_chars } } + sd->chat_lastmsg_time = sd->chat_threshold = sd->chat_repeatmsg = 0; + sd->chat_lastmsg[0] = '\0'; + #ifndef TXT_ONLY if(battle_config.mail_system) mail_check(sd,1); // check mail at login [Valaris] -- cgit v1.2.3-70-g09d2