added possibility for subcommands
[NeonServV5.git] / src / modcmd.c
index 931c508df83daaca0d0751e056effa8720d0c28c..f6ff75fca8e6fffb7e6b31cbdb54c96eb1905b1f 100644 (file)
@@ -68,6 +68,7 @@ static const struct default_language_entry msgtab[] = {
     {"MODCMD_PRIVILEGED",       "$b%s$b is a privileged command."}, /* {ARGS: "god"} */
     {"MODCMD_PUBCMD",           "Public commands in $b%s$b are restricted."}, /* {ARGS: "#TestChan"} */
     {"MODCMD_ACCESS_DENIED",    "Access denied."},
+    {"MODCMD_SUBCOMMANDS",      "Subcommands of %s: %s"}, /* {ARGS: "bot", "ADD, DEL, EDIT"} */
     {NULL, NULL}
 };
 
@@ -132,6 +133,11 @@ static USERAUTH_CALLBACK(command_checked_auth) {
     free(cache);
 }
 
+static CMD_BIND(modcmd_linker) {
+    //fake command for subcommands
+    //just empty
+}
+
 static void handle_command(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, char *message) {
     struct ChanNode *sent_chan = chan;
     if(message[0] == '#') {
@@ -155,6 +161,38 @@ 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->func->func == modcmd_linker) {
+                //links subcommands
+                char command[MAXLEN];
+                struct cmd_binding *parent_bind = cbind;
+                if(args) {
+                    char *subcmd = args;
+                    args = strstr(args, " ");
+                    if(args) {
+                        *args = '\0';
+                        args++;
+                    }
+                    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)
+                            break;
+                    }
+                    if(!cbind)
+                        break;
+                } else {
+                    //list all sub commands
+                    int commandlen = sprintf(command, "%s ", parent_bind->cmd);
+                    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) {
+                            subcompos += sprintf(subcommands + subcompos, (subcompos ? ", %s" : "%s"), cbind->cmd + commandlen);
+                        }
+                    }
+                    reply(tmp_text_client, user, "MODCMD_SUBCOMMANDS", parent_bind->cmd, subcommands);
+                    break;
+                }
+            }
             if(statistics_enabled)
                 statistics_commands++;
             total_triggered++;
@@ -170,6 +208,8 @@ static void handle_command(struct ClientSocket *client, struct UserNode *user, s
             char *arga[MAXNUMPARAMS];
             char **argv;
             int argc = 0;
+            int escape = 0;
+            int offset = 0;
             if(args) {
                 while(*args) {
                     //skip leading spaces
@@ -178,8 +218,22 @@ static void handle_command(struct ClientSocket *client, struct UserNode *user, s
                     arga[argc++] = args;
                     if (argc >= MAXNUMPARAMS)
                         break;
-                    while (*args != ' ' && *args)
+                    while ((escape || *args != ' ') && *args) {
+                        if((cbind->func->flags & CMDFLAG_ESCAPE_ARGS) && *args == '\\') {
+                            escape = 1;
+                            offset++;
+                        } else if(escape)
+                            escape = 0;
+                        if(!escape && offset) {
+                            args[0 - offset] = args[0];
+                        }
                         args++;
+                        
+                    }
+                    if(offset) {
+                        args[0-offset] = '\0';
+                        offset = 0;
+                    }
                 }
             }
             argv = arga;
@@ -428,7 +482,7 @@ static void handle_command_async(struct ClientSocket *client, struct UserNode *u
         reply(tmp_text_client, user, "MODCMD_PRIVILEGED", cbind->cmd);
         return;
     }
-    struct Event *event = createEvent(client, user, chan, cbind->func->name, argv, argc, eventflags);
+    struct Event *event = createEvent(client, user, chan, cbind, argv, argc, eventflags);
     cbind->func->func(client, user, chan, argv, argc, event);
 }
 
@@ -645,6 +699,7 @@ void init_modcmd() {
     bind_chanmsg(got_chanmsg);
     bind_privmsg(got_privmsg);
     register_default_language_table(msgtab);
+    register_command(0, "linker", modcmd_linker, 0, 0, 0, 0); //fake command for subcommands
 }
 
 void free_modcmd() {