added amb292, optional natives
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401118
This commit is contained in:
parent
68901b71d2
commit
fe8ebeae89
@ -335,12 +335,6 @@ static cell_t MarkNativeAsOptional(IPluginContext *pContext, const cell_t *param
|
|||||||
char *name;
|
char *name;
|
||||||
uint32_t idx;
|
uint32_t idx;
|
||||||
sp_context_t *ctx = pContext->GetContext();
|
sp_context_t *ctx = pContext->GetContext();
|
||||||
CPlugin *pl = g_PluginSys.GetPluginByCtx(ctx);
|
|
||||||
|
|
||||||
if (!pl->IsInAskPluginLoad())
|
|
||||||
{
|
|
||||||
return pContext->ThrowNativeError("Calling MarkNativeAsOptional outside AskPluginLoad is not allowed");
|
|
||||||
}
|
|
||||||
|
|
||||||
pContext->LocalToString(params[1], &name);
|
pContext->LocalToString(params[1], &name);
|
||||||
if (pContext->FindNativeByName(name, &idx) != SP_ERROR_NONE)
|
if (pContext->FindNativeByName(name, &idx) != SP_ERROR_NONE)
|
||||||
@ -353,6 +347,19 @@ static cell_t MarkNativeAsOptional(IPluginContext *pContext, const cell_t *param
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cell_t RegPluginLibrary(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
uint32_t idx;
|
||||||
|
CPlugin *pl = g_PluginSys.GetPluginByCtx(pContext->GetContext());
|
||||||
|
|
||||||
|
pContext->LocalToString(params[1], &name);
|
||||||
|
|
||||||
|
pl->AddLibrary(name);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
REGISTER_NATIVES(coreNatives)
|
REGISTER_NATIVES(coreNatives)
|
||||||
{
|
{
|
||||||
{"AutoExecConfig", AutoExecConfig},
|
{"AutoExecConfig", AutoExecConfig},
|
||||||
@ -369,5 +376,6 @@ REGISTER_NATIVES(coreNatives)
|
|||||||
{"SetFailState", SetFailState},
|
{"SetFailState", SetFailState},
|
||||||
{"FormatTime", FormatTime},
|
{"FormatTime", FormatTime},
|
||||||
{"MarkNativeAsOptional", MarkNativeAsOptional},
|
{"MarkNativeAsOptional", MarkNativeAsOptional},
|
||||||
|
{"RegPluginLibrary", RegPluginLibrary},
|
||||||
{NULL, NULL},
|
{NULL, NULL},
|
||||||
};
|
};
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
#include "ShareSys.h"
|
#include "ShareSys.h"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include "sourcemm_api.h"
|
#include "sourcemm_api.h"
|
||||||
#include "PluginSys.h"
|
|
||||||
#include "sm_srvcmds.h"
|
#include "sm_srvcmds.h"
|
||||||
#include "sm_stringutil.h"
|
#include "sm_stringutil.h"
|
||||||
|
|
||||||
@ -126,6 +125,13 @@ CExtension::~CExtension()
|
|||||||
{
|
{
|
||||||
m_pLib->CloseLibrary();
|
m_pLib->CloseLibrary();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<WeakNative *>::iterator iter;
|
||||||
|
for (iter=m_WeakNatives.begin(); iter!=m_WeakNatives.end(); iter++)
|
||||||
|
{
|
||||||
|
delete (*iter);
|
||||||
|
}
|
||||||
|
m_WeakNatives.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CExtension::MarkAllLoaded()
|
void CExtension::MarkAllLoaded()
|
||||||
@ -539,6 +545,9 @@ void CExtensionManager::BindAllNativesToPlugin(IPlugin *pPlugin)
|
|||||||
if (!(pContext->GetContext()->natives[idx].flags & SP_NTVFLAG_OPTIONAL))
|
if (!(pContext->GetContext()->natives[idx].flags & SP_NTVFLAG_OPTIONAL))
|
||||||
{
|
{
|
||||||
set = true;
|
set = true;
|
||||||
|
} else {
|
||||||
|
WeakNative *wkn = new WeakNative((CPlugin *)pPlugin, idx);
|
||||||
|
pExt->m_WeakNatives.push_back(wkn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
@ -584,6 +593,16 @@ bool CExtensionManager::UnloadExtension(IExtension *_pExt)
|
|||||||
p_iter = pExt->m_Plugins.erase(p_iter);
|
p_iter = pExt->m_Plugins.erase(p_iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Unbound weak natives */
|
||||||
|
WeakNative *wkn;
|
||||||
|
List<WeakNative *>::iterator wkn_iter;
|
||||||
|
for (wkn_iter=pExt->m_WeakNatives.begin(); wkn_iter!=pExt->m_WeakNatives.end(); wkn_iter++)
|
||||||
|
{
|
||||||
|
wkn = (*wkn_iter);
|
||||||
|
sp_context_t *ctx = wkn->pl->GetContext();
|
||||||
|
ctx->natives[wkn->idx].status = SP_NATIVE_UNBOUND;
|
||||||
|
}
|
||||||
|
|
||||||
/* Notify and/or unload all dependencies */
|
/* Notify and/or unload all dependencies */
|
||||||
List<CExtension *>::iterator c_iter;
|
List<CExtension *>::iterator c_iter;
|
||||||
CExtension *pDep;
|
CExtension *pDep;
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <ISmmAPI.h>
|
#include <ISmmAPI.h>
|
||||||
#include <IPluginSys.h>
|
#include <IPluginSys.h>
|
||||||
#include <IRootConsoleMenu.h>
|
#include <IRootConsoleMenu.h>
|
||||||
|
#include "PluginSys.h"
|
||||||
|
|
||||||
using namespace SourceMod;
|
using namespace SourceMod;
|
||||||
using namespace SourceHook;
|
using namespace SourceHook;
|
||||||
@ -63,6 +64,7 @@ private:
|
|||||||
List<SMInterface *> m_Interfaces;
|
List<SMInterface *> m_Interfaces;
|
||||||
List<IPlugin *> m_Plugins;
|
List<IPlugin *> m_Plugins;
|
||||||
List<const sp_nativeinfo_t *> m_Natives;
|
List<const sp_nativeinfo_t *> m_Natives;
|
||||||
|
List<WeakNative *> m_WeakNatives;
|
||||||
PluginId m_PlId;
|
PluginId m_PlId;
|
||||||
unsigned int unload_code;
|
unsigned int unload_code;
|
||||||
bool m_FullyLoaded;
|
bool m_FullyLoaded;
|
||||||
|
@ -47,6 +47,7 @@ CPlugin::CPlugin(const char *file)
|
|||||||
m_ident = NULL;
|
m_ident = NULL;
|
||||||
m_pProps = sm_trie_create();
|
m_pProps = sm_trie_create();
|
||||||
m_FakeNativesMissing = false;
|
m_FakeNativesMissing = false;
|
||||||
|
m_LibraryMissing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CPlugin::~CPlugin()
|
CPlugin::~CPlugin()
|
||||||
@ -91,6 +92,13 @@ CPlugin::~CPlugin()
|
|||||||
delete m_configs[i];
|
delete m_configs[i];
|
||||||
}
|
}
|
||||||
m_configs.clear();
|
m_configs.clear();
|
||||||
|
|
||||||
|
List<WeakNative *>::iterator iter;
|
||||||
|
for (iter=m_WeakNatives.begin(); iter!=m_WeakNatives.end(); iter++)
|
||||||
|
{
|
||||||
|
delete (*iter);
|
||||||
|
}
|
||||||
|
m_WeakNatives.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlugin::InitIdentity()
|
void CPlugin::InitIdentity()
|
||||||
@ -357,19 +365,15 @@ bool CPlugin::Call_AskPluginLoad(char *error, size_t maxlength)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_IsInAskPluginLoad = true;
|
|
||||||
pFunction->PushCell(m_handle);
|
pFunction->PushCell(m_handle);
|
||||||
pFunction->PushCell(g_PluginSys.IsLateLoadTime() ? 1 : 0);
|
pFunction->PushCell(g_PluginSys.IsLateLoadTime() ? 1 : 0);
|
||||||
pFunction->PushStringEx(error, maxlength, 0, SM_PARAM_COPYBACK);
|
pFunction->PushStringEx(error, maxlength, 0, SM_PARAM_COPYBACK);
|
||||||
pFunction->PushCell(maxlength);
|
pFunction->PushCell(maxlength);
|
||||||
if ((err=pFunction->Execute(&result)) != SP_ERROR_NONE)
|
if ((err=pFunction->Execute(&result)) != SP_ERROR_NONE)
|
||||||
{
|
{
|
||||||
m_IsInAskPluginLoad = false;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_IsInAskPluginLoad = false;
|
|
||||||
|
|
||||||
if (!result || m_status != Plugin_Loaded)
|
if (!result || m_status != Plugin_Loaded)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -592,6 +596,19 @@ void CPlugin::DependencyDropped(CPlugin *pOwner)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<String>::iterator reqlib_iter;
|
||||||
|
List<String>::iterator lib_iter;
|
||||||
|
for (lib_iter=pOwner->m_Libraries.begin(); lib_iter!=pOwner->m_Libraries.end(); lib_iter++)
|
||||||
|
{
|
||||||
|
for (reqlib_iter=m_RequiredLibs.begin(); reqlib_iter!=m_RequiredLibs.end(); reqlib_iter++)
|
||||||
|
{
|
||||||
|
if ((*reqlib_iter) == (*lib_iter))
|
||||||
|
{
|
||||||
|
m_LibraryMissing = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
List<FakeNative *>::iterator iter;
|
List<FakeNative *>::iterator iter;
|
||||||
FakeNative *pNative;
|
FakeNative *pNative;
|
||||||
sp_native_t *native;
|
sp_native_t *native;
|
||||||
@ -615,10 +632,14 @@ void CPlugin::DependencyDropped(CPlugin *pOwner)
|
|||||||
unbound++;
|
unbound++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* :IDEA: in the future, add native trapping? */
|
|
||||||
if (unbound)
|
if (unbound)
|
||||||
{
|
{
|
||||||
m_FakeNativesMissing = true;
|
m_FakeNativesMissing = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* :IDEA: in the future, add native trapping? */
|
||||||
|
if (m_FakeNativesMissing || m_LibraryMissing)
|
||||||
|
{
|
||||||
SetErrorState(Plugin_Error, "Depends on plugin: %s", pOwner->GetFilename());
|
SetErrorState(Plugin_Error, "Depends on plugin: %s", pOwner->GetFilename());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1001,6 +1022,96 @@ void CPluginManager::LoadAll_SecondPass()
|
|||||||
m_AllPluginsLoaded = true;
|
m_AllPluginsLoaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CPluginManager::FindOrRequirePluginDeps(CPlugin *pPlugin, char *error, size_t maxlength)
|
||||||
|
{
|
||||||
|
struct _pl
|
||||||
|
{
|
||||||
|
cell_t name;
|
||||||
|
cell_t file;
|
||||||
|
cell_t required;
|
||||||
|
} *pl;
|
||||||
|
|
||||||
|
IPluginContext *pBase = pPlugin->GetBaseContext();
|
||||||
|
uint32_t num = pBase->GetPubVarsNum();
|
||||||
|
sp_pubvar_t *pubvar;
|
||||||
|
char *name, *file;
|
||||||
|
char pathfile[PLATFORM_MAX_PATH];
|
||||||
|
|
||||||
|
for (uint32_t i=0; i<num; i++)
|
||||||
|
{
|
||||||
|
if (pBase->GetPubvarByIndex(i, &pubvar) != SP_ERROR_NONE)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (strncmp(pubvar->name, "__pl_", 5) == 0)
|
||||||
|
{
|
||||||
|
pl = (_pl *)pubvar->offs;
|
||||||
|
if (pBase->LocalToString(pl->file, &file) != SP_ERROR_NONE)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (pBase->LocalToString(pl->name, &name) != SP_ERROR_NONE)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
g_LibSys.GetFileFromPath(pathfile, sizeof(pathfile), pPlugin->GetFilename());
|
||||||
|
if (strcmp(pathfile, file) == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (pl->required == false)
|
||||||
|
{
|
||||||
|
IPluginFunction *pFunc;
|
||||||
|
char buffer[64];
|
||||||
|
UTIL_Format(buffer, sizeof(buffer), "__pl_%s_SetNTVOptional", &pubvar->name[6]);
|
||||||
|
if ((pFunc=pBase->GetFunctionByName(buffer)))
|
||||||
|
{
|
||||||
|
cell_t res;
|
||||||
|
pFunc->Execute(&res);
|
||||||
|
if (pPlugin->GetContext()->n_err != SP_ERROR_NONE)
|
||||||
|
{
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
snprintf(error, maxlength, "Fatal error during initializing plugin load");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Check that we aren't registering the same library twice */
|
||||||
|
if (pPlugin->m_RequiredLibs.find(name) == pPlugin->m_RequiredLibs.end())
|
||||||
|
{
|
||||||
|
pPlugin->m_RequiredLibs.push_back(name);
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
List<CPlugin *>::iterator iter;
|
||||||
|
CPlugin *pl;
|
||||||
|
bool found = false;
|
||||||
|
for (iter=m_plugins.begin(); iter!=m_plugins.end(); iter++)
|
||||||
|
{
|
||||||
|
pl = (*iter);
|
||||||
|
if (pl->m_Libraries.find(name) != pl->m_Libraries.end())
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
snprintf(error, maxlength, "Could not find required plugin \"%s\"", name);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool CPluginManager::LoadOrRequireExtensions(CPlugin *pPlugin, unsigned int pass, char *error, size_t maxlength)
|
bool CPluginManager::LoadOrRequireExtensions(CPlugin *pPlugin, unsigned int pass, char *error, size_t maxlength)
|
||||||
{
|
{
|
||||||
/* Find any extensions this plugin needs */
|
/* Find any extensions this plugin needs */
|
||||||
@ -1089,6 +1200,11 @@ bool CPluginManager::RunSecondPass(CPlugin *pPlugin, char *error, size_t maxleng
|
|||||||
g_Extensions.BindAllNativesToPlugin(pPlugin);
|
g_Extensions.BindAllNativesToPlugin(pPlugin);
|
||||||
AddFakeNativesToPlugin(pPlugin);
|
AddFakeNativesToPlugin(pPlugin);
|
||||||
|
|
||||||
|
if (!FindOrRequirePluginDeps(pPlugin, error, maxlength))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Find any unbound natives
|
/* Find any unbound natives
|
||||||
* Right now, these are not allowed
|
* Right now, these are not allowed
|
||||||
*/
|
*/
|
||||||
@ -1136,9 +1252,9 @@ bool CPluginManager::RunSecondPass(CPlugin *pPlugin, char *error, size_t maxleng
|
|||||||
{
|
{
|
||||||
pOther = (*pl_iter);
|
pOther = (*pl_iter);
|
||||||
if (pOther->GetStatus() == Plugin_Error
|
if (pOther->GetStatus() == Plugin_Error
|
||||||
&& pOther->m_FakeNativesMissing)
|
&& (pOther->m_FakeNativesMissing || pOther->m_LibraryMissing))
|
||||||
{
|
{
|
||||||
TryRefreshNatives(pOther);
|
TryRefreshDependencies(pOther);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1163,12 +1279,37 @@ void CPluginManager::AddCoreNativesToPlugin(CPlugin *pPlugin)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPluginManager::TryRefreshNatives(CPlugin *pPlugin)
|
void CPluginManager::TryRefreshDependencies(CPlugin *pPlugin)
|
||||||
{
|
{
|
||||||
assert(pPlugin->GetBaseContext() != NULL);
|
assert(pPlugin->GetBaseContext() != NULL);
|
||||||
|
|
||||||
AddFakeNativesToPlugin(pPlugin);
|
AddFakeNativesToPlugin(pPlugin);
|
||||||
|
|
||||||
|
List<String>::iterator lib_iter;
|
||||||
|
List<String>::iterator req_iter;
|
||||||
|
List<CPlugin *>::iterator pl_iter;
|
||||||
|
CPlugin *pl;
|
||||||
|
for (req_iter=pPlugin->m_RequiredLibs.begin(); req_iter!=pPlugin->m_RequiredLibs.end(); req_iter++)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
for (pl_iter=m_plugins.begin(); pl_iter!=m_plugins.end(); pl_iter++)
|
||||||
|
{
|
||||||
|
pl = (*pl_iter);
|
||||||
|
for (lib_iter=pl->m_Libraries.begin(); lib_iter!=pl->m_Libraries.end(); lib_iter++)
|
||||||
|
{
|
||||||
|
if ((*req_iter) == (*lib_iter))
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
pPlugin->SetErrorState(Plugin_Error, "Library not found: %s", (*req_iter).c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Find any unbound natives
|
/* Find any unbound natives
|
||||||
* Right now, these are not allowed
|
* Right now, these are not allowed
|
||||||
*/
|
*/
|
||||||
@ -1220,8 +1361,10 @@ void CPluginManager::AddFakeNativesToPlugin(CPlugin *pPlugin)
|
|||||||
{
|
{
|
||||||
uint32_t idx;
|
uint32_t idx;
|
||||||
pContext->FindNativeByName(native.name, &idx);
|
pContext->FindNativeByName(native.name, &idx);
|
||||||
if (!(pPlugin->GetContext()->natives[idx].flags & SP_NTVFLAG_OPTIONAL))
|
if (pPlugin->GetContext()->natives[idx].flags & SP_NTVFLAG_OPTIONAL)
|
||||||
{
|
{
|
||||||
|
WeakNative *wkn = new WeakNative(pPlugin, idx);
|
||||||
|
GetPluginByCtx(ctx)->m_WeakNatives.push_back(wkn);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* Add us as a dependency, but we're careful not to do this circularly! */
|
/* Add us as a dependency, but we're careful not to do this circularly! */
|
||||||
@ -1275,20 +1418,6 @@ bool CPluginManager::UnloadPlugin(IPlugin *plugin)
|
|||||||
pOther->m_dependents.remove(pPlugin);
|
pOther->m_dependents.remove(pPlugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove all of our native functions */
|
|
||||||
List<FakeNative *>::iterator fn_iter;
|
|
||||||
FakeNative *pNative;
|
|
||||||
for (fn_iter = pPlugin->m_fakeNatives.begin();
|
|
||||||
fn_iter != pPlugin->m_fakeNatives.end();
|
|
||||||
fn_iter++)
|
|
||||||
{
|
|
||||||
pNative = (*fn_iter);
|
|
||||||
m_Natives.remove(pNative);
|
|
||||||
sm_trie_delete(m_pNativeLookup, pNative->name.c_str());
|
|
||||||
g_pVM->DestroyFakeNative(pNative->func);
|
|
||||||
delete pNative;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<IPluginsListener *>::iterator iter;
|
List<IPluginsListener *>::iterator iter;
|
||||||
IPluginsListener *pListener;
|
IPluginsListener *pListener;
|
||||||
|
|
||||||
@ -1304,6 +1433,30 @@ bool CPluginManager::UnloadPlugin(IPlugin *plugin)
|
|||||||
pPlugin->Call_OnPluginEnd();
|
pPlugin->Call_OnPluginEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Remove all of our native functions */
|
||||||
|
List<FakeNative *>::iterator fn_iter;
|
||||||
|
FakeNative *pNative;
|
||||||
|
for (fn_iter = pPlugin->m_fakeNatives.begin();
|
||||||
|
fn_iter != pPlugin->m_fakeNatives.end();
|
||||||
|
fn_iter++)
|
||||||
|
{
|
||||||
|
pNative = (*fn_iter);
|
||||||
|
m_Natives.remove(pNative);
|
||||||
|
sm_trie_delete(m_pNativeLookup, pNative->name.c_str());
|
||||||
|
g_pVM->DestroyFakeNative(pNative->func);
|
||||||
|
delete pNative;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unbound weak natives */
|
||||||
|
WeakNative *wkn;
|
||||||
|
List<WeakNative *>::iterator wk_iter;
|
||||||
|
for (wk_iter=pPlugin->m_WeakNatives.begin(); wk_iter!=pPlugin->m_WeakNatives.end(); wk_iter++)
|
||||||
|
{
|
||||||
|
wkn = (*wk_iter);
|
||||||
|
sp_context_t *ctx = wkn->pl->GetContext();
|
||||||
|
ctx->natives[wkn->idx].status = SP_NATIVE_UNBOUND;
|
||||||
|
}
|
||||||
|
|
||||||
for (iter=m_listeners.begin(); iter!=m_listeners.end(); iter++)
|
for (iter=m_listeners.begin(); iter!=m_listeners.end(); iter++)
|
||||||
{
|
{
|
||||||
/* Notify listeners of destruction */
|
/* Notify listeners of destruction */
|
||||||
|
@ -116,6 +116,18 @@ struct AutoConfig
|
|||||||
bool create;
|
bool create;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CPlugin;
|
||||||
|
struct WeakNative
|
||||||
|
{
|
||||||
|
WeakNative(CPlugin *plugin, uint32_t index)
|
||||||
|
{
|
||||||
|
pl = plugin;
|
||||||
|
idx = index;
|
||||||
|
}
|
||||||
|
CPlugin *pl;
|
||||||
|
uint32_t idx;
|
||||||
|
};
|
||||||
|
|
||||||
class CPlugin : public IPlugin
|
class CPlugin : public IPlugin
|
||||||
{
|
{
|
||||||
friend class CPluginManager;
|
friend class CPluginManager;
|
||||||
@ -234,9 +246,9 @@ public:
|
|||||||
void AddConfig(bool autoCreate, const char *cfg, const char *folder);
|
void AddConfig(bool autoCreate, const char *cfg, const char *folder);
|
||||||
unsigned int GetConfigCount();
|
unsigned int GetConfigCount();
|
||||||
AutoConfig *GetConfig(unsigned int i);
|
AutoConfig *GetConfig(unsigned int i);
|
||||||
inline bool IsInAskPluginLoad()
|
inline void AddLibrary(const char *name)
|
||||||
{
|
{
|
||||||
return m_IsInAskPluginLoad;
|
m_Libraries.push_back(name);
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
void UpdateInfo();
|
void UpdateInfo();
|
||||||
@ -259,10 +271,13 @@ private:
|
|||||||
List<CPlugin *> m_dependents;
|
List<CPlugin *> m_dependents;
|
||||||
List<CPlugin *> m_dependsOn;
|
List<CPlugin *> m_dependsOn;
|
||||||
List<FakeNative *> m_fakeNatives;
|
List<FakeNative *> m_fakeNatives;
|
||||||
|
List<WeakNative *> m_WeakNatives;
|
||||||
|
List<String> m_RequiredLibs;
|
||||||
|
List<String> m_Libraries;
|
||||||
Trie *m_pProps;
|
Trie *m_pProps;
|
||||||
bool m_FakeNativesMissing;
|
bool m_FakeNativesMissing;
|
||||||
|
bool m_LibraryMissing;
|
||||||
CVector<AutoConfig *> m_configs;
|
CVector<AutoConfig *> m_configs;
|
||||||
bool m_IsInAskPluginLoad;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CPluginManager :
|
class CPluginManager :
|
||||||
@ -413,6 +428,11 @@ private:
|
|||||||
*/
|
*/
|
||||||
bool LoadOrRequireExtensions(CPlugin *pPlugin, unsigned int pass, char *error, size_t maxlength);
|
bool LoadOrRequireExtensions(CPlugin *pPlugin, unsigned int pass, char *error, size_t maxlength);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manages required natives.
|
||||||
|
*/
|
||||||
|
bool FindOrRequirePluginDeps(CPlugin *pPlugin, char *error, size_t maxlength);
|
||||||
|
|
||||||
void _SetPauseState(CPlugin *pPlugin, bool pause);
|
void _SetPauseState(CPlugin *pPlugin, bool pause);
|
||||||
|
|
||||||
void ExecAndGenPluginConfs();
|
void ExecAndGenPluginConfs();
|
||||||
@ -430,7 +450,7 @@ public:
|
|||||||
bool AddFakeNative(IPluginFunction *pFunction, const char *name, SPVM_FAKENATIVE_FUNC func);
|
bool AddFakeNative(IPluginFunction *pFunction, const char *name, SPVM_FAKENATIVE_FUNC func);
|
||||||
private:
|
private:
|
||||||
void AddFakeNativesToPlugin(CPlugin *pPlugin);
|
void AddFakeNativesToPlugin(CPlugin *pPlugin);
|
||||||
void TryRefreshNatives(CPlugin *pOther);
|
void TryRefreshDependencies(CPlugin *pOther);
|
||||||
private:
|
private:
|
||||||
List<IPluginsListener *> m_listeners;
|
List<IPluginsListener *> m_listeners;
|
||||||
List<CPlugin *> m_plugins;
|
List<CPlugin *> m_plugins;
|
||||||
|
@ -329,5 +329,24 @@ native GetSysTickCount();
|
|||||||
*/
|
*/
|
||||||
native AutoExecConfig(bool:autoCreate=true, const String:name[]="", const String:folder[]="sourcemod");
|
native AutoExecConfig(bool:autoCreate=true, const String:name[]="", const String:folder[]="sourcemod");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a native as optional, such that if it is unloaded, removed,
|
||||||
|
* or otherwise non-existent, the plugin will still work. Calling
|
||||||
|
* removed natives results in a run-time error.
|
||||||
|
*
|
||||||
|
* @param name Native name.
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
native MarkNativeAsOptional(const String:name[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a library name for identifying as a dependency to
|
||||||
|
* other plugins.
|
||||||
|
*
|
||||||
|
* @param name Library name.
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
native RegPluginLibrary(const String:name[]);
|
||||||
|
|
||||||
#include <helpers>
|
#include <helpers>
|
||||||
#include <entity>
|
#include <entity>
|
||||||
|
Loading…
Reference in New Issue
Block a user