added cmd_set for NeonSpam
authorpk910 <philipp@zoelle1.de>
Wed, 19 Oct 2011 21:42:49 +0000 (23:42 +0200)
committerpk910 <philipp@zoelle1.de>
Wed, 19 Oct 2011 22:12:50 +0000 (00:12 +0200)
Makefile.am
src/bot_NeonSpam.c
src/bot_NeonSpam.h
src/cmd_neonspam.h [new file with mode: 0644]
src/cmd_neonspam_set.c [new file with mode: 0644]

index ad6a87d2e04aacef5d03aa8ae07788c3069019c0..abd14a6a373a7c3a5e407dd03f38a5c3ec406512 100644 (file)
@@ -107,6 +107,7 @@ neonserv_SOURCES = src/version.c \
       src/cmd_neonserv_rename.c \
       src/cmd_neonserv_unvisited.c \
       src/cmd_neonserv_extscript.c \
+      src/cmd_neonspam_set.c \
       src/lib/ini.c
 
 neonserv_LDADD = $(MYSQL_LIBS) $(WINSOCK_LIBS)
index bf2ae92c6392712140a3927e5e514cd765263ec3..73755b733f30ba07cdb6b370fde59c4bc407ba6c 100644 (file)
@@ -36,6 +36,7 @@
 #include "EventLogger.h"
 #include "bots.h"
 #include "cmd_neonserv.h"
+#include "cmd_neonspam.h"
 
 #define BOTID 2
 
