From 391260f64a1dfb35bf0a55e7044fe1b8d83f2561 Mon Sep 17 00:00:00 2001 From: pk910 Date: Wed, 21 Dec 2011 23:52:06 +0100 Subject: [PATCH] added cmd_setbot for dynamic bot management --- Makefile.am | 1 + src/ClientSocket.c | 14 +- src/ClientSocket.h | 1 + src/bot_NeonServ.c | 12 + src/bots.c | 3 +- src/cmd_global.h | 1 + src/cmd_global_bots.c | 30 +-- src/cmd_global_setbot.c | 497 ++++++++++++++++++++++++++++++++++++++++ src/commands.c | 3 +- src/modcmd.c | 29 +++ src/modcmd.h | 2 + 11 files changed, 571 insertions(+), 22 deletions(-) create mode 100644 src/cmd_global_setbot.c diff --git a/Makefile.am b/Makefile.am index 0cfac17..094eb2c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -120,6 +120,7 @@ neonserv_SOURCES = src/version.c \ src/cmd_global_restart.c \ src/cmd_global_die.c \ src/cmd_neonserv_nicklist.c \ + src/cmd_global_setbot.c \ src/cmd_funcmds.c \ src/ConfigParser.c diff --git a/src/ClientSocket.c b/src/ClientSocket.c index db93f9a..2e2eb1c 100644 --- a/src/ClientSocket.c +++ b/src/ClientSocket.c @@ -185,6 +185,7 @@ int connect_socket(struct ClientSocket *client) { if(client->flags & SOCKET_FLAG_SSL) { ssl_connect(client); + client->flags |= SOCKET_FLAG_HAVE_SSL; } //send the IRC Headers @@ -239,6 +240,7 @@ int connect_socket(struct ClientSocket *client) { if(client->flags & SOCKET_FLAG_SSL) { ssl_connect(client); + client->flags |= SOCKET_FLAG_HAVE_SSL; } @@ -263,7 +265,7 @@ int close_socket(struct ClientSocket *client) { if(client == NULL) return 0; if((client->flags & SOCKET_FLAG_CONNECTED)) close(client->sock); - if(client->flags & SOCKET_FLAG_SSL) + if(client->flags & SOCKET_FLAG_HAVE_SSL) ssl_disconnect(client); struct ClientSocket *sock, *last_sock = NULL; for (sock = sockets->data; sock; sock = sock->next) { @@ -293,7 +295,7 @@ int close_socket(struct ClientSocket *client) { int write_socket_force(struct ClientSocket *client, char* msg, int len) { printf("[send %d] %s", len, msg); - if(!(client->flags & SOCKET_FLAG_SSL) || ssl_write(client, msg, len) == -2) { + if(!(client->flags & SOCKET_FLAG_HAVE_SSL) || ssl_write(client, msg, len) == -2) { #ifdef WIN32 send(client->sock, msg, len, 0); #else @@ -333,7 +335,7 @@ void socket_loop(int timeout_seconds) { for (sock = sockets->data; sock; sock = sock->next) { if((sock->flags & SOCKET_FLAG_CONNECTED) && FD_ISSET(sock->sock, &fds)) { if(sock->bufferpos != 0) { - if(!(sock->flags & SOCKET_FLAG_SSL) || (bytes = ssl_read(sock, buffer, sizeof(buffer))) == -2) { + if(!(sock->flags & SOCKET_FLAG_HAVE_SSL) || (bytes = ssl_read(sock, buffer, sizeof(buffer))) == -2) { #ifdef WIN32 bytes = recv(sock->sock, buffer, sizeof(buffer), 0); #else @@ -348,7 +350,7 @@ void socket_loop(int timeout_seconds) { sock->bufferpos += i; } } else { - if(!(sock->flags & SOCKET_FLAG_SSL) || (bytes = ssl_read(sock, sock->buffer, sizeof(sock->buffer))) == -2) { + if(!(sock->flags & SOCKET_FLAG_HAVE_SSL) || (bytes = ssl_read(sock, sock->buffer, sizeof(sock->buffer))) == -2) { #ifdef WIN32 bytes = recv(sock->sock, sock->buffer, sizeof(sock->buffer), 0); #else @@ -365,7 +367,7 @@ void socket_loop(int timeout_seconds) { if(sock->queue) queue_destroy(sock); close(sock->sock); - if(sock->flags & SOCKET_FLAG_SSL) + if(sock->flags & SOCKET_FLAG_HAVE_SSL) ssl_disconnect(sock); } else { sock->traffic_in += bytes; @@ -422,7 +424,7 @@ void free_sockets() { next = client->next; if((client->flags & SOCKET_FLAG_CONNECTED)) close(client->sock); - if(client->flags & SOCKET_FLAG_SSL) + if(client->flags & SOCKET_FLAG_HAVE_SSL) ssl_disconnect(client); if(client->queue) queue_destroy(client); diff --git a/src/ClientSocket.h b/src/ClientSocket.h index 8d7ba76..7ede0c3 100644 --- a/src/ClientSocket.h +++ b/src/ClientSocket.h @@ -26,6 +26,7 @@ #define SOCKET_FLAG_USE_QUEUE 0x10 #define SOCKET_FLAG_RECONNECT 0x20 #define SOCKET_FLAG_SSL 0x40 +#define SOCKET_FLAG_HAVE_SSL 0x80 #define BUF_SIZ 512 diff --git a/src/bot_NeonServ.c b/src/bot_NeonServ.c index 9685801..a55e9ad 100644 --- a/src/bot_NeonServ.c +++ b/src/bot_NeonServ.c @@ -334,6 +334,7 @@ static const struct default_language_entry msgtab[] = { {"NS_DNR_EXPIRES", "Expires"}, {"NS_DNR_REASON", "Reason"}, {"NS_STAFF_LOGGEDIN", "Logged in as"}, + {"NS_BOTS_ID", "Id"}, {"NS_BOTS_NICK", "Nick"}, {"NS_BOTS_SERVER", "Server:Port(:Pass)"}, {"NS_BOTS_CLASS", "Bot Class"}, @@ -344,6 +345,17 @@ static const struct default_language_entry msgtab[] = { {"NS_NICKLIST_STATE", "State"}, {"NS_NICKLIST_ACCESS", "Access"}, {"NS_NICKLIST_SYNC", "use `nicklist sync` to fix all red and orange entrys in the list above (add opped users with 200 and voiced with 100 access)"}, + {"NS_SETBOT_UNKNOWN", "`%d` is an unknown botid."}, /* {ARGS: 50} */ + {"NS_SETBOT_HEADER", "$bSettings for botid `%d`:$b"}, /* {ARGS: 50} */ + {"NS_SETBOT_SETTING", "$b%s$b is an unknown bot setting."}, + {"NS_SETBOT_NICK_INVALID", "`%s` is an invalid botnick."}, /* {ARGS: "-SuperMagicBananaBotWithManyFunctions"} */ + {"NS_SETBOT_NEED_RESTART", "You need to reconnect to bot to apply this setting."}, + {"NS_SETBOT_PORT_INVALID", "`%s` is an invalid port number."}, /* {ARGS: "-1"} */ + {"NS_SETBOT_INVALID_CLASS", "`%s` is an invalid botclass."}, /* {ARGS: "MistColaLeer"} */ + {"NS_SETBOT_MAXCHAN_INVALID", "`%s` is an invalid maxchan value."}, /* {ARGS: "-1"} */ + {"NS_SETBOT_PRIORITY_INVALID", "`%s` is an invalid priority value."}, /* {ARGS: "-1"} */ + {"NS_SETBOT_TRIGGER_INVALID", "`%s` is an invalid bot trigger."}, /* {ARGS: "tooLongTrigger"} */ + {"NS_SETBOT_TRIGGER_NOTE", "Please note: This Setting will only affect new channels."}, {NULL, NULL} }; diff --git a/src/bots.c b/src/bots.c index d8de4ee..3f1cac0 100644 --- a/src/bots.c +++ b/src/bots.c @@ -95,6 +95,7 @@ void init_bots() { init_DummyServ(); init_NeonHelp(); + set_bot_alias(0, "0"); start_zero_bots(); set_trigger_callback(0, zero_bots_trigger_callback); @@ -263,5 +264,5 @@ int resolve_botalias(const char *alias) { if(!stricmp(botalias->alias, alias)) return botalias->botid; } - return 0; + return -1; } diff --git a/src/cmd_global.h b/src/cmd_global.h index ffd2be8..aa5a67d 100644 --- a/src/cmd_global.h +++ b/src/cmd_global.h @@ -54,6 +54,7 @@ CMD_BIND(global_cmd_restart); CMD_BIND(global_cmd_reloadlang); CMD_BIND(global_cmd_say); CMD_BIND(global_cmd_setaccess); +CMD_BIND(global_cmd_setbot); CMD_BIND(global_cmd_staff); CMD_BIND(global_cmd_unbind); CMD_BIND(global_cmd_unregister); diff --git a/src/cmd_global_bots.c b/src/cmd_global_bots.c index 93a1d19..cec43b7 100644 --- a/src/cmd_global_bots.c +++ b/src/cmd_global_bots.c @@ -27,14 +27,15 @@ CMD_BIND(global_cmd_bots) { MYSQL_ROW row, row2; printf_mysql_query("SELECT `active`, `nick`, `server`, `port`, `pass`, `botclass`, `textbot`, `queue`, `defaulttrigger`, `max_channels`, `register_priority`, `id` FROM `bots`"); res = mysql_use(); - table = table_init(6, mysql_num_rows(res) + 1, 0); - char *content[6]; - content[0] = get_language_string(user, "NS_BOTS_NICK"); - content[1] = get_language_string(user, "NS_BOTS_SERVER"); - content[2] = get_language_string(user, "NS_BOTS_CLASS"); - content[3] = get_language_string(user, "NS_BOTS_FLAGS"); - content[4] = get_language_string(user, "NS_BOTS_CHANNELS"); - content[5] = get_language_string(user, "NS_BOTS_TRIGGER"); + table = table_init(7, mysql_num_rows(res) + 1, 0); + char *content[7]; + content[0] = get_language_string(user, "NS_BOTS_ID"); + content[1] = get_language_string(user, "NS_BOTS_NICK"); + content[2] = get_language_string(user, "NS_BOTS_SERVER"); + content[3] = get_language_string(user, "NS_BOTS_CLASS"); + content[4] = get_language_string(user, "NS_BOTS_FLAGS"); + content[5] = get_language_string(user, "NS_BOTS_CHANNELS"); + content[6] = get_language_string(user, "NS_BOTS_TRIGGER"); table_add(table, content); char botnick[NICKLEN + 3]; char botserver[MAXLEN]; @@ -42,24 +43,25 @@ CMD_BIND(global_cmd_bots) { int flagspos; char botchans[20]; while ((row = mysql_fetch_row(res)) != NULL) { + content[0] = row[11]; sprintf(botnick, (strcmp(row[0], "0") ? "%s" : "!%s"), row[1]); - content[0] = botnick; + content[1] = botnick; sprintf(botserver, (strcmp(row[4], "") ? "%s:%s:*" : "%s:%s"), row[2], row[3]); - content[1] = botserver; - content[2] = (char *) resolve_botid(atoi(row[5])); + content[2] = botserver; + content[3] = (char *) resolve_botid(atoi(row[5])); flagspos = 0; if(!strcmp(row[6], "1")) botflags[flagspos++] = 't'; if(!strcmp(row[7], "1")) botflags[flagspos++] = 'q'; botflags[flagspos] = '\0'; - content[3] = botflags; + content[4] = botflags; printf_mysql_query("SELECT COUNT(*) FROM `bot_channels` WHERE `botid` = '%s'", row[11]); res2 = mysql_use(); row2 = mysql_fetch_row(res2); sprintf(botchans, "%s/%s", row2[0], row[9]); - content[4] = botchans; - content[5] = row[8]; + content[5] = botchans; + content[6] = row[8]; table_add(table, content); } char **table_lines = table_end(table); diff --git a/src/cmd_global_setbot.c b/src/cmd_global_setbot.c new file mode 100644 index 0000000..458a92e --- /dev/null +++ b/src/cmd_global_setbot.c @@ -0,0 +1,497 @@ +/* cmd_global_setbot.c - NeonServ v5.2 + * Copyright (C) 2011 Philipp Kreil (pk910) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "cmd_global.h" + +/* +* argv[0] botid +* argv[1] setting +* argv[2] value +*/ + +static int global_cmd_setbot_active(struct UserNode *user, MYSQL_ROW bot, char *value); +static int global_cmd_setbot_nick(struct UserNode *user, MYSQL_ROW bot, char *value); +static int global_cmd_setbot_ident(struct UserNode *user, MYSQL_ROW bot, char *value); +static int global_cmd_setbot_realname(struct UserNode *user, MYSQL_ROW bot, char *value); +static int global_cmd_setbot_server(struct UserNode *user, MYSQL_ROW bot, char *value); +static int global_cmd_setbot_port(struct UserNode *user, MYSQL_ROW bot, char *value); +static int global_cmd_setbot_bind(struct UserNode *user, MYSQL_ROW bot, char *value); +static int global_cmd_setbot_ssl(struct UserNode *user, MYSQL_ROW bot, char *value); +static int global_cmd_setbot_serverpass(struct UserNode *user, MYSQL_ROW bot, char *value); +static int global_cmd_setbot_class(struct UserNode *user, MYSQL_ROW bot, char *value); +static int global_cmd_setbot_queue(struct UserNode *user, MYSQL_ROW bot, char *value); +static int global_cmd_setbot_prefered(struct UserNode *user, MYSQL_ROW bot, char *value); +static int global_cmd_setbot_maxchan(struct UserNode *user, MYSQL_ROW bot, char *value); +static int global_cmd_setbot_priority(struct UserNode *user, MYSQL_ROW bot, char *value); +static int global_cmd_setbot_trigger(struct UserNode *user, MYSQL_ROW bot, char *value); + +CMD_BIND(global_cmd_setbot) { + MYSQL_RES *res; + MYSQL_ROW row; + int botid = atoi(argv[0]); + 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); + res = mysql_use(); + if(!(row = mysql_fetch_row(res))) { + reply(getTextBot(), user, "NS_SETBOT_UNKNOWN", botid); + return; + } + if(argc > 1) { + char *value; + if(argc > 2) { + value = merge_argv(argv, 2, argc); + } else + value = NULL; + int log_event = 0; + if(!stricmp(argv[1], "active")) log_event = global_cmd_setbot_active(user, row, value); + else if(!stricmp(argv[1], "nick")) log_event = global_cmd_setbot_nick(user, row, value); + else if(!stricmp(argv[1], "ident")) log_event = global_cmd_setbot_ident(user, row, value); + else if(!stricmp(argv[1], "realname")) log_event = global_cmd_setbot_realname(user, row, value); + else if(!stricmp(argv[1], "server")) log_event = global_cmd_setbot_server(user, row, value); + else if(!stricmp(argv[1], "port")) log_event = global_cmd_setbot_port(user, row, value); + else if(!stricmp(argv[1], "bind")) log_event = global_cmd_setbot_bind(user, row, value); + else if(!stricmp(argv[1], "ssl")) log_event = global_cmd_setbot_ssl(user, row, value); + else if(!stricmp(argv[1], "serverpass")) log_event = global_cmd_setbot_serverpass(user, row, value); + else if(!stricmp(argv[1], "botclass")) log_event = global_cmd_setbot_class(user, row, value); + else if(!stricmp(argv[1], "queue")) log_event = global_cmd_setbot_queue(user, row, value); + else if(!stricmp(argv[1], "prefered")) log_event = global_cmd_setbot_prefered(user, row, value); + else if(!stricmp(argv[1], "maxchan")) log_event = global_cmd_setbot_maxchan(user, row, value); + else if(!stricmp(argv[1], "priority")) log_event = global_cmd_setbot_priority(user, row, value); + else if(!stricmp(argv[1], "trigger")) log_event = global_cmd_setbot_nick(user, row, value); + else { + reply(getTextBot(), user, "NS_SETBOT_SETTING", argv[1]); + } + if(log_event) { + logEvent(event); + } + } else { + reply(getTextBot(), user, "NS_SETBOT_HEADER", botid); + global_cmd_setbot_active(user, row, NULL); + global_cmd_setbot_nick(user, row, NULL); + global_cmd_setbot_ident(user, row, NULL); + global_cmd_setbot_realname(user, row, NULL); + global_cmd_setbot_server(user, row, NULL); + global_cmd_setbot_port(user, row, NULL); + global_cmd_setbot_bind(user, row, NULL); + global_cmd_setbot_ssl(user, row, NULL); + global_cmd_setbot_serverpass(user, row, NULL); + global_cmd_setbot_class(user, row, NULL); + global_cmd_setbot_queue(user, row, NULL); + global_cmd_setbot_prefered(user, row, NULL); + global_cmd_setbot_maxchan(user, row, NULL); + global_cmd_setbot_priority(user, row, NULL); + global_cmd_setbot_trigger(user, row, NULL); + } +} + +static int global_cmd_setbot_active(struct UserNode *user, MYSQL_ROW bot, char *value) { + int val = ((bot[0] && !strcmp(bot[0], "1")) ? 1 : 0); + int ret = 0; + if(value) { + if(!strcmp(value, "0") || !stricmp(value, "off") || !stricmp(value, get_language_string(user, "NS_SET_OFF"))) { + val = 0; + } else if(!strcmp(value, "1") || !stricmp(value, "on") || !stricmp(value, get_language_string(user, "NS_SET_ON"))) { + val = 1; + } else { + reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", value); + return 0; + } + if(val != ((bot[0] && !strcmp(bot[0], "1")) ? 1 : 0)) { + if(val) { + //add the bot + struct ClientSocket *client; + client = create_socket(bot[2], atoi(bot[3]), bot[11], bot[4], bot[1], bot[12], bot[13]); + client->flags |= (strcmp(bot[6], "0") ? SOCKET_FLAG_PREFERRED : 0); + client->flags |= (strcmp(bot[7], "0") ? SOCKET_FLAG_USE_QUEUE : 0); + client->flags |= (strcmp(bot[14], "0") ? SOCKET_FLAG_SSL : 0); + client->botid = atoi(bot[5]); + client->clientid = atoi(bot[15]); + connect_socket(client); + } else { + //remove the bot + struct ClientSocket *client; + for(client = getBots(0, NULL); client; client = getBots(0, client)) { + if(client->clientid == atoi(bot[15])) { + close_socket(client); + break; + } + } + } + printf_mysql_query("UPDATE `bots` SET `active` = '%d' WHERE `id` = '%s'", val, bot[15]); + ret = 1; + } + } + reply(getTextBot(), user, "\002ACTIVE \002 %s", get_language_string(user, (val ? "NS_SET_ON" : "NS_SET_OFF"))); + return ret; +} + +static int global_cmd_setbot_nick(struct UserNode *user, MYSQL_ROW bot, char *value) { + char *val = bot[1]; + int ret = 0; + if(value) { + if(!is_valid_nick(value)) { + reply(getTextBot(), user, "NS_SETBOT_NICK_INVALID", value); + return 0; + } + //rename the bot + struct ClientSocket *client; + for(client = getBots(0, NULL); client; client = getBots(0, client)) { + if(client->clientid == atoi(bot[15])) { + if(client->nick) + free(client->nick); + client->nick = strdup(value); + if(client->flags & SOCKET_FLAG_READY) + putsock(client, "NICK %s", value); + break; + } + } + printf_mysql_query("UPDATE `bots` SET `nick` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]); + val = value; + ret = 1; + } + reply(getTextBot(), user, "\002NICK \002 %s", val); + return ret; +} + +static int global_cmd_setbot_ident(struct UserNode *user, MYSQL_ROW bot, char *value) { + char *val = bot[12]; + int ret = 0; + if(value) { + if(strlen(value) > 12) + value[12] = '\0'; + //rename the bot + struct ClientSocket *client; + for(client = getBots(0, NULL); client; client = getBots(0, client)) { + if(client->clientid == atoi(bot[15])) { + if(client->ident) + free(client->ident); + client->ident = strdup(value); + break; + } + } + printf_mysql_query("UPDATE `bots` SET `ident` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]); + val = value; + ret = 1; + } + reply(getTextBot(), user, "\002IDENT \002 %s", val); + return ret; +} + +static int global_cmd_setbot_realname(struct UserNode *user, MYSQL_ROW bot, char *value) { + char *val = bot[13]; + int ret = 0; + if(value) { + if(strlen(value) > 255) + value[255] = '\0'; + //rename the bot + struct ClientSocket *client; + for(client = getBots(0, NULL); client; client = getBots(0, client)) { + if(client->clientid == atoi(bot[15])) { + if(client->ident) + free(client->ident); + client->ident = strdup(value); + break; + } + } + printf_mysql_query("UPDATE `bots` SET `realname` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]); + val = value; + ret = 1; + } + reply(getTextBot(), user, "\002REALNAME \002 %s", val); + return ret; +} + +static int global_cmd_setbot_server(struct UserNode *user, MYSQL_ROW bot, char *value) { + char *val = bot[2]; + int ret = 0; + if(value) { + struct ClientSocket *client; + for(client = getBots(0, NULL); client; client = getBots(0, client)) { + if(client->clientid == atoi(bot[15])) { + if(client->host) + free(client->host); + client->host = strdup(value); + if(client->flags & SOCKET_FLAG_READY) + reply(getTextBot(), user, "NS_SETBOT_NEED_RESTART"); + break; + } + } + printf_mysql_query("UPDATE `bots` SET `server` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]); + val = value; + ret = 1; + } + reply(getTextBot(), user, "\002SERVER \002 %s", val); + return ret; +} + +static int global_cmd_setbot_port(struct UserNode *user, MYSQL_ROW bot, char *value) { + int val = atoi(bot[3]); + int ret = 0; + if(value) { + val = atoi(value); + if(val <= 0 || val > 65534) { + reply(getTextBot(), user, "NS_SETBOT_PORT_INVALID", value); + return 0; + } + struct ClientSocket *client; + for(client = getBots(0, NULL); client; client = getBots(0, client)) { + if(client->clientid == atoi(bot[15])) { + client->port = val; + if(client->flags & SOCKET_FLAG_READY) + reply(getTextBot(), user, "NS_SETBOT_NEED_RESTART"); + break; + } + } + printf_mysql_query("UPDATE `bots` SET `port` = '%d' WHERE `id` = '%s'", val, bot[15]); + ret = 1; + } + reply(getTextBot(), user, "\002PORT \002 %d", val); + return ret; +} + +static int global_cmd_setbot_bind(struct UserNode *user, MYSQL_ROW bot, char *value) { + char *val = bot[11]; + int ret = 0; + if(value) { + if(!strcmp(value, "*")) + value = NULL; + struct ClientSocket *client; + for(client = getBots(0, NULL); client; client = getBots(0, client)) { + if(client->clientid == atoi(bot[15])) { + if(client->bind) + free(client->bind); + client->bind = (value ? strdup(value) : NULL); + if(client->flags & SOCKET_FLAG_READY) + reply(getTextBot(), user, "NS_SETBOT_NEED_RESTART"); + break; + } + } + if(value) + printf_mysql_query("UPDATE `bots` SET `bind` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]); + else + printf_mysql_query("UPDATE `bots` SET `bind` = NULL WHERE `id` = '%s'", bot[15]); + val = value; + ret = 1; + } + reply(getTextBot(), user, "\002BIND \002 %s", val); + return ret; +} + +static int global_cmd_setbot_ssl(struct UserNode *user, MYSQL_ROW bot, char *value) { + int val = (strcmp(bot[14], "0") ? 1 : 0); + int ret = 0; + if(value) { + if(!strcmp(value, "0") || !stricmp(value, "off") || !stricmp(value, get_language_string(user, "NS_SET_OFF"))) { + val = 0; + } else if(!strcmp(value, "1") || !stricmp(value, "on") || !stricmp(value, get_language_string(user, "NS_SET_ON"))) { + val = 1; + } else { + reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", value); + return 0; + } + struct ClientSocket *client; + for(client = getBots(0, NULL); client; client = getBots(0, client)) { + if(client->clientid == atoi(bot[15])) { + if(val) + client->flags |= SOCKET_FLAG_SSL; + else + client->flags &= ~SOCKET_FLAG_SSL; + if(client->flags & SOCKET_FLAG_READY) + reply(getTextBot(), user, "NS_SETBOT_NEED_RESTART"); + break; + } + } + printf_mysql_query("UPDATE `bots` SET `ssl` = '%d' WHERE `id` = '%s'", val, bot[15]); + ret = 1; + } + reply(getTextBot(), user, "\002SSL \002 %s", get_language_string(user, (val ? "NS_SET_ON" : "NS_SET_OFF"))); + return ret; +} + +static int global_cmd_setbot_serverpass(struct UserNode *user, MYSQL_ROW bot, char *value) { + char *val = bot[4]; + int ret = 0; + if(value) { + struct ClientSocket *client; + for(client = getBots(0, NULL); client; client = getBots(0, client)) { + if(client->clientid == atoi(bot[15])) { + if(client->pass) + free(client->pass); + client->pass = strdup(value); + if(client->flags & SOCKET_FLAG_READY) + reply(getTextBot(), user, "NS_SETBOT_NEED_RESTART"); + break; + } + } + printf_mysql_query("UPDATE `bots` SET `pass` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]); + val = value; + ret = 1; + } + reply(getTextBot(), user, "\002SERVERPASS \002 %s", val); + return ret; +} + +static int global_cmd_setbot_class(struct UserNode *user, MYSQL_ROW bot, char *value) { + int val = atoi(bot[5]); + int ret = 0; + if(value) { + if((val = resolve_botalias(value)) != -1) { + reply(getTextBot(), user, "NS_SETBOT_INVALID_CLASS", value); + return 0; + } + if(val != atoi(bot[5])) { + struct ClientSocket *client; + for(client = getBots(0, NULL); client; client = getBots(0, client)) { + if(client->clientid == atoi(bot[15])) { + unbind_botwise_allcmd(client->clientid); + client->botid = val; + if(client->botid == 0) { + MYSQL_RES *res; + MYSQL_ROW row; + printf_mysql_query("SELECT `command`, `function`, `parameters`, `global_access`, `chan_access` FROM `bot_binds` WHERE `botclass` = '0' AND `botid` = '%d'", client->clientid); + res = mysql_use(); + while ((row = mysql_fetch_row(res)) != NULL) { + if(bind_botwise_cmd_to_command(client->botid, client->clientid, row[0], row[1])) { + if(row[2] && strcmp(row[2], "")) { + bind_botwise_set_parameters(client->botid, client->clientid, row[0], row[2]); + } + if(row[3]) { + bind_botwise_set_global_access(client->botid, client->clientid, row[0], atoi(row[3])); + } + if(row[4]) { + bind_botwise_set_channel_access(client->botid, client->clientid, row[0], row[4]); + } + } + } + bind_botwise_unbound_required_functions(client->botid, client->clientid); + } + break; + } + } + printf_mysql_query("UPDATE `bots` SET `botclass` = '%d' WHERE `id` = '%s'", val, bot[15]); + ret = 1; + } + } + reply(getTextBot(), user, "\002BOTCLASS \002 %s", resolve_botid(val)); + return ret; +} + +static int global_cmd_setbot_queue(struct UserNode *user, MYSQL_ROW bot, char *value) { + int val = (strcmp(bot[7], "0") ? 1 : 0); + int ret = 0; + if(value) { + if(!strcmp(value, "0") || !stricmp(value, "off") || !stricmp(value, get_language_string(user, "NS_SET_OFF"))) { + val = 0; + } else if(!strcmp(value, "1") || !stricmp(value, "on") || !stricmp(value, get_language_string(user, "NS_SET_ON"))) { + val = 1; + } else { + reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", value); + return 0; + } + struct ClientSocket *client; + for(client = getBots(0, NULL); client; client = getBots(0, client)) { + if(client->clientid == atoi(bot[15])) { + if(val) + client->flags |= SOCKET_FLAG_USE_QUEUE; + else + client->flags &= ~SOCKET_FLAG_USE_QUEUE; + break; + } + } + printf_mysql_query("UPDATE `bots` SET `queue` = '%d' WHERE `id` = '%s'", val, bot[15]); + ret = 1; + } + reply(getTextBot(), user, "\002QUEUE \002 %s", get_language_string(user, (val ? "NS_SET_ON" : "NS_SET_OFF"))); + return ret; +} + +static int global_cmd_setbot_prefered(struct UserNode *user, MYSQL_ROW bot, char *value) { + int val = (strcmp(bot[6], "0") ? 1 : 0); + int ret = 0; + if(value) { + if(!strcmp(value, "0") || !stricmp(value, "off") || !stricmp(value, get_language_string(user, "NS_SET_OFF"))) { + val = 0; + } else if(!strcmp(value, "1") || !stricmp(value, "on") || !stricmp(value, get_language_string(user, "NS_SET_ON"))) { + val = 1; + } else { + reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", value); + return 0; + } + struct ClientSocket *client; + for(client = getBots(0, NULL); client; client = getBots(0, client)) { + if(client->clientid == atoi(bot[15])) { + if(val) + client->flags |= SOCKET_FLAG_PREFERRED; + else + client->flags &= ~SOCKET_FLAG_PREFERRED; + break; + } + } + printf_mysql_query("UPDATE `bots` SET `queue` = '%d' WHERE `id` = '%s'", val, bot[15]); + ret = 1; + } + reply(getTextBot(), user, "\002PREFERED \002 %s", get_language_string(user, (val ? "NS_SET_ON" : "NS_SET_OFF"))); + return ret; +} + +static int global_cmd_setbot_maxchan(struct UserNode *user, MYSQL_ROW bot, char *value) { + int val = atoi(bot[9]); + int ret = 0; + if(value) { + val = atoi(value); + if(val < 0 || val > 99999) { + reply(getTextBot(), user, "NS_SETBOT_MAXCHAN_INVALID", value); + return 0; + } + printf_mysql_query("UPDATE `bots` SET `maxchan` = '%d' WHERE `id` = '%s'", val, bot[15]); + ret = 1; + } + reply(getTextBot(), user, "\002MAXCHAN \002 %d", val); + return ret; +} + +static int global_cmd_setbot_priority(struct UserNode *user, MYSQL_ROW bot, char *value) { + int val = atoi(bot[10]); + int ret = 0; + if(value) { + val = atoi(value); + if(val < 0 || val > 99) { + reply(getTextBot(), user, "NS_SETBOT_PRIORITY_INVALID", value); + return 0; + } + printf_mysql_query("UPDATE `bots` SET `register_priority` = '%d' WHERE `id` = '%s'", val, bot[15]); + ret = 1; + } + reply(getTextBot(), user, "\002PRIORITY \002 %d", val); + return ret; +} + +static int global_cmd_setbot_trigger(struct UserNode *user, MYSQL_ROW bot, char *value) { + char *val = bot[8]; + int ret = 0; + if(value) { + if(!*value || strlen(value) > 10) { + reply(getTextBot(), user, "NS_SETBOT_TRIGGER_INVALID", value); + return 0; + } + printf_mysql_query("UPDATE `bots` SET `defaulttrigger` = '%s' WHERE `id` = '%s'", escape_string(value), bot[15]); + reply(getTextBot(), user, "NS_SETBOT_TRIGGER_NOTE"); + val = value; + ret = 1; + } + reply(getTextBot(), user, "\002TRIGGER \002 %s", val); + return ret; +} diff --git a/src/commands.c b/src/commands.c index 548cb4c..6d59818 100644 --- a/src/commands.c +++ b/src/commands.c @@ -47,10 +47,11 @@ void register_commands() { OPER_COMMAND("bind", global_cmd_bind, 2, 900, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG | CMDFLAG_REQUIRED | CMDFLAG_ESCAPE_ARGS); OPER_COMMAND("unbind", global_cmd_unbind, 1, 900, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG | CMDFLAG_REQUIRED | CMDFLAG_ESCAPE_ARGS); OPER_COMMAND("setaccess", global_cmd_setaccess, 2, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG); - OPER_COMMAND("bots", global_cmd_bots, 0, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH); + OPER_COMMAND("bots", global_cmd_bots, 0, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_REQUIRED); OPER_COMMAND("reload", global_cmd_reload, 0, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG); OPER_COMMAND("restart", global_cmd_restart, 0, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG); OPER_COMMAND("die", global_cmd_die, 0, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG); + OPER_COMMAND("setbot", global_cmd_setbot, 1, 1000, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_OPLOG | CMDFLAG_REQUIRED); #undef OPER_COMMAND //NeonServ Commands diff --git a/src/modcmd.c b/src/modcmd.c index 9846db2..058612a 100644 --- a/src/modcmd.c +++ b/src/modcmd.c @@ -704,6 +704,8 @@ int unbind_botwise_cmd(int botid, int clientid, char *cmd) { for(i = 0; i < cbind->paramcount; i++) free(cbind->parameters[i]); } + if(cbind->channel_access) + free(cbind->channel_access); free(cbind); return 1; } else @@ -712,6 +714,33 @@ int unbind_botwise_cmd(int botid, int clientid, char *cmd) { return 0; } +int unbind_botwise_allcmd(int clientid) { + int i; + for(i = 0; i < 27; i++) { + struct cmd_binding *cbind, *next, *last = NULL; + for(cbind = cmd_binds[i]; cbind; cbind = next) { + next = cbind->next; + if(clientid == cbind->clientid) { + if(last) + last->next = cbind->next; + else + cmd_binds[i] = cbind->next; + free(cbind->cmd); + if(cbind->paramcount) { + int j; + for(j = 0; j < cbind->paramcount; j++) + free(cbind->parameters[j]); + } + if(cbind->channel_access) + free(cbind->channel_access); + free(cbind); + } else + last = cbind; + } + } + return 1; +} + struct cmd_function *find_cmd_function(int botid, char *name) { struct cmd_function *cmdfunc; char *c; diff --git a/src/modcmd.h b/src/modcmd.h index fdc2965..52c272c 100644 --- a/src/modcmd.h +++ b/src/modcmd.h @@ -103,6 +103,8 @@ int bind_botwise_cmd_to_command(int botid, int clientid, char *cmd, char *func); #define unbind_cmd(BOTID,CMD) unbind_botwise_cmd(BOTID, 0, CMD) int unbind_botwise_cmd(int botid, int clientid, char *cmd); +int unbind_botwise_allcmd(int clientid); + #define bind_set_parameters(BOTID,CMD,PARAMETERS) bind_botwise_set_parameters(BOTID, 0, CMD, PARAMETERS) void bind_botwise_set_parameters(int botid, int clientid, char *cmd, char *parameters); -- 2.20.1