mirror of
https://github.com/alliedmodders/amxmodx.git
synced 2024-12-26 06:45:37 +03:00
Add amxclient_cmd native (bug 5887, r=Nextra)
This commit is contained in:
parent
d3f22d2089
commit
9c191949d8
@ -2532,19 +2532,20 @@ static cell AMX_NATIVE_CALL set_user_info(AMX *amx, cell *params) /* 3 param */
|
|||||||
|
|
||||||
static cell AMX_NATIVE_CALL read_argc(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL read_argc(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
return CMD_ARGC();
|
return g_fakecmd.notify ? g_fakecmd.argc : CMD_ARGC();
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL read_argv(AMX *amx, cell *params) /* 3 param */
|
static cell AMX_NATIVE_CALL read_argv(AMX *amx, cell *params) /* 3 param */
|
||||||
{
|
{
|
||||||
const char *value = CMD_ARGV(params[1]);
|
int argc = params[1];
|
||||||
return set_amxstring_utf8(amx, params[2], /*(params[1] < 0 ||
|
|
||||||
params[1] >= CMD_ARGC()) ? "" : */value, strlen(value), params[3] + 1); // + EOS
|
const char *value = g_fakecmd.notify ? (argc >= 0 && argc < 3 ? g_fakecmd.argv[argc] : "") : CMD_ARGV(argc);
|
||||||
|
return set_amxstring_utf8(amx, params[2], value, strlen(value), params[3] + 1); // + EOS
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL read_args(AMX *amx, cell *params) /* 2 param */
|
static cell AMX_NATIVE_CALL read_args(AMX *amx, cell *params) /* 2 param */
|
||||||
{
|
{
|
||||||
const char* sValue = CMD_ARGS();
|
const char* sValue = g_fakecmd.notify ? (g_fakecmd.argc > 1 ? g_fakecmd.args : g_fakecmd.argv[0]) : CMD_ARGS();
|
||||||
return set_amxstring_utf8(amx, params[1], sValue ? sValue : "", sValue ? strlen(sValue) : 0, params[2] + 1); // +EOS
|
return set_amxstring_utf8(amx, params[1], sValue ? sValue : "", sValue ? strlen(sValue) : 0, params[2] + 1); // +EOS
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2715,7 +2716,7 @@ static cell AMX_NATIVE_CALL server_exec(AMX *amx, cell *params)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL engclient_cmd(AMX *amx, cell *params) /* 4 param */
|
int sendFakeCommand(AMX *amx, cell *params, bool fwd = false)
|
||||||
{
|
{
|
||||||
int ilen;
|
int ilen;
|
||||||
const char* szCmd = get_amxstring(amx, params[2], 0, ilen);
|
const char* szCmd = get_amxstring(amx, params[2], 0, ilen);
|
||||||
@ -2736,7 +2737,7 @@ static cell AMX_NATIVE_CALL engclient_cmd(AMX *amx, cell *params) /* 4 param */
|
|||||||
CPlayer* pPlayer = GET_PLAYER_POINTER_I(i);
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(i);
|
||||||
|
|
||||||
if (pPlayer->ingame /*&& pPlayer->initialized */)
|
if (pPlayer->ingame /*&& pPlayer->initialized */)
|
||||||
UTIL_FakeClientCommand(pPlayer->pEdict, szCmd, sArg1, sArg2);
|
UTIL_FakeClientCommand(pPlayer->pEdict, szCmd, sArg1, sArg2, fwd);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int index = params[1];
|
int index = params[1];
|
||||||
@ -2750,11 +2751,20 @@ static cell AMX_NATIVE_CALL engclient_cmd(AMX *amx, cell *params) /* 4 param */
|
|||||||
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
||||||
|
|
||||||
if (/*pPlayer->initialized && */pPlayer->ingame)
|
if (/*pPlayer->initialized && */pPlayer->ingame)
|
||||||
UTIL_FakeClientCommand(pPlayer->pEdict, szCmd, sArg1, sArg2);
|
UTIL_FakeClientCommand(pPlayer->pEdict, szCmd, sArg1, sArg2, fwd);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
static cell AMX_NATIVE_CALL engclient_cmd(AMX *amx, cell *params) /* 4 param */
|
||||||
|
{
|
||||||
|
return sendFakeCommand(amx, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell AMX_NATIVE_CALL amxclient_cmd(AMX *amx, cell *params) /* 4 param */
|
||||||
|
{
|
||||||
|
return sendFakeCommand(amx, params, true);
|
||||||
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL pause(AMX *amx, cell *params) /* 3 param */
|
static cell AMX_NATIVE_CALL pause(AMX *amx, cell *params) /* 3 param */
|
||||||
{
|
{
|
||||||
@ -4886,6 +4896,7 @@ AMX_NATIVE_INFO amxmodx_Natives[] =
|
|||||||
{"admins_lookup", admins_lookup},
|
{"admins_lookup", admins_lookup},
|
||||||
{"admins_num", admins_num},
|
{"admins_num", admins_num},
|
||||||
{"admins_push", admins_push},
|
{"admins_push", admins_push},
|
||||||
|
{"amxclient_cmd", amxclient_cmd},
|
||||||
{"amxx_setpl_curweap", amxx_setpl_curweap},
|
{"amxx_setpl_curweap", amxx_setpl_curweap},
|
||||||
{"arrayset", arrayset},
|
{"arrayset", arrayset},
|
||||||
{"get_addr_val", get_addr_val},
|
{"get_addr_val", get_addr_val},
|
||||||
|
@ -137,7 +137,7 @@ char* UTIL_SplitHudMessage(register const char *src);
|
|||||||
int UTIL_ReadFlags(const char* c);
|
int UTIL_ReadFlags(const char* c);
|
||||||
|
|
||||||
void UTIL_ClientPrint(edict_t *pEntity, int msg_dest, char *msg);
|
void UTIL_ClientPrint(edict_t *pEntity, int msg_dest, char *msg);
|
||||||
void UTIL_FakeClientCommand(edict_t *pEdict, const char *cmd, const char *arg1 = NULL, const char *arg2 = NULL);
|
void UTIL_FakeClientCommand(edict_t *pEdict, const char *cmd, const char *arg1 = NULL, const char *arg2 = NULL, bool fwd = false);
|
||||||
void UTIL_GetFlags(char* flags, int flag);
|
void UTIL_GetFlags(char* flags, int flag);
|
||||||
void UTIL_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, const char *pMessage);
|
void UTIL_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, const char *pMessage);
|
||||||
void UTIL_DHudMessage(edict_t *pEntity, const hudtextparms_t &textparms, const char *pMessage, unsigned int length);
|
void UTIL_DHudMessage(edict_t *pEntity, const hudtextparms_t &textparms, const char *pMessage, unsigned int length);
|
||||||
@ -172,6 +172,7 @@ struct fakecmd_t
|
|||||||
const char *argv[3];
|
const char *argv[3];
|
||||||
int argc;
|
int argc;
|
||||||
bool fake;
|
bool fake;
|
||||||
|
bool notify; // notify to plugins.
|
||||||
};
|
};
|
||||||
|
|
||||||
extern CLog g_log;
|
extern CLog g_log;
|
||||||
|
@ -350,7 +350,7 @@ void UTIL_TeamInfo(edict_t *pEntity, int playerIndex, const char *pszTeamName)
|
|||||||
// 2) Invokes ClientCommand in GameDLL
|
// 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
|
// 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
|
// 4) unsets the global "fake" flag
|
||||||
void UTIL_FakeClientCommand(edict_t *pEdict, const char *cmd, const char *arg1, const char *arg2)
|
void UTIL_FakeClientCommand(edict_t *pEdict, const char *cmd, const char *arg1, const char *arg2, bool fwd)
|
||||||
{
|
{
|
||||||
if (!cmd)
|
if (!cmd)
|
||||||
return; // no command
|
return; // no command
|
||||||
@ -389,6 +389,44 @@ void UTIL_FakeClientCommand(edict_t *pEdict, const char *cmd, const char *arg1,
|
|||||||
else
|
else
|
||||||
g_fakecmd.argc = 1; // no argmuents -> only one command
|
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
|
// set the global "fake" flag so the Cmd_Arg* functions will be superceded
|
||||||
g_fakecmd.fake = true;
|
g_fakecmd.fake = true;
|
||||||
// tell the GameDLL that the client sent a command
|
// tell the GameDLL that the client sent a command
|
||||||
|
@ -446,12 +446,37 @@ native remove_quotes(text[]);
|
|||||||
/* Executes command on player. */
|
/* Executes command on player. */
|
||||||
native client_cmd(index,const command[],any:...);
|
native client_cmd(index,const command[],any:...);
|
||||||
|
|
||||||
/* This is an emulation of a client command (commands aren't send to client!).
|
/**
|
||||||
* It allows to execute some commands on players and bots.
|
* This is an emulation of a client command (commands aren't send to client!).
|
||||||
* Function is excellent for forcing to do an action related to a game (not settings!).
|
* It allows to execute some commands on players and bots.
|
||||||
* The command must stand alone but in arguments you can use spaces. */
|
* Function is excellent for forcing to do an action related to a game (not settings!).
|
||||||
|
* The command must stand alone but in arguments you can use spaces.
|
||||||
|
*
|
||||||
|
* @param index Index of the client, use 0 to send to all clients.
|
||||||
|
* @param command The client command to execute on.
|
||||||
|
* @param arg1 Optionnal. The command arguments.
|
||||||
|
* @param arg2 Optionnal. The command arguments.
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
native engclient_cmd(index,const command[],const arg1[]="",const arg2[]="");
|
native engclient_cmd(index,const command[],const arg1[]="",const arg2[]="");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is an emulation of a client command (commands aren't send to client!).
|
||||||
|
* It allows to execute some commands on players and bots.
|
||||||
|
* Function is excellent for forcing to do an action related to a game (not settings!).
|
||||||
|
* The command must stand alone but in arguments you can use spaces.
|
||||||
|
*
|
||||||
|
* @note This is similar to engclient_cmd with the difference all plugins hooking
|
||||||
|
* the command will be notified as well.
|
||||||
|
*
|
||||||
|
* @param index Index of the client, use 0 to send to all clients.
|
||||||
|
* @param command The client command to execute on.
|
||||||
|
* @param arg1 Optionnal. The command arguments.
|
||||||
|
* @param arg2 Optionnal. The command arguments.
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
native amxclient_cmd(index, const command[], const arg1[] = "", const arg2[] = "");
|
||||||
|
|
||||||
/* Executes command on a server console. */
|
/* Executes command on a server console. */
|
||||||
native server_cmd(const command[],any:...);
|
native server_cmd(const command[],any:...);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user