mirror of
https://github.com/alliedmodders/metamod-source.git
synced 2025-02-17 10:54:14 +01:00
Added API call for guessing iface names
Added interface query overriding+sharing examples to stub+sample --HG-- extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/trunk%40153
This commit is contained in:
parent
386eef09d3
commit
221e49cbc6
@ -288,3 +288,31 @@ void CSmmAPI::GetShVersions(int &shvers, int &shimpl)
|
||||
shvers = SH_IFACE_VERSION;
|
||||
shimpl = SH_IMPL_VERSION;
|
||||
}
|
||||
|
||||
int CSmmAPI::FormatIface(char iface[], unsigned int maxlength)
|
||||
{
|
||||
int length = (int)strlen(iface);
|
||||
int i;
|
||||
int num = 0;
|
||||
|
||||
for (i=length-1; i>=0; i--)
|
||||
{
|
||||
if (!isdigit(iface[i]))
|
||||
break;
|
||||
}
|
||||
|
||||
if ( (num && (maxlength <= length)) || (!num && (maxlength <= length+3)) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (i != length-1)
|
||||
num = atoi(&(iface[++i]));
|
||||
|
||||
num++;
|
||||
|
||||
snprintf(&(iface[i]), 4, "%03d", num);
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,7 @@ namespace SourceMM
|
||||
virtual void GetShVersions(int &shvers, int &shimpl);
|
||||
virtual void AddListener(ISmmPlugin *plugin, IMetamodListener *pListener);
|
||||
virtual void *MetaFactory(const char *iface, int *ret, PluginId *id);
|
||||
virtual int FormatIface(char buffer[], unsigned int maxlength);
|
||||
public:
|
||||
bool CacheCmds();
|
||||
private:
|
||||
|
@ -56,7 +56,7 @@ public: //Added in 1.00-RC2 (0:0)
|
||||
//these do not add newlines
|
||||
virtual void ConPrint(const char *fmt) =0;
|
||||
virtual void ConPrintf(const char *fmt, ...) =0;
|
||||
public: //Added in 1.10 (1:0)
|
||||
public: //Added in 1.1.0 (1:0)
|
||||
//added by request. Checks if ConPrint/ConPrintf will mirror to rcon.
|
||||
virtual bool RemotePrintingAvailable() =0;
|
||||
//Returns the Metamod Version numbers as major version and minor (API) version.
|
||||
@ -77,11 +77,18 @@ public: //Added in 1.10 (1:0)
|
||||
* @return Returned pointer
|
||||
*/
|
||||
virtual void *MetaFactory(const char *iface, int *ret, PluginId *id) =0;
|
||||
public: //Added in 1.1.2 (1:1)
|
||||
/**
|
||||
* @brief Given a base interface name, such as ServerGameDLL or ServerGameDLL003,
|
||||
* reformats the string to increase the number, then returns the new number.
|
||||
*/
|
||||
virtual int FormatIface(char iface[], unsigned int maxlength) =0;
|
||||
};
|
||||
|
||||
|
||||
/** Version history
|
||||
* 1.10 bumped API to 1:0. The breaking changes occured in sourcehook and the plugin API.
|
||||
* 1.1.0 bumped API to 1:0. The breaking changes occured in sourcehook and the plugin API.
|
||||
* 1.1.2 added API call for generating iface names.
|
||||
*/
|
||||
|
||||
#endif //_INCLUDE_ISMM_API_H
|
||||
|
@ -13,12 +13,28 @@
|
||||
#include "cvars.h"
|
||||
|
||||
SamplePlugin g_SamplePlugin;
|
||||
MyListener g_Listener;
|
||||
|
||||
PLUGIN_EXPOSE(SamplePlugin, g_SamplePlugin);
|
||||
|
||||
//This has all of the necessary hook declarations. Read it!
|
||||
#include "meta_hooks.h"
|
||||
|
||||
#define FIND_IFACE(func, assn_var, num_var, name, type) \
|
||||
do { \
|
||||
if ( (assn_var=(type)((ismm->func())(name, NULL))) != NULL ) { \
|
||||
num = 0; \
|
||||
break; \
|
||||
} \
|
||||
if (num >= 999) \
|
||||
break; \
|
||||
} while ( num_var=ismm->FormatIface(name, sizeof(name)-1) ); \
|
||||
if (!assn_var) { \
|
||||
if (error) \
|
||||
snprintf(error, maxlen, "Could not find interface %s", name); \
|
||||
return false; \
|
||||
}
|
||||
|
||||
bool SamplePlugin::LevelInit(const char *pMapName, const char *pMapEntities, const char *pOldLevel, const char *pLandmarkName, bool loadGame, bool background)
|
||||
{
|
||||
META_LOG(g_PLAPI, "LevelInit() called: pMapName=%s", pMapName);
|
||||
@ -107,34 +123,22 @@ bool SamplePlugin::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen,
|
||||
{
|
||||
PLUGIN_SAVEVARS();
|
||||
|
||||
m_ServerDll = (IServerGameDLL *)((ismm->serverFactory())(INTERFACEVERSION_SERVERGAMEDLL, NULL));
|
||||
m_Engine = (IVEngineServer *)((ismm->engineFactory())(INTERFACEVERSION_VENGINESERVER, NULL));
|
||||
m_ServerClients = (IServerGameClients *)((ismm->serverFactory())(INTERFACEVERSION_SERVERGAMECLIENTS, NULL));
|
||||
m_GameEventManager = (IGameEventManager2 *)((ismm->engineFactory())(INTERFACEVERSION_GAMEEVENTSMANAGER2, NULL));
|
||||
char iface_buffer[255];
|
||||
int num;
|
||||
|
||||
if (!m_ServerDll)
|
||||
{
|
||||
snprintf(error, maxlen, "Could not find interface %s", INTERFACEVERSION_SERVERGAMEDLL);
|
||||
return false;
|
||||
}
|
||||
if (!m_Engine)
|
||||
{
|
||||
snprintf(error, maxlen, "Could not find interface %s", INTERFACEVERSION_VENGINESERVER);
|
||||
return false;
|
||||
}
|
||||
if (!m_ServerClients)
|
||||
{
|
||||
snprintf(error, maxlen, "Could not find interface %s", INTERFACEVERSION_SERVERGAMECLIENTS);
|
||||
return false;
|
||||
}
|
||||
if (!m_GameEventManager)
|
||||
{
|
||||
snprintf(error, maxlen, "Could not find interface %s", INTERFACEVERSION_GAMEEVENTSMANAGER2);
|
||||
return false;
|
||||
}
|
||||
strcpy(iface_buffer, INTERFACEVERSION_SERVERGAMEDLL);
|
||||
FIND_IFACE(serverFactory, m_ServerDll, num, iface_buffer, IServerGameDLL *)
|
||||
strcpy(iface_buffer, INTERFACEVERSION_VENGINESERVER);
|
||||
FIND_IFACE(engineFactory, m_Engine, num, iface_buffer, IVEngineServer *)
|
||||
strcpy(iface_buffer, INTERFACEVERSION_SERVERGAMECLIENTS);
|
||||
FIND_IFACE(serverFactory, m_ServerClients, num, iface_buffer, IServerGameClients *)
|
||||
strcpy(iface_buffer, INTERFACEVERSION_GAMEEVENTSMANAGER2);
|
||||
FIND_IFACE(engineFactory, m_GameEventManager, num, iface_buffer, IGameEventManager2 *);
|
||||
|
||||
META_LOG(g_PLAPI, "Starting plugin.\n");
|
||||
|
||||
ismm->AddListener(this, &g_Listener);
|
||||
|
||||
//Init our cvars/concmds
|
||||
ConCommandBaseMgr::OneTimeInit(&g_Accessor);
|
||||
|
||||
@ -219,3 +223,19 @@ void SamplePlugin::AllPluginsLoaded()
|
||||
// interfaces we make. In this callback, the plugin could be assured that either
|
||||
// the interfaces it requires were either loaded in another plugin or not.
|
||||
}
|
||||
|
||||
void *MyListener::OnMetamodQuery(const char *iface, int *ret)
|
||||
{
|
||||
if (strcmp(iface, "SamplePlugin")==0)
|
||||
{
|
||||
if (ret)
|
||||
*ret = IFACE_OK;
|
||||
return static_cast<void *>(&g_SamplePlugin);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
*ret = IFACE_FAILED;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -118,6 +118,12 @@ private:
|
||||
SourceHook::CallClass<IVEngineServer> *m_Engine_CC;
|
||||
};
|
||||
|
||||
class MyListener : public IMetamodListener
|
||||
{
|
||||
public:
|
||||
virtual void *OnMetamodQuery(const char *iface, int *ret);
|
||||
};
|
||||
|
||||
extern SamplePlugin g_SamplePlugin;
|
||||
PLUGIN_GLOBALVARS();
|
||||
|
||||
|
@ -39,11 +39,11 @@
|
||||
* minor changes can also roll over, but a big change should ALWAYS roll over.
|
||||
* Increasing one grouping should make the lesser ones reset back to zero.
|
||||
*/
|
||||
#define SOURCEMM_VERSION "1.1.1"
|
||||
#define SOURCEMM_VERSION "1.1.2"
|
||||
#define SOURCEMM_DATE __DATE__
|
||||
#define SM_MAJOR_VERSION 1 //never need to increase this
|
||||
#define SM_VERS_API_MAJOR 1 //increase this on a breaking change
|
||||
#define SM_VERS_API_MINOR 0 //increase this on a non-breaking API change
|
||||
#define SM_VERS_API_MINOR 1 //increase this on a non-breaking API change
|
||||
#define SM_VERS_RELEASE 0 //increase this on a bug-fix release.
|
||||
|
||||
//We need a good CServerGameDLL version to work properly. We support these inclusively.
|
||||
|
@ -18,6 +18,21 @@ PLUGIN_EXPOSE(SamplePlugin, g_StubPlugin);
|
||||
//This has all of the necessary hook declarations. Read it!
|
||||
#include "meta_hooks.h"
|
||||
|
||||
#define FIND_IFACE(func, assn_var, num_var, name, type) \
|
||||
do { \
|
||||
if ( (assn_var=(type)((ismm->func())(name, NULL))) != NULL ) { \
|
||||
num = 0; \
|
||||
break; \
|
||||
} \
|
||||
if (num >= 999) \
|
||||
break; \
|
||||
} while ( num_var=ismm->FormatIface(name, sizeof(name)-1) ); \
|
||||
if (!assn_var) { \
|
||||
if (error) \
|
||||
snprintf(error, maxlen, "Could not find interface %s", name); \
|
||||
return false; \
|
||||
}
|
||||
|
||||
void ServerActivate_handler(edict_t *pEdictList, int edictCount, int clientMax)
|
||||
{
|
||||
META_LOG(g_PLAPI, "ServerActivate() called: edictCount=%d, clientMax=%d", edictCount, clientMax);
|
||||
@ -28,13 +43,11 @@ bool StubPlugin::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bo
|
||||
{
|
||||
PLUGIN_SAVEVARS();
|
||||
|
||||
m_ServerDll = (IServerGameDLL *)((ismm->serverFactory())(INTERFACEVERSION_SERVERGAMEDLL, NULL));
|
||||
char iface_buffer[255];
|
||||
int num;
|
||||
|
||||
if (!m_ServerDll)
|
||||
{
|
||||
snprintf(error, maxlen, "Could not find interface %s", INTERFACEVERSION_SERVERGAMEDLL);
|
||||
return false;
|
||||
}
|
||||
strcpy(iface_buffer, INTERFACEVERSION_SERVERGAMEDLL);
|
||||
FIND_IFACE(serverFactory, m_ServerDll, num, iface_buffer, IServerGameDLL *)
|
||||
|
||||
SH_ADD_HOOK_STATICFUNC(IServerGameDLL, ServerActivate, m_ServerDll, ServerActivate_handler, true);
|
||||
|
||||
@ -60,7 +73,15 @@ bool StubPlugin::Unpause(char *error, size_t maxlen)
|
||||
|
||||
void StubPlugin::AllPluginsLoaded()
|
||||
{
|
||||
|
||||
//This is an example of inter-plugin communication
|
||||
PluginId id;
|
||||
void *ptr = g_SMAPI->MetaFactory("SamplePlugin", NULL, &id);
|
||||
if (ptr)
|
||||
{
|
||||
META_LOG(g_PLAPI, "Found Sample Plugin[%d] at (%p)!", id, ptr);
|
||||
} else {
|
||||
META_LOG(g_PLAPI, "Did not find Sample Plugin!");
|
||||
}
|
||||
}
|
||||
|
||||
const char *StubPlugin::GetAuthor()
|
||||
@ -102,3 +123,4 @@ const char *StubPlugin::GetLogTag()
|
||||
{
|
||||
return "STUB";
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user