mirror of
https://github.com/alliedmodders/amxmodx.git
synced 2024-12-26 06:45:37 +03:00
added layout for "plugin cache"
dynamic natives that are paused now pause parent plugin with an error added catch for a potentially serious bug?
This commit is contained in:
parent
974e8882b9
commit
37151d361f
@ -130,6 +130,8 @@ int CPluginMngr::loadPluginsFromFile(const char* filename)
|
|||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
|
InvalidateCache();
|
||||||
|
|
||||||
return pCounter;
|
return pCounter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,3 +385,88 @@ void CPluginMngr::CPlugin::unpausePlugin()
|
|||||||
executeForwards(m_UnpauseFwd);
|
executeForwards(m_UnpauseFwd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *CPluginMngr::ReadIntoOrFromCache(const char *file, size_t &bufsize)
|
||||||
|
{
|
||||||
|
List<plcache_entry *>::iterator iter;
|
||||||
|
plcache_entry *pl;
|
||||||
|
|
||||||
|
for (iter=m_plcache.begin(); iter!=m_plcache.end(); iter++)
|
||||||
|
{
|
||||||
|
pl = (*iter);
|
||||||
|
if (pl->path.compare(file) == 0)
|
||||||
|
{
|
||||||
|
bufsize = pl->bufsize;
|
||||||
|
return pl->buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pl = new plcache_entry;
|
||||||
|
|
||||||
|
pl->file = new CAmxxReader(file, sizeof(cell));
|
||||||
|
if (pl->file->GetStatus() != CAmxxReader::Err_None)
|
||||||
|
{
|
||||||
|
delete pl->file;
|
||||||
|
delete pl;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pl->bufsize =pl->file->GetBufferSize();
|
||||||
|
pl->buffer = NULL;
|
||||||
|
if (pl->bufsize)
|
||||||
|
{
|
||||||
|
pl->buffer = new char[pl->bufsize];
|
||||||
|
pl->file->GetSection(pl->buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pl->bufsize || pl->file->GetStatus() != CAmxxReader::Err_None)
|
||||||
|
{
|
||||||
|
delete [] pl->buffer;
|
||||||
|
delete pl->file;
|
||||||
|
delete pl;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pl->path.assign(file);
|
||||||
|
|
||||||
|
bufsize = pl->bufsize;
|
||||||
|
|
||||||
|
return pl->buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPluginMngr::InvalidateCache()
|
||||||
|
{
|
||||||
|
List<plcache_entry *>::iterator iter;
|
||||||
|
plcache_entry *pl;
|
||||||
|
|
||||||
|
for (iter=m_plcache.begin(); iter!=m_plcache.end(); iter++)
|
||||||
|
{
|
||||||
|
pl = (*iter);
|
||||||
|
delete [] pl->buffer;
|
||||||
|
delete pl->file;
|
||||||
|
delete pl;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_plcache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPluginMngr::InvalidateFileInCache(const char *file, bool freebuf)
|
||||||
|
{
|
||||||
|
List<plcache_entry *>::iterator iter;
|
||||||
|
plcache_entry *pl;
|
||||||
|
|
||||||
|
for (iter=m_plcache.begin(); iter!=m_plcache.end(); iter++)
|
||||||
|
{
|
||||||
|
pl = (*iter);
|
||||||
|
if (pl->path.compare(file) == 0)
|
||||||
|
{
|
||||||
|
if (freebuf)
|
||||||
|
delete [] pl->buffer;
|
||||||
|
delete pl->file;
|
||||||
|
delete pl;
|
||||||
|
m_plcache.erase(iter);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,11 @@
|
|||||||
#ifndef PLUGIN_H
|
#ifndef PLUGIN_H
|
||||||
#define PLUGIN_H
|
#define PLUGIN_H
|
||||||
|
|
||||||
|
#include "CString.h"
|
||||||
|
#include "sh_list.h"
|
||||||
|
#include "amx.h"
|
||||||
|
#include "amxxfile.h"
|
||||||
|
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
// class CPluginMngr
|
// class CPluginMngr
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
@ -111,7 +116,7 @@ private:
|
|||||||
int pCounter;
|
int pCounter;
|
||||||
public:
|
public:
|
||||||
CPluginMngr() { head = 0; pCounter = 0; pNatives = NULL; m_Finalized=false;}
|
CPluginMngr() { head = 0; pCounter = 0; pNatives = NULL; m_Finalized=false;}
|
||||||
~CPluginMngr() { clear(); }
|
~CPluginMngr() { clear(); InvalidateCache(); }
|
||||||
|
|
||||||
bool m_Finalized;
|
bool m_Finalized;
|
||||||
AMX_NATIVE_INFO *pNatives;
|
AMX_NATIVE_INFO *pNatives;
|
||||||
@ -145,6 +150,19 @@ public:
|
|||||||
|
|
||||||
inline iterator begin() const { return iterator(head); }
|
inline iterator begin() const { return iterator(head); }
|
||||||
inline iterator end() const { return iterator(0); }
|
inline iterator end() const { return iterator(0); }
|
||||||
|
public:
|
||||||
|
struct plcache_entry
|
||||||
|
{
|
||||||
|
CAmxxReader *file;
|
||||||
|
size_t bufsize;
|
||||||
|
char *buffer;
|
||||||
|
String path;
|
||||||
|
};
|
||||||
|
char *ReadIntoOrFromCache(const char *file, size_t &bufsize);
|
||||||
|
void InvalidateCache();
|
||||||
|
void InvalidateFileInCache(const char *file, bool freebuf);
|
||||||
|
private:
|
||||||
|
List<plcache_entry *> m_plcache;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //PLUGIN_H
|
#endif //PLUGIN_H
|
||||||
|
@ -162,56 +162,63 @@ static binlogfuncs_t logfuncs =
|
|||||||
int load_amxscript(AMX *amx, void **program, const char *filename, char error[64], int debug)
|
int load_amxscript(AMX *amx, void **program, const char *filename, char error[64], int debug)
|
||||||
{
|
{
|
||||||
*error = 0;
|
*error = 0;
|
||||||
CAmxxReader reader(filename, PAWN_CELL_SIZE / 8);
|
size_t bufSize;
|
||||||
|
*program = (void *)g_plugins.ReadIntoOrFromCache(filename, bufSize);
|
||||||
if (reader.GetStatus() == CAmxxReader::Err_None)
|
if (!*program)
|
||||||
{
|
{
|
||||||
size_t bufSize = reader.GetBufferSize();
|
CAmxxReader reader(filename, PAWN_CELL_SIZE / 8);
|
||||||
|
|
||||||
if (bufSize != 0)
|
if (reader.GetStatus() == CAmxxReader::Err_None)
|
||||||
{
|
{
|
||||||
*program = (void*) (new char[bufSize]);
|
bufSize = reader.GetBufferSize();
|
||||||
|
|
||||||
if (!*program)
|
if (bufSize != 0)
|
||||||
{
|
{
|
||||||
strcpy(error, "Failed to allocate memory");
|
*program = (void*) (new char[bufSize]);
|
||||||
return (amx->error = AMX_ERR_MEMORY);
|
|
||||||
|
if (!*program)
|
||||||
|
{
|
||||||
|
strcpy(error, "Failed to allocate memory");
|
||||||
|
return (amx->error = AMX_ERR_MEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.GetSection(*program);
|
||||||
}
|
}
|
||||||
|
|
||||||
reader.GetSection(*program);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
switch (reader.GetStatus())
|
switch (reader.GetStatus())
|
||||||
{
|
{
|
||||||
case CAmxxReader::Err_None:
|
case CAmxxReader::Err_None:
|
||||||
break;
|
break;
|
||||||
case CAmxxReader::Err_FileOpen:
|
case CAmxxReader::Err_FileOpen:
|
||||||
strcpy(error, "Plugin file open error");
|
strcpy(error, "Plugin file open error");
|
||||||
return (amx->error = AMX_ERR_NOTFOUND);
|
return (amx->error = AMX_ERR_NOTFOUND);
|
||||||
case CAmxxReader::Err_FileRead:
|
case CAmxxReader::Err_FileRead:
|
||||||
strcpy(error, "Plugin file read error");
|
strcpy(error, "Plugin file read error");
|
||||||
return (amx->error = AMX_ERR_NOTFOUND);
|
return (amx->error = AMX_ERR_NOTFOUND);
|
||||||
case CAmxxReader::Err_InvalidParam:
|
case CAmxxReader::Err_InvalidParam:
|
||||||
strcpy(error, "Internal error: Invalid parameter");
|
strcpy(error, "Internal error: Invalid parameter");
|
||||||
return (amx->error = AMX_ERR_NOTFOUND);
|
return (amx->error = AMX_ERR_NOTFOUND);
|
||||||
case CAmxxReader::Err_FileInvalid:
|
case CAmxxReader::Err_FileInvalid:
|
||||||
strcpy(error, "Invalid Plugin");
|
strcpy(error, "Invalid Plugin");
|
||||||
return (amx->error = AMX_ERR_FORMAT);
|
return (amx->error = AMX_ERR_FORMAT);
|
||||||
case CAmxxReader::Err_SectionNotFound:
|
case CAmxxReader::Err_SectionNotFound:
|
||||||
strcpy(error, "Searched section not found (.amxx)");
|
strcpy(error, "Searched section not found (.amxx)");
|
||||||
return (amx->error = AMX_ERR_NOTFOUND);
|
return (amx->error = AMX_ERR_NOTFOUND);
|
||||||
case CAmxxReader::Err_DecompressorInit:
|
case CAmxxReader::Err_DecompressorInit:
|
||||||
strcpy(error, "Decompressor initialization failed");
|
strcpy(error, "Decompressor initialization failed");
|
||||||
return (amx->error = AMX_ERR_INIT);
|
return (amx->error = AMX_ERR_INIT);
|
||||||
case CAmxxReader::Err_Decompress:
|
case CAmxxReader::Err_Decompress:
|
||||||
strcpy(error, "Internal error: Decompress");
|
strcpy(error, "Internal error: Decompress");
|
||||||
return (amx->error = AMX_ERR_NOTFOUND);
|
return (amx->error = AMX_ERR_NOTFOUND);
|
||||||
case CAmxxReader::Err_OldFile:
|
case CAmxxReader::Err_OldFile:
|
||||||
strcpy(error, "Plugin uses deprecated format. Update compiler");
|
strcpy(error, "Plugin uses deprecated format. Update compiler");
|
||||||
default:
|
default:
|
||||||
strcpy(error, "Unknown error");
|
strcpy(error, "Unknown error");
|
||||||
return (amx->error = AMX_ERR_NOTFOUND);
|
return (amx->error = AMX_ERR_NOTFOUND);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
g_plugins.InvalidateFileInCache(filename, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for magic
|
// check for magic
|
||||||
@ -337,12 +344,12 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64
|
|||||||
if (amx->base)
|
if (amx->base)
|
||||||
memcpy(amx->base, np, amx->code_size);
|
memcpy(amx->base, np, amx->code_size);
|
||||||
|
|
||||||
delete[] np;
|
delete [] np;
|
||||||
delete[] rt;
|
delete [] rt;
|
||||||
|
|
||||||
char *prg = (char *)(*program);
|
char *prg = (char *)(*program);
|
||||||
|
|
||||||
delete[] prg;
|
delete [] prg;
|
||||||
(*program) = amx->base;
|
(*program) = amx->base;
|
||||||
|
|
||||||
if (*program == 0)
|
if (*program == 0)
|
||||||
@ -363,12 +370,6 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64
|
|||||||
|
|
||||||
CScript* aa = new CScript(amx, *program, filename);
|
CScript* aa = new CScript(amx, *program, filename);
|
||||||
|
|
||||||
if (aa == 0)
|
|
||||||
{
|
|
||||||
strcpy(error, "Failed to allocate memory");
|
|
||||||
return (amx->error = AMX_ERR_MEMORY);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_loadedscripts.put(aa);
|
g_loadedscripts.put(aa);
|
||||||
|
|
||||||
set_amxnatives(amx, error);
|
set_amxnatives(amx, error);
|
||||||
|
@ -68,10 +68,27 @@ int amxx_DynaCallback(int idx, AMX *amx, cell *params)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//parameter stack
|
|
||||||
pNative->caller = amx;
|
|
||||||
|
|
||||||
CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(amx);
|
CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(amx);
|
||||||
|
CPluginMngr::CPlugin *pNativePlugin = g_plugins.findPluginFast(pNative->amx);
|
||||||
|
|
||||||
|
if (!pNativePlugin->isExecutable(pNative->func))
|
||||||
|
{
|
||||||
|
LogError(amx, AMX_ERR_NATIVE, "Called dynanative into a paused plugin.");
|
||||||
|
pPlugin->setStatus(ps_paused);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pNative->caller)
|
||||||
|
{
|
||||||
|
LogError(amx, AMX_ERR_NATIVE, "Bug caught! Please contact the AMX Mod X Dev Team.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//parameter stack
|
||||||
|
//NOTE: it is possible that recursive register native calling
|
||||||
|
// could potentially be somehow damaged here.
|
||||||
|
//so, a :TODO: - make the stack unique, rather than a known ptr
|
||||||
|
pNative->caller = amx;
|
||||||
|
|
||||||
int err = 0;
|
int err = 0;
|
||||||
cell ret = 0;
|
cell ret = 0;
|
||||||
@ -112,6 +129,8 @@ int amxx_DynaCallback(int idx, AMX *amx, cell *params)
|
|||||||
g_NativeStack.pop();
|
g_NativeStack.pop();
|
||||||
g_ErrorStk.pop();
|
g_ErrorStk.pop();
|
||||||
|
|
||||||
|
pNative->caller = NULL;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -370,6 +389,7 @@ static cell AMX_NATIVE_CALL register_native(AMX *amx, cell *params)
|
|||||||
regnative *pNative = new regnative;
|
regnative *pNative = new regnative;
|
||||||
pNative->amx = amx;
|
pNative->amx = amx;
|
||||||
pNative->func = idx;
|
pNative->func = idx;
|
||||||
|
pNative->caller = NULL;
|
||||||
|
|
||||||
//we'll apply a safety buffer too
|
//we'll apply a safety buffer too
|
||||||
//make our function
|
//make our function
|
||||||
|
Loading…
Reference in New Issue
Block a user