added cmd_set for NeonSpam
[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, const char *setting, char *cvalue, char *argument);
21 static void neonspam_cmd_set_setting(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int setting, char *argument);
22 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);
23 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);
24 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);
25 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);
26 static char* neonspam_cmd_setjoinfloodreaction(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument);
27 static char* neonspam_cmd_setspamscan(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument);
28 static char* neonspam_cmd_setfloodscan(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument);
29 static char* neonspam_cmd_setjoinfloodscan(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument);
30 static char* neonspam_cmd_setscanchanops(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument);
31 static char* neonspam_cmd_setscanvoiced(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument);
32 static char* neonspam_cmd_setexceptlevel(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument);
33 static char* neonspam_cmd_setfloodsensibility(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument);
34 static char* neonspam_cmd_setjoinsensibility(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument);
35
36 #define NS_VALID_FUNCTION 0x01
37 #define NS_VALID_STRING   0x02
38 #define NS_VALID_ACCESS   0x04
39 #define NS_VALID_NO501    0x08
40 #define NS_VALID_OPTIONS  0x10
41 #define NS_VALID_NUMERIC  0x20
42 #define NS_VALID_BOOLEAN  0x40
43
44 #define NS_HAS_OPT  0x100 /* options (SET_OPTION_{NAME}_{VALUE}) */
45 #define NS_HAS_HELP 0x200 /* help    (SET_HELP_{NAME}) - only shown if help is requested */
46
47 static MYSQL_ROW neonspam_settings_row, neonspam_settings_defaults;
48 #define SPAMSERV_SETTINGS_QUERY "`channel_scanstate`, `channel_scanexcept`, `channel_maxrepeat`, `channel_repeatreaction`, `channel_maxflood`, `channel_floodtime`, `channel_floodreaction`, `channel_maxjoin`, `channel_jointime`, `channel_joinreaction`"
49 #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"
50
51 static const struct {
52     const char *setting;
53     const char *chanfield;
54     unsigned int valid;
55     void *parameter;
56     void *function;
57 } neonspam_settings[] = {
58     {"Trigger",           NULL,  NS_VALID_FUNCTION,                                 NULL, neonspam_cmd_set_trigger},
59     {"SpamLimit",         NULL,  NS_VALID_OPTIONS | NS_VALID_FUNCTION | NS_HAS_OPT, "5",  neonspam_cmd_set_spamlimit},
60     {"SpamReaction",      NULL,  NS_VALID_OPTIONS | NS_VALID_FUNCTION | NS_HAS_OPT, "3",  neonspam_cmd_set_spamreaction},
61     {"FloodReaction",     NULL,  NS_VALID_OPTIONS | NS_VALID_FUNCTION | NS_HAS_OPT, "3",  neonspam_cmd_set_floodreaction},
62     {"JoinFloodReaction", NULL,  NS_VALID_OPTIONS | NS_VALID_FUNCTION | NS_HAS_OPT, "3",  neonspam_cmd_setjoinfloodreaction},
63     {"SpamScan",          NULL,  NS_VALID_BOOLEAN | NS_VALID_FUNCTION,              NULL, neonspam_cmd_setspamscan},
64     {"FloodScan",         NULL,  NS_VALID_BOOLEAN | NS_VALID_FUNCTION,              NULL, neonspam_cmd_setfloodscan},
65     {"JoinFloodScan",     NULL,  NS_VALID_BOOLEAN | NS_VALID_FUNCTION,              NULL, neonspam_cmd_setjoinfloodscan},
66     {"ScanChanOps",       NULL,  NS_VALID_BOOLEAN | NS_VALID_FUNCTION,              NULL, neonspam_cmd_setscanchanops},
67     {"ScanVoiced",        NULL,  NS_VALID_BOOLEAN | NS_VALID_FUNCTION,              NULL, neonspam_cmd_setscanvoiced},
68     {"ExceptLevel",       NULL,  NS_VALID_ACCESS | NS_VALID_FUNCTION,               NULL, neonspam_cmd_setexceptlevel},
69     {"FloodSensibility",  NULL,  NS_VALID_FUNCTION,                                 NULL, neonspam_cmd_setfloodsensibility},
70     {"JoinSensibility",   NULL,  NS_VALID_FUNCTION,                                 NULL, neonspam_cmd_setjoinsensibility},
71     {NULL, NULL, 0, NULL}
72 };
73
74 #define MAX_QUERY_LEN 1024
75 CMD_BIND(neonspam_cmd_set) {
76     int i, j;
77     if(argc && !strcmp(argv[0], "defaults")) {
78         //reset channel settings
79         int uaccess = getChannelAccess(user, chan, 0);
80         if(uaccess < 500) {
81             if(isGodMode(user)) {
82                 event->flags |= CMDFLAG_OPLOG;
83             } else {
84                 reply(getTextBot(), user, "NS_SET_DEFAULTS_OWNER", chan->name);
85                 return;
86             }
87         }
88         int seed = 0;
89         char *tmp;
90         static char defaultskey[16];
91         for(tmp = user->auth; *tmp; tmp++)
92             seed = (seed * 0xEECE66DL ^ ((*tmp << 24) | (*tmp << 16) | (*tmp << 8) | *tmp));
93         for(tmp = chan->name; *tmp; tmp++)
94             seed = (seed * 0xEECE66DL ^ ((*tmp << 24) | (*tmp << 16) | (*tmp << 8) | *tmp));
95         sprintf(defaultskey, "%08x", seed);
96         if(argc > 1 && !strcmp(argv[1], defaultskey)) {
97             printf_mysql_query("UPDATE `channels` SET " SPAMSERV_SETTINGS_RESET " WHERE `channel_id` = '%d'", chan->channel_id);
98             reply(getTextBot(), user, "NS_SET_DEFAULTS_DONE", chan->name);
99             logEvent(event);
100         } else {
101             reply(getTextBot(), user, "NS_SET_DEFAULTS_CODE", chan->name, defaultskey);
102         }
103     } else if(argc && strcmp(argv[0], "help")) {
104         //find the correct command
105         i = 0;
106         j = 0;
107         char *args = (argc > 1 ? merge_argv(argv, 1, argc) : NULL);
108         while(neonspam_settings[i].setting) {
109             if(!stricmp(neonspam_settings[i].setting, argv[0])) {
110                 //setting found
111                 neonspam_cmd_set_setting(client, user, chan, event, i, args);
112                 j = 1;
113                 break;
114             }
115             i++;
116         }
117         if(j == 0) {
118             //unknown setting
119             reply(getTextBot(), user, "NS_SET_UNKNOWN_SETTING", argv[0]);
120         }
121     } else {
122         char *value, *org_value, *tmp, nameBuf[64];
123         MYSQL_RES *res, *defaults_res;
124         struct Table *table;
125         char *content[2];
126         char query[MAXLEN];
127         int querypos;
128         i = 0;
129         while(neonspam_settings[i].setting)
130             i++;
131         table = table_init(2, i, 0);
132         table_set_bold(table, 0, 1);
133         printf_mysql_query("SELECT " SPAMSERV_SETTINGS_QUERY " FROM `channels` WHERE `channel_name` = 'defaults'");
134         defaults_res = mysql_use();
135         neonspam_settings_defaults = mysql_fetch_row(defaults_res);
136         printf_mysql_query("SELECT " SPAMSERV_SETTINGS_QUERY " FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
137         res = mysql_use();
138         neonspam_settings_row = mysql_fetch_row(res);
139         i = 0;
140         j = 0;
141         reply(getTextBot(), user, "NS_SET_HEADER", chan->name);
142         while(neonspam_settings[i].setting) {
143             char valueBuf[MAXLEN];
144             if(neonspam_settings[i].valid & NS_VALID_FUNCTION) {
145                 neonspam_cmd_set_function *func = neonspam_settings[i].function;
146                 org_value = func(client, user, chan, event, NULL, NULL, valueBuf);
147             } else
148                 org_value = "0";
149             value = org_value;
150             if(neonspam_settings[i].valid & NS_VALID_BOOLEAN) {
151                 if(!strcmp(value, "0"))
152                     value = get_language_string(user, "NS_SET_OFF");
153                 else
154                     value = get_language_string(user, "NS_SET_ON");
155             }
156             strcpy(query, value);
157             querypos = strlen(query);
158             if(neonspam_settings[i].valid & NS_HAS_OPT) {
159                 sprintf(nameBuf, "NS_SET_OPTION_%s_%s", neonspam_settings[i].setting, org_value);
160                 tmp = get_language_string(user, nameBuf);
161                 if(tmp) {
162                     querypos += sprintf(query+querypos, " - %s", tmp);
163                 }
164             }
165             if(argc && neonspam_settings[i].valid & NS_HAS_HELP) {
166                 sprintf(nameBuf, "NS_SET_HELP_%s", neonspam_settings[i].setting);
167                 tmp = get_language_string(user, nameBuf);
168                 if(tmp) {
169                     querypos += sprintf(query+querypos, " - %s", tmp);
170                 }
171             }
172             content[0] = (char*)neonspam_settings[i].setting;
173             content[1] = query;
174             table_add(table, content);
175             i++;
176         }
177         char **table_lines = table_end(table);
178         for(i = 0; i < table->entrys; i++) {
179             reply(getTextBot(), user, table_lines[i]);
180         }
181         table_free(table);
182     }
183 }
184
185 static void neonspam_cmd_set_setting(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, int setting, char *args) {
186     char *value;
187     char valueBuf[MAXLEN];
188     char nameBuf[64];
189     //get current value
190     MYSQL_RES *res;
191     printf_mysql_query("SELECT " SPAMSERV_SETTINGS_QUERY " FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
192     res = mysql_use();
193     neonspam_settings_row = mysql_fetch_row(res);
194     printf_mysql_query("SELECT " SPAMSERV_SETTINGS_QUERY " FROM `channels` WHERE `channel_name` = 'defaults'");
195     res = mysql_use();
196     neonspam_settings_defaults = mysql_fetch_row(res);
197     if(neonspam_settings[setting].valid & NS_VALID_FUNCTION) {
198         neonspam_cmd_set_function *func = neonspam_settings[setting].function;
199         if(!(value = func(client, user, chan, event, NULL, NULL, valueBuf)))
200             return;
201     } else
202         value = "0";
203     if(args) {
204         //change the channel setting
205         //check the new argument
206         int valid = neonspam_settings[setting].valid;
207         if(valid & NS_VALID_STRING) {
208             if(!strcmp(args, "*")) {
209                 args = "";
210             }
211         }
212         if(valid & NS_VALID_ACCESS) {
213             int caccess = atoi(args);
214             int max = ((valid & NS_VALID_NO501) ? 500 : 501);
215             if(caccess < 0 || caccess > max) {
216                 reply(getTextBot(), user, "NS_INVALID_ACCESS", caccess);
217                 return;
218             }
219             int uaccess = getChannelAccess(user, chan, 0);
220             if(uaccess == 500) uaccess++;
221             if(atoi(value) > uaccess) {
222                 if(isGodMode(user)) {
223                     event->flags |= CMDFLAG_OPLOG;
224                 } else {
225                     reply(getTextBot(), user, "NS_SET_CANNOT_SET");
226                     return;
227                 }
228             }
229             if(caccess > uaccess) {
230                 if(isGodMode(user)) {
231                     event->flags |= CMDFLAG_OPLOG;
232                 } else {
233                     reply(getTextBot(), user, "NS_SET_BADLEVEL");
234                     return;
235                 }
236             }
237             sprintf(nameBuf, "%d", caccess);
238             args = nameBuf;
239         }
240         if(valid & NS_VALID_OPTIONS) {
241             int options = atoi((char *) neonspam_settings[setting].parameter);
242             int coption = atoi(args);
243             if(coption < 0 || coption >= options) {
244                 reply(getTextBot(), user, "NS_SET_INVALID_OPTION", coption);
245                 int i;
246                 int nameBufPos = 0;
247                 if(valid & NS_HAS_OPT) {
248                     for(i = 0; i < options; i++) {
249                         sprintf(nameBuf, "NS_SET_OPTION_%s_%d", neonspam_settings[setting].setting, i);
250                         reply(getTextBot(), user, "\002%d\002 - %s", i, get_language_string(user, nameBuf));
251                     }
252                 } else {
253                     for(i = 0; i < options; i++) {
254                         nameBufPos += sprintf(nameBuf + nameBufPos, "\002%d\002, ", i);
255                     }
256                     if(nameBufPos) {
257                         nameBuf[nameBufPos-2] = '\0';
258                         reply(getTextBot(), user, nameBuf);
259                     }
260                 }
261                 return;
262             }
263         }
264         if(valid & NS_VALID_NUMERIC) {
265             sprintf(nameBuf, "%d", atoi(args));
266             args = nameBuf;
267         }
268         if(valid & NS_VALID_BOOLEAN) {
269             if(!strcmp(args, "0") || !stricmp(args, "off") || !stricmp(args, get_language_string(user, "NS_SET_OFF"))) {
270                 args = "0";
271             } else if(!strcmp(args, "1") || !stricmp(args, "on") || !stricmp(args, get_language_string(user, "NS_SET_ON"))) {
272                 args = "1";
273             } else {
274                 reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", args);
275                 return;
276             }
277         }
278         //valid - set it
279         if(valid & NS_VALID_FUNCTION) {
280             neonspam_cmd_set_function *func = neonspam_settings[setting].function;
281             strcpy(valueBuf, value);
282             if(!(value = func(client, user, chan, event, neonspam_settings[setting].setting, valueBuf, args)))
283                 return;
284         }
285     }
286     reply(getTextBot(), user, "\002%s\002 %s", neonspam_settings[setting].setting, value);
287     if(neonspam_settings[setting].valid & NS_HAS_HELP) {
288          sprintf(nameBuf, "NS_SET_HELP_%s", neonspam_settings[setting].setting);
289          reply(getTextBot(), user, "  %s", get_language_string(user, nameBuf));
290     }
291 }
292
293 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) {
294     char *trigger;
295     //get current trigger
296     MYSQL_RES *res;
297     MYSQL_ROW row;
298     printf_mysql_query("SELECT `trigger` FROM `bot_channels` WHERE `chanid` = '%d' AND `botid` = '%d'", chan->channel_id, client->clientid);
299     res = mysql_use();
300     row = mysql_fetch_row(res);
301     trigger = row[0];
302     if(cvalue && argument) {
303         int uaccess = getChannelAccess(user, chan, 0);
304         if(uaccess < 500) {
305             if(isGodMode(user)) {
306                 event->flags |= CMDFLAG_OPLOG;
307             } else {
308                 reply(getTextBot(), user, "NS_SET_TRIGGER_OWNER", chan->name);
309                 return NULL;
310             }
311         }
312         if(strlen(argument) > 15)
313             argument[15] = '\0';
314         printf_mysql_query("UPDATE `bot_channels` SET `trigger` = '%s' WHERE `chanid` = '%d' AND `botid` = '%d'", escape_string(argument), chan->channel_id, client->clientid);
315         trigger = argument;
316         changeChannelTrigger(client->botid, chan, trigger);
317         logEvent(event);
318     }
319     return trigger;
320 }
321
322 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) {
323     if(!cvalue) {
324         //get current value
325         cvalue = (neonspam_settings_row[2] ? neonspam_settings_row[2] : neonspam_settings_defaults[2]);
326     }
327     else if(argument) {
328         //change value
329         printf_mysql_query("UPDATE `channels` SET `channel_maxrepeat` = '%d' WHERE `channel_id` = '%d' ", atoi(argument), chan->channel_id);
330         sprintf(cvalue, "%d", atoi(argument));
331     }
332     return cvalue;
333 }
334
335 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) {
336     if(!cvalue) {
337         //get current value
338         cvalue = (neonspam_settings_row[3] ? neonspam_settings_row[3] : neonspam_settings_defaults[3]);
339     }
340     else if(argument) {
341         //change value
342         printf_mysql_query("UPDATE `channels` SET `channel_repeatreaction` = '%d' WHERE `channel_id` = '%d' ", atoi(argument), chan->channel_id);
343         sprintf(cvalue, "%d", atoi(argument));
344     }
345     return cvalue;
346 }
347
348 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) {
349     if(!cvalue) {
350         //get current value
351         cvalue = (neonspam_settings_row[6] ? neonspam_settings_row[6] : neonspam_settings_defaults[6]);
352     }
353     else if(argument) {
354         //change value
355         printf_mysql_query("UPDATE `channels` SET `channel_floodreaction` = '%d' WHERE `channel_id` = '%d' ", atoi(argument), chan->channel_id);
356         sprintf(cvalue, "%d", atoi(argument));
357     }
358     return cvalue;
359 }
360
361 static char* neonspam_cmd_setjoinfloodreaction(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument) {
362     if(!cvalue) {
363         //get current value
364         cvalue = (neonspam_settings_row[9] ? neonspam_settings_row[9] : neonspam_settings_defaults[9]);
365     }
366     else if(argument) {
367         //change value
368         printf_mysql_query("UPDATE `channels` SET `channel_joinreaction` = '%d' WHERE `channel_id` = '%d' ", atoi(argument), chan->channel_id);
369         sprintf(cvalue, "%d", atoi(argument));
370     }
371     return cvalue;
372 }
373
374 static char* neonspam_cmd_setspamscan(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument) {
375     if(!cvalue) {
376         //get current value
377         cvalue = ((atoi(neonspam_settings_row[0] ? neonspam_settings_row[0] : neonspam_settings_defaults[0]) & SPAMSETTINGS_SPAMSCAN) ? "1" : "0");
378     }
379     else if(argument) {
380         //change value
381         int cflags = atoi((neonspam_settings_row[0] ? neonspam_settings_row[0] : neonspam_settings_defaults[0]));
382         if(!strcmp(argument, "0"))
383             cflags &= ~SPAMSETTINGS_SPAMSCAN;
384         else
385             cflags |= SPAMSETTINGS_SPAMSCAN;
386         printf_mysql_query("UPDATE `channels` SET `channel_scanstate` = '%d' WHERE `channel_id` = '%d' ", cflags, chan->channel_id);
387         cvalue = argument;
388     }
389     return cvalue;
390 }
391
392 static char* neonspam_cmd_setfloodscan(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument) {
393     if(!cvalue) {
394         //get current value
395         cvalue = ((atoi(neonspam_settings_row[0] ? neonspam_settings_row[0] : neonspam_settings_defaults[0]) & SPAMSETTINGS_FLOODSCAN) ? "1" : "0");
396     }
397     else if(argument) {
398         //change value
399         int cflags = atoi((neonspam_settings_row[0] ? neonspam_settings_row[0] : neonspam_settings_defaults[0]));
400         if(!strcmp(argument, "0"))
401             cflags &= ~SPAMSETTINGS_FLOODSCAN;
402         else
403             cflags |= SPAMSETTINGS_FLOODSCAN;
404         printf_mysql_query("UPDATE `channels` SET `channel_scanstate` = '%d' WHERE `channel_id` = '%d' ", cflags, chan->channel_id);
405         cvalue = argument;
406     }
407     return cvalue;
408 }
409
410 static char* neonspam_cmd_setjoinfloodscan(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument) {
411     if(!cvalue) {
412         //get current value
413         cvalue = ((atoi(neonspam_settings_row[0] ? neonspam_settings_row[0] : neonspam_settings_defaults[0]) & SPAMSETTINGS_JOINSCAN) ? "1" : "0");
414     }
415     else if(argument) {
416         //change value
417         int cflags = atoi((neonspam_settings_row[0] ? neonspam_settings_row[0] : neonspam_settings_defaults[0]));
418         if(!strcmp(argument, "0"))
419             cflags &= ~SPAMSETTINGS_JOINSCAN;
420         else
421             cflags |= SPAMSETTINGS_JOINSCAN;
422         printf_mysql_query("UPDATE `channels` SET `channel_scanstate` = '%d' WHERE `channel_id` = '%d' ", cflags, chan->channel_id);
423         cvalue = argument;
424     }
425     return cvalue;
426 }
427
428 static char* neonspam_cmd_setscanchanops(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument) {
429     if(!cvalue) {
430         //get current value
431         cvalue = ((atoi(neonspam_settings_row[0] ? neonspam_settings_row[0] : neonspam_settings_defaults[0]) & SPAMSETTINGS_SCANOPS) ? "1" : "0");
432     }
433     else if(argument) {
434         //change value
435         int cflags = atoi((neonspam_settings_row[0] ? neonspam_settings_row[0] : neonspam_settings_defaults[0]));
436         if(!strcmp(argument, "0"))
437             cflags &= ~SPAMSETTINGS_SCANOPS;
438         else
439             cflags |= SPAMSETTINGS_SCANOPS;
440         printf_mysql_query("UPDATE `channels` SET `channel_scanstate` = '%d' WHERE `channel_id` = '%d' ", cflags, chan->channel_id);
441         cvalue = argument;
442     }
443     return cvalue;
444 }
445
446 static char* neonspam_cmd_setscanvoiced(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument) {
447     if(!cvalue) {
448         //get current value
449         cvalue = ((atoi(neonspam_settings_row[0] ? neonspam_settings_row[0] : neonspam_settings_defaults[0]) & SPAMSETTINGS_SCANVOICE) ? "1" : "0");
450     }
451     else if(argument) {
452         //change value
453         int cflags = atoi((neonspam_settings_row[0] ? neonspam_settings_row[0] : neonspam_settings_defaults[0]));
454         if(!strcmp(argument, "0"))
455             cflags &= ~SPAMSETTINGS_SCANVOICE;
456         else
457             cflags |= SPAMSETTINGS_SCANVOICE;
458         printf_mysql_query("UPDATE `channels` SET `channel_scanstate` = '%d' WHERE `channel_id` = '%d' ", cflags, chan->channel_id);
459         cvalue = argument;
460     }
461     return cvalue;
462 }
463
464 static char* neonspam_cmd_setexceptlevel(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument) {
465     if(!cvalue) {
466         //get current value
467         cvalue = (neonspam_settings_row[1] ? neonspam_settings_row[1] : neonspam_settings_defaults[1]);
468     }
469     else if(argument) {
470         //change value
471         printf_mysql_query("UPDATE `channels` SET `channel_scanexcept` = '%d' WHERE `channel_id` = '%d' ", atoi(argument), chan->channel_id);
472         sprintf(cvalue, "%d", atoi(argument));
473     }
474     return cvalue;
475 }
476
477 static char* neonspam_cmd_setfloodsensibility(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument) {
478     if(!cvalue) {
479         //get current value
480         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]));
481         cvalue = argument;
482     }
483     else if(argument) {
484         //change value
485         char *delimiter = strstr(argument, ":");
486         if(!delimiter) {
487             //invalid format
488             return NULL;
489         }
490         *delimiter = '\0';
491         delimiter++;
492         int amount = atoi(argument);
493         int timep = atoi(delimiter);
494         if(amount > MAX_FLOOD_AMOUNT || amount < MIN_FLOOD_AMOUNT) {
495             //invalid amount
496             return NULL;
497         }
498         if(timep > MAX_FLOOD_TIME || timep < 0) {
499             //invalid time period
500             return NULL;
501         }
502         printf_mysql_query("UPDATE `channels` SET `channel_maxflood` = '%d', `channel_floodtime` = '%d' WHERE `channel_id` = '%d' ", amount, timep, chan->channel_id);
503         sprintf(cvalue, "%d:%d", amount, timep);
504     }
505     return cvalue;
506 }
507
508 static char* neonspam_cmd_setjoinsensibility(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, struct Event *event, const char *setting, char *cvalue, char *argument) {
509     if(!cvalue) {
510         //get current value
511         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]));
512         cvalue = argument;
513     }
514     else if(argument) {
515         //change value
516         char *delimiter = strstr(argument, ":");
517         if(!delimiter) {
518             //invalid format
519             return NULL;
520         }
521         *delimiter = '\0';
522         delimiter++;
523         int amount = atoi(argument);
524         int timep = atoi(delimiter);
525         if(amount > MAX_JOIN_AMOUNT || amount < MIN_JOIN_AMOUNT) {
526             //invalid amount
527             return NULL;
528         }
529         if(timep > MAX_JOIN_TIME || timep < 0) {
530             //invalid time period
531             return NULL;
532         }
533         printf_mysql_query("UPDATE `channels` SET `channel_maxjoin` = '%d', `channel_jointime` = '%d' WHERE `channel_id` = '%d' ", amount, timep, chan->channel_id);
534         sprintf(cvalue, "%d:%d", amount, timep);
535     }
536     return cvalue;
537 }
538
539
540 #undef MAX_QUERY_LEN