initial import of extension API and SDK as well as auto-loading
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40303
This commit is contained in:
parent
f7545a848f
commit
03277707b5
@ -14,6 +14,11 @@ namespace SourceMod
|
|||||||
class IExtension
|
class IExtension
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Returns whether or not the extension is properly loaded.
|
||||||
|
*/
|
||||||
|
virtual bool IsLoaded() =0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the extension's API interface
|
* @brief Returns the extension's API interface
|
||||||
*
|
*
|
||||||
@ -128,7 +133,7 @@ namespace SourceMod
|
|||||||
* @param err_max Maximum error buffer length.
|
* @param err_max Maximum error buffer length.
|
||||||
* @return New IExtension on success, NULL on failure.
|
* @return New IExtension on success, NULL on failure.
|
||||||
*/
|
*/
|
||||||
virtual IExtension *LoadModule(const char *path,
|
virtual IExtension *LoadExtension(const char *path,
|
||||||
ExtensionLifetime lifetime,
|
ExtensionLifetime lifetime,
|
||||||
char *error,
|
char *error,
|
||||||
size_t err_max) =0;
|
size_t err_max) =0;
|
||||||
@ -158,7 +163,7 @@ namespace SourceMod
|
|||||||
* @param pExt IExtension pointer.
|
* @param pExt IExtension pointer.
|
||||||
* @return True if successful, false otherwise.
|
* @return True if successful, false otherwise.
|
||||||
*/
|
*/
|
||||||
virtual bool UnloadModule(IExtension *pExt) =0;
|
virtual bool UnloadExtension(IExtension *pExt) =0;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
222
core/systems/ExtensionSys.cpp
Normal file
222
core/systems/ExtensionSys.cpp
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
#include "ExtensionSys.h"
|
||||||
|
#include "LibrarySys.h"
|
||||||
|
#include "ShareSys.h"
|
||||||
|
#include "CLogger.h"
|
||||||
|
|
||||||
|
CExtensionManager g_Extensions;
|
||||||
|
IdentityType_t g_ExtType;
|
||||||
|
|
||||||
|
CExtension::CExtension(const char *filename, char *error, size_t err_max)
|
||||||
|
{
|
||||||
|
m_File.assign(filename);
|
||||||
|
m_pAPI = NULL;
|
||||||
|
m_pIdentToken = NULL;
|
||||||
|
|
||||||
|
char path[PLATFORM_MAX_PATH+1];
|
||||||
|
g_LibSys.PathFormat(path, PLATFORM_MAX_PATH, "%s/extensions/%s", g_SourceMod.GetSMBaseDir(), filename);
|
||||||
|
|
||||||
|
m_pLib = g_LibSys.OpenLibrary(path, error, err_max);
|
||||||
|
|
||||||
|
if (m_pLib == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef IExtensionInterface *(*GETAPI)();
|
||||||
|
GETAPI pfnGetAPI = NULL;
|
||||||
|
|
||||||
|
if ((pfnGetAPI=(GETAPI)m_pLib->GetSymbolAddress("GetSMExtAPI")) == NULL)
|
||||||
|
{
|
||||||
|
m_pLib->CloseLibrary();
|
||||||
|
m_pLib = NULL;
|
||||||
|
snprintf(error, err_max, "Unable to find extension entry point");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pAPI = pfnGetAPI();
|
||||||
|
if (!m_pAPI || m_pAPI->GetExtensionVersion() > SMINTERFACE_EXTENSIONAPI_VERSION)
|
||||||
|
{
|
||||||
|
m_pLib->CloseLibrary();
|
||||||
|
m_pLib = NULL;
|
||||||
|
snprintf(error, err_max, "Extension version is too new to load (%d, max is %d)", m_pAPI->GetExtensionVersion(), SMINTERFACE_EXTENSIONAPI_VERSION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_pAPI->IsMetamodExtension())
|
||||||
|
{
|
||||||
|
/* :TODO: STUFF */
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pIdentToken = g_ShareSys.CreateIdentity(g_ExtType);
|
||||||
|
|
||||||
|
if (!m_pAPI->OnExtensionLoad(this, &g_ShareSys, error, err_max, g_SourceMod.IsLateLoadInMap()))
|
||||||
|
{
|
||||||
|
if (m_pAPI->IsMetamodExtension())
|
||||||
|
{
|
||||||
|
/* :TODO: stuff */
|
||||||
|
}
|
||||||
|
m_pAPI = NULL;
|
||||||
|
m_pLib->CloseLibrary();
|
||||||
|
m_pLib = NULL;
|
||||||
|
g_ShareSys.DestroyIdentity(m_pIdentToken);
|
||||||
|
m_pIdentToken = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CExtension::~CExtension()
|
||||||
|
{
|
||||||
|
if (m_pAPI)
|
||||||
|
{
|
||||||
|
m_pAPI->OnExtensionUnload();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_pIdentToken)
|
||||||
|
{
|
||||||
|
g_ShareSys.DestroyIdentity(m_pIdentToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_pLib)
|
||||||
|
{
|
||||||
|
m_pLib->CloseLibrary();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CExtension::SetError(const char *error)
|
||||||
|
{
|
||||||
|
m_Error.assign(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
IExtensionInterface *CExtension::GetAPI()
|
||||||
|
{
|
||||||
|
return m_pAPI;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *CExtension::GetFilename()
|
||||||
|
{
|
||||||
|
return m_File.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
IdentityToken_t *CExtension::GetIdentity()
|
||||||
|
{
|
||||||
|
return m_pIdentToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CExtension::IsLoaded()
|
||||||
|
{
|
||||||
|
return (m_pLib != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CExtensionManager::OnSourceModAllInitialized()
|
||||||
|
{
|
||||||
|
g_ExtType = g_ShareSys.CreateIdentType("EXTENSION");
|
||||||
|
}
|
||||||
|
|
||||||
|
void CExtensionManager::OnSourceModShutdown()
|
||||||
|
{
|
||||||
|
g_ShareSys.DestroyIdentType(g_ExtType);
|
||||||
|
}
|
||||||
|
|
||||||
|
IExtension *CExtensionManager::LoadAutoExtension(const char *path)
|
||||||
|
{
|
||||||
|
char error[256];
|
||||||
|
CExtension *p = new CExtension(path, error, sizeof(error));
|
||||||
|
|
||||||
|
if (!p->IsLoaded())
|
||||||
|
{
|
||||||
|
g_Logger.LogError("[SOURCEMOD] Unable to load extension \"%s\": %s", path, error);
|
||||||
|
p->SetError(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Libs.push_back(p);
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
IExtension *CExtensionManager::FindExtensionByFile(const char *file)
|
||||||
|
{
|
||||||
|
List<CExtension *>::iterator iter;
|
||||||
|
CExtension *pExt;
|
||||||
|
|
||||||
|
/* Make sure the file direction is right */
|
||||||
|
char path[PLATFORM_MAX_PATH+1];
|
||||||
|
g_LibSys.PathFormat(path, PLATFORM_MAX_PATH, "%s", file);
|
||||||
|
|
||||||
|
for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++)
|
||||||
|
{
|
||||||
|
pExt = (*iter);
|
||||||
|
if (strcmp(pExt->GetFilename(), path) == 0)
|
||||||
|
{
|
||||||
|
return pExt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
IExtension *CExtensionManager::FindExtensionByName(const char *ext)
|
||||||
|
{
|
||||||
|
List<CExtension *>::iterator iter;
|
||||||
|
CExtension *pExt;
|
||||||
|
IExtensionInterface *pAPI;
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++)
|
||||||
|
{
|
||||||
|
pExt = (*iter);
|
||||||
|
if (!pExt->IsLoaded())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((pAPI = pExt->GetAPI()) == NULL)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
name = pAPI->GetExtensionName();
|
||||||
|
if (!name)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (strcmp(name, ext) == 0)
|
||||||
|
{
|
||||||
|
return pExt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
IExtension *CExtensionManager::LoadExtension(const char *file, ExtensionLifetime lifetime, char *error, size_t err_max)
|
||||||
|
{
|
||||||
|
CExtension *pExt = new CExtension(file, error, err_max);
|
||||||
|
|
||||||
|
/* :NOTE: lifetime is currently ignored */
|
||||||
|
|
||||||
|
if (!pExt->IsLoaded())
|
||||||
|
{
|
||||||
|
delete pExt;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Libs.push_back(pExt);
|
||||||
|
|
||||||
|
return pExt;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CExtensionManager::UnloadExtension(IExtension *pExt)
|
||||||
|
{
|
||||||
|
/* :TODO: implement */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int CExtensionManager::NumberOfPluginDependents(IExtension *pExt, unsigned int *optional)
|
||||||
|
{
|
||||||
|
/* :TODO: implement */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CExtensionManager::IsExtensionUnloadable(IExtension *pExtension)
|
||||||
|
{
|
||||||
|
/* :TODO: implement */
|
||||||
|
return true;
|
||||||
|
}
|
58
core/systems/ExtensionSys.h
Normal file
58
core/systems/ExtensionSys.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#ifndef _INCLUDE_SOURCEMOD_EXTENSION_SYSTEM_H_
|
||||||
|
#define _INCLUDE_SOURCEMOD_EXTENSION_SYSTEM_H_
|
||||||
|
|
||||||
|
#include <IExtensionSys.h>
|
||||||
|
#include <ILibrarySys.h>
|
||||||
|
#include <sh_list.h>
|
||||||
|
#include <sh_string.h>
|
||||||
|
#include "sm_globals.h"
|
||||||
|
|
||||||
|
using namespace SourceMod;
|
||||||
|
using namespace SourceHook;
|
||||||
|
|
||||||
|
class CExtension : public IExtension
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CExtension(const char *filename, char *error, size_t maxlen);
|
||||||
|
~CExtension();
|
||||||
|
public: //IExtension
|
||||||
|
IExtensionInterface *GetAPI();
|
||||||
|
const char *GetFilename();
|
||||||
|
IdentityToken_t *GetIdentity();
|
||||||
|
bool IsLoaded();
|
||||||
|
public:
|
||||||
|
void SetError(const char *error);
|
||||||
|
private:
|
||||||
|
IdentityToken_t *m_pIdentToken;
|
||||||
|
IExtensionInterface *m_pAPI;
|
||||||
|
String m_File;
|
||||||
|
ILibrary *m_pLib;
|
||||||
|
String m_Error;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CExtensionManager :
|
||||||
|
public IExtensionManager,
|
||||||
|
public SMGlobalClass
|
||||||
|
{
|
||||||
|
public: //SMGlobalClass
|
||||||
|
void OnSourceModAllInitialized();
|
||||||
|
void OnSourceModShutdown();
|
||||||
|
public: //IExtensionManager
|
||||||
|
IExtension *LoadExtension(const char *path,
|
||||||
|
ExtensionLifetime lifetime,
|
||||||
|
char *error,
|
||||||
|
size_t err_max);
|
||||||
|
unsigned int NumberOfPluginDependents(IExtension *pExt, unsigned int *optional);
|
||||||
|
bool IsExtensionUnloadable(IExtension *pExtension);
|
||||||
|
bool UnloadExtension(IExtension *pExt);
|
||||||
|
IExtension *FindExtensionByFile(const char *file);
|
||||||
|
IExtension *FindExtensionByName(const char *ext);
|
||||||
|
public:
|
||||||
|
IExtension *LoadAutoExtension(const char *path);
|
||||||
|
private:
|
||||||
|
List<CExtension *> m_Libs;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern CExtensionManager g_Extensions;
|
||||||
|
|
||||||
|
#endif //_INCLUDE_SOURCEMOD_EXTENSION_SYSTEM_H_
|
@ -7,6 +7,7 @@
|
|||||||
#include "sourcemod.h"
|
#include "sourcemod.h"
|
||||||
#include "CTextParsers.h"
|
#include "CTextParsers.h"
|
||||||
#include "CLogger.h"
|
#include "CLogger.h"
|
||||||
|
#include "ExtensionSys.h"
|
||||||
|
|
||||||
CPluginManager g_PluginSys;
|
CPluginManager g_PluginSys;
|
||||||
HandleType_t g_PluginType = 0;
|
HandleType_t g_PluginType = 0;
|
||||||
@ -31,6 +32,16 @@ CPlugin::CPlugin(const char *file)
|
|||||||
|
|
||||||
CPlugin::~CPlugin()
|
CPlugin::~CPlugin()
|
||||||
{
|
{
|
||||||
|
if (m_handle)
|
||||||
|
{
|
||||||
|
HandleSecurity sec;
|
||||||
|
sec.pOwner = g_PluginSys.GetIdentity();
|
||||||
|
sec.pIdentity = sec.pOwner;
|
||||||
|
|
||||||
|
g_HandleSys.FreeHandle(m_handle, &sec);
|
||||||
|
g_ShareSys.DestroyIdentity(m_ident);
|
||||||
|
}
|
||||||
|
|
||||||
if (m_ctx.base)
|
if (m_ctx.base)
|
||||||
{
|
{
|
||||||
delete m_ctx.base;
|
delete m_ctx.base;
|
||||||
@ -72,16 +83,6 @@ CPlugin::~CPlugin()
|
|||||||
g_pSourcePawn->FreeFromMemory(m_plugin);
|
g_pSourcePawn->FreeFromMemory(m_plugin);
|
||||||
m_plugin = NULL;
|
m_plugin = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_handle)
|
|
||||||
{
|
|
||||||
HandleSecurity sec;
|
|
||||||
sec.pOwner = g_PluginSys.GetIdentity();
|
|
||||||
sec.pIdentity = sec.pOwner;
|
|
||||||
|
|
||||||
g_HandleSys.FreeHandle(m_handle, &sec);
|
|
||||||
g_ShareSys.DestroyIdentity(m_ident);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlugin::InitIdentity()
|
void CPlugin::InitIdentity()
|
||||||
@ -100,19 +101,17 @@ CPlugin *CPlugin::CreatePlugin(const char *file, char *error, size_t maxlength)
|
|||||||
g_LibSys.PathFormat(fullpath, sizeof(fullpath), "%s/plugins/%s", g_SourceMod.GetSMBaseDir(), file);
|
g_LibSys.PathFormat(fullpath, sizeof(fullpath), "%s/plugins/%s", g_SourceMod.GetSMBaseDir(), file);
|
||||||
FILE *fp = fopen(fullpath, "rb");
|
FILE *fp = fopen(fullpath, "rb");
|
||||||
|
|
||||||
|
CPlugin *pPlugin = new CPlugin(file);
|
||||||
|
|
||||||
if (!fp)
|
if (!fp)
|
||||||
{
|
{
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
snprintf(error, maxlength, "Unable to open file");
|
snprintf(error, maxlength, "Unable to open file");
|
||||||
return NULL;
|
}
|
||||||
} else {
|
|
||||||
CPlugin *pPlugin = new CPlugin(file);
|
|
||||||
snprintf(pPlugin->m_errormsg, sizeof(pPlugin->m_errormsg), "Unable to open file");
|
|
||||||
pPlugin->m_status = Plugin_BadLoad;
|
pPlugin->m_status = Plugin_BadLoad;
|
||||||
return pPlugin;
|
return pPlugin;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
int err;
|
int err;
|
||||||
sp_plugin_t *pl = g_pSourcePawn->LoadFromFilePointer(fp, &err);
|
sp_plugin_t *pl = g_pSourcePawn->LoadFromFilePointer(fp, &err);
|
||||||
@ -122,19 +121,15 @@ CPlugin *CPlugin::CreatePlugin(const char *file, char *error, size_t maxlength)
|
|||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
snprintf(error, maxlength, "Error %d while parsing plugin", err);
|
snprintf(error, maxlength, "Error %d while parsing plugin", err);
|
||||||
return NULL;
|
}
|
||||||
} else {
|
|
||||||
CPlugin *pPlugin = new CPlugin(file);
|
|
||||||
snprintf(pPlugin->m_errormsg, sizeof(pPlugin->m_errormsg), "Error %d while parsing plugin", err);
|
|
||||||
pPlugin->m_status = Plugin_BadLoad;
|
pPlugin->m_status = Plugin_BadLoad;
|
||||||
return pPlugin;
|
return pPlugin;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
CPlugin *pPlugin = new CPlugin(file);
|
|
||||||
pPlugin->m_plugin = pl;
|
pPlugin->m_plugin = pl;
|
||||||
|
|
||||||
return pPlugin;
|
return pPlugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,10 +180,8 @@ bool CPlugin::FinishMyCompile(char *error, size_t maxlength)
|
|||||||
if (!m_ctx.ctx)
|
if (!m_ctx.ctx)
|
||||||
{
|
{
|
||||||
memset(&m_ctx, 0, sizeof(m_ctx));
|
memset(&m_ctx, 0, sizeof(m_ctx));
|
||||||
if (!error)
|
if (error)
|
||||||
{
|
{
|
||||||
SetErrorState(Plugin_Failed, "Failed to compile (error %d)", err);
|
|
||||||
} else {
|
|
||||||
snprintf(error, maxlength, "Failed to compile (error %d)", err);
|
snprintf(error, maxlength, "Failed to compile (error %d)", err);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -377,12 +370,6 @@ bool CPlugin::Call_AskPluginLoad(char *error, size_t maxlength)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!error)
|
|
||||||
{
|
|
||||||
error = m_errormsg;
|
|
||||||
maxlength = sizeof(m_errormsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_status = Plugin_Loaded;
|
m_status = Plugin_Loaded;
|
||||||
|
|
||||||
int err;
|
int err;
|
||||||
@ -676,20 +663,20 @@ void CPluginManager::LoadPluginsFromDir(const char *basedir, const char *localpa
|
|||||||
|
|
||||||
//well i have discovered that gabe newell is very fat, so i wrote this comment now
|
//well i have discovered that gabe newell is very fat, so i wrote this comment now
|
||||||
//:TODO: remove this function, create a better wrapper for LoadPlugin()/LoadAutoPlugin()
|
//:TODO: remove this function, create a better wrapper for LoadPlugin()/LoadAutoPlugin()
|
||||||
void CPluginManager::LoadAutoPlugin(const char *file)
|
bool CPluginManager::_LoadPlugin(CPlugin **_plugin, const char *path, bool debug, PluginType type, char error[], size_t err_max)
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Does this plugin already exist?
|
* Does this plugin already exist?
|
||||||
*/
|
*/
|
||||||
CPlugin *pPlugin;
|
CPlugin *pPlugin;
|
||||||
if (sm_trie_retrieve(m_LoadLookup, file, (void **)&pPlugin))
|
if (sm_trie_retrieve(m_LoadLookup, path, (void **)&pPlugin))
|
||||||
{
|
{
|
||||||
/* First check the type */
|
/* First check the type */
|
||||||
PluginType type = pPlugin->GetType();
|
PluginType type = pPlugin->GetType();
|
||||||
if (type == PluginType_Private
|
if (type == PluginType_Private
|
||||||
|| type == PluginType_Global)
|
|| type == PluginType_Global)
|
||||||
{
|
{
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
/* Check to see if we should try reloading it */
|
/* Check to see if we should try reloading it */
|
||||||
if (pPlugin->GetStatus() == Plugin_BadLoad
|
if (pPlugin->GetStatus() == Plugin_BadLoad
|
||||||
@ -700,7 +687,7 @@ void CPluginManager::LoadAutoPlugin(const char *file)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pPlugin = CPlugin::CreatePlugin(file, NULL, 0);
|
pPlugin = CPlugin::CreatePlugin(path, error, err_max);
|
||||||
|
|
||||||
assert(pPlugin != NULL);
|
assert(pPlugin != NULL);
|
||||||
|
|
||||||
@ -717,8 +704,7 @@ void CPluginManager::LoadAutoPlugin(const char *file)
|
|||||||
unsigned int setcount = m_PluginInfo.GetSettingsNum();
|
unsigned int setcount = m_PluginInfo.GetSettingsNum();
|
||||||
for (unsigned int i=0; i<setcount; i++)
|
for (unsigned int i=0; i<setcount; i++)
|
||||||
{
|
{
|
||||||
pset = m_PluginInfo.GetSettingsIfMatch(i, file);
|
if ((pset=m_PluginInfo.GetSettingsIfMatch(i, path)) == NULL)
|
||||||
if (!pset)
|
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -735,8 +721,12 @@ void CPluginManager::LoadAutoPlugin(const char *file)
|
|||||||
}
|
}
|
||||||
if (!g_pVM->SetCompilationOption(co, key, val))
|
if (!g_pVM->SetCompilationOption(co, key, val))
|
||||||
{
|
{
|
||||||
pPlugin->SetErrorState(Plugin_Failed, "Unable to set option (key \"%s\") (value \"%s\")", key, val);
|
if (error)
|
||||||
|
{
|
||||||
|
snprintf(error, err_max, "Unable to set JIT option (key \"%s\") (value \"%s\")", key, val);
|
||||||
|
}
|
||||||
pPlugin->CancelMyCompile();
|
pPlugin->CancelMyCompile();
|
||||||
|
pPlugin->m_status = Plugin_Failed;
|
||||||
co = NULL;
|
co = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -744,100 +734,71 @@ void CPluginManager::LoadAutoPlugin(const char *file)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Do the actual compiling */
|
||||||
if (co)
|
if (co)
|
||||||
{
|
{
|
||||||
pPlugin->FinishMyCompile(NULL, 0);
|
pPlugin->FinishMyCompile(NULL, 0);
|
||||||
co = NULL;
|
co = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We don't care about the return value */
|
/* Get the status */
|
||||||
if (pPlugin->GetStatus() == Plugin_Created)
|
if (pPlugin->GetStatus() == Plugin_Created)
|
||||||
{
|
{
|
||||||
AddCoreNativesToPlugin(pPlugin);
|
AddCoreNativesToPlugin(pPlugin);
|
||||||
pPlugin->InitIdentity();
|
pPlugin->InitIdentity();
|
||||||
pPlugin->Call_AskPluginLoad(NULL, 0);
|
pPlugin->Call_AskPluginLoad(error, err_max);
|
||||||
}
|
}
|
||||||
|
|
||||||
AddPlugin(pPlugin);
|
if (_plugin)
|
||||||
|
{
|
||||||
|
*_plugin = pPlugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (pPlugin->GetStatus() == Plugin_Loaded);
|
||||||
}
|
}
|
||||||
|
|
||||||
IPlugin *CPluginManager::LoadPlugin(const char *path, bool debug, PluginType type, char error[], size_t err_max)
|
IPlugin *CPluginManager::LoadPlugin(const char *path, bool debug, PluginType type, char error[], size_t err_max)
|
||||||
{
|
{
|
||||||
/* See if this plugin is already loaded... reformat to get sep chars right */
|
CPlugin *pl;
|
||||||
char checkpath[PLATFORM_MAX_PATH+1];
|
|
||||||
g_LibSys.PathFormat(checkpath, sizeof(checkpath), "%s", path);
|
|
||||||
|
|
||||||
/**
|
if (!_LoadPlugin(&pl, path, debug, type, error, err_max))
|
||||||
* In manually loading a plugin, any sort of load error causes a deletion.
|
|
||||||
* This is because it's assumed manually loaded plugins will not be managed.
|
|
||||||
* For managed plugins, we need the UI to report them properly.
|
|
||||||
*/
|
|
||||||
|
|
||||||
CPlugin *pPlugin;
|
|
||||||
if (sm_trie_retrieve(m_LoadLookup, checkpath, (void **)&pPlugin))
|
|
||||||
{
|
{
|
||||||
snprintf(error, err_max, "Plugin file is already loaded");
|
delete pl;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pPlugin = CPlugin::CreatePlugin(path, error, err_max);
|
AddPlugin(pl);
|
||||||
|
|
||||||
if (!pPlugin)
|
return pl;
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ICompilation *co = pPlugin->StartMyCompile(g_pVM);
|
void CPluginManager::LoadAutoPlugin(const char *plugin)
|
||||||
if (!co || (debug && !g_pVM->SetCompilationOption(co, "debug", "1")))
|
|
||||||
{
|
{
|
||||||
snprintf(error, err_max, "Unable to start%s compilation", debug ? " debug" : "");
|
CPlugin *pl;
|
||||||
pPlugin->CancelMyCompile();
|
char error[255] = "Unknown error";
|
||||||
delete pPlugin;
|
|
||||||
return NULL;
|
if (!_LoadPlugin(&pl, plugin, false, PluginType_MapUpdated, error, sizeof(error)))
|
||||||
|
{
|
||||||
|
g_Logger.LogError("[SOURCEMOD] Failed to load plugin \"%s\": %s", plugin, error);
|
||||||
|
pl->SetErrorState(Plugin_Failed, "%s", error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pPlugin->FinishMyCompile(error, err_max))
|
AddPlugin(pl);
|
||||||
{
|
|
||||||
delete pPlugin;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
pPlugin->m_type = type;
|
|
||||||
|
|
||||||
AddCoreNativesToPlugin(pPlugin);
|
|
||||||
|
|
||||||
pPlugin->InitIdentity();
|
|
||||||
|
|
||||||
/* Finally, ask the plugin if it wants to be loaded */
|
|
||||||
if (!pPlugin->Call_AskPluginLoad(error, err_max))
|
|
||||||
{
|
|
||||||
delete pPlugin;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
AddPlugin(pPlugin);
|
|
||||||
|
|
||||||
return pPlugin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPluginManager::AddPlugin(CPlugin *pPlugin)
|
void CPluginManager::AddPlugin(CPlugin *pPlugin)
|
||||||
{
|
{
|
||||||
m_plugins.push_back(pPlugin);
|
|
||||||
sm_trie_insert(m_LoadLookup, pPlugin->m_filename, pPlugin);
|
|
||||||
|
|
||||||
List<IPluginsListener *>::iterator iter;
|
List<IPluginsListener *>::iterator iter;
|
||||||
IPluginsListener *pListener;
|
IPluginsListener *pListener;
|
||||||
|
|
||||||
for (iter=m_listeners.begin(); iter!=m_listeners.end(); iter++)
|
for (iter=m_listeners.begin(); iter!=m_listeners.end(); iter++)
|
||||||
{
|
{
|
||||||
pListener = (*iter);
|
pListener = (*iter);
|
||||||
pListener->OnPluginCreated(pPlugin);
|
pListener->OnPluginCreated(pPlugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the second pass was already completed, we have to run the pass on this plugin */
|
m_plugins.push_back(pPlugin);
|
||||||
if (m_AllPluginsLoaded && pPlugin->GetStatus() == Plugin_Loaded)
|
sm_trie_insert(m_LoadLookup, pPlugin->m_filename, pPlugin);
|
||||||
{
|
|
||||||
RunSecondPass(pPlugin);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPluginManager::LoadAll_SecondPass()
|
void CPluginManager::LoadAll_SecondPass()
|
||||||
@ -850,16 +811,77 @@ void CPluginManager::LoadAll_SecondPass()
|
|||||||
pPlugin = (*iter);
|
pPlugin = (*iter);
|
||||||
if (pPlugin->GetStatus() == Plugin_Loaded)
|
if (pPlugin->GetStatus() == Plugin_Loaded)
|
||||||
{
|
{
|
||||||
RunSecondPass(pPlugin);
|
/* :TODO: fix */
|
||||||
|
RunSecondPass(pPlugin, NULL, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_AllPluginsLoaded = true;
|
m_AllPluginsLoaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPluginManager::RunSecondPass(CPlugin *pPlugin)
|
bool CPluginManager::RunSecondPass(CPlugin *pPlugin, char *error, size_t maxlength)
|
||||||
{
|
{
|
||||||
/* Tell this plugin to finish initializing itself */
|
/* Find any extensions this plugin needs */
|
||||||
pPlugin->Call_OnPluginInit();
|
struct _ext
|
||||||
|
{
|
||||||
|
cell_t name;
|
||||||
|
cell_t file;
|
||||||
|
cell_t autoload;
|
||||||
|
cell_t required;
|
||||||
|
} *ext;
|
||||||
|
|
||||||
|
IPluginContext *pBase = pPlugin->GetBaseContext();
|
||||||
|
uint32_t num = pBase->GetPubVarsNum();
|
||||||
|
sp_pubvar_t *pubvar;
|
||||||
|
IExtension *pExt;
|
||||||
|
char path[PLATFORM_MAX_PATH+1];
|
||||||
|
char *file, *name;
|
||||||
|
for (uint32_t i=0; i<num; i++)
|
||||||
|
{
|
||||||
|
if (pBase->GetPubvarByIndex(i, &pubvar) != SP_ERROR_NONE)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (strncmp(pubvar->name, "__ext_", 6) == 0)
|
||||||
|
{
|
||||||
|
ext = (_ext *)pubvar->offs;
|
||||||
|
if (!ext->required && !ext->autoload)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (pBase->LocalToString(ext->file, &file) != SP_ERROR_NONE)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (pBase->LocalToString(ext->name, &name) != SP_ERROR_NONE)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
snprintf(path, PLATFORM_MAX_PATH, "%s.%s", file, PLATFORM_LIB_EXT);
|
||||||
|
pExt = NULL;
|
||||||
|
/* Attempt to auto-load if necessary */
|
||||||
|
if (ext->autoload)
|
||||||
|
{
|
||||||
|
pExt = g_Extensions.LoadAutoExtension(path);
|
||||||
|
}
|
||||||
|
if (ext->required && !pExt)
|
||||||
|
{
|
||||||
|
if ((pExt = g_Extensions.FindExtensionByFile(path)) == NULL)
|
||||||
|
{
|
||||||
|
pExt = g_Extensions.FindExtensionByName(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ext->required && (!pExt || !pExt->IsLoaded()))
|
||||||
|
{
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
snprintf(error, maxlength, "Required extension \"%s\" (file \"%s\") not found", name, file);
|
||||||
|
}
|
||||||
|
pPlugin->m_status = Plugin_Failed;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Finish by telling all listeners */
|
/* Finish by telling all listeners */
|
||||||
List<IPluginsListener *>::iterator iter;
|
List<IPluginsListener *>::iterator iter;
|
||||||
@ -869,6 +891,11 @@ void CPluginManager::RunSecondPass(CPlugin *pPlugin)
|
|||||||
pListener = (*iter);
|
pListener = (*iter);
|
||||||
pListener->OnPluginLoaded(pPlugin);
|
pListener->OnPluginLoaded(pPlugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Tell this plugin to finish initializing itself */
|
||||||
|
pPlugin->Call_OnPluginInit();
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPluginManager::AddCoreNativesToPlugin(CPlugin *pPlugin)
|
void CPluginManager::AddCoreNativesToPlugin(CPlugin *pPlugin)
|
||||||
@ -891,6 +918,13 @@ void CPluginManager::AddCoreNativesToPlugin(CPlugin *pPlugin)
|
|||||||
bool CPluginManager::UnloadPlugin(IPlugin *plugin)
|
bool CPluginManager::UnloadPlugin(IPlugin *plugin)
|
||||||
{
|
{
|
||||||
CPlugin *pPlugin = (CPlugin *)plugin;
|
CPlugin *pPlugin = (CPlugin *)plugin;
|
||||||
|
|
||||||
|
/* This prevents removal during insertion or anything else weird */
|
||||||
|
if (m_plugins.find(pPlugin) == m_plugins.end())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
List<IPluginsListener *>::iterator iter;
|
List<IPluginsListener *>::iterator iter;
|
||||||
IPluginsListener *pListener;
|
IPluginsListener *pListener;
|
||||||
|
|
||||||
@ -1215,6 +1249,12 @@ void CPluginManager::OnSourceModAllInitialized()
|
|||||||
|
|
||||||
void CPluginManager::OnSourceModShutdown()
|
void CPluginManager::OnSourceModShutdown()
|
||||||
{
|
{
|
||||||
|
List<CPlugin *>::iterator iter;
|
||||||
|
while ( (iter = m_plugins.begin()) != m_plugins.end() )
|
||||||
|
{
|
||||||
|
UnloadPlugin((*iter));
|
||||||
|
}
|
||||||
|
|
||||||
g_HandleSys.RemoveType(g_PluginType, m_MyIdent);
|
g_HandleSys.RemoveType(g_PluginType, m_MyIdent);
|
||||||
g_ShareSys.DestroyIdentType(g_PluginIdent);
|
g_ShareSys.DestroyIdentType(g_PluginIdent);
|
||||||
g_ShareSys.DestroyIdentity(m_MyIdent);
|
g_ShareSys.DestroyIdentity(m_MyIdent);
|
||||||
|
@ -269,17 +269,15 @@ public:
|
|||||||
*/
|
*/
|
||||||
CPlugin *GetPluginByOrder(int num);
|
CPlugin *GetPluginByOrder(int num);
|
||||||
private:
|
private:
|
||||||
|
bool _LoadPlugin(CPlugin **pPlugin, const char *path, bool debug, PluginType type, char error[], size_t err_max);
|
||||||
|
|
||||||
|
void LoadAutoPlugin(const char *plugin);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recursively loads all plugins in the given directory.
|
* Recursively loads all plugins in the given directory.
|
||||||
*/
|
*/
|
||||||
void LoadPluginsFromDir(const char *basedir, const char *localdir);
|
void LoadPluginsFromDir(const char *basedir, const char *localdir);
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads a plugin using automatic information.
|
|
||||||
* The file must be relative to the plugins folder.
|
|
||||||
*/
|
|
||||||
void LoadAutoPlugin(const char *file);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a plugin object. This is wrapped by LoadPlugin functions.
|
* Adds a plugin object. This is wrapped by LoadPlugin functions.
|
||||||
*/
|
*/
|
||||||
@ -288,7 +286,7 @@ private:
|
|||||||
/**
|
/**
|
||||||
* Runs the second loading pass on a plugin.
|
* Runs the second loading pass on a plugin.
|
||||||
*/
|
*/
|
||||||
void RunSecondPass(CPlugin *pPlugin);
|
bool RunSecondPass(CPlugin *pPlugin, char *error, size_t maxlength);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds any globally registered natives to a plugin
|
* Adds any globally registered natives to a plugin
|
||||||
|
5
extensions/sdk/extension.cpp
Normal file
5
extensions/sdk/extension.cpp
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#include "extension.h"
|
||||||
|
|
||||||
|
Sample g_Sample;
|
||||||
|
|
||||||
|
SMEXT_LINK(&g_Sample);
|
49
extensions/sdk/extension.h
Normal file
49
extensions/sdk/extension.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#ifndef _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
|
||||||
|
#define _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
|
||||||
|
|
||||||
|
#include "smsdk_ext.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sample implementation of the SDK Extension.
|
||||||
|
* Note: Uncomment one of the pre-defined virtual functions in order to use it.
|
||||||
|
*/
|
||||||
|
class Sample : public SDKExtension
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief This is called after the initial loading sequence has been processed.
|
||||||
|
*
|
||||||
|
* @param error Error message buffer.
|
||||||
|
* @param err_max Size of error message buffer.
|
||||||
|
* @param late Whether or not the module was loaded after map load.
|
||||||
|
* @return True to succeed loading, false to fail.
|
||||||
|
*/
|
||||||
|
//virtual bool SDK_OnLoad(char *error, size_t err_max, bool late);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This is called right before the extension is unloaded.
|
||||||
|
*/
|
||||||
|
//virtual void SDK_OnUnload();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This is called once all known extensions have been loaded.
|
||||||
|
*/
|
||||||
|
//virtual void SDK_OnAllLoaded();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Called when the pause state is changed.
|
||||||
|
*/
|
||||||
|
//virtual void SDK_OnPauseChange(bool paused);
|
||||||
|
public:
|
||||||
|
#if defined SMEXT_CONF_METAMOD
|
||||||
|
/**
|
||||||
|
* Read smext_base.h for documentation on these.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//virtual bool SDK_OnMetamodLoad(char *error, size_t err_max, bool late);
|
||||||
|
//virtual bool SDK_OnMetamodUnload(char *error, size_t err_max);
|
||||||
|
//virtual bool SDK_OnMetamodPauseChange(bool paused, char *error, size_t err_max);
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //_INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
|
26
extensions/sdk/sdk.sln
Normal file
26
extensions/sdk/sdk.sln
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||||
|
# Visual Studio 2005
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sdk", "sdk.vcproj", "{B3E797CF-4E77-4C9D-B8A8-7589B6902206}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug - Metamod|Win32 = Debug - Metamod|Win32
|
||||||
|
Debug|Win32 = Debug|Win32
|
||||||
|
Release - Metamod|Win32 = Release - Metamod|Win32
|
||||||
|
Release|Win32 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Metamod|Win32.ActiveCfg = Debug - Metamod|Win32
|
||||||
|
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Metamod|Win32.Build.0 = Debug - Metamod|Win32
|
||||||
|
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Metamod|Win32.ActiveCfg = Release - Metamod|Win32
|
||||||
|
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Metamod|Win32.Build.0 = Release - Metamod|Win32
|
||||||
|
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
364
extensions/sdk/sdk.vcproj
Normal file
364
extensions/sdk/sdk.vcproj
Normal file
@ -0,0 +1,364 @@
|
|||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="8.00"
|
||||||
|
Name="sdk"
|
||||||
|
ProjectGUID="{B3E797CF-4E77-4C9D-B8A8-7589B6902206}"
|
||||||
|
RootNamespace="sdk"
|
||||||
|
Keyword="Win32Proj"
|
||||||
|
>
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"
|
||||||
|
/>
|
||||||
|
</Platforms>
|
||||||
|
<ToolFiles>
|
||||||
|
</ToolFiles>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="2"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;SDK_EXPORTS;_CRT_SECURE_NO_DEPRECATE"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="true"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
LinkIncremental="2"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="2"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebDeploymentTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="2"
|
||||||
|
CharacterSet="1"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;SDK_EXPORTS;_CRT_SECURE_NO_DEPRECATE"
|
||||||
|
RuntimeLibrary="2"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="true"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
LinkIncremental="1"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="2"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebDeploymentTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug - Metamod|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="2"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;SDK_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SMEXT_CONF_METAMOD"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="true"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="tier0.lib"
|
||||||
|
LinkIncremental="2"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="2"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebDeploymentTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release - Metamod|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="2"
|
||||||
|
CharacterSet="1"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;SDK_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SMEXT_CONF_METAMOD"
|
||||||
|
RuntimeLibrary="2"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="true"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
LinkIncremental="1"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="2"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebDeploymentTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="Source Files"
|
||||||
|
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||||
|
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\extension.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\smsdk_ext.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Header Files"
|
||||||
|
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||||
|
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\extension.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\smsdk_config.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\smsdk_ext.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Resource Files"
|
||||||
|
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||||
|
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||||
|
>
|
||||||
|
</Filter>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
27
plugins/include/core.inc
Normal file
27
plugins/include/core.inc
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#if defined _core_included
|
||||||
|
#endinput
|
||||||
|
#endif
|
||||||
|
#define _core_included
|
||||||
|
|
||||||
|
#define SOURCEMOD_PLUGINAPI_VERSION 1
|
||||||
|
struct PlVers
|
||||||
|
{
|
||||||
|
version,
|
||||||
|
};
|
||||||
|
|
||||||
|
public PlVers:__version =
|
||||||
|
{
|
||||||
|
version = SOURCEMOD_PLUGINAPI_VERSION,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Extension
|
||||||
|
{
|
||||||
|
const String:name[], /* Short name */
|
||||||
|
const String:file[], /* Default file name */
|
||||||
|
bool:autoload, /* Whether or not to auto-load */
|
||||||
|
bool:required, /* Whether or not to require */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define AUTOLOAD_EXTENSIONS
|
||||||
|
#define REQUIRE_EXTENSIONS
|
||||||
|
|
@ -16,10 +16,10 @@ struct Plugin
|
|||||||
const String:url[], /* Plugin URL */
|
const String:url[], /* Plugin URL */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#include <core>
|
||||||
#include <float>
|
#include <float>
|
||||||
#include <handles>
|
#include <handles>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <files>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Declare this as a struct in your plugin to expose its information.
|
* Declare this as a struct in your plugin to expose its information.
|
||||||
|
Loading…
Reference in New Issue
Block a user