Add AskPluginLoad2() to allow silent failure, deprecate AskPluginLoad() (bug 3716, r=dvander)
This commit is contained in:
parent
81e30e75c4
commit
d7917a6a9a
@ -57,6 +57,7 @@ CPlugin::CPlugin(const char *file)
|
||||
|
||||
m_type = PluginType_Private;
|
||||
m_status = Plugin_Uncompiled;
|
||||
m_bSilentlyFailed = false;
|
||||
m_serial = ++MySerial;
|
||||
m_pRuntime = NULL;
|
||||
m_errormsg[256] = '\0';
|
||||
@ -386,22 +387,27 @@ void CPlugin::Call_OnAllPluginsLoaded()
|
||||
}
|
||||
}
|
||||
|
||||
bool CPlugin::Call_AskPluginLoad(char *error, size_t maxlength)
|
||||
APLRes CPlugin::Call_AskPluginLoad(char *error, size_t maxlength)
|
||||
{
|
||||
if (m_status != Plugin_Created)
|
||||
{
|
||||
return false;
|
||||
return APLRes_Failure;
|
||||
}
|
||||
|
||||
m_status = Plugin_Loaded;
|
||||
|
||||
int err;
|
||||
cell_t result;
|
||||
IPluginFunction *pFunction = m_pRuntime->GetFunctionByName("AskPluginLoad");
|
||||
bool haveNewAPL = false;
|
||||
IPluginFunction *pFunction = m_pRuntime->GetFunctionByName("AskPluginLoad2");
|
||||
|
||||
if (!pFunction)
|
||||
if (pFunction)
|
||||
{
|
||||
return true;
|
||||
haveNewAPL = true;
|
||||
}
|
||||
else if (!(pFunction = m_pRuntime->GetFunctionByName("AskPluginLoad")))
|
||||
{
|
||||
return APLRes_Success;
|
||||
}
|
||||
|
||||
pFunction->PushCell(m_handle);
|
||||
@ -410,15 +416,21 @@ bool CPlugin::Call_AskPluginLoad(char *error, size_t maxlength)
|
||||
pFunction->PushCell(maxlength);
|
||||
if ((err=pFunction->Execute(&result)) != SP_ERROR_NONE)
|
||||
{
|
||||
return false;
|
||||
return APLRes_Failure;
|
||||
}
|
||||
|
||||
if (!result || m_status != Plugin_Loaded)
|
||||
if (haveNewAPL)
|
||||
{
|
||||
return false;
|
||||
return (APLRes)result;
|
||||
}
|
||||
else if (result)
|
||||
{
|
||||
return APLRes_Success;
|
||||
}
|
||||
else
|
||||
{
|
||||
return APLRes_Failure;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void *CPlugin::GetPluginStructure()
|
||||
@ -470,6 +482,11 @@ PluginStatus CPlugin::GetStatus()
|
||||
return m_status;
|
||||
}
|
||||
|
||||
bool CPlugin::IsSilentlyFailed()
|
||||
{
|
||||
return m_bSilentlyFailed;
|
||||
}
|
||||
|
||||
bool CPlugin::IsDebugging()
|
||||
{
|
||||
if (m_pRuntime == NULL)
|
||||
@ -480,6 +497,11 @@ bool CPlugin::IsDebugging()
|
||||
return true;
|
||||
}
|
||||
|
||||
void CPlugin::SetSilentlyFailed(bool sf)
|
||||
{
|
||||
m_bSilentlyFailed = sf;
|
||||
}
|
||||
|
||||
void CPlugin::LibraryActions(bool dropping)
|
||||
{
|
||||
List<String>::iterator iter;
|
||||
@ -1004,20 +1026,31 @@ LoadRes CPluginManager::_LoadPlugin(CPlugin **_plugin, const char *path, bool de
|
||||
}
|
||||
}
|
||||
|
||||
LoadRes loadFailure = LoadRes_Failure;
|
||||
/* Get the status */
|
||||
if (pPlugin->GetStatus() == Plugin_Created)
|
||||
{
|
||||
/* First native pass - add anything from Core */
|
||||
g_ShareSys.BindNativesToPlugin(pPlugin, true);
|
||||
pPlugin->InitIdentity();
|
||||
if (pPlugin->Call_AskPluginLoad(error, maxlength))
|
||||
APLRes result = pPlugin->Call_AskPluginLoad(error, maxlength);
|
||||
switch (result)
|
||||
{
|
||||
case APLRes_Success:
|
||||
/* Autoload any modules */
|
||||
LoadOrRequireExtensions(pPlugin, 1, error, maxlength);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
case APLRes_Failure:
|
||||
pPlugin->SetErrorState(Plugin_Failed, "%s", error);
|
||||
loadFailure = LoadRes_Failure;
|
||||
break;
|
||||
case APLRes_SilentFailure:
|
||||
pPlugin->SetErrorState(Plugin_Failed, "%s", error);
|
||||
loadFailure = LoadRes_SilentFailure;
|
||||
pPlugin->SetSilentlyFailed(true);
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1030,7 +1063,7 @@ LoadRes CPluginManager::_LoadPlugin(CPlugin **_plugin, const char *path, bool de
|
||||
*_plugin = pPlugin;
|
||||
}
|
||||
|
||||
return (pPlugin->GetStatus() == Plugin_Loaded) ? LoadRes_Successful : LoadRes_Failure;
|
||||
return (pPlugin->GetStatus() == Plugin_Loaded) ? LoadRes_Successful : loadFailure;
|
||||
}
|
||||
|
||||
IPlugin *CPluginManager::LoadPlugin(const char *path, bool debug, PluginType type, char error[], size_t maxlength, bool *wasloaded)
|
||||
@ -1095,7 +1128,7 @@ void CPluginManager::LoadAutoPlugin(const char *plugin)
|
||||
error);
|
||||
}
|
||||
|
||||
if (res == LoadRes_Successful || res == LoadRes_Failure)
|
||||
if (res == LoadRes_Successful || res == LoadRes_Failure || res == LoadRes_SilentFailure)
|
||||
{
|
||||
AddPlugin(pl);
|
||||
}
|
||||
@ -1951,7 +1984,7 @@ void CPluginManager::OnRootConsoleCommand(const char *cmdname, const CCommand &c
|
||||
assert(pl->GetStatus() != Plugin_Created);
|
||||
int len = 0;
|
||||
const sm_plugininfo_t *info = pl->GetPublicInfo();
|
||||
if (pl->GetStatus() != Plugin_Running)
|
||||
if (pl->GetStatus() != Plugin_Running && !pl->IsSilentlyFailed())
|
||||
{
|
||||
len += UTIL_Format(buffer, sizeof(buffer), " %02d <%s>", id, GetStatusText(pl->GetStatus()));
|
||||
|
||||
@ -1967,6 +2000,8 @@ void CPluginManager::OnRootConsoleCommand(const char *cmdname, const CCommand &c
|
||||
}
|
||||
if (pl->GetStatus() < Plugin_Created)
|
||||
{
|
||||
if (pl->IsSilentlyFailed())
|
||||
len += UTIL_Format(&buffer[len], sizeof(buffer)-len, " Disabled:");
|
||||
len += UTIL_Format(&buffer[len], sizeof(buffer)-len, " \"%s\"", (IS_STR_FILLED(info->name)) ? info->name : pl->GetFilename());
|
||||
if (IS_STR_FILLED(info->version))
|
||||
{
|
||||
|
@ -117,9 +117,17 @@ enum LoadRes
|
||||
LoadRes_Successful,
|
||||
LoadRes_AlreadyLoaded,
|
||||
LoadRes_Failure,
|
||||
LoadRes_SilentFailure,
|
||||
LoadRes_NeverLoad
|
||||
};
|
||||
|
||||
enum APLRes
|
||||
{
|
||||
APLRes_Success,
|
||||
APLRes_Failure,
|
||||
APLRes_SilentFailure
|
||||
};
|
||||
|
||||
struct AutoConfig
|
||||
{
|
||||
String autocfg;
|
||||
@ -146,6 +154,8 @@ public:
|
||||
const char *GetFilename();
|
||||
bool IsDebugging();
|
||||
PluginStatus GetStatus();
|
||||
bool IsSilentlyFailed();
|
||||
void SetSilentlyFailed(bool sf);
|
||||
const sm_plugininfo_t *GetPublicInfo();
|
||||
bool SetPauseState(bool paused);
|
||||
unsigned int GetSerial();
|
||||
@ -183,7 +193,7 @@ public:
|
||||
*
|
||||
* If the error buffer is NULL, the error message is cached locally.
|
||||
*/
|
||||
bool Call_AskPluginLoad(char *error, size_t maxlength);
|
||||
APLRes Call_AskPluginLoad(char *error, size_t maxlength);
|
||||
|
||||
/**
|
||||
* Calls the OnPluginStart function.
|
||||
@ -247,6 +257,7 @@ private:
|
||||
PluginType m_type;
|
||||
char m_filename[PLATFORM_MAX_PATH];
|
||||
PluginStatus m_status;
|
||||
bool m_bSilentlyFailed;
|
||||
unsigned int m_serial;
|
||||
sm_plugininfo_t m_info;
|
||||
char m_errormsg[256];
|
||||
|
@ -74,6 +74,13 @@ struct Plugin
|
||||
#include <commandfilters>
|
||||
#include <nextmap>
|
||||
|
||||
enum APLRes
|
||||
{
|
||||
APLRes_Success = 0, /**< Plugin should load */
|
||||
APLRes_Failure, /**< Plugin shouldn't load and should display an error */
|
||||
APLRes_SilentFailure /**< Plugin shouldn't load but do so silently */
|
||||
};
|
||||
|
||||
/**
|
||||
* Declare this as a struct in your plugin to expose its information.
|
||||
* Example:
|
||||
@ -101,26 +108,35 @@ public Plugin:myinfo;
|
||||
* @noreturn
|
||||
*/
|
||||
forward OnPluginStart();
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use AskPluginLoad2() instead.
|
||||
* If a plugin contains both AskPluginLoad() and AskPluginLoad2(), the former will
|
||||
* not be called, but old plugins with only AskPluginLoad() will work.
|
||||
*/
|
||||
#pragma deprecated Use AskPluginLoad2() instead
|
||||
forward bool:AskPluginLoad(Handle:myself, bool:late, String:error[], err_max);
|
||||
|
||||
/**
|
||||
* Called before OnPluginStart, in case the plugin wants to check for load failure.
|
||||
* This is called even if the plugin type is "private." Any natives from modules are
|
||||
* not available at this point. Thus, this forward should only be used for explicit
|
||||
* pre-emptive things, such as adding dynamic natives, or setting certain types of load filters.
|
||||
* pre-emptive things, such as adding dynamic natives, setting certain types of load
|
||||
* filters (such as not loading the plugin for certain games).
|
||||
*
|
||||
* @note It is not safe to call externally resolved natives until OnPluginStart().
|
||||
* @note Any sort of RTE in this function will cause the plugin to fail loading.
|
||||
* @note You MUST remember to return SOMETHING here. The act of not returning is
|
||||
* equivalent to returning 0 (false). If you forgot to return, it will
|
||||
* cause your plugin to not load with a very strange error message.
|
||||
* @note If you do not return anything, it is treated like returning success.
|
||||
* @note If a plugin has an AskPluginLoad2(), AskPluginLoad() will not be called.
|
||||
*
|
||||
*
|
||||
* @param myself Handle to the plugin.
|
||||
* @param late Whether or not the plugin was loaded "late" (after map load).
|
||||
* @param error Error message buffer in case load failed.
|
||||
* @param err_max Maximum number of characters for error message buffer.
|
||||
* @return True if load success, false otherwise.
|
||||
* @return APLRes_Success for load success, APLRes_Failure or APLRes_SilentFailure otherwise
|
||||
*/
|
||||
forward bool:AskPluginLoad(Handle:myself, bool:late, String:error[], err_max);
|
||||
forward APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max);
|
||||
|
||||
/**
|
||||
* Called when the plugin is about to be unloaded.
|
||||
|
Loading…
Reference in New Issue
Block a user