1
0
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:
David Anderson 2005-12-06 07:59:18 +00:00
parent 386eef09d3
commit 221e49cbc6
7 changed files with 119 additions and 35 deletions

View File

@ -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;
}

View File

@ -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:

View File

@ -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

View File

@ -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;
}

View File

@ -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();

View File

@ -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.

View File

@ -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";
}