]> git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
Reimplement the ability to override engine commands with QC commands
authorbones_was_here <bones_was_here@xonotic.au>
Tue, 24 Jan 2023 00:11:40 +0000 (10:11 +1000)
committerbones_was_here <bones_was_here@xonotic.au>
Tue, 24 Jan 2023 00:11:40 +0000 (10:11 +1000)
This was working in div0-stable and was removed in 46acef5491629d06eddb8e78ed01e50b175d2bd8

Due to previous improvements by LH & Cloudwalk, the behaviour is now better:
the new QC command appears in the console in addition to the engine one,
the new command takes priority and what's going on is clearer.
When the CSQC VM shuts down, the registered command is removed.

Also this time we can has documentation.

Signed-off-by: bones_was_here <bones_was_here@xonotic.au>
clvm_cmds.c
cmd.c
cmd.h
dpdefs/dpextensions.qc
mvm_cmds.c
svvm_cmds.c

index 1f394845215e56d0f3628abaf48244dece9f0e6d..44e62aee30ceaad7241fffb4f17d89e2dff85552 100644 (file)
@@ -2407,8 +2407,7 @@ static void VM_CL_setlistener (prvm_prog_t *prog)
 static void VM_CL_registercmd (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_CL_registercmd);
-       if(!Cmd_Exists(cmd_local, PRVM_G_STRING(OFS_PARM0)))
-               Cmd_AddCommand(CF_CLIENT, PRVM_G_STRING(OFS_PARM0), NULL, "console command created by QuakeC");
+       Cmd_AddCommand(CF_CLIENT, PRVM_G_STRING(OFS_PARM0), NULL, "console command created by QuakeC");
 }
 
 //#360 float() readbyte (EXT_CSQC)
diff --git a/cmd.c b/cmd.c
index a12fae8ea0c4fa52839d66a46267e73b927936bf..c9b2cd5d8b0fc8d172d69685c59880122518d1d7 100644 (file)
--- a/cmd.c
+++ b/cmd.c
@@ -1900,7 +1900,6 @@ void Cmd_AddCommand(int flags, const char *cmd_name, xcommand_t function, const
                                        }
                                }
 
-
                                func = (cmd_function_t *)Mem_Alloc(cmd->mempool, sizeof(cmd_function_t));
                                func->flags = flags;
                                func->name = cmd_name;
@@ -1909,6 +1908,18 @@ void Cmd_AddCommand(int flags, const char *cmd_name, xcommand_t function, const
                                func->qcfunc = true; //[515]: csqc
                                func->next = cmd->userdefined->qc_functions;
 
+                               // bones_was_here: if this QC command overrides an engine command, store its pointer
+                               // to avoid doing this search at invocation if QC declines to handle this command.
+                               for (cmd_function_t *f = cmd->engine_functions; f; f = f->next)
+                               {
+                                       if (!strcmp(cmd_name, f->name))
+                                       {
+                                               Con_DPrintf("Adding QC override of engine command %s\n", cmd_name);
+                                               func->overridden = f;
+                                               break;
+                                       }
+                               }
+
                                // insert it at the right alphanumeric position
                                for (prev = NULL, current = cmd->userdefined->qc_functions; current && strcmp(current->name, func->name) < 0; prev = current, current = current->next)
                                        ;
@@ -2192,6 +2203,9 @@ qbool Cmd_CL_Callback(cmd_state_t *cmd, cmd_function_t *func, const char *text,
                if(((func->flags & CF_CLIENT) && CL_VM_ConsoleCommand(text)) ||
                   ((func->flags & CF_SERVER) && SV_VM_ConsoleCommand(text)))
                        return true;
+
+               if (func->overridden) // If this QC command overrides an engine command,
+                       func = func->overridden; // fall back to that command.
        }
        if (func->flags & CF_SERVER_FROM_CLIENT)
        {
diff --git a/cmd.h b/cmd.h
index c80fdf9078307f31f2f0afe5f9715af6fad25170..bee0a1f36b520b0695e863e0cdeda6de942a3e3d 100644 (file)
--- a/cmd.h
+++ b/cmd.h
@@ -90,6 +90,7 @@ typedef struct cmd_function_s
        const char *description;
        xcommand_t function;
        qbool qcfunc;
+       struct cmd_function_s *overridden; // the engine cmd overriden by this QC cmd, if applicable
        qbool autofunc;
        qbool initstate; // indicates this command existed at init
 } cmd_function_t;
index 48045a202faf22ed1b7bdcbf811db9d113d7752e..32c5e7c5ab6a145596decc113fc96b0521ae0b7d 100644 (file)
@@ -2633,12 +2633,16 @@ float(string pattern, float caseinsensitive, float quiet, string packfile) searc
 //extension to search_begin (DP_QC_FS_SEARCH), performs a filename search with the specified pattern (for example "maps/*.bsp") and stores the results in a search slot (minimum of 128 supported by any engine with this extension), the other functions take this returned search slot number, be sure to search_free when done (they are also freed on progs reload).
 //only searches for files within the specified packfile, which is expected to match the results of whichpack().
 
-//EXT_CSQC (registercommand for SSQC)
+//EXT_CSQC (registercommand for CSQC, now also available in SVQC)
 //idea: probably Spoike
 //darkplaces implementation: Cloudwalk
 //builtin definitions:
 void(string cmdname) registercommand = #352;
+//engine-called QC prototypes:
+//float CSQC_ConsoleCommand(string command);
+//float ConsoleCmd(string command);
 //description:
-//the registercommand builtin but the server can use it
+//Adds a new console command which will take priority over a previous command of the same name (including engine commands) and in CSQC is removed when the VM shuts down. This will call CSQC_ConsoleCommand(string command) or ConsoleCmd(string command) in SVQC.  Return value should be true if QC handled the command, otherwise return false to have the engine handle it.
+
 
 float(float dividend, float divisor) mod = #245;
index 69801a04a7078fa7d4916f0da00277f1fb69983e..3faf9a1f796999f0cb8910b62f1fceefcecd3345 100644 (file)
@@ -1058,8 +1058,7 @@ void VM_cin_restart(prvm_prog_t *prog)
 static void VM_M_registercommand(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_M_registercommand);
-       if(!Cmd_Exists(cmd_local, PRVM_G_STRING(OFS_PARM0)))
-               Cmd_AddCommand(CF_CLIENT, PRVM_G_STRING(OFS_PARM0), NULL, "console command created by QuakeC");
+       Cmd_AddCommand(CF_CLIENT, PRVM_G_STRING(OFS_PARM0), NULL, "console command created by QuakeC");
 }
 
 prvm_builtin_t vm_m_builtins[] = {
index a884d0f1b42c47393300edc8e88d21df774becb6..e77f965079b79d70760fe9eec548ffa509175543 100644 (file)
@@ -2865,8 +2865,7 @@ qbool SV_VM_ConsoleCommand (const char *text)
 static void VM_SV_registercommand (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_SV_registercmd);
-       if(!Cmd_Exists(cmd_local, PRVM_G_STRING(OFS_PARM0)))
-               Cmd_AddCommand(CF_SERVER, PRVM_G_STRING(OFS_PARM0), NULL, "console command created by QuakeC");
+       Cmd_AddCommand(CF_SERVER, PRVM_G_STRING(OFS_PARM0), NULL, "console command created by QuakeC");
 }
 
 //PF_setpause,    // void(float pause) setpause        = #531;