amxmodx/amxmodx/amxmodx.cpp

4799 lines
112 KiB
C++
Raw Normal View History

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>
#include <amtl/am-utility.h>
2004-03-24 01:35:44 +00:00
#include "amxmodx.h"
#include "CMenu.h"
#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"
#include "binlog.h"
#include "libraries.h"
#include "CFlagManager.h"
#include "nongpl_matches.h"
#include "format.h"
2004-03-24 01:35:44 +00:00
extern CFlagManager FlagMan;
ke::Vector<CAdminData *> DynamicAdmins;
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
{
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]))
{
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);
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 {
edict_t* pEdict = TypeConversion.id_to_edict(params[1]);
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);
2005-09-16 23:48:51 +00:00
if (len > 254)
len = 254;
2005-09-16 23:48:51 +00:00
message[len++] = '\n';
message[len] = 0;
SERVER_PRINT(message);
2005-09-09 03:23:31 +00:00
return len;
}
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
{
int len = 0;
2004-07-28 18:33:20 +00:00
char *msg;
PRINT_TYPE type = (PRINT_TYPE)params[2];
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);
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;
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;
}
2004-07-28 18:33:20 +00:00
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
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;
CLIENT_PRINT(pPlayer->pEdict, type, msg);
2004-07-28 18:33:20 +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);
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);
2006-08-24 21:13:52 +00:00
if (!pPlayer->IsBot() && pPlayer->initialized)
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
}
// 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-07-28 18:33:20 +00:00
int index = params[1];
2004-07-28 18:33:20 +00:00
if (index < 1 || index > gpGlobals->maxClients)
{
2004-07-28 18:33:20 +00:00
g_langMngr.SetDefLang(LANG_SERVER);
}
2004-07-28 18:33:20 +00:00
else
{
2004-07-28 18:33:20 +00:00
g_langMngr.SetDefLang(index);
}
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);
if (index < 1 || index > gpGlobals->maxClients) // Server console
{
if (len > 254)
{
len = 254;
if ((message[len - 1] & 1 << 7))
{
len -= UTIL_CheckValidChar(message + len - 1); // Don't truncate a multi-byte character
}
}
message[len++] = '\n';
message[len] = 0;
2005-09-16 23:48:51 +00:00
SERVER_PRINT(message);
}
else // A specific player's console
2004-07-28 18:33:20 +00:00
{
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
if (pPlayer->ingame && !pPlayer->IsBot())
{
if (len > 126) // Client console truncates after byte 127. (126 + \n = 127)
{
len = 126;
if ((message[len - 1] & 1 << 7))
{
len -= UTIL_CheckValidChar(message + len - 1); // Don't truncate a multi-byte character
}
}
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);
}
2004-07-28 18:33:20 +00:00
}
2004-07-28 18:33:20 +00:00
return len;
}
2004-03-24 01:35:44 +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;
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);
if (pPlayer->ingame && !pPlayer->IsBot())
2004-07-28 18:33:20 +00:00
{
g_langMngr.SetDefLang(i);
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;
if ((msg[len - 1] & 1 << 7))
{
len -= UTIL_CheckValidChar(msg + len - 1); // Don't truncate a multi-byte character
}
}
msg[len++] = '\n'; // Client expects newline from the server
2004-07-28 18:33:20 +00:00
msg[len] = 0;
UTIL_ClientPrint(pPlayer->pEdict, params[2], msg);
2004-07-28 18:33:20 +00:00
}
}
}
else // A specific player
{
2004-07-28 18:33:20 +00:00
int index = params[1];
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;
}
2004-07-28 18:33:20 +00:00
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
if (pPlayer->ingame && !pPlayer->IsBot())
{
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;
if ((msg[len - 1] & 1 << 7))
{
len -= UTIL_CheckValidChar(msg + len - 1); // Don't truncate a multi-byte character
}
}
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
}
2004-07-28 18:33:20 +00:00
return len;
2004-06-24 07:09:17 +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];
if (sender < print_team_blue || sender > gpGlobals->maxClients)
{
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);
if (static_cast<byte>(*msg) > 4) // Insert default color code at the start if not present, otherwise message will not be colored.
{
memmove(msg + 1, msg, ke::Min(len++, 191));
*msg = 1;
}
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
}
}
msg[len++] = '\n';
msg[len] = 0;
UTIL_ClientSayText(pPlayer->pEdict, sender ? sender : i, msg);
}
}
}
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);
msg = format_amxstring(amx, params, 3, len);
if (static_cast<byte>(*msg) > 4) // Insert default color code at the start if not present, otherwise message will not be colored.
{
memmove(msg + 1, msg, ke::Min(len++, 191));
*msg = 1;
}
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
}
}
msg[len++] = '\n';
msg[len] = 0;
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);
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;
2005-09-16 23:48:51 +00:00
if (ilen < 128)
sToShow = (char*)LOAD_FILE_FOR_ME(szBody, &iFile);
2005-09-09 03:23:31 +00:00
if (!iFile)
sToShow = szBody;
else
ilen = iFile;
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);
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];
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);
2005-09-09 03:23:31 +00:00
return 0;
}
2005-09-09 03:23:31 +00:00
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
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
if (iFile)
FREE_FILE(sToShow);
2005-09-09 03:23:31 +00:00
return 1;
2004-06-24 07:09:17 +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);
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;
}
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];
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
{
int len = 0;
g_langMngr.SetDefLang(params[1]);
char* message = NULL;
/**
* 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.
*/
bool aut = (g_hudset.channel == -1) ? true : false;
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);
}
if (params[1] == 0)
{
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 = UTIL_SplitHudMessage(format_amxstring(amx, params, 2, len));
if (aut)
{
channel = pPlayer->NextHUDChannel();
pPlayer->channels[channel] = gpGlobals->time;
g_hudset.channel = channel;
}
//don't need to set g_hudset!
pPlayer->hudmap[channel] = 0;
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));
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);
return 0;
}
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
if (pPlayer->ingame && !pPlayer->IsBot())
{
if (aut)
{
channel = pPlayer->NextHUDChannel();
pPlayer->channels[channel] = gpGlobals->time;
g_hudset.channel = channel;
}
pPlayer->hudmap[channel] = 0;
2005-09-16 23:48:51 +00:00
UTIL_HudMessage(pPlayer->pEdict, g_hudset, message);
}
}
return len;
2004-06-24 07:09:17 +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];
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
if (((message[len - 1] & 0xFF) >= 0xC2) && ((message[len - 1] & 0xFF) <= 0xEF))
{
--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];
if (index < 1 || index > gpGlobals->maxClients)
return set_amxstring_utf8(amx, params[2], hostname->string, strlen(hostname->string), maxlen);
else
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);
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);
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)
{
#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)
{
#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];
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-09 03:23:31 +00:00
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
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];
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);
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];
2005-09-16 23:48:51 +00:00
if (index < 1 || index > gpGlobals->maxClients)
2005-09-09 03:23:31 +00:00
return 0;
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];
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);
2005-09-09 03:23:31 +00:00
if (!pPlayer->initialized)
return 0;
2005-09-09 03:23:31 +00:00
if (pPlayer->pEdict->v.flags & FL_PROXY)
return 1;
2005-09-09 03:23:31 +00:00
const char *authid = GETPLAYERAUTHID(pPlayer->pEdict);
2005-09-09 03:23:31 +00:00
if (authid && stricmp(authid, "HLTV") == 0)
return 1;
2005-09-09 03:23:31 +00:00
return 0;
2004-03-24 01:35:44 +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];
2005-09-16 23:48:51 +00:00
if (index < 1 || index > gpGlobals->maxClients)
{
return FALSE;
}
2005-09-09 03:23:31 +00:00
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
if (!pPlayer->ingame)
{
return FALSE;
}
if (g_bmod_tfc)
{
edict_t *e = pPlayer->pEdict;
if (e->v.flags & FL_SPECTATOR ||
(!e->v.team || !e->v.playerclass))
{
return FALSE;
}
}
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 */
{
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];
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-09 03:23:31 +00:00
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
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];
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-09 03:23:31 +00:00
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
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];
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-09 03:23:31 +00:00
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
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];
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-09 03:23:31 +00:00
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
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];
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-09 03:23:31 +00:00
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
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;
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);
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];
2005-09-09 03:23:31 +00:00
if (index < 1 || index > gpGlobals->maxClients)
return 0;
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];
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;
}
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
{
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];
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);
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;
2005-09-09 03:23:31 +00:00
int weapons = pPlayer->pEdict->v.weapons & ~(1<<31); // don't count last element
if (g_bmod_dod)
{
// Don't ignore that last element for dod
weapons = pPlayer->pEdict->v.weapons;
}
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;
}
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];
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-09 03:23:31 +00:00
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
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]);
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;
}
2005-09-09 03:23:31 +00:00
edict_t* edict = pPlayer->pEdict;
Vector pos = edict->v.origin;
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;
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];
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;
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;
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;
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;
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;
2005-09-09 03:23:31 +00:00
return 1;
}
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];
strcpy(szIp, (index < 1 || index > gpGlobals->maxClients) ? CVAR_GET_STRING("net_address") : g_players[index].ip.chars());
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';
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];
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-09 03:23:31 +00:00
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
edict_t *enemy = NULL;
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;
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
}
}
}
}
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];
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-09 03:23:31 +00:00
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
if (!pPlayer->ingame)
{
return 0;
}
2005-09-09 03:23:31 +00:00
edict_t *pEntity = pPlayer->pEdict;
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;
}
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;
}
}
2005-09-09 03:23:31 +00:00
return 0;
}
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];
2005-09-09 03:23:31 +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-09 03:23:31 +00:00
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
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;
2005-09-09 03:23:31 +00:00
return wpn;
}
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];
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-09 03:23:31 +00:00
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
2005-09-16 23:48:51 +00:00
if (pPlayer->ingame)
{
2005-09-09 03:23:31 +00:00
int wpn = params[2];
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;
}
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;
2005-09-09 03:23:31 +00:00
return 1;
}
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];
2005-09-16 23:48:51 +00:00
if (index < 1 || index > gpGlobals->maxClients)
2005-09-09 03:23:31 +00:00
return -1;
2005-09-09 03:23:31 +00:00
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
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;
2005-09-16 23:48:51 +00:00
if (params[3])
{
const char *szTeam = "";
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
}
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])
{
set_amxstring(amx, params[2], pPlayer->team.chars(), params[3]);
}
2004-08-04 15:32:48 +00:00
2005-09-09 03:23:31 +00:00
return pPlayer->teamId;
}
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 */
{
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)
{
enum JoinState { Joined = 0 };
enum MenuState { Menu_OFF = 0, Menu_ChooseTeam = 1, Menu_ChooseAppearance = 3 };
GET_OFFSET("CBasePlayer", m_iJoiningState);
GET_OFFSET("CBasePlayer", m_iMenu);
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);
}
}
return 0;
};
int index = params[1];
// 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)
{
if (closeMenu(i) == 2)
{
return 0;
}
}
}
else
{
if (index < 1 || index > gpGlobals->maxClients)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index);
return 0;
}
if (closeMenu(index))
{
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;
2005-09-09 03:23:31 +00:00
if (ilen2 && lMenu)
{
menuid = g_menucmds.findMenuId(lMenu, amx);
} else {
menuid = g_menucmds.findMenuId(sMenu, amx);
}
2005-09-09 03:23:31 +00:00
int keys = params[2];
int time = params[4];
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;
2005-11-13 20:33:30 +00:00
if (time == -1)
pPlayer->menuexpire = INFINITE;
else
pPlayer->menuexpire = gpGlobals->time + static_cast<float>(time);
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
}
}
} else {
2005-09-09 03:23:31 +00:00
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
2005-11-13 20:33:30 +00:00
if (pPlayer->ingame)
{
pPlayer->keys = keys;
pPlayer->menu = menuid;
pPlayer->vgui = false;
if (time == -1)
pPlayer->menuexpire = INFINITE;
else
pPlayer->menuexpire = gpGlobals->time + static_cast<float>(time);
pPlayer->page = 0;
UTIL_ShowMenu(pPlayer->pEdict, keys, time, sMenu, ilen);
}
2005-09-09 03:23:31 +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;
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
a->setTitle(title);
a->setVersion(vers);
a->setAuthor(author);
/* 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++;
}
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);
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]);
2015-07-31 13:45:32 +00:00
if (params[0] / sizeof(cell) >= 12)
{
cell *jit_info = get_amxaddr(amx, params[12]);
#if defined AMD64 || !defined JIT
2015-07-31 13:45:32 +00:00
*jit_info = 0;
#else
2015-07-31 13:45:32 +00:00
*jit_info = a->isDebug() ? 0 : 1;
#endif
2015-07-31 13:45:32 +00:00
}
return a->getId();
}
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
}
static cell AMX_NATIVE_CALL amx_md5(AMX *amx, cell *params)
{
int len;
char *str = get_amxstring(amx, params[1], 0, len);
const char *hash = hashString((const char *)str, len, Hash_Md5);
return set_amxstring(amx, params[2], hash, 32);
}
static cell AMX_NATIVE_CALL amx_md5_file(AMX *amx, cell *params)
{
int len;
char *str = get_amxstring(amx, params[1], 0, len);
char file[PLATFORM_MAX_PATH];
build_pathname_r(file, sizeof(file), "%s", str);
const char *hash = hashFile((const char *)file, Hash_Md5);
if (!hash)
{
LogError(amx, AMX_ERR_NATIVE, "Cant open file \"%s\"", file);
return 0;
}
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);
char file[PLATFORM_MAX_PATH];
build_pathname_r(file, sizeof(file), "%s", str);
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;
}
return set_amxstring(amx, params[3], hash, params[4]);
}
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
}
// 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);
2005-09-09 03:23:31 +00:00
idx = registerSPForwardByName(amx, temp, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
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;
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;
}
if (FlagMan.ShouldIAddThisCommand(amx,params,temp)==1)
{
FlagMan.LookupOrAdd(temp,access,amx);
}
if ((cmd = g_commands.registerCommand(plugin, idx, temp, info, access, listable, info_ml)) == NULL)
2005-09-09 03:23:31 +00:00
return 0;
if (CheckBadConList(temp, 1))
{
plugin->AddToFailCounter(1);
}
2005-09-16 23:48:51 +00:00
cmd->setCmdType(CMD_ConsoleCommand);
REG_SVR_COMMAND((char*)cmd->getCommand(), plugin_srvcmd);
return cmd->getId();
2004-03-24 01:35:44 +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);
2005-09-09 03:23:31 +00:00
idx = registerSPForwardByName(amx, temp, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
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;
}
2005-09-16 23:48:51 +00:00
temp = get_amxstring(amx, params[1], 0, i);
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;
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;
}
if (FlagMan.ShouldIAddThisCommand(amx,params,temp)==1)
{
FlagMan.LookupOrAdd(temp,access,amx);
}
if ((cmd = g_commands.registerCommand(plugin, idx, temp, info, access, listable, info_ml)) == NULL)
2005-09-09 03:23:31 +00:00
return 0;
2005-09-16 23:48:51 +00:00
cmd->setCmdType(CMD_ClientCommand);
return cmd->getId();
2004-03-24 01:35:44 +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);
2005-09-09 03:23:31 +00:00
idx = registerSPForwardByName(amx, temp, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
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;
}
2005-09-16 23:48:51 +00:00
temp = get_amxstring(amx, params[1], 0, i);
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;
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;
}
if ((cmd = g_commands.registerCommand(plugin, idx, temp, info, access, listable, info_ml)) == NULL)
2005-09-09 03:23:31 +00:00
return 0;
2005-09-16 23:48:51 +00:00
cmd->setCmdType(CMD_ServerCommand);
REG_SVR_COMMAND((char*)cmd->getCommand(), plugin_srvcmd);
return cmd->getId();
2004-03-24 01:35:44 +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;
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();
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
}
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();
}
// 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]);
2005-09-16 23:48:51 +00:00
if (cmd == 0)
return 0;
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();
2004-03-24 01:35:44 +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
}
// 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]);
2005-09-16 23:48:51 +00:00
if (cmd == 0)
return 0;
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();
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];
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]);
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);
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;
}
// 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];
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-09 03:23:31 +00:00
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
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);
2005-09-16 23:48:51 +00:00
if (params[2])
pPlayer->pEdict->v.frags = bef;
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];
2005-09-16 23:48:51 +00:00
if (index < 1 || index > gpGlobals->maxClients)
2005-09-09 03:23:31 +00:00
return 0;
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);
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);
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
}
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;
2005-09-09 03:23:31 +00:00
int armor = (int)pEdict->v.armorvalue;
armor -= power;
2005-09-16 23:48:51 +00:00
if (armor < 0)
armor = 0;
2005-09-09 03:23:31 +00:00
pEdict->v.armorvalue = static_cast<float>(armor);
pEdict->v.dmg_inflictor = pEdict;
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
}
}
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);
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);
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*/)
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];
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-09 03:23:31 +00:00
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
2006-08-24 21:13:52 +00:00
if (!pPlayer->IsBot() && pPlayer->initialized /*&& pPlayer->ingame*/)
CLIENT_COMMAND(pPlayer->pEdict, "%s", cmd);
2005-09-09 03:23:31 +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);
2005-09-16 23:48:51 +00:00
message[len++] = '\n';
message[len] = 0;
2005-09-16 23:48:51 +00:00
ALERT(at_logged, "%s", message);
2005-09-09 03:23:31 +00:00
return len;
2004-03-24 01:35:44 +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;
char file[PLATFORM_MAX_PATH];
2005-09-09 03:23:31 +00:00
if (strchr(szFile, '/') || strchr(szFile, '\\'))
{
build_pathname_r(file, sizeof(file), "%s", szFile);
2005-09-09 03:23:31 +00:00
} else {
build_pathname_r(file, sizeof(file), "%s/%s", g_log_dir.chars(), szFile);
2005-09-09 03:23:31 +00:00
}
2005-09-09 03:23:31 +00:00
bool first_time = true;
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);
}
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;
}
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);
2005-09-16 23:48:51 +00:00
message[len++] = '\n';
message[len] = 0;
2005-09-16 23:48:51 +00:00
if (first_time)
{
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
}
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);
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);
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);
2005-09-09 03:23:31 +00:00
char szDate[512];
2005-09-16 23:48:51 +00:00
strftime(szDate, 511, sptemp, lt);
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);
2005-09-16 23:48:51 +00:00
if (lt == 0)
{
LogError(amx, AMX_ERR_NATIVE, "Couldn't get localtime");
2005-09-09 03:23:31 +00:00
return 0;
}
2005-09-09 03:23:31 +00:00
char szDate[512];
ilen = strftime(szDate, 511, sptemp, lt);
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;
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);
2005-09-16 23:48:51 +00:00
if (mytime == 0)
{
LogError(amx, AMX_ERR_NATIVE, "Couldn't get localtime");
2005-09-09 03:23:31 +00:00
return 0;
}
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);
2005-09-16 23:48:51 +00:00
if (mytime == 0)
{
LogError(amx, AMX_ERR_NATIVE, "Couldn't get localtime");
2005-09-09 03:23:31 +00:00
return 0;
}
2005-09-16 23:48:51 +00:00
strptime(sTime, sFormat, mytime, 1);
2005-09-09 03:23:31 +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];
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();
}
2005-09-16 23:48:51 +00:00
switch (*params / sizeof(cell))
{
case 1:
2005-09-16 23:48:51 +00:00
return g_events.getArgInteger(params[1]);
case 3:
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]));
default:
cell *fCell = get_amxaddr(amx, params[2]);
REAL fparam = (REAL)g_events.getArgFloat(params[1]);
fCell[0] = amx_ftoc(fparam);
return (int)fparam;
}
2004-03-24 01:35:44 +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;
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-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);
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)
{
Improve UTF-8 support in some natives (bug 6475) (#407) * Compile as static library, update AMBuildScript and link to core * Update VS project files to include the library * Add UTF-8 Rewind library (v1.5.1) to third_party directory * Update ACKNOWLEDGEMENTS.txt * Move AMXX buffer in its own function * Move constants from string.inc to string_const.inc and update project files * Move stocks from string.inc to string_stocks.inc and update project files * Improve UTF-8 support in containi() and update documentation * Improve UTF-8 support in strcmp() and update documentation * Improve UTF-8 support in strfind() and update documentation Worth to be noted that this native with ignorecase set was not working properly. So broken that no one reported the issue. This adds also a safety check for "pos" parameter to not go < 0. * Improve UTF-8 support in strncmp() and update documentation * Improve UTF-8 support in equali() and update documentation * Add an option to some UTF-8 Rewind functions for avoiding invalid data to be replaced By default it replaces any invalid byte or sequence of bytes by 0xFFFD (3 bytes). It can be problematic when the input buffer is not changed (from a plugin) and that some natives need to calculate a position from the converted string. With such replacement, the position is displaced due the final string length being larger. This compiles the library as C++, because I added some silly param with a default default value which is not supported by C. * Improve UTF-8 support in replace_string/ex() and update documentation * Add is_string_category() and update documentation * Update a little testsuite plugin (and fix linux compilation) * Add mb_strotolower/upper() and update documentation * Add mb_ucfirst() and update documentation * Add mb_strtotile() and update documentation * Improve UTF-8 support in get_players() and find_player() with name/case insenstive flags set * Fix KliPPy's complain
2017-08-05 08:32:16 +00:00
if (utf8stristr(pPlayer->name.chars(), sptemp) == NULL)
2005-09-09 03:23:31 +00:00
continue;
}
else if (strstr(pPlayer->name.chars(), sptemp) == NULL)
2005-09-09 03:23:31 +00:00
continue;
}
aPlayers[iNum++] = i;
}
}
*iMax = iNum;
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);
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]);
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)
Improve UTF-8 support in some natives (bug 6475) (#407) * Compile as static library, update AMBuildScript and link to core * Update VS project files to include the library * Add UTF-8 Rewind library (v1.5.1) to third_party directory * Update ACKNOWLEDGEMENTS.txt * Move AMXX buffer in its own function * Move constants from string.inc to string_const.inc and update project files * Move stocks from string.inc to string_stocks.inc and update project files * Improve UTF-8 support in containi() and update documentation * Improve UTF-8 support in strcmp() and update documentation * Improve UTF-8 support in strfind() and update documentation Worth to be noted that this native with ignorecase set was not working properly. So broken that no one reported the issue. This adds also a safety check for "pos" parameter to not go < 0. * Improve UTF-8 support in strncmp() and update documentation * Improve UTF-8 support in equali() and update documentation * Add an option to some UTF-8 Rewind functions for avoiding invalid data to be replaced By default it replaces any invalid byte or sequence of bytes by 0xFFFD (3 bytes). It can be problematic when the input buffer is not changed (from a plugin) and that some natives need to calculate a position from the converted string. With such replacement, the position is displaced due the final string length being larger. This compiles the library as C++, because I added some silly param with a default default value which is not supported by C. * Improve UTF-8 support in replace_string/ex() and update documentation * Add is_string_category() and update documentation * Update a little testsuite plugin (and fix linux compilation) * Add mb_strotolower/upper() and update documentation * Add mb_ucfirst() and update documentation * Add mb_strtotile() and update documentation * Improve UTF-8 support in get_players() and find_player() with name/case insenstive flags set * Fix KliPPy's complain
2017-08-05 08:32:16 +00:00
func = utf8strcasecmp;
2005-11-07 16:37:47 +00:00
else
func = strcmp;
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);
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;
2006-08-24 21:13:52 +00:00
if (pPlayer->IsBot() ? (flags & 128) : (flags & 256))
2005-09-09 03:23:31 +00:00
continue;
2005-09-16 23:48:51 +00:00
if (flags & 1)
{
if ((func)(pPlayer->name.chars(), sptemp))
2005-09-09 03:23:31 +00:00
continue;
}
2005-09-16 23:48:51 +00:00
if (flags & 2)
{
if (flags & 2048)
{
Improve UTF-8 support in some natives (bug 6475) (#407) * Compile as static library, update AMBuildScript and link to core * Update VS project files to include the library * Add UTF-8 Rewind library (v1.5.1) to third_party directory * Update ACKNOWLEDGEMENTS.txt * Move AMXX buffer in its own function * Move constants from string.inc to string_const.inc and update project files * Move stocks from string.inc to string_stocks.inc and update project files * Improve UTF-8 support in containi() and update documentation * Improve UTF-8 support in strcmp() and update documentation * Improve UTF-8 support in strfind() and update documentation Worth to be noted that this native with ignorecase set was not working properly. So broken that no one reported the issue. This adds also a safety check for "pos" parameter to not go < 0. * Improve UTF-8 support in strncmp() and update documentation * Improve UTF-8 support in equali() and update documentation * Add an option to some UTF-8 Rewind functions for avoiding invalid data to be replaced By default it replaces any invalid byte or sequence of bytes by 0xFFFD (3 bytes). It can be problematic when the input buffer is not changed (from a plugin) and that some natives need to calculate a position from the converted string. With such replacement, the position is displaced due the final string length being larger. This compiles the library as C++, because I added some silly param with a default default value which is not supported by C. * Improve UTF-8 support in replace_string/ex() and update documentation * Add is_string_category() and update documentation * Update a little testsuite plugin (and fix linux compilation) * Add mb_strotolower/upper() and update documentation * Add mb_ucfirst() and update documentation * Add mb_strtotile() and update documentation * Improve UTF-8 support in get_players() and find_player() with name/case insenstive flags set * Fix KliPPy's complain
2017-08-05 08:32:16 +00:00
if (utf8stristr(pPlayer->name.chars(), sptemp) == NULL)
2005-09-09 03:23:31 +00:00
continue;
}
else if (strstr(pPlayer->name.chars(), sptemp) == NULL)
2005-09-09 03:23:31 +00:00
continue;
}
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);
2005-11-07 16:37:47 +00:00
if (!authid || (func)(authid, sptemp))
2005-09-09 03:23:31 +00:00
continue;
}
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;
}
2005-09-16 23:48:51 +00:00
if (flags & 8)
{
if (strncmp(pPlayer->ip.chars(), sptemp, ilen))
2005-09-09 03:23:31 +00:00
continue;
}
2005-09-16 23:48:51 +00:00
if (flags & 16)
{
if ((func)(pPlayer->team.chars(), sptemp))
2005-09-09 03:23:31 +00:00
continue;
}
2005-09-09 03:23:31 +00:00
result = i;
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
}
// 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)
{
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 */
{
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);
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);
2005-09-16 23:48:51 +00:00
SET_LOCALINFO(sptemp, szValue);
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];
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-09 03:23:31 +00:00
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
2005-09-09 03:23:31 +00:00
if (!pPlayer->pEdict)
{
LogError(amx, AMX_ERR_NATIVE, "Player %d is not connected", index);
return 0;
}
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);
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];
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-09 03:23:31 +00:00
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
2005-09-09 03:23:31 +00:00
if (!pPlayer->pEdict)
{
LogError(amx, AMX_ERR_NATIVE, "Player %d is not connected", index);
return 0;
}
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);
2005-09-16 23:48:51 +00:00
ENTITY_SET_KEYVALUE(pPlayer->pEdict, sptemp, szValue);
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)
{
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 */
{
int argc = params[1];
const char *value = g_fakecmd.notify ? (argc >= 0 && argc < 3 ? g_fakecmd.argv[argc] : "") : CMD_ARGV(argc);
return set_amxstring_utf8(amx, params[2], value, strlen(value), params[3]);
}
2016-03-28 18:05:56 +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
{
return 0;
2016-03-28 18:05:56 +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 */
{
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);
2005-09-16 23:48:51 +00:00
return GET_USER_MSG_ID(PLID, sptemp, NULL);
2004-03-24 01:35:44 +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);
}
2005-09-09 03:23:31 +00:00
if (iFunc == -1)
{
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
}
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);
}
static cell AMX_NATIVE_CALL engine_changelevel(AMX *amx, cell *params)
2014-08-05 07:49:32 +00:00
{
int length;
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.
// Filling second param will call "changelevel2" command, but this is not usable in multiplayer game.
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];
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-09 03:23:31 +00:00
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
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;
2005-09-09 03:23:31 +00:00
return 1;
}
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];
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);
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;
}
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
}
int sendFakeCommand(AMX *amx, cell *params, bool send_forward = false)
2004-03-24 01:35:44 +00:00
{
enum args { arg_count, arg_index, arg_command, arg_argument1, arg_argument2 };
char command[128 * 2];
auto command_length = strncopy(command, get_amxaddr(amx, params[arg_command]), sizeof(command));
if (!command_length)
{
return 0;
}
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));
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);
2005-09-16 23:48:51 +00:00
if (pPlayer->ingame /*&& pPlayer->initialized */)
UTIL_FakeClientCommand(pPlayer->pEdict, command, pArgument1, pArgument2, send_forward);
2005-09-09 03:23:31 +00:00
}
}
else
{
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-09 03:23:31 +00:00
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
2005-09-16 23:48:51 +00:00
if (/*pPlayer->initialized && */pPlayer->ingame)
UTIL_FakeClientCommand(pPlayer->pEdict, command, pArgument1, pArgument2, send_forward);
2005-09-09 03:23:31 +00:00
}
2005-09-09 03:23:31 +00:00
return 1;
2004-03-24 01:35:44 +00:00
}
// native engclient_cmd(index, const command[], const arg1[] = "", const arg2[] = "");
static cell AMX_NATIVE_CALL engclient_cmd(AMX *amx, cell *params)
{
return sendFakeCommand(amx, params);
}
// native amxclient_cmd(index, const command[], const arg1[] = "", const arg2[] = "");
static cell AMX_NATIVE_CALL amxclient_cmd(AMX *amx, cell *params)
{
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
{
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);
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();
2005-09-09 03:23:31 +00:00
return 1;
}
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;
2005-09-16 23:48:51 +00:00
if (flags & 2)
2005-09-09 03:23:31 +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);
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);
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]);
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];
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;
}
2005-09-09 03:23:31 +00:00
int id = params[2];
2005-09-16 23:48:51 +00:00
if (id < 0)
id = 0;
2005-09-16 23:48:51 +00:00
if (id > 31)
id = 31;
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];
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;
}
2005-09-09 03:23:31 +00:00
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
int flag = params[2];
int id = params[3];
2005-09-16 23:48:51 +00:00
if (id < 0)
id = 0;
2005-09-16 23:48:51 +00:00
if (id > 31)
id = 31;
2005-09-09 03:23:31 +00:00
pPlayer->flags[id] |= flag;
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];
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;
}
2005-09-09 03:23:31 +00:00
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
int flag = params[2];
int id = params[3];
2005-09-16 23:48:51 +00:00
if (id < 0)
id = 0;
2005-09-16 23:48:51 +00:00
if (id > 31)
id = 31;
2005-09-09 03:23:31 +00:00
pPlayer->flags[id] &= ~flag;
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;
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];
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
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);
2005-09-16 23:48:51 +00:00
if (pPlayer->ingame)
{
2005-11-13 20:33:30 +00:00
if (gpGlobals->time > pPlayer->menuexpire)
{
if (Menu *pMenu = get_menu_by_id(pPlayer->newmenu))
pMenu->Close(pPlayer->index);
else
pPlayer->menu = 0;
2005-11-13 20:33:30 +00:00
*cpMenu = 0;
*cpKeys = 0;
2005-11-13 20:33:30 +00:00
return 0;
}
2005-09-09 03:23:31 +00:00
*cpMenu = pPlayer->menu;
*cpKeys = pPlayer->keys;
2005-09-09 03:23:31 +00:00
return 1;
}
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)
{
LogError(amx, AMX_ERR_NATIVE, "Precaching not allowed");
2005-09-09 03:23:31 +00:00
return 0;
}
int len;
char* sptemp = get_amxstring(amx, params[1], 0, len);
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)
{
LogError(amx, AMX_ERR_NATIVE, "Precaching not allowed");
2005-09-09 03:23:31 +00:00
return 0;
}
int len;
char* sptemp = get_amxstring(amx, params[1], 0, len);
2005-09-09 03:23:31 +00:00
return PRECACHE_MODEL((char*)STRING(ALLOC_STRING(sptemp)));
2004-03-24 01:35:44 +00:00
}
static cell AMX_NATIVE_CALL precache_generic(AMX *amx, cell *params)
2004-03-24 01:35:44 +00:00
{
if (g_dontprecache)
{
LogError(amx, AMX_ERR_NATIVE, "Precaching not allowed");
return 0;
}
int len;
char* sptemp = get_amxstring(amx, params[1], 0, len);
return PRECACHE_GENERIC((char*)STRING(ALLOC_STRING(sptemp)));
}
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);
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]);
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;
2005-09-16 23:48:51 +00:00
while (*temp++)
++len; // get length
2005-09-09 03:23:31 +00:00
cell *src = text;
2005-09-16 23:48:51 +00:00
if (src[len-1] == '\r')
2005-09-09 03:23:31 +00:00
src[--len] = 0;
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++));
2005-09-09 03:23:31 +00:00
return 1;
}
}
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];
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-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]);
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;
2005-09-09 03:23:31 +00:00
Vector v_forward;
Vector v_src = edict->v.origin + edict->v.view_ofs;
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);
2005-09-09 03:23:31 +00:00
*cpId = FNullEnt(trEnd.pHit) ? 0 : ENTINDEX(trEnd.pHit);
*cpBody = trEnd.iHitgroup;
2005-09-16 23:48:51 +00:00
if (trEnd.flFraction < 1.0)
{
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
}
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;
2005-09-16 23:48:51 +00:00
cell *cpVec1 = get_amxaddr(amx, params[2]);
cell *cpVec2 = get_amxaddr(amx, params[3]);
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]);
2005-09-16 23:48:51 +00:00
char* filename = get_amxstring(amx, params[4], 0, a);
auto object = ke::AutoPtr<ForceObject>(new ForceObject(filename, (FORCE_TYPE)((int)(params[1])), vec1, vec2, amx));
2005-09-16 23:48:51 +00:00
if (object)
2005-09-16 23:48:51 +00:00
{
auto forceObjVec = &g_forcegeneric;
2005-09-16 23:48:51 +00:00
if (stristr(filename, ".wav"))
forceObjVec = &g_forcesounds;
2005-09-16 23:48:51 +00:00
else if (stristr(filename, ".mdl"))
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)
{
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)
{
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);
2005-09-16 23:48:51 +00:00
if (len < 6) // no user to parse!?
{
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;
2005-09-16 23:48:51 +00:00
while (*end != '<' && len--)
2005-09-09 03:23:31 +00:00
--end;
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);
2005-09-16 23:48:51 +00:00
while (max-- && *end)
2005-09-09 03:23:31 +00:00
*cPtr++ = *end++;
2005-09-09 03:23:31 +00:00
*cPtr = 0;
2005-09-09 03:23:31 +00:00
/******** GET AUTHID **********/
2005-09-16 23:48:51 +00:00
if (len <= 0)
{
LogError(amx, AMX_ERR_NATIVE, "No Authid found");
2005-09-09 03:23:31 +00:00
return 0;
}
2005-09-09 03:23:31 +00:00
end = text + --len;
*end = 0;
2005-09-16 23:48:51 +00:00
while (*end != '<' && len--)
2005-09-09 03:23:31 +00:00
--end;
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);
2005-09-16 23:48:51 +00:00
while (max-- && *end)
2005-09-09 03:23:31 +00:00
*cPtr++ = *end++;
2005-09-09 03:23:31 +00:00
*cPtr = 0;
2005-09-09 03:23:31 +00:00
/******** GET USERID **********/
2005-09-16 23:48:51 +00:00
if (len <= 0)
{
LogError(amx, AMX_ERR_NATIVE, "No Userid found");
2005-09-09 03:23:31 +00:00
return 0;
}
2005-09-09 03:23:31 +00:00
end = text + --len;
*end = 0;
2005-09-16 23:48:51 +00:00
while (*end != '<' && len--)
2005-09-09 03:23:31 +00:00
--end;
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);
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);
2005-09-16 23:48:51 +00:00
while (max-- && *text)
2005-09-09 03:23:31 +00:00
*cPtr++ = *text++;
2005-09-09 03:23:31 +00:00
*cPtr = 0;
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);
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;
for (auto module : g_modules)
2004-03-24 01:35:44 +00:00
{
if (!stricmp(module->getName(), name))
2004-03-24 01:35:44 +00:00
return id;
2004-03-24 01:35:44 +00:00
++id;
}
2004-03-24 01:35:44 +00:00
return -1;
}
// native is_plugin_loaded(const name[]);
// 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;
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
{
// searching for registered plugin name
for (CPluginMngr::iterator iter = g_plugins.begin(); iter; ++iter)
{
if (stricmp((*iter).getTitle(), name) == 0)
return id;
++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;
++id;
}
2004-03-24 01:35:44 +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)
{
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];
for (auto module : g_modules)
{
if (i--)
{
continue;
}
2004-03-24 01:35:44 +00:00
// set name, author, version
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]);
// compatibility problem possible
int numParams = params[0] / sizeof(cell);
2004-03-24 01:35:44 +00:00
if (numParams < 8)
{
LogError(amx, AMX_ERR_NATIVE, "Call to incompatible version");
return 0;
}
2004-03-24 01:35:44 +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
*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);
AMXXLOG_Log("[%s] %s", plugin->getName(), format_amxstring(amx, params, 1, len));
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
cell *alloc; // allocated block
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);
2004-03-24 01:35:44 +00:00
if (g_CallFunc_Plugin)
{
// scripter's fault
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;
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;
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
}
// native callfunc_begin_i(funcId, pluginId = -1)
static cell AMX_NATIVE_CALL callfunc_begin_i(AMX *amx, cell *params)
{
CPluginMngr::CPlugin *plugin;
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;
}
if (!plugin->isExecutable(params[1]))
return -2;
2005-09-09 03:23:31 +00:00
g_CallFunc_Plugin = plugin;
g_CallFunc_Func = params[1];
2006-03-30 20:45:22 +00:00
g_CallFunc_CurParam = 0;
return 1;
}
// native get_func_id(funcName[], pluginId = -1)
static cell AMX_NATIVE_CALL get_func_id(AMX *amx, cell *params)
{
CPluginMngr::CPlugin *plugin;
if (params[2] < 0)
{
plugin = g_plugins.findPluginFast(amx);
} else {
plugin = g_plugins.findPlugin(params[2]);
}
if (!plugin)
{
return -1;
}
if (!plugin->isValid())
{
return -1;
}
2005-09-09 03:23:31 +00:00
int len;
const char *funcName = get_amxstring(amx, params[1], 0, len);
int index, err;
2005-09-16 23:48:51 +00:00
if ((err = amx_FindPublic(plugin->getAMX(), funcName, &index)) != AMX_ERR_NONE)
{
index = -1;
}
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);
2004-03-24 01:35:44 +00:00
if (!g_CallFunc_Plugin)
{
// scripter's fault
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();
Debugger *pDebugger = (Debugger *)pAmx->userdata[UD_DEBUGGER];
if (pDebugger)
{
pDebugger->BeginExec();
}
// 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]];
}
}
2004-03-24 01:35:44 +00:00
// actual call
// Pawn - push parameters in reverse order
2005-09-16 23:48:51 +00:00
for (int i = curParam - 1; i >= 0; i--)
{
2005-07-29 06:12:23 +00:00
amx_Push(pAmx, gparams[i]);
}
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)
{
2005-09-26 22:11:44 +00:00
pDebugger->EndExec();
}
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();
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 **/
(amxCaller->data ? amxCaller->data : (amxCaller->base + hdrCaller->dat)) + gparamInfo[i].byrefAddr,
/** SOURCE ADDR **/
(amxCalled->data ? amxCalled->data : (amxCalled->base + hdrCalled->dat)) + gparams[i],
/** 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
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)
{
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);
2004-03-24 01:35:44 +00:00
if (!g_CallFunc_Plugin)
{
// scripter's fault
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)
{
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;
g_CallFunc_ParamInfo[g_CallFunc_CurParam].alloc = NULL;
g_CallFunc_ParamInfo[g_CallFunc_CurParam].copyback = true;
g_CallFunc_Params[g_CallFunc_CurParam++] = i; /* referenced parameter */
2004-03-24 01:35:44 +00:00
return 0;
}
}
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;
g_CallFunc_ParamInfo[g_CallFunc_CurParam].alloc = phys_addr;
g_CallFunc_ParamInfo[g_CallFunc_CurParam].copyback = true;
g_CallFunc_Params[g_CallFunc_CurParam++] = 0;
return 0;
}
// native callfunc_push_array(array[], size, [copyback])
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;
g_CallFunc_ParamInfo[g_CallFunc_CurParam].copyback = g_CallFunc_ParamInfo[i].copyback;
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;
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;
}
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
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)
{
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;
g_CallFunc_ParamInfo[g_CallFunc_CurParam].alloc = NULL;
g_CallFunc_ParamInfo[g_CallFunc_CurParam].copyback = g_CallFunc_ParamInfo[i].copyback;
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);
2004-03-24 01:35:44 +00:00
// allocate enough memory for the string
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
// :NOTE: 4th parameter use_wchar since Small Abstract Machine 2.5.0
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;
g_CallFunc_ParamInfo[g_CallFunc_CurParam].alloc = phys_addr;
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;
}
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;
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
{
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
{
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
}
else
{
CPluginMngr::CPlugin* a = g_plugins.findPlugin((int)params[2]);
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
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;
}
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;
}
static cell AMX_NATIVE_CALL int3(AMX *amx, cell *params)
{
#if defined _DEBUG || defined DEBUG
#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);
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);
if (!FindLibrary(module, LibType_Library))
return FindLibrary(module, LibType_Class);
2005-09-11 04:43:40 +00:00
return true;
}
2005-09-11 04:43:40 +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
return FindLibrary(library, static_cast<LibType>(params[2]));
2005-09-11 04:43:40 +00:00
}
static cell AMX_NATIVE_CALL set_fail_state(AMX *amx, cell *params)
{
int len;
char* str;
g_langMngr.SetDefLang(LANG_SERVER); // Default language = server
if (params[0] / sizeof(cell) > 1)
str = format_amxstring(amx, params, 1, len);
else
str = get_amxstring(amx, params[1], 0, len);
CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(amx);
pPlugin->setStatus(ps_error);
pPlugin->setError(str);
AMXXLOG_Error("[AMXX] Plugin (\"%s\") is setting itself as failed.", pPlugin->getName());
AMXXLOG_Error("[AMXX] Plugin says: %s", str);
LogError(amx, AMX_ERR_EXIT, NULL);
//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)
{
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)
{
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
}
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
}
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]);
int len, err;
cell *addr = get_amxaddr(amx, params[2]);
2006-02-01 12:08:42 +00:00
if (!g_forwards.isIdValid(id))
return 0;
struct allot_info
{
cell amx_addr;
cell *phys_addr;
};
2006-02-01 12:08:42 +00:00
cell ps[FORWARD_MAX_PARAMS];
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)
{
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-02-01 12:08:42 +00:00
}
*addr = g_forwards.executeForwards(id, ps);
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;
}
ke::Vector<cell *> g_hudsync;
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));
g_hudsync.append(p);
return static_cast<cell>(g_hudsync.length());
}
void CheckAndClearPlayerHUD(CPlayer *player, int &channel, unsigned int sync_obj)
{
/**
* 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
if ((unsigned int)player->hudmap[last_channel] == sync_obj + 1)
{
//if so, we can safely REUSE it
channel = (int)last_channel;
}
//set the new states
plist[player->index] = channel;
2006-02-28 10:42:52 +00:00
player->hudmap[channel] = sync_obj + 1;
}
2006-03-01 02:20:44 +00:00
static cell AMX_NATIVE_CALL ClearSyncHud(AMX *amx, cell *params)
{
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;
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;
}
g_langMngr.SetDefLang(params[1]);
2006-03-01 02:20:44 +00:00
if (index == 0)
{
for (int i = 1; i <= gpGlobals->maxClients; ++i)
2006-03-01 02:20:44 +00:00
{
CPlayer *pPlayer = GET_PLAYER_POINTER_I(i);
2006-03-01 02:20:44 +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-01 02:20:44 +00:00
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
2006-03-01 02:20:44 +00:00
if (pPlayer->ingame)
{
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
}
}
return len;
2006-03-01 02:20:44 +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;
if (sync_obj >= g_hudsync.length())
{
LogError(amx, AMX_ERR_NATIVE, "HudSyncObject %d is invalid", sync_obj);
return 0;
}
g_langMngr.SetDefLang(params[1]);
if (index == 0)
{
for (int i = 1; i <= gpGlobals->maxClients; ++i)
{
CPlayer *pPlayer = GET_PLAYER_POINTER_I(i);
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;
2006-03-01 00:10:23 +00:00
message = UTIL_SplitHudMessage(format_amxstring(amx, params, 3, len));
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;
}
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
if (pPlayer->ingame)
{
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));
UTIL_HudMessage(pPlayer->pEdict, g_hudset, message);
}
}
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;
}
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);
2017-06-28 16:31:59 +00:00
if (key_index != -1)
{
2017-06-28 16:31:59 +00:00
return key_index;
}
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];
const char *phrase = get_amxstring(amx, params[3], 1, len);
ke::Vector<sKeyDef> queue;
sKeyDef def;
def.definition = new ke::AutoString(phrase);
2017-06-28 16:31:59 +00:00
def.key = key_index;
queue.append(def);
g_langMngr.MergeDefinitions(lang, queue);
return 1;
}
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);
}
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;
TempData->SetAuthID(get_amxaddr(amx,params[1]));
TempData->SetPass(get_amxaddr(amx,params[2]));
TempData->SetAccess(params[3]);
TempData->SetFlags(params[4]);
DynamicAdmins.append(TempData);
return 0;
};
static cell AMX_NATIVE_CALL admins_flush(AMX *amx, cell *params)
{
// admins_flush();
size_t iter=DynamicAdmins.length();
while (iter--)
{
delete DynamicAdmins[iter];
}
DynamicAdmins.clear();
return 0;
};
static cell AMX_NATIVE_CALL admins_num(AMX *amx, cell *params)
{
// admins_num();
return static_cast<cell>(DynamicAdmins.length());
};
static cell AMX_NATIVE_CALL admins_lookup(AMX *amx, cell *params)
{
// admins_lookup(Num, Property, Buffer[]={0}, BufferSize=-1);
if (params[1]>=static_cast<int>(DynamicAdmins.length()))
{
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;
};
// 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);
const char *def=translate(amx, playerlang(*get_amxaddr(amx, params[4])),key);
if (def==NULL)
{
return 0;
}
set_amxstring(amx,params[1],def,params[2]);
return 1;
};
// SetGlobalTransTarget(client)
static cell AMX_NATIVE_CALL SetGlobalTransTarget(AMX *amx, cell *params)
{
g_langMngr.SetDefLang(params[1]);
return 1;
};
// 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));
};
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];
ke::SafeSprintf(newName, sizeof(newName), "plugin-%s", pluginName);
name = newName;
}
plugin->AddConfig(autocreate, name, folder);
return 1;
}
//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},
{"admins_flush", admins_flush},
{"admins_lookup", admins_lookup},
{"admins_num", admins_num},
{"admins_push", admins_push},
{"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},
{"callfunc_push_array", callfunc_push_array},
2006-02-01 12:08:42 +00:00
{"change_task", change_task},
{"engine_changelevel", engine_changelevel},
2005-09-11 03:58:38 +00:00
{"client_cmd", client_cmd},
{"client_print", client_print},
{"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},
{"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},
{"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},
{"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},
{"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},
{"hash_string", amx_hash_string},
{"hash_file", amx_hash_file},
2005-09-11 04:43:40 +00:00
{"module_exists", module_exists},
{"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},
{"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},
{"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},
{"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},
{"set_fail_state", set_fail_state},
{"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},
{"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},
{"AddTranslation", AddTranslation},
2006-03-01 02:20:44 +00:00
{"ClearSyncHud", ClearSyncHud},
{"CreateHudSyncObj", CreateHudSyncObj},
{"CreateLangKey", CreateLangKey},
2006-02-01 12:08:42 +00:00
{"CreateMultiForward", CreateMultiForward},
{"CreateOneForward", CreateOneForward},
{"DestroyForward", DestroyForward},
{"ExecuteForward", ExecuteForward},
{"GetLangTransKey", GetLangTransKey},
2006-08-24 21:13:52 +00:00
{"LibraryExists", LibraryExists},
{"LookupLangKey", LookupLangKey},
{"SetGlobalTransTarget", SetGlobalTransTarget},
{"PrepareArray", PrepareArray},
{"ShowSyncHudMsg", ShowSyncHudMsg},
{"AutoExecConfig", AutoExecConfig},
{"RequestFrame", RequestFrame},
2005-09-11 03:58:38 +00:00
{NULL, NULL}
2004-03-24 01:35:44 +00:00
};