added possibility to change default trigger (even for registered channels)
[NeonServV5.git] / src / cmd_global_setbot.c
1 /* cmd_global_setbot.c - NeonServ v5.3
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_global.h"
19
20 /*
21 * argv[0]  botid
22 * argv[1]  setting
23 * argv[2]  value
24 */
25
26 static int global_cmd_setbot_active(struct UserNode *user, MYSQL_ROW bot, char *value);
27 static int global_cmd_setbot_nick(struct UserNode *user, MYSQL_ROW bot, char *value);
28 static int global_cmd_setbot_ident(struct UserNode *user, MYSQL_ROW bot, char *value);
29 static int global_cmd_setbot_realname(struct UserNode *user, MYSQL_ROW bot, char *value);
30 static int global_cmd_setbot_server(struct UserNode *user, MYSQL_ROW bot, char *value);
31 static int global_cmd_setbot_port(struct UserNode *user, MYSQL_ROW bot, char *value);
32 static int global_cmd_setbot_bind(struct UserNode *user, MYSQL_ROW bot, char *value);
33 static int global_cmd_setbot_ssl(struct UserNode *user, MYSQL_ROW bot, char *value);
34 static int global_cmd_setbot_serverpass(struct UserNode *user, MYSQL_ROW bot, char *value);
35 static int global_cmd_setbot_class(struct UserNode *user, MYSQL_ROW bot, char *value);
36 static int global_cmd_setbot_queue(struct UserNode *user, MYSQL_ROW bot, char *value);
37 static int global_cmd_setbot_prefered(struct UserNode *user, MYSQL_ROW bot, char *value);
38 static int global_cmd_setbot_maxchan(struct UserNode *user, MYSQL_ROW bot, char *value);
39 static int global_cmd_setbot_priority(struct UserNode *user, MYSQL_ROW bot, char *value);
40 static int global_cmd_setbot_trigger(struct UserNode *user, MYSQL_ROW bot, char *value);
41
42 CMD_BIND(global_cmd_setbot) {
43     MYSQL_RES *res;
44     MYSQL_ROW row;
45     int botid = atoi(argv[0]);
46     printf_mysql_query("SELECT `active`, `nick`, `server`, `port`, `pass`, `botclass`, `textbot`, `queue`, `defaulttrigger`, `max_channels`, `register_priority`, `bind`, `ident`, `realname`, `ssl`, `id` FROM `bots` WHERE `id` = '%d'", botid);
47     res = mysql_use();
48     if(!(row = mysql_fetch_row(res))) {
49         reply(getTextBot(), user, "NS_SETBOT_UNKNOWN", botid);
50         return;
51     }
52     if(argc > 1) {
53         char *value;
54         if(argc > 2) {
55             value = merge_argv(argv, 2, argc);
56         } else
57             value = NULL;
58         int log_event = 0;
59         if(!stricmp(argv[1], "active")) log_event = global_cmd_setbot_active(user, row, value);
60         else if(!stricmp(argv[1], "nick")) log_event = global_cmd_setbot_nick(user, row, value);
61         else if(!stricmp(argv[1], "ident")) log_event = global_cmd_setbot_ident(user, row, value);
62         else if(!stricmp(argv[1], "realname")) log_event = global_cmd_setbot_realname(user, row, value);
63         else if(!stricmp(argv[1], "server")) log_event = global_cmd_setbot_server(user, row, value);
64         else if(!stricmp(argv[1], "port")) log_event = global_cmd_setbot_port(user, row, value);
65         else if(!stricmp(argv[1], "bind")) log_event = global_cmd_setbot_bind(user, row, value);
66         else if(!stricmp(argv[1], "ssl")) log_event = global_cmd_setbot_ssl(user, row, value);
67         else if(!stricmp(argv[1], "serverpass")) log_event = global_cmd_setbot_serverpass(user, row, value);
68         else if(!stricmp(argv[1], "botclass")) log_event = global_cmd_setbot_class(user, row, value);
69         else if(!stricmp(argv[1], "queue")) log_event = global_cmd_setbot_queue(user, row, value);
70         else if(!stricmp(argv[1], "prefered")) log_event = global_cmd_setbot_prefered(user, row, value);
71         else if(!stricmp(argv[1], "maxchan")) log_event = global_cmd_setbot_maxchan(user, row, value);
72         else if(!stricmp(argv[1], "priority")) log_event = global_cmd_setbot_priority(user, row, value);
73         else if(!stricmp(argv[1], "trigger")) log_event = global_cmd_setbot_trigger(user, row, value);
74         else {
75             reply(getTextBot(), user, "NS_SETBOT_SETTING", argv[1]);
76         }
77         if(log_event) {
78             logEvent(event);
79         }
80     } else {
81         reply(getTextBot(), user, "NS_SETBOT_HEADER", botid);
82         global_cmd_setbot_active(user, row, NULL);
83         global_cmd_setbot_nick(user, row, NULL);
84         global_cmd_setbot_ident(user, row, NULL);
85         global_cmd_setbot_realname(user, row, NULL);
86         global_cmd_setbot_server(user, row, NULL);
87         global_cmd_setbot_port(user, row, NULL);
88         global_cmd_setbot_bind(user, row, NULL);
89         global_cmd_setbot_ssl(user, row, NULL);
90         global_cmd_setbot_serverpass(user, row, NULL);
91         global_cmd_setbot_class(user, row, NULL);
92         global_cmd_setbot_queue(user, row, NULL);
93         global_cmd_setbot_prefered(user, row, NULL);
94         global_cmd_setbot_maxchan(user, row, NULL);
95         global_cmd_setbot_priority(user, row, NULL);
96         global_cmd_setbot_trigger(user, row, NULL);
97     }
98 }
99
100 static int global_cmd_setbot_active(struct UserNode *user, MYSQL_ROW bot, char *value) {
101     int val = ((bot[0] && !strcmp(bot[0], "1")) ? 1 : 0);
102     int ret = 0;
103     if(value) {
104         if(!strcmp(value, "0") || !stricmp(value, "off") || !stricmp(value, get_language_string(user, "NS_SET_OFF"))) {
105             val = 0;
106         } else if(!strcmp(value, "1") || !stricmp(value, "on") || !stricmp(value, get_language_string(user, "NS_SET_ON"))) {
107             val = 1;
108         } else {
109             reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", value);
110             return 0;
111         }
112         if(val != ((bot[0] && !strcmp(bot[0], "1")) ? 1 : 0)) {
113             if(val) {
114                 //add the bot
115                 struct ClientSocket *client;
116                 client = create_socket(bot[2], atoi(bot[3]), bot[11], bot[4], bot[1], bot[12], bot[13]);
117                 client->flags |= (strcmp(bot[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
118                 client->flags |= (strcmp(bot[7], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
119                 client->flags |= (strcmp(bot[14], "0") ? SOCKET_FLAG_SSL : 0);
120                 client->botid = atoi(bot[5]);
121                 client->clientid = atoi(bot[15]);
122                 connect_socket(client);
123                 if(client->botid == 0) {
124                     MYSQL_RES *res;
125                     MYSQL_ROW row;
126                     printf_mysql_query("SELECT `command`, `function`, `parameters`, `global_access`, `chan_access` FROM `bot_binds` WHERE `botclass` = '0' AND `botid` = '%d'", client->clientid);
127                     res = mysql_use();
128                     while ((row = mysql_fetch_row(res)) != NULL) {
129                         if(bind_botwise_cmd_to_command(0, client->clientid, row[0], row[1])) {
130                             if(row[2] && strcmp(row[2], "")) {
131                                 bind_botwise_set_parameters(0, client->clientid, row[0], row[2]);
132                             }
133                             if(row[3]) {
134                                 bind_botwise_set_global_access(0, client->clientid, row[0], atoi(row[3]));
135                             }
136                             if(row[4]) {
137                                 bind_botwise_set_channel_access(0, client->clientid, row[0], row[4]);
138                             }
139                         }
140                     }
141                     bind_botwise_unbound_required_functions(0, client->clientid);
142                 }
143             } else {
144                 //remove the bot
145                 struct ClientSocket *client;
146                 for(client = getBots(0, NULL); client; client = getBots(0, client)) {
147                     if(client->clientid == atoi(bot[15])) {
148                         unbind_botwise_allcmd(client->clientid);
149                         close_socket(client);
150                         break;
151                     }
152                 }
153             }
154             printf_mysql_query("UPDATE `bots` SET `active` = '%d' WHERE `id` = '%s'", val, bot[15]);
155             ret = 1;
156         }
157     }
158     reply(getTextBot(), user, "\002ACTIVE     \002 %s", get_language_string(user, (val ? "NS_SET_ON" : "NS_SET_OFF")));
159     return ret;
160 }
161
162 static int global_cmd_setbot_nick(struct UserNode *user, MYSQL_ROW bot, char *value) {
163     char *val = bot[1];
164     int ret = 0;
165     if(value) {
166         if(!is_valid_nick(value)) {
167             reply(getTextBot(), user, "NS_SETBOT_NICK_INVALID", value);
168             return 0;
169         }
170         //rename the bot
171         struct ClientSocket *client;
172         for(client = getBots(0, NULL); client; client = getBots(0, client)) {
173             if(client->clientid == atoi(bot[15])) {
174                 if(client->nick)
175                     free(client->nick);
176                 client->nick = strdup(value);
177                 if(client->flags & SOCKET_FLAG_READY)
178                     putsock(client, "NICK %s", value);
179                 break;
180             }
181         }
182         printf_mysql_query("UPDATE `bots` SET `nick` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]);
183         val = value;
184         ret = 1;
185     }
186     reply(getTextBot(), user, "\002NICK       \002 %s", val);
187     return ret;
188 }
189
190 static int global_cmd_setbot_ident(struct UserNode *user, MYSQL_ROW bot, char *value) {
191     char *val = bot[12];
192     int ret = 0;
193     if(value) {
194         if(strlen(value) > 12)
195             value[12] = '\0';
196         //rename the bot
197         struct ClientSocket *client;
198         for(client = getBots(0, NULL); client; client = getBots(0, client)) {
199             if(client->clientid == atoi(bot[15])) {
200                 if(client->ident)
201                     free(client->ident);
202                 client->ident = strdup(value);
203                 break;
204             }
205         }
206         printf_mysql_query("UPDATE `bots` SET `ident` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]);
207         val = value;
208         ret = 1;
209     }
210     reply(getTextBot(), user, "\002IDENT      \002 %s", val);
211     return ret;
212 }
213
214 static int global_cmd_setbot_realname(struct UserNode *user, MYSQL_ROW bot, char *value) {
215     char *val = bot[13];
216     int ret = 0;
217     if(value) {
218         if(strlen(value) > 255)
219             value[255] = '\0';
220         //rename the bot
221         struct ClientSocket *client;
222         for(client = getBots(0, NULL); client; client = getBots(0, client)) {
223             if(client->clientid == atoi(bot[15])) {
224                 if(client->ident)
225                     free(client->ident);
226                 client->ident = strdup(value);
227                 break;
228             }
229         }
230         printf_mysql_query("UPDATE `bots` SET `realname` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]);
231         val = value;
232         ret = 1;
233     }
234     reply(getTextBot(), user, "\002REALNAME   \002 %s", val);
235     return ret;
236 }
237
238 static int global_cmd_setbot_server(struct UserNode *user, MYSQL_ROW bot, char *value) {
239     char *val = bot[2];
240     int ret = 0;
241     if(value) {
242         struct ClientSocket *client;
243         for(client = getBots(0, NULL); client; client = getBots(0, client)) {
244             if(client->clientid == atoi(bot[15])) {
245                 if(client->host)
246                     free(client->host);
247                 client->host = strdup(value);
248                 if(client->flags & SOCKET_FLAG_READY)
249                     reply(getTextBot(), user, "NS_SETBOT_NEED_RESTART");
250                 break;
251             }
252         }
253         printf_mysql_query("UPDATE `bots` SET `server` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]);
254         val = value;
255         ret = 1;
256     }
257     reply(getTextBot(), user, "\002SERVER     \002 %s", val);
258     return ret;
259 }
260
261 static int global_cmd_setbot_port(struct UserNode *user, MYSQL_ROW bot, char *value) {
262     int val = atoi(bot[3]);
263     int ret = 0;
264     if(value) {
265         val = atoi(value);
266         if(val <= 0 || val > 65534) {
267             reply(getTextBot(), user, "NS_SETBOT_PORT_INVALID", value);
268             return 0;
269         }
270         struct ClientSocket *client;
271         for(client = getBots(0, NULL); client; client = getBots(0, client)) {
272             if(client->clientid == atoi(bot[15])) {
273                 client->port = val;
274                 if(client->flags & SOCKET_FLAG_READY)
275                     reply(getTextBot(), user, "NS_SETBOT_NEED_RESTART");
276                 break;
277             }
278         }
279         printf_mysql_query("UPDATE `bots` SET `port` = '%d' WHERE `id` = '%s'", val, bot[15]);
280         ret = 1;
281     }
282     reply(getTextBot(), user, "\002PORT       \002 %d", val);
283     return ret;
284 }
285
286 static int global_cmd_setbot_bind(struct UserNode *user, MYSQL_ROW bot, char *value) {
287     char *val = bot[11];
288     int ret = 0;
289     if(value) {
290         if(!strcmp(value, "*")) 
291             value = NULL;
292         struct ClientSocket *client;
293         for(client = getBots(0, NULL); client; client = getBots(0, client)) {
294             if(client->clientid == atoi(bot[15])) {
295                 if(client->bind)
296                     free(client->bind);
297                 client->bind = (value ? strdup(value) : NULL);
298                 if(client->flags & SOCKET_FLAG_READY)
299                     reply(getTextBot(), user, "NS_SETBOT_NEED_RESTART");
300                 break;
301             }
302         }
303         if(value)
304             printf_mysql_query("UPDATE `bots` SET `bind` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]);
305         else
306             printf_mysql_query("UPDATE `bots` SET `bind` = NULL WHERE `id` = '%s'", bot[15]);
307         val = value;
308         ret = 1;
309     }
310     reply(getTextBot(), user, "\002BIND       \002 %s", val);
311     return ret;
312 }
313
314 static int global_cmd_setbot_ssl(struct UserNode *user, MYSQL_ROW bot, char *value) {
315     int val = (strcmp(bot[14], "0") ? 1 : 0);
316     int ret = 0;
317     if(value) {
318         if(!strcmp(value, "0") || !stricmp(value, "off") || !stricmp(value, get_language_string(user, "NS_SET_OFF"))) {
319             val = 0;
320         } else if(!strcmp(value, "1") || !stricmp(value, "on") || !stricmp(value, get_language_string(user, "NS_SET_ON"))) {
321             val = 1;
322         } else {
323             reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", value);
324             return 0;
325         }
326         struct ClientSocket *client;
327         for(client = getBots(0, NULL); client; client = getBots(0, client)) {
328             if(client->clientid == atoi(bot[15])) {
329                 if(val)
330                     client->flags |= SOCKET_FLAG_SSL;
331                 else
332                     client->flags &= ~SOCKET_FLAG_SSL;
333                 if(client->flags & SOCKET_FLAG_READY)
334                     reply(getTextBot(), user, "NS_SETBOT_NEED_RESTART");
335                 break;
336             }
337         }
338         printf_mysql_query("UPDATE `bots` SET `ssl` = '%d' WHERE `id` = '%s'", val, bot[15]);
339         ret = 1;
340     }
341     reply(getTextBot(), user, "\002SSL        \002 %s", get_language_string(user, (val ? "NS_SET_ON" : "NS_SET_OFF")));
342     return ret;
343 }
344
345 static int global_cmd_setbot_serverpass(struct UserNode *user, MYSQL_ROW bot, char *value) {
346     char *val = bot[4];
347     int ret = 0;
348     if(value) {
349         struct ClientSocket *client;
350         for(client = getBots(0, NULL); client; client = getBots(0, client)) {
351             if(client->clientid == atoi(bot[15])) {
352                 if(client->pass)
353                     free(client->pass);
354                 client->pass = strdup(value);
355                 if(client->flags & SOCKET_FLAG_READY)
356                     reply(getTextBot(), user, "NS_SETBOT_NEED_RESTART");
357                 break;
358             }
359         }
360         printf_mysql_query("UPDATE `bots` SET `pass` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]);
361         val = value;
362         ret = 1;
363     }
364     reply(getTextBot(), user, "\002SERVERPASS \002 %s", val);
365     return ret;
366 }
367
368 static int global_cmd_setbot_class(struct UserNode *user, MYSQL_ROW bot, char *value) {
369     int val = atoi(bot[5]);
370     int ret = 0;
371     if(value) {
372         if((val = resolve_botalias(value)) == -1) {
373             reply(getTextBot(), user, "NS_SETBOT_INVALID_CLASS", value);
374             return 0;
375         }
376         if(val != atoi(bot[5])) {
377             struct ClientSocket *client;
378             for(client = getBots(0, NULL); client; client = getBots(0, client)) {
379                 if(client->clientid == atoi(bot[15])) {
380                     unbind_botwise_allcmd(client->clientid);
381                     client->botid = val;
382                     if(client->botid == 0) {
383                         MYSQL_RES *res;
384                         MYSQL_ROW row;
385                         printf_mysql_query("SELECT `command`, `function`, `parameters`, `global_access`, `chan_access` FROM `bot_binds` WHERE `botclass` = '0' AND `botid` = '%d'", client->clientid);
386                         res = mysql_use();
387                         while ((row = mysql_fetch_row(res)) != NULL) {
388                             if(bind_botwise_cmd_to_command(client->botid, client->clientid, row[0], row[1])) {
389                                 if(row[2] && strcmp(row[2], "")) {
390                                     bind_botwise_set_parameters(client->botid, client->clientid, row[0], row[2]);
391                                 }
392                                 if(row[3]) {
393                                     bind_botwise_set_global_access(client->botid, client->clientid, row[0], atoi(row[3]));
394                                 }
395                                 if(row[4]) {
396                                     bind_botwise_set_channel_access(client->botid, client->clientid, row[0], row[4]);
397                                 }
398                             }
399                         }
400                         bind_botwise_unbound_required_functions(client->botid, client->clientid);
401                     }
402                     break;
403                 }
404             }
405             printf_mysql_query("UPDATE `bots` SET `botclass` = '%d' WHERE `id` = '%s'", val, bot[15]);
406             ret = 1;
407         }
408     }
409     reply(getTextBot(), user, "\002BOTCLASS   \002 %s", resolve_botid(val));
410     return ret;
411 }
412
413 static int global_cmd_setbot_queue(struct UserNode *user, MYSQL_ROW bot, char *value) {
414     int val = (strcmp(bot[7], "0") ? 1 : 0);
415     int ret = 0;
416     if(value) {
417         if(!strcmp(value, "0") || !stricmp(value, "off") || !stricmp(value, get_language_string(user, "NS_SET_OFF"))) {
418             val = 0;
419         } else if(!strcmp(value, "1") || !stricmp(value, "on") || !stricmp(value, get_language_string(user, "NS_SET_ON"))) {
420             val = 1;
421         } else {
422             reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", value);
423             return 0;
424         }
425         struct ClientSocket *client;
426         for(client = getBots(0, NULL); client; client = getBots(0, client)) {
427             if(client->clientid == atoi(bot[15])) {
428                 if(val)
429                     client->flags |= SOCKET_FLAG_USE_QUEUE;
430                 else
431                     client->flags &= ~SOCKET_FLAG_USE_QUEUE;
432                 break;
433             }
434         }
435         printf_mysql_query("UPDATE `bots` SET `queue` = '%d' WHERE `id` = '%s'", val, bot[15]);
436         ret = 1;
437     }
438     reply(getTextBot(), user, "\002QUEUE      \002 %s", get_language_string(user, (val ? "NS_SET_ON" : "NS_SET_OFF")));
439     return ret;
440 }
441
442 static int global_cmd_setbot_prefered(struct UserNode *user, MYSQL_ROW bot, char *value) {
443     int val = (strcmp(bot[6], "0") ? 1 : 0);
444     int ret = 0;
445     if(value) {
446         if(!strcmp(value, "0") || !stricmp(value, "off") || !stricmp(value, get_language_string(user, "NS_SET_OFF"))) {
447             val = 0;
448         } else if(!strcmp(value, "1") || !stricmp(value, "on") || !stricmp(value, get_language_string(user, "NS_SET_ON"))) {
449             val = 1;
450         } else {
451             reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", value);
452             return 0;
453         }
454         struct ClientSocket *client;
455         for(client = getBots(0, NULL); client; client = getBots(0, client)) {
456             if(client->clientid == atoi(bot[15])) {
457                 if(val)
458                     client->flags |= SOCKET_FLAG_PREFERRED;
459                 else
460                     client->flags &= ~SOCKET_FLAG_PREFERRED;
461                 break;
462             }
463         }
464         printf_mysql_query("UPDATE `bots` SET `queue` = '%d' WHERE `id` = '%s'", val, bot[15]);
465         ret = 1;
466     }
467     reply(getTextBot(), user, "\002PREFERED   \002 %s", get_language_string(user, (val ? "NS_SET_ON" : "NS_SET_OFF")));
468     return ret;
469 }
470
471 static int global_cmd_setbot_maxchan(struct UserNode *user, MYSQL_ROW bot, char *value) {
472     int val = atoi(bot[9]);
473     int ret = 0;
474     if(value) {
475         val = atoi(value);
476         if(val < 0 || val > 99999) {
477             reply(getTextBot(), user, "NS_SETBOT_MAXCHAN_INVALID", value);
478             return 0;
479         }
480         printf_mysql_query("UPDATE `bots` SET `max_channels` = '%d' WHERE `id` = '%s'", val, bot[15]);
481         ret = 1;
482     }
483     reply(getTextBot(), user, "\002MAXCHAN    \002 %d", val);
484     return ret;
485 }
486
487 static int global_cmd_setbot_priority(struct UserNode *user, MYSQL_ROW bot, char *value) {
488     int val = atoi(bot[10]);
489     int ret = 0;
490     if(value) {
491         val = atoi(value);
492         if(val < 0 || val > 99) {
493             reply(getTextBot(), user, "NS_SETBOT_PRIORITY_INVALID", value);
494             return 0;
495         }
496         printf_mysql_query("UPDATE `bots` SET `register_priority` = '%d' WHERE `id` = '%s'", val, bot[15]);
497         ret = 1;
498     }
499     reply(getTextBot(), user, "\002PRIORITY   \002 %d", val);
500     return ret;
501 }
502
503 static int global_cmd_setbot_trigger(struct UserNode *user, MYSQL_ROW bot, char *value) {
504     char *val = bot[8];
505     int ret = 0;
506     if(value) {
507         if(!*value || strlen(value) > 10) {
508             reply(getTextBot(), user, "NS_SETBOT_TRIGGER_INVALID", value);
509             return 0;
510         }
511         printf_mysql_query("UPDATE `bots` SET `defaulttrigger` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]);
512         flush_trigger_cache(atoi(bot[5]), atoi(bot[15]));
513         reply(getTextBot(), user, "NS_SETBOT_TRIGGER_NOTE");
514         val = value;
515         ret = 1;
516     }
517     reply(getTextBot(), user, "\002TRIGGER    \002 %s", val);
518     return ret;
519 }