diff --git a/sample_mm/engine_wrappers.h b/sample_mm/engine_wrappers.h
index 05b6ee5..120509f 100644
--- a/sample_mm/engine_wrappers.h
+++ b/sample_mm/engine_wrappers.h
@@ -21,7 +21,25 @@
extern IVEngineServer *engine;
-#if !defined ORANGEBOX_BUILD
+/**
+ * For non-OrangeBox builds, we have to make wrappers.
+ */
+#if defined ENGINE_ORIGINAL
+
+/**
+ * MM:S 1.4.x needs older API calls.
+ */
+#if !defined METAMOD_PLAPI_VERSION
+#define GetEngineFactory engineFactory
+#define GetServerFactory serverFactory
+#define MM_Format snprintf
+#else
+#error "Metamod:Source 1.6 is not supported on the old engine."
+#endif
+
+/**
+ * Wrap the CCommand class so our code looks the same for both engines.
+ */
class CCommand
{
public:
@@ -39,6 +57,13 @@ public:
return engine->Cmd_Argv(index);
}
};
+
+#define ENGINE_CALL(func) SH_CALL(m_EngineCC, func)
+
+#elif defined ENGINE_ORANGEBOX
+
+#define ENGINE_CALL(func) SH_CALL(engine, func)
+
#endif
#endif //_INCLUDE_SOURCE_ENGINE_WRAPPERS_
diff --git a/sample_mm/msvc8/sample_mm.sln b/sample_mm/msvc8/sample_mm.sln
index 37c4ebc..a695e78 100644
--- a/sample_mm/msvc8/sample_mm.sln
+++ b/sample_mm/msvc8/sample_mm.sln
@@ -6,17 +6,23 @@ EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug - Orange Box|Win32 = Debug - Orange Box|Win32
+ Debug - Original|Win32 = Debug - Original|Win32
Debug|Win32 = Debug|Win32
Release - Orange Box|Win32 = Release - Orange Box|Win32
+ Release - Original|Win32 = Release - Original|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Debug - Orange Box|Win32.ActiveCfg = Debug - Orange Box|Win32
{E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Debug - Orange Box|Win32.Build.0 = Debug - Orange Box|Win32
+ {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Debug - Original|Win32.ActiveCfg = Debug - Original|Win32
+ {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Debug - Original|Win32.Build.0 = Debug - Original|Win32
{E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Debug|Win32.ActiveCfg = Debug|Win32
{E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Debug|Win32.Build.0 = Debug|Win32
{E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Release - Orange Box|Win32.ActiveCfg = Release - Orange Box|Win32
{E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Release - Orange Box|Win32.Build.0 = Release - Orange Box|Win32
+ {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Release - Original|Win32.ActiveCfg = Release - Original|Win32
+ {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Release - Original|Win32.Build.0 = Release - Original|Win32
{E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Release|Win32.ActiveCfg = Release|Win32
{E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
diff --git a/sample_mm/msvc8/sample_mm.vcproj b/sample_mm/msvc8/sample_mm.vcproj
index e294cbd..241c832 100644
--- a/sample_mm/msvc8/sample_mm.vcproj
+++ b/sample_mm/msvc8/sample_mm.vcproj
@@ -196,8 +196,8 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sample_mm/sample_mm.cpp b/sample_mm/sample_mm.cpp
index 6178dfa..0916d1e 100644
--- a/sample_mm/sample_mm.cpp
+++ b/sample_mm/sample_mm.cpp
@@ -29,10 +29,10 @@ SH_DECL_HOOK1_void(IServerGameClients, ClientSettingsChanged, SH_NOATTRIB, 0, ed
SH_DECL_HOOK5(IServerGameClients, ClientConnect, SH_NOATTRIB, 0, bool, edict_t *, const char*, const char *, char *, int);
SH_DECL_HOOK2(IGameEventManager2, FireEvent, SH_NOATTRIB, 0, bool, IGameEvent *, bool);
-#if defined ORANGEBOX_BUILD
+#if defined ENGINE_ORANGEBOX
SH_DECL_HOOK2_void(IServerGameClients, NetworkIDValidated, SH_NOATTRIB, 0, const char *, const char *);
SH_DECL_HOOK2_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, edict_t *, const CCommand &);
-#else
+#elif defined ENGINE_ORIGINAL
SH_DECL_HOOK1_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, edict_t *);
#endif
@@ -45,6 +45,21 @@ IGameEventManager2 *gameevents = NULL;
IServerPluginCallbacks *vsp_callbacks = NULL;
IPlayerInfoManager *playerinfomanager = NULL;
+ConVar sample_cvar("sample_cvar", "42", 0);
+
+/**
+ * Something like this is needed to register cvars/CON_COMMANDs.
+ */
+class BaseAccessor : public IConCommandBaseAccessor
+{
+public:
+ bool RegisterConCommandBase(ConCommandBase *pCommandBase)
+ {
+ /* Always call META_REGCVAR instead of going through the engine. */
+ return META_REGCVAR(pCommandBase);
+ }
+} s_BaseAccessor;
+
PLUGIN_EXPOSE(StubPlugin, g_StubPlugin);
bool StubPlugin::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late)
{
@@ -59,40 +74,60 @@ bool StubPlugin::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bo
META_LOG(g_PLAPI, "Starting plugin.");
- /* Load the VSP listener. Most people won't need this. */
+ /* Load the VSP listener. This is usually needed for IServerPluginHelpers. */
+#if defined METAMOD_PLAPI_VERSION
if ((vsp_callbacks = ismm->GetVSPInfo(NULL)) == NULL)
+#endif
{
ismm->AddListener(this, this);
ismm->EnableVSPListener();
}
- m_hooks.push_back(SH_ADD_HOOK(IServerGameDLL, LevelInit, server, SH_MEMBER(this, &StubPlugin::Hook_LevelInit), true));
- m_hooks.push_back(SH_ADD_HOOK(IServerGameDLL, ServerActivate, server, SH_MEMBER(this, &StubPlugin::Hook_ServerActivate), true));
- m_hooks.push_back(SH_ADD_HOOK(IServerGameDLL, GameFrame, server, SH_MEMBER(this, &StubPlugin::Hook_GameFrame), true));
- m_hooks.push_back(SH_ADD_HOOK(IServerGameDLL, LevelShutdown, server, SH_MEMBER(this, &StubPlugin::Hook_LevelShutdown), false));
- m_hooks.push_back(SH_ADD_HOOK(IServerGameClients, ClientActive, gameclients, SH_MEMBER(this, &StubPlugin::Hook_ClientActive), true));
- m_hooks.push_back(SH_ADD_HOOK(IServerGameClients, ClientDisconnect, gameclients, SH_MEMBER(this, &StubPlugin::Hook_ClientDisconnect), true));
- m_hooks.push_back(SH_ADD_HOOK(IServerGameClients, ClientPutInServer, gameclients, SH_MEMBER(this, &StubPlugin::Hook_ClientPutInServer), true));
- m_hooks.push_back(SH_ADD_HOOK(IServerGameClients, SetCommandClient, gameclients, SH_MEMBER(this, &StubPlugin::Hook_SetCommandClient), true));
- m_hooks.push_back(SH_ADD_HOOK(IServerGameClients, ClientSettingsChanged, gameclients, SH_MEMBER(this, &StubPlugin::Hook_ClientSettingsChanged), false));
- m_hooks.push_back(SH_ADD_HOOK(IServerGameClients, ClientConnect, gameclients, SH_MEMBER(this, &StubPlugin::Hook_ClientConnect), false));
- m_hooks.push_back(SH_ADD_HOOK(IServerGameClients, ClientCommand, gameclients, SH_MEMBER(this, &StubPlugin::Hook_ClientCommand), false));
+ SH_ADD_HOOK_MEMFUNC(IServerGameDLL, LevelInit, server, this, &StubPlugin::Hook_LevelInit, true);
+ SH_ADD_HOOK_MEMFUNC(IServerGameDLL, ServerActivate, server, this, &StubPlugin::Hook_ServerActivate, true);
+ SH_ADD_HOOK_MEMFUNC(IServerGameDLL, GameFrame, server, this, &StubPlugin::Hook_GameFrame, true);
+ SH_ADD_HOOK_MEMFUNC(IServerGameDLL, LevelShutdown, server, this, &StubPlugin::Hook_LevelShutdown, false);
+ SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientActive, gameclients, this, &StubPlugin::Hook_ClientActive, true);
+ SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, gameclients, this, &StubPlugin::Hook_ClientDisconnect, true);
+ SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientPutInServer, gameclients, this, &StubPlugin::Hook_ClientPutInServer, true);
+ SH_ADD_HOOK_MEMFUNC(IServerGameClients, SetCommandClient, gameclients, this, &StubPlugin::Hook_SetCommandClient, true);
+ SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientSettingsChanged, gameclients, this, &StubPlugin::Hook_ClientSettingsChanged, false);
+ SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientConnect, gameclients, this, &StubPlugin::Hook_ClientConnect, false);
+ SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientCommand, gameclients, this, &StubPlugin::Hook_ClientCommand, false);
- SH_CALL(engine, &IVEngineServer::LogPrint)("All hooks started!\n");
+#if defined ENGINE_ORIGINAL
+ m_EngineCC = SH_GET_CALLCLASS(engine);
+#endif
+
+ ENGINE_CALL(&IVEngineServer::LogPrint)("All hooks started!\n");
+
+#if defined ENGINE_ORANGEBOX
+ g_pCVar = ICvar;
+ ConVar_Register(0, &s_BaseAccessor);
+#elif defined ENGINE_ORIGINAL
+ ConCommandBaseMgr::OneTimeInit(&s_BaseAccessor);
+#endif
return true;
}
bool StubPlugin::Unload(char *error, size_t maxlen)
{
- for (size_t i = 0; i < m_hooks.size(); i++)
- {
- if (m_hooks[i] != 0)
- {
- SH_REMOVE_HOOK_ID(m_hooks[i]);
- }
- }
- m_hooks.clear();
+ SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, LevelInit, server, this, &StubPlugin::Hook_LevelInit, true);
+ SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, ServerActivate, server, this, &StubPlugin::Hook_ServerActivate, true);
+ SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, GameFrame, server, this, &StubPlugin::Hook_GameFrame, true);
+ SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, LevelShutdown, server, this, &StubPlugin::Hook_LevelShutdown, false);
+ SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientActive, gameclients, this, &StubPlugin::Hook_ClientActive, true);
+ SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, gameclients, this, &StubPlugin::Hook_ClientDisconnect, true);
+ SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientPutInServer, gameclients, this, &StubPlugin::Hook_ClientPutInServer, true);
+ SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, SetCommandClient, gameclients, this, &StubPlugin::Hook_SetCommandClient, true);
+ SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientSettingsChanged, gameclients, this, &StubPlugin::Hook_ClientSettingsChanged, false);
+ SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientConnect, gameclients, this, &StubPlugin::Hook_ClientConnect, false);
+ SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientCommand, gameclients, this, &StubPlugin::Hook_ClientCommand, false);
+
+#if defined ENGINE_ORIGINAL
+ SH_RELEASE_CALLCLASS(m_EngineCC);
+#endif
return true;
}
@@ -119,13 +154,13 @@ void StubPlugin::Hook_ClientActive(edict_t *pEntity, bool bLoadGame)
META_LOG(g_PLAPI, "Hook_ClientActive(%d, %d)", engine->IndexOfEdict(pEntity), bLoadGame);
}
-#if defined ORANGEBOX_BUILD
+#if defined ENGINE_ORANGEBOX
void StubPlugin::Hook_ClientCommand(edict_t *pEntity, const CCommand &args)
-#else
+#elif defined ENGINE_ORIGINAL
void StubPlugin::Hook_ClientCommand(edict_t *pEntity)
#endif
{
-#if !defined ORANGEBOX_BUILD
+#if defined ENGINE_ORIGINAL
CCommand args;
#endif
@@ -147,9 +182,9 @@ void StubPlugin::Hook_ClientCommand(edict_t *pEntity)
for (int i = 1; i < 9; i++)
{
char num[10], msg[10], cmd[10];
- g_SMAPI->Format( num, sizeof(num), "%i", i );
- g_SMAPI->Format( msg, sizeof(msg), "Option %i", i );
- g_SMAPI->Format( cmd, sizeof(cmd), "option %i", i );
+ MM_Format( num, sizeof(num), "%i", i );
+ MM_Format( msg, sizeof(msg), "Option %i", i );
+ MM_Format( cmd, sizeof(cmd), "option %i", i );
KeyValues *item1 = kv->FindKey(num, true);
item1->SetString("msg", msg);
@@ -208,11 +243,12 @@ void StubPlugin::Hook_ClientSettingsChanged(edict_t *pEdict)
if (playerinfo != NULL
&& name != NULL
+ && strcmp(engine->GetPlayerNetworkIDString(pEdict), "BOT") != 0
&& playerinfo->GetName() != NULL
&& strcmp(name, playerinfo->GetName()) == 0)
{
char msg[128];
- g_SMAPI->Format(msg, sizeof(msg), "Your name changed to \"%s\" (from \"%s\")\n", name, playerinfo->GetName());
+ MM_Format(msg, sizeof(msg), "Your name changed to \"%s\" (from \"%s\")\n", name, playerinfo->GetName());
engine->ClientPrintf(pEdict, msg);
}
}
diff --git a/sample_mm/sample_mm.h b/sample_mm/sample_mm.h
index 4a0c0b9..3123078 100644
--- a/sample_mm/sample_mm.h
+++ b/sample_mm/sample_mm.h
@@ -23,6 +23,10 @@
#include
#include "engine_wrappers.h"
+#if defined WIN32 && !defined snprintf
+#define snprintf _snprintf
+#endif
+
class StubPlugin : public ISmmPlugin, public IMetamodListener
{
public:
@@ -53,9 +57,9 @@ public: //hooks
const char *pszAddress,
char *reject,
int maxrejectlen);
-#if defined ORANGEBOX_BUILD
+#if defined ENGINE_ORANGEBOX
void Hook_ClientCommand(edict_t *pEntity, const CCommand &args);
-#else
+#elif defined ENGINE_ORIGINAL
void Hook_ClientCommand(edict_t *pEntity);
#endif
public:
@@ -68,7 +72,9 @@ public:
const char *GetDate();
const char *GetLogTag();
private:
- SourceHook::CVector m_hooks;
+#if defined ENGINE_ORIGINAL
+ SourceHook::CallClass *m_EngineCC;
+#endif
};
extern StubPlugin g_StubPlugin;