Fixed a bug that caused crashes on registering a forward after unregistering a forward

This commit is contained in:
David Anderson 2004-09-07 05:43:55 +00:00
parent 8903bc7f04
commit baef3362ed
3 changed files with 28 additions and 39 deletions

View File

@ -174,6 +174,7 @@ void CSPForward::Set(int func, AMX *amx, int numParams, const ForwardParam *para
m_NumParams = numParams; m_NumParams = numParams;
memcpy((void *)m_ParamTypes, paramTypes, numParams * sizeof(ForwardParam)); memcpy((void *)m_ParamTypes, paramTypes, numParams * sizeof(ForwardParam));
m_HasFunc = true; m_HasFunc = true;
isFree = false;
} }
void CSPForward::Set(const char *funcName, AMX *amx, int numParams, const ForwardParam *paramTypes) void CSPForward::Set(const char *funcName, AMX *amx, int numParams, const ForwardParam *paramTypes)
@ -182,10 +183,13 @@ void CSPForward::Set(const char *funcName, AMX *amx, int numParams, const Forwar
m_NumParams = numParams; m_NumParams = numParams;
memcpy((void *)m_ParamTypes, paramTypes, numParams * sizeof(ForwardParam)); memcpy((void *)m_ParamTypes, paramTypes, numParams * sizeof(ForwardParam));
m_HasFunc = (amx_FindPublic(amx, funcName, &m_Func) == AMX_ERR_NONE); m_HasFunc = (amx_FindPublic(amx, funcName, &m_Func) == AMX_ERR_NONE);
isFree = false;
} }
cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays) cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
{ {
if (isFree)
return 0;
const int STRINGEX_MAXLENGTH = 128; const int STRINGEX_MAXLENGTH = 128;
cell realParams[FORWARD_MAX_PARAMS]; cell realParams[FORWARD_MAX_PARAMS];
@ -286,10 +290,10 @@ int CForwardMngr::registerSPForward(int func, AMX *amx, int numParams, const For
{ {
int retVal = (m_SPForwards.size() << 1) | 1; int retVal = (m_SPForwards.size() << 1) | 1;
CSPForward *pForward; CSPForward *pForward;
if (m_FreeSPForwards.size()) if (!m_FreeSPForwards.empty())
{ {
pForward = m_SPForwards[m_FreeSPForwards.back()]; pForward = m_SPForwards[m_FreeSPForwards.front() >> 1];
m_FreeSPForwards.pop_back(); m_FreeSPForwards.pop();
pForward->Set(func, amx, numParams, paramTypes); pForward->Set(func, amx, numParams, paramTypes);
} }
else else
@ -312,22 +316,12 @@ int CForwardMngr::registerSPForward(const char *funcName, AMX *amx, int numParam
{ {
int retVal = (m_SPForwards.size() << 1) | 1; int retVal = (m_SPForwards.size() << 1) | 1;
CSPForward *pForward; CSPForward *pForward;
if (m_FreeSPForwards.size()) if (!m_FreeSPForwards.empty())
{ {
if (m_SPForwards.size()) retVal = m_FreeSPForwards.front();
{ m_FreeSPForwards.pop();
retVal = m_FreeSPForwards.back(); pForward = m_SPForwards[retVal>>1]; // >>1 because unregisterSPForward pushes the id which contains the sp flag
m_FreeSPForwards.pop_back(); pForward->Set(funcName, amx, numParams, paramTypes);
pForward = m_SPForwards[retVal>>1]; // >>1 because unregisterSPForward pushes the id which contains the sp flag
pForward->Set(funcName, amx, numParams, paramTypes);
} else {
m_SPForwards.clear();
pForward = new CSPForward();
if (!pForward)
return -1;
pForward->Set(funcName, amx, numParams, paramTypes);
m_SPForwards.push_back(pForward);
}
} }
else else
{ {
@ -381,7 +375,8 @@ void CForwardMngr::clear()
m_Forwards.clear(); m_Forwards.clear();
m_SPForwards.clear(); m_SPForwards.clear();
m_FreeSPForwards.clear(); while (!m_FreeSPForwards.empty())
m_FreeSPForwards.pop();
m_TmpArraysNum = 0; m_TmpArraysNum = 0;
} }
@ -392,7 +387,15 @@ bool CForwardMngr::isSPForward(int id) const
void CForwardMngr::unregisterSPForward(int id) void CForwardMngr::unregisterSPForward(int id)
{ {
m_FreeSPForwards.push_back(id); unsigned int i = 0;
//make sure the id is valid
if ( !isIdValid(id) || m_SPForwards.at(i >> 1)->isFree )
return;
m_SPForwards.at(i >> 1)->isFree = true;
m_FreeSPForwards.push(id);
} }
int registerForward(const char *funcName, ForwardExecType et, ...) int registerForward(const char *funcName, ForwardExecType et, ...)

View File

@ -125,6 +125,8 @@ class CSPForward
AMX *m_Amx; AMX *m_Amx;
int m_Func; int m_Func;
bool m_HasFunc; bool m_HasFunc;
public:
bool isFree;
public: public:
CSPForward() { m_HasFunc = false; } CSPForward() { m_HasFunc = false; }
void Set(const char *funcName, AMX *amx, int numParams, const ForwardParam * paramTypes); void Set(const char *funcName, AMX *amx, int numParams, const ForwardParam * paramTypes);
@ -151,7 +153,7 @@ class CForwardMngr
{ {
typedef CVector<CForward*> ForwardVec; typedef CVector<CForward*> ForwardVec;
typedef CVector<CSPForward*> SPForwardVec; typedef CVector<CSPForward*> SPForwardVec;
typedef CVector<int> FreeSPVec; // Free SP Forwards typedef CQueue<int> FreeSPVec; // Free SP Forwards
ForwardVec m_Forwards; ForwardVec m_Forwards;

View File

@ -207,6 +207,7 @@ int C_Spawn( edict_t *pent ) {
hostname = CVAR_GET_POINTER("hostname"); hostname = CVAR_GET_POINTER("hostname");
mp_timelimit = CVAR_GET_POINTER("mp_timelimit"); mp_timelimit = CVAR_GET_POINTER("mp_timelimit");
g_forwards.clear();
g_log.MapChange(); g_log.MapChange();
@ -441,6 +442,7 @@ void C_ServerDeactivate_Post() {
// HACKHACK: // HACKHACK:
// Make sure the spawn function will be called again // Make sure the spawn function will be called again
// pft that's not really a hack
g_FakeMeta.m_Plugins.begin()->GetDllFuncTable().pfnSpawn = C_Spawn; g_FakeMeta.m_Plugins.begin()->GetDllFuncTable().pfnSpawn = C_Spawn;
detachReloadModules(); detachReloadModules();
@ -1228,15 +1230,6 @@ C_DLLEXPORT int GetEngineFunctions(enginefuncs_t *pengfuncsFromEngine, int *inte
meta_engfuncs.pfnChangeLevel = C_ChangeLevel; meta_engfuncs.pfnChangeLevel = C_ChangeLevel;
return g_FakeMeta.GetEngineFunctions(pengfuncsFromEngine, interfaceVersion, &meta_engfuncs); return g_FakeMeta.GetEngineFunctions(pengfuncsFromEngine, interfaceVersion, &meta_engfuncs);
/*
if(*interfaceVersion!=ENGINE_INTERFACE_VERSION) {
LOG_ERROR(PLID, "GetEngineFunctions version mismatch; requested=%d ours=%d", *interfaceVersion, ENGINE_INTERFACE_VERSION);
*interfaceVersion = ENGINE_INTERFACE_VERSION;
return(FALSE);
}
memcpy(pengfuncsFromEngine, &meta_engfuncs, sizeof(enginefuncs_t));
return(TRUE);
*/
} }
enginefuncs_t meta_engfuncs_post; enginefuncs_t meta_engfuncs_post;
@ -1279,15 +1272,6 @@ C_DLLEXPORT int GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, int
++iter; ++iter;
} }
return g_FakeMeta.GetEngineFunctions_Post(pengfuncsFromEngine, interfaceVersion, &meta_engfuncs_post); return g_FakeMeta.GetEngineFunctions_Post(pengfuncsFromEngine, interfaceVersion, &meta_engfuncs_post);
/*
if(*interfaceVersion!=ENGINE_INTERFACE_VERSION) {
LOG_ERROR(PLID, "GetEngineFunctions_Post version mismatch; requested=%d ours=%d", *interfaceVersion, ENGINE_INTERFACE_VERSION);
*interfaceVersion = ENGINE_INTERFACE_VERSION;
return(FALSE);
}
memcpy(pengfuncsFromEngine, &meta_engfuncs_post, sizeof(enginefuncs_t));
return(TRUE);
*/
} }
NEW_DLL_FUNCTIONS gNewDLLFunctionTable; NEW_DLL_FUNCTIONS gNewDLLFunctionTable;