/* ======================================================================================================================================= Cmd_RemoveCommandSafe Only remove commands with no associated function. ======================================================================================================================================= */ void Cmd_RemoveCommandSafe(const char *cmd_name) { cmd_function_t *cmd = Cmd_FindCommand(cmd_name); if (!cmd) { return; } if (cmd->function) { Com_Error(ERR_DROP, "Restricted source tried to remove system command \"%s\"", cmd_name); return; } Cmd_RemoveCommand(cmd_name); }
/* ============ Cmd_RemoveCommandSafe Only remove commands with no associated function ============ */ void Cmd_RemoveCommandSafe( const char *cmd_name ) { cmd_function_t *cmd = Cmd_FindCommand( cmd_name ); if( !cmd ) return; if( cmd->function ) { Com_Printf( S_COLOR_RED "Restricted source tried to remove " "system command \"%s\"", cmd_name ); return; } Cmd_RemoveCommand( cmd_name ); }
/** * @brief Only remove commands with no associated function * Already removed in ETL: +button4, -button4 * Allowed to remove: +lookup, +lookdown, -lookup, +lookup, configstrings */ void Cmd_RemoveCommandSafe(const char *cmd_name) { cmd_function_t *cmd; if (!cmd_name[0]) { Com_Printf(S_COLOR_RED "Cmd_RemoveCommandSafe called with an empty command name\n"); return; } // silent return for obsolete genuine ET cmds which have been removed in ETL if (!strcmp(cmd_name, "+button4") || !strcmp(cmd_name, "-button4")) { return; } cmd = Cmd_FindCommand(cmd_name); if (!cmd) { // don't nag for commands which might have been removed if (!(!strcmp(cmd_name, "+lookup") || !strcmp(cmd_name, "+lookdown") || !strcmp(cmd_name, "-lookup") || !strcmp(cmd_name, "-lookdown") || !strcmp(cmd_name, "configstrings"))) { Com_Printf(S_COLOR_RED "Cmd_RemoveCommandSafe called for an unknown command \"%s\"\n", cmd_name); } return; } // don't remove commands in general ... // this ensures commands like vid_restart, quit etc won't be removed from the engine by mod code if (cmd->function && // several mods are removing some system commands to avoid abuse - let's allow these !(!strcmp(cmd_name, "+lookup") || !strcmp(cmd_name, "+lookdown") || !strcmp(cmd_name, "-lookup") || !strcmp(cmd_name, "-lookdown") || !strcmp(cmd_name, "configstrings"))) { Com_Printf(S_COLOR_RED "Restricted source tried to remove system command \"%s\"\n", cmd_name); return; } Com_DPrintf(S_COLOR_YELLOW "Cmd_RemoveCommandSafe command \"%s\" removed\n", cmd_name); Cmd_RemoveCommand(cmd_name); }
/* ============ Cmd_AddCommand ============ */ void Cmd_AddCommand( const char *cmd_name, xcommand_t function ) { cmd_function_t *cmd; // fail if the command already exists if( Cmd_FindCommand( cmd_name ) ) { // allow completion-only commands to be silently doubled if( function != NULL ) Com_Printf( "Cmd_AddCommand: %s already defined\n", cmd_name ); return; } // use a small malloc to avoid zone fragmentation cmd = S_Malloc (sizeof(cmd_function_t)); cmd->name = CopyString( cmd_name ); cmd->function = function; cmd->complete = NULL; cmd->next = cmd_functions; cmd_functions = cmd; }
/* ============ Cmd_AddCommandExtended ============ */ void Cmd_AddSystemCommand(const char *cmd_name, xcommand_t function, const char *description, completionFunc_t complete) { cmd_function_t *cmd; if (!cmd_name || !cmd_name[0]) { Com_Printf(S_COLOR_RED "Cmd_AddSystemCommand can't add NULL or empty command name\n"); return; } // fail if the command already exists if (Cmd_FindCommand(cmd_name)) { // allow completion-only commands to be silently doubled if (function != NULL) { Com_Printf("Cmd_AddCommandExtended: %s already defined\n", cmd_name); } return; } // use a small malloc to avoid zone fragmentation cmd = S_Malloc(sizeof(cmd_function_t)); cmd->name = CopyString(cmd_name); cmd->function = function; cmd->complete = complete; cmd->next = cmd_functions; cmd_functions = cmd; if (description && description[0]) { cmd->description = CopyString(description); } else { cmd->description = NULL; } }
/* ============ Cmd_Alias_f ============ */ void Cmd_Alias_f(void) { cmd_alias_t *alias; const char *name; // Get args if (Cmd_Argc() < 2) { Com_Printf("alias <name> : show an alias\n"); Com_Printf("alias <name> <exec> : create an alias\n"); return; } name = Cmd_Argv(1); // Find existing alias for (alias = cmd_aliases; alias; alias = alias->next) { if (!Q_stricmp(name, alias->name)) break; } // Modify/create an alias if (Cmd_Argc() > 2) { cmd_function_t *cmd; // Crude protection from infinite loops if (!Q_stricmp(Cmd_Argv(2), name)) { Com_Printf("Can't make an alias to itself\n"); return; } // Don't allow overriding builtin commands cmd = Cmd_FindCommand( name ); if (cmd && cmd->function != Cmd_RunAlias_f) { Com_Printf("Can't override a builtin function with an alias\n"); return; } // Create/update an alias if (!alias) { alias = (cmd_alias_t*)S_Malloc(sizeof(cmd_alias_t)); alias->name = CopyString(name); alias->exec = CopyString(Cmd_ArgsFrom(2)); alias->next = cmd_aliases; cmd_aliases = alias; Cmd_AddCommand(name, Cmd_RunAlias_f, NULL); } else { // Reallocate the exec string Z_Free(alias->exec); alias->exec = CopyString(Cmd_ArgsFrom(2)); Cmd_AddCommand(name, Cmd_RunAlias_f, NULL); } } // Show the alias if (!alias) Com_Printf("Alias %s does not exist\n", name); else if (Cmd_Argc() == 2) Com_Printf("%s ==> %s\n", alias->name, alias->exec); // update autogen.cfg cvar_modifiedFlags |= CVAR_ARCHIVE; }
/* ============ Cmd_ExecuteString A complete command line has been parsed, so try to execute it FIXME: this function is getting really messy... ============ */ void Cmd_ExecuteString (char *text) { cmd_function_t *cmd; cmd_alias_t *a; int key; static char buf[1024]; cbuf_t *inserttarget; #ifndef SERVERONLY char **s; #endif Cmd_ExpandString (text, buf); Cmd_TokenizeString (buf); // execute the command line if (!Cmd_Argc()) return; // no tokens inserttarget = &cbuf_main; #ifndef SERVERONLY if (cbuf_current == &cbuf_safe) inserttarget = &cbuf_safe; if (cbuf_current == &cbuf_svc) { if (CL_CheckServerCommand()) return; } #endif key = Com_HashKey (cmd_argv[0]); // check functions for (cmd=cmd_hash_array[key] ; cmd ; cmd=cmd->hash_next) { if (!Q_stricmp (cmd_argv[0], cmd->name)) { #ifndef SERVERONLY // special check for msg_trigger commands if (cbuf_current == &cbuf_safe) { for (s = safe_commands; *s; s++) { if (!Q_stricmp(cmd_argv[0], *s)) break; } if (!*s) { if (cl_warncmd.value || developer.value) Com_Printf ("\"%s\" cannot be used in message triggers\n", cmd_argv[0]); return; } } #endif if (cmd->function) cmd->function (); else Cmd_ForwardToServer (); return; } } // some bright guy decided to use "skill" as a mod command in Custom TF, sigh if (!strcmp(Cmd_Argv(0), "skill") && Cmd_Argc() == 1 && Cmd_FindAlias("skill")) goto checkaliases; // check cvars if (Cvar_Command()) return; // check alias checkaliases: for (a=cmd_alias_hash[key] ; a ; a=a->hash_next) { if (!Q_stricmp (cmd_argv[0], a->name)) { #ifndef SERVERONLY if (cbuf_current == &cbuf_svc) { Cbuf_AddText (a->value); Cbuf_AddText ("\n"); } else #endif { Cbuf_InsertTextEx (inserttarget, "\n"); // if the alias value is a command or cvar and // the alias is called with parameters, add them if (Cmd_Argc() > 1 && !strchr(a->value, ' ') && !strchr(a->value, '\t') && (Cvar_FindVar(a->value) || (Cmd_FindCommand(a->value) && a->value[0] != '+' && a->value[0] != '-'))) { Cbuf_InsertTextEx (inserttarget, Cmd_Args()); Cbuf_InsertTextEx (inserttarget, " "); } Cbuf_InsertTextEx (inserttarget, a->value); } return; } } if (Cmd_LegacyCommand()) return; if (!host_initialized && Cmd_Argc() > 1) { if (Cvar_CreateTempVar()) return; } #ifndef SERVERONLY if (cbuf_current != &cbuf_svc) #endif if (cl_warncmd.value || developer.value) Com_Printf ("Unknown command \"%s\"\n", Cmd_Argv(0)); }