multiple fixes
[NeonServV5.git] / src / modcmd.c
index 629435d9a672e2f64e359bd9164fe2fbdd7d0265..0bfe56dd3ce951e534d8296f75d9e050db43e6c8 100644 (file)
@@ -30,6 +30,7 @@
 
 struct trigger_callback {
     int botid;
+    int module_id;
     trigger_callback_t *func;
     
     struct trigger_callback *next;
@@ -128,7 +129,8 @@ static void handle_command_async(struct ClientSocket *client, struct UserNode *u
 static USERAUTH_CALLBACK(command_checked_auth) {
     struct command_check_user_cache *cache = data;
     tmp_text_client = cache->textclient;
-    handle_command_async(cache->client, user, cache->chan, cache->sent_chan, cache->cbind, cache->argv, cache->argc);
+    if(user)
+        handle_command_async(cache->client, user, cache->chan, cache->sent_chan, cache->cbind, cache->argv, cache->argc);
     free(cache->message);
     if(cache->args_buffer)
         free(cache->args_buffer);
@@ -367,7 +369,7 @@ static void handle_command(struct ClientSocket *client, struct UserNode *user, s
                 data->args_buffer = args_buffer;
                 data->cbind = cbind;
                 data->textclient = tmp_text_client;
-                get_userauth(user, command_checked_auth, data);
+                get_userauth(user, 0, command_checked_auth, data);
                 return;
             } else
                 handle_command_async(client, user, chan, sent_chan, cbind, argv, argc);
@@ -391,7 +393,7 @@ static void handle_command_async(struct ClientSocket *client, struct UserNode *u
         reply(tmp_text_client, user, "MODCMD_AUTH_REQUIRED");
         return;
     }
-    if(chan && sent_chan != chan && !isUserOnChan(user, chan)) {
+    if(chan && sent_chan != chan && (BIND_FLAGS(cbind) & CMDFLAG_NO_CROSSCHAN) && !isUserOnChan(user, chan)) {
         char user_in_chan = 0;
         if((user->flags & USERFLAG_ISAUTHED)) {
             //maybe there's another user authed to user->auth on the channel...
@@ -595,7 +597,7 @@ static void got_privmsg(struct UserNode *user, struct UserNode *target, char *me
     }
 }
 
-int register_command(int botid, char *name, cmd_bind_t *func, int paramcount, char *channel_access, int global_access, unsigned int flags) {
+int register_command(int botid, char *name, int module_id, cmd_bind_t *func, int paramcount, char *channel_access, int global_access, unsigned int flags) {
     struct cmd_function *cmdfunc;
     for(cmdfunc = cmd_functions; cmdfunc; cmdfunc = cmdfunc->next) {
         if((cmdfunc->botid == botid || cmdfunc->botid == 0) && strcmp(cmdfunc->name, name) == 0)
@@ -608,6 +610,7 @@ int register_command(int botid, char *name, cmd_bind_t *func, int paramcount, ch
     }
     cmdfunc->botid = botid;
     cmdfunc->name = strdup(name);
+    cmdfunc->module_id = module_id;
     cmdfunc->func = func;
     cmdfunc->flags = flags;
     cmdfunc->paramcount = paramcount;
@@ -618,7 +621,7 @@ int register_command(int botid, char *name, cmd_bind_t *func, int paramcount, ch
     return 1;
 }
 
-int set_trigger_callback(int botid, trigger_callback_t *func) {
+int set_trigger_callback(int botid, int module_id, trigger_callback_t *func) {
     static struct trigger_callback *cb = NULL;
     for(cb = trigger_callbacks; cb; cb = cb->next) {
         if(cb->botid == botid)
@@ -634,6 +637,7 @@ int set_trigger_callback(int botid, trigger_callback_t *func) {
         cb->next = trigger_callbacks;
         trigger_callbacks = cb;
     }
+    cb->module_id = module_id;
     cb->func = func;
     return 1;
 }
@@ -768,13 +772,13 @@ int unbind_botwise_cmd(int botid, int clientid, char *cmd) {
     return 0;
 }
 
-int unbind_botwise_allcmd(int clientid) {
+int unbind_botwise_allcmd(int botid, 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((botid == 0 && clientid == cbind->clientid) || (botid && botid == cbind->botid)) {
                 if(last)
                     last->next = cbind->next;
                 else
@@ -823,10 +827,10 @@ struct ClientSocket *getTextBot() {
 
 void init_modcmd() {
     cmd_binds = calloc(27, sizeof(*cmd_binds));
-    bind_chanmsg(got_chanmsg);
-    bind_privmsg(got_privmsg);
+    bind_chanmsg(got_chanmsg, 0);
+    bind_privmsg(got_privmsg, 0);
     register_default_language_table(msgtab);
-    register_command(0, "linker", modcmd_linker, 0, 0, 0, 0); //fake command for subcommands
+    register_command(0, "linker", 0, modcmd_linker, 0, 0, 0, 0); //fake command for subcommands
 }
 
 void free_modcmd() {
@@ -1010,3 +1014,54 @@ struct cmd_binding *getAllBinds(struct cmd_binding *last) {
     } while(bind_index < 27);
     return NULL;
 }
+
+void unregister_module_commands(int module_id) {
+    struct cmd_function *cmdfunct, *nextfunct, *prevfunct = NULL;
+    int i;
+    for(cmdfunct = cmd_functions; cmdfunct; cmdfunct = nextfunct) {
+        nextfunct = cmdfunct->next;
+        if(cmdfunct->module_id == module_id) {
+            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(cmdfunct == cbind->func) {
+                        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;
+                }
+            }
+            if(prevfunct) 
+                prevfunct->next = nextfunct;
+            else
+                cmd_functions = nextfunct;
+            free(cmdfunct->name);
+            free(cmdfunct);
+        } else
+            prevfunct = cmdfunct;
+    }
+    static struct trigger_callback *cb, *prevcb = NULL, *nextcb;
+    for(cb = trigger_callbacks; cb; cb = nextcb) {
+        nextcb = cb->next;
+        if(cb->module_id == module_id) {
+            if(prevcb)
+                prevcb->next = nextcb;
+            else
+                trigger_callbacks = nextcb;
+            free(cb);
+        } else
+            prevcb = cb;
+    }
+}