2004-03-05 21:03:14 +00:00
|
|
|
/* AMX Mod X
|
|
|
|
*
|
|
|
|
* by the AMX Mod X Development Team
|
|
|
|
* originally developed by OLO
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License as published by the
|
|
|
|
* Free Software Foundation; either version 2 of the License, or (at
|
|
|
|
* your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2005-09-16 23:48:51 +00:00
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
2004-03-05 21:03:14 +00:00
|
|
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*
|
|
|
|
* In addition, as a special exception, the author gives permission to
|
|
|
|
* link the code of this program with the Half-Life Game Engine ("HL
|
2005-09-16 23:48:51 +00:00
|
|
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
2004-03-05 21:03:14 +00:00
|
|
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
|
|
|
* respects for all of the code used other than the HL Engine and MODs
|
|
|
|
* from Valve. If you modify this file, you may extend this exception
|
|
|
|
* to your version of the file, but you are not obligated to do so. If
|
|
|
|
* you do not wish to do so, delete this exception statement from your
|
|
|
|
* version.
|
|
|
|
*/
|
2004-01-31 20:56:22 +00:00
|
|
|
|
2004-03-24 01:35:44 +00:00
|
|
|
#include "amxmodx.h"
|
2005-09-09 03:23:31 +00:00
|
|
|
#include "debugger.h"
|
2006-03-16 06:36:01 +00:00
|
|
|
#include "binlog.h"
|
2005-07-26 21:31:21 +00:00
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
CForward::CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam *paramTypes)
|
|
|
|
{
|
|
|
|
m_FuncName = name;
|
|
|
|
m_ExecType = et;
|
|
|
|
m_NumParams = numParams;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
memcpy((void *)m_ParamTypes, paramTypes, numParams * sizeof(ForwardParam));
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
// find funcs
|
|
|
|
int func;
|
2004-06-30 08:04:12 +00:00
|
|
|
m_Funcs.clear();
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
for (CPluginMngr::iterator iter = g_plugins.begin(); iter; ++iter)
|
|
|
|
{
|
2004-05-29 12:22:33 +00:00
|
|
|
if ((*iter).isValid() && amx_FindPublic((*iter).getAMX(), name, &func) == AMX_ERR_NONE)
|
2004-04-03 19:14:03 +00:00
|
|
|
{
|
2004-07-03 13:45:56 +00:00
|
|
|
AMXForward tmp;
|
|
|
|
tmp.pPlugin = &(*iter);
|
|
|
|
tmp.func = func;
|
2004-06-30 08:04:12 +00:00
|
|
|
m_Funcs.push_back(tmp);
|
2004-04-03 19:14:03 +00:00
|
|
|
}
|
2004-01-31 20:56:22 +00:00
|
|
|
}
|
2006-05-06 02:03:25 +00:00
|
|
|
|
|
|
|
m_Name.assign(name);
|
2004-01-31 20:56:22 +00:00
|
|
|
}
|
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
2004-01-31 20:56:22 +00:00
|
|
|
{
|
2004-04-03 19:14:03 +00:00
|
|
|
cell realParams[FORWARD_MAX_PARAMS];
|
|
|
|
cell *physAddrs[FORWARD_MAX_PARAMS];
|
|
|
|
|
2004-04-07 04:06:55 +00:00
|
|
|
const int STRINGEX_MAXLENGTH = 128;
|
2004-04-03 19:14:03 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
cell globRetVal = 0;
|
2004-01-31 20:56:22 +00:00
|
|
|
|
2004-07-03 13:45:56 +00:00
|
|
|
AMXForwardList::iterator iter;
|
2004-06-30 08:04:12 +00:00
|
|
|
|
|
|
|
for (iter = m_Funcs.begin(); iter != m_Funcs.end(); iter++)
|
2004-01-31 20:56:22 +00:00
|
|
|
{
|
2004-07-03 13:45:56 +00:00
|
|
|
if (iter->pPlugin->isExecutable(iter->func))
|
2004-01-31 20:56:22 +00:00
|
|
|
{
|
2005-07-26 21:31:21 +00:00
|
|
|
// Get debug info
|
|
|
|
AMX *amx = (*iter).pPlugin->getAMX();
|
2005-09-09 03:23:31 +00:00
|
|
|
Debugger *pDebugger = (Debugger *)amx->userdata[UD_DEBUGGER];
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
if (pDebugger)
|
|
|
|
pDebugger->BeginExec();
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
// handle strings & arrays
|
2006-08-17 16:43:47 +00:00
|
|
|
int i;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
for (i = 0; i < m_NumParams; ++i)
|
|
|
|
{
|
|
|
|
if (m_ParamTypes[i] == FP_STRING || m_ParamTypes[i] == FP_STRINGEX)
|
|
|
|
{
|
2006-02-05 00:32:20 +00:00
|
|
|
const char *str = reinterpret_cast<const char*>(params[i]);
|
2004-04-03 19:14:03 +00:00
|
|
|
cell *tmp;
|
2006-02-05 00:32:20 +00:00
|
|
|
if (!str)
|
|
|
|
str = "";
|
|
|
|
amx_Allot(iter->pPlugin->getAMX(), (m_ParamTypes[i] == FP_STRING) ? strlen(str) + 1 : STRINGEX_MAXLENGTH, &realParams[i], &tmp);
|
|
|
|
amx_SetStringOld(tmp, str, 0, 0);
|
2004-04-03 19:14:03 +00:00
|
|
|
physAddrs[i] = tmp;
|
|
|
|
}
|
|
|
|
else if (m_ParamTypes[i] == FP_ARRAY)
|
|
|
|
{
|
|
|
|
cell *tmp;
|
2005-09-16 23:48:51 +00:00
|
|
|
amx_Allot(amx, preparedArrays[params[i]].size, &realParams[i], &tmp);
|
2004-04-03 19:14:03 +00:00
|
|
|
physAddrs[i] = tmp;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
if (preparedArrays[params[i]].type == Type_Cell)
|
|
|
|
{
|
|
|
|
memcpy(tmp, preparedArrays[params[i]].ptr, preparedArrays[params[i]].size * sizeof(cell));
|
2005-09-16 23:48:51 +00:00
|
|
|
} else {
|
2004-04-03 19:14:03 +00:00
|
|
|
char *data = (char*)preparedArrays[params[i]].ptr;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
|
|
|
*tmp++ = (static_cast<cell>(*data++)) & 0xFF;
|
|
|
|
}
|
2005-09-16 23:48:51 +00:00
|
|
|
} else {
|
2004-04-03 19:14:03 +00:00
|
|
|
realParams[i] = params[i];
|
|
|
|
}
|
|
|
|
}
|
2005-09-16 23:48:51 +00:00
|
|
|
|
|
|
|
//Push the parameters in reverse order. Weird, unfriendly part of Small 3.0!
|
|
|
|
for (i = m_NumParams-1; i >= 0; i--)
|
2005-07-25 06:03:43 +00:00
|
|
|
{
|
2005-07-26 21:31:21 +00:00
|
|
|
amx_Push(amx, realParams[i]);
|
2005-07-25 06:03:43 +00:00
|
|
|
}
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
// exec
|
|
|
|
cell retVal;
|
2006-03-16 06:36:01 +00:00
|
|
|
#if defined BINLOG_ENABLED
|
|
|
|
g_BinLog.WriteOp(BinLog_CallPubFunc, (*iter).pPlugin->getId(), iter->func);
|
|
|
|
#endif
|
2005-07-26 21:31:21 +00:00
|
|
|
int err = amx_Exec(amx, &retVal, iter->func);
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-06-10 13:19:41 +00:00
|
|
|
// log runtime error, if any
|
|
|
|
if (err != AMX_ERR_NONE)
|
2005-07-26 21:31:21 +00:00
|
|
|
{
|
|
|
|
//Did something else set an error?
|
2005-09-09 03:23:31 +00:00
|
|
|
if (pDebugger && pDebugger->ErrorExists())
|
2005-07-26 21:31:21 +00:00
|
|
|
{
|
|
|
|
//we don't care, something else logged the error.
|
2005-09-16 23:48:51 +00:00
|
|
|
}
|
|
|
|
else if (err != -1)
|
|
|
|
{
|
2005-07-26 21:31:21 +00:00
|
|
|
//nothing logged the error so spit it out anyway
|
2005-09-09 03:23:31 +00:00
|
|
|
LogError(amx, err, NULL);
|
2005-07-26 21:31:21 +00:00
|
|
|
}
|
|
|
|
}
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2005-07-26 21:31:21 +00:00
|
|
|
amx->error = AMX_ERR_NONE;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
if (pDebugger)
|
|
|
|
pDebugger->EndExec();
|
2004-06-10 13:19:41 +00:00
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
// cleanup strings & arrays
|
|
|
|
for (i = 0; i < m_NumParams; ++i)
|
|
|
|
{
|
|
|
|
if (m_ParamTypes[i] == FP_STRING)
|
|
|
|
{
|
2004-07-03 13:45:56 +00:00
|
|
|
amx_Release(iter->pPlugin->getAMX(), realParams[i]);
|
2004-04-03 19:14:03 +00:00
|
|
|
}
|
|
|
|
else if (m_ParamTypes[i] == FP_STRINGEX)
|
|
|
|
{
|
|
|
|
// copy back
|
2005-07-25 06:03:43 +00:00
|
|
|
amx_GetStringOld(reinterpret_cast<char*>(params[i]), physAddrs[i], 0);
|
2004-07-03 13:45:56 +00:00
|
|
|
amx_Release(iter->pPlugin->getAMX(), realParams[i]);
|
2004-04-03 19:14:03 +00:00
|
|
|
}
|
|
|
|
else if (m_ParamTypes[i] == FP_ARRAY)
|
|
|
|
{
|
|
|
|
// copy back
|
2004-09-18 13:33:21 +00:00
|
|
|
if (preparedArrays[params[i]].copyBack)
|
2004-04-03 19:14:03 +00:00
|
|
|
{
|
2004-09-18 13:33:21 +00:00
|
|
|
cell *tmp = physAddrs[i];
|
|
|
|
if (preparedArrays[params[i]].type == Type_Cell)
|
|
|
|
{
|
|
|
|
memcpy(preparedArrays[params[i]].ptr, tmp, preparedArrays[params[i]].size * sizeof(cell));
|
2005-09-16 23:48:51 +00:00
|
|
|
} else {
|
2004-09-18 13:33:21 +00:00
|
|
|
char *data = (char*)preparedArrays[params[i]].ptr;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-09-18 13:33:21 +00:00
|
|
|
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
|
|
|
*data++ = static_cast<char>(*tmp++ & 0xFF);
|
|
|
|
}
|
2004-04-03 19:14:03 +00:00
|
|
|
}
|
2004-09-19 09:32:52 +00:00
|
|
|
amx_Release(iter->pPlugin->getAMX(), realParams[i]);
|
2004-04-03 19:14:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// decide what to do (based on exectype and retval)
|
|
|
|
switch (m_ExecType)
|
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
case ET_IGNORE:
|
|
|
|
break;
|
|
|
|
case ET_STOP:
|
|
|
|
if (retVal > 0)
|
|
|
|
return retVal;
|
|
|
|
case ET_STOP2:
|
|
|
|
if (retVal == 1)
|
|
|
|
return 1;
|
|
|
|
else if (retVal > globRetVal)
|
|
|
|
globRetVal = retVal;
|
|
|
|
break;
|
|
|
|
case ET_CONTINUE:
|
|
|
|
if (retVal > globRetVal)
|
|
|
|
globRetVal = retVal;
|
|
|
|
break;
|
2004-04-03 19:14:03 +00:00
|
|
|
}
|
2004-01-31 20:56:22 +00:00
|
|
|
}
|
|
|
|
}
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
return globRetVal;
|
|
|
|
}
|
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
void CSPForward::Set(int func, AMX *amx, int numParams, const ForwardParam *paramTypes)
|
|
|
|
{
|
2006-05-06 02:03:25 +00:00
|
|
|
char name[sNAMEMAX];
|
2004-05-05 18:42:16 +00:00
|
|
|
m_Func = func;
|
|
|
|
m_Amx = amx;
|
|
|
|
m_NumParams = numParams;
|
|
|
|
memcpy((void *)m_ParamTypes, paramTypes, numParams * sizeof(ForwardParam));
|
|
|
|
m_HasFunc = true;
|
2004-09-07 05:43:55 +00:00
|
|
|
isFree = false;
|
2006-05-06 02:03:25 +00:00
|
|
|
name[0] = '\0';
|
|
|
|
amx_GetPublic(amx, func, name);
|
|
|
|
m_Name.assign(name);
|
2004-05-05 18:42:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CSPForward::Set(const char *funcName, AMX *amx, int numParams, const ForwardParam *paramTypes)
|
|
|
|
{
|
|
|
|
m_Amx = amx;
|
|
|
|
m_NumParams = numParams;
|
|
|
|
memcpy((void *)m_ParamTypes, paramTypes, numParams * sizeof(ForwardParam));
|
|
|
|
m_HasFunc = (amx_FindPublic(amx, funcName, &m_Func) == AMX_ERR_NONE);
|
2004-09-07 05:43:55 +00:00
|
|
|
isFree = false;
|
2006-05-06 02:03:25 +00:00
|
|
|
m_Name.assign(funcName);
|
2004-05-05 18:42:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
|
|
|
{
|
2004-09-07 05:43:55 +00:00
|
|
|
if (isFree)
|
|
|
|
return 0;
|
2004-09-18 13:33:21 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
const int STRINGEX_MAXLENGTH = 128;
|
|
|
|
|
|
|
|
cell realParams[FORWARD_MAX_PARAMS];
|
|
|
|
cell *physAddrs[FORWARD_MAX_PARAMS];
|
|
|
|
|
|
|
|
if (!m_HasFunc)
|
|
|
|
return 0;
|
2004-09-09 20:32:34 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(m_Amx);
|
|
|
|
if (!pPlugin->isExecutable(m_Func))
|
|
|
|
return 0;
|
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
Debugger *pDebugger = (Debugger *)m_Amx->userdata[UD_DEBUGGER];
|
|
|
|
if (pDebugger)
|
|
|
|
pDebugger->BeginExec();
|
2005-07-26 21:31:21 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
// handle strings & arrays
|
|
|
|
int i;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
for (i = 0; i < m_NumParams; ++i)
|
|
|
|
{
|
|
|
|
if (m_ParamTypes[i] == FP_STRING || m_ParamTypes[i] == FP_STRINGEX)
|
|
|
|
{
|
2006-02-05 00:32:20 +00:00
|
|
|
const char *str = reinterpret_cast<const char*>(params[i]);
|
|
|
|
if (!str)
|
|
|
|
str = "";
|
2004-05-05 18:42:16 +00:00
|
|
|
cell *tmp;
|
2006-02-05 00:32:20 +00:00
|
|
|
amx_Allot(m_Amx, (m_ParamTypes[i] == FP_STRING) ? strlen(str) + 1 : STRINGEX_MAXLENGTH, &realParams[i], &tmp);
|
|
|
|
amx_SetStringOld(tmp, str, 0, 0);
|
2004-05-05 18:42:16 +00:00
|
|
|
physAddrs[i] = tmp;
|
|
|
|
}
|
|
|
|
else if (m_ParamTypes[i] == FP_ARRAY)
|
|
|
|
{
|
|
|
|
cell *tmp;
|
2005-09-16 23:48:51 +00:00
|
|
|
amx_Allot(m_Amx, preparedArrays[params[i]].size, &realParams[i], &tmp);
|
2004-05-05 18:42:16 +00:00
|
|
|
physAddrs[i] = tmp;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
if (preparedArrays[params[i]].type == Type_Cell)
|
|
|
|
{
|
|
|
|
memcpy(tmp, preparedArrays[params[i]].ptr, preparedArrays[params[i]].size * sizeof(cell));
|
2005-09-16 23:48:51 +00:00
|
|
|
} else {
|
2004-05-05 18:42:16 +00:00
|
|
|
char *data = (char*)preparedArrays[params[i]].ptr;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
|
|
|
*tmp++ = (static_cast<cell>(*data++)) & 0xFF;
|
|
|
|
}
|
2005-09-16 23:48:51 +00:00
|
|
|
} else {
|
2004-05-05 18:42:16 +00:00
|
|
|
realParams[i] = params[i];
|
|
|
|
}
|
|
|
|
}
|
2005-09-16 23:48:51 +00:00
|
|
|
|
|
|
|
for (i = m_NumParams - 1; i >= 0; i--)
|
2005-07-25 06:03:43 +00:00
|
|
|
amx_Push(m_Amx, realParams[i]);
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
// exec
|
|
|
|
cell retVal;
|
2006-03-16 06:36:01 +00:00
|
|
|
#if defined BINLOG_ENABLED
|
|
|
|
g_BinLog.WriteOp(BinLog_CallPubFunc, pPlugin->getId(), m_Func);
|
|
|
|
#endif
|
2005-07-25 06:03:43 +00:00
|
|
|
int err = amx_Exec(m_Amx, &retVal, m_Func);
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-11-04 21:55:14 +00:00
|
|
|
if (err != AMX_ERR_NONE)
|
2005-07-26 21:31:21 +00:00
|
|
|
{
|
|
|
|
//Did something else set an error?
|
2005-09-09 03:23:31 +00:00
|
|
|
if (pDebugger && pDebugger->ErrorExists())
|
2005-07-26 21:31:21 +00:00
|
|
|
{
|
|
|
|
//we don't care, something else logged the error.
|
2005-09-16 23:48:51 +00:00
|
|
|
}
|
|
|
|
else if (err != -1)
|
|
|
|
{
|
2005-07-26 21:31:21 +00:00
|
|
|
//nothing logged the error so spit it out anyway
|
2005-09-09 03:23:31 +00:00
|
|
|
LogError(m_Amx, err, NULL);
|
2005-07-26 21:31:21 +00:00
|
|
|
}
|
|
|
|
}
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2005-09-09 03:23:31 +00:00
|
|
|
if (pDebugger)
|
|
|
|
pDebugger->EndExec();
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2005-07-26 21:31:21 +00:00
|
|
|
m_Amx->error = AMX_ERR_NONE;
|
2004-05-05 18:42:16 +00:00
|
|
|
|
|
|
|
// cleanup strings & arrays
|
|
|
|
for (i = 0; i < m_NumParams; ++i)
|
|
|
|
{
|
|
|
|
if (m_ParamTypes[i] == FP_STRING)
|
|
|
|
{
|
|
|
|
amx_Release(m_Amx, realParams[i]);
|
|
|
|
}
|
|
|
|
else if (m_ParamTypes[i] == FP_STRINGEX)
|
|
|
|
{
|
|
|
|
// copy back
|
2005-07-25 06:03:43 +00:00
|
|
|
amx_GetStringOld(reinterpret_cast<char*>(params[i]), physAddrs[i], 0);
|
2004-05-05 18:42:16 +00:00
|
|
|
amx_Release(m_Amx, realParams[i]);
|
|
|
|
}
|
|
|
|
else if (m_ParamTypes[i] == FP_ARRAY)
|
|
|
|
{
|
|
|
|
// copy back
|
2004-09-18 13:33:21 +00:00
|
|
|
if (preparedArrays[params[i]].copyBack)
|
2004-05-05 18:42:16 +00:00
|
|
|
{
|
2004-09-18 13:33:21 +00:00
|
|
|
cell *tmp = physAddrs[i];
|
|
|
|
if (preparedArrays[params[i]].type == Type_Cell)
|
|
|
|
{
|
|
|
|
memcpy(preparedArrays[params[i]].ptr, tmp, preparedArrays[params[i]].size * sizeof(cell));
|
2005-09-16 23:48:51 +00:00
|
|
|
} else {
|
2004-09-18 13:33:21 +00:00
|
|
|
char *data = (char*)preparedArrays[params[i]].ptr;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-09-18 13:33:21 +00:00
|
|
|
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
|
|
|
*data++ = static_cast<char>(*tmp++ & 0xFF);
|
|
|
|
}
|
2004-05-05 18:42:16 +00:00
|
|
|
}
|
2004-09-19 09:32:52 +00:00
|
|
|
amx_Release(m_Amx, realParams[i]);
|
2004-05-05 18:42:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return retVal;
|
|
|
|
}
|
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
int CForwardMngr::registerForward(const char *funcName, ForwardExecType et, int numParams, const ForwardParam * paramTypes)
|
|
|
|
{
|
2004-05-05 18:42:16 +00:00
|
|
|
int retVal = m_Forwards.size() << 1;
|
2004-05-28 11:24:59 +00:00
|
|
|
CForward *tmp = new CForward(funcName, et, numParams, paramTypes);
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-05-28 11:24:59 +00:00
|
|
|
if (!tmp)
|
|
|
|
return -1; // should be invalid
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-05-28 11:24:59 +00:00
|
|
|
m_Forwards.push_back(tmp);
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
return retVal;
|
|
|
|
}
|
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
int CForwardMngr::registerSPForward(int func, AMX *amx, int numParams, const ForwardParam *paramTypes)
|
|
|
|
{
|
2004-09-18 13:33:21 +00:00
|
|
|
int retVal = -1;
|
2004-05-05 18:42:16 +00:00
|
|
|
CSPForward *pForward;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-09-07 05:43:55 +00:00
|
|
|
if (!m_FreeSPForwards.empty())
|
2004-05-05 18:42:16 +00:00
|
|
|
{
|
2004-09-18 13:33:21 +00:00
|
|
|
retVal = m_FreeSPForwards.front();
|
|
|
|
pForward = m_SPForwards[retVal >> 1];
|
|
|
|
pForward->Set(func, amx, numParams, paramTypes);
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-09-18 13:33:21 +00:00
|
|
|
if (pForward->getFuncsNum() == 0)
|
2004-09-09 15:05:06 +00:00
|
|
|
return -1;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-09-18 13:33:21 +00:00
|
|
|
m_FreeSPForwards.pop();
|
2005-09-16 23:48:51 +00:00
|
|
|
} else {
|
2004-09-18 13:33:21 +00:00
|
|
|
retVal = (m_SPForwards.size() << 1) | 1;
|
2004-05-05 18:42:16 +00:00
|
|
|
pForward = new CSPForward();
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
if (!pForward)
|
|
|
|
return -1;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
pForward->Set(func, amx, numParams, paramTypes);
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-09-09 15:05:06 +00:00
|
|
|
if (pForward->getFuncsNum() == 0)
|
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
delete pForward;
|
|
|
|
}
|
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
m_SPForwards.push_back(pForward);
|
|
|
|
}
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
return retVal;
|
|
|
|
}
|
|
|
|
|
|
|
|
int CForwardMngr::registerSPForward(const char *funcName, AMX *amx, int numParams, const ForwardParam *paramTypes)
|
|
|
|
{
|
|
|
|
int retVal = (m_SPForwards.size() << 1) | 1;
|
|
|
|
CSPForward *pForward;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-09-07 05:43:55 +00:00
|
|
|
if (!m_FreeSPForwards.empty())
|
2004-05-05 18:42:16 +00:00
|
|
|
{
|
2004-09-07 05:43:55 +00:00
|
|
|
retVal = m_FreeSPForwards.front();
|
2005-09-16 23:48:51 +00:00
|
|
|
pForward = m_SPForwards[retVal>>1]; // >>1 because unregisterSPForward pushes the id which contains the sp flag
|
2004-09-07 05:43:55 +00:00
|
|
|
pForward->Set(funcName, amx, numParams, paramTypes);
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-09-09 15:05:06 +00:00
|
|
|
if (pForward->getFuncsNum() == 0)
|
|
|
|
return -1;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-09-09 15:05:06 +00:00
|
|
|
m_FreeSPForwards.pop();
|
2005-09-16 23:48:51 +00:00
|
|
|
} else {
|
2004-05-05 18:42:16 +00:00
|
|
|
pForward = new CSPForward();
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
if (!pForward)
|
|
|
|
return -1;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
pForward->Set(funcName, amx, numParams, paramTypes);
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-09-09 15:05:06 +00:00
|
|
|
if (pForward->getFuncsNum() == 0)
|
|
|
|
{
|
|
|
|
delete pForward;
|
|
|
|
return -1;
|
|
|
|
}
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
m_SPForwards.push_back(pForward);
|
|
|
|
}
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
return retVal;
|
|
|
|
}
|
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
bool CForwardMngr::isIdValid(int id) const
|
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
return (id >= 0) && ((id & 1) ? (static_cast<size_t>(id >> 1) < m_SPForwards.size()) : (static_cast<size_t>(id >> 1) < m_Forwards.size()));
|
2004-04-03 19:14:03 +00:00
|
|
|
}
|
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
cell CForwardMngr::executeForwards(int id, cell *params)
|
2004-04-03 19:14:03 +00:00
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
int retVal = (id & 1) ? m_SPForwards[id >> 1]->execute(params, m_TmpArrays) : m_Forwards[id >> 1]->execute(params, m_TmpArrays);
|
2004-04-03 19:14:03 +00:00
|
|
|
m_TmpArraysNum = 0;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
return retVal;
|
|
|
|
}
|
|
|
|
|
2006-05-06 02:03:25 +00:00
|
|
|
const char *CForwardMngr::getFuncName(int id) const
|
|
|
|
{
|
|
|
|
return (id & 1) ? m_SPForwards[id >> 1]->getFuncName() : m_Forwards[id >> 1]->getFuncName();
|
|
|
|
}
|
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
int CForwardMngr::getParamsNum(int id) const
|
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
return (id & 1) ? m_SPForwards[id >> 1]->getParamsNum() : m_Forwards[id >> 1]->getParamsNum();
|
2004-04-03 19:14:03 +00:00
|
|
|
}
|
|
|
|
|
2004-08-28 21:25:29 +00:00
|
|
|
ForwardParam CForwardMngr::getParamType(int id, int paramNum) const
|
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
return (id & 1) ? m_SPForwards[id >> 1]->getParamType(paramNum) : m_Forwards[id >> 1]->getParamType(paramNum);
|
2004-08-28 21:25:29 +00:00
|
|
|
}
|
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
void CForwardMngr::clear()
|
|
|
|
{
|
|
|
|
for (ForwardVec::iterator iter = m_Forwards.begin(); iter != m_Forwards.end(); ++iter)
|
|
|
|
{
|
2004-07-03 13:45:56 +00:00
|
|
|
delete *iter;
|
2004-04-03 19:14:03 +00:00
|
|
|
}
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
SPForwardVec::iterator spIter;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
for (spIter = m_SPForwards.begin(); spIter != m_SPForwards.end(); ++spIter)
|
|
|
|
{
|
|
|
|
delete (*spIter);
|
|
|
|
}
|
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
m_Forwards.clear();
|
2004-05-05 18:42:16 +00:00
|
|
|
m_SPForwards.clear();
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-09-07 05:43:55 +00:00
|
|
|
while (!m_FreeSPForwards.empty())
|
|
|
|
m_FreeSPForwards.pop();
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
m_TmpArraysNum = 0;
|
|
|
|
}
|
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
bool CForwardMngr::isSPForward(int id) const
|
|
|
|
{
|
|
|
|
return ((id & 1) == 0) ? false : true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CForwardMngr::unregisterSPForward(int id)
|
|
|
|
{
|
2004-09-07 05:43:55 +00:00
|
|
|
//make sure the id is valid
|
2005-09-16 23:48:51 +00:00
|
|
|
if (!isIdValid(id) || m_SPForwards.at(id >> 1)->isFree)
|
2004-09-07 05:43:55 +00:00
|
|
|
return;
|
|
|
|
|
2004-09-09 20:32:34 +00:00
|
|
|
m_SPForwards.at(id >> 1)->isFree = true;
|
2004-09-07 05:43:55 +00:00
|
|
|
m_FreeSPForwards.push(id);
|
2004-05-05 18:42:16 +00:00
|
|
|
}
|
|
|
|
|
2006-02-01 12:09:19 +00:00
|
|
|
int registerForwardC(const char *funcName, ForwardExecType et, cell *list, size_t num)
|
|
|
|
{
|
|
|
|
ForwardParam params[FORWARD_MAX_PARAMS];
|
|
|
|
|
|
|
|
for (size_t i=0; i<num; i++)
|
|
|
|
params[i] = static_cast<ForwardParam>(list[i]);
|
|
|
|
|
|
|
|
return g_forwards.registerForward(funcName, et, num, params);
|
|
|
|
}
|
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
int registerForward(const char *funcName, ForwardExecType et, ...)
|
|
|
|
{
|
|
|
|
int curParam = 0;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
va_list argptr;
|
|
|
|
va_start(argptr, et);
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
ForwardParam params[FORWARD_MAX_PARAMS];
|
|
|
|
ForwardParam tmp;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
if (curParam == FORWARD_MAX_PARAMS)
|
|
|
|
break;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-04-22 08:20:10 +00:00
|
|
|
tmp = (ForwardParam)va_arg(argptr, int);
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
if (tmp == FP_DONE)
|
|
|
|
break;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
params[curParam] = tmp;
|
|
|
|
++curParam;
|
|
|
|
}
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
va_end(argptr);
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
return g_forwards.registerForward(funcName, et, curParam, params);
|
|
|
|
}
|
|
|
|
|
2006-02-01 12:09:19 +00:00
|
|
|
int registerSPForwardByNameC(AMX *amx, const char *funcName, cell *list, size_t num)
|
|
|
|
{
|
|
|
|
ForwardParam params[FORWARD_MAX_PARAMS];
|
|
|
|
|
|
|
|
for (size_t i=0; i<num; i++)
|
|
|
|
params[i] = static_cast<ForwardParam>(list[i]);
|
|
|
|
|
|
|
|
return g_forwards.registerSPForward(funcName, amx, num, params);
|
|
|
|
}
|
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
int registerSPForwardByName(AMX *amx, const char *funcName, ...)
|
|
|
|
{
|
|
|
|
int curParam = 0;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
va_list argptr;
|
|
|
|
va_start(argptr, funcName);
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
ForwardParam params[FORWARD_MAX_PARAMS];
|
|
|
|
ForwardParam tmp;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
if (curParam == FORWARD_MAX_PARAMS)
|
|
|
|
break;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
tmp = (ForwardParam)va_arg(argptr, int);
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
if (tmp == FP_DONE)
|
|
|
|
break;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
params[curParam] = tmp;
|
|
|
|
++curParam;
|
|
|
|
}
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
va_end(argptr);
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
return g_forwards.registerSPForward(funcName, amx, curParam, params);
|
|
|
|
}
|
|
|
|
|
|
|
|
int registerSPForward(AMX *amx, int func, ...)
|
|
|
|
{
|
|
|
|
int curParam = 0;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
va_list argptr;
|
|
|
|
va_start(argptr, func);
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
ForwardParam params[FORWARD_MAX_PARAMS];
|
|
|
|
ForwardParam tmp;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
if (curParam == FORWARD_MAX_PARAMS)
|
|
|
|
break;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
tmp = (ForwardParam)va_arg(argptr, int);
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
if (tmp == FP_DONE)
|
|
|
|
break;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
params[curParam] = tmp;
|
|
|
|
++curParam;
|
|
|
|
}
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
va_end(argptr);
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-05-05 18:42:16 +00:00
|
|
|
return g_forwards.registerSPForward(func, amx, curParam, params);
|
|
|
|
}
|
|
|
|
|
|
|
|
cell executeForwards(int id, ...)
|
2004-04-03 19:14:03 +00:00
|
|
|
{
|
|
|
|
if (!g_forwards.isIdValid(id))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
cell params[FORWARD_MAX_PARAMS];
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
int paramsNum = g_forwards.getParamsNum(id);
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
va_list argptr;
|
|
|
|
va_start(argptr, id);
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
for (int i = 0; i < paramsNum && i < FORWARD_MAX_PARAMS; ++i)
|
|
|
|
{
|
2004-08-28 21:25:29 +00:00
|
|
|
if (g_forwards.getParamType(id, i) == FP_FLOAT)
|
2004-04-22 08:20:10 +00:00
|
|
|
{
|
|
|
|
REAL tmp = (REAL)va_arg(argptr, double); // floats get converted to doubles
|
|
|
|
params[i] = *(cell*)&tmp;
|
|
|
|
}
|
2004-10-08 19:18:41 +00:00
|
|
|
else
|
|
|
|
params[i] = (cell)va_arg(argptr, cell);
|
2004-04-03 19:14:03 +00:00
|
|
|
}
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
va_end(argptr);
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
return g_forwards.executeForwards(id, params);
|
|
|
|
}
|
|
|
|
|
2004-09-18 13:33:21 +00:00
|
|
|
cell CForwardMngr::prepareArray(void *ptr, unsigned int size, ForwardArrayElemType type, bool copyBack)
|
2004-04-03 19:14:03 +00:00
|
|
|
{
|
2004-09-27 14:33:50 +00:00
|
|
|
if (m_TmpArraysNum >= FORWARD_MAX_PARAMS)
|
|
|
|
{
|
2005-09-16 23:48:51 +00:00
|
|
|
#ifdef MEMORY_TEST
|
2004-10-02 08:11:33 +00:00
|
|
|
m_validateAllAllocUnits();
|
2005-09-16 23:48:51 +00:00
|
|
|
#endif // MEMORY_TEST
|
|
|
|
|
2004-10-02 08:11:33 +00:00
|
|
|
AMXXLOG_Log("[AMXX] Forwards with more than 32 parameters are not supported (tried to prepare array # %d).", m_TmpArraysNum + 1);
|
|
|
|
m_TmpArraysNum = 0;
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-09-27 14:33:50 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2005-09-16 23:48:51 +00:00
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
m_TmpArrays[m_TmpArraysNum].ptr = ptr;
|
|
|
|
m_TmpArrays[m_TmpArraysNum].size = size;
|
|
|
|
m_TmpArrays[m_TmpArraysNum].type = type;
|
2004-09-18 13:33:21 +00:00
|
|
|
m_TmpArrays[m_TmpArraysNum].copyBack = copyBack;
|
2004-09-27 14:33:50 +00:00
|
|
|
|
2004-04-03 19:14:03 +00:00
|
|
|
return m_TmpArraysNum++;
|
|
|
|
}
|
|
|
|
|
2004-09-18 13:33:21 +00:00
|
|
|
cell prepareCellArray(cell *ptr, unsigned int size, bool copyBack)
|
2004-04-03 19:14:03 +00:00
|
|
|
{
|
2004-09-18 13:33:21 +00:00
|
|
|
return g_forwards.prepareArray((void*)ptr, size, Type_Cell, copyBack);
|
2004-04-03 19:14:03 +00:00
|
|
|
}
|
|
|
|
|
2004-09-18 13:33:21 +00:00
|
|
|
cell prepareCharArray(char *ptr, unsigned int size, bool copyBack)
|
2004-04-03 19:14:03 +00:00
|
|
|
{
|
2004-09-18 13:33:21 +00:00
|
|
|
return g_forwards.prepareArray((void*)ptr, size, Type_Char, copyBack);
|
2004-04-07 04:06:55 +00:00
|
|
|
}
|
2004-05-05 18:42:16 +00:00
|
|
|
|
|
|
|
void unregisterSPForward(int id)
|
|
|
|
{
|
|
|
|
g_forwards.unregisterSPForward(id);
|
2004-07-23 16:55:53 +00:00
|
|
|
}
|