#include "ChanNode.h"
#include "ChanUser.h"
-static void got_chanmsg(struct UserNode *user, struct ChanNode *chan, char *message) {
- struct ClientSocket *client = getBots(SOCKET_FLAG_READY, NULL);
+struct trigger_callback {
+ int botid;
+ trigger_callback_t *func;
+
+ struct trigger_callback *next;
+}
+
+static struct cmd_binding **cmd_binds;
+static struct cmd_function *cmd_functions = NULL;
+static struct trigger_callback *trigger_callbacks = NULL;
+
+static int get_binds_index(char first_char) {
+ if(tolower(first_char) >= 'a' && tolower(first_char) <= 'z') {
+ return tolower(first_char - 'a');
+ }
+ return 26;
+}
+
+struct* ClientSocket get_prefered_bot(int botid) {
+ struct ClientSocket *client, *source = NULL;
+ for(client = getBots(SOCKET_FLAG_READY, NULL); client; client = getBots(SOCKET_FLAG_READY, client)) {
+ if(client->botid == botid && (client->flags & SOCKET_FLAG_PREFERED))
+ return client;
+ }
+ return NULL;
+}
+
+static char* get_channel_trigger(int botid, struct ChanNode *chan) {
+ struct trigger_cache *trigger;
+ for(trigger = chan->trigger; trigger; trigger = trigger->next) {
+ if(trigger->botid == botid)
+ return trigger->trigger;
+ }
+ struct trigger_callback *cb;
+ for(cb = trigger_callbacks; cb; cb = cb->next) {
+ if(cb->botid == botid)
+ break;
+ }
+ char triggerStr[TRIGGERLEN];
+ if(cb)
+ cb->func(chan, triggerStr);
+ else
+ strcpy(triggerStr, "+");
+ trigger = malloc(sizeof(*trigger));
+ if (!trigger) {
+ perror("malloc() failed");
+ return 0;
+ }
+ trigger->botid = botid;
+ trigger->trigger = strdup(triggerStr);
+ trigger->next = chan->trigger;
+ chan->trigger = trigger;
+ return trigger->trigger;
+}
+
+static void handle_command(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char *message) {
if(!strcmp(message, "users")) {
struct ChanUser *chanuser;
putsock(client, "PRIVMSG %s :[BOT JOIN] Users on this Channel:", chan->name);
}
}
+static void got_chanmsg(struct UserNode *user, struct ChanNode *chan, char *message) {
+ fd_set fds;
+ char *trigger;
+ struct ClientSocket *client;
+ FD_ZERO(&fds);
+ for(client = getBots(SOCKET_FLAG_READY, NULL); client; client = getBots(SOCKET_FLAG_READY, client)) {
+ if(isUserOnChan(client->user, chan) && (client->flags & SOCKET_FLAG_PREFERED) && !FD_ISSET(client->botid, &fds)) {
+ FD_SET(client->botid, &fds);
+ trigger = get_channel_trigger(client->botid, chan);
+ if(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)) {
+ FD_SET(client->botid, &fds);
+ trigger = get_channel_trigger(client->botid, chan);
+ if(stricmplen(message, trigger, strlen(trigger)) == 0) {
+ handle_command(client, user, chan, message + strlen(trigger));
+ }
+ }
+ }
+}
+
static void got_privmsg(struct UserNode *user, struct UserNode *target, char *message) {
-
+ struct ClientSocket *client;
+ for(client = getBots(SOCKET_FLAG_READY, NULL); client; client = getBots(SOCKET_FLAG_READY, client)) {
+ if(client->user == target) {
+ handle_command(client, user, NULL, message);
+ }
+ }
+}
+
+int register_command(int botid, char *name, cmd_bind_t *func) {
+ struct cmd_function *cmdfunc;
+ for(cmdfunc = cmd_functions; cmdfunc; cmdfunc = cmdfunc->next) {
+ if(cmdfunc->botid == botid && strcmp(cmdfunc->name, name) == 0)
+ return 0;
+ }
+ cmdfunc = malloc(sizeof(*cmdfunc));
+ if (!cmdfunc) {
+ perror("malloc() failed");
+ return 0;
+ }
+ cmdfunc->botid = botid;
+ cmdfunc->name = strdup(name);
+ cmdfunc->func = func;
+ cmdfunc->next = cmd_functions;
+ cmd_functions = cmdfunc;
+ return 1;
+}
+
+int set_trigger_callback(int botid, trigger_callback_t *func) {
+ static struct trigger_callback *cb = NULL;
+ for(cb = trigger_callbacks; cb; cb = cb->next) {
+ if(cb->botid == botid)
+ break;
+ }
+ if(!cb) {
+ cb = malloc(sizeof(*cb));
+ if (!cb) {
+ perror("malloc() failed");
+ return 0;
+ }
+ cb->botid = botid;
+ cb->next = trigger_callbacks;
+ trigger_callbacks = cb;
+ }
+ cb->func = func;
+ return 1;
+}
+
+int changeChannelTrigger(int botid, struct ChanNode *chan, char *new_trigger) {
+ struct trigger_cache *trigger;
+ for(trigger = chan->trigger; trigger; trigger = trigger->next) {
+ if(trigger->botid == botid) {
+ free(trigger->trigger);
+ trigger->trigger = strdup(new_trigger);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int bind_cmd_to_function(int botid, char *cmd, struct cmd_function *func) {
+ int bind_index = get_binds_index(cmd[0]);
+ struct cmd_binding *bind;
+ for(bind = cmd_binds[bind_index]; bind; bind = bind->next) {
+ if(bind->botid == botid && strcmp(bind->cmd, cmd) == 0)
+ return 0;
+ }
+ bind = malloc(sizeof(*bind));
+ if (!bind) {
+ perror("malloc() failed");
+ return 0;
+ }
+ bind->botid = botid;
+ bind->cmd = strdup(cmd);
+ bind->func = func;
+ bind->next = cmd_binds[bind_index];
+ cmd_binds[bind_index] = bind;
+ return 1;
+}
+
+int bind_cmd_to_command(int botid, char *cmd, char *func) {
+ struct cmd_function *cmdfunc;
+ for(cmdfunc = cmd_functions; cmdfunc; cmdfunc = cmdfunc->next) {
+ if(cmdfunc->botid == botid && strcmp(cmdfunc->name, func) == 0)
+ break;
+ }
+ if(!cmdfunc) return 0;
+ int bind_index = get_binds_index(cmd[0]);
+ struct cmd_binding *bind;
+ for(bind = cmd_binds[bind_index]; bind; bind = bind->next) {
+ if(bind->botid == botid && strcmp(bind->cmd, cmd) == 0)
+ return 0;
+ }
+ bind = malloc(sizeof(*bind));
+ if (!bind) {
+ perror("malloc() failed");
+ return 0;
+ }
+ bind->botid = botid;
+ bind->cmd = strdup(cmd);
+ bind->func = cmdfunc;
+ bind->next = cmd_binds[bind_index];
+ cmd_binds[bind_index] = bind;
+ return 1;
+}
+
+int unbind_cmd(int botid, char *cmd) {
+ int bind_index = get_binds_index(cmd[0]);
+ struct cmd_binding *bind, *last = NULL;
+ for(bind = cmd_binds[bind_index]; bind; bind = bind->next) {
+ if(bind->botid == botid && strcmp(bind->cmd, cmd) == 0) {
+ if(last)
+ last->next = bind->next;
+ else
+ cmd_binds[bind_index] = bind->next;
+ free(bind->cmd);
+ free(bind);
+ return 1;
+ } else
+ last = bind;
+ }
+ return 0;
}
void init_modcmd() {
- bind_chanmsg(got_chanmsg);
- bind_privmsg(got_privmsg);
+ cmd_binds = calloc(27, sizeof(*cmd_binds));
+ bind_chanmsg(got_chanmsg);
+ bind_privmsg(got_privmsg);
}