added missing text outputs and some "global set" functions to cmd_set
authorpk910 <philipp@zoelle1.de>
Tue, 25 Oct 2011 23:42:19 +0000 (01:42 +0200)
committerpk910 <philipp@zoelle1.de>
Tue, 25 Oct 2011 23:54:33 +0000 (01:54 +0200)
src/bot_NeonSpam.c
src/cmd_neonspam_set.c

index 0d9c5de855e401656f032fdd9ae9d82e58b05197..27d82750a49cb83f2850d5ec74c2cadda4696137 100644 (file)
 #define BOTID 2
 
 static const struct default_language_entry msgtab[] = {
+    {"SS_SET_PERCENT", "%u is an invalid percent value (valid: 0-100)"},
+    {"SS_SET_SENSIBILITY", "%s is an invalid sensibility format. (valid: amount:time   e.g. 5:10)"},
+    {"SS_SET_SENSIBILITY_AMOUNT", "%d is an invalid amount value. (valid: %d-%d)"},
+    {"SS_SET_SENSIBILITY_TIME", "%d is an invalid time value. (valid: %d-%d)"},
+    {"SS_SET_SPAMLIMIT", "%d is an invalid spamlimit value. (valid: %d-%d)"},
+    {"SS_SET_OPTION_SpamReaction_0", "Kick"},
+    {"SS_SET_OPTION_SpamReaction_1", "KickBan"},
+    {"SS_SET_OPTION_SpamReaction_2", "Timed Ban"},
+    {"SS_SET_OPTION_FloodReaction_0", "Kick"},
+    {"SS_SET_OPTION_FloodReaction_1", "KickBan"},
+    {"SS_SET_OPTION_FloodReaction_2", "Timed Ban"},
+    {"SS_SET_OPTION_JoinReaction_0", "Kick"},
+    {"SS_SET_OPTION_JoinReaction_1", "KickBan"},
+    {"SS_SET_OPTION_JoinReaction_2", "Timed Ban"},
+    {"SS_SET_OPTION_CapsReaction_0", "Kick"},
+    {"SS_SET_OPTION_CapsReaction_1", "KickBan"},
+    {"SS_SET_OPTION_CapsReaction_2", "Timed Ban"},
+    {"SS_SET_OPTION_DigitReaction_0", "Kick"},
+    {"SS_SET_OPTION_DigitReaction_1", "KickBan"},
+    {"SS_SET_OPTION_DigitReaction_2", "Timed Ban"},
     {NULL, NULL}
 };
 
