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 @@ <Tool Name="VCCLCompilerTool" Optimization="0" - AdditionalIncludeDirectories="..\..\sourcemm;..\..\sourcehook" - PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;STUB_MM_EXPORTS;ORANGEBOX_BUILD" + AdditionalIncludeDirectories="$(SOURCEMM16)\sourcemm;$(SOURCEMM16)\sourcehook;$(HL2SDKOB)\public;$(HL2SDKOB)\public\dlls;$(HL2SDKOB)\public\engine;$(HL2SDKOB)\public\tier0;$(HL2SDKOB)\public\tier1;$(HL2SDKOB)\public\vstdlib;$(HL2SDKOB)\tier1;$(HL2SDKOB)\public\game\server" + PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;STUB_MM_EXPORTS;ENGINE_ORANGEBOX" MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="1" @@ -217,7 +217,7 @@ /> <Tool Name="VCLinkerTool" - AdditionalDependencies="tier0.lib vstdlib.lib tier2.lib" + AdditionalDependencies="$(HL2SDKOB)\lib\public\tier0.lib $(HL2SDKOB)\lib\public\vstdlib.lib $(HL2SDKOB)\lib\public\tier2.lib $(HL2SDKOB)\lib\public\tier1.lib" OutputFile="$(OutDir)\sample_mm.dll" LinkIncremental="2" GenerateDebugInformation="true" @@ -274,8 +274,8 @@ /> <Tool Name="VCCLCompilerTool" - AdditionalIncludeDirectories="..\..\sourcemm;..\..\sourcehook" - PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;STUB_MM_EXPORTS;ORANGEBOX_BUILD" + AdditionalIncludeDirectories="$(SOURCEMM16)\sourcemm;$(SOURCEMM16)\sourcehook;$(HL2SDKOB)\public;$(HL2SDKOB)\public\dlls;$(HL2SDKOB)\public\engine;$(HL2SDKOB)\public\tier0;$(HL2SDKOB)\public\tier1;$(HL2SDKOB)\public\vstdlib;$(HL2SDKOB)\tier1;$(HL2SDKOB)\public\game\server" + PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;STUB_MM_EXPORTS;ENGINE_ORANGEBOX" RuntimeLibrary="0" UsePrecompiledHeader="0" WarningLevel="3" @@ -293,7 +293,7 @@ /> <Tool Name="VCLinkerTool" - AdditionalDependencies="tier0.lib vstdlib.lib tier2.lib tier1.lib" + AdditionalDependencies="$(HL2SDKOB)\lib\public\tier0.lib $(HL2SDKOB)\lib\public\vstdlib.lib $(HL2SDKOB)\lib\public\tier2.lib $(HL2SDKOB)\lib\public\tier1.lib" OutputFile="$(OutDir)\sample_mm.dll" LinkIncremental="1" GenerateDebugInformation="true" @@ -327,6 +327,162 @@ Name="VCPostBuildEventTool" /> </Configuration> + <Configuration + Name="Release - Original|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="2" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="$(SOURCEMM14);$(SOURCEMM14)\sourcemm;$(SOURCEMM14)\sourcehook;$(HL2SDK)\public;$(HL2SDK)\public\dlls;$(HL2SDK)\public\engine;$(HL2SDK)\public\tier0;$(HL2SDK)\public\tier1;$(HL2SDK)\public\vstdlib;$(HL2SDK)\tier1" + PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;STUB_MM_EXPORTS;ENGINE_ORIGINAL" + RuntimeLibrary="0" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="$(HL2SDK)\lib\public\tier0.lib $(HL2SDK)\lib\public\vstdlib.lib $(HL2SDK)\lib\public\tier2.lib $(HL2SDK)\lib\public\tier1.lib" + OutputFile="$(OutDir)\sample_mm.dll" + 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 - Original|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" + AdditionalIncludeDirectories="$(SOURCEMM14);$(SOURCEMM14)\sourcemm;$(SOURCEMM14)\sourcehook;$(HL2SDK)\public;$(HL2SDK)\public\dlls;$(HL2SDK)\public\engine;$(HL2SDK)\public\tier0;$(HL2SDK)\public\tier1;$(HL2SDK)\public\vstdlib;$(HL2SDK)\tier1" + PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;STUB_MM_EXPORTS;ENGINE_ORIGINAL" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="$(HL2SDK)\lib\public\tier0.lib $(HL2SDK)\lib\public\vstdlib.lib $(HL2SDK)\lib\public\tier2.lib $(HL2SDK)\lib\public\tier1.lib" + OutputFile="$(OutDir)\sample_mm.dll" + 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> </Configurations> <References> </References> 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 <sh_vector.h> #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<int> m_hooks; +#if defined ENGINE_ORIGINAL + SourceHook::CallClass<IVEngineServer> *m_EngineCC; +#endif }; extern StubPlugin g_StubPlugin;