Exemple #1
0
void FakeClientCommand (edict_t *fakeClient, const char *format, ...)
{
   // the purpose of this function is to provide fakeclients (bots) with the same client
   // command-scripting advantages (putting multiple commands in one line between semicolons)
   // as real players. It is an improved version of botman's FakeClientCommand, in which you
   // supply directly the whole string as if you were typing it in the bot's "console". It
   // is supposed to work exactly like the pfnClientCommand (server-sided client command).

   va_list ap;
   static char command[256];
   int start, stop, i, index, stringIndex = 0;

   if (FNullEnt (fakeClient))
      return; // reliability check

   // concatenate all the arguments in one string
   va_start (ap, format);
   _vsnprintf (command, sizeof (command), format, ap);
   va_end (ap);

   if (IsNullString (command))
      return; // if nothing in the command buffer, return

   g_isFakeCommand = true; // set the "fakeclient command" flag
   int length = strlen (command); // get the total length of the command string

   // process all individual commands (separated by a semicolon) one each a time
   while (stringIndex < length)
   {
      start = stringIndex; // save field start position (first character)

      while (stringIndex < length && command[stringIndex] != ';')
         stringIndex++; // reach end of field

      if (command[stringIndex - 1] == '\n')
         stop = stringIndex - 2; // discard any trailing '\n' if needed
      else
         stop = stringIndex - 1; // save field stop position (last character before semicolon or end)

      for (i = start; i <= stop; i++)
         g_fakeArgv[i - start] = command[i]; // store the field value in the g_fakeArgv global string

      g_fakeArgv[i - start] = 0; // terminate the string
      stringIndex++; // move the overall string index one step further to bypass the semicolon

      index = 0;
      g_fakeArgc = 0; // let's now parse that command and count the different arguments

      // count the number of arguments
      while (index < i - start)
      {
         while (index < i - start && g_fakeArgv[index] == ' ')
            index++; // ignore spaces

         // is this field a group of words between quotes or a single word ?
         if (g_fakeArgv[index] == '"')
         {
            index++; // move one step further to bypass the quote

            while (index < i - start && g_fakeArgv[index] != '"')
               index++; // reach end of field

            index++; // move one step further to bypass the quote
         }
         else
            while (index < i - start && g_fakeArgv[index] != ' ')
               index++; // this is a single word, so reach the end of field

         g_fakeArgc++; // we have processed one argument more
      }

      // tell now the MOD DLL to execute this ClientCommand...
      MDLL_ClientCommand (fakeClient);
   }

   g_fakeArgv[0] = 0; // when it's done, reset the g_fakeArgv field
   g_isFakeCommand = false; // reset the "fakeclient command" flag
   g_fakeArgc = 0; // and the argument count
}
Exemple #2
0
// UTIL_FakeClientCommand
// PURPOSE: Sends a fake client command to GameDLL
// HOW DOES IT WORK:
//  1) Stores command and arguments into a global and sets the global "fake" flag to true
//  2) Invokes ClientCommand in GameDLL
//  3) meta_api.cpp overrides Cmd_Args, Cmd_Argv, Cmd_Argc and gives them fake values if the "fake" flag is set
//  4) unsets the global "fake" flag
void UTIL_FakeClientCommand(edict_t *pEdict, const char *cmd, const char *arg1, const char *arg2, bool fwd)
{
	if (!cmd) 
		return;						// no command 

	// store command
	g_fakecmd.argv[0] = cmd;
	// if only arg2 is passed, swap the arguments
	if (!arg1 && arg2)
	{
		arg1 = arg2;
		arg2 = NULL;
	}

	// store arguments
	if (arg2)
	{								// both arguments passed
		g_fakecmd.argc = 3;			// 2 arguments + 1 command
		// store arguments
		g_fakecmd.argv[1] = arg1;
		g_fakecmd.argv[2] = arg2;
		// build argument line
		ke::SafeSprintf(g_fakecmd.args, sizeof(g_fakecmd.args), "%s %s", arg1, arg2);
	}
	else if (arg1)
	{								// only one argument passed
		g_fakecmd.argc = 2;			// 1 argument + 1 command
		// store argument
		g_fakecmd.argv[1] = arg1;
		// build argument line
		ke::SafeSprintf(g_fakecmd.args, sizeof(g_fakecmd.args), "%s", arg1);
	}
	else
		g_fakecmd.argc = 1;			// no argmuents -> only one command

	/* Notify plugins about this command */
	if (fwd)
	{
		/* Set flag so read_argc/v/s functions will give proper value */
		g_fakecmd.notify = true;

		if (executeForwards(FF_ClientCommand, static_cast<cell>(GET_PLAYER_POINTER(pEdict)->index)) > 0)
		{
			g_fakecmd.notify = false;
			return;
		}

		/* check for command and if needed also for first argument and call proper function */
		CmdMngr::iterator aa = g_commands.clcmdprefixbegin(cmd);

		if (!aa)
		{
			aa = g_commands.clcmdbegin();
		}

		while (aa)
		{
			if ((*aa).matchCommandLine(cmd, arg1) && (*aa).getPlugin()->isExecutable((*aa).getFunction()))
			{
				if (executeForwards((*aa).getFunction(), static_cast<cell>(GET_PLAYER_POINTER(pEdict)->index)),
					static_cast<cell>((*aa).getFlags()), static_cast<cell>((*aa).getId()) > 0)
				{
					g_fakecmd.notify = false;
					return;
				}	
			}
			++aa;
		}

		/* Unset flag */
		g_fakecmd.notify = false;
	}
	
	// set the global "fake" flag so the Cmd_Arg* functions will be superceded
	g_fakecmd.fake = true;
	// tell the GameDLL that the client sent a command
	MDLL_ClientCommand(pEdict);
	// unset the global "fake" flag
	g_fakecmd.fake = false;
}