From: cloudwalk <cloudwalk@d7cf8633-e32d-0410-b094-e92efae38249>
Date: Fri, 24 Jul 2020 16:00:52 +0000 (+0000)
Subject: cmd: Improve automatic assignment of command functions
X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=efe46dafe90be2b41ba9b06778a13204f3a35601;p=xonotic%2Fdarkplaces.git

cmd: Improve automatic assignment of command functions

See the new comment in cmd.h

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@12871 d7cf8633-e32d-0410-b094-e92efae38249
---

diff --git a/cmd.c b/cmd.c
index 6e2b6479..65c81258 100644
--- a/cmd.c
+++ b/cmd.c
@@ -1510,19 +1510,25 @@ void Cmd_Init(void)
 	// client console can see server cvars because the user may start a server
 	cmd_client.cvars = &cvars_all;
 	cmd_client.cvars_flagsmask = CVAR_CLIENT | CVAR_SERVER;
-	cmd_client.cmd_flags = CMD_CLIENT | CMD_CLIENT_FROM_SERVER | CMD_SERVER_FROM_CLIENT;
+	cmd_client.cmd_flags = CMD_CLIENT | CMD_CLIENT_FROM_SERVER;
+	cmd_client.auto_flags = CMD_SERVER_FROM_CLIENT;
+	cmd_client.auto_function = CL_ForwardToServer_f; // FIXME: Move this to the client.
 	cmd_client.userdefined = &cmd_userdefined_all;
 	cmd_client.text_mutex = Thread_CreateMutex();
 	// dedicated server console can only see server cvars, there is no client
 	cmd_server.cvars = &cvars_all;
 	cmd_server.cvars_flagsmask = CVAR_SERVER;
 	cmd_server.cmd_flags = CMD_SERVER;
+	cmd_server.auto_flags = 0;
+	cmd_server.auto_function = NULL;
 	cmd_server.userdefined = &cmd_userdefined_all;
 	cmd_server.text_mutex = Thread_CreateMutex();
 	// server commands received from clients have no reason to access cvars, cvar expansion seems perilous.
 	cmd_serverfromclient.cvars = &cvars_null;
 	cmd_serverfromclient.cvars_flagsmask = 0;
 	cmd_serverfromclient.cmd_flags = CMD_SERVER_FROM_CLIENT | CMD_USERINFO;
+	cmd_serverfromclient.auto_flags = 0;
+	cmd_serverfromclient.auto_function = NULL;
 	cmd_serverfromclient.userdefined = &cmd_userdefined_null;
 	cmd_serverfromclient.text_mutex = Thread_CreateMutex();
 
@@ -1621,7 +1627,6 @@ const char *Cmd_Args (cmd_state_t *cmd)
 	return cmd->args;
 }
 
-
 /*
 ============
 Cmd_TokenizeString
@@ -1693,18 +1698,21 @@ void Cmd_AddCommand(int flags, const char *cmd_name, xcommand_t function, const
 	cmd_function_t *prev, *current;
 	cmd_state_t *cmd;
 	xcommand_t save = NULL;
+	qboolean auto_add = false;
 	int i;
 
 	for (i = 0; i < 3; i++)
 	{
 		cmd = cmd_iter_all[i].cmd;
-		if (flags & cmd->cmd_flags)
+		if ((flags & cmd->cmd_flags) || (flags & cmd->auto_flags))
 		{
-			if(cmd == &cmd_client && (flags & CMD_SERVER_FROM_CLIENT) && !(flags & CMD_CLIENT))
+			if((flags & cmd->auto_flags) && cmd->auto_function)
 			{
 				save = function;
-				function = CL_ForwardToServer_f;
+				function = cmd->auto_function;
+				auto_add = true;
 			}
+
 			// fail if the command is a variable name
 			if (Cvar_FindVar(cmd->cvars, cmd_name, ~0))
 			{
@@ -1719,6 +1727,8 @@ void Cmd_AddCommand(int flags, const char *cmd_name, xcommand_t function, const
 				{
 					if (!strcmp(cmd_name, func->name))
 					{
+						if(func->autofunc && !auto_add)
+							break;
 						Con_Printf("Cmd_AddCommand: %s already defined\n", cmd_name);
 						goto next;
 					}
@@ -1730,6 +1740,7 @@ void Cmd_AddCommand(int flags, const char *cmd_name, xcommand_t function, const
 				func->function = function;
 				func->description = description;
 				func->next = cmd->engine_functions;
+				func->autofunc = auto_add;
 
 				// insert it at the right alphanumeric position
 				for (prev = NULL, current = cmd->engine_functions; current && strcmp(current->name, func->name) < 0; prev = current, current = current->next)
@@ -1761,6 +1772,7 @@ void Cmd_AddCommand(int flags, const char *cmd_name, xcommand_t function, const
 				func->description = description;
 				func->csqcfunc = true; //[515]: csqc
 				func->next = cmd->userdefined->csqc_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)
@@ -1777,6 +1789,7 @@ void Cmd_AddCommand(int flags, const char *cmd_name, xcommand_t function, const
 				function = save;
 		}
 next:
+		auto_add = false;
 		continue;
 	}
 }
diff --git a/cmd.h b/cmd.h
index 2fe4a956..387b24ff 100644
--- a/cmd.h
+++ b/cmd.h
@@ -78,6 +78,7 @@ typedef struct cmd_function_s
 	const char *description;
 	xcommand_t function;
 	qboolean csqcfunc;
+	qboolean autofunc;
 	qboolean initstate; // indicates this command existed at init
 } cmd_function_t;
 
@@ -130,6 +131,16 @@ typedef struct cmd_state_s
 	int cvars_flagsmask; // which CVAR_* flags should be visible to this interpreter? (CVAR_CLIENT | CVAR_SERVER, or just CVAR_SERVER)
 
 	int cmd_flags; // cmd flags that identify this interpreter
+
+	/*
+	 * If a requested flag matches auto_flags, a command will be
+	 * added to a given interpreter with auto_function. For example,
+	 * a CMD_SERVER_FROM_CLIENT command should be automatically added
+	 * to the client interpreter as CL_ForwardToServer_f. It can be
+	 * overridden at any time.
+	 */
+	int auto_flags;
+	xcommand_t auto_function;
 }
 cmd_state_t;
 
@@ -225,6 +236,7 @@ void Cmd_CompleteAliasPrint (cmd_state_t *cmd, const char *partial);
 int Cmd_Argc (cmd_state_t *cmd);
 const char *Cmd_Argv (cmd_state_t *cmd, int arg);
 const char *Cmd_Args (cmd_state_t *cmd);
+const char *Cmd_Args_After(cmd_state_t *cmd, int arg);
 // The functions that execute commands get their parameters with these
 // functions. Cmd_Argv(cmd, ) will return an empty string, not a NULL
 // if arg > argc, so string operations are always safe.