+static int neonspam_badwordscan(struct ClientSocket *client, struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message, int punish_now, int uaccess) {
+ struct NeonSpamBadword *badword;
+ int kick_user = 0;
+ int ban_user = 0;
+ int staticban_user = 0;
+ int ban_duration = 0;
+ int checked_defaults = 0;
+ int apply_default_reaction = 0;
+ for(badword = settings->badwords; badword; badword = badword->next) {
+ if(!match(badword->badword, message)) {
+ if(badword->use_defaults) {
+ if(checked_defaults == 2) continue;
+ else if(!checked_defaults) {
+ if(!(settings->flags & SPAMSETTINGS_BADWORDSCAN_OPS) && (chanuser->flags & CHANUSERFLAG_OPPED)) {
+ checked_defaults = 2;
+ continue;
+ }
+ if(!(settings->flags & SPAMSETTINGS_BADWORDSCAN_VOICE) && (chanuser->flags & CHANUSERFLAG_VOICED)) {
+ checked_defaults = 2;
+ continue;
+ }
+ if(settings->exceptlevel[SPAMSETTINGS_BADWORDEXCINDEX] && settings->exceptlevel[SPAMSETTINGS_BADWORDEXCINDEX] < 501) {
+ if(!punish_now)
+ return SPAMSERV_CHECK_PUNISH;
+ if(settings->exceptlevel[SPAMSETTINGS_BADWORDEXCINDEX] <= uaccess) {
+ checked_defaults = 2;
+ continue;
+ }
+ }
+ checked_defaults = 1;
+ }
+ } else {
+ if(!badword->scan_ops && (chanuser->flags & CHANUSERFLAG_OPPED)) continue;
+ if(!badword->scan_voice && (chanuser->flags & CHANUSERFLAG_VOICED)) continue;
+ if(badword->exceptlevel && badword->exceptlevel < 501) {
+ if(!punish_now)
+ return SPAMSERV_CHECK_PUNISH;
+ if(badword->exceptlevel <= uaccess) {
+ checked_defaults = 2;
+ continue;
+ }
+ }
+ }
+ if(badword->use_default_reaction) {
+ apply_default_reaction = 1;
+ } else {
+ switch(badword->reaction) {
+ case 2:
+ staticban_user = 1;
+ if(badword->reaction_time > ban_duration)
+ ban_duration = badword->reaction_time;
+ case 1:
+ ban_user = 1;
+ case 0:
+ kick_user = 1;
+ }
+ }
+ }
+ }
+ if(apply_default_reaction) {
+ MYSQL_RES *res;
+ MYSQL_ROW row, defaults;
+ loadChannelSettings(chanuser->chan);
+ printf_mysql_query("SELECT `channel_badword_reaction`, `channel_badword_reaction_duration` FROM `channels` WHERE `channel_id` = '%d'", chanuser->chan->channel_id);
+ res = mysql_use();
+ row = mysql_fetch_row(res);
+ if(!row[0] || !row[1]) {
+ printf_mysql_query("SELECT `channel_badword_reaction`, `channel_badword_reaction_duration` FROM `channels` WHERE `channel_name` = 'defaults'");
+ res = mysql_use();
+ defaults = mysql_fetch_row(res);
+ }
+ int reaction = atoi((row[0] ? row[0] : defaults[0]));
+ int reaction_time = atoi((row[1] ? row[1] : defaults[1]));
+ switch(reaction) {
+ case 2:
+ staticban_user = 1;
+ if(reaction_time > ban_duration)
+ ban_duration = reaction_time;
+ case 1:
+ ban_user = 1;
+ case 0:
+ kick_user = 1;
+ }
+ }
+ if(!kick_user) return SPAMSERV_CHECK_IGNORE;
+ char banmaskBuf[NICKLEN+USERLEN+HOSTLEN+3];
+ char *banmask = NULL;
+ if(staticban_user) {
+ 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) (ban_duration ? (time(0) + ban_duration) : 0), 0, escape_string(SPAMSERV_MSG_BADWORD));
+ if(ban_duration) {
+ int banid = (int) mysql_insert_id(get_mysql_conn());
+ char nameBuf[MAXLEN];
+ char banidBuf[20];
+ sprintf(nameBuf, "ban_%d", banid);
+ sprintf(banidBuf, "%d", banid);
+ timeq_add_name(nameBuf, ban_duration, module_id, channel_ban_timeout, strdup(banidBuf));
+ }
+ }
+ if(ban_user) {
+ if(!banmask)
+ banmask = generate_banmask(chanuser->user, banmaskBuf);
+ putsock(client, "MODE %s +b %s", chanuser->chan->name, banmask);
+ }
+ putsock(client, "KICK %s %s :%s", chanuser->chan->name, chanuser->user->nick, SPAMSERV_MSG_BADWORD);
+ return SPAMSERV_CHECK_DEAD;
+}