added cmd_setbot for dynamic bot management
[NeonServV5.git] / src / cmd_global_setbot.c
1 /* cmd_global_setbot.c - NeonServ v5.2
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_nick(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             } else {
124                 //remove the bot
125                 struct ClientSocket *client;
126                 for(client = getBots(0, NULL); client; client = getBots(0, client)) {
127                     if(client->clientid == atoi(bot[15])) {
128                         close_socket(client);
129                         break;
130                     }
131                 }
132             }
133             printf_mysql_query("UPDATE `bots` SET `active` = '%d' WHERE `id` = '%s'", val, bot[15]);
134             ret = 1;
135         }
136     }
137     reply(getTextBot(), user, "\002ACTIVE     \002 %s", get_language_string(user, (val ? "NS_SET_ON" : "NS_SET_OFF")));
138     return ret;
139 }
140
141 static int global_cmd_setbot_nick(struct UserNode *user, MYSQL_ROW bot, char *value) {
142     char *val = bot[1];
143     int ret = 0;
144     if(value) {
145         if(!is_valid_nick(value)) {
146             reply(getTextBot(), user, "NS_SETBOT_NICK_INVALID", value);
147             return 0;
148         }
149         //rename the bot
150         struct ClientSocket *client;
151         for(client = getBots(0, NULL); client; client = getBots(0, client)) {
152             if(client->clientid == atoi(bot[15])) {
153                 if(client->nick)
154                     free(client->nick);
155                 client->nick = strdup(value);
156                 if(client->flags & SOCKET_FLAG_READY)
157                     putsock(client, "NICK %s", value);
158                 break;
159             }
160         }
161         printf_mysql_query("UPDATE `bots` SET `nick` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]);
162         val = value;
163         ret = 1;
164     }
165     reply(getTextBot(), user, "\002NICK       \002 %s", val);
166     return ret;
167 }
168
169 static int global_cmd_setbot_ident(struct UserNode *user, MYSQL_ROW bot, char *value) {
170     char *val = bot[12];
171     int ret = 0;
172     if(value) {
173         if(strlen(value) > 12)
174             value[12] = '\0';
175         //rename the bot
176         struct ClientSocket *client;
177         for(client = getBots(0, NULL); client; client = getBots(0, client)) {
178             if(client->clientid == atoi(bot[15])) {
179                 if(client->ident)
180                     free(client->ident);
181                 client->ident = strdup(value);
182                 break;
183             }
184         }
185         printf_mysql_query("UPDATE `bots` SET `ident` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]);
186         val = value;
187         ret = 1;
188     }
189     reply(getTextBot(), user, "\002IDENT      \002 %s", val);
190     return ret;
191 }
192
193 static int global_cmd_setbot_realname(struct UserNode *user, MYSQL_ROW bot, char *value) {
194     char *val = bot[13];
195     int ret = 0;
196     if(value) {
197         if(strlen(value) > 255)
198             value[255] = '\0';
199         //rename the bot
200         struct ClientSocket *client;
201         for(client = getBots(0, NULL); client; client = getBots(0, client)) {
202             if(client->clientid == atoi(bot[15])) {
203                 if(client->ident)
204                     free(client->ident);
205                 client->ident = strdup(value);
206                 break;
207             }
208         }
209         printf_mysql_query("UPDATE `bots` SET `realname` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]);
210         val = value;
211         ret = 1;
212     }
213     reply(getTextBot(), user, "\002REALNAME   \002 %s", val);
214     return ret;
215 }
216
217 static int global_cmd_setbot_server(struct UserNode *user, MYSQL_ROW bot, char *value) {
218     char *val = bot[2];
219     int ret = 0;
220     if(value) {
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->host)
225                     free(client->host);
226                 client->host = strdup(value);
227                 if(client->flags & SOCKET_FLAG_READY)
228                     reply(getTextBot(), user, "NS_SETBOT_NEED_RESTART");
229                 break;
230             }
231         }
232         printf_mysql_query("UPDATE `bots` SET `server` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]);
233         val = value;
234         ret = 1;
235     }
236     reply(getTextBot(), user, "\002SERVER     \002 %s", val);
237     return ret;
238 }
239
240 static int global_cmd_setbot_port(struct UserNode *user, MYSQL_ROW bot, char *value) {
241     int val = atoi(bot[3]);
242     int ret = 0;
243     if(value) {
244         val = atoi(value);
245         if(val <= 0 || val > 65534) {
246             reply(getTextBot(), user, "NS_SETBOT_PORT_INVALID", value);
247             return 0;
248         }
249         struct ClientSocket *client;
250         for(client = getBots(0, NULL); client; client = getBots(0, client)) {
251             if(client->clientid == atoi(bot[15])) {
252                 client->port = val;
253                 if(client->flags & SOCKET_FLAG_READY)
254                     reply(getTextBot(), user, "NS_SETBOT_NEED_RESTART");
255                 break;
256             }
257         }
258         printf_mysql_query("UPDATE `bots` SET `port` = '%d' WHERE `id` = '%s'", val, bot[15]);
259         ret = 1;
260     }
261     reply(getTextBot(), user, "\002PORT       \002 %d", val);
262     return ret;
263 }
264
265 static int global_cmd_setbot_bind(struct UserNode *user, MYSQL_ROW bot, char *value) {
266     char *val = bot[11];
267     int ret = 0;
268     if(value) {
269         if(!strcmp(value, "*")) 
270             value = NULL;
271         struct ClientSocket *client;
272         for(client = getBots(0, NULL); client; client = getBots(0, client)) {
273             if(client->clientid == atoi(bot[15])) {
274                 if(client->bind)
275                     free(client->bind);
276                 client->bind = (value ? strdup(value) : NULL);
277                 if(client->flags & SOCKET_FLAG_READY)
278                     reply(getTextBot(), user, "NS_SETBOT_NEED_RESTART");
279                 break;
280             }
281         }
282         if(value)
283             printf_mysql_query("UPDATE `bots` SET `bind` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]);
284         else
285             printf_mysql_query("UPDATE `bots` SET `bind` = NULL WHERE `id` = '%s'", bot[15]);
286         val = value;
287         ret = 1;
288     }
289     reply(getTextBot(), user, "\002BIND       \002 %s", val);
290     return ret;
291 }
292
293 static int global_cmd_setbot_ssl(struct UserNode *user, MYSQL_ROW bot, char *value) {
294     int val = (strcmp(bot[14], "0") ? 1 : 0);
295     int ret = 0;
296     if(value) {
297         if(!strcmp(value, "0") || !stricmp(value, "off") || !stricmp(value, get_language_string(user, "NS_SET_OFF"))) {
298             val = 0;
299         } else if(!strcmp(value, "1") || !stricmp(value, "on") || !stricmp(value, get_language_string(user, "NS_SET_ON"))) {
300             val = 1;
301         } else {
302             reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", value);
303             return 0;
304         }
305         struct ClientSocket *client;
306         for(client = getBots(0, NULL); client; client = getBots(0, client)) {
307             if(client->clientid == atoi(bot[15])) {
308                 if(val)
309                     client->flags |= SOCKET_FLAG_SSL;
310                 else
311                     client->flags &= ~SOCKET_FLAG_SSL;
312                 if(client->flags & SOCKET_FLAG_READY)
313                     reply(getTextBot(), user, "NS_SETBOT_NEED_RESTART");
314                 break;
315             }
316         }
317         printf_mysql_query("UPDATE `bots` SET `ssl` = '%d' WHERE `id` = '%s'", val, bot[15]);
318         ret = 1;
319     }
320     reply(getTextBot(), user, "\002SSL        \002 %s", get_language_string(user, (val ? "NS_SET_ON" : "NS_SET_OFF")));
321     return ret;
322 }
323
324 static int global_cmd_setbot_serverpass(struct UserNode *user, MYSQL_ROW bot, char *value) {
325     char *val = bot[4];
326     int ret = 0;
327     if(value) {
328         struct ClientSocket *client;
329         for(client = getBots(0, NULL); client; client = getBots(0, client)) {
330             if(client->clientid == atoi(bot[15])) {
331                 if(client->pass)
332                     free(client->pass);
333                 client->pass = strdup(value);
334                 if(client->flags & SOCKET_FLAG_READY)
335                     reply(getTextBot(), user, "NS_SETBOT_NEED_RESTART");
336                 break;
337             }
338         }
339         printf_mysql_query("UPDATE `bots` SET `pass` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]);
340         val = value;
341         ret = 1;
342     }
343     reply(getTextBot(), user, "\002SERVERPASS \002 %s", val);
344     return ret;
345 }
346
347 static int global_cmd_setbot_class(struct UserNode *user, MYSQL_ROW bot, char *value) {
348     int val = atoi(bot[5]);
349     int ret = 0;
350     if(value) {
351         if((val = resolve_botalias(value)) != -1) {
352             reply(getTextBot(), user, "NS_SETBOT_INVALID_CLASS", value);
353             return 0;
354         }
355         if(val != atoi(bot[5])) {
356             struct ClientSocket *client;
357             for(client = getBots(0, NULL); client; client = getBots(0, client)) {
358                 if(client->clientid == atoi(bot[15])) {
359                     unbind_botwise_allcmd(client->clientid);
360                     client->botid = val;
361                     if(client->botid == 0) {
362                         MYSQL_RES *res;
363                         MYSQL_ROW row;
364                         printf_mysql_query("SELECT `command`, `function`, `parameters`, `global_access`, `chan_access` FROM `bot_binds` WHERE `botclass` = '0' AND `botid` = '%d'", client->clientid);
365                         res = mysql_use();
366                         while ((row = mysql_fetch_row(res)) != NULL) {
367                             if(bind_botwise_cmd_to_command(client->botid, client->clientid, row[0], row[1])) {
368                                 if(row[2] && strcmp(row[2], "")) {
369                                     bind_botwise_set_parameters(client->botid, client->clientid, row[0], row[2]);
370                                 }
371                                 if(row[3]) {
372                                     bind_botwise_set_global_access(client->botid, client->clientid, row[0], atoi(row[3]));
373                                 }
374                                 if(row[4]) {
375                                     bind_botwise_set_channel_access(client->botid, client->clientid, row[0], row[4]);
376                                 }
377                             }
378                         }
379                         bind_botwise_unbound_required_functions(client->botid, client->clientid);
380                     }
381                     break;
382                 }
383             }
384             printf_mysql_query("UPDATE `bots` SET `botclass` = '%d' WHERE `id` = '%s'", val, bot[15]);
385             ret = 1;
386         }
387     }
388     reply(getTextBot(), user, "\002BOTCLASS   \002 %s", resolve_botid(val));
389     return ret;
390 }
391
392 static int global_cmd_setbot_queue(struct UserNode *user, MYSQL_ROW bot, char *value) {
393     int val = (strcmp(bot[7], "0") ? 1 : 0);
394     int ret = 0;
395     if(value) {
396         if(!strcmp(value, "0") || !stricmp(value, "off") || !stricmp(value, get_language_string(user, "NS_SET_OFF"))) {
397             val = 0;
398         } else if(!strcmp(value, "1") || !stricmp(value, "on") || !stricmp(value, get_language_string(user, "NS_SET_ON"))) {
399             val = 1;
400         } else {
401             reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", value);
402             return 0;
403         }
404         struct ClientSocket *client;
405         for(client = getBots(0, NULL); client; client = getBots(0, client)) {
406             if(client->clientid == atoi(bot[15])) {
407                 if(val)
408                     client->flags |= SOCKET_FLAG_USE_QUEUE;
409                 else
410                     client->flags &= ~SOCKET_FLAG_USE_QUEUE;
411                 break;
412             }
413         }
414         printf_mysql_query("UPDATE `bots` SET `queue` = '%d' WHERE `id` = '%s'", val, bot[15]);
415         ret = 1;
416     }
417     reply(getTextBot(), user, "\002QUEUE      \002 %s", get_language_string(user, (val ? "NS_SET_ON" : "NS_SET_OFF")));
418     return ret;
419 }
420
421 static int global_cmd_setbot_prefered(struct UserNode *user, MYSQL_ROW bot, char *value) {
422     int val = (strcmp(bot[6], "0") ? 1 : 0);
423     int ret = 0;
424     if(value) {
425         if(!strcmp(value, "0") || !stricmp(value, "off") || !stricmp(value, get_language_string(user, "NS_SET_OFF"))) {
426             val = 0;
427         } else if(!strcmp(value, "1") || !stricmp(value, "on") || !stricmp(value, get_language_string(user, "NS_SET_ON"))) {
428             val = 1;
429         } else {
430             reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", value);
431             return 0;
432         }
433         struct ClientSocket *client;
434         for(client = getBots(0, NULL); client; client = getBots(0, client)) {
435             if(client->clientid == atoi(bot[15])) {
436                 if(val)
437                     client->flags |= SOCKET_FLAG_PREFERRED;
438                 else
439                     client->flags &= ~SOCKET_FLAG_PREFERRED;
440                 break;
441             }
442         }
443         printf_mysql_query("UPDATE `bots` SET `queue` = '%d' WHERE `id` = '%s'", val, bot[15]);
444         ret = 1;
445     }
446     reply(getTextBot(), user, "\002PREFERED   \002 %s", get_language_string(user, (val ? "NS_SET_ON" : "NS_SET_OFF")));
447     return ret;
448 }
449
450 static int global_cmd_setbot_maxchan(struct UserNode *user, MYSQL_ROW bot, char *value) {
451     int val = atoi(bot[9]);
452     int ret = 0;
453     if(value) {
454         val = atoi(value);
455         if(val < 0 || val > 99999) {
456             reply(getTextBot(), user, "NS_SETBOT_MAXCHAN_INVALID", value);
457             return 0;
458         }
459         printf_mysql_query("UPDATE `bots` SET `maxchan` = '%d' WHERE `id` = '%s'", val, bot[15]);
460         ret = 1;
461     }
462     reply(getTextBot(), user, "\002MAXCHAN    \002 %d", val);
463     return ret;
464 }
465
466 static int global_cmd_setbot_priority(struct UserNode *user, MYSQL_ROW bot, char *value) {
467     int val = atoi(bot[10]);
468     int ret = 0;
469     if(value) {
470         val = atoi(value);
471         if(val < 0 || val > 99) {
472             reply(getTextBot(), user, "NS_SETBOT_PRIORITY_INVALID", value);
473             return 0;
474         }
475         printf_mysql_query("UPDATE `bots` SET `register_priority` = '%d' WHERE `id` = '%s'", val, bot[15]);
476         ret = 1;
477     }
478     reply(getTextBot(), user, "\002PRIORITY   \002 %d", val);
479     return ret;
480 }
481
482 static int global_cmd_setbot_trigger(struct UserNode *user, MYSQL_ROW bot, char *value) {
483     char *val = bot[8];
484     int ret = 0;
485     if(value) {
486         if(!*value || strlen(value) > 10) {
487             reply(getTextBot(), user, "NS_SETBOT_TRIGGER_INVALID", value);
488             return 0;
489         }
490         printf_mysql_query("UPDATE `bots` SET `defaulttrigger` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]);
491         reply(getTextBot(), user, "NS_SETBOT_TRIGGER_NOTE");
492         val = value;
493         ret = 1;
494     }
495     reply(getTextBot(), user, "\002TRIGGER    \002 %s", val);
496     return ret;
497 }