completely changed the NeonSpam settings / scanner management
[NeonServV5.git] / src / cmd_neonspam_set.c
1 /* cmd_neonspam_set.c - NeonServ v5.1
2  * Copyright (C) 2011  Philipp Kreil (pk910)
3  * 
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  * 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  * 
14  * You should have received a copy of the GNU General Public License 
15  * along with this program. If not, see <http://www.gnu.org/licenses/>. 
16  */
17
18 #include "cmd_neonspam.h"
19
20 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);
21 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);
22 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);
23 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);
24 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);
25 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);
26 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);
27 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);
28 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);
29
30 static MYSQL_ROW neonspam_settings_row, neonspam_settings_defaults;
31 #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`"
32 #define SPAMSERV_SETTINGS_RESET "\
33 `channel_scanner` = NULL, \
34 `channel_spam_limit` = NULL, \
35 `channel_spam_reaction` = NULL, \
36 `channel_spam_reaction_duration` = NULL, \
37 `channel_spam_except` = NULL, \
38 `channel_flood_limit` = NULL, \
39 `channel_flood_time` = NULL, \
40 `channel_flood_reaction` = NULL, \
41 `channel_flood_reaction_duration` = NULL, \
42 `channel_flood_except` = NULL, \
43 `channel_join_limit` = NULL, \
44 `channel_join_time` = NULL, \
45 `channel_join_reaction` = NULL, \
46 `channel_join_reaction_duration` = NULL, \
47 `channel_join_except` = NULL, \
48 `channel_botnet_bantime` = NULL, \
49 `channel_botnet_except` = NULL, \
50 `channel_caps_percent` = NULL, \
51 `channel_caps_reaction` = NULL, \
52 `channel_caps_reaction_duration` = NULL, \
53 `channel_caps_except` = NULL,\
54 `channel_digit_percent` = NULL, \
55 `channel_digit_reaction` = NULL, \
56 `channel_digit_reaction_duration` = NULL, \
57 `channel_digit_except` = NULL "
58
59 static const struct {
60     unsigned int if_flag;
61     unsigned int indent;
62     const char *setting;
63     void *function;
64     int intparam;
65     char *charparam;
66 } neonspam_settings[] = {
67     {0,                                                0,  "Trigger",           neonspam_cmd_set_trigger,         0,                              NULL},
68     
69     {0,                                                0,  "SpamScan",          neonspam_cmd_setflags,            SPAMSETTINGS_SPAMSCAN,          NULL},
70     {SPAMSETTINGS_SPAMSCAN,                            2,  "SpamLimit",         neonspam_cmd_set_spamlimit,       0,                              NULL},
71     {SPAMSETTINGS_SPAMSCAN | SPAMSETTINGS_SETTIMEBAN,  2,  "SpamReaction",      neonspam_cmd_set_reaction,        0,                              "channel_spam_reaction"},
72     {SPAMSETTINGS_SPAMSCAN | SPAMSETTINGS_ISTIMEBAN,   4,  "SpamBanDuration",   neonspam_cmd_set_reaction_time,   1,                              "channel_spam_reaction_duration"},
73     {SPAMSETTINGS_SPAMSCAN,                            2,  "SpamScanChanOps",   neonspam_cmd_setflags,            SPAMSETTINGS_SPAMSCAN_OPS,      NULL},
74     {SPAMSETTINGS_SPAMSCAN,                            2,  "SpamScanVoiced",    neonspam_cmd_setflags,            SPAMSETTINGS_SPAMSCAN_VOICE,    NULL},
75     {SPAMSETTINGS_SPAMSCAN,                            2,  "SpamScanExcept",    neonspam_cmd_setexcept,           SPAMSETTINGS_SPAMEXCINDEX,      "channel_spam_except"},
76     
77     {0,                                                0,  "FloodScan",         neonspam_cmd_setflags,            SPAMSETTINGS_FLOODSCAN,         NULL},
78     {SPAMSETTINGS_FLOODSCAN,                           2,  "FloodSensibility",  neonspam_cmd_setsensibility,      SPAMSETTINGS_FLOODSENINDEX,     "channel_flood_"},
79     {SPAMSETTINGS_FLOODSCAN | SPAMSETTINGS_SETTIMEBAN, 2,  "FloodReaction",     neonspam_cmd_set_reaction,        2,                              "channel_flood_reaction"},
80     {SPAMSETTINGS_FLOODSCAN | SPAMSETTINGS_ISTIMEBAN,  4,  "FloodBanDuration",  neonspam_cmd_set_reaction_time,   3,                              "channel_flood_reaction_duration"},
81     {SPAMSETTINGS_FLOODSCAN,                           2,  "FloodScanChanOps",  neonspam_cmd_setflags,            SPAMSETTINGS_FLOODSCAN_OPS,     NULL},
82     {SPAMSETTINGS_FLOODSCAN,                           2,  "FloodScanVoiced",   neonspam_cmd_setflags,            SPAMSETTINGS_FLOODSCAN_VOICE,   NULL},
83     {SPAMSETTINGS_FLOODSCAN,                           2,  "FloodScanExcept",   neonspam_cmd_setexcept,           SPAMSETTINGS_FLOODEXCINDEX,     "channel_flood_except"},
84     
85     {0,                                                0,  "JoinScan",          neonspam_cmd_setflags,            SPAMSETTINGS_JOINSCAN,          NULL},
86     {SPAMSETTINGS_JOINSCAN,                            2,  "JoinSensibility",   neonspam_cmd_setsensibility,      SPAMSETTINGS_JOINSENINDEX,      "channel_join_"},
87     {SPAMSETTINGS_JOINSCAN | SPAMSETTINGS_SETTIMEBAN,  2,  "JoinReaction",      neonspam_cmd_set_reaction,        4,                              "channel_join_reaction"},
88     {SPAMSETTINGS_JOINSCAN | SPAMSETTINGS_ISTIMEBAN,   4,  "JoinBanDuration",   neonspam_cmd_set_reaction_time,   5,                              "channel_join_reaction_duration"},
89     {SPAMSETTINGS_JOINSCAN,                            2,  "JoinScanChanOps",   neonspam_cmd_setflags,            SPAMSETTINGS_JOINSCAN_OPS,      NULL},
90     {SPAMSETTINGS_JOINSCAN,                            2,  "JoinScanVoiced",    neonspam_cmd_setflags,            SPAMSETTINGS_JOINSCAN_VOICE,    NULL},
91     {SPAMSETTINGS_JOINSCAN,                            2,  "JoinScanExcept",    neonspam_cmd_setexcept,           SPAMSETTINGS_JOINEXCINDEX,      "channel_join_except"},
92     
93     {0,                                                0,  "BotNetScan",        neonspam_cmd_setflags,            SPAMSETTINGS_BOTNETSCAN,        NULL},
94     {SPAMSETTINGS_BOTNETSCAN,                          4,  "BotNetBanDuration", neonspam_cmd_set_reaction_time,   6,                              "channel_botnet_bantime"},
95     {SPAMSETTINGS_BOTNETSCAN,                          2,  "BotNetScanChanOps", neonspam_cmd_setflags,            SPAMSETTINGS_BOTNETSCAN_OPS,    NULL},
96     {SPAMSETTINGS_BOTNETSCAN,                          2,  "BotNetScanVoiced",  neonspam_cmd_setflags,            SPAMSETTINGS_BOTNETSCAN_VOICE,  NULL},
97     //{SPAMSETTINGS_BOTNETSCAN,                          2,  "BotNetScanExcept",  neonspam_cmd_setexcept,           SPAMSETTINGS_BOTNETEXCINDEX,    "channel_botnet_except"},
98     
99     {0,                                                0,  "CapsScan",          neonspam_cmd_setflags,            SPAMSETTINGS_CAPSSCAN,          NULL},
100     {SPAMSETTINGS_CAPSSCAN,                            2,  "CapsPercent",       neonspam_cmd_setpercent,          SPAMSETTINGS_CAPSPERCENTINDEX,  "channel_caps_percent"},
101     {SPAMSETTINGS_CAPSSCAN | SPAMSETTINGS_SETTIMEBAN,  2,  "CapsReaction",      neonspam_cmd_set_reaction,        7,                              "channel_caps_reaction"},
102     {SPAMSETTINGS_CAPSSCAN | SPAMSETTINGS_ISTIMEBAN,   4,  "CapsBanDuration",   neonspam_cmd_set_reaction_time,   8,                              "channel_caps_reaction_duration"},
103     {SPAMSETTINGS_CAPSSCAN,                            2,  "CapsScanChanOps",   neonspam_cmd_setflags,            SPAMSETTINGS_CAPSSCAN_OPS,      NULL},
104     {SPAMSETTINGS_CAPSSCAN,                            2,  "CapsScanVoiced",    neonspam_cmd_setflags,            SPAMSETTINGS_CAPSSCAN_VOICE,    NULL},
105     {SPAMSETTINGS_CAPSSCAN,                            2,  "CapsScanExcept",    neonspam_cmd_setexcept,           SPAMSETTINGS_CAPSEXCINDEX,      "channel_caps_except"},
106     
107     {0,                                                0,  "DigitScan",         neonspam_cmd_setflags,            SPAMSETTINGS_DIGITSCAN,         NULL},
108     {SPAMSETTINGS_DIGITSCAN,                           2,  "DigitPercent",      neonspam_cmd_setpercent,          SPAMSETTINGS_DIGITPERCENTINDEX, "channel_digit_percent"},
109     {SPAMSETTINGS_DIGITSCAN | SPAMSETTINGS_SETTIMEBAN, 2,  "DigitReaction",     neonspam_cmd_set_reaction,        9,                              "channel_digit_reaction"},
110     {SPAMSETTINGS_DIGITSCAN | SPAMSETTINGS_ISTIMEBAN,  4,  "DigitBanDuration",  neonspam_cmd_set_reaction_time,   10,                             "channel_digit_reaction_duration"},
111     {SPAMSETTINGS_DIGITSCAN,                           2,  "DigitScanChanOps",  neonspam_cmd_setflags,            SPAMSETTINGS_DIGITSCAN_OPS,     NULL},
112     {SPAMSETTINGS_DIGITSCAN,                           2,  "DigitScanVoiced",   neonspam_cmd_setflags,            SPAMSETTINGS_DIGITSCAN_VOICE,   NULL},
113     {SPAMSETTINGS_DIGITSCAN,                           2,  "DigitScanExcept",   neonspam_cmd_setexcept,           SPAMSETTINGS_DIGITEXCINDEX,     "channel_digit_except"},
114     
115     {0, 0, NULL, NULL, 0, NULL}
116 };
117
118 #define MAX_QUERY_LEN 1024
119 CMD_BIND(neonspam_cmd_set) {
120     int i, j;
121     if(argc && !strcmp(argv[0], "defaults")) {
122         //reset channel settings
123         int uaccess = getChannelAccess(user, chan, 0);
124         if(uaccess < 500) {
125             if(isGodMode(user)) {
126                 event->flags |= CMDFLAG_OPLOG;
127             } else {
128                 reply(getTextBot(), user, "NS_SET_DEFAULTS_OWNER", chan->name);
129                 return;
130             }
131         }
132         int seed = 0;
133         char *tmp;
134         static char defaultskey[16];
135         for(tmp = user->auth; *tmp; tmp++)
136             seed = (seed * 0xEECE66DL ^ ((*tmp << 24) | (*tmp << 16) | (*tmp << 8) | *tmp));
137         for(tmp = chan->name; *tmp; tmp++)
138             seed = (seed * 0xEECE66DL ^ ((*tmp << 24) | (*tmp << 16) | (*tmp << 8) | *tmp));
139         sprintf(defaultskey, "%08x", seed);
140         if(argc > 1 && !strcmp(argv[1], defaultskey)) {
141             printf_mysql_query("UPDATE `channels` SET " SPAMSERV_SETTINGS_RESET " WHERE `channel_id` = '%d'", chan->channel_id);
142             reply(getTextBot(), user, "NS_SET_DEFAULTS_DONE", chan->name);
143             logEvent(event);
144         } else {
145             reply(getTextBot(), user, "NS_SET_DEFAULTS_CODE", chan->name, defaultskey);
146         }
147     } else if(argc && strcmp(argv[0], "help")) {
148         //find the correct command
149         i = 0;
150         j = 0;
151         char *args = (argc > 1 ? merge_argv(argv, 1, argc) : NULL);
152         neonspam_settings_row = NULL;
153         neonspam_settings_defaults = NULL;
154         while(neonspam_settings[i].setting) {
155             if(!stricmp(neonspam_settings[i].setting, argv[0])) {
156                 //setting found
157                 char valueBuf[MAXLEN];
158                 char *value;
159                 neonspam_cmd_set_function *func = neonspam_settings[i].function;
160                 value = func(client, user, chan, event, neonspam_settings[i].intparam, neonspam_settings[i].charparam, args, valueBuf);
161                 if(value) {
162                     reply(getTextBot(), user, "\002%s\002 %s", neonspam_settings[i].setting, value);
163                     //TODO: reply valid options
164                 }
165                 j = 1;
166                 break;
167             }
168             i++;
169         }
170         if(j == 0) {
171             //unknown setting
172             reply(getTextBot(), user, "NS_SET_UNKNOWN_SETTING", argv[0]);
173         }
174     } else {
175         char valueBuf[MAXLEN], nameBuf[MAXLEN];
176         char *value;
177         int namePos, boolflag = 0;
178         MYSQL_RES *res, *defaults_res;
179         struct Table *table;
180         char *content[2];
181         i = 0;
182         while(neonspam_settings[i].setting)
183             i++;
184         table = table_init(2, i, 0);
185         table_set_bold(table, 0, 1);
186         printf_mysql_query("SELECT " SPAMSERV_SETTINGS_QUERY " FROM `channels` WHERE `channel_name` = 'defaults'");
187         defaults_res = mysql_use();
188         neonspam_settings_defaults = mysql_fetch_row(defaults_res);
189         printf_mysql_query("SELECT " SPAMSERV_SETTINGS_QUERY " FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
190         res = mysql_use();
191         neonspam_settings_row = mysql_fetch_row(res);
192         i = -1;
193         reply(getTextBot(), user, "NS_SET_HEADER", chan->name);
194         while(neonspam_settings[++i].setting) {
195             if((chan->spam_settings->flags & (neonspam_settings[i].if_flag & SPAMSETTINGS_FLAGS)) != (neonspam_settings[i].if_flag & SPAMSETTINGS_FLAGS))
196                 continue;
197             if((neonspam_settings[i].if_flag & SPAMSETTINGS_ISTIMEBAN) && !boolflag)
198                 continue;
199             namePos = 0;
200             for(j = 0; j < neonspam_settings[i].indent; j++) {
201                 nameBuf[namePos++] = ' ';
202             }
203             neonspam_cmd_set_function *func = neonspam_settings[i].function;
204             value = func(client, user, chan, event, neonspam_settings[i].intparam, neonspam_settings[i].charparam, NULL, valueBuf);
205             if(neonspam_settings[i].if_flag & SPAMSETTINGS_SETTIMEBAN)
206                 boolflag = !strcmp(value, "2");
207             //TODO: append option or help info
208             sprintf(nameBuf + namePos, "%s", neonspam_settings[i].setting);
209             content[0] = nameBuf;
210             content[1] = value;
211             table_add(table, content);
212         }
213         char **table_lines = table_end(table);
214         for(i = 0; i < table->entrys; i++) {
215             reply(getTextBot(), user, table_lines[i]);
216         }
217         table_free(table);
218     }
219 }
220
221 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) {
222     char *trigger;
223     //get current trigger
224     MYSQL_RES *res;
225     MYSQL_ROW row;
226     printf_mysql_query("SELECT `trigger` FROM `bot_channels` WHERE `chanid` = '%d' AND `botid` = '%d'", chan->channel_id, client->clientid);
227     res = mysql_use();
228     row = mysql_fetch_row(res);
229     trigger = row[0];
230     if(argument) {
231         int uaccess = getChannelAccess(user, chan, 0);
232         if(uaccess < 500) {
233             if(isGodMode(user)) {
234                 event->flags |= CMDFLAG_OPLOG;
235             } else {
236                 reply(getTextBot(), user, "NS_SET_TRIGGER_OWNER", chan->name);
237                 return NULL;
238             }
239         }
240         if(strlen(argument) > 15)
241             argument[15] = '\0';
242         printf_mysql_query("UPDATE `bot_channels` SET `trigger` = '%s' WHERE `chanid` = '%d' AND `botid` = '%d'", escape_string(argument), chan->channel_id, client->clientid);
243         trigger = argument;
244         changeChannelTrigger(client->botid, chan, trigger);
245         logEvent(event);
246     }
247     return trigger;
248 }
249
250 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) {
251     char *value = ((chan->spam_settings->flags & flag) ? "1" : "0");
252     if(argument) {
253         //binary argument...
254         if(!strcmp(argument, "0") || !stricmp(argument, "off") || !stricmp(argument, get_language_string(user, "NS_SET_OFF"))) {
255             chan->spam_settings->flags &= ~flag;
256         } else if(!strcmp(argument, "1") || !stricmp(argument, "on") || !stricmp(argument, get_language_string(user, "NS_SET_ON"))) {
257             chan->spam_settings->flags |= flag;
258         } else {
259             reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", argument);
260             return NULL;
261         }
262         char str_flags[50];
263         convertNeonSpamSettingsToString(chan->spam_settings->flags, str_flags);
264         printf_mysql_query("UPDATE `channels` SET `channel_scanner` = '%s' WHERE `channel_id` = '%d' ", str_flags, chan->channel_id);
265         value = argument;
266     }
267     return value;
268 }
269
270 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) {
271     unsigned int value = chan->spam_settings->exceptlevel[exceptlvl_index];
272     if(argument) {
273         //numeric argument... (access)
274         int caccess = atoi(argument);
275         if(caccess < 0 || caccess > 501) {
276             reply(getTextBot(), user, "NS_INVALID_ACCESS", caccess);
277             return NULL;
278         }
279         int uaccess = getChannelAccess(user, chan, 0);
280         if(uaccess == 500) uaccess++;
281         if(caccess > uaccess) {
282             if(isGodMode(user)) {
283                 event->flags |= CMDFLAG_OPLOG;
284             } else {
285                 reply(getTextBot(), user, "NS_SET_CANNOT_SET");
286                 return NULL;
287             }
288         }
289         if(caccess > uaccess) {
290             if(isGodMode(user)) {
291                 event->flags |= CMDFLAG_OPLOG;
292             } else {
293                 reply(getTextBot(), user, "NS_SET_BADLEVEL");
294                 return NULL;
295             }
296         }
297         value = caccess;
298         chan->spam_settings->exceptlevel[exceptlvl_index] = value;
299         printf_mysql_query("UPDATE `channels` SET `%s` = '%u' WHERE `channel_id` = '%d' ", field, value, chan->channel_id);
300     }
301     sprintf(retBuf, "%u", value);
302     return retBuf;
303 }
304
305 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) {
306     if(argument) {
307         /* valid options:
308         * 0/kick - kick
309         * 1/kickban - kickban
310         * 2/ban - timed ban
311         */
312         if(!strcmp(argument, "0") || !stricmp(argument, "kick")) {
313             argument = "0";
314         } else if(!strcmp(argument, "1") || !stricmp(argument, "kickban")) {
315             argument = "1";
316         } else if(!strcmp(argument, "2") || !stricmp(argument, "ban")) {
317             argument = "2";
318         } else {
319             reply(getTextBot(), user, "NS_SET_INVALID_OPTION_STR", argument);
320             return NULL;
321         }
322         printf_mysql_query("UPDATE `channels` SET `%s` = '%s' WHERE `channel_id` = '%d' ", mysqlfield, argument, chan->channel_id);
323         return argument;
324     } else {
325         if(neonspam_settings_row) {
326             return (neonspam_settings_row[mysqlindex] ? neonspam_settings_row[mysqlindex] : neonspam_settings_defaults[mysqlindex]);
327         } else {
328             MYSQL_RES *res;
329             MYSQL_ROW row;
330             printf_mysql_query("SELECT `%s` FROM `channels` WHERE `channel_id` = '%d'", mysqlfield, chan->channel_id);
331             res = mysql_use();
332             row = mysql_fetch_row(res);
333             return row[0];
334         }
335     }
336 }
337
338 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) {
339     int duration;
340     if(argument) {
341         duration = strToTime(user, argument);
342         if(duration < 30) {
343             reply(getTextBot(), user, "NS_TIMEBAN_DURATION_TOO_SHORT", 30);
344             return NULL;
345         }
346         printf_mysql_query("UPDATE `channels` SET `%s` = '%s' WHERE `channel_id` = '%d' ", mysqlfield, argument, chan->channel_id);
347     } else {
348         if(neonspam_settings_row) {
349             duration = atoi(neonspam_settings_row[mysqlindex] ? neonspam_settings_row[mysqlindex] : neonspam_settings_defaults[mysqlindex]);
350         } else {
351             MYSQL_RES *res;
352             MYSQL_ROW row;
353             printf_mysql_query("SELECT `%s` FROM `channels` WHERE `channel_id` = '%d'", mysqlfield, chan->channel_id);
354             res = mysql_use();
355             row = mysql_fetch_row(res);
356             duration = atoi(row[0]);
357         }
358     }
359     timeToStr(user, duration, 3, retBuf);
360     return retBuf;
361 }
362
363 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) {
364     unsigned int value = chan->spam_settings->percent[percent_index];
365     if(argument) {
366         //numeric argument... (access)
367         value = atoi(argument);
368         if(value < 0 || value > 100) {
369             //invalid percent value
370             return NULL;
371         }
372         chan->spam_settings->percent[percent_index] = value;
373         printf_mysql_query("UPDATE `channels` SET `%s` = '%u' WHERE `channel_id` = '%d' ", mysqlfield, value, chan->channel_id);
374     }
375     sprintf(retBuf, "%u", value);
376     return retBuf;
377 }
378
379 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) {
380     if(argument) {
381         //change value
382         char *delimiter = strstr(argument, ":");
383         if(!delimiter) {
384             //invalid format
385             return NULL;
386         }
387         *delimiter = '\0';
388         delimiter++;
389         int amount = atoi(argument);
390         int timep = atoi(delimiter);
391         if(amount > MAX_FLOOD_AMOUNT || amount < MIN_FLOOD_AMOUNT) {
392             //invalid amount
393             return NULL;
394         }
395         if(timep > MAX_FLOOD_TIME || timep < 0) {
396             //invalid time period
397             return NULL;
398         }
399         char amountfield[50], timefield[50];
400         sprintf(amountfield, "%s%s", mysqlfield, "limit");
401         sprintf(timefield, "%s%s", mysqlfield, "time");
402         printf_mysql_query("UPDATE `channels` SET `%s` = '%d', `%s` = '%d' WHERE `channel_id` = '%d' ", amountfield, amount, timefield, timep, chan->channel_id);
403         sprintf(retBuf, "%d:%d", amount, timep);
404         chan->spam_settings->sensibility_amount[sensibility_index] = amount;
405         chan->spam_settings->sensibility_time[sensibility_index] = timep;
406     } else {
407         sprintf(retBuf, "%d:%d", chan->spam_settings->sensibility_amount[sensibility_index], chan->spam_settings->sensibility_time[sensibility_index]);
408     }
409     return retBuf;
410 }
411
412 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) {
413     if(argument) {
414         //change value
415         int amount = atoi(argument);
416         if(amount > MAX_FLOOD_AMOUNT || amount < MIN_FLOOD_AMOUNT) {
417             //invalid amount
418             return NULL;
419         }
420         printf_mysql_query("UPDATE `channels` SET `channel_maxrepeat` = '%d' WHERE `channel_id` = '%d' ", amount, chan->channel_id);
421         sprintf(retBuf, "%d", amount);
422         chan->spam_settings->spam_amount = amount;
423     } else
424         sprintf(retBuf, "%d", chan->spam_settings->spam_amount);
425     return retBuf;
426 }
427
428 #undef MAX_QUERY_LEN