+static int neonspam_botnetscan(struct ClientSocket *client, struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message) {
+ //crc32 hash of the message
+ unsigned long msghash = crc32(message);
+ if((time(0) - settings->lastmsg_time) > BOTNETSCAN_TIME || settings->lastmsg != msghash) {
+ int i;
+ for(i = 0; i < BOTNETSCAN_USERS; i++) {
+ if(settings->botnicks[i]) {
+ free(settings->botnicks[i]);
+ settings->botnicks[i] = NULL;
+ }
+ }
+ settings->flags &= ~SPAMSETTINGS_KICKEDBOTQUEUE;
+ settings->lastmsg = msghash;
+ } else if(settings->lastmsg == msghash) {
+ int i;
+ for(i = 0; i < BOTNETSCAN_USERS; i++) {
+ if(!settings->botnicks[i]) {
+ settings->botnicks[i] = strdup(chanuser->user->nick);
+ break;
+ } else if(!stricmp(chanuser->user->nick, settings->botnicks[i])) {
+ return SPAMSERV_CHECK_IGNORE;
+ }
+ }
+ if(i == BOTNETSCAN_USERS) {
+ //BOTNETSCAN_USERS exceeded
+ if(!(settings->flags & SPAMSETTINGS_KICKEDBOTQUEUE)) {
+ for(i = 0; i < BOTNETSCAN_USERS; i++) {
+ putsock(client, "KICK %s %s :%s", chanuser->chan->name, settings->botnicks[i], SPAMSERV_MSG_BOTNET);
+ }
+ settings->flags |= SPAMSETTINGS_KICKEDBOTQUEUE;
+ }
+ putsock(client, "KICK %s %s :%s", chanuser->chan->name, chanuser->user->nick, SPAMSERV_MSG_BOTNET);
+ return SPAMSERV_CHECK_DEAD;
+ }
+ }
+ settings->lastmsg_time = time(0);
+ return SPAMSERV_CHECK_IGNORE;
+}
+
+static int neonspam_capsscan(struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message) {
+ int caps = 0, msglen = strlen(message);
+ int i;
+ if(msglen <= 4) return SPAMSERV_CHECK_IGNORE;
+ for(i = 0; i < msglen; i++) {
+ if(isupper(message[i])) caps++;
+ }
+ caps = 100*caps/msglen;
+ if(caps >= settings->percent[SPAMSETTINGS_CAPSPERCENTINDEX]) {
+ if(!chanuser->spamnode)
+ createSpamNode(chanuser);
+ if(chanuser->spamnode->flags & NEONSPAMNODE_FLAG_CAPSSCAN_WARNED)
+ return SPAMSERV_CHECK_PUNISH;
+ else {
+ chanuser->spamnode->flags |= NEONSPAMNODE_FLAG_CAPSSCAN_WARNED;
+ return SPAMSERV_CHECK_WARN;
+ }
+ }
+ return SPAMSERV_CHECK_IGNORE;
+}
+
+static int neonspam_digitscan(struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message) {
+ int digit = 0, msglen = strlen(message);
+ int i;
+ if(msglen <= 4) return SPAMSERV_CHECK_IGNORE;
+ for(i = 0; i < msglen; i++) {
+ if(isdigit(message[i])) digit++;
+ }
+ digit = 100*digit/msglen;
+ if(digit >= settings->percent[SPAMSETTINGS_DIGITPERCENTINDEX]) {
+ if(!chanuser->spamnode)
+ createSpamNode(chanuser);
+ if(chanuser->spamnode->flags & NEONSPAMNODE_FLAG_DIGITSCAN_WARNED)
+ return SPAMSERV_CHECK_PUNISH;
+ else {
+ chanuser->spamnode->flags |= NEONSPAMNODE_FLAG_DIGITSCAN_WARNED;
+ return SPAMSERV_CHECK_WARN;
+ }
+ }
+ return SPAMSERV_CHECK_IGNORE;
+}