2014-08-04 08:36:20 +00:00
|
|
|
// vim: set ts=4 sw=4 tw=99 noet:
|
|
|
|
//
|
|
|
|
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
|
|
|
|
// Copyright (C) The AMX Mod X Development Team.
|
|
|
|
//
|
|
|
|
// This software is licensed under the GNU General Public License, version 3 or higher.
|
|
|
|
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
|
|
|
|
// https://alliedmods.net/amxmodx-license
|
2004-03-24 01:35:44 +00:00
|
|
|
|
|
|
|
#include <time.h>
|
2017-12-07 23:06:37 +00:00
|
|
|
#include <amtl/am-utility.h>
|
2004-03-24 01:35:44 +00:00
|
|
|
#include "amxmodx.h"
|
2007-09-02 18:35:53 +00:00
|
|
|
#include "CMenu.h"
|
2014-05-21 16:17:09 +00:00
|
|
|
#include "newmenus.h"
|
2005-09-11 04:43:40 +00:00
|
|
|
#include "natives.h"
|
2005-09-26 22:11:44 +00:00
|
|
|
#include "debugger.h"
|
2006-03-15 13:43:06 +00:00
|
|
|
#include "binlog.h"
|
2006-05-07 09:56:06 +00:00
|
|
|
#include "libraries.h"
|
2007-03-09 03:04:40 +00:00
|
|
|
#include "CFlagManager.h"
|
2007-03-03 23:14:24 +00:00
|
|
|
#include "nongpl_matches.h"
|
2007-04-20 03:02:41 +00:00
|
|
|
#include "format.h"
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2007-03-09 03:04:40 +00:00
|
|
|
extern CFlagManager FlagMan;
|
2015-07-11 08:37:36 +00:00
|
|
|
ke::Vector<CAdminData *> DynamicAdmins;
|
2007-03-03 23:14:24 +00:00
|
|
|
|
2004-06-24 07:09:17 +00:00
|
|
|
static cell AMX_NATIVE_CALL get_xvar_id(AMX *amx, cell *params)
|
2004-03-24 01:35:44 +00:00
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int len;
|
2005-09-16 23:48:51 +00:00
|
|
|
char* sName = get_amxstring(amx, params[1], 0, len);
|
2005-09-09 03:23:31 +00:00
|
|
|
cell ptr;
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2015-05-06 09:28:54 +00:00
|
|
|
if (!strcmp(sName, "MaxClients") || !strcmp(sName, "NULL_STRING") || !strcmp(sName, "NULL_VECTOR"))
|
2014-07-19 17:54:57 +00:00
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
for (CPluginMngr::iterator a = g_plugins.begin(); a ; ++a)
|
2005-09-09 03:23:31 +00:00
|
|
|
{
|
2017-03-11 18:26:25 +00:00
|
|
|
if ((*a).isValid() && amx_FindPubVar((*a).getAMX(), sName, &ptr) == AMX_ERR_NONE)
|
2005-09-16 23:48:51 +00:00
|
|
|
return g_xvars.put((*a).getAMX(), get_amxaddr((*a).getAMX(), ptr));
|
2005-09-09 03:23:31 +00:00
|
|
|
}
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return -1;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
2004-06-24 07:09:17 +00:00
|
|
|
static cell AMX_NATIVE_CALL get_xvar_num(AMX *amx, cell *params)
|
2004-03-24 01:35:44 +00:00
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
return g_xvars.getValue(params[1]);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
2004-06-24 07:09:17 +00:00
|
|
|
static cell AMX_NATIVE_CALL set_xvar_num(AMX *amx, cell *params)
|
2004-03-24 01:35:44 +00:00
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
if (g_xvars.setValue(params[1], params[2]))
|
|
|
|
{
|
2006-04-13 16:29:01 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid xvar id");
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
2004-06-24 07:09:17 +00:00
|
|
|
static cell AMX_NATIVE_CALL xvar_exists(AMX *amx, cell *params)
|
2004-03-24 01:35:44 +00:00
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
return (get_xvar_id(amx, params) != -1) ? 1 : 0;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
2004-06-24 07:09:17 +00:00
|
|
|
static cell AMX_NATIVE_CALL emit_sound(AMX *amx, cell *params) /* 7 param */
|
2004-03-24 01:35:44 +00:00
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int len;
|
2005-09-16 23:48:51 +00:00
|
|
|
char* szSample = get_amxstring(amx, params[3], 0, len);
|
2005-09-09 03:23:31 +00:00
|
|
|
REAL vol = amx_ctof(params[4]);
|
|
|
|
REAL att = amx_ctof(params[5]);
|
|
|
|
int channel = params[2];
|
|
|
|
int pitch = params[7];
|
|
|
|
int flags = params[6];
|
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (params[1] == 0)
|
|
|
|
{
|
|
|
|
for (int i = 1; i <= gpGlobals->maxClients ; ++i)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(i);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
if (pPlayer->ingame)
|
2005-09-16 23:48:51 +00:00
|
|
|
EMIT_SOUND_DYN2(pPlayer->pEdict, channel, szSample, vol, att, flags, pitch);
|
2005-09-09 03:23:31 +00:00
|
|
|
}
|
2005-09-16 23:48:51 +00:00
|
|
|
} else {
|
2015-10-07 20:31:01 +00:00
|
|
|
edict_t* pEdict = TypeConversion.id_to_edict(params[1]);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
if (!FNullEnt(pEdict))
|
2005-09-16 23:48:51 +00:00
|
|
|
EMIT_SOUND_DYN2(pEdict, channel, szSample, vol, att, flags, pitch);
|
2005-09-09 03:23:31 +00:00
|
|
|
}
|
2004-06-24 07:09:17 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
2004-06-24 07:09:17 +00:00
|
|
|
static cell AMX_NATIVE_CALL server_print(AMX *amx, cell *params) /* 1 param */
|
2004-03-24 01:35:44 +00:00
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int len;
|
|
|
|
g_langMngr.SetDefLang(LANG_SERVER); // Default language = server
|
2005-09-16 23:48:51 +00:00
|
|
|
char* message = format_amxstring(amx, params, 1, len);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (len > 254)
|
|
|
|
len = 254;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
message[len++] = '\n';
|
|
|
|
message[len] = 0;
|
|
|
|
SERVER_PRINT(message);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return len;
|
2004-06-24 07:02:29 +00:00
|
|
|
}
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
static cell AMX_NATIVE_CALL engclient_print(AMX *amx, cell *params) /* 3 param */
|
2004-06-24 07:09:17 +00:00
|
|
|
{
|
2013-02-13 07:14:37 +00:00
|
|
|
int len = 0;
|
2004-07-28 18:33:20 +00:00
|
|
|
char *msg;
|
2014-08-17 21:31:46 +00:00
|
|
|
PRINT_TYPE type = (PRINT_TYPE)params[2];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2004-07-28 18:33:20 +00:00
|
|
|
if (params[1] == 0)
|
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
for (int i = 1; i <= gpGlobals->maxClients; ++i)
|
2004-07-28 18:33:20 +00:00
|
|
|
{
|
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(i);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2014-08-17 21:31:46 +00:00
|
|
|
if ((type == print_console && pPlayer->initialized) || pPlayer->ingame)
|
2004-07-28 18:33:20 +00:00
|
|
|
{
|
|
|
|
g_langMngr.SetDefLang(i);
|
|
|
|
msg = format_amxstring(amx, params, 3, len);
|
|
|
|
msg[len++] = '\n';
|
|
|
|
msg[len] = 0;
|
2014-08-17 21:31:46 +00:00
|
|
|
CLIENT_PRINT(pPlayer->pEdict, type, msg);
|
2004-07-28 18:33:20 +00:00
|
|
|
}
|
|
|
|
}
|
2005-09-16 23:48:51 +00:00
|
|
|
} else {
|
2004-07-28 18:33:20 +00:00
|
|
|
int index = params[1];
|
2005-09-16 23:48:51 +00:00
|
|
|
|
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
|
|
|
{
|
2005-08-17 17:21:57 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index);
|
2004-07-28 18:33:20 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2004-07-28 18:33:20 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2014-08-17 21:31:46 +00:00
|
|
|
if ((type == print_console && pPlayer->initialized) || pPlayer->ingame)
|
2004-07-28 18:33:20 +00:00
|
|
|
{
|
|
|
|
g_langMngr.SetDefLang(index);
|
|
|
|
msg = format_amxstring(amx, params, 3, len);
|
|
|
|
msg[len++] = '\n';
|
|
|
|
msg[len] = 0;
|
2014-08-17 21:31:46 +00:00
|
|
|
CLIENT_PRINT(pPlayer->pEdict, type, msg);
|
2004-07-28 18:33:20 +00:00
|
|
|
}
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2004-07-28 18:33:20 +00:00
|
|
|
return len;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
2004-06-24 07:09:17 +00:00
|
|
|
static cell AMX_NATIVE_CALL console_cmd(AMX *amx, cell *params) /* 2 param */
|
2004-03-24 01:35:44 +00:00
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
|
|
|
g_langMngr.SetDefLang(index);
|
|
|
|
int len;
|
2005-09-16 23:48:51 +00:00
|
|
|
char* cmd = format_amxstring(amx, params, 2, len);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
cmd[len++] = '\n';
|
|
|
|
cmd[len] = 0;
|
2004-06-24 07:09:17 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
|
|
|
{
|
|
|
|
SERVER_COMMAND(cmd);
|
|
|
|
} else {
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2006-08-24 21:13:52 +00:00
|
|
|
if (!pPlayer->IsBot() && pPlayer->initialized)
|
2005-10-09 15:39:20 +00:00
|
|
|
CLIENT_COMMAND(pPlayer->pEdict, "%s", cmd);
|
2005-09-09 03:23:31 +00:00
|
|
|
}
|
2004-06-24 07:09:17 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return len;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
2013-08-23 22:58:23 +00:00
|
|
|
// The server console is limited to 255 bytes, including the newline.
|
|
|
|
// The client console is limited to 127 bytes, including the newline.
|
2004-06-24 07:09:17 +00:00
|
|
|
static cell AMX_NATIVE_CALL console_print(AMX *amx, cell *params) /* 2 param */
|
2004-06-24 07:02:29 +00:00
|
|
|
{
|
2004-07-28 18:33:20 +00:00
|
|
|
int index = params[1];
|
2013-08-23 22:58:23 +00:00
|
|
|
|
2004-07-28 18:33:20 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
2013-08-23 22:58:23 +00:00
|
|
|
{
|
2004-07-28 18:33:20 +00:00
|
|
|
g_langMngr.SetDefLang(LANG_SERVER);
|
2013-08-23 22:58:23 +00:00
|
|
|
}
|
2004-07-28 18:33:20 +00:00
|
|
|
else
|
2013-08-23 22:58:23 +00:00
|
|
|
{
|
2004-07-28 18:33:20 +00:00
|
|
|
g_langMngr.SetDefLang(index);
|
2013-08-23 22:58:23 +00:00
|
|
|
}
|
2004-07-28 18:33:20 +00:00
|
|
|
|
|
|
|
int len;
|
2005-09-16 23:48:51 +00:00
|
|
|
char* message = format_amxstring(amx, params, 2, len);
|
2013-08-23 22:58:23 +00:00
|
|
|
|
|
|
|
if (index < 1 || index > gpGlobals->maxClients) // Server console
|
|
|
|
{
|
|
|
|
if (len > 254)
|
|
|
|
{
|
|
|
|
len = 254;
|
2014-04-30 07:33:03 +00:00
|
|
|
if ((message[len - 1] & 1 << 7))
|
|
|
|
{
|
|
|
|
len -= UTIL_CheckValidChar(message + len - 1); // Don't truncate a multi-byte character
|
2013-08-23 22:58:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
message[len++] = '\n';
|
|
|
|
message[len] = 0;
|
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
SERVER_PRINT(message);
|
2013-08-23 22:58:23 +00:00
|
|
|
}
|
|
|
|
else // A specific player's console
|
2004-07-28 18:33:20 +00:00
|
|
|
{
|
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2013-08-23 22:58:23 +00:00
|
|
|
|
2018-08-26 15:18:39 +00:00
|
|
|
if (pPlayer->ingame && !pPlayer->IsBot())
|
2013-08-23 22:58:23 +00:00
|
|
|
{
|
|
|
|
if (len > 126) // Client console truncates after byte 127. (126 + \n = 127)
|
|
|
|
{
|
|
|
|
len = 126;
|
2014-04-30 07:33:03 +00:00
|
|
|
if ((message[len - 1] & 1 << 7))
|
2013-08-23 22:58:23 +00:00
|
|
|
{
|
2014-04-30 07:33:03 +00:00
|
|
|
len -= UTIL_CheckValidChar(message + len - 1); // Don't truncate a multi-byte character
|
2013-08-23 22:58:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
message[len++] = '\n'; // Client expects newline from the server
|
|
|
|
message[len] = 0;
|
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
UTIL_ClientPrint(pPlayer->pEdict, 2, message);
|
2013-08-23 22:58:23 +00:00
|
|
|
}
|
2004-07-28 18:33:20 +00:00
|
|
|
}
|
2013-08-23 22:58:23 +00:00
|
|
|
|
2004-07-28 18:33:20 +00:00
|
|
|
return len;
|
2004-06-24 07:02:29 +00:00
|
|
|
}
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2013-08-23 22:58:23 +00:00
|
|
|
// print_notify and print_console are limited to 127 bytes, including the newline.
|
|
|
|
// print_chat and print_center are not limited by *this* function.
|
2004-06-24 07:09:17 +00:00
|
|
|
static cell AMX_NATIVE_CALL client_print(AMX *amx, cell *params) /* 3 param */
|
|
|
|
{
|
2004-08-13 08:46:04 +00:00
|
|
|
int len = 0;
|
2004-07-28 18:33:20 +00:00
|
|
|
char *msg;
|
2013-08-23 22:58:23 +00:00
|
|
|
|
|
|
|
if (params[1] == 0) // 0 = All players
|
2004-07-28 18:33:20 +00:00
|
|
|
{
|
|
|
|
for (int i = 1; i <= gpGlobals->maxClients; ++i)
|
|
|
|
{
|
|
|
|
CPlayer *pPlayer = GET_PLAYER_POINTER_I(i);
|
2013-08-23 22:58:23 +00:00
|
|
|
|
2018-08-26 15:18:39 +00:00
|
|
|
if (pPlayer->ingame && !pPlayer->IsBot())
|
2004-07-28 18:33:20 +00:00
|
|
|
{
|
|
|
|
g_langMngr.SetDefLang(i);
|
|
|
|
msg = format_amxstring(amx, params, 3, len);
|
2013-08-23 22:58:23 +00:00
|
|
|
|
|
|
|
// params[2]: print_notify = 1, print_console = 2, print_chat = 3, print_center = 4
|
|
|
|
if (((params[2] == 1) || (params[2] == 2)) && (len > 126)) // Client console truncates after byte 127. (126 + \n = 127)
|
|
|
|
{
|
|
|
|
len = 126;
|
2014-04-30 07:33:03 +00:00
|
|
|
if ((msg[len - 1] & 1 << 7))
|
2013-08-23 22:58:23 +00:00
|
|
|
{
|
2014-04-30 07:33:03 +00:00
|
|
|
len -= UTIL_CheckValidChar(msg + len - 1); // Don't truncate a multi-byte character
|
2013-08-23 22:58:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
msg[len++] = '\n'; // Client expects newline from the server
|
2004-07-28 18:33:20 +00:00
|
|
|
msg[len] = 0;
|
2013-08-23 22:58:23 +00:00
|
|
|
|
2004-08-19 16:37:15 +00:00
|
|
|
UTIL_ClientPrint(pPlayer->pEdict, params[2], msg);
|
2004-07-28 18:33:20 +00:00
|
|
|
}
|
|
|
|
}
|
2013-08-23 22:58:23 +00:00
|
|
|
}
|
|
|
|
else // A specific player
|
|
|
|
{
|
2004-07-28 18:33:20 +00:00
|
|
|
int index = params[1];
|
2013-08-23 22:58:23 +00:00
|
|
|
|
2004-07-28 18:33:20 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
|
|
|
{
|
2005-08-17 17:21:57 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index);
|
2004-07-28 18:33:20 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2013-08-23 22:58:23 +00:00
|
|
|
|
2004-07-28 18:33:20 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2013-08-23 22:58:23 +00:00
|
|
|
|
2018-08-26 15:18:39 +00:00
|
|
|
if (pPlayer->ingame && !pPlayer->IsBot())
|
2013-08-23 22:58:23 +00:00
|
|
|
{
|
|
|
|
g_langMngr.SetDefLang(index);
|
|
|
|
|
|
|
|
msg = format_amxstring(amx, params, 3, len);
|
|
|
|
|
|
|
|
// params[2]: print_notify = 1, print_console = 2, print_chat = 3, print_center = 4
|
|
|
|
if (((params[2] == 1) || (params[2] == 2)) && (len > 126)) // Client console truncates after byte 127. (126 + \n = 127)
|
|
|
|
{
|
|
|
|
len = 126;
|
2014-04-30 07:33:03 +00:00
|
|
|
if ((msg[len - 1] & 1 << 7))
|
2013-08-23 22:58:23 +00:00
|
|
|
{
|
2014-04-30 07:33:03 +00:00
|
|
|
len -= UTIL_CheckValidChar(msg + len - 1); // Don't truncate a multi-byte character
|
2013-08-23 22:58:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
msg[len++] = '\n'; // Client expects newline from the server
|
|
|
|
msg[len] = 0;
|
|
|
|
|
|
|
|
UTIL_ClientPrint(pPlayer->pEdict, params[2], msg);
|
|
|
|
}
|
2004-07-28 18:33:20 +00:00
|
|
|
}
|
2013-08-23 22:58:23 +00:00
|
|
|
|
2004-07-28 18:33:20 +00:00
|
|
|
return len;
|
2004-06-24 07:09:17 +00:00
|
|
|
}
|
|
|
|
|
2013-08-23 23:03:13 +00:00
|
|
|
static cell AMX_NATIVE_CALL client_print_color(AMX *amx, cell *params) /* 3 param */
|
|
|
|
{
|
|
|
|
if (!g_bmod_cstrike)
|
|
|
|
{
|
|
|
|
params[2] = print_chat;
|
|
|
|
return client_print(amx, params);
|
|
|
|
}
|
|
|
|
|
|
|
|
int len = 0;
|
|
|
|
char *msg;
|
|
|
|
int index = params[1];
|
|
|
|
int sender = params[2];
|
|
|
|
|
2017-03-11 18:26:25 +00:00
|
|
|
if (sender < print_team_blue || sender > gpGlobals->maxClients)
|
2013-08-23 23:03:13 +00:00
|
|
|
{
|
|
|
|
sender = print_team_default;
|
|
|
|
}
|
|
|
|
else if (sender < print_team_default)
|
|
|
|
{
|
|
|
|
sender = abs(sender) + 32; // align indexes to the TeamInfo ones.
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!index)
|
|
|
|
{
|
|
|
|
for (int i = 1; i <= gpGlobals->maxClients; ++i)
|
|
|
|
{
|
|
|
|
CPlayer *pPlayer = GET_PLAYER_POINTER_I(i);
|
|
|
|
|
|
|
|
if (pPlayer->ingame && !pPlayer->IsBot())
|
|
|
|
{
|
|
|
|
g_langMngr.SetDefLang(i);
|
|
|
|
msg = format_amxstring(amx, params, 3, len);
|
2014-04-30 07:33:03 +00:00
|
|
|
|
2018-07-24 13:45:50 +00:00
|
|
|
if (static_cast<byte>(*msg) > 4) // Insert default color code at the start if not present, otherwise message will not be colored.
|
2016-01-16 11:09:13 +00:00
|
|
|
{
|
|
|
|
memmove(msg + 1, msg, ke::Min(len++, 191));
|
|
|
|
*msg = 1;
|
|
|
|
}
|
|
|
|
|
2014-04-30 07:33:03 +00:00
|
|
|
if (len > 190) // Server crashes after byte 190. (190 + \n = 191)
|
|
|
|
{
|
|
|
|
len = 190;
|
|
|
|
if ((msg[len - 1] & 1 << 7))
|
|
|
|
{
|
|
|
|
len -= UTIL_CheckValidChar(msg + len - 1); // Don't truncate a multi-byte character
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-23 23:03:13 +00:00
|
|
|
msg[len++] = '\n';
|
|
|
|
msg[len] = 0;
|
|
|
|
|
|
|
|
UTIL_ClientSayText(pPlayer->pEdict, sender ? sender : i, msg);
|
|
|
|
}
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
}
|
2013-08-23 23:03:13 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
|
|
|
{
|
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2013-08-23 23:03:13 +00:00
|
|
|
if (pPlayer->ingame && !pPlayer->IsBot())
|
|
|
|
{
|
|
|
|
g_langMngr.SetDefLang(index);
|
|
|
|
|
|
|
|
msg = format_amxstring(amx, params, 3, len);
|
2014-04-30 07:33:03 +00:00
|
|
|
|
2018-07-24 13:45:50 +00:00
|
|
|
if (static_cast<byte>(*msg) > 4) // Insert default color code at the start if not present, otherwise message will not be colored.
|
2016-01-16 11:09:13 +00:00
|
|
|
{
|
|
|
|
memmove(msg + 1, msg, ke::Min(len++, 191));
|
|
|
|
*msg = 1;
|
|
|
|
}
|
|
|
|
|
2014-04-30 07:33:03 +00:00
|
|
|
if (len > 190) // Server crashes after byte 190. (190 + \n = 191)
|
|
|
|
{
|
|
|
|
len = 190;
|
|
|
|
if ((msg[len - 1] & 1 << 7))
|
|
|
|
{
|
|
|
|
len -= UTIL_CheckValidChar(msg + len - 1); // Don't truncate a multi-byte character
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-23 23:03:13 +00:00
|
|
|
msg[len++] = '\n';
|
|
|
|
msg[len] = 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2013-08-23 23:03:13 +00:00
|
|
|
UTIL_ClientSayText(pPlayer->pEdict, sender ? sender : index, msg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
static cell AMX_NATIVE_CALL show_motd(AMX *amx, cell *params) /* 3 param */
|
2004-06-24 07:09:17 +00:00
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int ilen;
|
2005-09-16 23:48:51 +00:00
|
|
|
const char* szHead = get_amxstring(amx, params[3], 0, ilen);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (!ilen)
|
|
|
|
szHead = hostname->string;
|
|
|
|
|
|
|
|
char* szBody = get_amxstring(amx, params[2], 1, ilen);
|
2005-09-09 03:23:31 +00:00
|
|
|
int iFile = 0;
|
|
|
|
char* sToShow = NULL; // = szBody;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (ilen < 128)
|
|
|
|
sToShow = (char*)LOAD_FILE_FOR_ME(szBody, &iFile);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
if (!iFile)
|
|
|
|
sToShow = szBody;
|
|
|
|
else
|
|
|
|
ilen = iFile;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (params[1] == 0)
|
|
|
|
{
|
|
|
|
for (int i = 1; i <= gpGlobals->maxClients; ++i)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(i);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2018-08-26 15:18:39 +00:00
|
|
|
if (pPlayer->ingame && !pPlayer->IsBot())
|
2005-09-16 23:48:51 +00:00
|
|
|
UTIL_ShowMOTD(pPlayer->pEdict, sToShow, ilen, szHead);
|
2005-09-09 03:23:31 +00:00
|
|
|
}
|
2005-09-16 23:48:51 +00:00
|
|
|
} else {
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index);
|
2005-09-16 23:48:51 +00:00
|
|
|
if (iFile)
|
|
|
|
FREE_FILE(sToShow);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2018-08-26 15:18:39 +00:00
|
|
|
if (pPlayer->ingame && !pPlayer->IsBot())
|
2005-09-16 23:48:51 +00:00
|
|
|
UTIL_ShowMOTD(pPlayer->pEdict, sToShow, ilen, szHead);
|
2005-09-09 03:23:31 +00:00
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (iFile)
|
|
|
|
FREE_FILE(sToShow);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
2004-06-24 07:09:17 +00:00
|
|
|
}
|
|
|
|
|
2005-11-19 01:25:34 +00:00
|
|
|
static cell AMX_NATIVE_CALL next_hudchannel(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
int index = params[1];
|
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
|
|
|
{
|
2016-11-25 10:26:58 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid player %d", index);
|
2005-11-19 01:25:34 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
CPlayer *pPlayer = GET_PLAYER_POINTER_I(index);
|
|
|
|
if (!pPlayer->ingame)
|
|
|
|
{
|
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Player %d not in game", index);
|
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-11-19 01:25:34 +00:00
|
|
|
return pPlayer->NextHUDChannel();
|
|
|
|
}
|
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
static cell AMX_NATIVE_CALL set_hudmessage(AMX *amx, cell *params) /* 11 param */
|
2004-06-24 07:09:17 +00:00
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
g_hudset.a1 = 0;
|
|
|
|
g_hudset.a2 = 0;
|
|
|
|
g_hudset.r2 = 255;
|
|
|
|
g_hudset.g2 = 255;
|
|
|
|
g_hudset.b2 = 250;
|
|
|
|
g_hudset.r1 = static_cast<byte>(params[1]);
|
|
|
|
g_hudset.g1 = static_cast<byte>(params[2]);
|
|
|
|
g_hudset.b1 = static_cast<byte>(params[3]);
|
|
|
|
g_hudset.x = amx_ctof(params[4]);
|
|
|
|
g_hudset.y = amx_ctof(params[5]);
|
|
|
|
g_hudset.effect = params[6];
|
|
|
|
g_hudset.fxTime = amx_ctof(params[7]);
|
|
|
|
g_hudset.holdTime = amx_ctof(params[8]);
|
|
|
|
g_hudset.fadeinTime = amx_ctof(params[9]);
|
|
|
|
g_hudset.fadeoutTime = amx_ctof(params[10]);
|
|
|
|
g_hudset.channel = params[11];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
2004-06-24 07:09:17 +00:00
|
|
|
}
|
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
static cell AMX_NATIVE_CALL show_hudmessage(AMX *amx, cell *params) /* 2 param */
|
2004-06-24 07:09:17 +00:00
|
|
|
{
|
2006-02-28 09:43:20 +00:00
|
|
|
int len = 0;
|
2004-08-19 16:37:15 +00:00
|
|
|
g_langMngr.SetDefLang(params[1]);
|
|
|
|
char* message = NULL;
|
2006-05-22 00:00:11 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Earlier versions would ignore invalid bounds.
|
|
|
|
* Now, bounds are only checked for internal operations.
|
|
|
|
* "channel" stores the valid channel that core uses.
|
|
|
|
* "g_hudset.channel" stores the direct channel passed to the engine.
|
|
|
|
*/
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-11-19 01:25:34 +00:00
|
|
|
bool aut = (g_hudset.channel == -1) ? true : false;
|
2006-05-22 00:00:11 +00:00
|
|
|
int channel = -1;
|
|
|
|
if (!aut)
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* guarantee this to be between 0-4
|
|
|
|
* if it's not auto, we don't care
|
|
|
|
*/
|
|
|
|
channel = abs(g_hudset.channel % 5);
|
|
|
|
}
|
2004-08-19 16:37:15 +00:00
|
|
|
if (params[1] == 0)
|
|
|
|
{
|
|
|
|
for (int i = 1; i <= gpGlobals->maxClients; ++i)
|
|
|
|
{
|
|
|
|
CPlayer *pPlayer = GET_PLAYER_POINTER_I(i);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2018-08-26 15:18:39 +00:00
|
|
|
if (pPlayer->ingame && !pPlayer->IsBot())
|
2004-08-19 16:37:15 +00:00
|
|
|
{
|
|
|
|
g_langMngr.SetDefLang(i);
|
|
|
|
message = UTIL_SplitHudMessage(format_amxstring(amx, params, 2, len));
|
2005-11-19 01:25:34 +00:00
|
|
|
if (aut)
|
|
|
|
{
|
2006-05-22 00:00:11 +00:00
|
|
|
channel = pPlayer->NextHUDChannel();
|
|
|
|
pPlayer->channels[channel] = gpGlobals->time;
|
|
|
|
g_hudset.channel = channel;
|
2005-11-19 01:25:34 +00:00
|
|
|
}
|
2006-05-22 00:00:11 +00:00
|
|
|
//don't need to set g_hudset!
|
|
|
|
pPlayer->hudmap[channel] = 0;
|
2004-08-19 16:37:15 +00:00
|
|
|
UTIL_HudMessage(pPlayer->pEdict, g_hudset, message);
|
|
|
|
}
|
|
|
|
}
|
2005-09-16 23:48:51 +00:00
|
|
|
} else {
|
|
|
|
message = UTIL_SplitHudMessage(format_amxstring(amx, params, 2, len));
|
2004-08-19 16:37:15 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
|
|
|
{
|
2005-08-17 17:21:57 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index);
|
2004-08-19 16:37:15 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2004-08-19 16:37:15 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2018-08-26 15:18:39 +00:00
|
|
|
if (pPlayer->ingame && !pPlayer->IsBot())
|
2005-11-19 01:25:34 +00:00
|
|
|
{
|
|
|
|
if (aut)
|
|
|
|
{
|
2006-05-22 00:00:11 +00:00
|
|
|
channel = pPlayer->NextHUDChannel();
|
|
|
|
pPlayer->channels[channel] = gpGlobals->time;
|
|
|
|
g_hudset.channel = channel;
|
2005-11-19 01:25:34 +00:00
|
|
|
}
|
2006-05-22 00:00:11 +00:00
|
|
|
pPlayer->hudmap[channel] = 0;
|
2005-09-16 23:48:51 +00:00
|
|
|
UTIL_HudMessage(pPlayer->pEdict, g_hudset, message);
|
2005-11-19 01:25:34 +00:00
|
|
|
}
|
2004-08-19 16:37:15 +00:00
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2004-08-19 16:37:15 +00:00
|
|
|
return len;
|
2004-06-24 07:09:17 +00:00
|
|
|
}
|
|
|
|
|
2014-04-11 19:54:24 +00:00
|
|
|
static cell AMX_NATIVE_CALL set_dhudmessage(AMX *amx, cell *params) /* 10 param */
|
|
|
|
{
|
|
|
|
g_hudset.a1 = 0;
|
|
|
|
g_hudset.a2 = 0;
|
|
|
|
g_hudset.r2 = 255;
|
|
|
|
g_hudset.g2 = 255;
|
|
|
|
g_hudset.b2 = 250;
|
|
|
|
g_hudset.r1 = static_cast<byte>(params[1]);
|
|
|
|
g_hudset.g1 = static_cast<byte>(params[2]);
|
|
|
|
g_hudset.b1 = static_cast<byte>(params[3]);
|
|
|
|
g_hudset.x = amx_ctof(params[4]);
|
|
|
|
g_hudset.y = amx_ctof(params[5]);
|
2015-10-20 08:34:18 +00:00
|
|
|
g_hudset.effect = params[6];
|
2014-04-11 19:54:24 +00:00
|
|
|
g_hudset.fxTime = amx_ctof(params[7]);
|
|
|
|
g_hudset.holdTime = amx_ctof(params[8]);
|
|
|
|
g_hudset.fadeinTime = amx_ctof(params[9]);
|
|
|
|
g_hudset.fadeoutTime = amx_ctof(params[10]);
|
|
|
|
g_hudset.channel = -1;
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL show_dhudmessage(AMX *amx, cell *params) /* 2 param */
|
|
|
|
{
|
|
|
|
int len = 0;
|
|
|
|
int index = params[1];
|
|
|
|
char *message;
|
|
|
|
|
|
|
|
if (!index)
|
|
|
|
{
|
|
|
|
for (int i = 1; i <= gpGlobals->maxClients; ++i)
|
|
|
|
{
|
|
|
|
CPlayer *pPlayer = GET_PLAYER_POINTER_I(i);
|
|
|
|
|
|
|
|
if (pPlayer->ingame && !pPlayer->IsBot())
|
|
|
|
{
|
|
|
|
g_langMngr.SetDefLang(i);
|
|
|
|
message = format_amxstring(amx, params, 2, len);
|
|
|
|
|
|
|
|
if (len > 127) // Client truncates after byte 127.
|
|
|
|
{
|
|
|
|
len = 127;
|
|
|
|
|
|
|
|
// Don't truncate a double-byte character
|
|
|
|
if (((message[len - 1] & 0xFF) >= 0xC2) && ((message[len - 1] & 0xFF) <= 0xEF))
|
|
|
|
{
|
|
|
|
len--;
|
|
|
|
}
|
|
|
|
|
|
|
|
message[len] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
UTIL_DHudMessage(pPlayer->pEdict, g_hudset, message, len);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
|
|
|
{
|
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
|
|
|
|
|
|
|
if (pPlayer->ingame && !pPlayer->IsBot())
|
|
|
|
{
|
|
|
|
g_langMngr.SetDefLang(index);
|
|
|
|
message = format_amxstring(amx, params, 2, len);
|
|
|
|
|
|
|
|
if (len > 127) // Client truncates after byte 127.
|
|
|
|
{
|
|
|
|
len = 127;
|
|
|
|
|
|
|
|
// Don't truncate a double-byte character
|
2017-03-11 18:26:25 +00:00
|
|
|
if (((message[len - 1] & 0xFF) >= 0xC2) && ((message[len - 1] & 0xFF) <= 0xEF))
|
2014-04-11 19:54:24 +00:00
|
|
|
{
|
|
|
|
--len;
|
|
|
|
}
|
|
|
|
|
|
|
|
message[len] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
UTIL_DHudMessage(pPlayer->pEdict, g_hudset, message, len);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
static cell AMX_NATIVE_CALL get_user_name(AMX *amx, cell *params) /* 3 param */
|
2004-06-24 07:09:17 +00:00
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2015-06-29 09:28:11 +00:00
|
|
|
int maxlen = params[3];
|
2014-11-13 18:01:26 +00:00
|
|
|
|
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
|
|
|
return set_amxstring_utf8(amx, params[2], hostname->string, strlen(hostname->string), maxlen);
|
|
|
|
else
|
2015-07-11 08:37:36 +00:00
|
|
|
return set_amxstring_utf8(amx, params[2], g_players[index].name.chars(), g_players[index].name.length(), maxlen);
|
2004-06-24 07:09:17 +00:00
|
|
|
}
|
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
static cell AMX_NATIVE_CALL get_user_index(AMX *amx, cell *params) /* 1 param */
|
2004-06-24 07:09:17 +00:00
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int i;
|
2005-09-16 23:48:51 +00:00
|
|
|
char* sptemp = get_amxstring(amx, params[1], 0, i);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
for (i = 1; i <= gpGlobals->maxClients; ++i)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(i);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2015-07-11 08:37:36 +00:00
|
|
|
if (strcmp(pPlayer->name.chars(), sptemp) == 0)
|
2005-09-09 03:23:31 +00:00
|
|
|
return i;
|
|
|
|
}
|
2004-06-24 07:09:17 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL is_dedicated_server(AMX *amx, cell *params)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
return (IS_DEDICATED_SERVER() ? 1 : 0);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL is_linux_server(AMX *amx, cell *params)
|
|
|
|
{
|
2013-02-13 07:14:37 +00:00
|
|
|
#if defined(__linux__) || defined(__APPLE__)
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
2004-03-24 01:35:44 +00:00
|
|
|
#else
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2004-03-24 01:35:44 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2004-09-21 02:40:30 +00:00
|
|
|
static cell AMX_NATIVE_CALL is_amd64_server(AMX *amx, cell *params)
|
|
|
|
{
|
2005-07-25 06:03:43 +00:00
|
|
|
#if PAWN_CELL_SIZE==64
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
2004-09-21 02:40:30 +00:00
|
|
|
#else
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2004-09-21 02:40:30 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2004-07-21 19:59:39 +00:00
|
|
|
static cell AMX_NATIVE_CALL is_jit_enabled(AMX *amx, cell *params) // PM: Useless ;P
|
|
|
|
{
|
|
|
|
#ifdef JIT
|
|
|
|
return 1;
|
|
|
|
#else
|
|
|
|
return 0;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
static cell AMX_NATIVE_CALL is_map_valid(AMX *amx, cell *params) /* 1 param */
|
2004-03-24 01:35:44 +00:00
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int ilen;
|
2005-09-16 23:48:51 +00:00
|
|
|
return (IS_MAP_VALID(get_amxstring(amx, params[1], 0, ilen)) ? 1 : 0);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL is_user_connected(AMX *amx, cell *params) /* 1 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return (pPlayer->ingame ? 1 : 0);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL is_user_connecting(AMX *amx, cell *params) /* 1 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
return (!pPlayer->ingame && pPlayer->initialized && (GETPLAYERUSERID(pPlayer->pEdict) > 0)) ? 1 : 0;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL is_user_bot(AMX *amx, cell *params) /* 1 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2006-08-24 21:13:52 +00:00
|
|
|
return (GET_PLAYER_POINTER_I(index)->IsBot() ? 1 : 0);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL is_user_hltv(AMX *amx, cell *params) /* 1 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer *pPlayer = GET_PLAYER_POINTER_I(index);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
if (!pPlayer->initialized)
|
|
|
|
return 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
if (pPlayer->pEdict->v.flags & FL_PROXY)
|
|
|
|
return 1;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
const char *authid = GETPLAYERAUTHID(pPlayer->pEdict);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
if (authid && stricmp(authid, "HLTV") == 0)
|
|
|
|
return 1;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
2006-09-21 23:33:05 +00:00
|
|
|
extern bool g_bmod_tfc;
|
2004-03-24 01:35:44 +00:00
|
|
|
static cell AMX_NATIVE_CALL is_user_alive(AMX *amx, cell *params) /* 1 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
2006-09-21 23:33:05 +00:00
|
|
|
{
|
2018-08-26 15:18:39 +00:00
|
|
|
return FALSE;
|
2006-09-21 23:33:05 +00:00
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2006-09-21 23:33:05 +00:00
|
|
|
|
2018-08-26 15:18:39 +00:00
|
|
|
if (!pPlayer->ingame)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2006-09-21 23:33:05 +00:00
|
|
|
if (g_bmod_tfc)
|
|
|
|
{
|
|
|
|
edict_t *e = pPlayer->pEdict;
|
2017-03-11 18:26:25 +00:00
|
|
|
if (e->v.flags & FL_SPECTATOR ||
|
2006-09-21 23:33:05 +00:00
|
|
|
(!e->v.team || !e->v.playerclass))
|
|
|
|
{
|
2018-08-26 15:18:39 +00:00
|
|
|
return FALSE;
|
2006-09-21 23:33:05 +00:00
|
|
|
}
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2018-08-26 15:18:39 +00:00
|
|
|
return pPlayer->IsAlive() ? TRUE : FALSE;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
2006-04-25 17:19:58 +00:00
|
|
|
static cell AMX_NATIVE_CALL get_amxx_verstring(AMX *amx, cell *params) /* 2 params */
|
|
|
|
{
|
2014-12-08 00:41:52 +00:00
|
|
|
return set_amxstring(amx, params[1], AMXX_VERSION, params[2]);
|
2006-04-25 17:19:58 +00:00
|
|
|
}
|
|
|
|
|
2004-03-24 01:35:44 +00:00
|
|
|
static cell AMX_NATIVE_CALL get_user_frags(AMX *amx, cell *params) /* 1 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return (cell)(pPlayer->ingame ? pPlayer->pEdict->v.frags : 0);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL get_user_deaths(AMX *amx, cell *params) /* 1 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return (cell)(pPlayer->ingame ? pPlayer->deaths : 0);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL get_user_armor(AMX *amx, cell *params) /* 1 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return (cell)(pPlayer->ingame ? pPlayer->pEdict->v.armorvalue : 0);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
static cell AMX_NATIVE_CALL get_user_health(AMX *amx, cell *params) /* param */
|
2004-03-24 01:35:44 +00:00
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return (cell)(pPlayer->ingame ? pPlayer->pEdict->v.health : 0);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL get_user_userid(AMX *amx, cell *params) /* 1 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return pPlayer->initialized ? GETPLAYERUSERID(pPlayer->pEdict) : -1;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL get_user_authid(AMX *amx, cell *params) /* 3 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
|
|
|
const char* authid = 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index > 0 && index <= gpGlobals->maxClients)
|
2005-09-09 03:23:31 +00:00
|
|
|
authid = GETPLAYERAUTHID(g_players[index].pEdict);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
return set_amxstring(amx, params[2], authid ? authid : "", params[3]);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL is_user_authorized(AMX *amx, cell *params)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
|
|
|
return 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return GET_PLAYER_POINTER_I(index)->authorized;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL get_weaponname(AMX *amx, cell *params) /* 3 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 1 || index >= MAX_WEAPONS)
|
|
|
|
{
|
2005-09-28 22:10:11 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid weapon id %d", index);
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2015-07-11 08:37:36 +00:00
|
|
|
return set_amxstring(amx, params[2], g_weaponsData[index].fullName.chars(), params[3]);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
2006-05-13 14:59:24 +00:00
|
|
|
static cell AMX_NATIVE_CALL get_weaponid(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
int ilen;
|
|
|
|
const char *name = get_amxstring(amx, params[1], 0, ilen);
|
|
|
|
|
2006-05-17 13:44:58 +00:00
|
|
|
for (int i = 1; i < MAX_WEAPONS; i++)
|
2006-05-13 14:59:24 +00:00
|
|
|
{
|
2015-07-11 08:37:36 +00:00
|
|
|
if (!strcmp(g_weaponsData[i].fullName.chars(), name))
|
2006-05-13 14:59:24 +00:00
|
|
|
return g_weaponsData[i].iId;
|
|
|
|
}
|
|
|
|
|
2006-05-17 13:44:58 +00:00
|
|
|
return 0;
|
2006-05-13 14:59:24 +00:00
|
|
|
}
|
|
|
|
|
2004-03-24 01:35:44 +00:00
|
|
|
static cell AMX_NATIVE_CALL get_user_weapons(AMX *amx, cell *params) /* 3 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index);
|
|
|
|
return 0;
|
|
|
|
}
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (pPlayer->ingame)
|
|
|
|
{
|
|
|
|
cell *cpNum = get_amxaddr(amx, params[3]);
|
|
|
|
cell *cpIds = get_amxaddr(amx, params[2]);
|
2005-09-09 03:23:31 +00:00
|
|
|
*cpIds = 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
int weapons = pPlayer->pEdict->v.weapons & ~(1<<31); // don't count last element
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2007-06-22 17:10:21 +00:00
|
|
|
if (g_bmod_dod)
|
|
|
|
{
|
|
|
|
// Don't ignore that last element for dod
|
|
|
|
weapons = pPlayer->pEdict->v.weapons;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
for (int i = 1; i < MAX_WEAPONS; ++i)
|
2005-09-09 03:23:31 +00:00
|
|
|
{
|
|
|
|
if (weapons & (1<<i))
|
|
|
|
{
|
|
|
|
*(cpIds+(*cpNum)) = i;
|
|
|
|
(*cpNum)++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return weapons;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL get_user_origin(AMX *amx, cell *params) /* 3 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index);
|
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (pPlayer->ingame)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int mode = params[3];
|
2005-09-16 23:48:51 +00:00
|
|
|
cell *cpOrigin = get_amxaddr(amx, params[2]);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (mode == 4)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
cpOrigin[0] = (long int)pPlayer->lastHit.x;
|
|
|
|
cpOrigin[1] = (long int)pPlayer->lastHit.y;
|
|
|
|
cpOrigin[2] = (long int)pPlayer->lastHit.z;
|
|
|
|
return 1;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
edict_t* edict = pPlayer->pEdict;
|
|
|
|
Vector pos = edict->v.origin;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (mode && mode != 2)
|
2005-09-09 03:23:31 +00:00
|
|
|
pos = pos + edict->v.view_ofs;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (mode > 1)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
Vector vec;
|
|
|
|
Vector v_angle = edict->v.v_angle;
|
|
|
|
float v_vec[3];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
v_vec[0] = v_angle.x;
|
|
|
|
v_vec[1] = v_angle.y;
|
|
|
|
v_vec[2] = v_angle.z;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
ANGLEVECTORS(v_vec, vec, NULL, NULL);
|
2005-09-09 03:23:31 +00:00
|
|
|
TraceResult trEnd;
|
2005-09-16 23:48:51 +00:00
|
|
|
Vector v_dest = pos + vec * 9999;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
float f_pos[3];
|
|
|
|
f_pos[0] = pos.x;
|
|
|
|
f_pos[1] = pos.y;
|
|
|
|
f_pos[2] = pos.z;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
float f_dest[3];
|
|
|
|
f_dest[0] = v_dest.x;
|
|
|
|
f_dest[1] = v_dest.y;
|
|
|
|
f_dest[2] = v_dest.z;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
TRACE_LINE(f_pos, f_dest, 0, edict, &trEnd);
|
|
|
|
pos = (trEnd.flFraction < 1.0) ? trEnd.vecEndPos : Vector(0, 0, 0);
|
2005-09-09 03:23:31 +00:00
|
|
|
}
|
|
|
|
cpOrigin[0] = (long int)pos.x;
|
|
|
|
cpOrigin[1] = (long int)pos.y;
|
|
|
|
cpOrigin[2] = (long int)pos.z;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL get_user_ip(AMX *amx, cell *params) /* 3 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
|
|
|
char *ptr;
|
|
|
|
char szIp[32];
|
2015-07-11 08:37:36 +00:00
|
|
|
strcpy(szIp, (index < 1 || index > gpGlobals->maxClients) ? CVAR_GET_STRING("net_address") : g_players[index].ip.chars());
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (params[4] && (ptr = strstr(szIp, ":")) != 0)
|
2005-09-09 03:23:31 +00:00
|
|
|
*ptr = '\0';
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
return set_amxstring(amx, params[2], szIp, params[3]);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL get_user_attacker(AMX *amx, cell *params) /* 2 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index);
|
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
|
|
|
edict_t *enemy = NULL;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (pPlayer->ingame)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
enemy = pPlayer->pEdict->v.dmg_inflictor;
|
2005-09-16 23:48:51 +00:00
|
|
|
if (!FNullEnt(enemy))
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int weapon = 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (enemy->v.flags & (FL_CLIENT | FL_FAKECLIENT))
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
pPlayer = GET_PLAYER_POINTER(enemy);
|
|
|
|
weapon = pPlayer->current;
|
2005-11-19 21:24:49 +00:00
|
|
|
} else if (g_grenades.find(enemy, &pPlayer, weapon)) {
|
2005-09-09 03:23:31 +00:00
|
|
|
enemy = pPlayer->pEdict;
|
2005-11-19 21:24:49 +00:00
|
|
|
} else {
|
|
|
|
enemy = enemy->v.owner;
|
|
|
|
if (!FNullEnt(enemy) && (enemy->v.flags & (FL_CLIENT | FL_FAKECLIENT)))
|
|
|
|
{
|
|
|
|
pPlayer = GET_PLAYER_POINTER(enemy);
|
|
|
|
weapon = pPlayer->current;
|
|
|
|
} else {
|
|
|
|
switch (*params / sizeof(cell))
|
|
|
|
{
|
|
|
|
case 3: *get_amxaddr(amx, params[3]) = 0;
|
|
|
|
case 2: *get_amxaddr(amx, params[2]) = 0;
|
|
|
|
}
|
|
|
|
return ENTINDEX(pPlayer->pEdict->v.dmg_inflictor);
|
|
|
|
}
|
|
|
|
}
|
2005-09-09 03:23:31 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (enemy)
|
|
|
|
{
|
|
|
|
switch (*params / sizeof(cell))
|
|
|
|
{
|
|
|
|
case 3: *get_amxaddr(amx, params[3]) = pPlayer->aiming;
|
|
|
|
case 2: *get_amxaddr(amx, params[2]) = weapon;
|
2005-09-09 03:23:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return (enemy ? pPlayer->index : 0);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
static cell AMX_NATIVE_CALL user_has_weapon(AMX *amx, cell *params)
|
2004-05-26 08:28:54 +00:00
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index);
|
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2018-08-26 15:18:39 +00:00
|
|
|
|
|
|
|
if (!pPlayer->ingame)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
edict_t *pEntity = pPlayer->pEdict;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
if (params[3] == -1)
|
|
|
|
{
|
|
|
|
if ((pEntity->v.weapons & (1<<params[2])) > 0)
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
2005-09-16 23:48:51 +00:00
|
|
|
} else {
|
2005-09-09 03:23:31 +00:00
|
|
|
if ((pEntity->v.weapons & (1<<params[2])) > 0)
|
|
|
|
{
|
|
|
|
if (params[3] == 0)
|
|
|
|
{
|
|
|
|
pEntity->v.weapons &= ~(1<<params[2]);
|
|
|
|
return 1;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2005-09-16 23:48:51 +00:00
|
|
|
} else {
|
2005-09-09 03:23:31 +00:00
|
|
|
if (params[3] == 1)
|
|
|
|
{
|
|
|
|
pEntity->v.weapons |= (1<<params[2]);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2004-05-26 08:28:54 +00:00
|
|
|
}
|
|
|
|
|
2004-03-24 01:35:44 +00:00
|
|
|
static cell AMX_NATIVE_CALL get_user_weapon(AMX *amx, cell *params) /* 3 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
2005-08-17 17:32:51 +00:00
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index);
|
2005-08-17 17:32:51 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
if (pPlayer->ingame)
|
|
|
|
{
|
|
|
|
int wpn = pPlayer->current;
|
2005-11-12 00:46:26 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
cell *cpTemp = get_amxaddr(amx, params[2]);
|
2005-09-09 03:23:31 +00:00
|
|
|
*cpTemp = pPlayer->weapons[wpn].clip;
|
2005-09-16 23:48:51 +00:00
|
|
|
cpTemp = get_amxaddr(amx, params[3]);
|
2005-09-09 03:23:31 +00:00
|
|
|
*cpTemp = pPlayer->weapons[wpn].ammo;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return wpn;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL get_user_ammo(AMX *amx, cell *params) /* 4 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index);
|
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (pPlayer->ingame)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int wpn = params[2];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (wpn < 1 || wpn >= MAX_WEAPONS)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid weapon id %d", wpn);
|
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
cell *cpTemp = get_amxaddr(amx, params[3]);
|
2005-09-09 03:23:31 +00:00
|
|
|
*cpTemp = pPlayer->weapons[wpn].clip;
|
2005-09-16 23:48:51 +00:00
|
|
|
cpTemp = get_amxaddr(amx, params[4]);
|
2005-09-09 03:23:31 +00:00
|
|
|
*cpTemp = pPlayer->weapons[wpn].ammo;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL get_user_team(AMX *amx, cell *params) /* 3 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
2005-09-09 03:23:31 +00:00
|
|
|
return -1;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (pPlayer->ingame)
|
|
|
|
{
|
|
|
|
// SidLuke, DoD fix
|
|
|
|
if (g_bmod_dod)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int iTeam = pPlayer->pEdict->v.team;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (params[3])
|
|
|
|
{
|
2013-02-13 07:14:37 +00:00
|
|
|
const char *szTeam = "";
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
switch (iTeam)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
szTeam = "Allies";
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
szTeam = "Axis";
|
|
|
|
break;
|
2005-09-09 03:23:31 +00:00
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
set_amxstring(amx, params[2], szTeam, params[3]);
|
2005-09-09 03:23:31 +00:00
|
|
|
}
|
|
|
|
return iTeam;
|
2004-08-04 15:32:48 +00:00
|
|
|
}
|
2005-09-09 03:23:31 +00:00
|
|
|
//
|
2005-09-16 23:48:51 +00:00
|
|
|
if (params[3])
|
2006-10-24 22:57:19 +00:00
|
|
|
{
|
2015-07-11 08:37:36 +00:00
|
|
|
set_amxstring(amx, params[2], pPlayer->team.chars(), params[3]);
|
2006-10-24 22:57:19 +00:00
|
|
|
}
|
2004-08-04 15:32:48 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return pPlayer->teamId;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return -1;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL show_menu(AMX *amx, cell *params) /* 3 param */
|
|
|
|
{
|
2018-07-10 10:09:20 +00:00
|
|
|
auto closeMenu = [amx](int index) -> int
|
|
|
|
{
|
|
|
|
auto pPlayer = GET_PLAYER_POINTER_I(index);
|
|
|
|
|
|
|
|
if (!pPlayer->ingame)
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
pPlayer->keys = 0;
|
|
|
|
pPlayer->menu = 0;
|
|
|
|
|
|
|
|
// Fire newmenu callback so closing it can be handled by the plugin
|
|
|
|
if (!CloseNewMenus(pPlayer))
|
|
|
|
{
|
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Plugin called menu_display when item=MENU_EXIT");
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (g_bmod_cstrike)
|
|
|
|
{
|
2018-09-03 16:39:08 +00:00
|
|
|
enum JoinState { Joined = 0 };
|
|
|
|
enum MenuState { Menu_OFF = 0, Menu_ChooseTeam = 1, Menu_ChooseAppearance = 3 };
|
|
|
|
|
|
|
|
GET_OFFSET("CBasePlayer", m_iJoiningState);
|
2018-07-10 10:09:20 +00:00
|
|
|
GET_OFFSET("CBasePlayer", m_iMenu);
|
2018-09-03 16:39:08 +00:00
|
|
|
|
|
|
|
if (get_pdata<int>(pPlayer->pEdict, m_iJoiningState) == Joined || (get_pdata<int>(pPlayer->pEdict, m_iMenu) != Menu_ChooseTeam && get_pdata<int>(pPlayer->pEdict, m_iMenu) != Menu_ChooseAppearance))
|
|
|
|
{
|
|
|
|
set_pdata<int>(pPlayer->pEdict, m_iMenu, Menu_OFF);
|
|
|
|
}
|
2018-07-10 10:09:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
int index = params[1];
|
|
|
|
|
2014-10-10 22:35:05 +00:00
|
|
|
// If show_menu is called from within a newmenu callback upon receiving MENU_EXIT
|
|
|
|
// it is possible for this native to recurse. We need to close newmenus right away
|
|
|
|
// because the recursive call would otherwise modify/corrupt the static get_amxstring
|
|
|
|
// buffer mid execution. This will either display incorrect text or result in UTIL_ShowMenu
|
|
|
|
// running into an infinite loop.
|
|
|
|
if (index == 0)
|
|
|
|
{
|
|
|
|
for (int i = 1; i <= gpGlobals->maxClients; ++i)
|
|
|
|
{
|
2018-07-10 10:09:20 +00:00
|
|
|
if (closeMenu(i) == 2)
|
2014-10-10 22:35:05 +00:00
|
|
|
{
|
2018-07-10 10:09:20 +00:00
|
|
|
return 0;
|
2014-10-10 22:35:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
|
|
|
{
|
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-07-10 10:09:20 +00:00
|
|
|
if (closeMenu(index))
|
2014-10-10 22:35:05 +00:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
int ilen = 0, ilen2 = 0;
|
2005-09-09 03:23:31 +00:00
|
|
|
char *sMenu = get_amxstring(amx, params[3], 0, ilen);
|
|
|
|
char *lMenu = get_amxstring(amx, params[5], 1, ilen2);
|
|
|
|
int menuid = 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
if (ilen2 && lMenu)
|
|
|
|
{
|
|
|
|
menuid = g_menucmds.findMenuId(lMenu, amx);
|
|
|
|
} else {
|
|
|
|
menuid = g_menucmds.findMenuId(sMenu, amx);
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
int keys = params[2];
|
|
|
|
int time = params[4];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2014-10-10 22:35:05 +00:00
|
|
|
if (index == 0)
|
2005-09-16 23:48:51 +00:00
|
|
|
{
|
|
|
|
for (int i = 1; i <= gpGlobals->maxClients; ++i)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(i);
|
2005-11-13 20:33:30 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (pPlayer->ingame)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
pPlayer->keys = keys;
|
|
|
|
pPlayer->menu = menuid;
|
2005-11-17 23:04:43 +00:00
|
|
|
pPlayer->vgui = false;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-11-13 20:33:30 +00:00
|
|
|
if (time == -1)
|
|
|
|
pPlayer->menuexpire = INFINITE;
|
|
|
|
else
|
|
|
|
pPlayer->menuexpire = gpGlobals->time + static_cast<float>(time);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
pPlayer->page = 0;
|
2005-09-16 23:48:51 +00:00
|
|
|
UTIL_ShowMenu(pPlayer->pEdict, keys, time, sMenu, ilen);
|
2005-09-09 03:23:31 +00:00
|
|
|
}
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
} else {
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2005-11-13 20:33:30 +00:00
|
|
|
|
2018-08-26 15:18:39 +00:00
|
|
|
if (pPlayer->ingame)
|
|
|
|
{
|
|
|
|
pPlayer->keys = keys;
|
|
|
|
pPlayer->menu = menuid;
|
|
|
|
pPlayer->vgui = false;
|
2014-05-21 16:17:09 +00:00
|
|
|
|
2018-08-26 15:18:39 +00:00
|
|
|
if (time == -1)
|
|
|
|
pPlayer->menuexpire = INFINITE;
|
|
|
|
else
|
|
|
|
pPlayer->menuexpire = gpGlobals->time + static_cast<float>(time);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2018-08-26 15:18:39 +00:00
|
|
|
pPlayer->page = 0;
|
|
|
|
UTIL_ShowMenu(pPlayer->pEdict, keys, time, sMenu, ilen);
|
|
|
|
}
|
2005-09-09 03:23:31 +00:00
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL register_plugin(AMX *amx, cell *params) /* 3 param */
|
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
CPluginMngr::CPlugin* a = g_plugins.findPluginFast(amx);
|
2005-09-09 03:23:31 +00:00
|
|
|
int i;
|
2006-03-15 13:43:06 +00:00
|
|
|
|
|
|
|
char *title = get_amxstring(amx, params[1], 0, i);
|
|
|
|
char *vers = get_amxstring(amx, params[2], 1, i);
|
|
|
|
char *author = get_amxstring(amx, params[3], 2, i);
|
|
|
|
|
|
|
|
#if defined BINLOG_ENABLED
|
|
|
|
g_BinLog.WriteOp(BinLog_Registered, a->getId(), title, vers);
|
|
|
|
#endif
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2006-03-15 13:43:06 +00:00
|
|
|
a->setTitle(title);
|
|
|
|
a->setVersion(vers);
|
|
|
|
a->setAuthor(author);
|
2007-03-03 23:14:24 +00:00
|
|
|
|
|
|
|
/* Check if we need to add fail counters */
|
|
|
|
i = 0;
|
|
|
|
unsigned int counter = 0;
|
|
|
|
while (NONGPL_PLUGIN_LIST[i].author != NULL)
|
|
|
|
{
|
|
|
|
if (strcmp(NONGPL_PLUGIN_LIST[i].author, author) == 0)
|
|
|
|
{
|
|
|
|
counter++;
|
|
|
|
}
|
|
|
|
if (stricmp(NONGPL_PLUGIN_LIST[i].filename, a->getName()) == 0)
|
|
|
|
{
|
|
|
|
counter++;
|
|
|
|
}
|
|
|
|
if (stricmp(NONGPL_PLUGIN_LIST[i].title, title) == 0)
|
|
|
|
{
|
|
|
|
counter++;
|
|
|
|
}
|
|
|
|
if (counter)
|
|
|
|
{
|
|
|
|
a->AddToFailCounter(counter);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2006-04-17 12:57:52 +00:00
|
|
|
return a->getId();
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL register_menucmd(AMX *amx, cell *params) /* 3 param */
|
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
CPluginMngr::CPlugin* plugin = g_plugins.findPluginFast(amx);
|
2005-09-09 03:23:31 +00:00
|
|
|
int ilen, idx;
|
2005-09-16 23:48:51 +00:00
|
|
|
char* sptemp = get_amxstring(amx, params[3], 0, ilen);
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
idx = registerSPForwardByName(amx, sptemp, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
if (idx == -1)
|
|
|
|
{
|
|
|
|
LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", sptemp);
|
|
|
|
return 0;
|
|
|
|
}
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
g_menucmds.registerMenuCmd(plugin, params[1], params[2], idx);
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL get_plugin(AMX *amx, cell *params) /* 11 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
CPluginMngr::CPlugin* a;
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (params[1] < 0)
|
|
|
|
a = g_plugins.findPluginFast(amx);
|
2005-09-09 03:23:31 +00:00
|
|
|
else
|
2005-09-16 23:48:51 +00:00
|
|
|
a = g_plugins.findPlugin((int)params[1]);
|
|
|
|
|
|
|
|
if (a)
|
|
|
|
{
|
|
|
|
set_amxstring(amx, params[2], a->getName(), params[3]);
|
|
|
|
set_amxstring(amx, params[4], a->getTitle(), params[5]);
|
|
|
|
set_amxstring(amx, params[6], a->getVersion(), params[7]);
|
|
|
|
set_amxstring(amx, params[8], a->getAuthor(), params[9]);
|
|
|
|
set_amxstring(amx, params[10], a->getStatus(), params[11]);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2015-07-31 13:45:32 +00:00
|
|
|
if (params[0] / sizeof(cell) >= 12)
|
|
|
|
{
|
|
|
|
cell *jit_info = get_amxaddr(amx, params[12]);
|
2006-09-12 07:59:56 +00:00
|
|
|
#if defined AMD64 || !defined JIT
|
2015-07-31 13:45:32 +00:00
|
|
|
*jit_info = 0;
|
2006-09-12 07:59:56 +00:00
|
|
|
#else
|
2015-07-31 13:45:32 +00:00
|
|
|
*jit_info = a->isDebug() ? 0 : 1;
|
2006-09-12 07:59:56 +00:00
|
|
|
#endif
|
2015-07-31 13:45:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return a->getId();
|
2006-09-12 07:59:56 +00:00
|
|
|
}
|
2015-07-31 13:45:32 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return -1;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
2004-08-15 10:53:48 +00:00
|
|
|
static cell AMX_NATIVE_CALL amx_md5(AMX *amx, cell *params)
|
|
|
|
{
|
Add new hashers and new natives
Replace the only hasher called MD5 with the ones listed below.
(+) CRC32, MD5, SHA1, SHA256, SHA3 224 BIT, SHA3 256 BIT, SHA3 384 BIT,
SHA3 512 BIT, Keccak 224 BIT, Keccak 256 BIT, Keccak 384 BIT and Keccak
512 BIT.
Add the natives listed below.
(+) hash_string(const string[], hashType:type, output[], const
outputSize)
(+) hash_file(const fileName, hashType:type, output[], const outputSize)
(+) is_arkshine_a_doctor() : Hidden native, but a sign of recompense
for him being very active since 1.8.3 version of AMX Mod X
(+) get_system_endianness() : Checks if the system is currently Big
Endian or Little Endian.
Add the following Enum.
(+) hashType {}
(+) sysEndianness {}
Deprecate the following natives.
(-) amx_md5()
(-) amx_md5_file()
It has been tested on Windows and Linux. The sanity checks seems to be
properly working, so no worries about them.
These are useful if people are using Sockets, cURLs or MySQLs in order
to compare hashes of different files On-line for further investigation.
You are not able to check if the files are older or newer, but you can
see if the content is different (Hash Checksum mismatch).
I'm glad I did this. Thanks to
2015-02-15 06:44:33 +00:00
|
|
|
int len;
|
2004-08-15 10:53:48 +00:00
|
|
|
char *str = get_amxstring(amx, params[1], 0, len);
|
Add new hashers and new natives
Replace the only hasher called MD5 with the ones listed below.
(+) CRC32, MD5, SHA1, SHA256, SHA3 224 BIT, SHA3 256 BIT, SHA3 384 BIT,
SHA3 512 BIT, Keccak 224 BIT, Keccak 256 BIT, Keccak 384 BIT and Keccak
512 BIT.
Add the natives listed below.
(+) hash_string(const string[], hashType:type, output[], const
outputSize)
(+) hash_file(const fileName, hashType:type, output[], const outputSize)
(+) is_arkshine_a_doctor() : Hidden native, but a sign of recompense
for him being very active since 1.8.3 version of AMX Mod X
(+) get_system_endianness() : Checks if the system is currently Big
Endian or Little Endian.
Add the following Enum.
(+) hashType {}
(+) sysEndianness {}
Deprecate the following natives.
(-) amx_md5()
(-) amx_md5_file()
It has been tested on Windows and Linux. The sanity checks seems to be
properly working, so no worries about them.
These are useful if people are using Sockets, cURLs or MySQLs in order
to compare hashes of different files On-line for further investigation.
You are not able to check if the files are older or newer, but you can
see if the content is different (Hash Checksum mismatch).
I'm glad I did this. Thanks to
2015-02-15 06:44:33 +00:00
|
|
|
const char *hash = hashString((const char *)str, len, Hash_Md5);
|
2004-08-15 10:53:48 +00:00
|
|
|
|
Add new hashers and new natives
Replace the only hasher called MD5 with the ones listed below.
(+) CRC32, MD5, SHA1, SHA256, SHA3 224 BIT, SHA3 256 BIT, SHA3 384 BIT,
SHA3 512 BIT, Keccak 224 BIT, Keccak 256 BIT, Keccak 384 BIT and Keccak
512 BIT.
Add the natives listed below.
(+) hash_string(const string[], hashType:type, output[], const
outputSize)
(+) hash_file(const fileName, hashType:type, output[], const outputSize)
(+) is_arkshine_a_doctor() : Hidden native, but a sign of recompense
for him being very active since 1.8.3 version of AMX Mod X
(+) get_system_endianness() : Checks if the system is currently Big
Endian or Little Endian.
Add the following Enum.
(+) hashType {}
(+) sysEndianness {}
Deprecate the following natives.
(-) amx_md5()
(-) amx_md5_file()
It has been tested on Windows and Linux. The sanity checks seems to be
properly working, so no worries about them.
These are useful if people are using Sockets, cURLs or MySQLs in order
to compare hashes of different files On-line for further investigation.
You are not able to check if the files are older or newer, but you can
see if the content is different (Hash Checksum mismatch).
I'm glad I did this. Thanks to
2015-02-15 06:44:33 +00:00
|
|
|
return set_amxstring(amx, params[2], hash, 32);
|
2004-08-15 10:53:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL amx_md5_file(AMX *amx, cell *params)
|
|
|
|
{
|
Add new hashers and new natives
Replace the only hasher called MD5 with the ones listed below.
(+) CRC32, MD5, SHA1, SHA256, SHA3 224 BIT, SHA3 256 BIT, SHA3 384 BIT,
SHA3 512 BIT, Keccak 224 BIT, Keccak 256 BIT, Keccak 384 BIT and Keccak
512 BIT.
Add the natives listed below.
(+) hash_string(const string[], hashType:type, output[], const
outputSize)
(+) hash_file(const fileName, hashType:type, output[], const outputSize)
(+) is_arkshine_a_doctor() : Hidden native, but a sign of recompense
for him being very active since 1.8.3 version of AMX Mod X
(+) get_system_endianness() : Checks if the system is currently Big
Endian or Little Endian.
Add the following Enum.
(+) hashType {}
(+) sysEndianness {}
Deprecate the following natives.
(-) amx_md5()
(-) amx_md5_file()
It has been tested on Windows and Linux. The sanity checks seems to be
properly working, so no worries about them.
These are useful if people are using Sockets, cURLs or MySQLs in order
to compare hashes of different files On-line for further investigation.
You are not able to check if the files are older or newer, but you can
see if the content is different (Hash Checksum mismatch).
I'm glad I did this. Thanks to
2015-02-15 06:44:33 +00:00
|
|
|
int len;
|
2004-08-15 10:53:48 +00:00
|
|
|
char *str = get_amxstring(amx, params[1], 0, len);
|
2017-03-11 18:26:25 +00:00
|
|
|
char file[PLATFORM_MAX_PATH];
|
2004-08-15 10:53:48 +00:00
|
|
|
|
2017-03-11 18:26:25 +00:00
|
|
|
build_pathname_r(file, sizeof(file), "%s", str);
|
2005-12-01 13:42:28 +00:00
|
|
|
|
Add new hashers and new natives
Replace the only hasher called MD5 with the ones listed below.
(+) CRC32, MD5, SHA1, SHA256, SHA3 224 BIT, SHA3 256 BIT, SHA3 384 BIT,
SHA3 512 BIT, Keccak 224 BIT, Keccak 256 BIT, Keccak 384 BIT and Keccak
512 BIT.
Add the natives listed below.
(+) hash_string(const string[], hashType:type, output[], const
outputSize)
(+) hash_file(const fileName, hashType:type, output[], const outputSize)
(+) is_arkshine_a_doctor() : Hidden native, but a sign of recompense
for him being very active since 1.8.3 version of AMX Mod X
(+) get_system_endianness() : Checks if the system is currently Big
Endian or Little Endian.
Add the following Enum.
(+) hashType {}
(+) sysEndianness {}
Deprecate the following natives.
(-) amx_md5()
(-) amx_md5_file()
It has been tested on Windows and Linux. The sanity checks seems to be
properly working, so no worries about them.
These are useful if people are using Sockets, cURLs or MySQLs in order
to compare hashes of different files On-line for further investigation.
You are not able to check if the files are older or newer, but you can
see if the content is different (Hash Checksum mismatch).
I'm glad I did this. Thanks to
2015-02-15 06:44:33 +00:00
|
|
|
const char *hash = hashFile((const char *)file, Hash_Md5);
|
|
|
|
if (!hash)
|
2004-08-15 10:53:48 +00:00
|
|
|
{
|
2006-04-13 16:29:01 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Cant open file \"%s\"", file);
|
2004-08-15 10:53:48 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
Add new hashers and new natives
Replace the only hasher called MD5 with the ones listed below.
(+) CRC32, MD5, SHA1, SHA256, SHA3 224 BIT, SHA3 256 BIT, SHA3 384 BIT,
SHA3 512 BIT, Keccak 224 BIT, Keccak 256 BIT, Keccak 384 BIT and Keccak
512 BIT.
Add the natives listed below.
(+) hash_string(const string[], hashType:type, output[], const
outputSize)
(+) hash_file(const fileName, hashType:type, output[], const outputSize)
(+) is_arkshine_a_doctor() : Hidden native, but a sign of recompense
for him being very active since 1.8.3 version of AMX Mod X
(+) get_system_endianness() : Checks if the system is currently Big
Endian or Little Endian.
Add the following Enum.
(+) hashType {}
(+) sysEndianness {}
Deprecate the following natives.
(-) amx_md5()
(-) amx_md5_file()
It has been tested on Windows and Linux. The sanity checks seems to be
properly working, so no worries about them.
These are useful if people are using Sockets, cURLs or MySQLs in order
to compare hashes of different files On-line for further investigation.
You are not able to check if the files are older or newer, but you can
see if the content is different (Hash Checksum mismatch).
I'm glad I did this. Thanks to
2015-02-15 06:44:33 +00:00
|
|
|
return set_amxstring(amx, params[2], hash, 32);
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL amx_hash_string(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
int len;
|
|
|
|
char *str = get_amxstring(amx, params[1], 0, len);
|
|
|
|
HashType type = (HashType)params[2];
|
|
|
|
|
|
|
|
const char *hash = hashString((const char *)str, len, type);
|
|
|
|
if (!hash)
|
|
|
|
{
|
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Cant hash string \"%s\"", str);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return set_amxstring(amx, params[3], hash, params[4]);
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL amx_hash_file(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
int len;
|
|
|
|
char *str = get_amxstring(amx, params[1], 0, len);
|
2017-03-11 18:26:25 +00:00
|
|
|
char file[PLATFORM_MAX_PATH];
|
|
|
|
build_pathname_r(file, sizeof(file), "%s", str);
|
Add new hashers and new natives
Replace the only hasher called MD5 with the ones listed below.
(+) CRC32, MD5, SHA1, SHA256, SHA3 224 BIT, SHA3 256 BIT, SHA3 384 BIT,
SHA3 512 BIT, Keccak 224 BIT, Keccak 256 BIT, Keccak 384 BIT and Keccak
512 BIT.
Add the natives listed below.
(+) hash_string(const string[], hashType:type, output[], const
outputSize)
(+) hash_file(const fileName, hashType:type, output[], const outputSize)
(+) is_arkshine_a_doctor() : Hidden native, but a sign of recompense
for him being very active since 1.8.3 version of AMX Mod X
(+) get_system_endianness() : Checks if the system is currently Big
Endian or Little Endian.
Add the following Enum.
(+) hashType {}
(+) sysEndianness {}
Deprecate the following natives.
(-) amx_md5()
(-) amx_md5_file()
It has been tested on Windows and Linux. The sanity checks seems to be
properly working, so no worries about them.
These are useful if people are using Sockets, cURLs or MySQLs in order
to compare hashes of different files On-line for further investigation.
You are not able to check if the files are older or newer, but you can
see if the content is different (Hash Checksum mismatch).
I'm glad I did this. Thanks to
2015-02-15 06:44:33 +00:00
|
|
|
|
|
|
|
HashType type = (HashType)params[2];
|
|
|
|
|
|
|
|
const char *hash = hashFile((const char *)file, type);
|
|
|
|
if (!hash)
|
|
|
|
{
|
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Cant open file \"%s\"", file);
|
|
|
|
return 0;
|
|
|
|
}
|
2004-08-15 10:53:48 +00:00
|
|
|
|
Add new hashers and new natives
Replace the only hasher called MD5 with the ones listed below.
(+) CRC32, MD5, SHA1, SHA256, SHA3 224 BIT, SHA3 256 BIT, SHA3 384 BIT,
SHA3 512 BIT, Keccak 224 BIT, Keccak 256 BIT, Keccak 384 BIT and Keccak
512 BIT.
Add the natives listed below.
(+) hash_string(const string[], hashType:type, output[], const
outputSize)
(+) hash_file(const fileName, hashType:type, output[], const outputSize)
(+) is_arkshine_a_doctor() : Hidden native, but a sign of recompense
for him being very active since 1.8.3 version of AMX Mod X
(+) get_system_endianness() : Checks if the system is currently Big
Endian or Little Endian.
Add the following Enum.
(+) hashType {}
(+) sysEndianness {}
Deprecate the following natives.
(-) amx_md5()
(-) amx_md5_file()
It has been tested on Windows and Linux. The sanity checks seems to be
properly working, so no worries about them.
These are useful if people are using Sockets, cURLs or MySQLs in order
to compare hashes of different files On-line for further investigation.
You are not able to check if the files are older or newer, but you can
see if the content is different (Hash Checksum mismatch).
I'm glad I did this. Thanks to
2015-02-15 06:44:33 +00:00
|
|
|
return set_amxstring(amx, params[3], hash, params[4]);
|
2004-08-15 10:53:48 +00:00
|
|
|
}
|
|
|
|
|
2004-03-24 01:35:44 +00:00
|
|
|
static cell AMX_NATIVE_CALL get_pluginsnum(AMX *amx, cell *params)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
return g_plugins.getPluginsNum();
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
2016-02-02 22:07:53 +00:00
|
|
|
// native register_concmd(const cmd[], const function[], flags = -1, const info[] = "", FlagManager = -1, bool:info_ml = false);
|
|
|
|
static cell AMX_NATIVE_CALL register_concmd(AMX *amx, cell *params)
|
2004-03-24 01:35:44 +00:00
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
CPluginMngr::CPlugin* plugin = g_plugins.findPluginFast(amx);
|
2005-09-09 03:23:31 +00:00
|
|
|
int i, idx = 0;
|
2005-09-16 23:48:51 +00:00
|
|
|
char* temp = get_amxstring(amx, params[2], 0, i);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
idx = registerSPForwardByName(amx, temp, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
if (idx == -1)
|
|
|
|
{
|
|
|
|
LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", temp);
|
|
|
|
return 0;
|
|
|
|
}
|
2005-09-16 23:48:51 +00:00
|
|
|
|
|
|
|
temp = get_amxstring(amx, params[1], 0, i);
|
|
|
|
char* info = get_amxstring(amx, params[4], 1, i);
|
2005-09-09 03:23:31 +00:00
|
|
|
CmdMngr::Command* cmd;
|
|
|
|
int access = params[3];
|
|
|
|
bool listable = true;
|
2016-02-02 22:07:53 +00:00
|
|
|
bool info_ml = *params / sizeof(cell) >= 6 && params[6] != 0 && i;
|
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (access < 0) // is access is -1 then hide from listing
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
access = 0;
|
|
|
|
listable = false;
|
|
|
|
}
|
2007-03-09 03:04:40 +00:00
|
|
|
|
|
|
|
if (FlagMan.ShouldIAddThisCommand(amx,params,temp)==1)
|
|
|
|
{
|
|
|
|
FlagMan.LookupOrAdd(temp,access,amx);
|
|
|
|
}
|
|
|
|
|
2016-02-02 22:07:53 +00:00
|
|
|
if ((cmd = g_commands.registerCommand(plugin, idx, temp, info, access, listable, info_ml)) == NULL)
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2007-03-03 23:14:24 +00:00
|
|
|
|
|
|
|
if (CheckBadConList(temp, 1))
|
|
|
|
{
|
|
|
|
plugin->AddToFailCounter(1);
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
cmd->setCmdType(CMD_ConsoleCommand);
|
|
|
|
REG_SVR_COMMAND((char*)cmd->getCommand(), plugin_srvcmd);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2006-11-22 02:45:12 +00:00
|
|
|
return cmd->getId();
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
2016-02-02 22:07:53 +00:00
|
|
|
// native register_clcmd(const client_cmd[], const function[], flags = -1, const info[] = "", FlagManager = -1, bool:info_ml = false);
|
|
|
|
static cell AMX_NATIVE_CALL register_clcmd(AMX *amx, cell *params)
|
2004-03-24 01:35:44 +00:00
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
CPluginMngr::CPlugin* plugin = g_plugins.findPluginFast(amx);
|
2005-09-09 03:23:31 +00:00
|
|
|
int i, idx = 0;
|
2005-09-16 23:48:51 +00:00
|
|
|
char* temp = get_amxstring(amx, params[2], 0, i);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
idx = registerSPForwardByName(amx, temp, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (idx == -1)
|
2005-09-09 03:23:31 +00:00
|
|
|
{
|
|
|
|
LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", temp);
|
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
temp = get_amxstring(amx, params[1], 0, i);
|
2016-02-02 22:07:53 +00:00
|
|
|
const char* info = get_amxstring(amx, params[4], 1, i);
|
2005-09-09 03:23:31 +00:00
|
|
|
CmdMngr::Command* cmd;
|
|
|
|
int access = params[3];
|
|
|
|
bool listable = true;
|
2016-02-02 22:07:53 +00:00
|
|
|
bool info_ml = *params / sizeof(cell) >= 6 && params[6] != 0 && i;
|
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (access < 0) // is access is -1 then hide from listing
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
access = 0;
|
|
|
|
listable = false;
|
|
|
|
}
|
2007-03-09 03:04:40 +00:00
|
|
|
|
|
|
|
if (FlagMan.ShouldIAddThisCommand(amx,params,temp)==1)
|
|
|
|
{
|
|
|
|
FlagMan.LookupOrAdd(temp,access,amx);
|
|
|
|
}
|
|
|
|
|
2016-02-02 22:07:53 +00:00
|
|
|
if ((cmd = g_commands.registerCommand(plugin, idx, temp, info, access, listable, info_ml)) == NULL)
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
cmd->setCmdType(CMD_ClientCommand);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2006-11-22 02:45:12 +00:00
|
|
|
return cmd->getId();
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
2016-02-02 22:07:53 +00:00
|
|
|
// native register_srvcmd(const server_cmd[], const function[], flags = -1, const info[] = "", bool:info_ml = false);
|
|
|
|
static cell AMX_NATIVE_CALL register_srvcmd(AMX *amx, cell *params)
|
2004-03-24 01:35:44 +00:00
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
CPluginMngr::CPlugin* plugin = g_plugins.findPluginFast(amx);
|
2005-09-09 03:23:31 +00:00
|
|
|
int i, idx = 0;
|
2005-09-16 23:48:51 +00:00
|
|
|
char* temp = get_amxstring(amx, params[2], 0, i);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
idx = registerSPForwardByName(amx, temp, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (idx == -1)
|
2005-09-09 03:23:31 +00:00
|
|
|
{
|
|
|
|
LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", temp);
|
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
temp = get_amxstring(amx, params[1], 0, i);
|
2016-02-02 22:07:53 +00:00
|
|
|
const char* info = get_amxstring(amx, params[4], 1, i);
|
2005-09-09 03:23:31 +00:00
|
|
|
CmdMngr::Command* cmd;
|
|
|
|
int access = params[3];
|
|
|
|
bool listable = true;
|
2016-02-02 22:07:53 +00:00
|
|
|
bool info_ml = *params / sizeof(cell) >= 5 && params[5] != 0 && i;
|
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (access < 0) // is access is -1 then hide from listing
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
access = 0;
|
|
|
|
listable = false;
|
|
|
|
}
|
2016-02-02 22:07:53 +00:00
|
|
|
|
|
|
|
if ((cmd = g_commands.registerCommand(plugin, idx, temp, info, access, listable, info_ml)) == NULL)
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
cmd->setCmdType(CMD_ServerCommand);
|
|
|
|
REG_SVR_COMMAND((char*)cmd->getCommand(), plugin_srvcmd);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2006-11-22 02:45:12 +00:00
|
|
|
return cmd->getId();
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
2016-02-02 22:07:53 +00:00
|
|
|
// native get_concmd(index, cmd[], len1, &flags, info[], len2, flag, id = -1, &bool:info_ml = false);
|
|
|
|
static cell AMX_NATIVE_CALL get_concmd(AMX *amx, cell *params)
|
2004-03-24 01:35:44 +00:00
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int who = params[8];
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (who > 0) // id of player - client command
|
2005-09-09 03:23:31 +00:00
|
|
|
who = CMD_ClientCommand;
|
2005-09-16 23:48:51 +00:00
|
|
|
else if (who == 0) // server
|
2005-09-09 03:23:31 +00:00
|
|
|
who = CMD_ServerCommand;
|
2005-09-16 23:48:51 +00:00
|
|
|
else // -1 parameter - all commands
|
2005-09-09 03:23:31 +00:00
|
|
|
who = CMD_ConsoleCommand;
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
CmdMngr::Command* cmd = g_commands.getCmd(params[1], who, params[7]);
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (cmd == 0)
|
|
|
|
return 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2015-06-29 09:28:11 +00:00
|
|
|
set_amxstring_utf8(amx, params[2], cmd->getCmdLine(), strlen(cmd->getCmdLine()), params[3]);
|
|
|
|
set_amxstring_utf8(amx, params[5], cmd->getCmdInfo(), strlen(cmd->getCmdInfo()), params[6]);
|
2005-09-16 23:48:51 +00:00
|
|
|
cell *cpFlags = get_amxaddr(amx, params[4]);
|
2005-09-09 03:23:31 +00:00
|
|
|
*cpFlags = cmd->getFlags();
|
2016-02-02 22:07:53 +00:00
|
|
|
|
|
|
|
if (*params / sizeof(cell) >= 9)
|
|
|
|
{
|
|
|
|
*get_amxaddr(amx, params[9]) = cmd->isInfoML();
|
|
|
|
}
|
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
2006-09-12 07:59:56 +00:00
|
|
|
static cell AMX_NATIVE_CALL get_concmd_plid(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
int who = params[3];
|
|
|
|
if (who > 0)
|
|
|
|
{
|
|
|
|
who = CMD_ClientCommand;
|
|
|
|
} else if (who == 0) {
|
|
|
|
who = CMD_ServerCommand;
|
|
|
|
} else {
|
|
|
|
who = CMD_ConsoleCommand;
|
|
|
|
}
|
|
|
|
|
|
|
|
CmdMngr::Command *cmd = g_commands.getCmd(params[1], who, params[2]);
|
|
|
|
|
|
|
|
if (cmd == NULL)
|
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return cmd->getPlugin()->getId();
|
|
|
|
}
|
|
|
|
|
2016-02-02 22:07:53 +00:00
|
|
|
// native get_clcmd(index, command[], len1, &flags, info[], len2, flag, &bool:info_ml = false);
|
|
|
|
static cell AMX_NATIVE_CALL get_clcmd(AMX *amx, cell *params)
|
2004-03-24 01:35:44 +00:00
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
CmdMngr::Command* cmd = g_commands.getCmd(params[1], CMD_ClientCommand, params[7]);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (cmd == 0)
|
|
|
|
return 0;
|
2014-04-30 07:33:03 +00:00
|
|
|
|
2015-06-29 09:28:11 +00:00
|
|
|
set_amxstring_utf8(amx, params[2], cmd->getCmdLine(), strlen(cmd->getCmdLine()), params[3]);
|
|
|
|
set_amxstring_utf8(amx, params[5], cmd->getCmdInfo(), strlen(cmd->getCmdInfo()), params[6]);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
cell *cpFlags = get_amxaddr(amx, params[4]);
|
2005-09-09 03:23:31 +00:00
|
|
|
*cpFlags = cmd->getFlags();
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2016-02-02 22:07:53 +00:00
|
|
|
if (*params / sizeof(cell) >= 8)
|
|
|
|
{
|
|
|
|
*get_amxaddr(amx, params[8]) = cmd->isInfoML();
|
|
|
|
}
|
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
2016-02-02 22:07:53 +00:00
|
|
|
// native get_srvcmd(index, server_cmd[], len1, &flags, info[], len2, flag, &bool:info_ml = false);
|
2004-03-24 01:35:44 +00:00
|
|
|
static cell AMX_NATIVE_CALL get_srvcmd(AMX *amx, cell *params)
|
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
CmdMngr::Command* cmd = g_commands.getCmd(params[1], CMD_ServerCommand, params[7]);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (cmd == 0)
|
|
|
|
return 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2015-06-29 09:28:11 +00:00
|
|
|
set_amxstring_utf8(amx, params[2], cmd->getCmdLine(), strlen(cmd->getCmdLine()), params[3]);
|
|
|
|
set_amxstring_utf8(amx, params[5], cmd->getCmdInfo(), strlen(cmd->getCmdInfo()), params[6]);
|
2005-09-16 23:48:51 +00:00
|
|
|
cell *cpFlags = get_amxaddr(amx, params[4]);
|
2005-09-09 03:23:31 +00:00
|
|
|
*cpFlags = cmd->getFlags();
|
2016-02-02 22:07:53 +00:00
|
|
|
|
|
|
|
if (*params / sizeof(cell) >= 8)
|
|
|
|
{
|
|
|
|
*get_amxaddr(amx, params[8]) = cmd->isInfoML();
|
|
|
|
}
|
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL get_srvcmdsnum(AMX *amx, cell *params)
|
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
return g_commands.getCmdNum(CMD_ServerCommand, params[1]);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL get_clcmdsnum(AMX *amx, cell *params) /* 1 param */
|
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
return g_commands.getCmdNum(CMD_ClientCommand, params[1]);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL get_concmdsnum(AMX *amx, cell *params) /* 1 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int who = params[2];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (who > 0)
|
|
|
|
return g_commands.getCmdNum(CMD_ClientCommand, params[1]);
|
|
|
|
if (who == 0)
|
|
|
|
return g_commands.getCmdNum(CMD_ServerCommand, params[1]);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
return g_commands.getCmdNum(CMD_ConsoleCommand, params[1]);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
2015-07-20 09:07:10 +00:00
|
|
|
// native register_event(const event[], const function[], const flags[], const cond[] = "", ...);
|
|
|
|
static cell AMX_NATIVE_CALL register_event(AMX *amx, cell *params)
|
2004-03-24 01:35:44 +00:00
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
CPluginMngr::CPlugin* plugin = g_plugins.findPluginFast(amx);
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2015-07-20 09:07:10 +00:00
|
|
|
int len, eventId, forwardId;
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2015-07-20 09:07:10 +00:00
|
|
|
const char* eventName = get_amxstring(amx, params[1], 0, len);
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2015-07-20 09:07:10 +00:00
|
|
|
if ((eventId = g_events.getEventId(eventName)) == 0)
|
2005-09-16 23:48:51 +00:00
|
|
|
{
|
2015-07-20 09:07:10 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid event (name \"%s\") (plugin \"%s\")", eventName, plugin->getName());
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2015-07-20 09:07:10 +00:00
|
|
|
const char* callback = get_amxstring(amx, params[2], 0, len);
|
|
|
|
|
|
|
|
forwardId = registerSPForwardByName(amx, callback, FP_CELL, FP_DONE);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2015-07-20 09:07:10 +00:00
|
|
|
if (forwardId == -1)
|
2005-09-09 03:23:31 +00:00
|
|
|
{
|
2015-07-20 09:07:10 +00:00
|
|
|
LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", callback);
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
int numparam = *params / sizeof(cell);
|
2005-09-09 03:23:31 +00:00
|
|
|
int flags = 0;
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (numparam > 2)
|
2015-07-20 09:07:10 +00:00
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
flags = UTIL_ReadFlags(get_amxstring(amx, params[3], 0, len));
|
2015-07-20 09:07:10 +00:00
|
|
|
}
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2015-07-20 09:07:10 +00:00
|
|
|
int handle = g_events.registerEvent(plugin, forwardId, flags, eventId);
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2015-07-20 09:07:10 +00:00
|
|
|
if (!handle)
|
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
return 0;
|
2015-07-20 09:07:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
auto event = EventHandles.lookup(handle)->m_event;
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
for (int i = 4; i <= numparam; ++i)
|
2015-07-20 09:07:10 +00:00
|
|
|
{
|
|
|
|
event->registerFilter(get_amxstring(amx, params[i], 0, len));
|
|
|
|
}
|
|
|
|
|
|
|
|
return handle;
|
|
|
|
}
|
|
|
|
|
2017-12-07 23:06:37 +00:00
|
|
|
// native register_event_ex(const event[], const function[], RegisterEventFlags:flags, const cond[] = "", ...);
|
|
|
|
static cell AMX_NATIVE_CALL register_event_ex(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
cell amx_addr;
|
|
|
|
cell *phys_addr;
|
|
|
|
char strFlags[8];
|
|
|
|
|
|
|
|
amx_Allot(amx, ARRAY_LENGTH(strFlags), &amx_addr, &phys_addr);
|
|
|
|
UTIL_GetFlags(strFlags, params[3]);
|
|
|
|
set_amxstring(amx, amx_addr, strFlags, ARRAY_LENGTH(strFlags) - 1);
|
|
|
|
|
|
|
|
params[3] = amx_addr;
|
|
|
|
cell ret = register_event(amx, params);
|
|
|
|
amx_Release(amx, amx_addr);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-07-20 09:07:10 +00:00
|
|
|
static cell AMX_NATIVE_CALL enable_event(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
auto handle = EventHandles.lookup(params[1]);
|
|
|
|
|
|
|
|
if (!handle)
|
|
|
|
{
|
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid event handle %d", params[1]);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
handle->m_event->setForwardState(FSTATE_ACTIVE);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL disable_event(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
auto handle = EventHandles.lookup(params[1]);
|
|
|
|
|
|
|
|
if (!handle)
|
|
|
|
{
|
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid event handle: %d", params[1]);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
handle->m_event->setForwardState(FSTATE_STOP);
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL user_kill(AMX *amx, cell *params) /* 2 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (pPlayer->ingame && pPlayer->IsAlive())
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
float bef = pPlayer->pEdict->v.frags;
|
|
|
|
MDLL_ClientKill(pPlayer->pEdict);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (params[2])
|
|
|
|
pPlayer->pEdict->v.frags = bef;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL user_slap(AMX *amx, cell *params) /* 2 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2013-06-25 09:45:00 +00:00
|
|
|
|
|
|
|
int power = (int)params[2];
|
|
|
|
|
|
|
|
if (power < 0)
|
|
|
|
power = 0;
|
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (pPlayer->ingame && pPlayer->IsAlive())
|
|
|
|
{
|
|
|
|
if (pPlayer->pEdict->v.health <= power)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
float bef = pPlayer->pEdict->v.frags;
|
|
|
|
MDLL_ClientKill(pPlayer->pEdict);
|
|
|
|
pPlayer->pEdict->v.frags = bef;
|
2005-09-16 23:48:51 +00:00
|
|
|
} else {
|
2005-09-09 03:23:31 +00:00
|
|
|
edict_t *pEdict = pPlayer->pEdict;
|
2005-09-16 23:48:51 +00:00
|
|
|
int numparam = *params / sizeof(cell);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (numparam < 3 || params[3])
|
|
|
|
{
|
|
|
|
pEdict->v.velocity.x += RANDOM_LONG(-600, 600);
|
|
|
|
pEdict->v.velocity.y += RANDOM_LONG(-180, 180);
|
|
|
|
pEdict->v.velocity.z += RANDOM_LONG(100, 200);
|
|
|
|
} else {
|
2005-09-09 03:23:31 +00:00
|
|
|
Vector v_forward, v_right;
|
|
|
|
Vector vang = pEdict->v.angles;
|
|
|
|
float fang[3];
|
|
|
|
fang[0] = vang.x;
|
|
|
|
fang[1] = vang.y;
|
|
|
|
fang[2] = vang.z;
|
2005-09-16 23:48:51 +00:00
|
|
|
ANGLEVECTORS(fang, v_forward, v_right, NULL);
|
|
|
|
pEdict->v.velocity = pEdict->v.velocity + v_forward * 220 + Vector(0, 0, 200);
|
2005-09-09 03:23:31 +00:00
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
pEdict->v.punchangle.x = static_cast<vec_t>(RANDOM_LONG(-10, 10));
|
|
|
|
pEdict->v.punchangle.y = static_cast<vec_t>(RANDOM_LONG(-10, 10));
|
2005-09-09 03:23:31 +00:00
|
|
|
pEdict->v.health -= power;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
int armor = (int)pEdict->v.armorvalue;
|
|
|
|
armor -= power;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (armor < 0)
|
|
|
|
armor = 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
pEdict->v.armorvalue = static_cast<float>(armor);
|
|
|
|
pEdict->v.dmg_inflictor = pEdict;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (g_bmod_cstrike)
|
|
|
|
{
|
|
|
|
static const char *cs_sound[4] =
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
"player/bhit_flesh-3.wav",
|
2005-09-16 23:48:51 +00:00
|
|
|
"player/bhit_flesh-2.wav",
|
|
|
|
"player/pl_die1.wav",
|
|
|
|
"player/pl_pain6.wav"
|
|
|
|
};
|
|
|
|
EMIT_SOUND_DYN2(pEdict, CHAN_VOICE, cs_sound[RANDOM_LONG(0, 3)], 1.0, ATTN_NORM, 0, PITCH_NORM);
|
|
|
|
} else{
|
|
|
|
static const char *bit_sound[3] =
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
"weapons/cbar_hitbod1.wav",
|
2005-09-16 23:48:51 +00:00
|
|
|
"weapons/cbar_hitbod2.wav",
|
|
|
|
"weapons/cbar_hitbod3.wav"
|
|
|
|
};
|
|
|
|
EMIT_SOUND_DYN2(pEdict, CHAN_VOICE, bit_sound[RANDOM_LONG(0, 2)], 1.0, ATTN_NORM, 0, PITCH_NORM);
|
2005-09-09 03:23:31 +00:00
|
|
|
}
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL server_cmd(AMX *amx, cell *params) /* 1 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int len;
|
|
|
|
g_langMngr.SetDefLang(LANG_SERVER);
|
2005-09-16 23:48:51 +00:00
|
|
|
char* cmd = format_amxstring(amx, params, 1, len);
|
2007-02-20 22:25:17 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
cmd[len++] = '\n';
|
|
|
|
cmd[len] = 0;
|
2015-07-19 19:11:34 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
SERVER_COMMAND(cmd);
|
2015-07-19 19:11:34 +00:00
|
|
|
|
|
|
|
CoreCfg.CheckLegacyBufferedCommand(cmd);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return len;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL client_cmd(AMX *amx, cell *params) /* 2 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int len;
|
2005-09-16 23:48:51 +00:00
|
|
|
char* cmd = format_amxstring(amx, params, 2, len);
|
|
|
|
cmd[len++] = '\n';
|
|
|
|
cmd[len] = 0;
|
2005-09-09 03:23:31 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (params[1] == 0)
|
|
|
|
{
|
|
|
|
for (int i = 1; i <= gpGlobals->maxClients; ++i)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(i);
|
2006-08-24 21:13:52 +00:00
|
|
|
if (!pPlayer->IsBot() && pPlayer->initialized /*&& pPlayer->ingame*/)
|
2005-10-09 15:39:20 +00:00
|
|
|
CLIENT_COMMAND(pPlayer->pEdict, "%s", cmd);
|
2005-09-09 03:23:31 +00:00
|
|
|
}
|
2005-09-16 23:48:51 +00:00
|
|
|
} else {
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index);
|
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2006-08-24 21:13:52 +00:00
|
|
|
if (!pPlayer->IsBot() && pPlayer->initialized /*&& pPlayer->ingame*/)
|
2005-10-09 15:39:20 +00:00
|
|
|
CLIENT_COMMAND(pPlayer->pEdict, "%s", cmd);
|
2005-09-09 03:23:31 +00:00
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return len;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL log_message(AMX *amx, cell *params) /* 1 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int len;
|
|
|
|
g_langMngr.SetDefLang(LANG_SERVER);
|
2005-09-16 23:48:51 +00:00
|
|
|
char* message = format_amxstring(amx, params, 1, len);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
message[len++] = '\n';
|
|
|
|
message[len] = 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
ALERT(at_logged, "%s", message);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return len;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
2017-08-01 13:14:53 +00:00
|
|
|
static cell AMX_NATIVE_CALL elog_message(AMX *amx, cell *params) /* 1 param */
|
|
|
|
{
|
|
|
|
int len;
|
|
|
|
g_langMngr.SetDefLang(LANG_SERVER);
|
|
|
|
char* message = format_amxstring(amx, params, 1, len);
|
|
|
|
|
|
|
|
message[len++] = '\n';
|
|
|
|
message[len] = 0;
|
|
|
|
|
|
|
|
g_pEngTable->pfnAlertMessage(at_logged, "%s", message);
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2004-03-24 01:35:44 +00:00
|
|
|
static cell AMX_NATIVE_CALL log_to_file(AMX *amx, cell *params) /* 1 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int ilen;
|
2005-09-16 23:48:51 +00:00
|
|
|
char* szFile = get_amxstring(amx, params[1], 0, ilen);
|
2005-09-09 03:23:31 +00:00
|
|
|
FILE*fp;
|
2017-03-11 18:26:25 +00:00
|
|
|
char file[PLATFORM_MAX_PATH];
|
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
if (strchr(szFile, '/') || strchr(szFile, '\\'))
|
|
|
|
{
|
2017-03-11 18:26:25 +00:00
|
|
|
build_pathname_r(file, sizeof(file), "%s", szFile);
|
2005-09-09 03:23:31 +00:00
|
|
|
} else {
|
2017-03-11 18:26:25 +00:00
|
|
|
build_pathname_r(file, sizeof(file), "%s/%s", g_log_dir.chars(), szFile);
|
2005-09-09 03:23:31 +00:00
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
bool first_time = true;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if ((fp = fopen(file, "r")) != NULL)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
first_time = false;
|
|
|
|
fclose(fp);
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if ((fp = fopen(file, "a")) == NULL)
|
|
|
|
{
|
|
|
|
//amx_RaiseError(amx, AMX_ERR_NATIVE);
|
2005-09-09 03:23:31 +00:00
|
|
|
//would cause too much troubles in old plugins
|
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
char date[32];
|
|
|
|
time_t td; time(&td);
|
2005-09-16 23:48:51 +00:00
|
|
|
strftime(date, 31, "%m/%d/%Y - %H:%M:%S", localtime(&td));
|
2005-09-09 03:23:31 +00:00
|
|
|
int len;
|
|
|
|
g_langMngr.SetDefLang(LANG_SERVER);
|
2005-09-16 23:48:51 +00:00
|
|
|
char* message = format_amxstring(amx, params, 2, len);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
message[len++] = '\n';
|
|
|
|
message[len] = 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (first_time)
|
|
|
|
{
|
2015-07-11 08:37:36 +00:00
|
|
|
fprintf(fp, "L %s: Log file started (file \"%s\") (game \"%s\") (amx \"%s\")\n", date, file, g_mod_name.chars(), Plugin_info.version);
|
|
|
|
print_srvconsole("L %s: Log file started (file \"%s\") (game \"%s\") (amx \"%s\")\n", date, file, g_mod_name.chars(), Plugin_info.version);
|
2005-09-16 23:48:51 +00:00
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
fprintf(fp, "L %s: %s", date, message);
|
|
|
|
print_srvconsole("L %s: %s", date, message);
|
2005-09-09 03:23:31 +00:00
|
|
|
fclose(fp);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL num_to_word(AMX *amx, cell *params) /* 3 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
char sptemp[512];
|
|
|
|
UTIL_IntToString(params[1], sptemp);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
return set_amxstring(amx, params[2], sptemp, params[3]);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL get_timeleft(AMX *amx, cell *params)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
float flCvarTimeLimit = mp_timelimit->value;
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (flCvarTimeLimit)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int iReturn = (int)((g_game_timeleft + flCvarTimeLimit * 60.0) - gpGlobals->time);
|
|
|
|
return (iReturn < 0) ? 0 : iReturn;
|
|
|
|
}
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL get_time(AMX *amx, cell *params) /* 3 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int ilen;
|
2005-09-16 23:48:51 +00:00
|
|
|
char* sptemp = get_amxstring(amx, params[1], 0, ilen);
|
2005-09-09 03:23:31 +00:00
|
|
|
time_t td = time(NULL);
|
|
|
|
tm* lt = localtime(&td);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
char szDate[512];
|
2005-09-16 23:48:51 +00:00
|
|
|
strftime(szDate, 511, sptemp, lt);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
return set_amxstring(amx, params[2], szDate, params[3]);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL format_time(AMX *amx, cell *params) /* 3 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int ilen;
|
2005-09-16 23:48:51 +00:00
|
|
|
char* sptemp = get_amxstring(amx, params[3], 0, ilen);
|
2005-09-09 03:23:31 +00:00
|
|
|
time_t tim = params[4];
|
2005-09-16 23:48:51 +00:00
|
|
|
time_t td = (tim != -1) ? tim : time(NULL);
|
2005-09-09 03:23:31 +00:00
|
|
|
tm* lt = localtime(&td);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (lt == 0)
|
|
|
|
{
|
2006-04-13 16:29:01 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Couldn't get localtime");
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
char szDate[512];
|
2014-05-03 13:41:05 +00:00
|
|
|
ilen = strftime(szDate, 511, sptemp, lt);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2015-06-29 09:28:11 +00:00
|
|
|
return set_amxstring_utf8(amx, params[1], szDate, ilen, params[2]);
|
2004-03-24 01:35:44 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL parse_time(AMX *amx, cell *params) /* 3 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int ilen;
|
2005-09-16 23:48:51 +00:00
|
|
|
char* sTime = get_amxstring(amx, params[1], 1, ilen);
|
|
|
|
char* sFormat = get_amxstring(amx, params[2], 0, ilen);
|
2005-09-09 03:23:31 +00:00
|
|
|
tm* mytime;
|
|
|
|
time_t td;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (params[3] == -1)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
td = time(NULL);
|
|
|
|
mytime = localtime(&td);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (mytime == 0)
|
|
|
|
{
|
2006-04-13 16:29:01 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Couldn't get localtime");
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
strptime(sTime, sFormat, mytime, 0);
|
|
|
|
} else {
|
2005-09-09 03:23:31 +00:00
|
|
|
td = params[3];
|
|
|
|
mytime = localtime(&td);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (mytime == 0)
|
|
|
|
{
|
2006-04-13 16:29:01 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Couldn't get localtime");
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
strptime(sTime, sFormat, mytime, 1);
|
2005-09-09 03:23:31 +00:00
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return mktime(mytime);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL get_systime(AMX *amx, cell *params) /* 3 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
time_t td = time(NULL);
|
2005-09-16 23:48:51 +00:00
|
|
|
td += params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return td;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL read_datanum(AMX *amx, cell *params) /* 0 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
return g_events.getArgNum();
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL read_data(AMX *amx, cell *params) /* 3 param */
|
|
|
|
{
|
2004-04-03 19:16:26 +00:00
|
|
|
if (params[0] == 0)
|
|
|
|
{
|
|
|
|
return g_events.getCurrentMsgType();
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
switch (*params / sizeof(cell))
|
|
|
|
{
|
2004-11-13 08:56:11 +00:00
|
|
|
case 1:
|
2005-09-16 23:48:51 +00:00
|
|
|
return g_events.getArgInteger(params[1]);
|
2004-11-13 08:56:11 +00:00
|
|
|
case 3:
|
2017-03-11 18:26:25 +00:00
|
|
|
return set_amxstring_utf8(amx, params[2], g_events.getArgString(params[1]),
|
2015-06-29 09:28:11 +00:00
|
|
|
strlen(g_events.getArgString(params[1])),*get_amxaddr(amx, params[3]));
|
2004-11-13 08:56:11 +00:00
|
|
|
default:
|
|
|
|
cell *fCell = get_amxaddr(amx, params[2]);
|
2006-06-10 21:00:33 +00:00
|
|
|
REAL fparam = (REAL)g_events.getArgFloat(params[1]);
|
2004-11-13 08:56:11 +00:00
|
|
|
fCell[0] = amx_ftoc(fparam);
|
|
|
|
return (int)fparam;
|
|
|
|
}
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
2013-07-27 18:49:19 +00:00
|
|
|
static cell AMX_NATIVE_CALL read_datatype(AMX *amx, cell *params) /* 0 param */
|
|
|
|
{
|
|
|
|
return g_events.getCurrentMsgType();
|
|
|
|
}
|
|
|
|
|
2004-03-24 01:35:44 +00:00
|
|
|
static cell AMX_NATIVE_CALL get_playersnum(AMX *amx, cell *params)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
if (!params[1])
|
|
|
|
return g_players_num;
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
int a = 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
for (int i = 1; i <= gpGlobals->maxClients; ++i)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(i);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (pPlayer->initialized && (GETPLAYERUSERID(pPlayer->pEdict) > 0))
|
2005-09-09 03:23:31 +00:00
|
|
|
++a;
|
|
|
|
}
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return a;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL get_players(AMX *amx, cell *params) /* 4 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int iNum = 0;
|
|
|
|
int ilen;
|
2005-09-16 23:48:51 +00:00
|
|
|
char* sptemp = get_amxstring(amx, params[3], 0, ilen);
|
2005-09-09 03:23:31 +00:00
|
|
|
int flags = UTIL_ReadFlags(sptemp);
|
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
cell *aPlayers = get_amxaddr(amx, params[1]);
|
|
|
|
cell *iMax = get_amxaddr(amx, params[2]);
|
2005-09-09 03:23:31 +00:00
|
|
|
|
|
|
|
int team = 0;
|
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (flags & 48)
|
|
|
|
{
|
|
|
|
sptemp = get_amxstring(amx, params[4], 0, ilen);
|
2005-09-09 03:23:31 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (flags & 16)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
if (flags & 64)
|
2005-09-16 23:48:51 +00:00
|
|
|
team = g_teamsIds.findTeamId(sptemp);
|
2005-09-09 03:23:31 +00:00
|
|
|
else
|
2005-09-16 23:48:51 +00:00
|
|
|
team = g_teamsIds.findTeamIdCase(sptemp);
|
2005-09-09 03:23:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
for (int i = 1; i <= gpGlobals->maxClients; ++i)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(i);
|
2014-08-19 16:25:00 +00:00
|
|
|
if (pPlayer->ingame || ((flags & 256) && pPlayer->initialized))
|
2005-09-16 23:48:51 +00:00
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
if (pPlayer->IsAlive() ? (flags & 2) : (flags & 1))
|
|
|
|
continue;
|
2006-08-24 21:13:52 +00:00
|
|
|
if (pPlayer->IsBot() ? (flags & 4) : (flags & 8))
|
2005-09-09 03:23:31 +00:00
|
|
|
continue;
|
2005-09-16 23:48:51 +00:00
|
|
|
if ((flags & 16) && (pPlayer->teamId != team))
|
2005-09-09 03:23:31 +00:00
|
|
|
continue;
|
2006-03-13 22:43:55 +00:00
|
|
|
if ((flags & 128) && (pPlayer->pEdict->v.flags & FL_PROXY))
|
|
|
|
continue;
|
2005-09-16 23:48:51 +00:00
|
|
|
if (flags & 32)
|
|
|
|
{
|
|
|
|
if (flags & 64)
|
|
|
|
{
|
2017-08-05 08:32:16 +00:00
|
|
|
if (utf8stristr(pPlayer->name.chars(), sptemp) == NULL)
|
2005-09-09 03:23:31 +00:00
|
|
|
continue;
|
|
|
|
}
|
2015-07-11 08:37:36 +00:00
|
|
|
else if (strstr(pPlayer->name.chars(), sptemp) == NULL)
|
2005-09-09 03:23:31 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
aPlayers[iNum++] = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*iMax = iNum;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL find_player(AMX *amx, cell *params) /* 1 param */
|
|
|
|
{
|
2005-11-07 16:37:47 +00:00
|
|
|
typedef int (*STRCOMPARE)(const char*, const char*);
|
|
|
|
STRCOMPARE func;
|
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
int ilen, userid = 0;
|
2005-09-16 23:48:51 +00:00
|
|
|
char* sptemp = get_amxstring(amx, params[1], 0, ilen);
|
2005-09-09 03:23:31 +00:00
|
|
|
int flags = UTIL_ReadFlags(sptemp);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (flags & 31)
|
|
|
|
sptemp = get_amxstring(amx, params[2], 0, ilen);
|
|
|
|
else if (flags & 1024)
|
|
|
|
userid = *get_amxaddr(amx, params[2]);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
// a b c d e f g h i j k l
|
|
|
|
int result = 0;
|
2005-11-07 16:37:47 +00:00
|
|
|
|
|
|
|
// Switch for the l flag
|
|
|
|
if (flags & 2048)
|
2017-08-05 08:32:16 +00:00
|
|
|
func = utf8strcasecmp;
|
2005-11-07 16:37:47 +00:00
|
|
|
else
|
|
|
|
func = strcmp;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
for (int i = 1; i <= gpGlobals->maxClients; ++i)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(i);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2014-08-19 16:25:00 +00:00
|
|
|
if (pPlayer->ingame || ((flags & 4096) && pPlayer->initialized))
|
2005-09-16 23:48:51 +00:00
|
|
|
{
|
|
|
|
if (pPlayer->IsAlive() ? (flags & 64) : (flags & 32))
|
2005-09-09 03:23:31 +00:00
|
|
|
continue;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2006-08-24 21:13:52 +00:00
|
|
|
if (pPlayer->IsBot() ? (flags & 128) : (flags & 256))
|
2005-09-09 03:23:31 +00:00
|
|
|
continue;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (flags & 1)
|
|
|
|
{
|
2015-07-11 08:37:36 +00:00
|
|
|
if ((func)(pPlayer->name.chars(), sptemp))
|
2005-09-09 03:23:31 +00:00
|
|
|
continue;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (flags & 2)
|
|
|
|
{
|
|
|
|
if (flags & 2048)
|
|
|
|
{
|
2017-08-05 08:32:16 +00:00
|
|
|
if (utf8stristr(pPlayer->name.chars(), sptemp) == NULL)
|
2005-09-09 03:23:31 +00:00
|
|
|
continue;
|
|
|
|
}
|
2015-07-11 08:37:36 +00:00
|
|
|
else if (strstr(pPlayer->name.chars(), sptemp) == NULL)
|
2005-09-09 03:23:31 +00:00
|
|
|
continue;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (flags & 4)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
const char* authid = GETPLAYERAUTHID(pPlayer->pEdict);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-11-07 16:37:47 +00:00
|
|
|
if (!authid || (func)(authid, sptemp))
|
2005-09-09 03:23:31 +00:00
|
|
|
continue;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (flags & 1024)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
if (userid != GETPLAYERUSERID(pPlayer->pEdict))
|
|
|
|
continue;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (flags & 8)
|
|
|
|
{
|
2015-07-11 08:37:36 +00:00
|
|
|
if (strncmp(pPlayer->ip.chars(), sptemp, ilen))
|
2005-09-09 03:23:31 +00:00
|
|
|
continue;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (flags & 16)
|
|
|
|
{
|
2015-07-11 08:37:36 +00:00
|
|
|
if ((func)(pPlayer->team.chars(), sptemp))
|
2005-09-09 03:23:31 +00:00
|
|
|
continue;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
result = i;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if ((flags & 512) == 0)
|
2005-09-09 03:23:31 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
2017-12-07 23:06:37 +00:00
|
|
|
// native find_player_ex(FindPlayerFlags:flags, ...);
|
|
|
|
static cell AMX_NATIVE_CALL find_player_ex(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
cell amx_addr;
|
|
|
|
cell *phys_addr;
|
|
|
|
char strFlags[14];
|
|
|
|
|
|
|
|
amx_Allot(amx, ARRAY_LENGTH(strFlags), &amx_addr, &phys_addr);
|
|
|
|
UTIL_GetFlags(strFlags, params[1]);
|
|
|
|
set_amxstring(amx, amx_addr, strFlags, ARRAY_LENGTH(strFlags) - 1);
|
|
|
|
|
|
|
|
params[1] = amx_addr;
|
|
|
|
cell ret = find_player(amx, params);
|
|
|
|
amx_Release(amx, amx_addr);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2004-03-24 01:35:44 +00:00
|
|
|
static cell AMX_NATIVE_CALL get_maxplayers(AMX *amx, cell *params)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
return gpGlobals->maxClients;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL get_gametime(AMX *amx, cell *params)
|
|
|
|
{
|
2006-06-10 21:00:33 +00:00
|
|
|
REAL pFloat = (REAL)gpGlobals->time;
|
2005-09-09 03:23:31 +00:00
|
|
|
return amx_ftoc(pFloat);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL get_mapname(AMX *amx, cell *params) /* 2 param */
|
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
return set_amxstring(amx, params[1], STRING(gpGlobals->mapname), params[2]);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL get_modname(AMX *amx, cell *params) /* 2 param */
|
|
|
|
{
|
2015-07-11 08:37:36 +00:00
|
|
|
return set_amxstring(amx, params[1], g_mod_name.chars(), params[2]);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL get_localinfo(AMX *amx, cell *params) /* 3 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int ilen;
|
2005-09-16 23:48:51 +00:00
|
|
|
char* sptemp = get_amxstring(amx, params[1], 0, ilen);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2014-04-30 07:33:03 +00:00
|
|
|
char *value = LOCALINFO(sptemp);
|
2015-06-29 09:28:11 +00:00
|
|
|
return set_amxstring_utf8(amx, params[2], value, strlen(value), params[3]);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL set_localinfo(AMX *amx, cell *params) /* 2 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int ilen;
|
2005-09-16 23:48:51 +00:00
|
|
|
char* sptemp = get_amxstring(amx, params[1], 0, ilen);
|
|
|
|
char* szValue = get_amxstring(amx, params[2], 1, ilen);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
SET_LOCALINFO(sptemp, szValue);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL get_user_info(AMX *amx, cell *params) /* 4 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index);
|
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
if (!pPlayer->pEdict)
|
|
|
|
{
|
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Player %d is not connected", index);
|
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
int ilen;
|
2005-09-16 23:48:51 +00:00
|
|
|
char* sptemp = get_amxstring(amx, params[2], 0, ilen);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
return set_amxstring(amx, params[3], ENTITY_KEYVALUE(pPlayer->pEdict, sptemp), params[4]);
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL set_user_info(AMX *amx, cell *params) /* 3 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index);
|
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
if (!pPlayer->pEdict)
|
|
|
|
{
|
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Player %d is not connected", index);
|
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
int ilen;
|
2005-09-16 23:48:51 +00:00
|
|
|
char* sptemp = get_amxstring(amx, params[2], 0, ilen);
|
|
|
|
char* szValue = get_amxstring(amx, params[3], 1, ilen);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
ENTITY_SET_KEYVALUE(pPlayer->pEdict, sptemp, szValue);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL read_argc(AMX *amx, cell *params)
|
|
|
|
{
|
2014-05-02 07:16:16 +00:00
|
|
|
return g_fakecmd.notify ? g_fakecmd.argc : CMD_ARGC();
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL read_argv(AMX *amx, cell *params) /* 3 param */
|
|
|
|
{
|
2014-05-02 07:16:16 +00:00
|
|
|
int argc = params[1];
|
|
|
|
|
|
|
|
const char *value = g_fakecmd.notify ? (argc >= 0 && argc < 3 ? g_fakecmd.argv[argc] : "") : CMD_ARGV(argc);
|
2016-08-31 18:34:02 +00:00
|
|
|
return set_amxstring_utf8(amx, params[2], value, strlen(value), params[3]);
|
|
|
|
}
|
2016-03-28 18:05:56 +00:00
|
|
|
|
2016-08-31 18:34:02 +00:00
|
|
|
static cell AMX_NATIVE_CALL read_argv_int(AMX *amx, cell *params) /* 1 param */
|
|
|
|
{
|
|
|
|
int argc = params[1];
|
|
|
|
|
|
|
|
if (argc <= 0)
|
2016-03-28 18:05:56 +00:00
|
|
|
{
|
2016-08-31 18:34:02 +00:00
|
|
|
return 0;
|
2016-03-28 18:05:56 +00:00
|
|
|
}
|
2016-08-31 18:34:02 +00:00
|
|
|
|
|
|
|
const char *value = g_fakecmd.notify ? (argc >= 1 && argc < 3 ? g_fakecmd.argv[argc] : "") : CMD_ARGV(argc);
|
|
|
|
|
|
|
|
return atoi(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL read_argv_float(AMX *amx, cell *params) /* 1 param */
|
|
|
|
{
|
|
|
|
int argc = params[1];
|
|
|
|
|
|
|
|
if (argc <= 0)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *value = g_fakecmd.notify ? (argc >= 1 && argc < 3 ? g_fakecmd.argv[argc] : "") : CMD_ARGV(argc);
|
|
|
|
float flValue = atof(value);
|
|
|
|
|
|
|
|
return amx_ftoc(flValue);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL read_args(AMX *amx, cell *params) /* 2 param */
|
|
|
|
{
|
2014-05-02 07:16:16 +00:00
|
|
|
const char* sValue = g_fakecmd.notify ? (g_fakecmd.argc > 1 ? g_fakecmd.args : g_fakecmd.argv[0]) : CMD_ARGS();
|
2015-06-29 09:28:11 +00:00
|
|
|
return set_amxstring_utf8(amx, params[1], sValue ? sValue : "", sValue ? strlen(sValue) : 0, params[2]);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL get_user_msgid(AMX *amx, cell *params) /* 1 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int ilen;
|
2005-09-16 23:48:51 +00:00
|
|
|
char* sptemp = get_amxstring(amx, params[1], 0, ilen);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
return GET_USER_MSG_ID(PLID, sptemp, NULL);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
2004-10-25 23:00:16 +00:00
|
|
|
static cell AMX_NATIVE_CALL get_user_msgname(AMX *amx, cell *params) /* get_user_msgname(msg, str[], len) = 3 params */
|
|
|
|
{
|
|
|
|
const char* STRING = GET_USER_MSG_NAME(PLID, params[1], NULL);
|
|
|
|
if (STRING)
|
|
|
|
return set_amxstring(amx, params[2], STRING, params[3]);
|
|
|
|
|
|
|
|
// Comes here if GET_USER_MSG_NAME failed (ie, invalid msg id)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2004-03-24 01:35:44 +00:00
|
|
|
static cell AMX_NATIVE_CALL set_task(AMX *amx, cell *params) /* 2 param */
|
|
|
|
{
|
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
CPluginMngr::CPlugin *plugin = g_plugins.findPluginFast(amx);
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
int a, iFunc;
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
char* stemp = get_amxstring(amx, params[2], 1, a);
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
if (params[5])
|
|
|
|
{
|
|
|
|
iFunc = registerSPForwardByName(amx, stemp, FP_ARRAY, FP_CELL, FP_DONE);
|
|
|
|
} else {
|
|
|
|
iFunc = registerSPForwardByName(amx, stemp, FP_CELL, FP_DONE);
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
if (iFunc == -1)
|
|
|
|
{
|
2006-04-13 16:29:01 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Function is not present (function \"%s\") (plugin \"%s\")", stemp, plugin->getName());
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
float base = amx_ctof(params[1]);
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (base < 0.1f)
|
2005-09-09 03:23:31 +00:00
|
|
|
base = 0.1f;
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
char* temp = get_amxstring(amx, params[6], 0, a);
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
g_tasksMngr.registerTask(plugin, iFunc, UTIL_ReadFlags(temp), params[3], base, params[5], get_amxaddr(amx, params[4]), params[7]);
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL remove_task(AMX *amx, cell *params) /* 1 param */
|
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
return g_tasksMngr.removeTasks(params[1], params[2] ? 0 : amx);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
2004-07-18 08:07:50 +00:00
|
|
|
static cell AMX_NATIVE_CALL change_task(AMX *amx, cell *params)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
REAL flNewTime = amx_ctof(params[2]);
|
|
|
|
return g_tasksMngr.changeTasks(params[1], params[3] ? 0 : amx, flNewTime);
|
2004-07-18 08:07:50 +00:00
|
|
|
}
|
|
|
|
|
2015-01-23 15:52:58 +00:00
|
|
|
static cell AMX_NATIVE_CALL engine_changelevel(AMX *amx, cell *params)
|
2014-08-05 07:49:32 +00:00
|
|
|
{
|
|
|
|
int length;
|
2018-07-24 08:37:05 +00:00
|
|
|
ke::AString new_map(get_amxstring(amx, params[1], 0, length));
|
2014-08-05 07:49:32 +00:00
|
|
|
|
|
|
|
// Same as calling "changelevel" command but will trigger "server_changelevel" AMXX forward as well.
|
2017-03-11 18:26:25 +00:00
|
|
|
// Filling second param will call "changelevel2" command, but this is not usable in multiplayer game.
|
2018-07-24 08:37:05 +00:00
|
|
|
g_pEngTable->pfnChangeLevel(new_map.chars(), NULL);
|
2014-08-05 07:49:32 +00:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2004-03-24 01:35:44 +00:00
|
|
|
static cell AMX_NATIVE_CALL task_exists(AMX *amx, cell *params) /* 1 param */
|
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
return g_tasksMngr.taskExists(params[1], params[2] ? 0 : amx);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL get_user_ping(AMX *amx, cell *params) /* 3 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (pPlayer->ingame)
|
|
|
|
{
|
|
|
|
cell *cpPing = get_amxaddr(amx, params[2]);
|
|
|
|
cell *cpLoss = get_amxaddr(amx, params[3]);
|
2005-09-09 03:23:31 +00:00
|
|
|
int ping, loss;
|
2005-09-16 23:48:51 +00:00
|
|
|
PLAYER_CNX_STATS(pPlayer->pEdict, &ping, &loss);
|
2005-09-09 03:23:31 +00:00
|
|
|
*cpPing = ping;
|
|
|
|
*cpLoss = loss;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL get_user_time(AMX *amx, cell *params) /* 1 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (pPlayer->ingame)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int time = (int)(gpGlobals->time - (params[2] ? pPlayer->playtime : pPlayer->time));
|
|
|
|
return time;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL server_exec(AMX *amx, cell *params)
|
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
SERVER_EXECUTE();
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
2017-07-21 21:44:05 +00:00
|
|
|
int sendFakeCommand(AMX *amx, cell *params, bool send_forward = false)
|
2004-03-24 01:35:44 +00:00
|
|
|
{
|
2017-07-21 21:44:05 +00:00
|
|
|
enum args { arg_count, arg_index, arg_command, arg_argument1, arg_argument2 };
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2017-07-21 21:44:05 +00:00
|
|
|
char command[128 * 2];
|
|
|
|
auto command_length = strncopy(command, get_amxaddr(amx, params[arg_command]), sizeof(command));
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2017-07-21 21:44:05 +00:00
|
|
|
if (!command_length)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2017-07-21 21:44:05 +00:00
|
|
|
char argument1[128];
|
|
|
|
char argument2[128];
|
|
|
|
auto argument1_length = strncopy(argument1, get_amxaddr(amx, params[arg_argument1]), sizeof(argument1));
|
|
|
|
auto argument2_length = strncopy(argument2, get_amxaddr(amx, params[arg_argument2]), sizeof(argument2));
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2017-07-21 21:44:05 +00:00
|
|
|
const char *pArgument1 = argument1_length ? argument1 : nullptr;
|
|
|
|
const char *pArgument2 = argument2_length ? argument2 : nullptr;
|
|
|
|
|
|
|
|
int index = params[arg_index];
|
|
|
|
|
|
|
|
if (index == 0)
|
2005-09-16 23:48:51 +00:00
|
|
|
{
|
|
|
|
for (int i = 1; i <= gpGlobals->maxClients; ++i)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(i);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (pPlayer->ingame /*&& pPlayer->initialized */)
|
2017-07-21 21:44:05 +00:00
|
|
|
UTIL_FakeClientCommand(pPlayer->pEdict, command, pArgument1, pArgument2, send_forward);
|
2005-09-09 03:23:31 +00:00
|
|
|
}
|
2017-12-07 17:45:16 +00:00
|
|
|
}
|
|
|
|
else
|
2017-07-21 21:44:05 +00:00
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index);
|
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (/*pPlayer->initialized && */pPlayer->ingame)
|
2017-07-21 21:44:05 +00:00
|
|
|
UTIL_FakeClientCommand(pPlayer->pEdict, command, pArgument1, pArgument2, send_forward);
|
2005-09-09 03:23:31 +00:00
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
2017-07-21 21:44:05 +00:00
|
|
|
|
|
|
|
// native engclient_cmd(index, const command[], const arg1[] = "", const arg2[] = "");
|
|
|
|
static cell AMX_NATIVE_CALL engclient_cmd(AMX *amx, cell *params)
|
2014-05-02 07:16:16 +00:00
|
|
|
{
|
|
|
|
return sendFakeCommand(amx, params);
|
|
|
|
}
|
|
|
|
|
2017-07-21 21:44:05 +00:00
|
|
|
// native amxclient_cmd(index, const command[], const arg1[] = "", const arg2[] = "");
|
|
|
|
static cell AMX_NATIVE_CALL amxclient_cmd(AMX *amx, cell *params)
|
2014-05-02 07:16:16 +00:00
|
|
|
{
|
|
|
|
return sendFakeCommand(amx, params, true);
|
|
|
|
}
|
2004-03-24 01:35:44 +00:00
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL pause(AMX *amx, cell *params) /* 3 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int ilen;
|
2005-09-16 23:48:51 +00:00
|
|
|
char* temp = get_amxstring(amx, params[1], 0, ilen);
|
2005-09-09 03:23:31 +00:00
|
|
|
int flags = UTIL_ReadFlags(temp);
|
|
|
|
|
|
|
|
CPluginMngr::CPlugin *plugin = 0;
|
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (flags & 2) // pause function
|
|
|
|
{
|
2006-04-13 16:29:01 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "This usage of the native pause() has been deprecated!");
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2005-09-16 23:48:51 +00:00
|
|
|
else if (flags & 4)
|
|
|
|
{
|
|
|
|
temp = get_amxstring(amx, params[2], 0, ilen);
|
2005-09-09 03:23:31 +00:00
|
|
|
plugin = g_plugins.findPlugin(temp);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
plugin = g_plugins.findPluginFast(amx);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (plugin && plugin->isValid())
|
|
|
|
{
|
|
|
|
if (flags & 8)
|
|
|
|
plugin->setStatus(ps_stopped);
|
2005-11-29 21:59:21 +00:00
|
|
|
/*else if (flags & 16)
|
|
|
|
plugin->setStatus(ps_locked);*/
|
2005-09-09 03:23:31 +00:00
|
|
|
else
|
|
|
|
plugin->pausePlugin();
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL unpause(AMX *amx, cell *params) /* 3 param */
|
|
|
|
{
|
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
int ilen;
|
2005-09-16 23:48:51 +00:00
|
|
|
char* sptemp = get_amxstring(amx, params[1], 0, ilen);
|
2005-09-09 03:23:31 +00:00
|
|
|
int flags = UTIL_ReadFlags(sptemp);
|
|
|
|
CPluginMngr::CPlugin *plugin = 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (flags & 2)
|
2005-09-09 03:23:31 +00:00
|
|
|
{
|
2006-04-13 16:29:01 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "This usage of the native pause() has been deprecated!");
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
2005-09-16 23:48:51 +00:00
|
|
|
}
|
|
|
|
else if (flags & 4)
|
|
|
|
{
|
|
|
|
sptemp = get_amxstring(amx, params[2], 0, ilen);
|
2005-09-09 03:23:31 +00:00
|
|
|
plugin = g_plugins.findPlugin(sptemp);
|
|
|
|
}
|
|
|
|
else
|
2005-09-16 23:48:51 +00:00
|
|
|
plugin = g_plugins.findPluginFast(amx);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2007-02-19 06:43:52 +00:00
|
|
|
if (plugin && plugin->isValid() && plugin->isPaused() && !plugin->isStopped())
|
2005-09-09 03:23:31 +00:00
|
|
|
{
|
|
|
|
plugin->unpausePlugin();
|
|
|
|
return 1;
|
|
|
|
}
|
2004-06-24 07:09:17 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2004-03-24 01:35:44 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL read_flags(AMX *amx, cell *params) /* 1 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int ilen;
|
2005-09-16 23:48:51 +00:00
|
|
|
char* sptemp = get_amxstring(amx, params[1], 0, ilen);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return UTIL_ReadFlags(sptemp);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL get_flags(AMX *amx, cell *params) /* 1 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
char flags[32];
|
2005-09-16 23:48:51 +00:00
|
|
|
UTIL_GetFlags(flags, params[1]);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
return set_amxstring(amx, params[2], flags, params[3]);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL get_user_flags(AMX *amx, cell *params) /* 2 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 0 || index > gpGlobals->maxClients)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index);
|
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
int id = params[2];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (id < 0)
|
|
|
|
id = 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (id > 31)
|
|
|
|
id = 31;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return GET_PLAYER_POINTER_I(index)->flags[id];
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL set_user_flags(AMX *amx, cell *params) /* 3 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 0 || index > gpGlobals->maxClients)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index);
|
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
|
|
|
int flag = params[2];
|
|
|
|
int id = params[3];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (id < 0)
|
|
|
|
id = 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (id > 31)
|
|
|
|
id = 31;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
pPlayer->flags[id] |= flag;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL remove_user_flags(AMX *amx, cell *params) /* 3 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 0 || index > gpGlobals->maxClients)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index);
|
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
|
|
|
int flag = params[2];
|
|
|
|
int id = params[3];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (id < 0)
|
|
|
|
id = 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (id > 31)
|
|
|
|
id = 31;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
pPlayer->flags[id] &= ~flag;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL register_menuid(AMX *amx, cell *params) /* 1 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int i;
|
2005-09-16 23:48:51 +00:00
|
|
|
char* temp = get_amxstring(amx, params[1], 0, i);
|
|
|
|
AMX* a = (*params / sizeof(cell) < 2 || params[2]) ? 0 : amx;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
return g_menucmds.registerMenuId(temp, a);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL get_user_menu(AMX *amx, cell *params) /* 3 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index);
|
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
cell *cpMenu = get_amxaddr(amx, params[2]);
|
|
|
|
cell *cpKeys = get_amxaddr(amx, params[3]);
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (pPlayer->ingame)
|
|
|
|
{
|
2005-11-13 20:33:30 +00:00
|
|
|
if (gpGlobals->time > pPlayer->menuexpire)
|
|
|
|
{
|
2014-05-27 08:33:53 +00:00
|
|
|
if (Menu *pMenu = get_menu_by_id(pPlayer->newmenu))
|
2014-05-21 17:01:27 +00:00
|
|
|
pMenu->Close(pPlayer->index);
|
|
|
|
else
|
|
|
|
pPlayer->menu = 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-11-13 20:33:30 +00:00
|
|
|
*cpMenu = 0;
|
|
|
|
*cpKeys = 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-11-13 20:33:30 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
*cpMenu = pPlayer->menu;
|
|
|
|
*cpKeys = pPlayer->keys;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL precache_sound(AMX *amx, cell *params) /* 1 param */
|
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
if (g_dontprecache)
|
|
|
|
{
|
2006-04-13 16:29:01 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Precaching not allowed");
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2006-06-05 07:48:54 +00:00
|
|
|
int len;
|
|
|
|
char* sptemp = get_amxstring(amx, params[1], 0, len);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2007-05-04 01:38:30 +00:00
|
|
|
return PRECACHE_SOUND((char*)STRING(ALLOC_STRING(sptemp)));
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL precache_model(AMX *amx, cell *params) /* 1 param */
|
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
if (g_dontprecache)
|
|
|
|
{
|
2006-04-13 16:29:01 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Precaching not allowed");
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2006-06-05 07:48:54 +00:00
|
|
|
int len;
|
|
|
|
char* sptemp = get_amxstring(amx, params[1], 0, len);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return PRECACHE_MODEL((char*)STRING(ALLOC_STRING(sptemp)));
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
2006-06-05 07:48:54 +00:00
|
|
|
static cell AMX_NATIVE_CALL precache_generic(AMX *amx, cell *params)
|
2004-03-24 01:35:44 +00:00
|
|
|
{
|
2006-06-05 07:48:54 +00:00
|
|
|
if (g_dontprecache)
|
|
|
|
{
|
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Precaching not allowed");
|
|
|
|
return 0;
|
|
|
|
}
|
2005-07-13 23:31:02 +00:00
|
|
|
|
2006-06-05 07:48:54 +00:00
|
|
|
int len;
|
|
|
|
char* sptemp = get_amxstring(amx, params[1], 0, len);
|
2005-07-13 23:31:02 +00:00
|
|
|
|
2006-06-05 07:48:54 +00:00
|
|
|
return PRECACHE_GENERIC((char*)STRING(ALLOC_STRING(sptemp)));
|
2005-07-13 23:31:02 +00:00
|
|
|
}
|
|
|
|
|
2015-05-10 21:45:01 +00:00
|
|
|
static cell AMX_NATIVE_CALL precache_event(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
int len;
|
|
|
|
char *sptemp = format_amxstring(amx, params, 2, len);
|
|
|
|
|
|
|
|
return PRECACHE_EVENT(params[1], (char*)STRING(ALLOC_STRING(sptemp)));
|
|
|
|
}
|
|
|
|
|
2004-03-24 01:35:44 +00:00
|
|
|
static cell AMX_NATIVE_CALL random_float(AMX *amx, cell *params) /* 2 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
float one = amx_ctof(params[1]);
|
|
|
|
float two = amx_ctof(params[2]);
|
2005-09-16 23:48:51 +00:00
|
|
|
REAL fRnd = RANDOM_FLOAT(one, two);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return amx_ftoc(fRnd);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL random_num(AMX *amx, cell *params) /* 2 param */
|
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
return RANDOM_LONG(params[1], params[2]);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL remove_quotes(AMX *amx, cell *params) /* 1 param */
|
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
cell *text = get_amxaddr(amx, params[1]);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (*text == '\"')
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
register cell *temp = text;
|
|
|
|
int len = 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
while (*temp++)
|
|
|
|
++len; // get length
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
cell *src = text;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (src[len-1] == '\r')
|
2005-09-09 03:23:31 +00:00
|
|
|
src[--len] = 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (src[--len] == '\"')
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
src[len] = 0;
|
2005-09-16 23:48:51 +00:00
|
|
|
temp = src + 1;
|
|
|
|
while ((*src++ = *temp++));
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL get_user_aiming(AMX *amx, cell *params) /* 4 param */
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int index = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index);
|
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2005-09-16 23:48:51 +00:00
|
|
|
cell *cpId = get_amxaddr(amx, params[2]);
|
|
|
|
cell *cpBody = get_amxaddr(amx, params[3]);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2006-08-17 00:23:03 +00:00
|
|
|
REAL pfloat = 0.0f;
|
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (pPlayer->ingame)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
edict_t* edict = pPlayer->pEdict;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
Vector v_forward;
|
|
|
|
Vector v_src = edict->v.origin + edict->v.view_ofs;
|
2006-08-17 00:23:03 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
ANGLEVECTORS(edict->v.v_angle, v_forward, NULL, NULL);
|
2005-09-09 03:23:31 +00:00
|
|
|
TraceResult trEnd;
|
|
|
|
Vector v_dest = v_src + v_forward * static_cast<float>(params[4]);
|
2005-09-16 23:48:51 +00:00
|
|
|
TRACE_LINE(v_src, v_dest, 0, edict, &trEnd);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
*cpId = FNullEnt(trEnd.pHit) ? 0 : ENTINDEX(trEnd.pHit);
|
|
|
|
*cpBody = trEnd.iHitgroup;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (trEnd.flFraction < 1.0)
|
|
|
|
{
|
2006-08-17 00:23:03 +00:00
|
|
|
pfloat = (trEnd.vecEndPos - v_src).Length();
|
2005-09-09 03:23:31 +00:00
|
|
|
}
|
2006-08-27 01:38:47 +00:00
|
|
|
} else {
|
|
|
|
*cpId = 0;
|
|
|
|
*cpBody = 0;
|
2005-09-09 03:23:31 +00:00
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2006-08-17 00:23:03 +00:00
|
|
|
return amx_ftoc(pfloat);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL force_unmodified(AMX *amx, cell *params)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int a;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
cell *cpVec1 = get_amxaddr(amx, params[2]);
|
|
|
|
cell *cpVec2 = get_amxaddr(amx, params[3]);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
Vector vec1 = Vector((float)cpVec1[0], (float)cpVec1[1], (float)cpVec1[2]);
|
|
|
|
Vector vec2 = Vector((float)cpVec2[0], (float)cpVec2[1], (float)cpVec2[2]);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
char* filename = get_amxstring(amx, params[4], 0, a);
|
|
|
|
|
2017-04-14 17:36:59 +00:00
|
|
|
auto object = ke::AutoPtr<ForceObject>(new ForceObject(filename, (FORCE_TYPE)((int)(params[1])), vec1, vec2, amx));
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2017-04-14 17:36:59 +00:00
|
|
|
if (object)
|
2005-09-16 23:48:51 +00:00
|
|
|
{
|
2017-04-14 17:36:59 +00:00
|
|
|
auto forceObjVec = &g_forcegeneric;
|
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (stristr(filename, ".wav"))
|
2017-04-14 17:36:59 +00:00
|
|
|
forceObjVec = &g_forcesounds;
|
2005-09-16 23:48:51 +00:00
|
|
|
else if (stristr(filename, ".mdl"))
|
2017-04-14 17:36:59 +00:00
|
|
|
forceObjVec = &g_forcemodels;
|
|
|
|
|
|
|
|
forceObjVec->append(ke::Move(object));
|
2005-09-09 03:23:31 +00:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL read_logdata(AMX *amx, cell *params)
|
|
|
|
{
|
2014-04-30 07:33:03 +00:00
|
|
|
const char *value = g_logevents.getLogString();
|
2015-06-29 09:28:11 +00:00
|
|
|
return set_amxstring_utf8(amx, params[1], value, strlen(value), params[2]);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL read_logargc(AMX *amx, cell *params)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
return g_logevents.getLogArgNum();
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL read_logargv(AMX *amx, cell *params)
|
|
|
|
{
|
2014-04-30 07:33:03 +00:00
|
|
|
const char *value = g_logevents.getLogArg(params[1]);
|
2015-06-29 09:28:11 +00:00
|
|
|
return set_amxstring_utf8(amx, params[2], value, strlen(value), params[3]);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL parse_loguser(AMX *amx, cell *params)
|
|
|
|
{
|
2005-09-09 03:23:31 +00:00
|
|
|
int len;
|
2005-09-16 23:48:51 +00:00
|
|
|
char *text = get_amxstring(amx, params[1], 0, len);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if (len < 6) // no user to parse!?
|
|
|
|
{
|
2006-04-13 16:29:01 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "No user name specified");
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
/******** GET TEAM **********/
|
|
|
|
char* end = text + --len;
|
|
|
|
*end = 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
while (*end != '<' && len--)
|
2005-09-09 03:23:31 +00:00
|
|
|
--end;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
++end;
|
2005-09-16 23:48:51 +00:00
|
|
|
cell *cPtr = get_amxaddr(amx, params[7]);
|
2005-09-09 03:23:31 +00:00
|
|
|
int max = params[8]; // get TEAM
|
2005-09-16 23:48:51 +00:00
|
|
|
// print_srvconsole("Got team: %s (Len %d)\n", end, len);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
while (max-- && *end)
|
2005-09-09 03:23:31 +00:00
|
|
|
*cPtr++ = *end++;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
*cPtr = 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
/******** GET AUTHID **********/
|
2005-09-16 23:48:51 +00:00
|
|
|
if (len <= 0)
|
|
|
|
{
|
2006-04-13 16:29:01 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "No Authid found");
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
end = text + --len;
|
|
|
|
*end = 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
while (*end != '<' && len--)
|
2005-09-09 03:23:31 +00:00
|
|
|
--end;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
++end;
|
2005-09-16 23:48:51 +00:00
|
|
|
cPtr = get_amxaddr(amx, params[5]);
|
2005-09-09 03:23:31 +00:00
|
|
|
max = params[6]; // get AUTHID
|
2005-09-16 23:48:51 +00:00
|
|
|
// print_srvconsole("Got auth: %s (Len %d)\n", end, len);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
while (max-- && *end)
|
2005-09-09 03:23:31 +00:00
|
|
|
*cPtr++ = *end++;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
*cPtr = 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
/******** GET USERID **********/
|
2005-09-16 23:48:51 +00:00
|
|
|
if (len <= 0)
|
|
|
|
{
|
2006-04-13 16:29:01 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "No Userid found");
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
end = text + --len;
|
|
|
|
*end = 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
while (*end != '<' && len--)
|
2005-09-09 03:23:31 +00:00
|
|
|
--end;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
// print_srvconsole("Got userid: %s (Len %d)\n", end + 1, len);
|
|
|
|
if (*(cPtr = get_amxaddr(amx, params[4])) != -2)
|
|
|
|
*cPtr = atoi(end + 1);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
/******** GET NAME **********/
|
|
|
|
*end = 0;
|
2005-09-16 23:48:51 +00:00
|
|
|
cPtr = get_amxaddr(amx, params[2]);
|
2005-09-09 03:23:31 +00:00
|
|
|
max = params[3]; // get NAME
|
2005-09-16 23:48:51 +00:00
|
|
|
// print_srvconsole("Got name: %s (Len %d)\n", text, len);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
while (max-- && *text)
|
2005-09-09 03:23:31 +00:00
|
|
|
*cPtr++ = *text++;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
*cPtr = 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
2015-12-24 17:25:52 +00:00
|
|
|
// native register_logevent(const function[], argsnum, ...);
|
2004-03-24 01:35:44 +00:00
|
|
|
static cell AMX_NATIVE_CALL register_logevent(AMX *amx, cell *params)
|
|
|
|
{
|
2015-12-24 17:25:52 +00:00
|
|
|
int length;
|
|
|
|
auto callback = get_amxstring(amx, params[1], 0, length);
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2015-12-24 17:25:52 +00:00
|
|
|
auto forwardId = registerSPForwardByName(amx, callback, FP_DONE);
|
|
|
|
|
|
|
|
if (forwardId == -1)
|
2005-09-09 03:23:31 +00:00
|
|
|
{
|
2015-12-24 17:25:52 +00:00
|
|
|
LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", callback);
|
2005-09-09 03:23:31 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2015-12-24 17:25:52 +00:00
|
|
|
auto handle = g_logevents.registerLogEvent(g_plugins.findPluginFast(amx), forwardId, params[2]);
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2015-12-24 17:25:52 +00:00
|
|
|
if (!handle)
|
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
return 0;
|
2015-12-24 17:25:52 +00:00
|
|
|
}
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2015-12-24 17:25:52 +00:00
|
|
|
auto logevent = LogEventHandles.lookup(handle)->m_logevent;
|
|
|
|
auto numparam = *params / sizeof(cell);
|
|
|
|
|
2017-04-04 08:32:04 +00:00
|
|
|
for (auto i = 3U; i <= numparam; ++i)
|
2015-12-24 17:25:52 +00:00
|
|
|
{
|
|
|
|
logevent->registerFilter(get_amxstring(amx, params[i], 0, length));
|
|
|
|
}
|
|
|
|
|
|
|
|
return handle;
|
|
|
|
}
|
|
|
|
|
|
|
|
// native enable_logevent(handle);
|
|
|
|
static cell AMX_NATIVE_CALL enable_logevent(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
auto handle = LogEventHandles.lookup(params[1]);
|
|
|
|
|
|
|
|
if (!handle)
|
|
|
|
{
|
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid log event handle %d", params[1]);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
handle->m_logevent->setForwardState(FSTATE_ACTIVE);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// native disable_logevent(handle);
|
|
|
|
static cell AMX_NATIVE_CALL disable_logevent(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
auto handle = LogEventHandles.lookup(params[1]);
|
|
|
|
|
|
|
|
if (!handle)
|
|
|
|
{
|
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid log event handle: %d", params[1]);
|
|
|
|
return 0;
|
|
|
|
}
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2015-12-24 17:25:52 +00:00
|
|
|
handle->m_logevent->setForwardState(FSTATE_STOP);
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
return 1;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// native is_module_loaded(const name[]);
|
|
|
|
static cell AMX_NATIVE_CALL is_module_loaded(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
// param1: name
|
|
|
|
int len;
|
|
|
|
char *name = get_amxstring(amx, params[1], 0, len);
|
|
|
|
int id = 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2017-04-14 17:36:59 +00:00
|
|
|
for (auto module : g_modules)
|
2004-03-24 01:35:44 +00:00
|
|
|
{
|
2017-04-14 17:36:59 +00:00
|
|
|
if (!stricmp(module->getName(), name))
|
2004-03-24 01:35:44 +00:00
|
|
|
return id;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2004-03-24 01:35:44 +00:00
|
|
|
++id;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2004-03-24 01:35:44 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// native is_plugin_loaded(const name[]);
|
2007-07-25 18:54:32 +00:00
|
|
|
// 1.8 changed to: is_plugin_loaded(const name[], bool:usefilename=false);
|
2004-03-24 01:35:44 +00:00
|
|
|
static cell AMX_NATIVE_CALL is_plugin_loaded(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
// param1: name
|
|
|
|
int len;
|
|
|
|
char *name = get_amxstring(amx, params[1], 0, len);
|
|
|
|
int id = 0;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2007-07-25 18:54:32 +00:00
|
|
|
if (params[0] / sizeof(cell) == 1 || // compiled pre-1.8 - assume plugin's registered name
|
|
|
|
params[2] == 0) // compiled post 1.8 - wants plugin's registered name
|
2004-03-24 01:35:44 +00:00
|
|
|
{
|
2007-07-25 18:54:32 +00:00
|
|
|
// searching for registered plugin name
|
|
|
|
for (CPluginMngr::iterator iter = g_plugins.begin(); iter; ++iter)
|
|
|
|
{
|
|
|
|
if (stricmp((*iter).getTitle(), name) == 0)
|
|
|
|
return id;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2007-07-25 18:54:32 +00:00
|
|
|
++id;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// searching for filename
|
|
|
|
// filename search is case sensitive
|
|
|
|
for (CPluginMngr::iterator iter = g_plugins.begin(); iter; ++iter)
|
|
|
|
{
|
|
|
|
if (strcmp((*iter).getName(), name) == 0)
|
|
|
|
return id;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2007-07-25 18:54:32 +00:00
|
|
|
++id;
|
|
|
|
}
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2004-03-24 01:35:44 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-03-24 01:35:44 +00:00
|
|
|
// native get_modulesnum();
|
|
|
|
static cell AMX_NATIVE_CALL get_modulesnum(AMX *amx, cell *params)
|
|
|
|
{
|
2004-03-27 17:06:08 +00:00
|
|
|
return (cell)countModules(CountModules_All);
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// native get_module(id, name[], nameLen, author[], authorLen, version[], versionLen, &status);
|
|
|
|
static cell AMX_NATIVE_CALL get_module(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
// find the module
|
|
|
|
int i = params[1];
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2017-04-14 17:36:59 +00:00
|
|
|
for (auto module : g_modules)
|
2017-03-11 18:26:25 +00:00
|
|
|
{
|
2017-04-14 17:36:59 +00:00
|
|
|
if (i--)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2017-04-14 17:36:59 +00:00
|
|
|
// set name, author, version
|
2017-12-07 17:45:16 +00:00
|
|
|
const amxx_module_info_s *info = module->getInfoNew();
|
|
|
|
const char *name = info && info->name ? info->name : "unk";
|
|
|
|
const char *author = info && info->author ? info->author : "unk";
|
|
|
|
const char *version = info && info->version ? info->version : "unk";
|
|
|
|
|
|
|
|
set_amxstring_utf8(amx, params[2], name, strlen(name), params[3]);
|
|
|
|
set_amxstring_utf8(amx, params[4], author, strlen(author), params[5]);
|
|
|
|
set_amxstring_utf8(amx, params[6], version, strlen(version), params[7]);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2017-04-14 17:36:59 +00:00
|
|
|
// compatibility problem possible
|
|
|
|
int numParams = params[0] / sizeof(cell);
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2017-04-14 17:36:59 +00:00
|
|
|
if (numParams < 8)
|
|
|
|
{
|
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Call to incompatible version");
|
|
|
|
return 0;
|
|
|
|
}
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2017-04-14 17:36:59 +00:00
|
|
|
// set status
|
|
|
|
cell *addr;
|
|
|
|
if (amx_GetAddr(amx, params[8], &addr) != AMX_ERR_NONE)
|
|
|
|
{
|
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid reference plugin");
|
|
|
|
return 0;
|
|
|
|
}
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2017-04-14 17:36:59 +00:00
|
|
|
*addr = (cell)module->getStatusValue();
|
|
|
|
return params[1];
|
|
|
|
}
|
|
|
|
return -1;
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// native log_amx(const msg[], ...);
|
|
|
|
static cell AMX_NATIVE_CALL log_amx(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
CPluginMngr::CPlugin *plugin = g_plugins.findPluginFast(amx);
|
|
|
|
int len;
|
|
|
|
|
2004-07-28 18:33:20 +00:00
|
|
|
g_langMngr.SetDefLang(LANG_SERVER);
|
2004-03-27 17:06:08 +00:00
|
|
|
AMXXLOG_Log("[%s] %s", plugin->getName(), format_amxstring(amx, params, 1, len));
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2004-03-24 01:35:44 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************/
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-03-24 01:35:44 +00:00
|
|
|
CPluginMngr::CPlugin *g_CallFunc_Plugin = NULL; // The plugin
|
|
|
|
int g_CallFunc_Func = 0; // The func
|
|
|
|
|
|
|
|
struct CallFunc_ParamInfo
|
|
|
|
{
|
|
|
|
unsigned char flags; // flags
|
|
|
|
cell byrefAddr; // byref address in caller plugin
|
|
|
|
cell size; // byref size
|
2006-08-18 05:52:21 +00:00
|
|
|
cell *alloc; // allocated block
|
2006-09-10 02:30:10 +00:00
|
|
|
bool copyback; // copy back?
|
2004-03-24 01:35:44 +00:00
|
|
|
};
|
|
|
|
|
2006-02-01 12:08:42 +00:00
|
|
|
#if !defined CALLFUNC_MAXPARAMS
|
2004-03-24 01:35:44 +00:00
|
|
|
#define CALLFUNC_MAXPARAMS 64 /* Maximal params number */
|
2006-02-01 12:08:42 +00:00
|
|
|
#endif
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-03-24 01:35:44 +00:00
|
|
|
cell g_CallFunc_Params[CALLFUNC_MAXPARAMS] = {0}; // Params
|
2004-04-01 05:53:22 +00:00
|
|
|
CallFunc_ParamInfo g_CallFunc_ParamInfo[CALLFUNC_MAXPARAMS] = {{0}}; // Flags
|
2004-03-24 01:35:44 +00:00
|
|
|
int g_CallFunc_CurParam = 0; // Current param id
|
|
|
|
|
|
|
|
#define CALLFUNC_FLAG_BYREF 1 /* Byref flag so that mem is released */
|
|
|
|
#define CALLFUNC_FLAG_BYREF_REUSED 2 /* Reused byref */
|
|
|
|
|
|
|
|
// native callfunc_begin(const func[], const plugin[]="");
|
|
|
|
static cell AMX_NATIVE_CALL callfunc_begin(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
CPluginMngr::CPlugin *curPlugin = g_plugins.findPluginFast(amx);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2004-03-24 01:35:44 +00:00
|
|
|
if (g_CallFunc_Plugin)
|
|
|
|
{
|
|
|
|
// scripter's fault
|
2005-07-25 06:03:43 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "callfunc_begin called without callfunc_end");
|
2004-03-24 01:35:44 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int len;
|
|
|
|
char *pluginStr = get_amxstring(amx, params[2], 0, len);
|
|
|
|
char *funcStr = get_amxstring(amx, params[1], 1, len);
|
|
|
|
CPluginMngr::CPlugin *plugin = NULL;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2004-03-24 01:35:44 +00:00
|
|
|
if (!pluginStr || !*pluginStr)
|
|
|
|
plugin = curPlugin;
|
|
|
|
else
|
|
|
|
plugin = g_plugins.findPlugin(pluginStr);
|
|
|
|
|
|
|
|
if (!plugin)
|
|
|
|
{
|
|
|
|
return -1; // plugin not found: -1
|
|
|
|
}
|
|
|
|
|
|
|
|
int func;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2004-03-24 01:35:44 +00:00
|
|
|
if (amx_FindPublic(plugin->getAMX(), funcStr, &func) != AMX_ERR_NONE)
|
|
|
|
{
|
|
|
|
return -2; // func not found: -2
|
|
|
|
}
|
|
|
|
|
|
|
|
// set globals
|
|
|
|
g_CallFunc_Plugin = plugin;
|
|
|
|
g_CallFunc_Func = func;
|
2006-03-30 20:45:22 +00:00
|
|
|
g_CallFunc_CurParam = 0;
|
2004-03-24 01:35:44 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
return 1; // success: 1
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
2004-10-29 19:50:38 +00:00
|
|
|
// native callfunc_begin_i(funcId, pluginId = -1)
|
|
|
|
static cell AMX_NATIVE_CALL callfunc_begin_i(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
CPluginMngr::CPlugin *plugin;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2004-10-29 19:50:38 +00:00
|
|
|
if (params[2] < 0)
|
|
|
|
plugin = g_plugins.findPluginFast(amx);
|
|
|
|
else
|
|
|
|
plugin = g_plugins.findPlugin(params[2]);
|
|
|
|
|
|
|
|
if (!plugin)
|
|
|
|
return -1;
|
2005-09-09 03:23:31 +00:00
|
|
|
|
2006-03-30 20:42:11 +00:00
|
|
|
if (g_CallFunc_Plugin)
|
|
|
|
{
|
|
|
|
// scripter's fault
|
|
|
|
LogError(amx, AMX_ERR_NATIVE, "callfunc_begin called without callfunc_end");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-09-27 19:51:23 +00:00
|
|
|
if (params[1] < 0)
|
|
|
|
{
|
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Public function %d is invalid", params[1]);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2004-10-29 19:50:38 +00:00
|
|
|
if (!plugin->isExecutable(params[1]))
|
|
|
|
return -2;
|
2005-09-09 03:23:31 +00:00
|
|
|
|
2004-10-29 19:50:38 +00:00
|
|
|
g_CallFunc_Plugin = plugin;
|
|
|
|
g_CallFunc_Func = params[1];
|
2006-03-30 20:45:22 +00:00
|
|
|
g_CallFunc_CurParam = 0;
|
2004-10-29 19:50:38 +00:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// native get_func_id(funcName[], pluginId = -1)
|
|
|
|
static cell AMX_NATIVE_CALL get_func_id(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
CPluginMngr::CPlugin *plugin;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2004-10-29 19:50:38 +00:00
|
|
|
if (params[2] < 0)
|
2006-10-02 06:12:02 +00:00
|
|
|
{
|
2004-10-29 19:50:38 +00:00
|
|
|
plugin = g_plugins.findPluginFast(amx);
|
2006-10-02 06:12:02 +00:00
|
|
|
} else {
|
2004-10-29 19:50:38 +00:00
|
|
|
plugin = g_plugins.findPlugin(params[2]);
|
2006-10-02 06:12:02 +00:00
|
|
|
}
|
2004-10-29 19:50:38 +00:00
|
|
|
|
|
|
|
if (!plugin)
|
2006-10-02 06:12:02 +00:00
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!plugin->isValid())
|
|
|
|
{
|
2004-10-29 19:50:38 +00:00
|
|
|
return -1;
|
2006-10-02 06:12:02 +00:00
|
|
|
}
|
2005-09-09 03:23:31 +00:00
|
|
|
|
2004-10-29 19:50:38 +00:00
|
|
|
int len;
|
|
|
|
const char *funcName = get_amxstring(amx, params[1], 0, len);
|
2005-07-08 05:05:06 +00:00
|
|
|
int index, err;
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
if ((err = amx_FindPublic(plugin->getAMX(), funcName, &index)) != AMX_ERR_NONE)
|
2006-10-02 06:12:02 +00:00
|
|
|
{
|
2004-10-29 19:50:38 +00:00
|
|
|
index = -1;
|
2006-10-02 06:12:02 +00:00
|
|
|
}
|
2004-10-29 19:50:38 +00:00
|
|
|
|
|
|
|
return index;
|
|
|
|
}
|
|
|
|
|
2004-03-24 01:35:44 +00:00
|
|
|
// native callfunc_end();
|
|
|
|
static cell AMX_NATIVE_CALL callfunc_end(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
CPluginMngr::CPlugin *curPlugin = g_plugins.findPluginFast(amx);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2004-03-24 01:35:44 +00:00
|
|
|
if (!g_CallFunc_Plugin)
|
|
|
|
{
|
|
|
|
// scripter's fault
|
2005-07-25 06:03:43 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "callfunc_end called without callfunc_begin");
|
2004-03-24 01:35:44 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// call the func
|
|
|
|
cell retVal;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
// copy the globs so the called func can also use callfunc
|
|
|
|
cell gparams[CALLFUNC_MAXPARAMS];
|
|
|
|
CallFunc_ParamInfo gparamInfo[CALLFUNC_MAXPARAMS];
|
|
|
|
|
|
|
|
CPluginMngr::CPlugin *plugin = g_CallFunc_Plugin;
|
|
|
|
int func = g_CallFunc_Func;
|
|
|
|
int curParam = g_CallFunc_CurParam;
|
|
|
|
|
|
|
|
memcpy(gparams, g_CallFunc_Params, sizeof(cell) * curParam);
|
|
|
|
memcpy(gparamInfo, g_CallFunc_ParamInfo, sizeof(CallFunc_ParamInfo) * curParam);
|
|
|
|
|
|
|
|
// cleanup
|
|
|
|
g_CallFunc_Plugin = NULL;
|
|
|
|
g_CallFunc_CurParam = 0;
|
|
|
|
|
2005-07-29 06:12:23 +00:00
|
|
|
AMX *pAmx = plugin->getAMX();
|
|
|
|
|
2005-10-13 05:27:13 +00:00
|
|
|
Debugger *pDebugger = (Debugger *)pAmx->userdata[UD_DEBUGGER];
|
|
|
|
|
|
|
|
if (pDebugger)
|
2006-08-18 05:52:21 +00:00
|
|
|
{
|
2005-10-13 05:27:13 +00:00
|
|
|
pDebugger->BeginExec();
|
2006-08-18 05:52:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// first pass over byref things
|
|
|
|
for (int i = curParam - 1; i >= 0; i--)
|
|
|
|
{
|
|
|
|
if (gparamInfo[i].flags & CALLFUNC_FLAG_BYREF)
|
|
|
|
{
|
|
|
|
cell amx_addr, *phys_addr;
|
|
|
|
amx_Allot(pAmx, gparamInfo[i].size, &amx_addr, &phys_addr);
|
|
|
|
memcpy(phys_addr, gparamInfo[i].alloc, gparamInfo[i].size * sizeof(cell));
|
|
|
|
gparams[i] = amx_addr;
|
|
|
|
delete [] gparamInfo[i].alloc;
|
|
|
|
gparamInfo[i].alloc = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// second pass, link in reused byrefs
|
|
|
|
for (int i = curParam - 1; i >= 0; i--)
|
|
|
|
{
|
|
|
|
if (gparamInfo[i].flags & CALLFUNC_FLAG_BYREF_REUSED)
|
|
|
|
{
|
|
|
|
gparams[i] = gparams[gparams[i]];
|
|
|
|
}
|
|
|
|
}
|
2005-10-13 05:27:13 +00:00
|
|
|
|
2004-03-24 01:35:44 +00:00
|
|
|
// actual call
|
2005-07-25 06:03:43 +00:00
|
|
|
// Pawn - push parameters in reverse order
|
2005-09-16 23:48:51 +00:00
|
|
|
for (int i = curParam - 1; i >= 0; i--)
|
2005-07-25 06:03:43 +00:00
|
|
|
{
|
2005-07-29 06:12:23 +00:00
|
|
|
amx_Push(pAmx, gparams[i]);
|
2005-07-25 06:03:43 +00:00
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-26 22:11:44 +00:00
|
|
|
err = amx_Exec(pAmx, &retVal, func);
|
|
|
|
|
|
|
|
if (err != AMX_ERR_NONE)
|
2004-03-24 01:35:44 +00:00
|
|
|
{
|
2005-09-26 22:11:44 +00:00
|
|
|
if (pDebugger && pDebugger->ErrorExists())
|
|
|
|
{
|
|
|
|
//already handled
|
|
|
|
} else {
|
|
|
|
LogError(amx, err, NULL);
|
|
|
|
}
|
2004-03-24 01:35:44 +00:00
|
|
|
}
|
|
|
|
|
2005-09-26 22:11:44 +00:00
|
|
|
if (pDebugger)
|
2006-08-18 05:52:21 +00:00
|
|
|
{
|
2005-09-26 22:11:44 +00:00
|
|
|
pDebugger->EndExec();
|
2006-08-18 05:52:21 +00:00
|
|
|
}
|
2005-09-26 22:11:44 +00:00
|
|
|
|
2004-03-24 01:35:44 +00:00
|
|
|
// process byref params (not byref_reused)
|
|
|
|
for (int i = 0; i < curParam; ++i)
|
|
|
|
{
|
|
|
|
if (gparamInfo[i].flags & CALLFUNC_FLAG_BYREF)
|
|
|
|
{
|
|
|
|
// copy back so that references work
|
|
|
|
AMX *amxCalled = plugin->getAMX();
|
2006-09-10 02:30:10 +00:00
|
|
|
|
|
|
|
if (gparamInfo[i].copyback)
|
|
|
|
{
|
|
|
|
AMX *amxCaller = curPlugin->getAMX();
|
|
|
|
AMX_HEADER *hdrCaller = (AMX_HEADER *)amxCaller->base;
|
|
|
|
AMX_HEADER *hdrCalled = (AMX_HEADER *)amxCalled->base;
|
|
|
|
memcpy( /** DEST ADDR **/
|
2017-03-11 18:26:25 +00:00
|
|
|
(amxCaller->data ? amxCaller->data : (amxCaller->base + hdrCaller->dat)) + gparamInfo[i].byrefAddr,
|
2006-09-10 02:30:10 +00:00
|
|
|
/** SOURCE ADDR **/
|
2017-03-11 18:26:25 +00:00
|
|
|
(amxCalled->data ? amxCalled->data : (amxCalled->base + hdrCalled->dat)) + gparams[i],
|
2006-09-10 02:30:10 +00:00
|
|
|
/** SIZE **/
|
|
|
|
gparamInfo[i].size * sizeof(cell));
|
|
|
|
}
|
2004-03-24 01:35:44 +00:00
|
|
|
|
|
|
|
// free memory used for params passed by reference
|
|
|
|
amx_Release(amxCalled, gparams[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return retVal;
|
|
|
|
}
|
|
|
|
|
|
|
|
// native callfunc_push_int(value);
|
|
|
|
// native callfunc_push_float(Float: value);
|
2004-09-09 06:04:50 +00:00
|
|
|
static cell AMX_NATIVE_CALL callfunc_push_byval(AMX *amx, cell *params)
|
2004-03-24 01:35:44 +00:00
|
|
|
{
|
|
|
|
if (!g_CallFunc_Plugin)
|
|
|
|
{
|
|
|
|
// scripter's fault
|
2005-07-25 06:03:43 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "callfunc_push_xxx called without callfunc_begin");
|
2004-03-24 01:35:44 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (g_CallFunc_CurParam == CALLFUNC_MAXPARAMS)
|
|
|
|
{
|
2006-04-13 16:29:01 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Callfunc_push_xxx: maximal parameters num: %d", CALLFUNC_MAXPARAMS);
|
2004-03-24 01:35:44 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].flags = 0;
|
|
|
|
g_CallFunc_Params[g_CallFunc_CurParam++] = params[1];
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// native callfunc_push_intref(&value);
|
|
|
|
// native callfunc_push_floatref(Float: &value);
|
2004-09-09 06:04:50 +00:00
|
|
|
static cell AMX_NATIVE_CALL callfunc_push_byref(AMX *amx, cell *params)
|
2004-03-24 01:35:44 +00:00
|
|
|
{
|
|
|
|
CPluginMngr::CPlugin *curPlugin = g_plugins.findPluginFast(amx);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2004-03-24 01:35:44 +00:00
|
|
|
if (!g_CallFunc_Plugin)
|
|
|
|
{
|
|
|
|
// scripter's fault
|
2005-07-25 06:03:43 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "callfunc_push_xxx called without callfunc_begin");
|
2004-03-24 01:35:44 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (g_CallFunc_CurParam == CALLFUNC_MAXPARAMS)
|
|
|
|
{
|
2005-07-25 06:03:43 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "callfunc_push_xxx: maximal parameters num: %d", CALLFUNC_MAXPARAMS);
|
2004-03-24 01:35:44 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// search for the address; if it is found, dont create a new copy
|
|
|
|
for (int i = 0; i < g_CallFunc_CurParam; ++i)
|
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
if ((g_CallFunc_ParamInfo[i].flags & CALLFUNC_FLAG_BYREF) && (g_CallFunc_ParamInfo[i].byrefAddr == params[1]))
|
2004-03-24 01:35:44 +00:00
|
|
|
{
|
|
|
|
// the byrefAddr and size params should not be used; set them anyways...
|
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].flags = CALLFUNC_FLAG_BYREF_REUSED;
|
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].byrefAddr = params[1];
|
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].size = 1;
|
2006-08-18 05:52:21 +00:00
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].alloc = NULL;
|
2006-09-10 02:30:10 +00:00
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].copyback = true;
|
2006-08-18 05:52:21 +00:00
|
|
|
g_CallFunc_Params[g_CallFunc_CurParam++] = i; /* referenced parameter */
|
2004-03-24 01:35:44 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-08-18 05:52:21 +00:00
|
|
|
cell *phys_addr = new cell[1];
|
2004-03-24 01:35:44 +00:00
|
|
|
|
|
|
|
// copy the value to the allocated memory
|
|
|
|
cell *phys_addr2;
|
|
|
|
amx_GetAddr(curPlugin->getAMX(), params[1], &phys_addr2);
|
|
|
|
*phys_addr = *phys_addr2;
|
|
|
|
|
|
|
|
// push the address and set the reference flag so that memory is released after function call.
|
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].flags = CALLFUNC_FLAG_BYREF;
|
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].byrefAddr = params[1];
|
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].size = 1;
|
2006-08-18 05:52:21 +00:00
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].alloc = phys_addr;
|
2006-09-10 02:30:10 +00:00
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].copyback = true;
|
2006-08-18 05:52:21 +00:00
|
|
|
g_CallFunc_Params[g_CallFunc_CurParam++] = 0;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-09-10 02:30:10 +00:00
|
|
|
// native callfunc_push_array(array[], size, [copyback])
|
2006-08-18 05:52:21 +00:00
|
|
|
static cell AMX_NATIVE_CALL callfunc_push_array(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
if (!g_CallFunc_Plugin)
|
|
|
|
{
|
|
|
|
// scripter's fault
|
|
|
|
LogError(amx, AMX_ERR_NATIVE, "callfunc_push_xxx called without callfunc_begin");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (g_CallFunc_CurParam == CALLFUNC_MAXPARAMS)
|
|
|
|
{
|
|
|
|
LogError(amx, AMX_ERR_NATIVE, "callfunc_push_xxx: maximal parameters num: %d", CALLFUNC_MAXPARAMS);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// search for the address; if it is found, dont create a new copy
|
|
|
|
for (int i = 0; i < g_CallFunc_CurParam; ++i)
|
|
|
|
{
|
|
|
|
if ((g_CallFunc_ParamInfo[i].flags & CALLFUNC_FLAG_BYREF) && (g_CallFunc_ParamInfo[i].byrefAddr == params[1]))
|
|
|
|
{
|
|
|
|
// the byrefAddr and size params should not be used; set them anyways...
|
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].flags = CALLFUNC_FLAG_BYREF_REUSED;
|
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].byrefAddr = params[1];
|
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].size = 1;
|
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].alloc = NULL;
|
2006-09-10 02:30:10 +00:00
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].copyback = g_CallFunc_ParamInfo[i].copyback;
|
2006-08-18 05:52:21 +00:00
|
|
|
g_CallFunc_Params[g_CallFunc_CurParam++] = i; /* referenced parameter */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// not found; create an own copy
|
|
|
|
// get the string and its length
|
|
|
|
cell *pArray = get_amxaddr(amx, params[1]);
|
|
|
|
cell array_size = params[2];
|
|
|
|
|
|
|
|
// allocate enough memory for the array
|
|
|
|
cell *phys_addr = new cell[array_size];
|
|
|
|
|
|
|
|
memcpy(phys_addr, pArray, array_size * sizeof(cell));
|
|
|
|
|
|
|
|
// push the address and set the reference flag so that memory is released after function call.
|
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].flags = CALLFUNC_FLAG_BYREF;
|
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].byrefAddr = params[1];
|
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].size = array_size;
|
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].alloc = phys_addr;
|
2006-09-10 02:30:10 +00:00
|
|
|
|
|
|
|
if (params[0] / sizeof(cell) >= 3)
|
|
|
|
{
|
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].copyback = params[3] ? true : false;
|
|
|
|
} else {
|
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].copyback = true;
|
|
|
|
}
|
|
|
|
|
2006-08-18 05:52:21 +00:00
|
|
|
g_CallFunc_Params[g_CallFunc_CurParam++] = 0;
|
2004-03-24 01:35:44 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// native callfunc_push_str(value[]);
|
2004-09-09 06:04:50 +00:00
|
|
|
static cell AMX_NATIVE_CALL callfunc_push_str(AMX *amx, cell *params)
|
2004-03-24 01:35:44 +00:00
|
|
|
{
|
|
|
|
if (!g_CallFunc_Plugin)
|
|
|
|
{
|
|
|
|
// scripter's fault
|
2005-07-25 06:03:43 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "callfunc_push_xxx called without callfunc_begin");
|
2004-03-24 01:35:44 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (g_CallFunc_CurParam == CALLFUNC_MAXPARAMS)
|
|
|
|
{
|
2005-07-25 06:03:43 +00:00
|
|
|
LogError(amx, AMX_ERR_NATIVE, "callfunc_push_xxx: maximal parameters num: %d", CALLFUNC_MAXPARAMS);
|
2004-03-24 01:35:44 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// search for the address; if it is found, dont create a new copy
|
|
|
|
for (int i = 0; i < g_CallFunc_CurParam; ++i)
|
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
if ((g_CallFunc_ParamInfo[i].flags & CALLFUNC_FLAG_BYREF) && (g_CallFunc_ParamInfo[i].byrefAddr == params[1]))
|
2004-03-24 01:35:44 +00:00
|
|
|
{
|
|
|
|
// the byrefAddr and size params should not be used; set them anyways...
|
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].flags = CALLFUNC_FLAG_BYREF_REUSED;
|
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].byrefAddr = params[1];
|
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].size = 1;
|
2006-08-18 05:52:21 +00:00
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].alloc = NULL;
|
2006-09-10 02:30:10 +00:00
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].copyback = g_CallFunc_ParamInfo[i].copyback;
|
2006-08-18 05:52:21 +00:00
|
|
|
g_CallFunc_Params[g_CallFunc_CurParam++] = i;
|
2004-03-24 01:35:44 +00:00
|
|
|
// we are done
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// not found; create an own copy
|
|
|
|
// get the string and its length
|
|
|
|
int len;
|
|
|
|
char *str = get_amxstring(amx, params[1], 0, len);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2004-03-24 01:35:44 +00:00
|
|
|
// allocate enough memory for the string
|
2006-08-18 05:52:21 +00:00
|
|
|
cell *phys_addr = new cell[len+1];
|
2004-03-24 01:35:44 +00:00
|
|
|
|
|
|
|
// copy it to the allocated memory
|
|
|
|
// we assume it's unpacked
|
2004-03-27 17:06:08 +00:00
|
|
|
// :NOTE: 4th parameter use_wchar since Small Abstract Machine 2.5.0
|
2014-05-27 13:15:56 +00:00
|
|
|
amx_SetStringOld(phys_addr, str, 0, 0);
|
2004-03-24 01:35:44 +00:00
|
|
|
|
|
|
|
// push the address and set the reference flag so that memory is released after function call.
|
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].flags = CALLFUNC_FLAG_BYREF;
|
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].byrefAddr = params[1];
|
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].size = len + 1;
|
2006-08-18 05:52:21 +00:00
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].alloc = phys_addr;
|
2006-09-10 02:30:10 +00:00
|
|
|
|
|
|
|
if (params[0] / sizeof(cell) >= 3)
|
|
|
|
{
|
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].copyback = params[3] ? true : false;
|
|
|
|
} else {
|
|
|
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].copyback = true;
|
|
|
|
}
|
|
|
|
|
2006-08-18 05:52:21 +00:00
|
|
|
g_CallFunc_Params[g_CallFunc_CurParam++] = 0;
|
2004-03-24 01:35:44 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2004-07-28 18:33:20 +00:00
|
|
|
// get_langsnum();
|
2004-09-09 06:04:50 +00:00
|
|
|
static cell AMX_NATIVE_CALL get_langsnum(AMX *amx, cell *params)
|
2004-07-28 18:33:20 +00:00
|
|
|
{
|
|
|
|
return g_langMngr.GetLangsNum();
|
|
|
|
}
|
|
|
|
|
|
|
|
// get_lang(id, name[(at least 3)]);
|
2004-09-09 06:04:50 +00:00
|
|
|
static cell AMX_NATIVE_CALL get_lang(AMX *amx, cell *params)
|
2004-07-28 18:33:20 +00:00
|
|
|
{
|
|
|
|
set_amxstring(amx, params[2], g_langMngr.GetLangName(params[1]), 2);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// register_dictionary(const filename[]);
|
2004-09-09 06:04:50 +00:00
|
|
|
static cell AMX_NATIVE_CALL register_dictionary(AMX *amx, cell *params)
|
2004-07-28 18:33:20 +00:00
|
|
|
{
|
|
|
|
int len;
|
2017-03-11 18:26:25 +00:00
|
|
|
static char file[PLATFORM_MAX_PATH];
|
|
|
|
int result = g_langMngr.MergeDefinitionFile(build_pathname_r(file, sizeof(file), "%s/lang/%s", get_localinfo("amxx_datadir", "addons/amxmodx/data"), get_amxstring(amx, params[1], 1, len)));
|
|
|
|
|
2004-08-18 15:30:06 +00:00
|
|
|
return result;
|
2004-07-28 18:33:20 +00:00
|
|
|
}
|
|
|
|
|
2004-09-09 06:04:50 +00:00
|
|
|
static cell AMX_NATIVE_CALL plugin_flags(AMX *amx, cell *params)
|
2004-09-08 18:27:39 +00:00
|
|
|
{
|
2007-08-03 06:48:08 +00:00
|
|
|
if ((params[0] / sizeof(cell)) == 1 || // compiled with old include file
|
|
|
|
params[2] < 0) // specifically want calling plugin's flags
|
2005-07-29 19:25:24 +00:00
|
|
|
{
|
2007-08-03 06:48:08 +00:00
|
|
|
if (params[1])
|
|
|
|
{
|
|
|
|
AMX_HEADER *hdr;
|
|
|
|
hdr = (AMX_HEADER *)amx->base;
|
|
|
|
return hdr->flags;
|
|
|
|
}
|
|
|
|
|
|
|
|
return amx->flags;
|
2005-07-29 19:25:24 +00:00
|
|
|
}
|
2007-08-03 06:48:08 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
CPluginMngr::CPlugin* a = g_plugins.findPlugin((int)params[2]);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2007-08-03 06:48:08 +00:00
|
|
|
if (a == NULL)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (params[1])
|
|
|
|
{
|
|
|
|
AMX_HEADER *hdr;
|
|
|
|
hdr = (AMX_HEADER *)a->getAMX()->base;
|
|
|
|
return hdr->flags;
|
|
|
|
}
|
2005-07-29 19:25:24 +00:00
|
|
|
|
2007-08-03 06:48:08 +00:00
|
|
|
return a->getAMX()->flags;
|
|
|
|
}
|
2004-09-08 18:27:39 +00:00
|
|
|
}
|
|
|
|
|
2004-07-28 18:33:20 +00:00
|
|
|
// lang_exists(const name[]);
|
2004-09-09 06:04:50 +00:00
|
|
|
static cell AMX_NATIVE_CALL lang_exists(AMX *amx, cell *params)
|
2004-07-28 18:33:20 +00:00
|
|
|
{
|
2004-08-19 18:35:18 +00:00
|
|
|
int len = 0;
|
2004-07-28 18:33:20 +00:00
|
|
|
return g_langMngr.LangExists(get_amxstring(amx, params[1], 1, len)) ? 1 : 0;
|
|
|
|
}
|
|
|
|
|
2017-12-07 17:45:16 +00:00
|
|
|
static cell AMX_NATIVE_CALL require_module(AMX *amx, cell *params)
|
2004-09-09 05:16:53 +00:00
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2005-07-08 01:15:54 +00:00
|
|
|
static cell AMX_NATIVE_CALL find_plugin_byfile(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
typedef int (*STRCOMPARE)(const char*, const char*);
|
|
|
|
|
|
|
|
STRCOMPARE func;
|
|
|
|
|
|
|
|
if (params[2])
|
|
|
|
{
|
2005-07-27 16:24:14 +00:00
|
|
|
func = strcasecmp;
|
2005-07-08 01:15:54 +00:00
|
|
|
} else {
|
|
|
|
func = strcmp;
|
|
|
|
}
|
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
int len, i = 0;
|
2005-07-08 01:15:54 +00:00
|
|
|
char *file = get_amxstring(amx, params[1], 0, len);
|
|
|
|
|
|
|
|
for (CPluginMngr::iterator iter = g_plugins.begin(); iter; ++iter)
|
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
if ((func)((*iter).getName(), file) == 0)
|
2005-07-08 01:15:54 +00:00
|
|
|
return i;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2005-08-16 23:09:55 +00:00
|
|
|
static cell AMX_NATIVE_CALL int3(AMX *amx, cell *params)
|
|
|
|
{
|
2006-02-11 21:51:28 +00:00
|
|
|
#if defined _DEBUG || defined DEBUG
|
2005-08-16 23:09:55 +00:00
|
|
|
#if defined WIN32
|
|
|
|
__asm
|
|
|
|
{
|
|
|
|
int 3;
|
|
|
|
};
|
|
|
|
#else
|
|
|
|
asm("int $3");
|
|
|
|
#endif //WIN32
|
|
|
|
#endif //DEBUG
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-08-27 23:00:44 +00:00
|
|
|
/*********************************************************************/
|
|
|
|
|
2005-09-11 03:58:38 +00:00
|
|
|
static cell AMX_NATIVE_CALL amx_abort(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
int err = params[1];
|
|
|
|
|
|
|
|
int len;
|
|
|
|
char *fmt = format_amxstring(amx, params, 2, len);
|
|
|
|
|
|
|
|
if (fmt[0] == '\0')
|
|
|
|
fmt = NULL;
|
|
|
|
|
|
|
|
const char *filename = "";
|
|
|
|
CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(amx);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-09-11 03:58:38 +00:00
|
|
|
if (pPlugin)
|
|
|
|
filename = pPlugin->getName();
|
|
|
|
|
2006-03-30 20:42:11 +00:00
|
|
|
//we were in a callfunc?
|
|
|
|
if (g_CallFunc_Plugin == pPlugin)
|
|
|
|
g_CallFunc_Plugin = NULL;
|
|
|
|
|
2005-09-11 03:58:38 +00:00
|
|
|
if (fmt)
|
|
|
|
LogError(amx, err, "[%s] %s", filename, fmt);
|
|
|
|
else
|
|
|
|
LogError(amx, err, NULL);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2005-09-11 04:43:40 +00:00
|
|
|
static cell AMX_NATIVE_CALL module_exists(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
int len;
|
|
|
|
char *module = get_amxstring(amx, params[1], 0, len);
|
|
|
|
|
2006-05-07 09:56:06 +00:00
|
|
|
if (!FindLibrary(module, LibType_Library))
|
|
|
|
return FindLibrary(module, LibType_Class);
|
2005-09-11 04:43:40 +00:00
|
|
|
|
2006-05-07 09:56:06 +00:00
|
|
|
return true;
|
|
|
|
}
|
2005-09-11 04:43:40 +00:00
|
|
|
|
2006-05-07 09:56:06 +00:00
|
|
|
static cell AMX_NATIVE_CALL LibraryExists(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
int len;
|
|
|
|
char *library = get_amxstring(amx, params[1], 0, len);
|
2005-09-11 04:43:40 +00:00
|
|
|
|
2006-05-07 09:56:06 +00:00
|
|
|
return FindLibrary(library, static_cast<LibType>(params[2]));
|
2005-09-11 04:43:40 +00:00
|
|
|
}
|
|
|
|
|
2005-12-01 13:42:28 +00:00
|
|
|
static cell AMX_NATIVE_CALL set_fail_state(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
int len;
|
2013-07-27 18:33:17 +00:00
|
|
|
char* str;
|
|
|
|
|
2017-03-11 18:26:25 +00:00
|
|
|
g_langMngr.SetDefLang(LANG_SERVER); // Default language = server
|
2013-07-27 18:33:17 +00:00
|
|
|
|
|
|
|
if (params[0] / sizeof(cell) > 1)
|
|
|
|
str = format_amxstring(amx, params, 1, len);
|
|
|
|
else
|
|
|
|
str = get_amxstring(amx, params[1], 0, len);
|
2005-12-01 13:42:28 +00:00
|
|
|
|
|
|
|
CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(amx);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2005-12-01 13:42:28 +00:00
|
|
|
pPlugin->setStatus(ps_error);
|
|
|
|
pPlugin->setError(str);
|
|
|
|
|
2006-08-18 19:02:37 +00:00
|
|
|
AMXXLOG_Error("[AMXX] Plugin (\"%s\") is setting itself as failed.", pPlugin->getName());
|
|
|
|
AMXXLOG_Error("[AMXX] Plugin says: %s", str);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2006-08-18 19:02:37 +00:00
|
|
|
LogError(amx, AMX_ERR_EXIT, NULL);
|
|
|
|
|
2005-12-01 13:42:28 +00:00
|
|
|
//plugin dies once amx_Exec concludes
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-01-06 14:47:59 +00:00
|
|
|
static cell AMX_NATIVE_CALL get_var_addr(AMX *amx, cell *params)
|
2006-01-06 14:22:12 +00:00
|
|
|
{
|
|
|
|
if (params[0] / sizeof(cell) > 0)
|
|
|
|
{
|
|
|
|
return params[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-01-06 14:47:59 +00:00
|
|
|
static cell AMX_NATIVE_CALL get_addr_val(AMX *amx, cell *params)
|
2006-01-06 14:22:12 +00:00
|
|
|
{
|
|
|
|
cell *addr;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
if ( (err=amx_GetAddr(amx, params[1], &addr)) != AMX_ERR_NONE )
|
|
|
|
{
|
|
|
|
LogError(amx, err, "Bad reference %d supplied", params[1]);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return addr ? *addr : 0;
|
|
|
|
}
|
|
|
|
|
2006-01-06 14:47:59 +00:00
|
|
|
static cell AMX_NATIVE_CALL set_addr_val(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
cell *addr;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
if ( (err=amx_GetAddr(amx, params[1], &addr)) != AMX_ERR_NONE )
|
|
|
|
{
|
|
|
|
LogError(amx, err, "Bad reference %d supplied", params[1]);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (addr)
|
|
|
|
*addr = params[2];
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2006-02-01 12:08:42 +00:00
|
|
|
static cell AMX_NATIVE_CALL CreateMultiForward(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
int len;
|
|
|
|
char *funcname = get_amxstring(amx, params[1], 0, len);
|
|
|
|
|
|
|
|
cell ps[FORWARD_MAX_PARAMS];
|
|
|
|
cell count = params[0] / sizeof(cell);
|
|
|
|
for (cell i=3; i<=count; i++)
|
2006-09-10 00:51:35 +00:00
|
|
|
{
|
2006-02-01 12:08:42 +00:00
|
|
|
ps[i-3] = *get_amxaddr(amx, params[i]);
|
2006-09-10 00:51:35 +00:00
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2006-02-01 12:08:42 +00:00
|
|
|
return registerForwardC(funcname, static_cast<ForwardExecType>(params[2]), ps, count-2);
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL CreateOneForward(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
CPluginMngr::CPlugin *p = g_plugins.findPlugin(params[1]);
|
2006-09-10 00:51:35 +00:00
|
|
|
|
|
|
|
if (!p)
|
|
|
|
{
|
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid plugin id: %d", params[1]);
|
|
|
|
return -1;
|
|
|
|
} else if (!p->isExecutable(0)) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2006-02-01 12:08:42 +00:00
|
|
|
int len;
|
|
|
|
char *funcname = get_amxstring(amx, params[2], 0, len);
|
|
|
|
|
|
|
|
cell ps[FORWARD_MAX_PARAMS];
|
|
|
|
cell count = params[0] / sizeof(cell);
|
|
|
|
for (cell i=3; i<=count; i++)
|
2006-09-10 00:51:35 +00:00
|
|
|
{
|
2006-02-01 12:08:42 +00:00
|
|
|
ps[i-3] = *get_amxaddr(amx, params[i]);
|
2006-09-10 00:51:35 +00:00
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2006-06-11 08:58:15 +00:00
|
|
|
return registerSPForwardByNameC(p->getAMX(), funcname, ps, count-2);
|
2006-02-01 12:08:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL PrepareArray(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
cell *addr = get_amxaddr(amx, params[1]);
|
|
|
|
unsigned int len = static_cast<unsigned int>(params[2]);
|
|
|
|
bool copyback = params[3] ? true : false;
|
|
|
|
|
|
|
|
return prepareCellArray(addr, len, copyback);
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL ExecuteForward(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
int id = static_cast<int>(params[1]);
|
2006-07-18 04:39:54 +00:00
|
|
|
int len, err;
|
2006-03-10 19:04:04 +00:00
|
|
|
cell *addr = get_amxaddr(amx, params[2]);
|
2006-02-01 12:08:42 +00:00
|
|
|
|
|
|
|
if (!g_forwards.isIdValid(id))
|
|
|
|
return 0;
|
|
|
|
|
2006-07-18 04:39:54 +00:00
|
|
|
struct allot_info
|
|
|
|
{
|
|
|
|
cell amx_addr;
|
|
|
|
cell *phys_addr;
|
|
|
|
};
|
|
|
|
|
2006-02-01 12:08:42 +00:00
|
|
|
cell ps[FORWARD_MAX_PARAMS];
|
2006-07-18 04:39:54 +00:00
|
|
|
allot_info allots[FORWARD_MAX_PARAMS];
|
2006-02-01 12:08:42 +00:00
|
|
|
cell count = params[0] / sizeof(cell);
|
|
|
|
if (count - 2 != g_forwards.getParamsNum(id))
|
|
|
|
{
|
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Expected %d parameters, got %d", g_forwards.getParamsNum(id), count-2);
|
|
|
|
return 0;
|
|
|
|
}
|
2016-04-05 16:51:18 +00:00
|
|
|
|
|
|
|
ForwardParam param_type;
|
|
|
|
|
2006-02-01 12:08:42 +00:00
|
|
|
for (cell i=3; i<=count; i++)
|
|
|
|
{
|
2016-04-05 16:51:18 +00:00
|
|
|
param_type = g_forwards.getParamType(id, i-3);
|
|
|
|
if (param_type == FP_STRING)
|
2006-07-18 04:39:54 +00:00
|
|
|
{
|
|
|
|
char *tmp = get_amxstring(amx, params[i], 0, len);
|
|
|
|
cell num = len / sizeof(cell) + 1;
|
|
|
|
if ((err=amx_Allot(amx, num, &allots[i-3].amx_addr, &allots[i-3].phys_addr)) != AMX_ERR_NONE)
|
|
|
|
{
|
|
|
|
LogError(amx, err, NULL);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
strcpy((char *)allots[i-3].phys_addr, tmp);
|
|
|
|
ps[i-3] = (cell)allots[i-3].phys_addr;
|
2016-04-05 16:51:18 +00:00
|
|
|
}
|
|
|
|
else if (param_type == FP_CELL_BYREF)
|
|
|
|
{
|
|
|
|
cell *temp = get_amxaddr(amx, params[i]);
|
|
|
|
ps[i-3] = reinterpret_cast<cell>(temp);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-02-01 12:08:42 +00:00
|
|
|
ps[i-3] = *get_amxaddr(amx, params[i]);
|
2006-07-18 04:39:54 +00:00
|
|
|
}
|
2006-02-01 12:08:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
*addr = g_forwards.executeForwards(id, ps);
|
|
|
|
|
2006-07-18 04:39:54 +00:00
|
|
|
for (cell i=3; i<=count; i++)
|
|
|
|
{
|
|
|
|
if (g_forwards.getParamType(id, i-3) == FP_STRING)
|
|
|
|
{
|
|
|
|
amx_Release(amx, allots[i-3].amx_addr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-02-01 12:08:42 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL DestroyForward(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
int id = static_cast<int>(params[1]);
|
|
|
|
|
|
|
|
/* only implemented for single forwards */
|
|
|
|
if (g_forwards.isIdValid(id) && g_forwards.isSPForward(id))
|
|
|
|
g_forwards.unregisterSPForward(id);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-07-11 08:37:36 +00:00
|
|
|
ke::Vector<cell *> g_hudsync;
|
2006-02-28 09:43:20 +00:00
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL CreateHudSyncObj(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
cell *p = new cell[gpGlobals->maxClients+1];
|
2006-02-28 10:10:44 +00:00
|
|
|
memset(p, 0, sizeof(cell) * (gpGlobals->maxClients + 1));
|
2015-07-11 08:37:36 +00:00
|
|
|
g_hudsync.append(p);
|
2006-02-28 09:43:20 +00:00
|
|
|
|
2015-07-11 08:37:36 +00:00
|
|
|
return static_cast<cell>(g_hudsync.length());
|
2006-02-28 09:43:20 +00:00
|
|
|
}
|
|
|
|
|
2006-03-20 01:03:30 +00:00
|
|
|
void CheckAndClearPlayerHUD(CPlayer *player, int &channel, unsigned int sync_obj)
|
2006-02-28 09:43:20 +00:00
|
|
|
{
|
|
|
|
/**
|
|
|
|
* player and channel should be guaranteed to be good to go.
|
|
|
|
*/
|
|
|
|
//get the sync object's hud list
|
|
|
|
cell *plist = g_hudsync[sync_obj];
|
|
|
|
//get the last channel this message class was displayed on.
|
|
|
|
cell last_channel = plist[player->index];
|
|
|
|
//check if the last sync on this channel was this sync obj
|
2006-08-17 16:41:41 +00:00
|
|
|
if ((unsigned int)player->hudmap[last_channel] == sync_obj + 1)
|
2006-02-28 09:43:20 +00:00
|
|
|
{
|
2006-03-20 01:03:30 +00:00
|
|
|
//if so, we can safely REUSE it
|
|
|
|
channel = (int)last_channel;
|
2006-02-28 09:43:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//set the new states
|
|
|
|
plist[player->index] = channel;
|
2006-02-28 10:42:52 +00:00
|
|
|
player->hudmap[channel] = sync_obj + 1;
|
2006-02-28 09:43:20 +00:00
|
|
|
}
|
|
|
|
|
2006-03-01 02:20:44 +00:00
|
|
|
static cell AMX_NATIVE_CALL ClearSyncHud(AMX *amx, cell *params)
|
|
|
|
{
|
2006-03-20 01:03:30 +00:00
|
|
|
int len = 0;
|
2006-03-01 02:20:44 +00:00
|
|
|
int index = params[1];
|
|
|
|
unsigned int sync_obj = static_cast<unsigned int>(params[2]) - 1;
|
|
|
|
|
2015-07-11 08:37:36 +00:00
|
|
|
if (sync_obj >= g_hudsync.length())
|
2006-03-01 02:20:44 +00:00
|
|
|
{
|
|
|
|
LogError(amx, AMX_ERR_NATIVE, "HudSyncObject %d is invalid", sync_obj);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-03-20 01:03:30 +00:00
|
|
|
g_langMngr.SetDefLang(params[1]);
|
2006-03-01 02:20:44 +00:00
|
|
|
|
|
|
|
if (index == 0)
|
|
|
|
{
|
2006-03-20 01:03:30 +00:00
|
|
|
for (int i = 1; i <= gpGlobals->maxClients; ++i)
|
2006-03-01 02:20:44 +00:00
|
|
|
{
|
2006-03-20 01:03:30 +00:00
|
|
|
CPlayer *pPlayer = GET_PLAYER_POINTER_I(i);
|
2006-03-01 02:20:44 +00:00
|
|
|
|
2006-03-20 01:03:30 +00:00
|
|
|
int channel;
|
|
|
|
if (pPlayer->ingame)
|
|
|
|
{
|
|
|
|
g_langMngr.SetDefLang(i);
|
|
|
|
channel = pPlayer->NextHUDChannel();
|
|
|
|
CheckAndClearPlayerHUD(pPlayer, channel, sync_obj);
|
|
|
|
pPlayer->channels[channel] = gpGlobals->time;
|
|
|
|
g_hudset.channel = channel;
|
|
|
|
UTIL_HudMessage(pPlayer->pEdict, g_hudset, "");
|
|
|
|
}
|
2006-03-01 02:20:44 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
|
|
|
{
|
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index);
|
|
|
|
return 0;
|
|
|
|
}
|
2006-03-20 01:03:30 +00:00
|
|
|
|
2006-03-01 02:20:44 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2006-03-20 01:03:30 +00:00
|
|
|
|
2006-03-01 02:20:44 +00:00
|
|
|
if (pPlayer->ingame)
|
|
|
|
{
|
2006-03-20 01:03:30 +00:00
|
|
|
int channel = pPlayer->NextHUDChannel();
|
|
|
|
CheckAndClearPlayerHUD(pPlayer, channel, sync_obj);
|
|
|
|
pPlayer->channels[channel] = gpGlobals->time;
|
|
|
|
g_hudset.channel = channel;
|
|
|
|
UTIL_HudMessage(pPlayer->pEdict, g_hudset, "");
|
2006-03-01 02:20:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-03-20 01:03:30 +00:00
|
|
|
return len;
|
2006-03-01 02:20:44 +00:00
|
|
|
}
|
|
|
|
|
2006-02-28 09:43:20 +00:00
|
|
|
//params[1] - target
|
|
|
|
//params[2] - HudSyncObj
|
|
|
|
//params[3] - hud message
|
|
|
|
static cell AMX_NATIVE_CALL ShowSyncHudMsg(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
int len = 0;
|
|
|
|
char* message = NULL;
|
|
|
|
int index = params[1];
|
2006-03-01 00:10:23 +00:00
|
|
|
unsigned int sync_obj = static_cast<unsigned int>(params[2]) - 1;
|
2006-02-28 09:43:20 +00:00
|
|
|
|
2015-07-11 08:37:36 +00:00
|
|
|
if (sync_obj >= g_hudsync.length())
|
2006-02-28 09:43:20 +00:00
|
|
|
{
|
|
|
|
LogError(amx, AMX_ERR_NATIVE, "HudSyncObject %d is invalid", sync_obj);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_langMngr.SetDefLang(params[1]);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2006-02-28 09:43:20 +00:00
|
|
|
if (index == 0)
|
|
|
|
{
|
|
|
|
for (int i = 1; i <= gpGlobals->maxClients; ++i)
|
|
|
|
{
|
|
|
|
CPlayer *pPlayer = GET_PLAYER_POINTER_I(i);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2006-03-20 01:03:30 +00:00
|
|
|
int channel;
|
2006-02-28 09:43:20 +00:00
|
|
|
if (pPlayer->ingame)
|
|
|
|
{
|
|
|
|
g_langMngr.SetDefLang(i);
|
2006-03-20 01:03:30 +00:00
|
|
|
channel = pPlayer->NextHUDChannel();
|
|
|
|
CheckAndClearPlayerHUD(pPlayer, channel, sync_obj);
|
|
|
|
pPlayer->channels[channel] = gpGlobals->time;
|
|
|
|
g_hudset.channel = channel;
|
2006-03-01 00:10:23 +00:00
|
|
|
message = UTIL_SplitHudMessage(format_amxstring(amx, params, 3, len));
|
2006-02-28 09:43:20 +00:00
|
|
|
UTIL_HudMessage(pPlayer->pEdict, g_hudset, message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (index < 1 || index > gpGlobals->maxClients)
|
|
|
|
{
|
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index);
|
|
|
|
return 0;
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2006-02-28 09:43:20 +00:00
|
|
|
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2006-02-28 09:43:20 +00:00
|
|
|
if (pPlayer->ingame)
|
|
|
|
{
|
2006-03-20 01:03:30 +00:00
|
|
|
int channel = pPlayer->NextHUDChannel();
|
|
|
|
CheckAndClearPlayerHUD(pPlayer, channel, sync_obj);
|
|
|
|
pPlayer->channels[channel] = gpGlobals->time;
|
|
|
|
g_hudset.channel = channel;
|
2006-03-01 00:10:23 +00:00
|
|
|
message = UTIL_SplitHudMessage(format_amxstring(amx, params, 3, len));
|
2006-02-28 09:43:20 +00:00
|
|
|
UTIL_HudMessage(pPlayer->pEdict, g_hudset, message);
|
|
|
|
}
|
|
|
|
}
|
2017-03-11 18:26:25 +00:00
|
|
|
|
2006-02-28 09:43:20 +00:00
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2006-03-16 00:13:13 +00:00
|
|
|
static cell AMX_NATIVE_CALL arrayset(AMX *amx, cell *params)
|
|
|
|
{
|
2006-11-05 18:38:09 +00:00
|
|
|
cell value = params[2];
|
|
|
|
|
|
|
|
if (!value)
|
|
|
|
{
|
|
|
|
memset(get_amxaddr(amx, params[1]), 0, params[3] * sizeof(cell));
|
|
|
|
} else {
|
|
|
|
int size = params[3];
|
|
|
|
cell *addr = get_amxaddr(amx, params[1]);
|
|
|
|
for (int i=0; i<size; i++)
|
|
|
|
{
|
|
|
|
addr[i] = value;
|
|
|
|
}
|
|
|
|
}
|
2006-03-16 00:13:13 +00:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2006-08-28 11:08:18 +00:00
|
|
|
static cell AMX_NATIVE_CALL CreateLangKey(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
int len;
|
|
|
|
const char *key = get_amxstring(amx, params[1], 0, len);
|
2017-06-28 16:31:59 +00:00
|
|
|
int key_index = g_langMngr.GetKeyEntry(key);
|
2006-08-28 11:08:18 +00:00
|
|
|
|
2017-06-28 16:31:59 +00:00
|
|
|
if (key_index != -1)
|
2006-08-28 11:08:18 +00:00
|
|
|
{
|
2017-06-28 16:31:59 +00:00
|
|
|
return key_index;
|
2006-08-28 11:08:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return g_langMngr.AddKeyEntry(key);
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell AMX_NATIVE_CALL AddTranslation(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
int len;
|
|
|
|
const char *lang = get_amxstring(amx, params[1], 0, len);
|
2017-06-28 16:31:59 +00:00
|
|
|
int key_index = params[2];
|
2006-08-28 11:08:18 +00:00
|
|
|
const char *phrase = get_amxstring(amx, params[3], 1, len);
|
|
|
|
|
2015-07-11 08:37:36 +00:00
|
|
|
ke::Vector<sKeyDef> queue;
|
2006-08-28 11:08:18 +00:00
|
|
|
sKeyDef def;
|
|
|
|
|
2015-07-11 08:37:36 +00:00
|
|
|
def.definition = new ke::AutoString(phrase);
|
2017-06-28 16:31:59 +00:00
|
|
|
def.key = key_index;
|
2006-08-28 11:08:18 +00:00
|
|
|
|
2015-07-11 08:37:36 +00:00
|
|
|
queue.append(def);
|
2006-08-28 11:08:18 +00:00
|
|
|
|
|
|
|
g_langMngr.MergeDefinitions(lang, queue);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2006-09-12 07:59:56 +00:00
|
|
|
static cell AMX_NATIVE_CALL GetLangTransKey(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
int len;
|
|
|
|
const char *key = get_amxstring(amx, params[1], 0, len);
|
|
|
|
|
|
|
|
return g_langMngr.GetKeyEntry(key);
|
|
|
|
}
|
|
|
|
|
2007-03-09 03:04:40 +00:00
|
|
|
static cell AMX_NATIVE_CALL admins_push(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
// admins_push("SteamID","password",access,flags);
|
2015-10-20 08:34:18 +00:00
|
|
|
CAdminData *TempData=new CAdminData;
|
2007-03-09 03:04:40 +00:00
|
|
|
|
|
|
|
TempData->SetAuthID(get_amxaddr(amx,params[1]));
|
|
|
|
TempData->SetPass(get_amxaddr(amx,params[2]));
|
|
|
|
TempData->SetAccess(params[3]);
|
|
|
|
TempData->SetFlags(params[4]);
|
|
|
|
|
2015-07-11 08:37:36 +00:00
|
|
|
DynamicAdmins.append(TempData);
|
2007-03-09 03:04:40 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
};
|
|
|
|
static cell AMX_NATIVE_CALL admins_flush(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
// admins_flush();
|
|
|
|
|
2015-07-11 08:37:36 +00:00
|
|
|
size_t iter=DynamicAdmins.length();
|
2007-03-09 03:04:40 +00:00
|
|
|
|
|
|
|
while (iter--)
|
|
|
|
{
|
|
|
|
delete DynamicAdmins[iter];
|
|
|
|
}
|
|
|
|
|
|
|
|
DynamicAdmins.clear();
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
};
|
|
|
|
static cell AMX_NATIVE_CALL admins_num(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
// admins_num();
|
|
|
|
|
2015-07-11 08:37:36 +00:00
|
|
|
return static_cast<cell>(DynamicAdmins.length());
|
2007-03-09 03:04:40 +00:00
|
|
|
};
|
|
|
|
static cell AMX_NATIVE_CALL admins_lookup(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
// admins_lookup(Num, Property, Buffer[]={0}, BufferSize=-1);
|
|
|
|
|
2015-07-11 08:37:36 +00:00
|
|
|
if (params[1]>=static_cast<int>(DynamicAdmins.length()))
|
2007-03-09 03:04:40 +00:00
|
|
|
{
|
|
|
|
LogError(amx,AMX_ERR_NATIVE,"Invalid admins num");
|
|
|
|
return 1;
|
|
|
|
};
|
|
|
|
|
|
|
|
int BufferSize;
|
|
|
|
cell *Buffer;
|
|
|
|
const cell *Input;
|
|
|
|
|
|
|
|
switch(params[2])
|
|
|
|
{
|
|
|
|
case Admin_Auth:
|
|
|
|
BufferSize=params[4];
|
|
|
|
Buffer=get_amxaddr(amx, params[3]);
|
|
|
|
Input=DynamicAdmins[params[1]]->GetAuthID();
|
|
|
|
|
|
|
|
while (BufferSize-->0)
|
|
|
|
{
|
|
|
|
if ((*Buffer++=*Input++)==0)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// hit max buffer size, terminate string
|
|
|
|
*Buffer=0;
|
|
|
|
return 0;
|
|
|
|
break;
|
|
|
|
case Admin_Password:
|
|
|
|
BufferSize=params[4];
|
|
|
|
Buffer=get_amxaddr(amx, params[3]);
|
|
|
|
Input=DynamicAdmins[params[1]]->GetPass();
|
|
|
|
|
|
|
|
while (BufferSize-->0)
|
|
|
|
{
|
|
|
|
if ((*Buffer++=*Input++)==0)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// hit max buffer size, terminate string
|
|
|
|
*Buffer=0;
|
|
|
|
return 0;
|
|
|
|
break;
|
|
|
|
case Admin_Access:
|
|
|
|
return DynamicAdmins[params[1]]->GetAccess();
|
|
|
|
break;
|
|
|
|
case Admin_Flags:
|
|
|
|
return DynamicAdmins[params[1]]->GetFlags();
|
|
|
|
break;
|
|
|
|
};
|
|
|
|
|
|
|
|
// unknown property
|
|
|
|
return 0;
|
|
|
|
};
|
2007-04-20 02:55:59 +00:00
|
|
|
// LookupLangKey(Output[], OutputSize, const Key[], const &id)
|
|
|
|
static cell AMX_NATIVE_CALL LookupLangKey(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
int len;
|
|
|
|
char *key=get_amxstring(amx,params[3],0,len);
|
2016-02-01 13:48:32 +00:00
|
|
|
const char *def=translate(amx, playerlang(*get_amxaddr(amx, params[4])),key);
|
2007-04-20 02:55:59 +00:00
|
|
|
|
|
|
|
if (def==NULL)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
set_amxstring(amx,params[1],def,params[2]);
|
|
|
|
return 1;
|
|
|
|
};
|
2013-08-07 14:40:37 +00:00
|
|
|
|
2015-03-26 15:40:39 +00:00
|
|
|
// SetGlobalTransTarget(client)
|
|
|
|
static cell AMX_NATIVE_CALL SetGlobalTransTarget(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
g_langMngr.SetDefLang(params[1]);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
};
|
|
|
|
|
2013-08-07 14:40:37 +00:00
|
|
|
// has_map_ent_class(const classname[])
|
|
|
|
static cell AMX_NATIVE_CALL has_map_ent_class(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
int len;
|
|
|
|
char *name = get_amxstring(amx, params[1], 0, len);
|
|
|
|
|
|
|
|
return len && !FNullEnt(FIND_ENTITY_BY_STRING(NULL, "classname", name));
|
|
|
|
};
|
|
|
|
|
2015-07-19 19:12:24 +00:00
|
|
|
static cell AMX_NATIVE_CALL AutoExecConfig(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
int length;
|
|
|
|
bool autocreate = params[1] != 0;
|
|
|
|
const char *name = get_amxstring(amx, params[2], 0, length);
|
|
|
|
const char *folder = get_amxstring(amx, params[3], 1, length);
|
|
|
|
|
|
|
|
auto plugin = g_plugins.findPluginFast(amx);
|
|
|
|
|
|
|
|
if (*name == '\0')
|
|
|
|
{
|
|
|
|
char pluginName[PLATFORM_MAX_PATH];
|
|
|
|
strncopy(pluginName, plugin->getName(), sizeof(pluginName));
|
|
|
|
|
|
|
|
char *ptr;
|
|
|
|
|
|
|
|
if ((ptr = strstr(pluginName, ".amxx")))
|
|
|
|
{
|
|
|
|
*ptr = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
static char newName[PLATFORM_MAX_PATH];
|
2015-10-01 09:06:04 +00:00
|
|
|
ke::SafeSprintf(newName, sizeof(newName), "plugin-%s", pluginName);
|
2015-07-19 19:12:24 +00:00
|
|
|
|
|
|
|
name = newName;
|
|
|
|
}
|
|
|
|
|
|
|
|
plugin->AddConfig(autocreate, name, folder);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2017-02-23 11:55:53 +00:00
|
|
|
//native RequestFrame(const callback[], any:data);
|
|
|
|
static cell AMX_NATIVE_CALL RequestFrame(AMX *amx, cell *params)
|
|
|
|
{
|
|
|
|
int len;
|
|
|
|
const char *funcName = get_amxstring(amx, params[1], 0, len);
|
|
|
|
|
|
|
|
int func = registerSPForwardByName(amx, funcName, FP_CELL, FP_DONE);
|
|
|
|
if (func < 0)
|
|
|
|
{
|
|
|
|
LogError(amx, AMX_ERR_NATIVE, "Function \"%s\" was not found", funcName);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_frameActionMngr.AddFrameAction(func, params[2]);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2005-09-16 23:48:51 +00:00
|
|
|
AMX_NATIVE_INFO amxmodx_Natives[] =
|
|
|
|
{
|
2005-09-11 03:58:38 +00:00
|
|
|
{"abort", amx_abort},
|
2007-03-09 03:04:40 +00:00
|
|
|
{"admins_flush", admins_flush},
|
|
|
|
{"admins_lookup", admins_lookup},
|
|
|
|
{"admins_num", admins_num},
|
|
|
|
{"admins_push", admins_push},
|
2014-05-02 07:16:16 +00:00
|
|
|
{"amxclient_cmd", amxclient_cmd},
|
2006-03-16 00:13:13 +00:00
|
|
|
{"arrayset", arrayset},
|
2006-01-06 14:47:59 +00:00
|
|
|
{"get_addr_val", get_addr_val},
|
|
|
|
{"get_var_addr", get_var_addr},
|
|
|
|
{"set_addr_val", set_addr_val},
|
2005-09-11 03:58:38 +00:00
|
|
|
{"callfunc_begin", callfunc_begin},
|
|
|
|
{"callfunc_begin_i", callfunc_begin_i},
|
|
|
|
{"callfunc_end", callfunc_end},
|
|
|
|
{"callfunc_push_int", callfunc_push_byval},
|
|
|
|
{"callfunc_push_float", callfunc_push_byval},
|
|
|
|
{"callfunc_push_intrf", callfunc_push_byref},
|
|
|
|
{"callfunc_push_floatrf", callfunc_push_byref},
|
|
|
|
{"callfunc_push_str", callfunc_push_str},
|
2006-08-18 05:52:21 +00:00
|
|
|
{"callfunc_push_array", callfunc_push_array},
|
2006-02-01 12:08:42 +00:00
|
|
|
{"change_task", change_task},
|
2015-01-23 15:52:58 +00:00
|
|
|
{"engine_changelevel", engine_changelevel},
|
2005-09-11 03:58:38 +00:00
|
|
|
{"client_cmd", client_cmd},
|
|
|
|
{"client_print", client_print},
|
2013-08-23 23:03:13 +00:00
|
|
|
{"client_print_color", client_print_color},
|
2005-09-11 03:58:38 +00:00
|
|
|
{"console_cmd", console_cmd},
|
|
|
|
{"console_print", console_print},
|
|
|
|
{"emit_sound", emit_sound},
|
|
|
|
{"engclient_cmd", engclient_cmd},
|
|
|
|
{"engclient_print", engclient_print},
|
|
|
|
{"find_player", find_player},
|
2017-12-07 23:06:37 +00:00
|
|
|
{"find_player_ex", find_player_ex},
|
2005-09-11 03:58:38 +00:00
|
|
|
{"find_plugin_byfile", find_plugin_byfile},
|
|
|
|
{"force_unmodified", force_unmodified},
|
|
|
|
{"format_time", format_time},
|
|
|
|
{"get_clcmd", get_clcmd},
|
|
|
|
{"get_clcmdsnum", get_clcmdsnum},
|
|
|
|
{"get_concmd", get_concmd},
|
|
|
|
{"get_concmdsnum", get_concmdsnum},
|
2006-09-12 07:59:56 +00:00
|
|
|
{"get_concmd_plid", get_concmd_plid},
|
2005-09-11 03:58:38 +00:00
|
|
|
{"get_flags", get_flags},
|
|
|
|
{"get_func_id", get_func_id},
|
|
|
|
{"get_gametime", get_gametime},
|
|
|
|
{"get_lang", get_lang},
|
|
|
|
{"get_langsnum", get_langsnum},
|
|
|
|
{"get_localinfo", get_localinfo},
|
|
|
|
{"get_mapname", get_mapname},
|
|
|
|
{"get_maxplayers", get_maxplayers},
|
|
|
|
{"get_modname", get_modname},
|
|
|
|
{"get_module", get_module},
|
|
|
|
{"get_modulesnum", get_modulesnum},
|
|
|
|
{"get_players", get_players},
|
|
|
|
{"get_playersnum", get_playersnum},
|
|
|
|
{"get_plugin", get_plugin},
|
|
|
|
{"get_pluginsnum", get_pluginsnum},
|
|
|
|
{"get_srvcmd", get_srvcmd},
|
|
|
|
{"get_srvcmdsnum", get_srvcmdsnum},
|
|
|
|
{"get_systime", get_systime},
|
|
|
|
{"get_time", get_time},
|
|
|
|
{"get_timeleft", get_timeleft},
|
2006-04-25 17:19:58 +00:00
|
|
|
{"get_amxx_verstring", get_amxx_verstring},
|
2005-09-11 03:58:38 +00:00
|
|
|
{"get_user_aiming", get_user_aiming},
|
|
|
|
{"get_user_ammo", get_user_ammo},
|
|
|
|
{"get_user_armor", get_user_armor},
|
|
|
|
{"get_user_attacker", get_user_attacker},
|
|
|
|
{"get_user_authid", get_user_authid},
|
|
|
|
{"get_user_flags", get_user_flags},
|
|
|
|
{"get_user_frags", get_user_frags},
|
|
|
|
{"get_user_deaths", get_user_deaths},
|
|
|
|
{"get_user_health", get_user_health},
|
|
|
|
{"get_user_index", get_user_index},
|
|
|
|
{"get_user_info", get_user_info},
|
|
|
|
{"get_user_ip", get_user_ip},
|
|
|
|
{"get_user_menu", get_user_menu},
|
|
|
|
{"get_user_msgid", get_user_msgid},
|
|
|
|
{"get_user_msgname", get_user_msgname},
|
|
|
|
{"get_user_name", get_user_name},
|
|
|
|
{"get_user_origin", get_user_origin},
|
|
|
|
{"get_user_ping", get_user_ping},
|
|
|
|
{"get_user_team", get_user_team},
|
|
|
|
{"get_user_time", get_user_time},
|
|
|
|
{"get_user_userid", get_user_userid},
|
|
|
|
{"get_user_weapon", get_user_weapon},
|
|
|
|
{"get_user_weapons", get_user_weapons},
|
2006-05-13 14:59:24 +00:00
|
|
|
{"get_weaponid", get_weaponid},
|
2005-09-11 03:58:38 +00:00
|
|
|
{"get_weaponname", get_weaponname},
|
|
|
|
{"get_xvar_float", get_xvar_num},
|
|
|
|
{"get_xvar_id", get_xvar_id},
|
|
|
|
{"get_xvar_num", get_xvar_num},
|
2013-08-07 14:40:37 +00:00
|
|
|
{"has_map_ent_class", has_map_ent_class},
|
2005-09-11 03:58:38 +00:00
|
|
|
{"int3", int3},
|
|
|
|
{"is_amd64_server", is_amd64_server},
|
|
|
|
{"is_dedicated_server", is_dedicated_server},
|
|
|
|
{"is_jit_enabled", is_jit_enabled},
|
|
|
|
{"is_linux_server", is_linux_server},
|
|
|
|
{"is_map_valid", is_map_valid},
|
|
|
|
{"is_module_loaded", is_module_loaded},
|
|
|
|
{"is_plugin_loaded", is_plugin_loaded},
|
|
|
|
{"is_user_alive", is_user_alive},
|
|
|
|
{"is_user_authorized", is_user_authorized},
|
|
|
|
{"is_user_bot", is_user_bot},
|
|
|
|
{"is_user_connected", is_user_connected},
|
|
|
|
{"is_user_connecting", is_user_connecting},
|
|
|
|
{"is_user_hltv", is_user_hltv},
|
|
|
|
{"lang_exists", lang_exists},
|
|
|
|
{"log_amx", log_amx},
|
|
|
|
{"log_message", log_message},
|
2017-08-01 13:14:53 +00:00
|
|
|
{"elog_message", elog_message},
|
2005-09-11 03:58:38 +00:00
|
|
|
{"log_to_file", log_to_file},
|
|
|
|
{"md5", amx_md5},
|
|
|
|
{"md5_file", amx_md5_file},
|
Add new hashers and new natives
Replace the only hasher called MD5 with the ones listed below.
(+) CRC32, MD5, SHA1, SHA256, SHA3 224 BIT, SHA3 256 BIT, SHA3 384 BIT,
SHA3 512 BIT, Keccak 224 BIT, Keccak 256 BIT, Keccak 384 BIT and Keccak
512 BIT.
Add the natives listed below.
(+) hash_string(const string[], hashType:type, output[], const
outputSize)
(+) hash_file(const fileName, hashType:type, output[], const outputSize)
(+) is_arkshine_a_doctor() : Hidden native, but a sign of recompense
for him being very active since 1.8.3 version of AMX Mod X
(+) get_system_endianness() : Checks if the system is currently Big
Endian or Little Endian.
Add the following Enum.
(+) hashType {}
(+) sysEndianness {}
Deprecate the following natives.
(-) amx_md5()
(-) amx_md5_file()
It has been tested on Windows and Linux. The sanity checks seems to be
properly working, so no worries about them.
These are useful if people are using Sockets, cURLs or MySQLs in order
to compare hashes of different files On-line for further investigation.
You are not able to check if the files are older or newer, but you can
see if the content is different (Hash Checksum mismatch).
I'm glad I did this. Thanks to
2015-02-15 06:44:33 +00:00
|
|
|
{"hash_string", amx_hash_string},
|
|
|
|
{"hash_file", amx_hash_file},
|
2005-09-11 04:43:40 +00:00
|
|
|
{"module_exists", module_exists},
|
2005-11-19 01:25:34 +00:00
|
|
|
{"next_hudchannel", next_hudchannel},
|
2005-09-11 03:58:38 +00:00
|
|
|
{"num_to_word", num_to_word},
|
|
|
|
{"parse_loguser", parse_loguser},
|
|
|
|
{"parse_time", parse_time},
|
|
|
|
{"pause", pause},
|
|
|
|
{"plugin_flags", plugin_flags},
|
|
|
|
{"precache_model", precache_model},
|
|
|
|
{"precache_sound", precache_sound},
|
2018-07-10 09:50:31 +00:00
|
|
|
{"precache_generic", precache_generic},
|
|
|
|
{"precache_event", precache_event},
|
2005-09-11 03:58:38 +00:00
|
|
|
{"random_float", random_float},
|
|
|
|
{"random_num", random_num},
|
|
|
|
{"read_argc", read_argc},
|
|
|
|
{"read_args", read_args},
|
|
|
|
{"read_argv", read_argv},
|
2016-08-31 18:34:02 +00:00
|
|
|
{"read_argv_int", read_argv_int},
|
|
|
|
{"read_argv_float", read_argv_float},
|
2005-09-11 03:58:38 +00:00
|
|
|
{"read_data", read_data},
|
|
|
|
{"read_datanum", read_datanum},
|
2013-07-27 18:49:19 +00:00
|
|
|
{"read_datatype", read_datatype},
|
2005-09-11 03:58:38 +00:00
|
|
|
{"read_flags", read_flags},
|
|
|
|
{"read_logargc", read_logargc},
|
|
|
|
{"read_logargv", read_logargv},
|
|
|
|
{"read_logdata", read_logdata},
|
|
|
|
{"register_clcmd", register_clcmd},
|
|
|
|
{"register_concmd", register_concmd},
|
|
|
|
{"register_dictionary", register_dictionary},
|
|
|
|
{"register_event", register_event},
|
2017-12-07 23:06:37 +00:00
|
|
|
{"register_event_ex", register_event_ex},
|
2015-07-20 09:07:10 +00:00
|
|
|
{"enable_event", enable_event},
|
|
|
|
{"disable_event", disable_event},
|
2005-09-11 03:58:38 +00:00
|
|
|
{"register_logevent", register_logevent},
|
2015-12-24 17:25:52 +00:00
|
|
|
{"enable_logevent", enable_logevent},
|
|
|
|
{"disable_logevent", disable_logevent},
|
2005-09-11 03:58:38 +00:00
|
|
|
{"register_menucmd", register_menucmd},
|
|
|
|
{"register_menuid", register_menuid},
|
|
|
|
{"register_plugin", register_plugin},
|
|
|
|
{"register_srvcmd", register_srvcmd},
|
|
|
|
{"require_module", require_module},
|
|
|
|
{"remove_quotes", remove_quotes},
|
|
|
|
{"remove_task", remove_task},
|
|
|
|
{"remove_user_flags", remove_user_flags},
|
|
|
|
{"server_cmd", server_cmd},
|
|
|
|
{"server_exec", server_exec},
|
|
|
|
{"server_print", server_print},
|
2005-12-01 13:42:28 +00:00
|
|
|
{"set_fail_state", set_fail_state},
|
2014-04-11 19:54:24 +00:00
|
|
|
{"set_dhudmessage", set_dhudmessage},
|
2005-09-11 03:58:38 +00:00
|
|
|
{"set_hudmessage", set_hudmessage},
|
|
|
|
{"set_localinfo", set_localinfo},
|
|
|
|
{"set_task", set_task},
|
|
|
|
{"set_user_flags", set_user_flags},
|
|
|
|
{"set_user_info", set_user_info},
|
|
|
|
{"set_xvar_float", set_xvar_num},
|
|
|
|
{"set_xvar_num", set_xvar_num},
|
2017-03-11 18:26:25 +00:00
|
|
|
{"show_dhudmessage", show_dhudmessage},
|
2005-09-11 03:58:38 +00:00
|
|
|
{"show_hudmessage", show_hudmessage},
|
|
|
|
{"show_menu", show_menu},
|
|
|
|
{"show_motd", show_motd},
|
|
|
|
{"task_exists", task_exists},
|
|
|
|
{"unpause", unpause},
|
2006-02-01 12:08:42 +00:00
|
|
|
{"user_has_weapon", user_has_weapon},
|
2005-09-11 03:58:38 +00:00
|
|
|
{"user_kill", user_kill},
|
|
|
|
{"user_slap", user_slap},
|
|
|
|
{"xvar_exists", xvar_exists},
|
2006-08-28 11:08:18 +00:00
|
|
|
{"AddTranslation", AddTranslation},
|
2006-03-01 02:20:44 +00:00
|
|
|
{"ClearSyncHud", ClearSyncHud},
|
2006-02-28 09:43:20 +00:00
|
|
|
{"CreateHudSyncObj", CreateHudSyncObj},
|
2006-08-28 11:08:18 +00:00
|
|
|
{"CreateLangKey", CreateLangKey},
|
2006-02-01 12:08:42 +00:00
|
|
|
{"CreateMultiForward", CreateMultiForward},
|
|
|
|
{"CreateOneForward", CreateOneForward},
|
|
|
|
{"DestroyForward", DestroyForward},
|
2006-02-28 09:43:20 +00:00
|
|
|
{"ExecuteForward", ExecuteForward},
|
2006-09-12 07:59:56 +00:00
|
|
|
{"GetLangTransKey", GetLangTransKey},
|
2006-08-24 21:13:52 +00:00
|
|
|
{"LibraryExists", LibraryExists},
|
2007-04-20 03:02:41 +00:00
|
|
|
{"LookupLangKey", LookupLangKey},
|
2015-03-26 15:40:39 +00:00
|
|
|
{"SetGlobalTransTarget", SetGlobalTransTarget},
|
2006-02-28 09:43:20 +00:00
|
|
|
{"PrepareArray", PrepareArray},
|
|
|
|
{"ShowSyncHudMsg", ShowSyncHudMsg},
|
2015-07-19 19:12:24 +00:00
|
|
|
{"AutoExecConfig", AutoExecConfig},
|
2017-02-23 11:55:53 +00:00
|
|
|
{"RequestFrame", RequestFrame},
|
2005-09-11 03:58:38 +00:00
|
|
|
{NULL, NULL}
|
2004-03-24 01:35:44 +00:00
|
|
|
};
|