From ff6c5041af889bbc986199316daba8676b8e9cfd Mon Sep 17 00:00:00 2001 From: pk910 Date: Sun, 23 Oct 2011 00:13:34 +0200 Subject: [PATCH] completely changed the NeonSpam settings / scanner management --- database.upgrade.sql | 41 +++ src/bot_NeonSpam.c | 57 ++- src/bot_NeonSpam.h | 75 +++- src/cmd_neonspam_set.c | 668 ++++++++++++++--------------------- src/event_neonspam_chanmsg.c | 170 +++++---- src/event_neonspam_join.c | 93 ++--- src/mysqlConn.c | 2 +- 7 files changed, 532 insertions(+), 574 deletions(-) diff --git a/database.upgrade.sql b/database.upgrade.sql index f44c5ee..dbd063d 100644 --- a/database.upgrade.sql +++ b/database.upgrade.sql @@ -18,3 +18,44 @@ ALTER TABLE `owner_history` CHANGE `owner_history_uid` `owner_history_to_uid` IN ALTER TABLE `owner_history` ADD `owner_history_from_uid` INT( 11 ) NOT NULL AFTER `owner_history_to_uid`; -- version: 3 + +ALTER TABLE `channels` + DROP `channel_scanstate`, + DROP `channel_scanexcept`, + DROP `channel_maxrepeat`, + DROP `channel_repeatreaction`, + DROP `channel_maxflood`, + DROP `channel_floodtime`, + DROP `channel_floodreaction`, + DROP `channel_maxjoin`, + DROP `channel_jointime`, + DROP `channel_joinreaction`; + +ALTER TABLE `channels` + ADD `channel_scanner` VARCHAR(50) NULL, + ADD `channel_spam_limit` SMALLINT(3) NULL, + ADD `channel_spam_reaction` TINYINT(1) NULL, + ADD `channel_spam_reaction_duration` MEDIUMINT(7) NULL, + ADD `channel_spam_except` SMALLINT(3) NULL, + ADD `channel_flood_limit` SMALLINT(3) NULL, + ADD `channel_flood_time` SMALLINT(3) NULL, + ADD `channel_flood_reaction` TINYINT(1) NULL, + ADD `channel_flood_reaction_duration` MEDIUMINT(7) NULL, + ADD `channel_flood_except` SMALLINT(3) NULL, + ADD `channel_join_limit` SMALLINT(3) NULL, + ADD `channel_join_time` SMALLINT(3) NULL, + ADD `channel_join_reaction` TINYINT(1) NULL, + ADD `channel_join_reaction_duration` MEDIUMINT(7) NULL, + ADD `channel_join_except` SMALLINT(3) NULL, + ADD `channel_botnet_bantime` MEDIUMINT(7) NULL, + ADD `channel_botnet_except` SMALLINT(3) NULL, + ADD `channel_caps_percent` TINYINT(3) NULL, + ADD `channel_caps_reaction` TINYINT(1) NULL, + ADD `channel_caps_reaction_duration` MEDIUMINT(7) NULL, + ADD `channel_caps_except` SMALLINT(3) NULL, + ADD `channel_digit_percent` TINYINT(3) NULL, + ADD `channel_digit_reaction` TINYINT(1) NULL, + ADD `channel_digit_reaction_duration` MEDIUMINT(7) NULL, + ADD `channel_digit_except` SMALLINT(3) NULL; + +-- version: 4 \ No newline at end of file diff --git a/src/bot_NeonSpam.c b/src/bot_NeonSpam.c index fdfd914..911c9b8 100644 --- a/src/bot_NeonSpam.c +++ b/src/bot_NeonSpam.c @@ -44,6 +44,7 @@ static const struct default_language_entry msgtab[] = { {NULL, NULL} }; +static unsigned int convertNeonSpamSettingsToFlags(char *str); static int loadNeonSpamSettings(struct ChanNode *chan); static void createSpamNode(struct ChanUser *chanuser); static void freeJoinNode(struct NeonSpamJoinNode *joinnode); @@ -131,6 +132,38 @@ static void start_bots() { } } +char* convertNeonSpamSettingsToString(unsigned int flags, char *buffer) { + int pos = 0; + unsigned int i; + int j = 0; + char *chars = SPAMSETTINGS_CHARS; + for(i = 1; i <= SPAMSETTINGS_FLAGS; i = i << 1) { + if(flags & i) + buffer[pos++] = chars[j]; + j++; + } + buffer[pos] = '\0'; + return buffer; +} + +static unsigned int convertNeonSpamSettingsToFlags(char *str) { + unsigned int i = 1, flags = 0; + int j = 0; + char *chars = SPAMSETTINGS_CHARS; + while(*str) { + for(; i <= SPAMSETTINGS_FLAGS; i = i << 1) { + if(*str == chars[j]) { + flags |= i; + j++; + break; + } + j++; + } + str++; + } + return flags; +} + static int loadNeonSpamSettings(struct ChanNode *chan) { if(chan->spam_settings) return 0; struct NeonSpamSettings *settings = malloc(sizeof(*settings)); @@ -141,21 +174,27 @@ static int loadNeonSpamSettings(struct ChanNode *chan) { MYSQL_RES *res; MYSQL_ROW row, defaults = NULL; loadChannelSettings(chan); - printf_mysql_query("SELECT `channel_scanstate`, `channel_maxrepeat`, `channel_maxflood`, `channel_floodtime`, `channel_maxjoin`, `channel_jointime`, `channel_scanexcept` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id); + printf_mysql_query("SELECT `channel_scanner`, `channel_spam_limit`, `channel_spam_except`, `channel_flood_limit`, `channel_flood_time`, `channel_flood_except`, `channel_join_limit`, `channel_join_time`, `channel_join_except`, `channel_caps_percent`, `channel_caps_except`, `channel_digit_percent`, `channel_digit_except` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id); res = mysql_use(); row = mysql_fetch_row(res); - if(!row[0] || !row[1] || !row[2] || !row[3] || !row[4] || !row[5]) { - printf_mysql_query("SELECT `channel_scanstate`, `channel_maxrepeat`, `channel_maxflood`, `channel_floodtime`, `channel_maxjoin`, `channel_jointime`, `channel_scanexcept` FROM `channels` WHERE `channel_name` = 'defaults'"); + if(!row[0] || !row[1] || !row[2] || !row[3] || !row[4] || !row[5] || !row[6] || !row[7] || !row[8] || !row[9] || !row[10] || !row[11] || !row[12]) { + printf_mysql_query("SELECT `channel_scanner`, `channel_spam_limit`, `channel_spam_except`, `channel_flood_limit`, `channel_flood_time`, `channel_flood_except`, `channel_join_limit`, `channel_join_time`, `channel_join_except`, `channel_caps_percent`, `channel_caps_except`, `channel_digit_percent`, `channel_digit_except` FROM `channels` WHERE `channel_name` = 'defaults'"); res = mysql_use(); defaults = mysql_fetch_row(res); } - settings->flags = atoi(row[0] ? row[0] : defaults[0]); + settings->flags = convertNeonSpamSettingsToFlags(row[0] ? row[0] : defaults[0]); settings->spam_amount = atoi(row[1] ? row[1] : defaults[1]); - settings->flood_amount = atoi(row[2] ? row[2] : defaults[2]); - settings->flood_time = atoi(row[3] ? row[3] : defaults[3]); - settings->join_amount = atoi(row[4] ? row[4] : defaults[4]); - settings->join_time = atoi(row[5] ? row[5] : defaults[5]); - settings->exceptlevel = atoi(row[6] ? row[6] : defaults[6]); + settings->exceptlevel[SPAMSETTINGS_SPAMEXCINDEX] = atoi(row[2] ? row[2] : defaults[2]); + settings->sensibility_amount[SPAMSETTINGS_FLOODSENINDEX] = atoi(row[3] ? row[3] : defaults[3]); + settings->sensibility_time[SPAMSETTINGS_FLOODSENINDEX] = atoi(row[4] ? row[4] : defaults[4]); + settings->exceptlevel[SPAMSETTINGS_FLOODEXCINDEX] = atoi(row[5] ? row[5] : defaults[5]); + settings->sensibility_amount[SPAMSETTINGS_JOINSENINDEX] = atoi(row[6] ? row[6] : defaults[6]); + settings->sensibility_time[SPAMSETTINGS_JOINSENINDEX] = atoi(row[7] ? row[7] : defaults[7]); + settings->exceptlevel[SPAMSETTINGS_JOINEXCINDEX] = atoi(row[8] ? row[8] : defaults[8]); + settings->percent[SPAMSETTINGS_CAPSPERCENTINDEX] = atoi(row[9] ? row[9] : defaults[9]); + settings->exceptlevel[SPAMSETTINGS_CAPSEXCINDEX] = atoi(row[10] ? row[10] : defaults[10]); + settings->percent[SPAMSETTINGS_DIGITPERCENTINDEX] = atoi(row[11] ? row[11] : defaults[11]); + settings->exceptlevel[SPAMSETTINGS_DIGITEXCINDEX] = atoi(row[12] ? row[12] : defaults[12]); settings->join_nodes = NULL; settings->lastmsg_time = 0; int i; diff --git a/src/bot_NeonSpam.h b/src/bot_NeonSpam.h index 77fb4ee..e3a32ef 100644 --- a/src/bot_NeonSpam.h +++ b/src/bot_NeonSpam.h @@ -20,13 +20,64 @@ #include "main.h" -#define SPAMSETTINGS_SPAMSCAN 0x0001 -#define SPAMSETTINGS_FLOODSCAN 0x0002 -#define SPAMSETTINGS_JOINSCAN 0x0004 -#define SPAMSETTINGS_SCANOPS 0x0008 -#define SPAMSETTINGS_SCANVOICE 0x0010 -#define SPAMSETTINGS_BOTNETSCAN 0x0020 -#define SPAMSETTINGS_KICKEDBOTQUEUE 0x0040 +//SPAMSCAN +#define SPAMSETTINGS_SPAMSCAN 0x000001 +#define SPAMSETTINGS_SPAMSCAN_OPS 0x000002 +#define SPAMSETTINGS_SPAMSCAN_VOICE 0x000004 +#define SPAMSETTINGS_SPAMCHARS "abc" +#define SPAMSETTINGS_SPAMEXCINDEX 0 + +//FLOODSCAN +#define SPAMSETTINGS_FLOODSCAN 0x000008 +#define SPAMSETTINGS_FLOODSCAN_OPS 0x000010 +#define SPAMSETTINGS_FLOODSCAN_VOICE 0x000020 +#define SPAMSETTINGS_FLOODCHARS "def" +#define SPAMSETTINGS_FLOODEXCINDEX 1 +#define SPAMSETTINGS_FLOODSENINDEX 0 + +//JOINSCAN +#define SPAMSETTINGS_JOINSCAN 0x000040 +#define SPAMSETTINGS_JOINSCAN_OPS 0x000080 +#define SPAMSETTINGS_JOINSCAN_VOICE 0x000100 +#define SPAMSETTINGS_JOINCHARS "ghi" +#define SPAMSETTINGS_JOINEXCINDEX 2 +#define SPAMSETTINGS_JOINSENINDEX 1 + +//BOTNET SCAN +#define SPAMSETTINGS_BOTNETSCAN 0x000200 +#define SPAMSETTINGS_BOTNETSCAN_OPS 0x000400 +#define SPAMSETTINGS_BOTNETSCAN_VOICE 0x000800 +#define SPAMSETTINGS_BOTNETSCAN_STRIPCC 0x001000 +#define SPAMSETTINGS_BOTNETCHARS "jklm" +#define SPAMSETTINGS_BOTNETEXCINDEX 3 + +//CAPSSCAN +#define SPAMSETTINGS_CAPSSCAN 0x002000 +#define SPAMSETTINGS_CAPSSCAN_OPS 0x004000 +#define SPAMSETTINGS_CAPSSCAN_VOICE 0x008000 +#define SPAMSETTINGS_CAPSCHARS "nop" +#define SPAMSETTINGS_CAPSEXCINDEX 4 +#define SPAMSETTINGS_CAPSPERCENTINDEX 0 + +//DIGITSCAN +#define SPAMSETTINGS_DIGITSCAN 0x010000 +#define SPAMSETTINGS_DIGITSCAN_OPS 0x020000 +#define SPAMSETTINGS_DIGITSCAN_VOICE 0x040000 +#define SPAMSETTINGS_DIGITCHARS "qrs" +#define SPAMSETTINGS_DIGITEXCINDEX 5 +#define SPAMSETTINGS_DIGITPERCENTINDEX 1 + + +#define SPAMSETTINGS_CHARS SPAMSETTINGS_SPAMCHARS SPAMSETTINGS_FLOODCHARS SPAMSETTINGS_JOINCHARS SPAMSETTINGS_BOTNETCHARS SPAMSETTINGS_CAPSCHARS SPAMSETTINGS_DIGITCHARS +#define SPAMSETTINGS_FLAGS 0x07ffff /* all flags that can be stored in the database */ +#define SPAMSETTINGS_EXCEPTINDEXES 6 +#define SPAMSETTINGS_SENSIBILITYINDEXES 2 +#define SPAMSETTINGS_PERCENTINDEXES 2 + +//SCRIPT FLAGS +#define SPAMSETTINGS_KICKEDBOTQUEUE 0x080000 +#define SPAMSETTINGS_ISTIMEBAN 0x100000 +#define SPAMSETTINGS_SETTIMEBAN 0x200000 #define MAX_FLOOD_AMOUNT 300 #define MIN_FLOOD_AMOUNT 2 @@ -42,11 +93,10 @@ struct NeonSpamSettings { unsigned int flags; unsigned char spam_amount; - unsigned char flood_amount; - unsigned char flood_time; - unsigned char join_amount; - unsigned char join_time; - unsigned int exceptlevel : 10; + unsigned char sensibility_amount[SPAMSETTINGS_SENSIBILITYINDEXES]; + unsigned char sensibility_time[SPAMSETTINGS_SENSIBILITYINDEXES]; + unsigned int exceptlevel[SPAMSETTINGS_EXCEPTINDEXES]; + unsigned char percent[SPAMSETTINGS_PERCENTINDEXES]; //joinflood struct NeonSpamJoinNode *join_nodes; @@ -88,5 +138,6 @@ void loop_NeonSpam(); void free_NeonSpam(); void freeNeonSpamSettings(struct NeonSpamSettings *settings); +char* convertNeonSpamSettingsToString(unsigned int flags, char *buffer); #endif \ No newline at end of file diff --git a/src/cmd_neonspam_set.c b/src/cmd_neonspam_set.c index 41e7825..9890a62 100644 --- a/src/cmd_neonspam_set.c +++ b/src/cmd_neonspam_set.c @@ -17,60 +17,102 @@ #include "cmd_neonspam.h" -typedef char* neonspam_cmd_set_function(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument); -static void neonspam_cmd_set_setting(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int setting, char *argument); -static char* neonspam_cmd_set_trigger(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument); -static char* neonspam_cmd_set_spamlimit(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument); -static char* neonspam_cmd_set_spamreaction(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument); -static char* neonspam_cmd_set_floodreaction(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument); -static char* neonspam_cmd_setjoinfloodreaction(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument); -static char* neonspam_cmd_setspamscan(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument); -static char* neonspam_cmd_setfloodscan(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument); -static char* neonspam_cmd_setjoinfloodscan(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument); -static char* neonspam_cmd_setbotnetscan(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument); -static char* neonspam_cmd_setscanchanops(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument); -static char* neonspam_cmd_setscanvoiced(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument); -static char* neonspam_cmd_setexceptlevel(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument); -static char* neonspam_cmd_setfloodsensibility(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument); -static char* neonspam_cmd_setjoinsensibility(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument); - -#define NS_VALID_FUNCTION 0x01 -#define NS_VALID_STRING 0x02 -#define NS_VALID_ACCESS 0x04 -#define NS_VALID_NO501 0x08 -#define NS_VALID_OPTIONS 0x10 -#define NS_VALID_NUMERIC 0x20 -#define NS_VALID_BOOLEAN 0x40 - -#define NS_HAS_OPT 0x100 /* options (SET_OPTION_{NAME}_{VALUE}) */ -#define NS_HAS_HELP 0x200 /* help (SET_HELP_{NAME}) - only shown if help is requested */ +typedef char* neonspam_cmd_set_function(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf); +static char* neonspam_cmd_set_trigger(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf); +static char* neonspam_cmd_setflags(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf); +static char* neonspam_cmd_setexcept(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf); +static char* neonspam_cmd_set_reaction(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf); +static char* neonspam_cmd_set_reaction_time(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf); +static char* neonspam_cmd_setpercent(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf); +static char* neonspam_cmd_setsensibility(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf); +static char* neonspam_cmd_set_spamlimit(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf); static MYSQL_ROW neonspam_settings_row, neonspam_settings_defaults; -#define SPAMSERV_SETTINGS_QUERY "`channel_scanstate`, `channel_scanexcept`, `channel_maxrepeat`, `channel_repeatreaction`, `channel_maxflood`, `channel_floodtime`, `channel_floodreaction`, `channel_maxjoin`, `channel_jointime`, `channel_joinreaction`" -#define SPAMSERV_SETTINGS_RESET "`channel_scanstate` = NULL, `channel_scanexcept` = NULL, `channel_maxrepeat` = NULL, `channel_repeatreaction` = NULL, `channel_maxflood` = NULL, `channel_floodtime` = NULL, `channel_floodreaction` = NULL, `channel_maxjoin` = NULL, `channel_jointime` = NULL, `channel_joinreaction` = NULL" +#define SPAMSERV_SETTINGS_QUERY "`channel_spam_reaction`, `channel_spam_reaction_duration`, `channel_flood_reaction`, `channel_flood_reaction_duration`, `channel_join_reaction`, `channel_join_reaction_duration`, `channel_botnet_bantime`, `channel_caps_reaction`, `channel_caps_reaction_duration`, `channel_digit_reaction`, `channel_digit_reaction_duration`" +#define SPAMSERV_SETTINGS_RESET "\ +`channel_scanner` = NULL, \ +`channel_spam_limit` = NULL, \ +`channel_spam_reaction` = NULL, \ +`channel_spam_reaction_duration` = NULL, \ +`channel_spam_except` = NULL, \ +`channel_flood_limit` = NULL, \ +`channel_flood_time` = NULL, \ +`channel_flood_reaction` = NULL, \ +`channel_flood_reaction_duration` = NULL, \ +`channel_flood_except` = NULL, \ +`channel_join_limit` = NULL, \ +`channel_join_time` = NULL, \ +`channel_join_reaction` = NULL, \ +`channel_join_reaction_duration` = NULL, \ +`channel_join_except` = NULL, \ +`channel_botnet_bantime` = NULL, \ +`channel_botnet_except` = NULL, \ +`channel_caps_percent` = NULL, \ +`channel_caps_reaction` = NULL, \ +`channel_caps_reaction_duration` = NULL, \ +`channel_caps_except` = NULL,\ +`channel_digit_percent` = NULL, \ +`channel_digit_reaction` = NULL, \ +`channel_digit_reaction_duration` = NULL, \ +`channel_digit_except` = NULL " static const struct { + unsigned int if_flag; + unsigned int indent; const char *setting; - const char *chanfield; - unsigned int valid; - void *parameter; void *function; + int intparam; + char *charparam; } neonspam_settings[] = { - {"Trigger", NULL, NS_VALID_FUNCTION, NULL, neonspam_cmd_set_trigger}, - {"SpamLimit", NULL, NS_VALID_OPTIONS | NS_VALID_FUNCTION | NS_HAS_OPT, "5", neonspam_cmd_set_spamlimit}, - {"SpamReaction", NULL, NS_VALID_OPTIONS | NS_VALID_FUNCTION | NS_HAS_OPT, "3", neonspam_cmd_set_spamreaction}, - {"FloodReaction", NULL, NS_VALID_OPTIONS | NS_VALID_FUNCTION | NS_HAS_OPT, "3", neonspam_cmd_set_floodreaction}, - {"JoinFloodReaction", NULL, NS_VALID_OPTIONS | NS_VALID_FUNCTION | NS_HAS_OPT, "3", neonspam_cmd_setjoinfloodreaction}, - {"SpamScan", NULL, NS_VALID_BOOLEAN | NS_VALID_FUNCTION, NULL, neonspam_cmd_setspamscan}, - {"FloodScan", NULL, NS_VALID_BOOLEAN | NS_VALID_FUNCTION, NULL, neonspam_cmd_setfloodscan}, - {"JoinFloodScan", NULL, NS_VALID_BOOLEAN | NS_VALID_FUNCTION, NULL, neonspam_cmd_setjoinfloodscan}, - {"BotNetScan", NULL, NS_VALID_BOOLEAN | NS_VALID_FUNCTION, NULL, neonspam_cmd_setbotnetscan}, - {"ScanChanOps", NULL, NS_VALID_BOOLEAN | NS_VALID_FUNCTION, NULL, neonspam_cmd_setscanchanops}, - {"ScanVoiced", NULL, NS_VALID_BOOLEAN | NS_VALID_FUNCTION, NULL, neonspam_cmd_setscanvoiced}, - {"ExceptLevel", NULL, NS_VALID_ACCESS | NS_VALID_FUNCTION, NULL, neonspam_cmd_setexceptlevel}, - {"FloodSensibility", NULL, NS_VALID_FUNCTION, NULL, neonspam_cmd_setfloodsensibility}, - {"JoinSensibility", NULL, NS_VALID_FUNCTION, NULL, neonspam_cmd_setjoinsensibility}, - {NULL, NULL, 0, NULL} + {0, 0, "Trigger", neonspam_cmd_set_trigger, 0, NULL}, + + {0, 0, "SpamScan", neonspam_cmd_setflags, SPAMSETTINGS_SPAMSCAN, NULL}, + {SPAMSETTINGS_SPAMSCAN, 2, "SpamLimit", neonspam_cmd_set_spamlimit, 0, NULL}, + {SPAMSETTINGS_SPAMSCAN | SPAMSETTINGS_SETTIMEBAN, 2, "SpamReaction", neonspam_cmd_set_reaction, 0, "channel_spam_reaction"}, + {SPAMSETTINGS_SPAMSCAN | SPAMSETTINGS_ISTIMEBAN, 4, "SpamBanDuration", neonspam_cmd_set_reaction_time, 1, "channel_spam_reaction_duration"}, + {SPAMSETTINGS_SPAMSCAN, 2, "SpamScanChanOps", neonspam_cmd_setflags, SPAMSETTINGS_SPAMSCAN_OPS, NULL}, + {SPAMSETTINGS_SPAMSCAN, 2, "SpamScanVoiced", neonspam_cmd_setflags, SPAMSETTINGS_SPAMSCAN_VOICE, NULL}, + {SPAMSETTINGS_SPAMSCAN, 2, "SpamScanExcept", neonspam_cmd_setexcept, SPAMSETTINGS_SPAMEXCINDEX, "channel_spam_except"}, + + {0, 0, "FloodScan", neonspam_cmd_setflags, SPAMSETTINGS_FLOODSCAN, NULL}, + {SPAMSETTINGS_FLOODSCAN, 2, "FloodSensibility", neonspam_cmd_setsensibility, SPAMSETTINGS_FLOODSENINDEX, "channel_flood_"}, + {SPAMSETTINGS_FLOODSCAN | SPAMSETTINGS_SETTIMEBAN, 2, "FloodReaction", neonspam_cmd_set_reaction, 2, "channel_flood_reaction"}, + {SPAMSETTINGS_FLOODSCAN | SPAMSETTINGS_ISTIMEBAN, 4, "FloodBanDuration", neonspam_cmd_set_reaction_time, 3, "channel_flood_reaction_duration"}, + {SPAMSETTINGS_FLOODSCAN, 2, "FloodScanChanOps", neonspam_cmd_setflags, SPAMSETTINGS_FLOODSCAN_OPS, NULL}, + {SPAMSETTINGS_FLOODSCAN, 2, "FloodScanVoiced", neonspam_cmd_setflags, SPAMSETTINGS_FLOODSCAN_VOICE, NULL}, + {SPAMSETTINGS_FLOODSCAN, 2, "FloodScanExcept", neonspam_cmd_setexcept, SPAMSETTINGS_FLOODEXCINDEX, "channel_flood_except"}, + + {0, 0, "JoinScan", neonspam_cmd_setflags, SPAMSETTINGS_JOINSCAN, NULL}, + {SPAMSETTINGS_JOINSCAN, 2, "JoinSensibility", neonspam_cmd_setsensibility, SPAMSETTINGS_JOINSENINDEX, "channel_join_"}, + {SPAMSETTINGS_JOINSCAN | SPAMSETTINGS_SETTIMEBAN, 2, "JoinReaction", neonspam_cmd_set_reaction, 4, "channel_join_reaction"}, + {SPAMSETTINGS_JOINSCAN | SPAMSETTINGS_ISTIMEBAN, 4, "JoinBanDuration", neonspam_cmd_set_reaction_time, 5, "channel_join_reaction_duration"}, + {SPAMSETTINGS_JOINSCAN, 2, "JoinScanChanOps", neonspam_cmd_setflags, SPAMSETTINGS_JOINSCAN_OPS, NULL}, + {SPAMSETTINGS_JOINSCAN, 2, "JoinScanVoiced", neonspam_cmd_setflags, SPAMSETTINGS_JOINSCAN_VOICE, NULL}, + {SPAMSETTINGS_JOINSCAN, 2, "JoinScanExcept", neonspam_cmd_setexcept, SPAMSETTINGS_JOINEXCINDEX, "channel_join_except"}, + + {0, 0, "BotNetScan", neonspam_cmd_setflags, SPAMSETTINGS_BOTNETSCAN, NULL}, + {SPAMSETTINGS_BOTNETSCAN, 4, "BotNetBanDuration", neonspam_cmd_set_reaction_time, 6, "channel_botnet_bantime"}, + {SPAMSETTINGS_BOTNETSCAN, 2, "BotNetScanChanOps", neonspam_cmd_setflags, SPAMSETTINGS_BOTNETSCAN_OPS, NULL}, + {SPAMSETTINGS_BOTNETSCAN, 2, "BotNetScanVoiced", neonspam_cmd_setflags, SPAMSETTINGS_BOTNETSCAN_VOICE, NULL}, + //{SPAMSETTINGS_BOTNETSCAN, 2, "BotNetScanExcept", neonspam_cmd_setexcept, SPAMSETTINGS_BOTNETEXCINDEX, "channel_botnet_except"}, + + {0, 0, "CapsScan", neonspam_cmd_setflags, SPAMSETTINGS_CAPSSCAN, NULL}, + {SPAMSETTINGS_CAPSSCAN, 2, "CapsPercent", neonspam_cmd_setpercent, SPAMSETTINGS_CAPSPERCENTINDEX, "channel_caps_percent"}, + {SPAMSETTINGS_CAPSSCAN | SPAMSETTINGS_SETTIMEBAN, 2, "CapsReaction", neonspam_cmd_set_reaction, 7, "channel_caps_reaction"}, + {SPAMSETTINGS_CAPSSCAN | SPAMSETTINGS_ISTIMEBAN, 4, "CapsBanDuration", neonspam_cmd_set_reaction_time, 8, "channel_caps_reaction_duration"}, + {SPAMSETTINGS_CAPSSCAN, 2, "CapsScanChanOps", neonspam_cmd_setflags, SPAMSETTINGS_CAPSSCAN_OPS, NULL}, + {SPAMSETTINGS_CAPSSCAN, 2, "CapsScanVoiced", neonspam_cmd_setflags, SPAMSETTINGS_CAPSSCAN_VOICE, NULL}, + {SPAMSETTINGS_CAPSSCAN, 2, "CapsScanExcept", neonspam_cmd_setexcept, SPAMSETTINGS_CAPSEXCINDEX, "channel_caps_except"}, + + {0, 0, "DigitScan", neonspam_cmd_setflags, SPAMSETTINGS_DIGITSCAN, NULL}, + {SPAMSETTINGS_DIGITSCAN, 2, "DigitPercent", neonspam_cmd_setpercent, SPAMSETTINGS_DIGITPERCENTINDEX, "channel_digit_percent"}, + {SPAMSETTINGS_DIGITSCAN | SPAMSETTINGS_SETTIMEBAN, 2, "DigitReaction", neonspam_cmd_set_reaction, 9, "channel_digit_reaction"}, + {SPAMSETTINGS_DIGITSCAN | SPAMSETTINGS_ISTIMEBAN, 4, "DigitBanDuration", neonspam_cmd_set_reaction_time, 10, "channel_digit_reaction_duration"}, + {SPAMSETTINGS_DIGITSCAN, 2, "DigitScanChanOps", neonspam_cmd_setflags, SPAMSETTINGS_DIGITSCAN_OPS, NULL}, + {SPAMSETTINGS_DIGITSCAN, 2, "DigitScanVoiced", neonspam_cmd_setflags, SPAMSETTINGS_DIGITSCAN_VOICE, NULL}, + {SPAMSETTINGS_DIGITSCAN, 2, "DigitScanExcept", neonspam_cmd_setexcept, SPAMSETTINGS_DIGITEXCINDEX, "channel_digit_except"}, + + {0, 0, NULL, NULL, 0, NULL} }; #define MAX_QUERY_LEN 1024 @@ -107,10 +149,19 @@ CMD_BIND(neonspam_cmd_set) { i = 0; j = 0; char *args = (argc > 1 ? merge_argv(argv, 1, argc) : NULL); + neonspam_settings_row = NULL; + neonspam_settings_defaults = NULL; while(neonspam_settings[i].setting) { if(!stricmp(neonspam_settings[i].setting, argv[0])) { //setting found - neonspam_cmd_set_setting(client, user, chan, event, i, args); + char valueBuf[MAXLEN]; + char *value; + neonspam_cmd_set_function *func = neonspam_settings[i].function; + value = func(client, user, chan, event, neonspam_settings[i].intparam, neonspam_settings[i].charparam, args, valueBuf); + if(value) { + reply(getTextBot(), user, "\002%s\002 %s", neonspam_settings[i].setting, value); + //TODO: reply valid options + } j = 1; break; } @@ -121,12 +172,12 @@ CMD_BIND(neonspam_cmd_set) { reply(getTextBot(), user, "NS_SET_UNKNOWN_SETTING", argv[0]); } } else { - char *value, *org_value, *tmp, nameBuf[64]; + char valueBuf[MAXLEN], nameBuf[MAXLEN]; + char *value; + int namePos, boolflag = 0; MYSQL_RES *res, *defaults_res; struct Table *table; char *content[2]; - char query[MAXLEN]; - int querypos; i = 0; while(neonspam_settings[i].setting) i++; @@ -138,43 +189,26 @@ CMD_BIND(neonspam_cmd_set) { printf_mysql_query("SELECT " SPAMSERV_SETTINGS_QUERY " FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id); res = mysql_use(); neonspam_settings_row = mysql_fetch_row(res); - i = 0; - j = 0; + i = -1; reply(getTextBot(), user, "NS_SET_HEADER", chan->name); - while(neonspam_settings[i].setting) { - char valueBuf[MAXLEN]; - if(neonspam_settings[i].valid & NS_VALID_FUNCTION) { - neonspam_cmd_set_function *func = neonspam_settings[i].function; - org_value = func(client, user, chan, event, NULL, NULL, valueBuf); - } else - org_value = "0"; - value = org_value; - if(neonspam_settings[i].valid & NS_VALID_BOOLEAN) { - if(!strcmp(value, "0")) - value = get_language_string(user, "NS_SET_OFF"); - else - value = get_language_string(user, "NS_SET_ON"); + while(neonspam_settings[++i].setting) { + if((chan->spam_settings->flags & (neonspam_settings[i].if_flag & SPAMSETTINGS_FLAGS)) != (neonspam_settings[i].if_flag & SPAMSETTINGS_FLAGS)) + continue; + if((neonspam_settings[i].if_flag & SPAMSETTINGS_ISTIMEBAN) && !boolflag) + continue; + namePos = 0; + for(j = 0; j < neonspam_settings[i].indent; j++) { + nameBuf[namePos++] = ' '; } - strcpy(query, value); - querypos = strlen(query); - if(neonspam_settings[i].valid & NS_HAS_OPT) { - sprintf(nameBuf, "NS_SET_OPTION_%s_%s", neonspam_settings[i].setting, org_value); - tmp = get_language_string(user, nameBuf); - if(tmp) { - querypos += sprintf(query+querypos, " - %s", tmp); - } - } - if(argc && neonspam_settings[i].valid & NS_HAS_HELP) { - sprintf(nameBuf, "NS_SET_HELP_%s", neonspam_settings[i].setting); - tmp = get_language_string(user, nameBuf); - if(tmp) { - querypos += sprintf(query+querypos, " - %s", tmp); - } - } - content[0] = (char*)neonspam_settings[i].setting; - content[1] = query; + neonspam_cmd_set_function *func = neonspam_settings[i].function; + value = func(client, user, chan, event, neonspam_settings[i].intparam, neonspam_settings[i].charparam, NULL, valueBuf); + if(neonspam_settings[i].if_flag & SPAMSETTINGS_SETTIMEBAN) + boolflag = !strcmp(value, "2"); + //TODO: append option or help info + sprintf(nameBuf + namePos, "%s", neonspam_settings[i].setting); + content[0] = nameBuf; + content[1] = value; table_add(table, content); - i++; } char **table_lines = table_end(table); for(i = 0; i < table->entrys; i++) { @@ -184,115 +218,7 @@ CMD_BIND(neonspam_cmd_set) { } } -static void neonspam_cmd_set_setting(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int setting, char *args) { - char *value; - char valueBuf[MAXLEN]; - char nameBuf[64]; - //get current value - MYSQL_RES *res; - printf_mysql_query("SELECT " SPAMSERV_SETTINGS_QUERY " FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id); - res = mysql_use(); - neonspam_settings_row = mysql_fetch_row(res); - printf_mysql_query("SELECT " SPAMSERV_SETTINGS_QUERY " FROM `channels` WHERE `channel_name` = 'defaults'"); - res = mysql_use(); - neonspam_settings_defaults = mysql_fetch_row(res); - if(neonspam_settings[setting].valid & NS_VALID_FUNCTION) { - neonspam_cmd_set_function *func = neonspam_settings[setting].function; - if(!(value = func(client, user, chan, event, NULL, NULL, valueBuf))) - return; - } else - value = "0"; - if(args) { - //change the channel setting - //check the new argument - int valid = neonspam_settings[setting].valid; - if(valid & NS_VALID_STRING) { - if(!strcmp(args, "*")) { - args = ""; - } - } - if(valid & NS_VALID_ACCESS) { - int caccess = atoi(args); - int max = ((valid & NS_VALID_NO501) ? 500 : 501); - if(caccess < 0 || caccess > max) { - reply(getTextBot(), user, "NS_INVALID_ACCESS", caccess); - return; - } - int uaccess = getChannelAccess(user, chan, 0); - if(uaccess == 500) uaccess++; - if(atoi(value) > uaccess) { - if(isGodMode(user)) { - event->flags |= CMDFLAG_OPLOG; - } else { - reply(getTextBot(), user, "NS_SET_CANNOT_SET"); - return; - } - } - if(caccess > uaccess) { - if(isGodMode(user)) { - event->flags |= CMDFLAG_OPLOG; - } else { - reply(getTextBot(), user, "NS_SET_BADLEVEL"); - return; - } - } - sprintf(nameBuf, "%d", caccess); - args = nameBuf; - } - if(valid & NS_VALID_OPTIONS) { - int options = atoi((char *) neonspam_settings[setting].parameter); - int coption = atoi(args); - if(coption < 0 || coption >= options) { - reply(getTextBot(), user, "NS_SET_INVALID_OPTION", coption); - int i; - int nameBufPos = 0; - if(valid & NS_HAS_OPT) { - for(i = 0; i < options; i++) { - sprintf(nameBuf, "NS_SET_OPTION_%s_%d", neonspam_settings[setting].setting, i); - reply(getTextBot(), user, "\002%d\002 - %s", i, get_language_string(user, nameBuf)); - } - } else { - for(i = 0; i < options; i++) { - nameBufPos += sprintf(nameBuf + nameBufPos, "\002%d\002, ", i); - } - if(nameBufPos) { - nameBuf[nameBufPos-2] = '\0'; - reply(getTextBot(), user, nameBuf); - } - } - return; - } - } - if(valid & NS_VALID_NUMERIC) { - sprintf(nameBuf, "%d", atoi(args)); - args = nameBuf; - } - if(valid & NS_VALID_BOOLEAN) { - if(!strcmp(args, "0") || !stricmp(args, "off") || !stricmp(args, get_language_string(user, "NS_SET_OFF"))) { - args = "0"; - } else if(!strcmp(args, "1") || !stricmp(args, "on") || !stricmp(args, get_language_string(user, "NS_SET_ON"))) { - args = "1"; - } else { - reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", args); - return; - } - } - //valid - set it - if(valid & NS_VALID_FUNCTION) { - neonspam_cmd_set_function *func = neonspam_settings[setting].function; - strcpy(valueBuf, value); - if(!(value = func(client, user, chan, event, neonspam_settings[setting].setting, valueBuf, args))) - return; - } - } - reply(getTextBot(), user, "\002%s\002 %s", neonspam_settings[setting].setting, value); - if(neonspam_settings[setting].valid & NS_HAS_HELP) { - sprintf(nameBuf, "NS_SET_HELP_%s", neonspam_settings[setting].setting); - reply(getTextBot(), user, " %s", get_language_string(user, nameBuf)); - } -} - -static char* neonspam_cmd_set_trigger(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument) { +static char* neonspam_cmd_set_trigger(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf) { char *trigger; //get current trigger MYSQL_RES *res; @@ -301,7 +227,7 @@ static char* neonspam_cmd_set_trigger(struct ClientSocket *client, struct UserNo res = mysql_use(); row = mysql_fetch_row(res); trigger = row[0]; - if(cvalue && argument) { + if(argument) { int uaccess = getChannelAccess(user, chan, 0); if(uaccess < 500) { if(isGodMode(user)) { @@ -321,202 +247,137 @@ static char* neonspam_cmd_set_trigger(struct ClientSocket *client, struct UserNo return trigger; } -static char* neonspam_cmd_set_spamlimit(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument) { - if(!cvalue) { - //get current value - cvalue = (neonspam_settings_row[2] ? neonspam_settings_row[2] : neonspam_settings_defaults[2]); - } - else if(argument) { - //change value - printf_mysql_query("UPDATE `channels` SET `channel_maxrepeat` = '%d' WHERE `channel_id` = '%d' ", atoi(argument), chan->channel_id); - sprintf(cvalue, "%d", atoi(argument)); - if(chan->spam_settings) - chan->spam_settings->spam_amount = atoi(argument); - } - return cvalue; -} - -static char* neonspam_cmd_set_spamreaction(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument) { - if(!cvalue) { - //get current value - cvalue = (neonspam_settings_row[3] ? neonspam_settings_row[3] : neonspam_settings_defaults[3]); - } - else if(argument) { - //change value - printf_mysql_query("UPDATE `channels` SET `channel_repeatreaction` = '%d' WHERE `channel_id` = '%d' ", atoi(argument), chan->channel_id); - sprintf(cvalue, "%d", atoi(argument)); - } - return cvalue; -} - -static char* neonspam_cmd_set_floodreaction(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument) { - if(!cvalue) { - //get current value - cvalue = (neonspam_settings_row[6] ? neonspam_settings_row[6] : neonspam_settings_defaults[6]); - } - else if(argument) { - //change value - printf_mysql_query("UPDATE `channels` SET `channel_floodreaction` = '%d' WHERE `channel_id` = '%d' ", atoi(argument), chan->channel_id); - sprintf(cvalue, "%d", atoi(argument)); - } - return cvalue; -} - -static char* neonspam_cmd_setjoinfloodreaction(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument) { - if(!cvalue) { - //get current value - cvalue = (neonspam_settings_row[9] ? neonspam_settings_row[9] : neonspam_settings_defaults[9]); - } - else if(argument) { - //change value - printf_mysql_query("UPDATE `channels` SET `channel_joinreaction` = '%d' WHERE `channel_id` = '%d' ", atoi(argument), chan->channel_id); - sprintf(cvalue, "%d", atoi(argument)); - } - return cvalue; -} - -static char* neonspam_cmd_setspamscan(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument) { - if(!cvalue) { - //get current value - cvalue = ((atoi(neonspam_settings_row[0] ? neonspam_settings_row[0] : neonspam_settings_defaults[0]) & SPAMSETTINGS_SPAMSCAN) ? "1" : "0"); - } - else if(argument) { - //change value - int cflags = atoi((neonspam_settings_row[0] ? neonspam_settings_row[0] : neonspam_settings_defaults[0])); - if(!strcmp(argument, "0")) - cflags &= ~SPAMSETTINGS_SPAMSCAN; - else - cflags |= SPAMSETTINGS_SPAMSCAN; - printf_mysql_query("UPDATE `channels` SET `channel_scanstate` = '%d' WHERE `channel_id` = '%d' ", cflags, chan->channel_id); - cvalue = argument; - if(chan->spam_settings) - chan->spam_settings->flags = cflags; - } - return cvalue; -} - -static char* neonspam_cmd_setfloodscan(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument) { - if(!cvalue) { - //get current value - cvalue = ((atoi(neonspam_settings_row[0] ? neonspam_settings_row[0] : neonspam_settings_defaults[0]) & SPAMSETTINGS_FLOODSCAN) ? "1" : "0"); - } - else if(argument) { - //change value - int cflags = atoi((neonspam_settings_row[0] ? neonspam_settings_row[0] : neonspam_settings_defaults[0])); - if(!strcmp(argument, "0")) - cflags &= ~SPAMSETTINGS_FLOODSCAN; - else - cflags |= SPAMSETTINGS_FLOODSCAN; - printf_mysql_query("UPDATE `channels` SET `channel_scanstate` = '%d' WHERE `channel_id` = '%d' ", cflags, chan->channel_id); - cvalue = argument; - if(chan->spam_settings) - chan->spam_settings->flags = cflags; - } - return cvalue; -} - -static char* neonspam_cmd_setjoinfloodscan(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument) { - if(!cvalue) { - //get current value - cvalue = ((atoi(neonspam_settings_row[0] ? neonspam_settings_row[0] : neonspam_settings_defaults[0]) & SPAMSETTINGS_JOINSCAN) ? "1" : "0"); - } - else if(argument) { - //change value - int cflags = atoi((neonspam_settings_row[0] ? neonspam_settings_row[0] : neonspam_settings_defaults[0])); - if(!strcmp(argument, "0")) - cflags &= ~SPAMSETTINGS_JOINSCAN; - else - cflags |= SPAMSETTINGS_JOINSCAN; - printf_mysql_query("UPDATE `channels` SET `channel_scanstate` = '%d' WHERE `channel_id` = '%d' ", cflags, chan->channel_id); - cvalue = argument; - if(chan->spam_settings) - chan->spam_settings->flags = cflags; +static char* neonspam_cmd_setflags(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int flag, char *charparam, char *argument, char *retBuf) { + char *value = ((chan->spam_settings->flags & flag) ? "1" : "0"); + if(argument) { + //binary argument... + if(!strcmp(argument, "0") || !stricmp(argument, "off") || !stricmp(argument, get_language_string(user, "NS_SET_OFF"))) { + chan->spam_settings->flags &= ~flag; + } else if(!strcmp(argument, "1") || !stricmp(argument, "on") || !stricmp(argument, get_language_string(user, "NS_SET_ON"))) { + chan->spam_settings->flags |= flag; + } else { + reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", argument); + return NULL; + } + char str_flags[50]; + convertNeonSpamSettingsToString(chan->spam_settings->flags, str_flags); + printf_mysql_query("UPDATE `channels` SET `channel_scanner` = '%s' WHERE `channel_id` = '%d' ", str_flags, chan->channel_id); + value = argument; } - return cvalue; + return value; } -static char* neonspam_cmd_setbotnetscan(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument) { - if(!cvalue) { - //get current value - cvalue = ((atoi(neonspam_settings_row[0] ? neonspam_settings_row[0] : neonspam_settings_defaults[0]) & SPAMSETTINGS_BOTNETSCAN) ? "1" : "0"); - } - else if(argument) { - //change value - int cflags = atoi((neonspam_settings_row[0] ? neonspam_settings_row[0] : neonspam_settings_defaults[0])); - if(!strcmp(argument, "0")) - cflags &= ~SPAMSETTINGS_BOTNETSCAN; - else - cflags |= SPAMSETTINGS_BOTNETSCAN; - printf_mysql_query("UPDATE `channels` SET `channel_scanstate` = '%d' WHERE `channel_id` = '%d' ", cflags, chan->channel_id); - cvalue = argument; - if(chan->spam_settings) - chan->spam_settings->flags = cflags; +static char* neonspam_cmd_setexcept(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int exceptlvl_index, char *field, char *argument, char *retBuf) { + unsigned int value = chan->spam_settings->exceptlevel[exceptlvl_index]; + if(argument) { + //numeric argument... (access) + int caccess = atoi(argument); + if(caccess < 0 || caccess > 501) { + reply(getTextBot(), user, "NS_INVALID_ACCESS", caccess); + return NULL; + } + int uaccess = getChannelAccess(user, chan, 0); + if(uaccess == 500) uaccess++; + if(caccess > uaccess) { + if(isGodMode(user)) { + event->flags |= CMDFLAG_OPLOG; + } else { + reply(getTextBot(), user, "NS_SET_CANNOT_SET"); + return NULL; + } + } + if(caccess > uaccess) { + if(isGodMode(user)) { + event->flags |= CMDFLAG_OPLOG; + } else { + reply(getTextBot(), user, "NS_SET_BADLEVEL"); + return NULL; + } + } + value = caccess; + chan->spam_settings->exceptlevel[exceptlvl_index] = value; + printf_mysql_query("UPDATE `channels` SET `%s` = '%u' WHERE `channel_id` = '%d' ", field, value, chan->channel_id); } - return cvalue; + sprintf(retBuf, "%u", value); + return retBuf; } -static char* neonspam_cmd_setscanchanops(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument) { - if(!cvalue) { - //get current value - cvalue = ((atoi(neonspam_settings_row[0] ? neonspam_settings_row[0] : neonspam_settings_defaults[0]) & SPAMSETTINGS_SCANOPS) ? "1" : "0"); - } - else if(argument) { - //change value - int cflags = atoi((neonspam_settings_row[0] ? neonspam_settings_row[0] : neonspam_settings_defaults[0])); - if(!strcmp(argument, "0")) - cflags &= ~SPAMSETTINGS_SCANOPS; - else - cflags |= SPAMSETTINGS_SCANOPS; - printf_mysql_query("UPDATE `channels` SET `channel_scanstate` = '%d' WHERE `channel_id` = '%d' ", cflags, chan->channel_id); - cvalue = argument; - if(chan->spam_settings) - chan->spam_settings->flags = cflags; +static char* neonspam_cmd_set_reaction(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int mysqlindex, char *mysqlfield, char *argument, char *retBuf) { + if(argument) { + /* valid options: + * 0/kick - kick + * 1/kickban - kickban + * 2/ban - timed ban + */ + if(!strcmp(argument, "0") || !stricmp(argument, "kick")) { + argument = "0"; + } else if(!strcmp(argument, "1") || !stricmp(argument, "kickban")) { + argument = "1"; + } else if(!strcmp(argument, "2") || !stricmp(argument, "ban")) { + argument = "2"; + } else { + reply(getTextBot(), user, "NS_SET_INVALID_OPTION_STR", argument); + return NULL; + } + printf_mysql_query("UPDATE `channels` SET `%s` = '%s' WHERE `channel_id` = '%d' ", mysqlfield, argument, chan->channel_id); + return argument; + } else { + if(neonspam_settings_row) { + return (neonspam_settings_row[mysqlindex] ? neonspam_settings_row[mysqlindex] : neonspam_settings_defaults[mysqlindex]); + } else { + MYSQL_RES *res; + MYSQL_ROW row; + printf_mysql_query("SELECT `%s` FROM `channels` WHERE `channel_id` = '%d'", mysqlfield, chan->channel_id); + res = mysql_use(); + row = mysql_fetch_row(res); + return row[0]; + } } - return cvalue; } -static char* neonspam_cmd_setscanvoiced(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument) { - if(!cvalue) { - //get current value - cvalue = ((atoi(neonspam_settings_row[0] ? neonspam_settings_row[0] : neonspam_settings_defaults[0]) & SPAMSETTINGS_SCANVOICE) ? "1" : "0"); - } - else if(argument) { - //change value - int cflags = atoi((neonspam_settings_row[0] ? neonspam_settings_row[0] : neonspam_settings_defaults[0])); - if(!strcmp(argument, "0")) - cflags &= ~SPAMSETTINGS_SCANVOICE; - else - cflags |= SPAMSETTINGS_SCANVOICE; - printf_mysql_query("UPDATE `channels` SET `channel_scanstate` = '%d' WHERE `channel_id` = '%d' ", cflags, chan->channel_id); - cvalue = argument; - if(chan->spam_settings) - chan->spam_settings->flags = cflags; +static char* neonspam_cmd_set_reaction_time(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int mysqlindex, char *mysqlfield, char *argument, char *retBuf) { + int duration; + if(argument) { + duration = strToTime(user, argument); + if(duration < 30) { + reply(getTextBot(), user, "NS_TIMEBAN_DURATION_TOO_SHORT", 30); + return NULL; + } + printf_mysql_query("UPDATE `channels` SET `%s` = '%s' WHERE `channel_id` = '%d' ", mysqlfield, argument, chan->channel_id); + } else { + if(neonspam_settings_row) { + duration = atoi(neonspam_settings_row[mysqlindex] ? neonspam_settings_row[mysqlindex] : neonspam_settings_defaults[mysqlindex]); + } else { + MYSQL_RES *res; + MYSQL_ROW row; + printf_mysql_query("SELECT `%s` FROM `channels` WHERE `channel_id` = '%d'", mysqlfield, chan->channel_id); + res = mysql_use(); + row = mysql_fetch_row(res); + duration = atoi(row[0]); + } } - return cvalue; + timeToStr(user, duration, 3, retBuf); + return retBuf; } -static char* neonspam_cmd_setexceptlevel(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument) { - if(!cvalue) { - //get current value - cvalue = (neonspam_settings_row[1] ? neonspam_settings_row[1] : neonspam_settings_defaults[1]); - } - else if(argument) { - //change value - printf_mysql_query("UPDATE `channels` SET `channel_scanexcept` = '%d' WHERE `channel_id` = '%d' ", atoi(argument), chan->channel_id); - sprintf(cvalue, "%d", atoi(argument)); - if(chan->spam_settings) - chan->spam_settings->exceptlevel = atoi(argument); +static char* neonspam_cmd_setpercent(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int percent_index, char *mysqlfield, char *argument, char *retBuf) { + unsigned int value = chan->spam_settings->percent[percent_index]; + if(argument) { + //numeric argument... (access) + value = atoi(argument); + if(value < 0 || value > 100) { + //invalid percent value + return NULL; + } + chan->spam_settings->percent[percent_index] = value; + printf_mysql_query("UPDATE `channels` SET `%s` = '%u' WHERE `channel_id` = '%d' ", mysqlfield, value, chan->channel_id); } - return cvalue; + sprintf(retBuf, "%u", value); + return retBuf; } -static char* neonspam_cmd_setfloodsensibility(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument) { - if(!cvalue) { - //get current value - sprintf(argument, "%s:%s", (neonspam_settings_row[4] ? neonspam_settings_row[4] : neonspam_settings_defaults[4]), (neonspam_settings_row[5] ? neonspam_settings_row[5] : neonspam_settings_defaults[5])); - cvalue = argument; - } - else if(argument) { +static char* neonspam_cmd_setsensibility(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int sensibility_index, char *mysqlfield, char *argument, char *retBuf) { + if(argument) { //change value char *delimiter = strstr(argument, ":"); if(!delimiter) { @@ -535,50 +396,33 @@ static char* neonspam_cmd_setfloodsensibility(struct ClientSocket *client, struc //invalid time period return NULL; } - printf_mysql_query("UPDATE `channels` SET `channel_maxflood` = '%d', `channel_floodtime` = '%d' WHERE `channel_id` = '%d' ", amount, timep, chan->channel_id); - sprintf(cvalue, "%d:%d", amount, timep); - if(chan->spam_settings) { - chan->spam_settings->flood_amount = amount; - chan->spam_settings->flood_time = timep; - } + char amountfield[50], timefield[50]; + sprintf(amountfield, "%s%s", mysqlfield, "limit"); + sprintf(timefield, "%s%s", mysqlfield, "time"); + printf_mysql_query("UPDATE `channels` SET `%s` = '%d', `%s` = '%d' WHERE `channel_id` = '%d' ", amountfield, amount, timefield, timep, chan->channel_id); + sprintf(retBuf, "%d:%d", amount, timep); + chan->spam_settings->sensibility_amount[sensibility_index] = amount; + chan->spam_settings->sensibility_time[sensibility_index] = timep; + } else { + sprintf(retBuf, "%d:%d", chan->spam_settings->sensibility_amount[sensibility_index], chan->spam_settings->sensibility_time[sensibility_index]); } - return cvalue; + return retBuf; } -static char* neonspam_cmd_setjoinsensibility(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument) { - if(!cvalue) { - //get current value - sprintf(argument, "%s:%s", (neonspam_settings_row[7] ? neonspam_settings_row[7] : neonspam_settings_defaults[7]), (neonspam_settings_row[8] ? neonspam_settings_row[8] : neonspam_settings_defaults[8])); - cvalue = argument; - } - else if(argument) { +static char* neonspam_cmd_set_spamlimit(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf) { + if(argument) { //change value - char *delimiter = strstr(argument, ":"); - if(!delimiter) { - //invalid format - return NULL; - } - *delimiter = '\0'; - delimiter++; int amount = atoi(argument); - int timep = atoi(delimiter); - if(amount > MAX_JOIN_AMOUNT || amount < MIN_JOIN_AMOUNT) { + if(amount > MAX_FLOOD_AMOUNT || amount < MIN_FLOOD_AMOUNT) { //invalid amount return NULL; } - if(timep > MAX_JOIN_TIME || timep < 0) { - //invalid time period - return NULL; - } - printf_mysql_query("UPDATE `channels` SET `channel_maxjoin` = '%d', `channel_jointime` = '%d' WHERE `channel_id` = '%d' ", amount, timep, chan->channel_id); - sprintf(cvalue, "%d:%d", amount, timep); - if(chan->spam_settings) { - chan->spam_settings->join_amount = amount; - chan->spam_settings->join_time = timep; - } - } - return cvalue; + printf_mysql_query("UPDATE `channels` SET `channel_maxrepeat` = '%d' WHERE `channel_id` = '%d' ", amount, chan->channel_id); + sprintf(retBuf, "%d", amount); + chan->spam_settings->spam_amount = amount; + } else + sprintf(retBuf, "%d", chan->spam_settings->spam_amount); + return retBuf; } - #undef MAX_QUERY_LEN diff --git a/src/event_neonspam_chanmsg.c b/src/event_neonspam_chanmsg.c index 7bcd4b5..b7f124f 100644 --- a/src/event_neonspam_chanmsg.c +++ b/src/event_neonspam_chanmsg.c @@ -20,17 +20,18 @@ static int neonspam_floodscan(struct NeonSpamSettings *settings, struct ChanUser static int neonspam_botnetscan(struct ClientSocket *client, struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message); static USERAUTH_CALLBACK(neonspam_event_chanmsg_nick_lookup); -static void neonspam_event_chanmsg_punish(struct ClientSocket *client, struct ChanUser *chanuser, struct NeonSpamSettings *settings, int action, char *reason, char *reaction); +static void neonspam_event_chanmsg_punish(struct ClientSocket *client, struct ChanUser *chanuser, struct NeonSpamSettings *settings, unsigned int warn, unsigned int punish); struct neonspam_event_chanmsg_cache { struct ClientSocket *client; struct ChanUser *chanuser; struct NeonSpamSettings *settings; - int action; - char *reason; - char *reaction; + unsigned int warn; + unsigned int punish; }; + + static void neonspam_event_chanmsg(struct UserNode *user, struct ChanNode *chan, char *message) { struct ClientSocket *client = getChannelBot(chan, BOTID); if(!client) return; //we can't "see" this event @@ -38,57 +39,50 @@ static void neonspam_event_chanmsg(struct UserNode *user, struct ChanNode *chan, struct NeonSpamSettings *settings = chan->spam_settings; struct ChanUser *chanuser = getChanUser(user, chan); if(!settings || !chanuser) return; - - //ignore messages from ops/voices if we ignore them - if(!(settings->flags & SPAMSETTINGS_SCANOPS) && (chanuser->flags & CHANUSERFLAG_OPPED)) return; - if(!(settings->flags & SPAMSETTINGS_SCANVOICE) && (chanuser->flags & CHANUSERFLAG_VOICED)) return; - if(settings->exceptlevel == 0) return; + #define NEONSPAM_CHANMSG_DO_SCANOPS(FLAG) ((settings->flags & FLAG) || !(chanuser->flags & CHANUSERFLAG_OPPED)) + #define NEONSPAM_CHANMSG_DO_SCANVOICE(FLAG) ((settings->flags & FLAG) || !(chanuser->flags & CHANUSERFLAG_VOICED)) + #define NEONSPAM_CHANMSG_DO_EXCEPT(INDEX) (settings->exceptlevel[INDEX] != 0) + #define NEONSPAM_CHANMSG_NEED_WHO(INDEX) (settings->exceptlevel[INDEX] != 501) //scan the message int result = 0; - int action = SPAMSERV_CHECK_IGNORE; - char reason[MAXLEN]; - char *reaction = NULL; - if(action != SPAMSERV_CHECK_PUNISH && (settings->flags & SPAMSETTINGS_SPAMSCAN)) { + unsigned int warn = 0; + unsigned int punish = 0; + int needwho = 0; + if((settings->flags & SPAMSETTINGS_SPAMSCAN) && NEONSPAM_CHANMSG_DO_SCANOPS(SPAMSETTINGS_SPAMSCAN_OPS) && NEONSPAM_CHANMSG_DO_SCANVOICE(SPAMSETTINGS_SPAMSCAN_VOICE) && NEONSPAM_CHANMSG_DO_EXCEPT(SPAMSETTINGS_SPAMEXCINDEX)) { result = neonspam_spamscan(settings, chanuser, message); switch(result) { case SPAMSERV_CHECK_IGNORE: break; case SPAMSERV_CHECK_WARN: - if(action == SPAMSERV_CHECK_IGNORE) { - action = result; - sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_SPAM); - } + warn |= SPAMSETTINGS_SPAMSCAN; + if(NEONSPAM_CHANMSG_NEED_WHO(SPAMSETTINGS_SPAMEXCINDEX)) + needwho = 1; break; case SPAMSERV_CHECK_PUNISH: - if(action != SPAMSERV_CHECK_PUNISH) { - action = result; - sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_SPAM); - reaction = "channel_repeatreaction"; - } + punish |= SPAMSETTINGS_SPAMSCAN; + if(NEONSPAM_CHANMSG_NEED_WHO(SPAMSETTINGS_SPAMEXCINDEX)) + needwho = 1; break; } } - if(action != SPAMSERV_CHECK_PUNISH && (settings->flags & SPAMSETTINGS_FLOODSCAN)) { + if((settings->flags & SPAMSETTINGS_FLOODSCAN) && NEONSPAM_CHANMSG_DO_SCANOPS(SPAMSETTINGS_FLOODSCAN_OPS) && NEONSPAM_CHANMSG_DO_SCANVOICE(SPAMSETTINGS_FLOODSCAN_VOICE) && NEONSPAM_CHANMSG_DO_EXCEPT(SPAMSETTINGS_FLOODEXCINDEX)) { result = neonspam_floodscan(settings, chanuser); switch(result) { case SPAMSERV_CHECK_IGNORE: break; case SPAMSERV_CHECK_WARN: - if(action == SPAMSERV_CHECK_IGNORE) { - action = result; - sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_FLOOD); - } + warn |= SPAMSETTINGS_FLOODSCAN; + if(NEONSPAM_CHANMSG_NEED_WHO(SPAMSETTINGS_FLOODEXCINDEX)) + needwho = 1; break; case SPAMSERV_CHECK_PUNISH: - if(action != SPAMSERV_CHECK_PUNISH) { - action = result; - sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_FLOOD); - reaction = "channel_floodreaction"; - } + punish |= SPAMSETTINGS_FLOODSCAN; + if(NEONSPAM_CHANMSG_NEED_WHO(SPAMSETTINGS_FLOODEXCINDEX)) + needwho = 1; break; } } - if(action != SPAMSERV_CHECK_PUNISH && (settings->flags & SPAMSETTINGS_BOTNETSCAN)) { + if((settings->flags & SPAMSETTINGS_BOTNETSCAN) && NEONSPAM_CHANMSG_DO_SCANOPS(SPAMSETTINGS_BOTNETSCAN_OPS) && NEONSPAM_CHANMSG_DO_SCANVOICE(SPAMSETTINGS_BOTNETSCAN_VOICE)) { result = neonspam_botnetscan(client, settings, chanuser, message); switch(result) { case SPAMSERV_CHECK_DEAD: @@ -99,10 +93,10 @@ static void neonspam_event_chanmsg(struct UserNode *user, struct ChanNode *chan, } //some other checks? - if(action != SPAMSERV_CHECK_IGNORE) { + if(warn || punish) { //whois the user to check against exceptlevel - if((user->flags & USERFLAG_ISAUTHED) || settings->exceptlevel == 501) { - neonspam_event_chanmsg_punish(client, chanuser, settings, action, reason, reaction); + if(!needwho || (user->flags & USERFLAG_ISAUTHED)) { + neonspam_event_chanmsg_punish(client, chanuser, settings, warn, punish); } else { struct neonspam_event_chanmsg_cache *cache = malloc(sizeof(*cache)); if (!cache) { @@ -112,72 +106,92 @@ static void neonspam_event_chanmsg(struct UserNode *user, struct ChanNode *chan, cache->client = client; cache->chanuser = chanuser; cache->settings = settings; - cache->action = action; - cache->reason = strdup(reason); - cache->reaction = reaction; + cache->warn = warn; + cache->punish = punish; get_userauth(user, neonspam_event_chanmsg_nick_lookup, cache); } } + #undef NEONSPAM_CHANMSG_DO_SCANOPS + #undef NEONSPAM_CHANMSG_DO_SCANVOICE + #undef NEONSPAM_CHANMSG_DO_EXCEPT + #undef NEONSPAM_CHANMSG_NEED_WHO } static USERAUTH_CALLBACK(neonspam_event_chanmsg_nick_lookup) { struct neonspam_event_chanmsg_cache *cache = data; - neonspam_event_chanmsg_punish(cache->client, cache->chanuser, cache->settings, cache->action, cache->reason, cache->reaction); - free(cache->reason); + neonspam_event_chanmsg_punish(cache->client, cache->chanuser, cache->settings, cache->warn, cache->punish); free(cache); } -static void neonspam_event_chanmsg_punish(struct ClientSocket *client, struct ChanUser *chanuser, struct NeonSpamSettings *settings, int action, char *reason, char *reaction) { +static void neonspam_event_chanmsg_punish(struct ClientSocket *client, struct ChanUser *chanuser, struct NeonSpamSettings *settings, unsigned int warn, unsigned int punish) { + MYSQL_RES *res; + MYSQL_ROW row; + loadChannelSettings(chanuser->chan); int uaccess = 0; if(chanuser->user->flags & USERFLAG_ISAUTHED) uaccess = getChannelAccess(chanuser->user, chanuser->chan, 0); - if(uaccess >= settings->exceptlevel) return; - if(action == SPAMSERV_CHECK_WARN) { - reply(client, chanuser->user, "%s", reason); - } else if(action == SPAMSERV_CHECK_PUNISH) { - loadChannelSettings(chanuser->chan); - int reactionid; - if(!(reactionid = atoi(reaction))) { - MYSQL_RES *res; - MYSQL_ROW row; - printf_mysql_query("SELECT `%s` FROM `channels` WHERE `channel_id` = '%d'", reaction, chanuser->chan->channel_id); + char reason[MAXLEN]; + reason[0] = '\0'; + int punishment = 0; + int punish_time = 0; + if(!punishment && (punish & SPAMSETTINGS_SPAMSCAN) && settings->exceptlevel[SPAMSETTINGS_SPAMEXCINDEX] > uaccess) { + printf_mysql_query("SELECT `channel_spam_reaction`, `channel_spam_reaction_duration` FROM `channels` WHERE `channel_id` = '%d'", chanuser->chan->channel_id); + res = mysql_use(); + row = mysql_fetch_row(res); + if(!row[0]) { + printf_mysql_query("SELECT `channel_spam_reaction`, `channel_spam_reaction_duration` FROM `channels` WHERE `channel_name` = 'defaults'"); res = mysql_use(); row = mysql_fetch_row(res); - if(!row[0]) { - printf_mysql_query("SELECT `%s` FROM `channels` WHERE `channel_name` = 'defaults'", reaction); - res = mysql_use(); - row = mysql_fetch_row(res); - } - reactionid = atoi(row[0]); } - - int duration = 0; + sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_SPAM); + punishment = atoi(row[0]) + 1; + punish_time = atoi(row[1]); + } + if(!punishment && (punish & SPAMSETTINGS_FLOODSCAN) && settings->exceptlevel[SPAMSETTINGS_FLOODEXCINDEX] > uaccess) { + printf_mysql_query("SELECT `channel_flood_reaction`, `channel_flood_reaction_duration` FROM `channels` WHERE `channel_id` = '%d'", chanuser->chan->channel_id); + res = mysql_use(); + row = mysql_fetch_row(res); + if(!row[0]) { + printf_mysql_query("SELECT `channel_flood_reaction`, `channel_flood_reaction_duration` FROM `channels` WHERE `channel_name` = 'defaults'"); + res = mysql_use(); + row = mysql_fetch_row(res); + } + sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_FLOOD); + punishment = atoi(row[0]) + 1; + punish_time = atoi(row[1]); + } + if(!punishment && (warn & SPAMSETTINGS_SPAMSCAN) && settings->exceptlevel[SPAMSETTINGS_SPAMEXCINDEX] > uaccess) { + sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_SPAM); + } + if(!punishment && (warn & SPAMSETTINGS_FLOODSCAN) && settings->exceptlevel[SPAMSETTINGS_FLOODEXCINDEX] > uaccess) { + sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_FLOOD); + } + if(punishment) { char banmaskBuf[NICKLEN+USERLEN+HOSTLEN+3]; char *banmask = NULL; - switch (reactionid) { - case 2: //TIMEBAN: 3min - duration = 180; + switch (punishment) { case 3: //TIMEBAN: 1h - if(!duration) - duration = 3600; banmask = generate_banmask(chanuser->user, banmaskBuf); - printf_mysql_query("INSERT INTO `bans` (`ban_channel`, `ban_mask`, `ban_triggered`, `ban_timeout`, `ban_owner`, `ban_reason`) VALUES ('%d', '%s', UNIX_TIMESTAMP(), '%lu', '%d', '%s')", chanuser->chan->channel_id, escape_string(banmask), (unsigned long) (time(0) + duration), 0, escape_string(reason)); - int banid = (int) mysql_insert_id(mysql_conn); - char nameBuf[MAXLEN]; - char banidBuf[20]; - sprintf(nameBuf, "ban_%d", banid); - sprintf(banidBuf, "%d", banid); - timeq_add_name(nameBuf, duration, channel_ban_timeout, strdup(banidBuf)); - case 1: //KICKBAN + printf_mysql_query("INSERT INTO `bans` (`ban_channel`, `ban_mask`, `ban_triggered`, `ban_timeout`, `ban_owner`, `ban_reason`) VALUES ('%d', '%s', UNIX_TIMESTAMP(), '%lu', '%d', '%s')", chanuser->chan->channel_id, escape_string(banmask), (unsigned long) (punish_time ? (time(0) + punish_time) : 0), 0, escape_string(reason)); + if(punish_time) { + int banid = (int) mysql_insert_id(mysql_conn); + char nameBuf[MAXLEN]; + char banidBuf[20]; + sprintf(nameBuf, "ban_%d", banid); + sprintf(banidBuf, "%d", banid); + timeq_add_name(nameBuf, punish_time, channel_ban_timeout, strdup(banidBuf)); + } + case 2: //KICKBAN if(!banmask) banmask = generate_banmask(chanuser->user, banmaskBuf); putsock(client, "MODE %s +b %s", chanuser->chan->name, banmask); - case 0: //KICK + case 1: //KICK putsock(client, "KICK %s %s :%s", chanuser->chan->name, chanuser->user->nick, reason); break; } - } + } else if(*reason) + reply(client, chanuser->user, "%s", reason); } static int neonspam_spamscan(struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message) { @@ -204,7 +218,7 @@ static int neonspam_update_penalty(struct NeonSpamSettings *settings, struct Cha int last_update = time(0) - chanuser->spamnode->last_penalty_update; if(last_update) { if(last_update < MAX_FLOOD_TIME && chanuser->spamnode->floodpenalty) { - chanuser->spamnode->floodpenalty -= last_update * (MAX_FLOOD_TIME / settings->flood_time); + chanuser->spamnode->floodpenalty -= last_update * (MAX_FLOOD_TIME / settings->sensibility_time[SPAMSETTINGS_FLOODSENINDEX]); if(chanuser->spamnode->floodpenalty < 0) chanuser->spamnode->floodpenalty = 0; } else @@ -219,9 +233,9 @@ static int neonspam_floodscan(struct NeonSpamSettings *settings, struct ChanUser if(!chanuser->spamnode) createSpamNode(chanuser); int messages_pending = neonspam_update_penalty(settings, chanuser, 1); - if(messages_pending == settings->flood_amount) + if(messages_pending == settings->sensibility_amount[SPAMSETTINGS_FLOODSENINDEX]) return SPAMSERV_CHECK_WARN; - else if(messages_pending > settings->flood_amount) + else if(messages_pending > settings->sensibility_amount[SPAMSETTINGS_FLOODSENINDEX]) return SPAMSERV_CHECK_PUNISH; else return SPAMSERV_CHECK_IGNORE; diff --git a/src/event_neonspam_join.c b/src/event_neonspam_join.c index b263903..2ef8dbd 100644 --- a/src/event_neonspam_join.c +++ b/src/event_neonspam_join.c @@ -16,7 +16,7 @@ */ static USERAUTH_CALLBACK(neonspam_event_join_nick_lookup); -static void neonspam_event_join_punish(struct ClientSocket *client, struct ChanUser *chanuser, struct NeonSpamSettings *settings, int action, char *reason, char *reaction); +static void neonspam_event_join_punish(struct ClientSocket *client, struct ChanUser *chanuser, struct NeonSpamSettings *settings, int action); static int neonspam_joinfloodscan(struct NeonSpamSettings *settings, struct ChanUser *chanuser); struct neonspam_event_join_cache { @@ -24,8 +24,6 @@ struct neonspam_event_join_cache { struct ChanUser *chanuser; struct NeonSpamSettings *settings; int action; - char *reason; - char *reaction; }; static void neonspam_event_join(struct ChanUser *chanuser) { @@ -33,38 +31,13 @@ static void neonspam_event_join(struct ChanUser *chanuser) { if(!client) return; //we can't "see" this event loadNeonSpamSettings(chanuser->chan); struct NeonSpamSettings *settings = chanuser->chan->spam_settings; - if(!settings) return; - if(settings->exceptlevel == 0) return; - //scan the message - int result = 0; - int action = SPAMSERV_CHECK_IGNORE; - char reason[MAXLEN]; - char *reaction = NULL; - if(action != SPAMSERV_CHECK_PUNISH && (settings->flags & SPAMSETTINGS_JOINSCAN)) { - result = neonspam_joinfloodscan(settings, chanuser); - switch(result) { - case SPAMSERV_CHECK_IGNORE: - break; - case SPAMSERV_CHECK_WARN: - if(action == SPAMSERV_CHECK_IGNORE) { - action = result; - sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_JOINFLOOD); - } - break; - case SPAMSERV_CHECK_PUNISH: - if(action != SPAMSERV_CHECK_PUNISH) { - action = result; - sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_JOINFLOOD); - reaction = "channel_joinreaction"; - } - break; - } - } - //some other checks? - if(action != SPAMSERV_CHECK_IGNORE) { + if(!settings || !(settings->flags & SPAMSETTINGS_JOINSCAN)) return; + if(settings->exceptlevel[SPAMSETTINGS_JOINEXCINDEX] == 0) return; + int result = neonspam_joinfloodscan(settings, chanuser); + if(result != SPAMSERV_CHECK_IGNORE) { //whois the user to check against exceptlevel - if((chanuser->user->flags & USERFLAG_ISAUTHED) || settings->exceptlevel == 501) { - neonspam_event_join_punish(client, chanuser, settings, action, reason, reaction); + if((chanuser->user->flags & USERFLAG_ISAUTHED) || settings->exceptlevel[SPAMSETTINGS_JOINEXCINDEX] == 501) { + neonspam_event_join_punish(client, chanuser, settings, result); } else { struct neonspam_event_join_cache *cache = malloc(sizeof(*cache)); if (!cache) { @@ -74,61 +47,57 @@ static void neonspam_event_join(struct ChanUser *chanuser) { cache->client = client; cache->chanuser = chanuser; cache->settings = settings; - cache->action = action; - cache->reason = strdup(reason); - cache->reaction = reaction; + cache->action = result; get_userauth(chanuser->user, neonspam_event_join_nick_lookup, cache); } - } } static USERAUTH_CALLBACK(neonspam_event_join_nick_lookup) { struct neonspam_event_join_cache *cache = data; - neonspam_event_join_punish(cache->client, cache->chanuser, cache->settings, cache->action, cache->reason, cache->reaction); - free(cache->reason); + neonspam_event_join_punish(cache->client, cache->chanuser, cache->settings, cache->action); free(cache); } -static void neonspam_event_join_punish(struct ClientSocket *client, struct ChanUser *chanuser, struct NeonSpamSettings *settings, int action, char *reason, char *reaction) { +static void neonspam_event_join_punish(struct ClientSocket *client, struct ChanUser *chanuser, struct NeonSpamSettings *settings, int action) { int uaccess = 0; if(chanuser->user->flags & USERFLAG_ISAUTHED) uaccess = getChannelAccess(chanuser->user, chanuser->chan, 0); - if(uaccess >= settings->exceptlevel) return; + if(uaccess >= settings->exceptlevel[SPAMSETTINGS_JOINEXCINDEX]) return; //scanops / scanvoiced MYSQL_RES *res; MYSQL_ROW row, defaults = NULL; loadChannelSettings(chanuser->chan); - printf_mysql_query("SELECT `%s`, `channel_getop`, `channel_getvoice` FROM `channels` WHERE `channel_id` = '%d'", reaction, chanuser->chan->channel_id); + printf_mysql_query("SELECT `channel_flood_reaction`, `channel_flood_reaction_duration`, `channel_getop`, `channel_getvoice` FROM `channels` WHERE `channel_id` = '%d'", chanuser->chan->channel_id); res = mysql_use(); row = mysql_fetch_row(res); - if(!row[0] || !row[1] || !row[2]) { - printf_mysql_query("SELECT `%s`, `channel_getop`, `channel_getvoice` FROM `channels` WHERE `channel_name` = 'defaults'", reaction); + if(!row[0] || !row[1] || !row[2] || !row[3]) { + printf_mysql_query("SELECT `channel_flood_reaction`, `channel_flood_reaction_duration`, `channel_getop`, `channel_getvoice` FROM `channels` WHERE `channel_name` = 'defaults'"); res = mysql_use(); defaults = mysql_fetch_row(res); } - if(!(settings->flags & SPAMSETTINGS_SCANOPS) && uaccess >= atoi((row[1] ? row[1] : defaults[1]))) return; - if(!(settings->flags & SPAMSETTINGS_SCANVOICE) && uaccess >= atoi((row[2] ? row[2] : defaults[2]))) return; + if(!(settings->flags & SPAMSETTINGS_JOINSCAN_OPS) && uaccess >= atoi((row[2] ? row[2] : defaults[2]))) return; + if(!(settings->flags & SPAMSETTINGS_JOINSCAN_VOICE) && uaccess >= atoi((row[3] ? row[3] : defaults[3]))) return; + char reason[MAXLEN]; + sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_JOINFLOOD); if(action == SPAMSERV_CHECK_WARN) { reply(client, chanuser->user, "%s", reason); } else if(action == SPAMSERV_CHECK_PUNISH) { - int duration = 0; + int duration = atoi((row[1] ? row[1] : defaults[1])); char banmaskBuf[NICKLEN+USERLEN+HOSTLEN+3]; char *banmask = NULL; switch (atoi((row[0] ? row[0] : defaults[0]))) { - case 2: //TIMEBAN: 3min - duration = 180; case 3: //TIMEBAN: 1h - if(!duration) - duration = 3600; banmask = generate_banmask(chanuser->user, banmaskBuf); - printf_mysql_query("INSERT INTO `bans` (`ban_channel`, `ban_mask`, `ban_triggered`, `ban_timeout`, `ban_owner`, `ban_reason`) VALUES ('%d', '%s', UNIX_TIMESTAMP(), '%lu', '%d', '%s')", chanuser->chan->channel_id, escape_string(banmask), (unsigned long) (time(0) + duration), 0, escape_string(reason)); - int banid = (int) mysql_insert_id(mysql_conn); - char nameBuf[MAXLEN]; - char banidBuf[20]; - sprintf(nameBuf, "ban_%d", banid); - sprintf(banidBuf, "%d", banid); - timeq_add_name(nameBuf, duration, channel_ban_timeout, strdup(banidBuf)); + printf_mysql_query("INSERT INTO `bans` (`ban_channel`, `ban_mask`, `ban_triggered`, `ban_timeout`, `ban_owner`, `ban_reason`) VALUES ('%d', '%s', UNIX_TIMESTAMP(), '%lu', '%d', '%s')", chanuser->chan->channel_id, escape_string(banmask), (unsigned long) (duration ? (time(0) + duration) : 0), 0, escape_string(reason)); + if(duration) { + int banid = (int) mysql_insert_id(mysql_conn); + char nameBuf[MAXLEN]; + char banidBuf[20]; + sprintf(nameBuf, "ban_%d", banid); + sprintf(banidBuf, "%d", banid); + timeq_add_name(nameBuf, duration, channel_ban_timeout, strdup(banidBuf)); + } case 1: //KICKBAN if(!banmask) banmask = generate_banmask(chanuser->user, banmaskBuf); @@ -144,7 +113,7 @@ static int neonspam_update_join_penalty(struct NeonSpamSettings *settings, struc int last_update = time(0) - joinnode->last_penalty_update; if(last_update) { if(last_update < MAX_JOIN_TIME && joinnode->joinpenalty) { - joinnode->joinpenalty -= last_update * (MAX_JOIN_TIME / settings->join_time); + joinnode->joinpenalty -= last_update * (MAX_JOIN_TIME / settings->sensibility_time[SPAMSETTINGS_JOINSENINDEX]); if(joinnode->joinpenalty < 0) joinnode->joinpenalty = 0; } else @@ -159,9 +128,9 @@ static int neonspam_joinfloodscan(struct NeonSpamSettings *settings, struct Chan if(!chanuser->spamnode) createSpamNode(chanuser); int joins_pending = neonspam_update_join_penalty(settings, getNeonSpamJoinNode(chanuser), 1); - if(joins_pending == settings->join_amount) + if(joins_pending == settings->sensibility_amount[SPAMSETTINGS_JOINSENINDEX]) return SPAMSERV_CHECK_WARN; - else if(joins_pending > settings->join_amount) + else if(joins_pending > settings->sensibility_amount[SPAMSETTINGS_JOINSENINDEX]) return SPAMSERV_CHECK_PUNISH; else return SPAMSERV_CHECK_IGNORE; diff --git a/src/mysqlConn.c b/src/mysqlConn.c index 437821a..dfc65a9 100644 --- a/src/mysqlConn.c +++ b/src/mysqlConn.c @@ -16,7 +16,7 @@ */ #include "mysqlConn.h" -#define DATABASE_VERSION "3" +#define DATABASE_VERSION "4" struct used_result { MYSQL_RES *result; -- 2.20.1