summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMadCamel <madcamel@gmail.com>2009-04-07 14:52:49 +0000
committerJared Adams <jaxad0127@gmail.com>2009-04-09 07:01:45 -0600
commit25d9040b9e3b71d6534a7dedbfe34364f2a7ad66 (patch)
treec6ee0579c4d3ebb6b61cf89345ad99602e526a5e
parente4b494e5b6540c88c597c67df114c0328ea9d7b7 (diff)
downloadtmwa-25d9040b9e3b71d6534a7dedbfe34364f2a7ad66.tar.gz
tmwa-25d9040b9e3b71d6534a7dedbfe34364f2a7ad66.tar.bz2
tmwa-25d9040b9e3b71d6534a7dedbfe34364f2a7ad66.tar.xz
tmwa-25d9040b9e3b71d6534a7dedbfe34364f2a7ad66.zip
New and improved anti-spam system
-rw-r--r--src/map/atcommand.c2
-rw-r--r--src/map/battle.c52
-rw-r--r--src/map/battle.h9
-rw-r--r--src/map/clif.c72
-rw-r--r--src/map/map.h5
-rw-r--r--src/map/pc.c2
-rw-r--r--src/map/tmw.c90
-rw-r--r--src/map/tmw.h2
8 files changed, 113 insertions, 121 deletions
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index cb34569..07751bd 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -6309,7 +6309,7 @@ atcommand_npcmove(const int fd, struct map_session_data* sd,
memset(character, '\0', sizeof character);
- if (sscanf(message, "%d %d %99[^\n]", &x, &y, character) < 4)
+ if (sscanf(message, "%d %d %99[^\n]", &x, &y, character) < 3)
return -1;
nd=npc_name2id(character);
diff --git a/src/map/battle.c b/src/map/battle.c
index 7d88413..d15c36d 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -4498,7 +4498,6 @@ int battle_config_read(const char *cfgName)
battle_config.day_duration = 2*60*60*1000; // added by [Yor] (2 hours)
battle_config.night_duration = 30*60*1000; // added by [Yor] (30 minutes)
battle_config.show_mob_hp = 0; // [Valaris]
- battle_config.ban_spoof_namer = 5; // added by [Yor] (default: 5 minutes)
battle_config.hack_info_GM_level = 60; // added by [Yor] (default: 60, GM level)
battle_config.any_warp_GM_min_level = 20; // added by [Yor]
battle_config.packet_ver_flag = 63; // added by [Yor]
@@ -4513,9 +4512,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_lame_penalty = 2;
+ battle_config.chat_spam_threshold = 10000;
+ battle_config.chat_spam_flood = 10;
+ battle_config.chat_spam_ban = 1;
+ battle_config.chat_spam_warn = 8;
battle_config.chat_maxline = 255;
}
@@ -4707,7 +4708,6 @@ int battle_config_read(const char *cfgName)
{ "day_duration", &battle_config.day_duration }, // added by [Yor]
{ "night_duration", &battle_config.night_duration }, // added by [Yor]
{ "show_mob_hp", &battle_config.show_mob_hp }, // [Valaris]
- { "ban_spoof_namer", &battle_config.ban_spoof_namer }, // added by [Yor]
{ "hack_info_GM_level", &battle_config.hack_info_GM_level }, // added by [Yor]
{ "any_warp_GM_min_level", &battle_config.any_warp_GM_min_level }, // added by [Yor]
{ "packet_ver_flag", &battle_config.packet_ver_flag }, // added by [Yor]
@@ -4720,9 +4720,11 @@ int battle_config_read(const char *cfgName)
{ "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]
- { "spam_ban", &battle_config.spam_ban },
- { "spam_time", &battle_config.spam_time },
- { "spam_threshold", &battle_config.spam_threshold },
+ { "chat_lame_penalty", &battle_config.chat_lame_penalty },
+ { "chat_spam_threshold", &battle_config.chat_spam_threshold },
+ { "chat_spam_flood", &battle_config.chat_spam_flood },
+ { "chat_spam_ban", &battle_config.chat_spam_ban },
+ { "chat_spam_warn", &battle_config.chat_spam_warn },
{ "chat_maxline", &battle_config.chat_maxline }
};
@@ -4828,11 +4830,6 @@ int battle_config_read(const char *cfgName)
if (battle_config.night_duration < 0) // added by [Yor]
battle_config.night_duration = 0;
- if (battle_config.ban_spoof_namer < 0) // added by [Yor]
- battle_config.ban_spoof_namer = 0;
- else if (battle_config.ban_spoof_namer > 32767)
- battle_config.ban_spoof_namer = 32767;
-
if (battle_config.hack_info_GM_level < 0) // added by [Yor]
battle_config.hack_info_GM_level = 0;
else if (battle_config.hack_info_GM_level > 100)
@@ -4844,20 +4841,25 @@ int battle_config_read(const char *cfgName)
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.chat_spam_ban < 0)
+ battle_config.chat_spam_ban = 0;
+ else if (battle_config.chat_spam_ban > 32767)
+ battle_config.chat_spam_ban = 32767;
+
+ if (battle_config.chat_spam_flood < 0)
+ battle_config.chat_spam_flood = 0;
+ else if (battle_config.chat_spam_flood > 32767)
+ battle_config.chat_spam_flood = 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.chat_spam_warn < 0)
+ battle_config.chat_spam_warn = 0;
+ else if (battle_config.chat_spam_warn > 32767)
+ battle_config.chat_spam_warn = 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_spam_threshold < 0)
+ battle_config.chat_spam_threshold = 0;
+ else if (battle_config.chat_spam_threshold > 32767)
+ battle_config.chat_spam_threshold = 32767;
if (battle_config.chat_maxline < 1)
battle_config.chat_maxline = 1;
diff --git a/src/map/battle.h b/src/map/battle.h
index 65abac4..3c46586 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -297,7 +297,6 @@ extern struct Battle_Config {
int night_at_start; // added by [Yor]
int day_duration; // added by [Yor]
int night_duration; // added by [Yor]
- int ban_spoof_namer; // added by [Yor]
int hack_info_GM_level; // added by [Yor]
int any_warp_GM_min_level; // added by [Yor]
int packet_ver_flag; // added by [Yor]
@@ -313,9 +312,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_lame_penalty;
+ int chat_spam_threshold;
+ int chat_spam_flood;
+ int chat_spam_ban;
+ int chat_spam_warn;
int chat_maxline;
int drop_pickup_safety_zone; // [Fate] Max. distance to an object dropped by a kill by self in which dropsteal protection works
diff --git a/src/map/clif.c b/src/map/clif.c
index 455f7cc..6558ed1 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -6477,83 +6477,47 @@ void clif_parse_GetCharNameRequest(int fd, struct map_session_data *sd) {
*------------------------------------------
*/
void clif_parse_GlobalMessage(int fd, struct map_session_data *sd) { // S 008c <len>.w <str>.?B
- char *message = (char *) malloc(RFIFOW(fd,2) + 128);
- char *buf = (char *) malloc(RFIFOW(fd,2) + 4);
nullpo_retv(sd);
- memset(message, '\0', RFIFOW(fd,2) + 128);
- memset(buf, '\0', RFIFOW(fd,2) + 4);
if ((is_atcommand(fd, sd, RFIFOP(fd, 4), 0) != AtCommand_None) ||
( sd->sc_data &&
(sd->sc_data[SC_BERSERK].timer!=-1 || //バーサーク時は会話も不可
sd->sc_data[SC_NOCHAT].timer!=-1 ) )) //チャット禁止
- {
- free(message);
- free(buf);
+ {
return;
}
int ret = tmw_CheckChatSpam(sd, RFIFOP(fd,4));
if (ret == 2) clif_setwaitclose(fd);
- if (ret > 0) {
- free(message);
+ if (ret > 0)
return;
- }
//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);
-
- // information is sended to all online GM
- sprintf(message, "Hack on global message (normal message): character '%s' (account: %d) uses an other name.", sd->status.name, sd->status.account_id);
- intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, message, strlen(message) + 1);
- if (strlen(RFIFOP(fd,4)) == 0)
- strcpy(message, " This player sends a void name and a void message.");
- else
- sprintf(message, " This player sends (name:message): '%s'.", RFIFOP(fd,4));
- intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, message, strlen(message) + 1);
- // message about the ban
- if (battle_config.ban_spoof_namer > 0)
- sprintf(message, " This player has been banned for %d minute(s).", battle_config.ban_spoof_namer);
- else
- sprintf(message, " This player hasn't been banned (Ban option is disabled).");
- intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, message, strlen(message) + 1);
- // if we ban people
- if (battle_config.ban_spoof_namer > 0) {
- chrif_char_ask_name(-1, sd->status.name, 2, 0, 0, 0, 0, battle_config.ban_spoof_namer, 0); // type: 2 - ban (year, month, day, hour, minute, second)
- clif_setwaitclose(fd); // forced to disconnect because of the hack
- }
- // but for the hacker, we display on his screen (he see/look no difference).
- } else {
- int magic_status;
- // send message to others
- WBUFW(buf,0) = 0x8d;
- WBUFW(buf,2) = RFIFOW(fd,2) + 4; // len of message - 4 + 8
- WBUFL(buf,4) = sd->bl.id;
- memcpy(WBUFP(buf,8), RFIFOP(fd,4), RFIFOW(fd,2) - 4);
- magic_status = magic_message(sd, buf, WBUFW(buf, 2));
- if (magic_status) {
- sd->chat_threshold = 0;
- sd->chat_repeatmsg -= 2;
-
- if (sd->chat_repeatmsg < 0)
- sd->chat_repeatmsg = 0;
- }
+ // Simply ignore messages with spoofed/incorrect source names.
+ if (strncmp(RFIFOP(fd,4), sd->status.name, strlen(sd->status.name)) != 0)
+ return;
- if (magic_status == 0)
- clif_send(buf, WBUFW(buf,2), &sd->bl, sd->chatID ? CHAT_WOS : AREA_CHAT_WOC);
- }
+ char *buf = (char *) malloc(RFIFOW(fd,2) + 4);
+
+ // Send message to others
+ WBUFW(buf,0) = 0x8d;
+ WBUFW(buf,2) = RFIFOW(fd,2) + 4; // len of message - 4 + 8
+ WBUFL(buf,4) = sd->bl.id;
+ memcpy(WBUFP(buf,8), RFIFOP(fd,4), RFIFOW(fd,2) - 4);
+
+ if (magic_message(sd, buf, WBUFW(buf, 2)))
+ sd->chat_lines_in--;
+ else
+ clif_send(buf, WBUFW(buf,2), &sd->bl, sd->chatID ? CHAT_WOS : AREA_CHAT_WOC);
// send back message to the speaker
memcpy(WFIFOP(fd,0), RFIFOP(fd,0), RFIFOW(fd,2));
WFIFOW(fd,0) = 0x8e;
WFIFOSET(fd, WFIFOW(fd,2));
- free(message);
- free(buf);
-
+ free(buf);
return;
}
diff --git a/src/map/map.h b/src/map/map.h
index a3dbb03..fa97e0e 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -354,10 +354,9 @@ struct map_session_data {
int ignoreAll;
short sg_count;
- unsigned int chat_lastmsg_time;
+ unsigned int chat_reset_due;
+ int chat_lines_in;
char chat_lastmsg[513];
- int chat_threshold;
- int chat_repeatmsg;
};
struct npc_timerevent_list {
diff --git a/src/map/pc.c b/src/map/pc.c
index 112506c..136a2e7 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -812,7 +812,7 @@ int pc_authok(int id, int login_id2, time_t connect_until_time, short tmw_versio
}
}
- sd->chat_lastmsg_time = sd->chat_threshold = sd->chat_repeatmsg = 0;
+ sd->chat_reset_due = sd->chat_lines_in = 0;
sd->chat_lastmsg[0] = '\0';
// message of the limited time of the account
diff --git a/src/map/tmw.c b/src/map/tmw.c
index c6bfc40..775c6e1 100644
--- a/src/map/tmw.c
+++ b/src/map/tmw.c
@@ -1,5 +1,10 @@
//
+#include <string.h>
+#include <ctype.h>
+#include <stdarg.h>
+
+
#include "tmw.h"
#include "socket.h"
@@ -25,62 +30,81 @@
#include "script.h"
#include "skill.h"
#include "storage.h"
-#include "tmw.h"
#include "trade.h"
-#include <string.h>
-
int tmw_CheckChatSpam(struct map_session_data *sd, char* message) {
- unsigned int tick,elapsed = 0;
nullpo_retr(1, sd);
if (pc_isGM(sd)) return 0;
- 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 (gettick() > sd->chat_reset_due) {
+ sd->chat_reset_due = gettick() + battle_config.chat_spam_threshold;
+ sd->chat_lines_in = 0;
+ }
- if (sd->chat_threshold < 0)
- sd->chat_threshold = 0;
+ sd->chat_lines_in++;
+ // Penalty for repeating
if (strncmp(sd->chat_lastmsg, message, battle_config.chat_maxline) == 0)
- sd->chat_repeatmsg++;
- else
- sd->chat_repeatmsg--;
+ sd->chat_lines_in += battle_config.chat_lame_penalty;
- if (sd->chat_repeatmsg < 0)
- sd->chat_repeatmsg = 0;
+ // Penalty for lame, it can stack on top of the repeat penalty
+ if (tmw_CheckChatLameness(sd, message))
+ sd->chat_lines_in += battle_config.chat_lame_penalty;
strncpy((char*)sd->chat_lastmsg, message, 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 (sd->chat_lines_in >= battle_config.chat_spam_flood) {
+ sd->chat_lines_in = 0;
+ tmw_GmHackMsg("Spam detected from character '%s' (account: %d)", sd->status.name, sd->status.account_id);
- 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.chat_spam_ban > 0) {
+ clif_displaymessage(sd->fd, "You have been banned for spamming. Please do not spam.");
+ tmw_GmHackMsg("This player has been banned for %d hour(s).", battle_config.chat_spam_ban);
- 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)
+ chrif_char_ask_name(-1, sd->status.name, 2, 0, 0, 0, battle_config.chat_spam_ban, 0, 0); // type: 2 - ban (year, month, day, hour, minute, second)
return 2; // forced to disconnect
}
else
return 1; // just ignore, dont ban.
}
+ if (battle_config.chat_spam_ban && sd->chat_lines_in >= battle_config.chat_spam_warn) {
+ clif_displaymessage(sd->fd, "WARNING: You are about to be automaticly banned for spam!");
+ clif_displaymessage(sd->fd, "WARNING: Please slow down, do not repeat, and do not SHOUT!");
+ }
+
if (strlen(message) >= battle_config.chat_maxline)
return 1; // ignore lines exceeding the max length in config.
return 0;
-} \ No newline at end of file
+}
+
+// Returns true if more than 50% of input message is caps or punctuation
+int tmw_CheckChatLameness(struct map_session_data *sd, char *message)
+{
+ int count, lame;
+
+ // Ignore the name
+ message += strlen(sd->status.name);
+
+ for(count = lame = 0; *message; message++,count++)
+ if (isupper(*message) || ispunct(*message))
+ lame++;
+
+ if (count > 7 && lame > count / 2)
+ return(1);
+
+ return(0);
+}
+
+void tmw_GmHackMsg(const char *fmt, ...) {
+ char buf[513];
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsprintf(buf, fmt, ap);
+ va_end(ap);
+
+ intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, buf, strlen(buf) + 1);
+}
diff --git a/src/map/tmw.h b/src/map/tmw.h
index 44970e6..87066d9 100644
--- a/src/map/tmw.h
+++ b/src/map/tmw.h
@@ -3,3 +3,5 @@
#include "map.h"
int tmw_CheckChatSpam(struct map_session_data *sd, char* message);
+int tmw_CheckChatLameness(struct map_session_data *sd, char *message);
+void tmw_GmHackMsg(const char *fmt, ...);