@@ -149,6 +150,7 @@ void init_NeonSpam() {
     //               NAME              FUNCTION        PARAMS     PRIVS                FLAGS
     USER_COMMAND("netinfo",      neonserv_cmd_netinfo,   0, NULL,                   0);
     USER_COMMAND("version",      neonserv_cmd_version,   0, NULL,                   0);
+    USER_COMMAND("set",          neonspam_cmd_set,       0, "#channel_setters",     CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_LOG);
     #undef USER_COMMAND
     
     #define OPER_COMMAND(NAME,FUNCTION,PARAMCOUNT,GACCESS,FLAGS) register_command(BOTID, NAME, FUNCTION, PARAMCOUNT, NULL, GACCESS, FLAGS)
index 723f1a26cf13ed6f9c422fd4fceb8dae59a4c07f..4cf64a928be5c3231a673b88f573d0be67259179 100644 (file)
 #define SPAMSETTINGS_SCANOPS   0x08
 #define SPAMSETTINGS_SCANVOICE 0x10
 
-#define MAX_FLOOD_TIME 200
+#define MAX_FLOOD_AMOUNT 300
+#define MIN_FLOOD_AMOUNT 2
+#define MAX_FLOOD_TIME   200
+
+#define MAX_JOIN_AMOUNT 300
+#define MIN_JOIN_AMOUNT 2
+#define MAX_JOIN_TIME   200
 
 struct NeonSpamSettings {
     unsigned int flags;
diff --git a/src/cmd_neonspam.h b/src/cmd_neonspam.h
new file mode 100644 (file)
index 0000000..433853d
--- /dev/null
@@ -0,0 +1,43 @@
+/* cmd_neonspam.h - NeonServ v5.1
+ * Copyright (C) 2011  Philipp Kreil (pk910)
+ * 
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License 
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 
+ */
+#ifndef _cmd_neonspam_h
+#define _cmd_neonspam_h
+#include "main.h"
+#include "modcmd.h"
+#include "IRCParser.h"
+#include "IRCEvents.h"
+#include "UserNode.h"
+#include "ChanNode.h"
+#include "ChanUser.h"
+#include "ModeNode.h"
+#include "BanNode.h"
+#include "ClientSocket.h"
+#include "mysqlConn.h"
+#include "lang.h"
+#include "HandleInfoHandler.h"
+#include "WHOHandler.h"
+#include "DBHelper.h"
+#include "tools.h"
+#include "timeq.h"
+#include "version.h"
+#include "EventLogger.h"
+#include "bots.h"
+#include "bot_NeonSpam.h"
+
+CMD_BIND(neonspam_cmd_set);
+
+#endif
\ No newline at end of file
diff --git a/src/cmd_neonspam_set.c b/src/cmd_neonspam_set.c
new file mode 100644 (file)
index 0000000..9a9c238
--- /dev/null
@@ -0,0 +1,540 @@
+/* cmd_neonspam_set.c - NeonServ v5.1
+ * Copyright (C) 2011  Philipp Kreil (pk910)
+ * 
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License 
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 
+ */
+
+#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_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 */
+
+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"
+
+static const struct {
+    const char *setting;
+    const char *chanfield;
+    unsigned int valid;
+    void *parameter;
+    void *function;
+} 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},
+    {"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}
+};
+
+#define MAX_QUERY_LEN 1024
+CMD_BIND(neonspam_cmd_set) {
+    int i, j;
+    if(argc && !strcmp(argv[0], "defaults")) {
+        //reset channel settings
+        int uaccess = getChannelAccess(user, chan, 0);
+        if(uaccess < 500) {
+            if(isGodMode(user)) {
+                event->flags |= CMDFLAG_OPLOG;
+            } else {
+                reply(getTextBot(), user, "NS_SET_DEFAULTS_OWNER", chan->name);
+                return;
+            }
+        }
+        int seed = 0;
+        char *tmp;
+        static char defaultskey[16];
+        for(tmp = user->auth; *tmp; tmp++)
+            seed = (seed * 0xEECE66DL ^ ((*tmp << 24) | (*tmp << 16) | (*tmp << 8) | *tmp));
+        for(tmp = chan->name; *tmp; tmp++)
+            seed = (seed * 0xEECE66DL ^ ((*tmp << 24) | (*tmp << 16) | (*tmp << 8) | *tmp));
+        sprintf(defaultskey, "%08x", seed);
+        if(argc > 1 && !strcmp(argv[1], defaultskey)) {
+            printf_mysql_query("UPDATE `channels` SET " SPAMSERV_SETTINGS_RESET " WHERE `channel_id` = '%d'", chan->channel_id);
+            reply(getTextBot(), user, "NS_SET_DEFAULTS_DONE", chan->name);
+            logEvent(event);
+        } else {
+            reply(getTextBot(), user, "NS_SET_DEFAULTS_CODE", chan->name, defaultskey);
+        }
+    } else if(argc && strcmp(argv[0], "help")) {
+        //find the correct command
+        i = 0;
+        j = 0;
+        char *args = (argc > 1 ? merge_argv(argv, 1, argc) : 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);
+                j = 1;
+                break;
+            }
+            i++;
+        }
+        if(j == 0) {
+            //unknown setting
+            reply(getTextBot(), user, "NS_SET_UNKNOWN_SETTING", argv[0]);
+        }
+    } else {
+        char *value, *org_value, *tmp, nameBuf[64];
+        MYSQL_RES *res, *defaults_res;
+        struct Table *table;
+        char *content[2];
+        char query[MAXLEN];
+        int querypos;
+        i = 0;
+        while(neonspam_settings[i].setting)
+            i++;
+        table = table_init(2, i, 0);
+        table_set_bold(table, 0, 1);
+        printf_mysql_query("SELECT " SPAMSERV_SETTINGS_QUERY " FROM `channels` WHERE `channel_name` = 'defaults'");
+        defaults_res = mysql_use();
+        neonspam_settings_defaults = mysql_fetch_row(defaults_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);
+        i = 0;
+        j = 0;
+        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");
+            }
+            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;
+            table_add(table, content);
+            i++;
+        }
+        char **table_lines = table_end(table);
+        for(i = 0; i < table->entrys; i++) {
+            reply(getTextBot(), user, table_lines[i]);
+        }
+        table_free(table);
+    }
+}
+
+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) {
+    char *trigger;
+    //get current trigger
+    MYSQL_RES *res;
+    MYSQL_ROW row;
+    printf_mysql_query("SELECT `trigger` FROM `bot_channels` WHERE `chanid` = '%d' AND `botid` = '%d'", chan->channel_id, client->clientid);
+    res = mysql_use();
+    row = mysql_fetch_row(res);
+    trigger = row[0];
+    if(cvalue && argument) {
+        int uaccess = getChannelAccess(user, chan, 0);
+        if(uaccess < 500) {
+            if(isGodMode(user)) {
+                event->flags |= CMDFLAG_OPLOG;
+            } else {
+                reply(getTextBot(), user, "NS_SET_TRIGGER_OWNER", chan->name);
+                return NULL;
+            }
+        }
+        if(strlen(argument) > 15)
+            argument[15] = '\0';
+        printf_mysql_query("UPDATE `bot_channels` SET `trigger` = '%s' WHERE `chanid` = '%d' AND `botid` = '%d'", escape_string(argument), chan->channel_id, client->clientid);
+        trigger = argument;
+        changeChannelTrigger(client->botid, chan, trigger);
+        logEvent(event);
+    }
+    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));
+    }
+    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;
+    }
+    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;
+    }
+    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;
+    }
+    return cvalue;
+}
+
+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;
+    }
+    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;
+    }
+    return cvalue;
+}
+
+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));
+    }
+    return cvalue;
+}
+
+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) {
+        //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_FLOOD_AMOUNT || amount < MIN_FLOOD_AMOUNT) {
+            //invalid amount
+            return NULL;
+        }
+        if(timep > MAX_FLOOD_TIME || timep < 0) {
+            //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);
+    }
+    return cvalue;
+}
+
+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) {
+        //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) {
+            //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);
+    }
+    return cvalue;
+}
+
+
+#undef MAX_QUERY_LEN