From 7c656ac03a03a5fa910f9cad3c4735ed62f7ab69 Mon Sep 17 00:00:00 2001 From: cloudwalk Date: Tue, 6 Oct 2020 14:10:26 +0000 Subject: [PATCH] svvm_cmds: Implement built-in #352 (registercommand) for SSQC git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@13002 d7cf8633-e32d-0410-b094-e92efae38249 --- cmd.c | 46 +++++++++++++++++++++++------------------- cmd.h | 4 ++-- dpdefs/dpextensions.qc | 8 ++++++++ prvm_offsets.h | 2 ++ server.h | 2 ++ svvm_cmds.c | 35 +++++++++++++++++++++++++++++++- 6 files changed, 73 insertions(+), 24 deletions(-) diff --git a/cmd.c b/cmd.c index 08da25ac..eca5bf3d 100644 --- a/cmd.c +++ b/cmd.c @@ -1506,7 +1506,7 @@ static void Cmd_List_f (cmd_state_t *cmd) } count = 0; - for (func = cmd->userdefined->csqc_functions; func; func = func->next) + for (func = cmd->userdefined->qc_functions; func; func = func->next) { if (partial && (ispattern ? !matchpattern_with_separator(func->name, partial, false, "", false) : strncmp(partial, func->name, len))) continue; @@ -1574,7 +1574,7 @@ static void Cmd_Apropos_f(cmd_state_t *cmd) } } } - for (func = cmd->userdefined->csqc_functions; func; func = func->next) + for (func = cmd->userdefined->qc_functions; func; func = func->next) { if (!matchpattern_with_separator(func->name, partial, true, "", false)) if (!matchpattern_with_separator(func->description, partial, true, "", false)) @@ -1875,12 +1875,12 @@ void Cmd_AddCommand(int flags, const char *cmd_name, xcommand_t function, const } else { - // mark csqcfunc if the function already exists in the csqc_functions list - for (func = cmd->userdefined->csqc_functions; func; func = func->next) + // mark qcfunc if the function already exists in the qc_functions list + for (func = cmd->userdefined->qc_functions; func; func = func->next) { if (!strcmp(cmd_name, func->name)) { - func->csqcfunc = true; //[515]: csqc + func->qcfunc = true; //[515]: csqc continue; } } @@ -1890,18 +1890,18 @@ void Cmd_AddCommand(int flags, const char *cmd_name, xcommand_t function, const func->name = cmd_name; func->function = function; func->description = description; - func->csqcfunc = true; //[515]: csqc - func->next = cmd->userdefined->csqc_functions; + func->qcfunc = true; //[515]: csqc + func->next = cmd->userdefined->qc_functions; func->autofunc = false; // insert it at the right alphanumeric position - for (prev = NULL, current = cmd->userdefined->csqc_functions; current && strcmp(current->name, func->name) < 0; prev = current, current = current->next) + for (prev = NULL, current = cmd->userdefined->qc_functions; current && strcmp(current->name, func->name) < 0; prev = current, current = current->next) ; if (prev) { prev->next = func; } else { - cmd->userdefined->csqc_functions = func; + cmd->userdefined->qc_functions = func; } func->next = current; } @@ -1923,7 +1923,7 @@ qbool Cmd_Exists (cmd_state_t *cmd, const char *cmd_name) { cmd_function_t *func; - for (func = cmd->userdefined->csqc_functions; func; func = func->next) + for (func = cmd->userdefined->qc_functions; func; func = func->next) if (!strcmp(cmd_name, func->name)) return true; @@ -1951,7 +1951,7 @@ const char *Cmd_CompleteCommand (cmd_state_t *cmd, const char *partial) return NULL; // check functions - for (func = cmd->userdefined->csqc_functions; func; func = func->next) + for (func = cmd->userdefined->qc_functions; func; func = func->next) if (!strncasecmp(partial, func->name, len)) return func->name; @@ -1984,7 +1984,7 @@ int Cmd_CompleteCountPossible (cmd_state_t *cmd, const char *partial) return 0; // Loop through the command list and count all partial matches - for (func = cmd->userdefined->csqc_functions; func; func = func->next) + for (func = cmd->userdefined->qc_functions; func; func = func->next) if (!strncasecmp(partial, func->name, len)) h++; @@ -2015,7 +2015,7 @@ const char **Cmd_CompleteBuildList (cmd_state_t *cmd, const char *partial) len = strlen(partial); buf = (const char **)Mem_Alloc(tempmempool, sizeofbuf + sizeof (const char *)); // Loop through the functions lists and print all matches - for (func = cmd->userdefined->csqc_functions; func; func = func->next) + for (func = cmd->userdefined->qc_functions; func; func = func->next) if (!strncasecmp(partial, func->name, len)) buf[bpos++] = func->name; for (func = cmd->engine_functions; func; func = func->next) @@ -2032,7 +2032,7 @@ void Cmd_CompleteCommandPrint (cmd_state_t *cmd, const char *partial) cmd_function_t *func; size_t len = strlen(partial); // Loop through the command list and print all matches - for (func = cmd->userdefined->csqc_functions; func; func = func->next) + for (func = cmd->userdefined->qc_functions; func; func = func->next) if (!strncasecmp(partial, func->name, len)) Con_Printf("^2%s^7: %s\n", func->name, func->description); for (func = cmd->engine_functions; func; func = func->next) @@ -2141,7 +2141,7 @@ const char **Cmd_CompleteAliasBuildList (cmd_state_t *cmd, const char *partial) void Cmd_ClearCSQCCommands (cmd_state_t *cmd) { cmd_function_t *func; - cmd_function_t **next = &cmd->userdefined->csqc_functions; + cmd_function_t **next = &cmd->userdefined->qc_functions; while(*next) { @@ -2178,13 +2178,17 @@ void Cmd_ExecuteString (cmd_state_t *cmd, const char *text, cmd_source_t src, qb goto done; // no tokens // check functions - for (func = cmd->userdefined->csqc_functions; func; func = func->next) + for (func = cmd->userdefined->qc_functions; func; func = func->next) { if (!strcasecmp(cmd->argv[0], func->name)) { - if (func->csqcfunc && CL_VM_ConsoleCommand(text)) //[515]: csqc - goto done; - break; + if(func->qcfunc) + { + if((func->flags & CF_CLIENT) && CL_VM_ConsoleCommand(text)) + goto done; + else if((func->flags & CF_SERVER) && SV_VM_ConsoleCommand(text)) + goto done; + } } } @@ -2276,7 +2280,7 @@ void Cmd_SaveInitState(void) cmd_state_t *cmd = cmd_iter->cmd; cmd_function_t *f; cmd_alias_t *a; - for (f = cmd->userdefined->csqc_functions; f; f = f->next) + for (f = cmd->userdefined->qc_functions; f; f = f->next) f->initstate = true; for (f = cmd->engine_functions; f; f = f->next) f->initstate = true; @@ -2297,7 +2301,7 @@ void Cmd_RestoreInitState(void) cmd_state_t *cmd = cmd_iter->cmd; cmd_function_t *f, **fp; cmd_alias_t *a, **ap; - for (fp = &cmd->userdefined->csqc_functions; (f = *fp);) + for (fp = &cmd->userdefined->qc_functions; (f = *fp);) { if (f->initstate) fp = &f->next; diff --git a/cmd.h b/cmd.h index 445e08c1..f7b3b4d1 100644 --- a/cmd.h +++ b/cmd.h @@ -89,7 +89,7 @@ typedef struct cmd_function_s const char *name; const char *description; xcommand_t function; - qbool csqcfunc; + qbool qcfunc; qbool autofunc; qbool initstate; // indicates this command existed at init } cmd_function_t; @@ -98,7 +98,7 @@ typedef struct cmd_function_s typedef struct cmd_userdefined_s { // csqc functions - this is a mess - cmd_function_t *csqc_functions; + cmd_function_t *qc_functions; // aliases cmd_alias_t *alias; diff --git a/dpdefs/dpextensions.qc b/dpdefs/dpextensions.qc index 1aeecfaf..2dba6b62 100644 --- a/dpdefs/dpextensions.qc +++ b/dpdefs/dpextensions.qc @@ -2632,3 +2632,11 @@ float(string pattern, float caseinsensitive, float quiet, string packfile) searc //description: //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) +//idea: probably Spoike +//darkplaces implementation: Cloudwalk +//builtin definitions: +void(string cmdname) registercommand = #352; +//description: +//the registercommand builtin but the server can use it \ No newline at end of file diff --git a/prvm_offsets.h b/prvm_offsets.h index 5eada948..97a2defb 100644 --- a/prvm_offsets.h +++ b/prvm_offsets.h @@ -419,6 +419,7 @@ PRVM_DECLARE_function(CSQC_UpdateView) PRVM_DECLARE_function(ClientConnect) PRVM_DECLARE_function(ClientDisconnect) PRVM_DECLARE_function(ClientKill) +PRVM_DECLARE_function(ConsoleCmd) PRVM_DECLARE_function(EndFrame) PRVM_DECLARE_function(GameCommand) PRVM_DECLARE_function(PlayerPostThink) @@ -782,6 +783,7 @@ PRVM_DECLARE_serverfieldvector(view_ofs) PRVM_DECLARE_serverfunction(ClientConnect) PRVM_DECLARE_serverfunction(ClientDisconnect) PRVM_DECLARE_serverfunction(ClientKill) +PRVM_DECLARE_serverfunction(ConsoleCmd) PRVM_DECLARE_serverfunction(EndFrame) PRVM_DECLARE_serverfunction(GameCommand) PRVM_DECLARE_serverfunction(PlayerPostThink) diff --git a/server.h b/server.h index 4f643c82..283f1660 100644 --- a/server.h +++ b/server.h @@ -635,4 +635,6 @@ void SV_PreSpawn_f(cmd_state_t *cmd); void SV_Spawn_f(cmd_state_t *cmd); void SV_Begin_f(cmd_state_t *cmd); +qbool SV_VM_ConsoleCommand (const char *text); + #endif diff --git a/svvm_cmds.c b/svvm_cmds.c index 6c8c558a..ac391a3e 100644 --- a/svvm_cmds.c +++ b/svvm_cmds.c @@ -2847,6 +2847,39 @@ static void VM_SV_pointparticles(prvm_prog_t *prog) SV_FlushBroadcastMessages(); } +qbool SV_VM_ConsoleCommand (const char *text) +{ + prvm_prog_t *prog = SVVM_prog; + int restorevm_tempstringsbuf_cursize; + int save_self; + qbool r = false; + + if(!sv.active || !prog || !prog->loaded) + return false; + + if (PRVM_serverfunction(ConsoleCmd)) + { + save_self = PRVM_serverglobaledict(self); + PRVM_serverglobalfloat(time) = sv.time; + restorevm_tempstringsbuf_cursize = prog->tempstringsbuf.cursize; + PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(sv.world.prog->edicts); + PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(prog, text); + prog->ExecuteProgram(prog, PRVM_serverfunction(ConsoleCmd), "QC function ConsoleCmd is missing"); + prog->tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize; + PRVM_serverglobaledict(self) = save_self; + r = (int) PRVM_G_FLOAT(OFS_RETURN) != 0; + } + return r; +} + +// #352 void(string cmdname) registercommand (EXT_CSQC) +static void VM_SV_registercommand (prvm_prog_t *prog) +{ + VM_SAFEPARMCOUNT(1, VM_SV_registercmd); + if(!Cmd_Exists(&cmd_server, PRVM_G_STRING(OFS_PARM0))) + Cmd_AddCommand(CF_SERVER, PRVM_G_STRING(OFS_PARM0), NULL, "console command created by QuakeC"); +} + //PF_setpause, // void(float pause) setpause = #531; static void VM_SV_setpause(prvm_prog_t *prog) { int pauseValue; @@ -3528,7 +3561,7 @@ NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (E NULL, // #349 float() isdemo (EXT_CSQC) VM_isserver, // #350 float() isserver (EXT_CSQC) NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC) -NULL, // #352 void(string cmdname) registercommand (EXT_CSQC) +VM_SV_registercommand, // #352 void(string cmdname) registercommand (EXT_CSQC) VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too) VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC) NULL, // #355 -- 2.39.2