From f80fa658483884289cf2585790b1cf64ef722197 Mon Sep 17 00:00:00 2001 From: pk910 Date: Wed, 14 Dec 2011 15:47:25 +0100 Subject: [PATCH] added support for independent "zero-bots" (bots without an own source file) --- database.upgrade.sql | 5 +++ src/bot_DummyServ.c | 2 +- src/bot_NeonHelp.c | 2 +- src/bot_NeonServ.c | 2 +- src/bot_NeonSpam.c | 2 +- src/bots.c | 55 +++++++++++++++++++++++++++ src/cmd_global_bind.c | 11 ++++-- src/cmd_global_command.c | 2 +- src/cmd_global_commands.c | 4 +- src/cmd_global_unbind.c | 14 +++++-- src/modcmd.c | 78 +++++++++++++++++++++------------------ src/modcmd.h | 47 +++++++++++++++++------ src/mysqlConn.c | 2 +- 13 files changed, 162 insertions(+), 64 deletions(-) diff --git a/database.upgrade.sql b/database.upgrade.sql index cb710fd..84e9aeb 100644 --- a/database.upgrade.sql +++ b/database.upgrade.sql @@ -83,3 +83,8 @@ ALTER TABLE `fundata` ADD INDEX ( `user` ); ALTER TABLE `fundata` ADD INDEX ( `name` ); -- version: 7 + +ALTER TABLE `bot_binds` ADD `botid` INT( 11 ) NOT NULL AFTER `botclass`; +ALTER TABLE `bot_binds` ADD INDEX ( `botclass` ); + +-- version: 8 \ No newline at end of file diff --git a/src/bot_DummyServ.c b/src/bot_DummyServ.c index e9ae76b..b6605d5 100644 --- a/src/bot_DummyServ.c +++ b/src/bot_DummyServ.c @@ -59,7 +59,7 @@ static void dummyserv_bot_ready(struct ClientSocket *client) { } } -static void dummyserv_trigger_callback(struct ChanNode *chan, char *trigger) { +static void dummyserv_trigger_callback(int clientid, struct ChanNode *chan, char *trigger) { //this bot doesn't have a trigger strcpy(trigger, ""); } diff --git a/src/bot_NeonHelp.c b/src/bot_NeonHelp.c index aa75426..a3ea7d1 100644 --- a/src/bot_NeonHelp.c +++ b/src/bot_NeonHelp.c @@ -49,7 +49,7 @@ static void neonhelp_bot_ready(struct ClientSocket *client) { } } -static void neonhelp_trigger_callback(struct ChanNode *chan, char *trigger) { +static void neonhelp_trigger_callback(int clientid, struct ChanNode *chan, char *trigger) { MYSQL_RES *res; MYSQL_ROW row; loadChannelSettings(chan); diff --git a/src/bot_NeonServ.c b/src/bot_NeonServ.c index 785de6f..613487a 100644 --- a/src/bot_NeonServ.c +++ b/src/bot_NeonServ.c @@ -390,7 +390,7 @@ static void neonserv_bot_ready(struct ClientSocket *client) { } } -static void neonserv_trigger_callback(struct ChanNode *chan, char *trigger) { +static void neonserv_trigger_callback(int clientid, struct ChanNode *chan, char *trigger) { MYSQL_RES *res; MYSQL_ROW row; loadChannelSettings(chan); diff --git a/src/bot_NeonSpam.c b/src/bot_NeonSpam.c index 9d5ea64..bd25010 100644 --- a/src/bot_NeonSpam.c +++ b/src/bot_NeonSpam.c @@ -132,7 +132,7 @@ static void neonspam_bot_ready(struct ClientSocket *client) { } } -static void neonspam_trigger_callback(struct ChanNode *chan, char *trigger) { +static void neonspam_trigger_callback(int clientid, struct ChanNode *chan, char *trigger) { MYSQL_RES *res; MYSQL_ROW row; loadChannelSettings(chan); diff --git a/src/bots.c b/src/bots.c index aece825..d8de4ee 100644 --- a/src/bots.c +++ b/src/bots.c @@ -23,6 +23,8 @@ #include "ChanNode.h" #include "ChanUser.h" #include "version.h" +#include "modcmd.h" +#include "DBHelper.h" #include "bot_NeonServ.h" #include "bot_NeonSpam.h" @@ -37,12 +39,65 @@ struct cmd_bot_alias { static struct cmd_bot_alias *bot_aliases = NULL; +static void start_zero_bots() { + struct ClientSocket *client; + MYSQL_RES *res, *res2; + MYSQL_ROW row; + + printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind` FROM `bots` WHERE `botclass` = '0' AND `active` = '1'"); + res = mysql_use(); + + while ((row = mysql_fetch_row(res)) != NULL) { + client = create_socket(row[3], atoi(row[4]), row[10], row[5], row[0], row[1], row[2]); + client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0); + client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0); + client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0); + client->botid = 0; + client->clientid = atoi(row[7]); + connect_socket(client); + + printf_mysql_query("SELECT `command`, `function`, `parameters`, `global_access`, `chan_access` FROM `bot_binds` WHERE `botclass` = '0' AND `botid` = '%d'", client->clientid); + res2 = mysql_use(); + while ((row = mysql_fetch_row(res2)) != NULL) { + if(bind_botwise_cmd_to_command(0, client->clientid, row[0], row[1])) { + if(row[2] && strcmp(row[2], "")) { + bind_botwise_set_parameters(0, client->clientid, row[0], row[2]); + } + if(row[3]) { + bind_botwise_set_global_access(0, client->clientid, row[0], atoi(row[3])); + } + if(row[4]) { + bind_botwise_set_channel_access(0, client->clientid, row[0], row[4]); + } + } + } + bind_botwise_unbound_required_functions(0, client->clientid); + } +} + +static void zero_bots_trigger_callback(int clientid, struct ChanNode *chan, char *trigger) { + MYSQL_RES *res; + MYSQL_ROW row; + loadChannelSettings(chan); + if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) { + strcpy(trigger, "+"); + return; + } + printf_mysql_query("SELECT `trigger` FROM `bot_channels` LEFT JOIN `bots` ON `botid` = `bots`.`id` WHERE `chanid` = '%d' AND `botclass` = '0' AND `botid` = '%d'", chan->channel_id, clientid); + res = mysql_use(); + row = mysql_fetch_row(res); + strcpy(trigger, (strlen(row[0]) ? row[0] : "+")); +} + void init_bots() { init_NeonServ(); init_NeonSpam(); init_DummyServ(); init_NeonHelp(); + start_zero_bots(); + set_trigger_callback(0, zero_bots_trigger_callback); + MYSQL_RES *res; MYSQL_ROW row; //load all timed bans diff --git a/src/cmd_global_bind.c b/src/cmd_global_bind.c index 19e3599..4b5cc89 100644 --- a/src/cmd_global_bind.c +++ b/src/cmd_global_bind.c @@ -26,7 +26,10 @@ CMD_BIND(global_cmd_bind) { MYSQL_RES *res; MYSQL_ROW row; - printf_mysql_query("SELECT `function` FROM `bot_binds` WHERE `botclass` = '%d' AND `command` = '%s'", client->botid, escape_string(argv[0])); + if(client->botid == 0) + printf_mysql_query("SELECT `function` FROM `bot_binds` WHERE `botclass` = '%d' AND `botid` = '%d' AND `command` = '%s'", client->botid, client->clientid, escape_string(argv[0])); + else + printf_mysql_query("SELECT `function` FROM `bot_binds` WHERE `botclass` = '%d' AND `command` = '%s'", client->botid, escape_string(argv[0])); res = mysql_use(); if ((row = mysql_fetch_row(res)) != NULL) { reply(getTextBot(), user, "NS_BIND_ALREADY", argv[0], row[0]); @@ -42,10 +45,10 @@ CMD_BIND(global_cmd_bind) { reply(getTextBot(), user, "NS_BIND_UNKNOWN", argv[1]); return; } - bind_cmd_to_function(client->botid, argv[0], function); - printf_mysql_query("INSERT INTO `bot_binds` (`botclass`, `command`, `function`, `parameters`) VALUES ('%d', '%s', '%s', '%s')", client->botid, escape_string(argv[0]), escape_string(argv[1]), params); + bind_botwise_cmd_to_function(client->botid, client->clientid, argv[0], function); + printf_mysql_query("INSERT INTO `bot_binds` (`botclass`, `botid`, `command`, `function`, `parameters`) VALUES ('%d', '%d', '%s', '%s', '%s')", client->botid, (client->botid == 0 ? client->clientid : 0), escape_string(argv[0]), escape_string(argv[1]), params); if(*params) - bind_set_parameters(client->botid, argv[0], params); + bind_botwise_set_parameters(client->botid, client->clientid, argv[0], params); reply(getTextBot(), user, "NS_BIND_DONE", argv[0], function->name); logEvent(event); } diff --git a/src/cmd_global_command.c b/src/cmd_global_command.c index 1382296..8ed615d 100644 --- a/src/cmd_global_command.c +++ b/src/cmd_global_command.c @@ -27,7 +27,7 @@ CMD_BIND(global_cmd_command) { char *ident; MYSQL_RES *res; MYSQL_ROW row; - struct cmd_binding *cbind = find_cmd_binding(client->botid, argv[0]); + struct cmd_binding *cbind = find_botwise_cmd_binding(client->botid, client->clientid, argv[0]); if (!cbind) { reply(getTextBot(), user, "NS_UNBIND_NOT_FOUND", argv[0]); return; diff --git a/src/cmd_global_commands.c b/src/cmd_global_commands.c index e0cfba0..4008574 100644 --- a/src/cmd_global_commands.c +++ b/src/cmd_global_commands.c @@ -29,13 +29,13 @@ CMD_BIND(global_cmd_commands) { struct cmd_binding *cbind; int bindcount = 0; for(cbind = getAllBinds(NULL); cbind; cbind = getAllBinds(cbind)) { - if(cbind->botid == client->botid && !(cbind->func->flags & CMDFLAG_FUNCMD)) + if(cbind->botid == client->botid && (cbind->botid || cbind->clientid == client->clientid) && !(cbind->func->flags & CMDFLAG_FUNCMD)) bindcount++; } struct cmd_binding *binds[bindcount]; bindcount = 0; for(cbind = getAllBinds(NULL); cbind; cbind = getAllBinds(cbind)) { - if(cbind->botid == client->botid && !(cbind->func->flags & CMDFLAG_FUNCMD)) + if(cbind->botid == client->botid && (cbind->botid || cbind->clientid == client->clientid) && !(cbind->func->flags & CMDFLAG_FUNCMD)) binds[bindcount++] = cbind; } qsort(binds, bindcount, sizeof(struct cmd_binding *), global_cmd_commands_sort); diff --git a/src/cmd_global_unbind.c b/src/cmd_global_unbind.c index f4940d3..c83a387 100644 --- a/src/cmd_global_unbind.c +++ b/src/cmd_global_unbind.c @@ -24,8 +24,11 @@ CMD_BIND(global_cmd_unbind) { MYSQL_RES *res; MYSQL_ROW row; - struct cmd_binding *cbind = find_cmd_binding(client->botid, argv[0]); - printf_mysql_query("SELECT `id`, `function` FROM `bot_binds` WHERE `botclass` = '%d' AND `command` = '%s'", client->botid, escape_string(argv[0])); + struct cmd_binding *cbind = find_botwise_cmd_binding(client->botid, client->clientid, argv[0]); + if(client->botid == 0) + printf_mysql_query("SELECT `id`, `function` FROM `bot_binds` WHERE `botclass` = '0' AND `botid` = '%d' AND `command` = '%s'", client->clientid, escape_string(argv[0])); + else + printf_mysql_query("SELECT `id`, `function` FROM `bot_binds` WHERE `botclass` = '%d' AND `command` = '%s'", client->botid, escape_string(argv[0])); res = mysql_use(); if ((row = mysql_fetch_row(res)) == NULL && (!cbind || !(cbind->flags & CMDFLAG_TEMPONARY_BIND))) { reply(getTextBot(), user, "NS_UNBIND_NOT_FOUND", argv[0]); @@ -33,14 +36,17 @@ CMD_BIND(global_cmd_unbind) { } struct cmd_function *function = find_cmd_function(client->botid, row[1]); if(function && (function->flags & CMDFLAG_REQUIRED)) { - printf_mysql_query("SELECT `id` FROM `bot_binds` WHERE `botclass` = '%d' AND `function` = '%s'", client->botid, escape_string(function->name)); + if(client->botid == 0) + printf_mysql_query("SELECT `id` FROM `bot_binds` WHERE `botclass` = '0' AND `botid` = '%d' AND `function` = '%s'", client->clientid, escape_string(function->name)); + else + printf_mysql_query("SELECT `id` FROM `bot_binds` WHERE `botclass` = '%d' AND `function` = '%s'", client->botid, escape_string(function->name)); res = mysql_use(); if (mysql_num_rows(res) <= 1) { reply(getTextBot(), user, "NS_UNBIND_REQUIRED", function->name); return; } } - unbind_cmd(client->botid, argv[0]); + unbind_botwise_cmd(client->botid, client->clientid, argv[0]); if(!cbind || !(cbind->flags & CMDFLAG_TEMPONARY_BIND)) printf_mysql_query("DELETE FROM `bot_binds` WHERE `id` = '%s'", row[0]); reply(getTextBot(), user, "NS_UNBIND_DONE", argv[0]); diff --git a/src/modcmd.c b/src/modcmd.c index 420567f..50f71c8 100644 --- a/src/modcmd.c +++ b/src/modcmd.c @@ -80,10 +80,10 @@ static int get_binds_index(char first_char) { return 26; } -struct ClientSocket* get_prefered_bot(int botid) { +struct ClientSocket* get_botwise_prefered_bot(int botid, int clientid) { struct ClientSocket *client, *lowbot = NULL; for(client = getBots(SOCKET_FLAG_READY, NULL); client; client = getBots(SOCKET_FLAG_READY, client)) { - if(client->botid == botid) { + if(client->botid == botid && (botid || clientid == client->clientid)) { if((client->flags & SOCKET_FLAG_PREFERRED)) return client; else @@ -93,10 +93,10 @@ struct ClientSocket* get_prefered_bot(int botid) { return lowbot; } -static char* get_channel_trigger(int botid, struct ChanNode *chan) { +static char* get_channel_trigger(int botid, int clientid, struct ChanNode *chan) { struct trigger_cache *trigger; for(trigger = chan->trigger; trigger; trigger = trigger->next) { - if(trigger->botid == botid) + if(trigger->botid == botid && (botid || trigger->clientid == clientid)) return trigger->trigger; } struct trigger_callback *cb; @@ -106,15 +106,16 @@ static char* get_channel_trigger(int botid, struct ChanNode *chan) { } char triggerStr[TRIGGERLEN]; if(cb) - cb->func(chan, triggerStr); + cb->func(clientid, chan, triggerStr); else - strcpy(triggerStr, "+"); + triggerStr[0] = '\0'; trigger = malloc(sizeof(*trigger)); if (!trigger) { perror("malloc() failed"); return 0; } trigger->botid = botid; + trigger->clientid = clientid; trigger->trigger = (triggerStr[0] ? strdup(triggerStr) : NULL); trigger->next = chan->trigger; chan->trigger = trigger; @@ -161,7 +162,7 @@ static void handle_command(struct ClientSocket *client, struct UserNode *user, s } struct cmd_binding *cbind; for(cbind = cmd_binds[bind_index]; cbind; cbind = cbind->next) { - if(cbind->botid == client->botid && stricmp(cbind->cmd, message) == 0) { + if(cbind->botid == client->botid && (cbind->botid || cbind->clientid == client->clientid) && stricmp(cbind->cmd, message) == 0) { if(cbind->func->func == modcmd_linker) { //links subcommands char command[MAXLEN]; @@ -175,7 +176,7 @@ static void handle_command(struct ClientSocket *client, struct UserNode *user, s } sprintf(command, "%s %s", parent_bind->cmd, subcmd); for(cbind = cmd_binds[bind_index]; cbind; cbind = cbind->next) { - if(cbind->botid == client->botid && stricmp(cbind->cmd, command) == 0) + if(cbind->botid == client->botid && (cbind->botid || cbind->clientid == client->clientid) && stricmp(cbind->cmd, command) == 0) break; } if(!cbind) @@ -186,7 +187,7 @@ static void handle_command(struct ClientSocket *client, struct UserNode *user, s char subcommands[MAXLEN]; int subcompos = 0; for(cbind = cmd_binds[bind_index]; cbind; cbind = cbind->next) { - if(cbind->botid == client->botid && stricmplen(cbind->cmd, command, commandlen) == 0) { + if(cbind->botid == client->botid && (cbind->botid || cbind->clientid == client->clientid) && stricmplen(cbind->cmd, command, commandlen) == 0) { subcompos += sprintf(subcommands + subcompos, (subcompos ? ", %s" : "%s"), cbind->cmd + commandlen); } } @@ -204,7 +205,7 @@ static void handle_command(struct ClientSocket *client, struct UserNode *user, s chan = sent_chan; } //get a text bot - tmp_text_client = get_prefered_bot(client->botid); + tmp_text_client = get_botwise_prefered_bot(client->botid, (client->botid == 0 ? client->clientid : 0)); //parse the arguments... char *arga[MAXNUMPARAMS]; char **argv; @@ -511,23 +512,26 @@ static void handle_command_async(struct ClientSocket *client, struct UserNode *u } static void got_chanmsg(struct UserNode *user, struct ChanNode *chan, char *message) { - fd_set fds; + fd_set fds, fds2; char *trigger; struct ClientSocket *client; FD_ZERO(&fds); + FD_ZERO(&fds2); for(client = getBots(SOCKET_FLAG_READY, NULL); client; client = getBots(SOCKET_FLAG_READY, client)) { - if(isUserOnChan(client->user, chan) && (client->flags & SOCKET_FLAG_PREFERRED) && !FD_ISSET(client->botid, &fds)) { - FD_SET(client->botid, &fds); - trigger = get_channel_trigger(client->botid, chan); + if(isUserOnChan(client->user, chan) && (client->flags & SOCKET_FLAG_PREFERRED) && ((client->botid == 0 && !FD_ISSET(client->clientid, &fds)) || (client->botid && !FD_ISSET(client->botid, &fds2)))) { + FD_SET(client->clientid, &fds); + FD_SET(client->botid, &fds2); + trigger = get_channel_trigger(client->botid, client->clientid, chan); if(trigger && stricmplen(message, trigger, strlen(trigger)) == 0) { handle_command(client, user, chan, message + strlen(trigger)); } } } for(client = getBots(SOCKET_FLAG_READY, NULL); client; client = getBots(SOCKET_FLAG_READY, client)) { - if(isUserOnChan(client->user, chan) && !FD_ISSET(client->botid, &fds)) { + if(isUserOnChan(client->user, chan) && ((client->botid == 0 && !FD_ISSET(client->clientid, &fds)) || (client->botid && !FD_ISSET(client->botid, &fds2)))) { FD_SET(client->botid, &fds); - trigger = get_channel_trigger(client->botid, chan); + FD_SET(client->botid, &fds2); + trigger = get_channel_trigger(client->botid, client->clientid, chan); if(trigger && stricmplen(message, trigger, strlen(trigger)) == 0) { handle_command(client, user, chan, message + strlen(trigger)); } @@ -587,10 +591,10 @@ int set_trigger_callback(int botid, trigger_callback_t *func) { return 1; } -int changeChannelTrigger(int botid, struct ChanNode *chan, char *new_trigger) { +int changeBotwiseChannelTrigger(int botid, int clientid, struct ChanNode *chan, char *new_trigger) { struct trigger_cache *trigger; for(trigger = chan->trigger; trigger; trigger = trigger->next) { - if(trigger->botid == botid) { + if(trigger->botid == botid && (botid || trigger->clientid == clientid)) { free(trigger->trigger); trigger->trigger = strdup(new_trigger); return 1; @@ -599,11 +603,11 @@ int changeChannelTrigger(int botid, struct ChanNode *chan, char *new_trigger) { return 0; } -int bind_cmd_to_function(int botid, char *cmd, struct cmd_function *func) { +int bind_botwise_cmd_to_function(int botid, int clientid, char *cmd, struct cmd_function *func) { int bind_index = get_binds_index(cmd[0]); struct cmd_binding *cbind; for(cbind = cmd_binds[bind_index]; cbind; cbind = cbind->next) { - if(cbind->botid == botid && strcmp(cbind->cmd, cmd) == 0) + if(((botid && cbind->botid == botid) || (botid == 0 && clientid == cbind->clientid)) && strcmp(cbind->cmd, cmd) == 0) return 0; } cbind = malloc(sizeof(*cbind)); @@ -612,6 +616,7 @@ int bind_cmd_to_function(int botid, char *cmd, struct cmd_function *func) { return 0; } cbind->botid = botid; + cbind->clientid = clientid; cbind->cmd = strdup(cmd); cbind->func = func; cbind->paramcount = 0; @@ -624,7 +629,7 @@ int bind_cmd_to_function(int botid, char *cmd, struct cmd_function *func) { return 1; } -int bind_cmd_to_command(int botid, char *cmd, char *func) { +int bind_botwise_cmd_to_command(int botid, int clientid, char *cmd, char *func) { struct cmd_function *cmdfunc; int fbotid = botid; char *c; @@ -648,7 +653,7 @@ int bind_cmd_to_command(int botid, char *cmd, char *func) { int bind_index = get_binds_index(cmd[0]); struct cmd_binding *cbind; for(cbind = cmd_binds[bind_index]; cbind; cbind = cbind->next) { - if(cbind->botid == botid && strcmp(cbind->cmd, cmd) == 0) + if(((botid && cbind->botid == botid) || (botid == 0 && clientid == cbind->clientid)) && strcmp(cbind->cmd, cmd) == 0) return 0; } cbind = malloc(sizeof(*cbind)); @@ -657,6 +662,7 @@ int bind_cmd_to_command(int botid, char *cmd, char *func) { return 0; } cbind->botid = botid; + cbind->clientid = clientid; cbind->cmd = strdup(cmd); cbind->func = cmdfunc; cbind->next = cmd_binds[bind_index]; @@ -669,11 +675,11 @@ int bind_cmd_to_command(int botid, char *cmd, char *func) { return 1; } -int unbind_cmd(int botid, char *cmd) { +int unbind_botwise_cmd(int botid, int clientid, char *cmd) { int bind_index = get_binds_index(cmd[0]); struct cmd_binding *cbind, *last = NULL; for(cbind = cmd_binds[bind_index]; cbind; cbind = cbind->next) { - if(cbind->botid == botid && strcmp(cbind->cmd, cmd) == 0) { + if(cbind->botid == botid && (botid || clientid == cbind->clientid) && strcmp(cbind->cmd, cmd) == 0) { if(last) last->next = cbind->next; else @@ -766,11 +772,11 @@ void free_modcmd() { bot_aliases = NULL; } -void bind_set_parameters(int botid, char *cmd, char *parameters) { +void bind_botwise_set_parameters(int botid, int clientid, char *cmd, char *parameters) { int bind_index = get_binds_index(cmd[0]); struct cmd_binding *cbind; for(cbind = cmd_binds[bind_index]; cbind; cbind = cbind->next) { - if(cbind->botid == botid && strcmp(cbind->cmd, cmd) == 0) { + if(cbind->botid == botid && (botid || clientid == cbind->clientid) && strcmp(cbind->cmd, cmd) == 0) { if(cbind->paramcount) { int i; for(i = 0; i < cbind->paramcount; i++) @@ -789,11 +795,11 @@ void bind_set_parameters(int botid, char *cmd, char *parameters) { } } -void bind_set_global_access(int botid, char *cmd, int gaccess) { +void bind_botwise_set_global_access(int botid, int clientid, char *cmd, int gaccess) { int bind_index = get_binds_index(cmd[0]); struct cmd_binding *cbind; for(cbind = cmd_binds[bind_index]; cbind; cbind = cbind->next) { - if(cbind->botid == botid && strcmp(cbind->cmd, cmd) == 0) { + if(cbind->botid == botid && (botid || clientid == cbind->clientid) && strcmp(cbind->cmd, cmd) == 0) { if(gaccess > -1) { cbind->global_access = gaccess; cbind->flags |= CMDFLAG_OVERRIDE_GLOBAL_ACCESS; @@ -805,11 +811,11 @@ void bind_set_global_access(int botid, char *cmd, int gaccess) { } } -void bind_set_channel_access(int botid, char *cmd, char *chanaccess) { +void bind_botwise_set_channel_access(int botid, int clientid, char *cmd, char *chanaccess) { int bind_index = get_binds_index(cmd[0]); struct cmd_binding *cbind; for(cbind = cmd_binds[bind_index]; cbind; cbind = cbind->next) { - if(cbind->botid == botid && strcmp(cbind->cmd, cmd) == 0) { + if(cbind->botid == botid && (botid || clientid == cbind->clientid) && strcmp(cbind->cmd, cmd) == 0) { if(cbind->channel_access) free(cbind->channel_access); if(chanaccess) { @@ -824,18 +830,18 @@ void bind_set_channel_access(int botid, char *cmd, char *chanaccess) { } } -struct cmd_binding *find_cmd_binding(int botid, char *cmd) { +struct cmd_binding *find_botwise_cmd_binding(int botid, int clientid, char *cmd) { int bind_index = get_binds_index(cmd[0]); struct cmd_binding *cbind; for(cbind = cmd_binds[bind_index]; cbind; cbind = cbind->next) { - if(cbind->botid == botid && strcmp(cbind->cmd, cmd) == 0) { + if(cbind->botid == botid && (botid || clientid == cbind->clientid) && strcmp(cbind->cmd, cmd) == 0) { return cbind; } } return NULL; } -void bind_unbound_required_functions(int botid) { +void bind_botwise_unbound_required_functions(int botid, int clientid) { struct cmd_function *cmdfunc; int i, found; struct cmd_binding *cbind; @@ -844,7 +850,7 @@ void bind_unbound_required_functions(int botid) { found = 0; for(i = 0; i < 27; i++) { for(cbind = cmd_binds[i]; cbind; cbind = cbind->next) { - if(cbind->botid == botid && cbind->func == cmdfunc) { + if(cbind->botid == botid && (botid || clientid == cbind->clientid) && cbind->func == cmdfunc) { found = 1; break; } @@ -852,8 +858,8 @@ void bind_unbound_required_functions(int botid) { if(found) break; } - if(!found && bind_cmd_to_function(botid, cmdfunc->name, cmdfunc)) { - cbind = find_cmd_binding(botid, cmdfunc->name); + if(!found && bind_botwise_cmd_to_function(botid, clientid, cmdfunc->name, cmdfunc)) { + cbind = find_botwise_cmd_binding(botid, clientid, cmdfunc->name); cbind->flags |= CMDFLAG_TEMPONARY_BIND; } } diff --git a/src/modcmd.h b/src/modcmd.h index 44333b5..fdc2965 100644 --- a/src/modcmd.h +++ b/src/modcmd.h @@ -43,7 +43,7 @@ struct Event; #define CMD_BIND(NAME) void NAME(UNUSED_ARG(struct ClientSocket *client), UNUSED_ARG(struct UserNode *user), UNUSED_ARG(struct ChanNode *chan), UNUSED_ARG(char **argv), UNUSED_ARG(char argc), UNUSED_ARG(struct Event *event)) typedef void cmd_bind_t(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char **argv, char argc, struct Event *event); -typedef void trigger_callback_t(struct ChanNode *chan, char *trigger); +typedef void trigger_callback_t(int clientid, struct ChanNode *chan, char *trigger); struct cmd_function { char *name; @@ -60,6 +60,7 @@ struct cmd_function { struct cmd_binding { char *cmd; int botid; + int clientid; struct cmd_function *func; unsigned int flags; char *parameters[MAXPARAMETERS]; @@ -73,6 +74,7 @@ struct cmd_binding { struct trigger_cache { int botid; + int clientid; char *trigger; struct trigger_cache *next; @@ -82,21 +84,42 @@ extern int statistics_commands; void init_modcmd(); void free_modcmd(); -struct ClientSocket* get_prefered_bot(int botid); + +#define get_prefered_bot(BOTID) get_botwise_prefered_bot(BOTID, 0) +struct ClientSocket* get_botwise_prefered_bot(int botid, int clientid); + int register_command(int botid, char *name, cmd_bind_t *func, int paramcount, char *channel_access, int global_access, unsigned int flags); int set_trigger_callback(int botid, trigger_callback_t *func); -int changeChannelTrigger(int botid, struct ChanNode *chan, char *new_trigger); -int bind_cmd_to_function(int botid, char *cmd, struct cmd_function *func); -int bind_cmd_to_command(int botid, char *cmd, char *func); -int unbind_cmd(int botid, char *cmd); + +#define changeChannelTrigger(BOTID,CHAN,NEW) changeBotwiseChannelTrigger(BOTID, 0, CHAN, NEW) +int changeBotwiseChannelTrigger(int botid, int clientid, struct ChanNode *chan, char *new_trigger); + +#define bind_cmd_to_function(BOTID,CMD,FUNC) bind_botwise_cmd_to_function(BOTID, 0, CMD, FUNC) +int bind_botwise_cmd_to_function(int botid, int clientid, char *cmd, struct cmd_function *func); + +#define bind_cmd_to_command(BOTID,CMD,FUNC) bind_botwise_cmd_to_command(BOTID, 0, CMD, FUNC) +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); + +#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); + +#define bind_set_global_access(BOTID,CMD,GACCESS) bind_botwise_set_global_access(BOTID, 0, CMD, GACCESS) +void bind_botwise_set_global_access(int botid, int clientid, char *cmd, int gaccess); + +#define bind_set_channel_access(BOTID,CMD,CACCESS) bind_botwise_set_channel_access(BOTID, 0, CMD, CACCESS) +void bind_botwise_set_channel_access(int botid, int clientid, char *cmd, char *chanaccess); + +#define find_cmd_binding(BOTID,CMD) find_botwise_cmd_binding(BOTID, 0, CMD) +struct cmd_binding *find_botwise_cmd_binding(int botid, int clientid, char *cmd); + +#define bind_unbound_required_functions(BOTID) bind_botwise_unbound_required_functions(BOTID, 0) +void bind_botwise_unbound_required_functions(int botid, int clientid); + struct cmd_function *find_cmd_function(int botid, char *name); struct ClientSocket *getTextBot(); -void bind_set_parameters(int botid, char *cmd, char *parameters); -void bind_set_global_access(int botid, char *cmd, int gaccess); -void bind_set_channel_access(int botid, char *cmd, char *chanaccess); -struct cmd_binding *find_cmd_binding(int botid, char *cmd); -void bind_unbound_required_functions(int botid); - void register_command_alias(int botid, char *alias); struct cmd_binding *getAllBinds(struct cmd_binding *last); diff --git a/src/mysqlConn.c b/src/mysqlConn.c index ec27037..3a9ac68 100644 --- a/src/mysqlConn.c +++ b/src/mysqlConn.c @@ -16,7 +16,7 @@ */ #include "mysqlConn.h" -#define DATABASE_VERSION "7" +#define DATABASE_VERSION "8" struct used_result { MYSQL_RES *result; -- 2.20.1