From: divverent Date: Sun, 15 Apr 2007 20:01:38 +0000 (+0000) Subject: New console commands sv_cmd, menu_cmd, cl_cmd, that call GameCommand(string s) in... X-Git-Tag: xonotic-v0.1.0preview~3333 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=10335c4c27003a165ae9c4557447c9bd109d0623;p=xonotic%2Fdarkplaces.git New console commands sv_cmd, menu_cmd, cl_cmd, that call GameCommand(string s) in the server, menu, client program with the remainder of the command line as argument. Extension: DP_QC_CMD for all of them, DP_SV_CMD for sv_cmd. git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@7097 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/mvm_cmds.c b/mvm_cmds.c index a18d71f5..1a9a84f3 100644 --- a/mvm_cmds.c +++ b/mvm_cmds.c @@ -11,7 +11,9 @@ char *vm_m_extensions = "DP_QC_STRFTIME " "DP_QC_STRINGCOLORFUNCTIONS " "DP_QC_TOKENIZEBYSEPARATOR " -"DP_QC_UNLIMITEDTEMPSTRINGS"; +"DP_QC_UNLIMITEDTEMPSTRINGS " +"DP_QC_CMD " +; /* ========= diff --git a/progsvm.h b/progsvm.h index 87806d74..d8eb4953 100644 --- a/progsvm.h +++ b/progsvm.h @@ -256,6 +256,7 @@ typedef struct prvm_prog_funcoffsets_s func_t SV_ChangeTeam; // ssqc func_t SV_ParseClientCommand; // ssqc func_t SV_PlayerPhysics; // ssqc + func_t GameCommand; // any // menu qc only uses some functions, nothing else func_t m_display; // mqc diff --git a/prvm_edict.c b/prvm_edict.c index 8a97b425..c7429950 100644 --- a/prvm_edict.c +++ b/prvm_edict.c @@ -38,6 +38,8 @@ cvar_t prvm_traceqc = {0, "prvm_traceqc", "0", "prints every QuakeC statement as // LordHavoc: counts usage of each QuakeC statement cvar_t prvm_statementprofiling = {0, "prvm_statementprofiling", "0", "counts how many times each QuakeC statement has been executed, these counts are displayed in prvm_printfunction output (if enabled)"}; +extern sizebuf_t vm_tempstringsbuf; + //============================================================================ // mempool handling @@ -985,6 +987,71 @@ qboolean PRVM_ED_ParseEpair(prvm_edict_t *ent, ddef_t *key, const char *s) return true; } +/* +============= +PRVM_GameCommand_f + +Console command to send a string to QC function GameCommand of the +indicated progs + +Usage: + sv_cmd adminmsg 3 "do not teamkill" + cl_cmd someclientcommand + menu_cmd somemenucommand + +All progs can support this extension; sg calls it in server QC, cg in client +QC, mg in menu QC. +============= +*/ +void PRVM_GameCommand(const char *whichprogs, const char *whichcmd) +{ + if(Cmd_Argc() < 1) + { + Con_Printf("%s text...\n", whichcmd); + return; + } + + PRVM_Begin; + if(!PRVM_SetProgFromString(whichprogs)) + // note: this is not PRVM_SetProg because that one aborts "hard" using PRVM_Error + // also, it makes printing error messages easier! + { + Con_Printf("%s program not loaded.\n", whichprogs); + return; + } + + if(!prog->funcoffsets.GameCommand) + { + Con_Printf("%s program do not support GameCommand!\n", whichprogs); + } + else + { + int restorevm_tempstringsbuf_cursize; + const char *s; + + s = Cmd_Args(); + + restorevm_tempstringsbuf_cursize = vm_tempstringsbuf.cursize; + PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(s ? s : ""); + PRVM_ExecuteProgram (prog->funcoffsets.GameCommand, "QC function GameCommand is missing"); + vm_tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize; + } + + PRVM_End; +} +void PRVM_GameCommand_Server_f(void) +{ + PRVM_GameCommand("server", "sv_cmd"); +} +void PRVM_GameCommand_Client_f(void) +{ + PRVM_GameCommand("client", "cl_cmd"); +} +void PRVM_GameCommand_Menu_f(void) +{ + PRVM_GameCommand("menu", "menu_cmd"); +} + /* ============= PRVM_ED_EdictSet_f @@ -1331,6 +1398,7 @@ void PRVM_FindOffsets(void) prog->funcoffsets.SV_ChangeTeam = PRVM_ED_FindFunctionOffset("SV_ChangeTeam"); prog->funcoffsets.SV_ParseClientCommand = PRVM_ED_FindFunctionOffset("SV_ParseClientCommand"); prog->funcoffsets.SV_PlayerPhysics = PRVM_ED_FindFunctionOffset("SV_PlayerPhysics"); + prog->funcoffsets.GameCommand = PRVM_ED_FindFunctionOffset("GameCommand"); prog->globaloffsets.SV_InitCmd = PRVM_ED_FindGlobalOffset("SV_InitCmd"); prog->globaloffsets.self = PRVM_ED_FindGlobalOffset("self"); prog->globaloffsets.time = PRVM_ED_FindGlobalOffset("time"); @@ -1910,6 +1978,9 @@ void PRVM_Init (void) Cmd_AddCommand ("prvm_globalset", PRVM_GlobalSet_f, "sets value of a specified global variable in the selected VM (server, client, menu)"); Cmd_AddCommand ("prvm_edictset", PRVM_ED_EdictSet_f, "changes value of a specified property of a specified entity in the selected VM (server, client, menu)"); Cmd_AddCommand ("prvm_printfunction", PRVM_PrintFunction_f, "prints a disassembly (QuakeC instructions) of the specified function in the selected VM (server, client, menu)"); + Cmd_AddCommand ("cl_cmd", PRVM_GameCommand_Client_f, "calls the client QC function GameCommand with the supplied string as argument"); + Cmd_AddCommand ("menu_cmd", PRVM_GameCommand_Menu_f, "calls the menu QC function GameCommand with the supplied string as argument"); + Cmd_AddCommand ("sv_cmd", PRVM_GameCommand_Server_f, "calls the server QC function GameCommand with the supplied string as argument"); // LordHavoc: optional runtime bounds checking (speed drain, but worth it for security, on by default - breaks most QCCX features (used by CRMod and others)) Cvar_RegisterVariable (&prvm_boundscheck); Cvar_RegisterVariable (&prvm_traceqc); diff --git a/svvm_cmds.c b/svvm_cmds.c index bbe14a77..cfe61808 100644 --- a/svvm_cmds.c +++ b/svvm_cmds.c @@ -132,6 +132,8 @@ char *vm_sv_extensions = "PRYDON_CLIENTCURSOR " "TENEBRAE_GFX_DLIGHTS " "TW_SV_STEPCONTROL " +"DP_SV_CMD " +"DP_QC_CMD " ; /*