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