index 9890a6272493150a56f4082fcf59fbc9391a1e3f..857e597d9fd71e1d60fcafceb271069555255b41 100644 (file)
@@ -26,6 +26,9 @@ static char* neonspam_cmd_set_reaction_time(struct ClientSocket *client, struct
 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 char* neonspam_cmd_setscanops(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf);
+static char* neonspam_cmd_setscanvoice(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int intparam, char *charparam, char *argument, char *retBuf);
+static char* neonspam_cmd_setscanexcept(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_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`"
@@ -56,6 +59,17 @@ static MYSQL_ROW neonspam_settings_row, neonspam_settings_defaults;
 `channel_digit_reaction_duration` = NULL, \
 `channel_digit_except` = NULL "
 
+#define SET_HELP       0x0001
+#define SET_BOOL       0x0002
+#define SET_OPT        0x0004
+
+#define SET_SCANOPS    0x0010
+#define SET_SCANVOICE  0x0020
+#define SET_SCANEXCEPT 0x0040
+
+#define SET_OPT_MAX    0xff00
+#define SET_OPT_SHIFT  8
+
 static const struct {
     unsigned int if_flag;
     unsigned int indent;
@@ -63,56 +77,61 @@ static const struct {
     void *function;
     int intparam;
     char *charparam;
+    int flags;
 } neonspam_settings[] = {
-    {0,                                                0,  "Trigger",           neonspam_cmd_set_trigger,         0,                              NULL},
+    {0,                                                0,  "Trigger",           neonspam_cmd_set_trigger,         0,                              NULL,                             SET_HELP},
+    
+    {0,                                                0,  "SpamScan",          neonspam_cmd_setflags,            SPAMSETTINGS_SPAMSCAN,          NULL,                             SET_BOOL},
+    {SPAMSETTINGS_SPAMSCAN,                            2,  "SpamLimit",         neonspam_cmd_set_spamlimit,       0,                              NULL,                             SET_HELP},
+    {SPAMSETTINGS_SPAMSCAN | SPAMSETTINGS_SETTIMEBAN,  2,  "SpamReaction",      neonspam_cmd_set_reaction,        0,                              "channel_spam_reaction",          SET_OPT | (3 << SET_OPT_SHIFT)},
+    {SPAMSETTINGS_SPAMSCAN | SPAMSETTINGS_ISTIMEBAN,   4,  "SpamBanDuration",   neonspam_cmd_set_reaction_time,   1,                              "channel_spam_reaction_duration", 0},
+    {SPAMSETTINGS_SPAMSCAN,                            2,  "SpamScanChanOps",   neonspam_cmd_setflags,            SPAMSETTINGS_SPAMSCAN_OPS,      NULL,                             SET_BOOL | SET_SCANOPS},
+    {SPAMSETTINGS_SPAMSCAN,                            2,  "SpamScanVoiced",    neonspam_cmd_setflags,            SPAMSETTINGS_SPAMSCAN_VOICE,    NULL,                             SET_BOOL | SET_SCANVOICE},
+    {SPAMSETTINGS_SPAMSCAN,                            2,  "SpamScanExcept",    neonspam_cmd_setexcept,           SPAMSETTINGS_SPAMEXCINDEX,      "channel_spam_except",            SET_HELP | SET_SCANEXCEPT},
     
-    {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,                             SET_BOOL},
+    {SPAMSETTINGS_FLOODSCAN,                           2,  "FloodSensibility",  neonspam_cmd_setsensibility,      SPAMSETTINGS_FLOODSENINDEX,     "channel_flood_",                 SET_HELP},
+    {SPAMSETTINGS_FLOODSCAN | SPAMSETTINGS_SETTIMEBAN, 2,  "FloodReaction",     neonspam_cmd_set_reaction,        2,                              "channel_flood_reaction",         SET_OPT | (3 << SET_OPT_SHIFT)},
+    {SPAMSETTINGS_FLOODSCAN | SPAMSETTINGS_ISTIMEBAN,  4,  "FloodBanDuration",  neonspam_cmd_set_reaction_time,   3,                              "channel_flood_reaction_duration",0},
+    {SPAMSETTINGS_FLOODSCAN,                           2,  "FloodScanChanOps",  neonspam_cmd_setflags,            SPAMSETTINGS_FLOODSCAN_OPS,     NULL,                             SET_BOOL | SET_SCANOPS},
+    {SPAMSETTINGS_FLOODSCAN,                           2,  "FloodScanVoiced",   neonspam_cmd_setflags,            SPAMSETTINGS_FLOODSCAN_VOICE,   NULL,                             SET_BOOL | SET_SCANVOICE},
+    {SPAMSETTINGS_FLOODSCAN,                           2,  "FloodScanExcept",   neonspam_cmd_setexcept,           SPAMSETTINGS_FLOODEXCINDEX,     "channel_flood_except",           SET_HELP | SET_SCANEXCEPT},
     
-    {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,                             SET_BOOL},
+    {SPAMSETTINGS_JOINSCAN,                            2,  "JoinSensibility",   neonspam_cmd_setsensibility,      SPAMSETTINGS_JOINSENINDEX,      "channel_join_",                  SET_HELP},
+    {SPAMSETTINGS_JOINSCAN | SPAMSETTINGS_SETTIMEBAN,  2,  "JoinReaction",      neonspam_cmd_set_reaction,        4,                              "channel_join_reaction",          SET_OPT | (3 << SET_OPT_SHIFT)},
+    {SPAMSETTINGS_JOINSCAN | SPAMSETTINGS_ISTIMEBAN,   4,  "JoinBanDuration",   neonspam_cmd_set_reaction_time,   5,                              "channel_join_reaction_duration", 0},
+    {SPAMSETTINGS_JOINSCAN,                            2,  "JoinScanChanOps",   neonspam_cmd_setflags,            SPAMSETTINGS_JOINSCAN_OPS,      NULL,                             SET_BOOL | SET_SCANOPS},
+    {SPAMSETTINGS_JOINSCAN,                            2,  "JoinScanVoiced",    neonspam_cmd_setflags,            SPAMSETTINGS_JOINSCAN_VOICE,    NULL,                             SET_BOOL | SET_SCANVOICE},
+    {SPAMSETTINGS_JOINSCAN,                            2,  "JoinScanExcept",    neonspam_cmd_setexcept,           SPAMSETTINGS_JOINEXCINDEX,      "channel_join_except",            SET_HELP | SET_SCANEXCEPT},
     
-    {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,                             SET_BOOL},
+    {SPAMSETTINGS_BOTNETSCAN,                          4,  "BotNetBanDuration", neonspam_cmd_set_reaction_time,   6,                              "channel_botnet_bantime",         0},
+    {SPAMSETTINGS_BOTNETSCAN,                          2,  "BotNetScanChanOps", neonspam_cmd_setflags,            SPAMSETTINGS_BOTNETSCAN_OPS,    NULL,                             SET_BOOL | SET_SCANOPS},
+    {SPAMSETTINGS_BOTNETSCAN,                          2,  "BotNetScanVoiced",  neonspam_cmd_setflags,            SPAMSETTINGS_BOTNETSCAN_VOICE,  NULL,                             SET_BOOL | SET_SCANVOICE},
+    //{SPAMSETTINGS_BOTNETSCAN,                          2,  "BotNetScanExcept",  neonspam_cmd_setexcept,           SPAMSETTINGS_BOTNETEXCINDEX,    "channel_botnet_except",          SET_HELP},
     
-    {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,                             SET_BOOL},
+    {SPAMSETTINGS_CAPSSCAN,                            2,  "CapsPercent",       neonspam_cmd_setpercent,          SPAMSETTINGS_CAPSPERCENTINDEX,  "channel_caps_percent",           SET_HELP},
+    {SPAMSETTINGS_CAPSSCAN | SPAMSETTINGS_SETTIMEBAN,  2,  "CapsReaction",      neonspam_cmd_set_reaction,        7,                              "channel_caps_reaction",          SET_OPT | (3 << SET_OPT_SHIFT)},
+    {SPAMSETTINGS_CAPSSCAN | SPAMSETTINGS_ISTIMEBAN,   4,  "CapsBanDuration",   neonspam_cmd_set_reaction_time,   8,                              "channel_caps_reaction_duration", 0},
+    {SPAMSETTINGS_CAPSSCAN,                            2,  "CapsScanChanOps",   neonspam_cmd_setflags,            SPAMSETTINGS_CAPSSCAN_OPS,      NULL,                             SET_BOOL | SET_SCANOPS},
+    {SPAMSETTINGS_CAPSSCAN,                            2,  "CapsScanVoiced",    neonspam_cmd_setflags,            SPAMSETTINGS_CAPSSCAN_VOICE,    NULL,                             SET_BOOL | SET_SCANVOICE},
+    {SPAMSETTINGS_CAPSSCAN,                            2,  "CapsScanExcept",    neonspam_cmd_setexcept,           SPAMSETTINGS_CAPSEXCINDEX,      "channel_caps_except",            SET_HELP | SET_SCANEXCEPT},
     
-    {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,                             SET_BOOL},
+    {SPAMSETTINGS_DIGITSCAN,                           2,  "DigitPercent",      neonspam_cmd_setpercent,          SPAMSETTINGS_DIGITPERCENTINDEX, "channel_digit_percent",          SET_HELP},
+    {SPAMSETTINGS_DIGITSCAN | SPAMSETTINGS_SETTIMEBAN, 2,  "DigitReaction",     neonspam_cmd_set_reaction,        9,                              "channel_digit_reaction",         SET_OPT | (3 << SET_OPT_SHIFT)},
+    {SPAMSETTINGS_DIGITSCAN | SPAMSETTINGS_ISTIMEBAN,  4,  "DigitBanDuration",  neonspam_cmd_set_reaction_time,   10,                             "channel_digit_reaction_duration", 0},
+    {SPAMSETTINGS_DIGITSCAN,                           2,  "DigitScanChanOps",  neonspam_cmd_setflags,            SPAMSETTINGS_DIGITSCAN_OPS,     NULL,                             SET_BOOL | SET_SCANOPS},
+    {SPAMSETTINGS_DIGITSCAN,                           2,  "DigitScanVoiced",   neonspam_cmd_setflags,            SPAMSETTINGS_DIGITSCAN_VOICE,   NULL,                             SET_BOOL | SET_SCANVOICE},
+    {SPAMSETTINGS_DIGITSCAN,                           2,  "DigitScanExcept",   neonspam_cmd_setexcept,           SPAMSETTINGS_DIGITEXCINDEX,     "channel_digit_except",           SET_HELP | SET_SCANEXCEPT},
     
-    {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,  "GlobalScanChanOps", neonspam_cmd_setscanops,          0,                              NULL,                             SET_BOOL},
+    {0,                                                0,  "GlobalScanVoice",   neonspam_cmd_setscanvoice,        0,                              NULL,                             SET_BOOL},
+    {0,                                                0,  "GlobalScanExcept",  neonspam_cmd_setscanexcept,       0,                              NULL,                             SET_HELP},
     
-    {0, 0, NULL, NULL, 0, NULL}
+    {0, 0, NULL, NULL, 0, NULL, 0}
 };
 
 #define MAX_QUERY_LEN 1024
@@ -154,13 +173,40 @@ CMD_BIND(neonspam_cmd_set) {
         while(neonspam_settings[i].setting) {
             if(!stricmp(neonspam_settings[i].setting, argv[0])) {
                 //setting found
-                char valueBuf[MAXLEN];
-                char *value;
+                char valueBuf[MAXLEN], nameBuf[MAXLEN];
+                char *value, *optimized_value, *option_help;
                 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
+                    optimized_value = value;
+                    if(neonspam_settings[i].flags & SET_BOOL) {
+                        if(!strcmp(value, "0"))
+                            optimized_value = get_language_string(user, "NS_SET_OFF");
+                        else if(!strcmp(value, "1"))
+                            optimized_value = get_language_string(user, "NS_SET_ON");
+                    }
+                    if(neonspam_settings[i].flags & SET_OPT) {
+                        sprintf(nameBuf, "SS_SET_OPTION_%s_%s", neonspam_settings[i].setting, value);
+                        option_help = get_language_string(user, nameBuf);
+                    } else
+                        option_help = NULL;
+                    reply(getTextBot(), user, "\002%s\002 %s%s%s", neonspam_settings[i].setting, optimized_value, (option_help ? " - " : ""), (option_help ? option_help : ""));
+                    if(neonspam_settings[i].flags & SET_OPT) {
+                        int maxoption = (neonspam_settings[i].flags & SET_OPT_MAX) >> SET_OPT_SHIFT;
+                        for(j = 0; j < maxoption; j++) {
+                            sprintf(nameBuf, "SS_SET_OPTION_%s_%d", neonspam_settings[i].setting, j);
+                            
+                            reply(getTextBot(), user, " \002%d\002 - %s", j, option_help);
+                        }
+                    }
+                    if((neonspam_settings[i].flags & SET_HELP) && argc && !strcmp(argv[0], "help")) {
+                        char *tmp;
+                        sprintf(nameBuf, "SS_SET_HELP_%s", neonspam_settings[i].setting);
+                        tmp = get_language_string(user, nameBuf);
+                        if(tmp) {
+                            reply(getTextBot(), user, "  %s", tmp);
+                        }
+                    }
                 }
                 j = 1;
                 break;
@@ -196,18 +242,41 @@ CMD_BIND(neonspam_cmd_set) {
                 continue;
             if((neonspam_settings[i].if_flag & SPAMSETTINGS_ISTIMEBAN) && !boolflag)
                 continue;
-            namePos = 0;
-            for(j = 0; j < neonspam_settings[i].indent; j++) {
-                nameBuf[namePos++] = ' ';
-            }
             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
+            strcpy(valueBuf, value);
+            if(neonspam_settings[i].flags & SET_BOOL) {
+                if(!strcmp(value, "0"))
+                    strcpy(valueBuf, get_language_string(user, "NS_SET_OFF"));
+                else if(!strcmp(value, "1"))
+                    strcpy(valueBuf, get_language_string(user, "NS_SET_ON"));
+            }
+            if(neonspam_settings[i].flags & SET_OPT) {
+                char *tmp;
+                sprintf(nameBuf, "SS_SET_OPTION_%s_%s", neonspam_settings[i].setting, value);
+                tmp = get_language_string(user, nameBuf);
+                if(tmp) {
+                    sprintf(valueBuf + strlen(valueBuf), " - %s", tmp);
+                }
+            }
+            if((neonspam_settings[i].flags & SET_HELP) && argc && !strcmp(argv[0], "help")) {
+                char *tmp;
+                sprintf(nameBuf, "SS_SET_HELP_%s", neonspam_settings[i].setting);
+                tmp = get_language_string(user, nameBuf);
+                if(tmp) {
+                    sprintf(valueBuf + strlen(valueBuf), " - %s", tmp);
+                }
+            }
+            namePos = 0;
+            for(j = 0; j < neonspam_settings[i].indent; j++) {
+                nameBuf[namePos++] = ' ';
+            }
             sprintf(nameBuf + namePos, "%s", neonspam_settings[i].setting);
             content[0] = nameBuf;
-            content[1] = value;
+            content[1] = valueBuf;
             table_add(table, content);
         }
         char **table_lines = table_end(table);
@@ -278,7 +347,7 @@ static char* neonspam_cmd_setexcept(struct ClientSocket *client, struct UserNode
         }
         int uaccess = getChannelAccess(user, chan, 0);
         if(uaccess == 500) uaccess++;
-        if(caccess > uaccess) {
+        if(value > uaccess) {
             if(isGodMode(user)) {
                 event->flags |= CMDFLAG_OPLOG;
             } else {
@@ -367,6 +436,7 @@ static char* neonspam_cmd_setpercent(struct ClientSocket *client, struct UserNod
         value = atoi(argument);
         if(value < 0 || value > 100) {
             //invalid percent value
+            reply(getTextBot(), user, "SS_SET_PERCENT", value);
             return NULL;
         }
         chan->spam_settings->percent[percent_index] = value;
@@ -382,6 +452,7 @@ static char* neonspam_cmd_setsensibility(struct ClientSocket *client, struct Use
         char *delimiter = strstr(argument, ":");
         if(!delimiter) {
             //invalid format
+            reply(getTextBot(), user, "SS_SET_SENSIBILITY", argument);
             return NULL;
         }
         *delimiter = '\0';
@@ -390,10 +461,12 @@ static char* neonspam_cmd_setsensibility(struct ClientSocket *client, struct Use
         int timep = atoi(delimiter);
         if(amount > MAX_FLOOD_AMOUNT || amount < MIN_FLOOD_AMOUNT) {
             //invalid amount
+            reply(getTextBot(), user, "SS_SET_SENSIBILITY_AMOUNT", amount, MIN_FLOOD_AMOUNT, MAX_FLOOD_AMOUNT);
             return NULL;
         }
         if(timep > MAX_FLOOD_TIME || timep < 0) {
             //invalid time period
+            reply(getTextBot(), user, "SS_SET_SENSIBILITY_TIME", timep, 0, MAX_FLOOD_TIME);
             return NULL;
         }
         char amountfield[50], timefield[50];
@@ -413,8 +486,9 @@ static char* neonspam_cmd_set_spamlimit(struct ClientSocket *client, struct User
     if(argument) {
         //change value
         int amount = atoi(argument);
-        if(amount > MAX_FLOOD_AMOUNT || amount < MIN_FLOOD_AMOUNT) {
+        if(amount > 10 || amount < 2) {
             //invalid amount
+            reply(getTextBot(), user, "SS_SET_SPAMLIMIT", amount, 2, 10);
             return NULL;
         }
         printf_mysql_query("UPDATE `channels` SET `channel_maxrepeat` = '%d' WHERE `channel_id` = '%d' ", amount, chan->channel_id);
@@ -425,4 +499,156 @@ static char* neonspam_cmd_set_spamlimit(struct ClientSocket *client, struct User
     return retBuf;
 }
 
+static char* neonspam_cmd_setscanops(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int flag, char *charparam, char *argument, char *retBuf) {
+    int i = 0;
+    int value = -1;
+    int identical = 1;
+    while(neonspam_settings[i].setting) {
+        if(neonspam_settings[i].flags & SET_SCANOPS) {
+            if(value == -1)
+                value = ((chan->spam_settings->flags & neonspam_settings[i].intparam) ? 1 : 0);
+            else {
+                if(((chan->spam_settings->flags & neonspam_settings[i].intparam) ? 1 : 0) != value) {
+                    identical = 0;
+                    break;
+                }
+            }
+        }
+        i++;
+    }
+    if(argument) {
+        //binary argument...
+        if(!strcmp(argument, "0") || !stricmp(argument, "off") || !stricmp(argument, get_language_string(user, "NS_SET_OFF"))) {
+            value = 0;
+        } else if(!strcmp(argument, "1") || !stricmp(argument, "on") || !stricmp(argument, get_language_string(user, "NS_SET_ON"))) {
+            value = 1;
+        } else {
+            reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", argument);
+            return NULL;
+        }
+        i = 0;
+        char valueBuf[MAXLEN];
+        while(neonspam_settings[i].setting) {
+            if(neonspam_settings[i].flags & SET_SCANOPS) {
+                neonspam_cmd_set_function *func = neonspam_settings[i].function;
+                func(client, user, chan, event, neonspam_settings[i].intparam, neonspam_settings[i].charparam, (value ? "1" : "0"), valueBuf);
+            }
+            i++;
+        }
+        identical = 1;
+    }
+    if(identical && value)
+        return "1";
+    if(identical && !value)
+        return "0";
+    return "?";
+}
+
+static char* neonspam_cmd_setscanvoice(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int flag, char *charparam, char *argument, char *retBuf) {
+    int i = 0;
+    int value = -1;
+    int identical = 1;
+    while(neonspam_settings[i].setting) {
+        if(neonspam_settings[i].flags & SET_SCANVOICE) {
+            if(value == -1)
+                value = ((chan->spam_settings->flags & neonspam_settings[i].intparam) ? 1 : 0);
+            else {
+                if(((chan->spam_settings->flags & neonspam_settings[i].intparam) ? 1 : 0) != value) {
+                    identical = 0;
+                    break;
+                }
+            }
+        }
+        i++;
+    }
+    if(argument) {
+        //binary argument...
+        if(!strcmp(argument, "0") || !stricmp(argument, "off") || !stricmp(argument, get_language_string(user, "NS_SET_OFF"))) {
+            value = 0;
+        } else if(!strcmp(argument, "1") || !stricmp(argument, "on") || !stricmp(argument, get_language_string(user, "NS_SET_ON"))) {
+            value = 1;
+        } else {
+            reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", argument);
+            return NULL;
+        }
+        i = 0;
+        char valueBuf[MAXLEN];
+        while(neonspam_settings[i].setting) {
+            if(neonspam_settings[i].flags & SET_SCANVOICE) {
+                neonspam_cmd_set_function *func = neonspam_settings[i].function;
+                func(client, user, chan, event, neonspam_settings[i].intparam, neonspam_settings[i].charparam, (value ? "1" : "0"), valueBuf);
+            }
+            i++;
+        }
+        identical = 1;
+    }
+    if(identical && value)
+        return "1";
+    if(identical && !value)
+        return "0";
+    return "?";
+}
+
+static char* neonspam_cmd_setscanexcept(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int flag, char *charparam, char *argument, char *retBuf) {
+    int i = 0;
+    int value = -1;
+    int identical = 1;
+    while(neonspam_settings[i].setting) {
+        if(neonspam_settings[i].flags & SET_SCANEXCEPT) {
+            if(value == -1)
+                value = chan->spam_settings->exceptlevel[neonspam_settings[i].intparam];
+            else {
+                if(chan->spam_settings->exceptlevel[neonspam_settings[i].intparam] != value) {
+                    identical = 0;
+                    break;
+                }
+            }
+        }
+        i++;
+    }
+    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(identical && value > 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;
+            }
+        }
+        i = 0;
+        char valueBuf[MAXLEN];
+        sprintf(retBuf, "%d", caccess);
+        while(neonspam_settings[i].setting) {
+            if(neonspam_settings[i].flags & SET_SCANEXCEPT) {
+                neonspam_cmd_set_function *func = neonspam_settings[i].function;
+                func(client, user, chan, event, neonspam_settings[i].intparam, neonspam_settings[i].charparam, retBuf, valueBuf);
+            }
+            i++;
+        }
+        identical = 1;
+        value = caccess;
+    }
+    if(identical) {
+        sprintf(retBuf, "%d", value);
+        return retBuf;
+    }
+    return "?";
+}
+
 #undef MAX_QUERY_LEN