diff --git a/sourcemm/episode1/console.cpp b/sourcemm/episode1/console.cpp index 1f64a2a..64cb498 100644 --- a/sourcemm/episode1/console.cpp +++ b/sourcemm/episode1/console.cpp @@ -23,147 +23,147 @@ * 3. This notice may not be removed or altered from any source distribution. * * Version: $Id$ - */ - -#include "console.h" -#include "provider_ep1.h" - -using namespace SourceHook; - -SMConVarAccessor g_SMConVarAccessor; - -class CAlwaysRegisterableCommand : public ConCommandBase -{ -public: - CAlwaysRegisterableCommand() - { - Create("metamod_eternal", NULL, FCVAR_UNREGISTERED|FCVAR_GAMEDLL); - } - bool IsRegistered( void ) const - { - return false; - } - void BringToFront() - { - // First, let's try to find us! - ConCommandBase *pPtr = icvar->GetCommands(); - - if (pPtr == this) - { - // We are already at the beginning; Nothing to do - return; - } - - while (pPtr) - { - if (pPtr == this) - { - break; - } - ConCommandBase *pPrev = NULL; - while (pPtr) - { - if (pPtr == this) - { - break; - } - pPrev = pPtr; - pPtr = const_cast(pPtr->GetNext()); - } - if (pPrev && pPtr == this) - { - pPrev->SetNext(m_pNext); // Remove us from the list - } - // Now, register us - SetNext(NULL); - icvar->RegisterConCommandBase(this); - } - } -} s_EternalCommand; - -bool SMConVarAccessor::RegisterConCommandBase(ConCommandBase *pCommand) -{ - m_RegisteredCommands.push_back(pCommand); - pCommand->SetNext(NULL); - icvar->RegisterConCommandBase(pCommand); - - return true; -} - -bool SMConVarAccessor::Register(ConCommandBase *pCommand) -{ - pCommand->SetNext(NULL); - icvar->RegisterConCommandBase(pCommand); - - return true; -} - -void SMConVarAccessor::MarkCommandsAsGameDLL() -{ - for (List::iterator iter = m_RegisteredCommands.begin(); - iter != m_RegisteredCommands.end(); ++iter) - { - (*iter)->AddFlags(FCVAR_GAMEDLL); - } -} - -void SMConVarAccessor::UnregisterGameDLLCommands() -{ - ConCommandBase *begin = icvar->GetCommands(); - ConCommandBase *iter = begin; - ConCommandBase *prev = NULL; - while (iter) - { - /* Watch out for the ETERNAL COMMAND! */ - if (iter != &s_EternalCommand && iter->IsBitSet(FCVAR_GAMEDLL)) - { - /* Remove it! */ - if (iter == begin) - { - s_EternalCommand.BringToFront(); - iter = const_cast(iter->GetNext()); - s_EternalCommand.SetNext(iter); - prev = &s_EternalCommand; - continue; - } - else - { - iter = const_cast(iter->GetNext()); - prev->SetNext(iter); - continue; - } - } - prev = iter; - iter = const_cast(iter->GetNext()); - } -} - -void SMConVarAccessor::Unregister(ConCommandBase *pCommand) -{ - ConCommandBase *ptr = icvar->GetCommands(); - - if (ptr == pCommand) - { - s_EternalCommand.BringToFront(); - s_EternalCommand.SetNext(const_cast(pCommand->GetNext())); - } - else - { - /* Find us and unregister us */ - ConCommandBase *pPrev = NULL; - while (ptr) - { - if (ptr == pCommand) - { - break; - } - pPrev = ptr; - ptr = const_cast(ptr->GetNext()); - } - if (pPrev && ptr == pCommand) - { - pPrev->SetNext(const_cast(pCommand->GetNext())); - } - } -} - + */ + +#include "console.h" +#include "provider_ep1.h" + +using namespace SourceHook; + +SMConVarAccessor g_SMConVarAccessor; + +class CAlwaysRegisterableCommand : public ConCommandBase +{ +public: + CAlwaysRegisterableCommand() + { + Create("metamod_eternal", NULL, FCVAR_UNREGISTERED|FCVAR_GAMEDLL); + } + bool IsRegistered( void ) const + { + return false; + } + void BringToFront() + { + // First, let's try to find us! + ConCommandBase *pPtr = icvar->GetCommands(); + + if (pPtr == this) + { + // We are already at the beginning; Nothing to do + return; + } + + while (pPtr) + { + if (pPtr == this) + { + break; + } + ConCommandBase *pPrev = NULL; + while (pPtr) + { + if (pPtr == this) + { + break; + } + pPrev = pPtr; + pPtr = const_cast(pPtr->GetNext()); + } + if (pPrev && pPtr == this) + { + pPrev->SetNext(m_pNext); // Remove us from the list + } + // Now, register us + SetNext(NULL); + icvar->RegisterConCommandBase(this); + } + } +} s_EternalCommand; + +bool SMConVarAccessor::RegisterConCommandBase(ConCommandBase *pCommand) +{ + m_RegisteredCommands.push_back(pCommand); + pCommand->SetNext(NULL); + icvar->RegisterConCommandBase(pCommand); + + return true; +} + +bool SMConVarAccessor::Register(ConCommandBase *pCommand) +{ + pCommand->SetNext(NULL); + icvar->RegisterConCommandBase(pCommand); + + return true; +} + +void SMConVarAccessor::MarkCommandsAsGameDLL() +{ + for (List::iterator iter = m_RegisteredCommands.begin(); + iter != m_RegisteredCommands.end(); ++iter) + { + (*iter)->AddFlags(FCVAR_GAMEDLL); + } +} + +void SMConVarAccessor::UnregisterGameDLLCommands() +{ + ConCommandBase *begin = icvar->GetCommands(); + ConCommandBase *iter = begin; + ConCommandBase *prev = NULL; + while (iter) + { + /* Watch out for the ETERNAL COMMAND! */ + if (iter != &s_EternalCommand && iter->IsBitSet(FCVAR_GAMEDLL)) + { + /* Remove it! */ + if (iter == begin) + { + s_EternalCommand.BringToFront(); + iter = const_cast(iter->GetNext()); + s_EternalCommand.SetNext(iter); + prev = &s_EternalCommand; + continue; + } + else + { + iter = const_cast(iter->GetNext()); + prev->SetNext(iter); + continue; + } + } + prev = iter; + iter = const_cast(iter->GetNext()); + } +} + +void SMConVarAccessor::Unregister(ConCommandBase *pCommand) +{ + ConCommandBase *ptr = icvar->GetCommands(); + + if (ptr == pCommand) + { + s_EternalCommand.BringToFront(); + s_EternalCommand.SetNext(const_cast(pCommand->GetNext())); + } + else + { + /* Find us and unregister us */ + ConCommandBase *pPrev = NULL; + while (ptr) + { + if (ptr == pCommand) + { + break; + } + pPrev = ptr; + ptr = const_cast(ptr->GetNext()); + } + if (pPrev && ptr == pCommand) + { + pPrev->SetNext(const_cast(pCommand->GetNext())); + } + } +} + diff --git a/sourcemm/episode1/console.h b/sourcemm/episode1/console.h index 6f22cdb..a446be6 100644 --- a/sourcemm/episode1/console.h +++ b/sourcemm/episode1/console.h @@ -23,29 +23,29 @@ * 3. This notice may not be removed or altered from any source distribution. * * Version: $Id$ - */ - -#ifndef _INCLUDE_CONSOLE_MMS_H_ -#define _INCLUDE_CONSOLE_MMS_H_ - -#include -#include -#include "convar_smm.h" -#include - -class SMConVarAccessor : public IConCommandBaseAccessor -{ -public: - bool RegisterConCommandBase(ConCommandBase *pCommand); - bool Register(ConCommandBase *pCommand); - void MarkCommandsAsGameDLL(); - void Unregister(ConCommandBase *pCommand); - void UnregisterGameDLLCommands(); -private: - SourceHook::List m_RegisteredCommands; -}; - -extern SMConVarAccessor g_SMConVarAccessor; - -#endif //_INCLUDE_CONSOLE_MMS_H_ - + */ + +#ifndef _INCLUDE_CONSOLE_MMS_H_ +#define _INCLUDE_CONSOLE_MMS_H_ + +#include +#include +#include "convar_smm.h" +#include + +class SMConVarAccessor : public IConCommandBaseAccessor +{ +public: + bool RegisterConCommandBase(ConCommandBase *pCommand); + bool Register(ConCommandBase *pCommand); + void MarkCommandsAsGameDLL(); + void Unregister(ConCommandBase *pCommand); + void UnregisterGameDLLCommands(); +private: + SourceHook::List m_RegisteredCommands; +}; + +extern SMConVarAccessor g_SMConVarAccessor; + +#endif //_INCLUDE_CONSOLE_MMS_H_ + diff --git a/sourcemm/episode1/vsp_listener.cpp b/sourcemm/episode1/vsp_listener.cpp index 9097732..370a66d 100644 --- a/sourcemm/episode1/vsp_listener.cpp +++ b/sourcemm/episode1/vsp_listener.cpp @@ -23,116 +23,116 @@ * 3. This notice may not be removed or altered from any source distribution. * * Version: $Id$ - */ - -#include "vsp_listener.h" -#include "svn_version.h" -#include "metamod.h" - -using namespace SourceMM; - -VSPListener::VSPListener() -{ - m_bLoaded = false; - m_bLoadable = false; -} - -void VSPListener::ClientActive(edict_t *pEntity) -{ -} - -PLUGIN_RESULT VSPListener::ClientCommand(edict_t *pEntity) -{ - return PLUGIN_CONTINUE; -} - -PLUGIN_RESULT VSPListener::ClientConnect(bool *bAllowConnect, edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen) -{ - return PLUGIN_CONTINUE; -} - -void VSPListener::ClientDisconnect(edict_t *pEntity) -{ -} - -void VSPListener::ClientPutInServer(edict_t *pEntity, char const *playername) -{ -} - -void VSPListener::ClientSettingsChanged(edict_t *pEdict) -{ -} - -void VSPListener::SetCommandClient(int index) -{ -} - -void VSPListener::GameFrame(bool simulating) -{ -} - -const char *VSPListener::GetPluginDescription() -{ - return "Metamod:Source Interface v" SVN_FILE_VERSION_STRING; -} - -bool VSPListener::IsLoaded() -{ - return m_bLoaded; -} - -void VSPListener::LevelInit(char const *pMapName) -{ -} - -void VSPListener::LevelShutdown() -{ -} - -PLUGIN_RESULT VSPListener::NetworkIDValidated(const char *pszUserName, const char *pszNetworkID) -{ - return PLUGIN_CONTINUE; -} - -void VSPListener::Pause() -{ -} - -void VSPListener::UnPause() -{ -} - -void VSPListener::ServerActivate(edict_t *pEdictList, int edictCount, int clientMax) -{ -} - -void VSPListener::Unload() -{ -} - -void VSPListener::SetLoadable(bool set) -{ - m_bLoadable = set; -} - -bool VSPListener::Load(CreateInterfaceFn interfaceFactory, CreateInterfaceFn gameServerFactory) -{ - if (!m_bLoadable) - { - Warning("Do not manually load Metamod:Source as a Valve Server Plugin\n"); - return false; - } - - if (m_bLoaded) - { - return false; - } - - m_bLoaded = true; - SetLoadable(false); - - g_Metamod.NotifyVSPListening(this); - - return true; -} - + */ + +#include "vsp_listener.h" +#include "svn_version.h" +#include "metamod.h" + +using namespace SourceMM; + +VSPListener::VSPListener() +{ + m_bLoaded = false; + m_bLoadable = false; +} + +void VSPListener::ClientActive(edict_t *pEntity) +{ +} + +PLUGIN_RESULT VSPListener::ClientCommand(edict_t *pEntity) +{ + return PLUGIN_CONTINUE; +} + +PLUGIN_RESULT VSPListener::ClientConnect(bool *bAllowConnect, edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen) +{ + return PLUGIN_CONTINUE; +} + +void VSPListener::ClientDisconnect(edict_t *pEntity) +{ +} + +void VSPListener::ClientPutInServer(edict_t *pEntity, char const *playername) +{ +} + +void VSPListener::ClientSettingsChanged(edict_t *pEdict) +{ +} + +void VSPListener::SetCommandClient(int index) +{ +} + +void VSPListener::GameFrame(bool simulating) +{ +} + +const char *VSPListener::GetPluginDescription() +{ + return "Metamod:Source Interface v" SVN_FILE_VERSION_STRING; +} + +bool VSPListener::IsLoaded() +{ + return m_bLoaded; +} + +void VSPListener::LevelInit(char const *pMapName) +{ +} + +void VSPListener::LevelShutdown() +{ +} + +PLUGIN_RESULT VSPListener::NetworkIDValidated(const char *pszUserName, const char *pszNetworkID) +{ + return PLUGIN_CONTINUE; +} + +void VSPListener::Pause() +{ +} + +void VSPListener::UnPause() +{ +} + +void VSPListener::ServerActivate(edict_t *pEdictList, int edictCount, int clientMax) +{ +} + +void VSPListener::Unload() +{ +} + +void VSPListener::SetLoadable(bool set) +{ + m_bLoadable = set; +} + +bool VSPListener::Load(CreateInterfaceFn interfaceFactory, CreateInterfaceFn gameServerFactory) +{ + if (!m_bLoadable) + { + Warning("Do not manually load Metamod:Source as a Valve Server Plugin\n"); + return false; + } + + if (m_bLoaded) + { + return false; + } + + m_bLoaded = true; + SetLoadable(false); + + g_Metamod.NotifyVSPListening(this); + + return true; +} + diff --git a/sourcemm/episode1/vsp_listener.h b/sourcemm/episode1/vsp_listener.h index 558be21..8b5af85 100644 --- a/sourcemm/episode1/vsp_listener.h +++ b/sourcemm/episode1/vsp_listener.h @@ -23,42 +23,42 @@ * 3. This notice may not be removed or altered from any source distribution. * * Version: $Id$ - */ - -#ifndef _INCLUDE_METAMOD_SOURCE_VSP_LISTENER_H_ -#define _INCLUDE_METAMOD_SOURCE_VSP_LISTENER_H_ - -#include "iserverplugin.h" - -class VSPListener : public IServerPluginCallbacks -{ -public: - VSPListener(); -public: - virtual bool Load(CreateInterfaceFn interfaceFactory, CreateInterfaceFn gameServerFactory); - virtual void Unload(); - virtual void Pause(); - virtual void UnPause(); - virtual const char *GetPluginDescription(); - virtual void LevelInit(char const *pMapName); - virtual void ServerActivate(edict_t *pEdictList, int edictCount, int clientMax); - virtual void GameFrame(bool simulating); - virtual void LevelShutdown(void); - virtual void ClientActive(edict_t *pEntity); - virtual void ClientDisconnect(edict_t *pEntity); - virtual void ClientPutInServer(edict_t *pEntity, char const *playername); - virtual void SetCommandClient(int index); - virtual void ClientSettingsChanged(edict_t *pEdict); - virtual PLUGIN_RESULT ClientConnect(bool *bAllowConnect, edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen); - virtual PLUGIN_RESULT ClientCommand(edict_t *pEntity); - virtual PLUGIN_RESULT NetworkIDValidated(const char *pszUserName, const char *pszNetworkID); -public: - bool IsLoaded(); - void SetLoadable(bool loadable); -private: - bool m_bLoaded; - bool m_bLoadable; -}; - -#endif //_INCLUDE_METAMOD_SOURCE_VSP_LISTENER_H_ - + */ + +#ifndef _INCLUDE_METAMOD_SOURCE_VSP_LISTENER_H_ +#define _INCLUDE_METAMOD_SOURCE_VSP_LISTENER_H_ + +#include "iserverplugin.h" + +class VSPListener : public IServerPluginCallbacks +{ +public: + VSPListener(); +public: + virtual bool Load(CreateInterfaceFn interfaceFactory, CreateInterfaceFn gameServerFactory); + virtual void Unload(); + virtual void Pause(); + virtual void UnPause(); + virtual const char *GetPluginDescription(); + virtual void LevelInit(char const *pMapName); + virtual void ServerActivate(edict_t *pEdictList, int edictCount, int clientMax); + virtual void GameFrame(bool simulating); + virtual void LevelShutdown(void); + virtual void ClientActive(edict_t *pEntity); + virtual void ClientDisconnect(edict_t *pEntity); + virtual void ClientPutInServer(edict_t *pEntity, char const *playername); + virtual void SetCommandClient(int index); + virtual void ClientSettingsChanged(edict_t *pEdict); + virtual PLUGIN_RESULT ClientConnect(bool *bAllowConnect, edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen); + virtual PLUGIN_RESULT ClientCommand(edict_t *pEntity); + virtual PLUGIN_RESULT NetworkIDValidated(const char *pszUserName, const char *pszNetworkID); +public: + bool IsLoaded(); + void SetLoadable(bool loadable); +private: + bool m_bLoaded; + bool m_bLoadable; +}; + +#endif //_INCLUDE_METAMOD_SOURCE_VSP_LISTENER_H_ + diff --git a/sourcemm/episode2/console.cpp b/sourcemm/episode2/console.cpp new file mode 100644 index 0000000..61c7aef --- /dev/null +++ b/sourcemm/episode2/console.cpp @@ -0,0 +1,57 @@ +/** + * vim: set ts=4 : + * ====================================================== + * Metamod:Source + * Copyright (C) 2004-2007 AlliedModders LLC and authors. + * All rights reserved. + * ====================================================== + * + * This software is provided 'as-is', without any express or implied warranty. + * In no event will the authors be held liable for any damages arising from + * the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software in a + * product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + * Version: $Id$ + */ + +#include "console.h" +#include "provider_ep2.h" + +using namespace SourceHook; + +SMConVarAccessor g_SMConVarAccessor; + +static int s_nDLLIdentifier = 0x3058132; // A unique identifier indicating which DLL this convar came from + +bool SMConVarAccessor::RegisterConCommandBase(ConCommandBase *pCommand) +{ + pCommand->SetNext(NULL); + icvar->RegisterConCommand(pCommand); + + return true; +} + +bool SMConVarAccessor::Register(ConCommandBase *pCommand) +{ + pCommand->SetNext(NULL); + icvar->RegisterConCommand(pCommand); + + return true; +} + +void SMConVarAccessor::Unregister(ConCommandBase *pCommand) +{ + icvar->UnregisterConCommand(pCommand); +} + diff --git a/sourcemm/episode2/console.h b/sourcemm/episode2/console.h new file mode 100644 index 0000000..004cb8f --- /dev/null +++ b/sourcemm/episode2/console.h @@ -0,0 +1,55 @@ +/** + * vim: set ts=4 : + * ====================================================== + * Metamod:Source + * Copyright (C) 2004-2007 AlliedModders LLC and authors. + * All rights reserved. + * ====================================================== + * + * This software is provided 'as-is', without any express or implied warranty. + * In no event will the authors be held liable for any damages arising from + * the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software in a + * product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + * Version: $Id$ + */ + +#ifndef _INCLUDE_CONSOLE_MMS_H_ +#define _INCLUDE_CONSOLE_MMS_H_ + +#if defined _DEBUG +#define DEBUG2 +#undef _DEBUG +#endif +#include +#include +#include "convar.h" +#include +#if defined DEBUG2 +#undef DEBUG2 +#define _DEBUG +#endif + +class SMConVarAccessor : public IConCommandBaseAccessor +{ +public: + bool RegisterConCommandBase(ConCommandBase *pCommand); + bool Register(ConCommandBase *pCommand); + void Unregister(ConCommandBase *pCommand); +}; + +extern SMConVarAccessor g_SMConVarAccessor; + +#endif //_INCLUDE_CONSOLE_MMS_H_ + diff --git a/sourcemm/episode2/msvc8/sourcemm.sln b/sourcemm/episode2/msvc8/sourcemm.sln new file mode 100644 index 0000000..b338452 --- /dev/null +++ b/sourcemm/episode2/msvc8/sourcemm.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sourcemm", "sourcemm.vcproj", "{F7D47743-73B3-49B5-9D76-2333C5DFD565}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F7D47743-73B3-49B5-9D76-2333C5DFD565}.Debug|Win32.ActiveCfg = Debug|Win32 + {F7D47743-73B3-49B5-9D76-2333C5DFD565}.Debug|Win32.Build.0 = Debug|Win32 + {F7D47743-73B3-49B5-9D76-2333C5DFD565}.Release|Win32.ActiveCfg = Release|Win32 + {F7D47743-73B3-49B5-9D76-2333C5DFD565}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/sourcemm/episode2/msvc8/sourcemm.vcproj b/sourcemm/episode2/msvc8/sourcemm.vcproj new file mode 100644 index 0000000..db2ff0d --- /dev/null +++ b/sourcemm/episode2/msvc8/sourcemm.vcproj @@ -0,0 +1,333 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sourcemm/episode2/provider_ep2.cpp b/sourcemm/episode2/provider_ep2.cpp new file mode 100644 index 0000000..f82052e --- /dev/null +++ b/sourcemm/episode2/provider_ep2.cpp @@ -0,0 +1,598 @@ + +/** + * vim: set ts=4 : + * ====================================================== + * Metamod:Source + * Copyright (C) 2004-2007 AlliedModders LLC and authors. + * All rights reserved. + * ====================================================== + * + * This software is provided 'as-is', without any express or implied warranty. + * In no event will the authors be held liable for any damages arising from + * the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software in a + * product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + * Version: $Id$ + */ + +#if defined _DEBUG +#define DEBUG2 +#undef _DEBUG +#endif +#include +#include +#include +#include +#include +#include +#include +#include "../metamod_util.h" +#include "provider_ep2.h" +#include "console.h" +#include "metamod_console.h" +#include "vsp_listener.h" +#if defined DEBUG2 +#undef DEBUG2 +#define _DEBUG +#endif + +/* Types */ +typedef void (*CONPRINTF_FUNC)(const char *, ...); +struct UsrMsgInfo +{ + int size; + String name; +}; +/* Imports */ +#undef CommandLine +DLL_IMPORT ICommandLine *CommandLine(); +/* Functions */ +CONPRINTF_FUNC ExtractRemotePrinter(void *addr); +bool CacheUserMessages(); +void ClientCommand(edict_t *pEdict, const CCommand &args); +void LocalCommand_Meta(const CCommand &args); +void _ServerCommand(); +/* Variables */ +bool usermsgs_extracted = false; +CVector usermsgs_list; +CONPRINTF_FUNC echo_msg_func = NULL; +ICvar *icvar = NULL; +ISmmAPI *metamod_api = NULL; +IVEngineServer *engine = NULL; +IServerGameClients *gameclients = NULL; +VSPListener g_VspListener; +BaseProvider g_Ep1Provider; +IMetamodSourceProvider *provider = &g_Ep1Provider; +List conbases_unreg; +ConCommand meta_local_cmd("meta", LocalCommand_Meta, "Metamod:Source control options"); + +SH_DECL_HOOK2_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, edict_t *, const CCommand &); + +void BaseProvider::ConsolePrint(const char *str) +{ + if (echo_msg_func != NULL) + { + ConMsg("%s", str); + } + else + { + Msg("%s", str); + } +} + +void BaseProvider::Notify_DLLInit_Pre(void *gamedll, + CreateInterfaceFn engineFactory, + CreateInterfaceFn serverFactory) +{ + server = (IServerGameDLL *)gamedll; + engine = (IVEngineServer *)((engineFactory)(INTERFACEVERSION_VENGINESERVER, NULL)); + if (!engine) + { + DisplayError("Could not find IVEngineServer! Metamod cannot load."); + return; + } + icvar = (ICvar *)((engineFactory)(CVAR_INTERFACE_VERSION, NULL)); + if (!icvar) + { + DisplayError("Could not find ICvar! Metamod cannot load."); + return; + } + + if ((gameclients = (IServerGameClients *)(serverFactory("ServerGameClients003", NULL))) + == NULL) + { + gameclients = (IServerGameClients *)(serverFactory("ServerGameClients004", NULL)); + } + + RegisterConCommandBase(&meta_local_cmd); + conbases_unreg.push_back(&meta_local_cmd); + + echo_msg_func = ExtractRemotePrinter(engineFactory); + usermsgs_extracted = CacheUserMessages(); + + if (gameclients) + { + SH_ADD_HOOK_STATICFUNC(IServerGameClients, ClientCommand, gameclients, ClientCommand, false); + } +} + +void BaseProvider::Notify_DLLShutdown_Pre() +{ + List::iterator iter; + + for (iter = conbases_unreg.begin(); + iter != conbases_unreg.end(); + iter++) + { + UnregisterConCommandBase((*iter)); + } +} + +bool BaseProvider::IsRemotePrintingAvailable() +{ + return (echo_msg_func != NULL); +} + +void BaseProvider::ClientConsolePrint(edict_t *client, const char *message) +{ + engine->ClientPrintf(client, message); +} + +void BaseProvider::ServerCommand(const char *cmd) +{ + engine->ServerCommand(cmd); +} + +const char *BaseProvider::GetConVarString(ConVar *convar) +{ + if (convar == NULL) + { + return NULL; + } + + return convar->GetString(); +} + +bool BaseProvider::IsConCommandBaseACommand(ConCommandBase *pCommand) +{ + return pCommand->IsCommand(); +} + + +bool BaseProvider::IsSourceEngineBuildCompatible(int build) +{ + return (build == SOURCE_ENGINE_ORIGINAL + || build == SOURCE_ENGINE_EPISODEONE); +} + +const char *BaseProvider::GetCommandLineValue(const char *key, const char *defval) +{ + if (key[0] == '-' || key[0] == '+') + { + return CommandLine_Tier0()->ParmValue(key, defval); + } + else if (icvar) + { + const char *val; + if ((val = icvar->GetCommandLineValue(key)) == NULL) + { + return defval; + } + + return val; + } + + return NULL; +} + +int BaseProvider::TryServerGameDLL(const char *iface) +{ + if (strncmp(iface, "ServerGameDLL", 13) != 0) + { + return 0; + } + + return atoi(&iface[13]); +} + +bool BaseProvider::LogMessage(const char *buffer) +{ + if (!engine) + { + return false; + } + + engine->LogPrint(buffer); + + return true; +} + +bool BaseProvider::GetHookInfo(ProvidedHooks hook, SourceHook::MemFuncInfo *pInfo) +{ + SourceHook::MemFuncInfo mfi = {true, -1, 0, 0}; + + if (hook == ProvidedHook_LevelInit) + { + SourceHook::GetFuncInfo(&IServerGameDLL::LevelInit, mfi); + } + else if (hook == ProvidedHook_LevelShutdown) + { + SourceHook::GetFuncInfo(&IServerGameDLL::LevelShutdown, mfi); + } + else if (hook == ProvidedHook_GameInit) + { + SourceHook::GetFuncInfo(&IServerGameDLL::GameInit, mfi); + } + else if (hook == ProvidedHook_DLLShutdown) + { + SourceHook::GetFuncInfo(&IServerGameDLL::DLLShutdown, mfi); + } + else if (hook == ProvidedHook_DLLInit) + { + SourceHook::GetFuncInfo(&IServerGameDLL::DLLInit, mfi); + } + + *pInfo = mfi; + + return (mfi.thisptroffs >= 0); +} + +void BaseProvider::DisplayError(const char *fmt, ...) +{ + va_list ap; + char buffer[2048]; + + va_start(ap, fmt); + UTIL_FormatArgs(buffer, sizeof(buffer), fmt, ap); + va_end(ap); + + Error(buffer); +} + +void BaseProvider::DisplayWarning(const char *fmt, ...) +{ + va_list ap; + char buffer[2048]; + + va_start(ap, fmt); + UTIL_FormatArgs(buffer, sizeof(buffer), fmt, ap); + va_end(ap); + + Warning(buffer); +} + +IConCommandBaseAccessor *BaseProvider::GetConCommandBaseAccessor() +{ + return &g_SMConVarAccessor; +} + +bool BaseProvider::RegisterConCommandBase(ConCommandBase *pCommand) +{ + return g_SMConVarAccessor.Register(pCommand); +} + +void BaseProvider::UnregisterConCommandBase(ConCommandBase *pCommand) +{ + return g_SMConVarAccessor.Unregister(pCommand); +} + +int BaseProvider::GetUserMessageCount() +{ + if (!usermsgs_extracted) + { + return -1; + } + + return (int)usermsgs_list.size(); +} + +int BaseProvider::FindUserMessage(const char *name, int *size) +{ + for (size_t i = 0; i < usermsgs_list.size(); i++) + { + if (usermsgs_list[i].name.compare(name) == 0) + { + if (size) + { + *size = usermsgs_list[i].size; + } + return (int)i; + } + } + + return -1; +} + +const char *BaseProvider::GetUserMessage(int index, int *size) +{ + if (!usermsgs_extracted || index < 0 || index >= (int)usermsgs_list.size()) + { + return NULL; + } + + if (size) + { + *size = usermsgs_list[index].size; + } + + return usermsgs_list[index].name.c_str(); +} + +const char *BaseProvider::GetGameDescription() +{ + return server->GetGameDescription(); +} + +ConVar *BaseProvider::CreateConVar(const char *name, + const char *defval, + const char *help, + int flags) +{ + int newflags = 0; + if (flags & ConVarFlag_Notify) + { + newflags |= FCVAR_NOTIFY; + } + if (flags & ConVarFlag_Replicated) + { + newflags |= FCVAR_REPLICATED; + } + if (flags & ConVarFlag_SpOnly) + { + newflags |= FCVAR_SPONLY; + } + + ConVar *pVar = new ConVar(name, defval, newflags, help); + + RegisterConCommandBase(pVar); + conbases_unreg.push_back(pVar); + + return pVar; +} + +IServerPluginCallbacks *BaseProvider::GetVSPCallbacks(const char *iface) +{ + g_VspListener.SetLoadable(true); + return &g_VspListener; +} + +class GlobCommand : public IMetamodSourceCommandInfo +{ +public: + GlobCommand(const CCommand *cmd) : m_cmd(cmd) + { + } +public: + unsigned int GetArgCount() + { + return m_cmd->ArgC(); + } + + const char *GetArg(unsigned int num) + { + return m_cmd->Arg(num); + } + + const char *GetArgString() + { + return m_cmd->ArgS(); + } +private: + const CCommand *m_cmd; +}; + +void LocalCommand_Meta(const CCommand &args) +{ + GlobCommand cmd(&args); + Command_Meta(&cmd); +} + +void ClientCommand(edict_t *pEdict, const CCommand &_cmd) +{ + GlobCommand cmd(&_cmd); + + if (strcmp(cmd.GetArg(0), "meta") == 0) + { + Command_ClientMeta(pEdict, &cmd); + } +} + +bool vcmp(const void *_addr1, const void *_addr2, size_t len) +{ + unsigned char *addr1 = (unsigned char *)_addr1; + unsigned char *addr2 = (unsigned char *)_addr2; + + for (size_t i=0; i UserMsgDict; + +/* This is the ugliest function in all of SourceMM */ +bool CacheUserMessages() +{ + /* Get address of original GetUserMessageInfo() */ + char *vfunc = (char *)SH_GET_ORIG_VFNPTR_ENTRY(server, &IServerGameDLL::GetUserMessageInfo); + + /* Oh dear, we have a relative jump on our hands + * PVK II on Windows made me do this, but I suppose it doesn't hurt to check this on Linux too... + */ + if (*vfunc == '\xE9') + { + /* Get address from displacement... + * + * Add 5 because it's relative to next instruction: + * Opcode <1 byte> + 32-bit displacement <4 bytes> + */ + vfunc += *reinterpret_cast(vfunc + 1) + 5; + } + + CUtlDict *dict = NULL; + + if (vcmp(vfunc, MSGCLASS_SIG, MSGCLASS_SIGLEN)) + { + /* Get address of CUserMessages instance */ + char **userMsgClass = *reinterpret_cast(vfunc + MSGCLASS_OFFS); + + /* Get address of CUserMessages::m_UserMessages */ + dict = reinterpret_cast(*userMsgClass); + } + else if (vcmp(vfunc, MSGCLASS2_SIG, MSGCLASS2_SIGLEN)) + { + #ifdef OS_WIN32 + /* If we get here, the code is possibly inlined like in Dystopia */ + + /* Get the address of the CUtlRBTree */ + char *rbtree = *reinterpret_cast(vfunc + MSGCLASS2_OFFS); + + /* CUtlDict should be 8 bytes before the CUtlRBTree (hacktacular!) */ + dict = reinterpret_cast(rbtree - 8); + #elif defined OS_LINUX + /* Get address of CUserMessages instance */ + char **userMsgClass = *reinterpret_cast(vfunc + MSGCLASS2_OFFS); + + /* Get address of CUserMessages::m_UserMessages */ + dict = reinterpret_cast(*userMsgClass); + #endif + #ifdef OS_WIN32 + } + else if (vcmp(vfunc, MSGCLASS3_SIG, MSGCLASS3_SIGLEN)) + { + /* Get address of CUserMessages instance */ + char **userMsgClass = *reinterpret_cast(vfunc + MSGCLASS3_OFFS); + + /* Get address of CUserMessages::m_UserMessages */ + dict = reinterpret_cast(*userMsgClass); + #endif + } + + if (dict) + { + int msg_count = dict->Count(); + + /* Ensure that count is within bounds of an unsigned byte, because that's what engine supports */ + if (msg_count < 0 || msg_count > 255) + { + return false; + } + + UserMessage *msg; + UsrMsgInfo u_msg; + + /* Cache messages in our CUtlDict */ + for (int i = 0; i < msg_count; i++) + { + msg = dict->Element(i); + u_msg.name = msg->name; + u_msg.size = msg->size; + usermsgs_list.push_back(u_msg); + } + + return true; + } + + return false; +} + diff --git a/sourcemm/episode2/provider_ep2.h b/sourcemm/episode2/provider_ep2.h new file mode 100644 index 0000000..c042e11 --- /dev/null +++ b/sourcemm/episode2/provider_ep2.h @@ -0,0 +1,89 @@ +/** + * vim: set ts=4 : + * ====================================================== + * Metamod:Source + * Copyright (C) 2004-2007 AlliedModders LLC and authors. + * All rights reserved. + * ====================================================== + * + * This software is provided 'as-is', without any express or implied warranty. + * In no event will the authors be held liable for any damages arising from + * the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software in a + * product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + * Version: $Id$ + */ + +#ifndef _INCLUDE_METAMOD_SOURCE_BASE_PROVIDER_H_ +#define _INCLUDE_METAMOD_SOURCE_BASE_PROVIDER_H_ + +#if defined _DEBUG +#define DEBUG2 +#undef _DEBUG +#endif +#include +#include +#include +#include "ISmmAPI.h" +#include "metamod_provider.h" +#include "metamod_oslink.h" +#if defined DEBUG2 +#undef DEBUG2 +#define _DEBUG +#endif + +using namespace SourceMM; +using namespace SourceHook; + +class BaseProvider : public IMetamodSourceProvider +{ +public: + virtual bool IsSourceEngineBuildCompatible(int build); + virtual bool GetHookInfo(ProvidedHooks hook, SourceHook::MemFuncInfo *pInfo); + virtual bool LogMessage(const char *buffer); + virtual const char *GetCommandLineValue(const char *key, const char *defval); + virtual void ConsolePrint(const char *msg); + virtual bool IsRemotePrintingAvailable(); + virtual void ClientConsolePrint(edict_t *client, const char *msg); + virtual IServerPluginCallbacks *GetVSPCallbacks(const char *iface); + virtual void DisplayError(const char *fmt, ...); + virtual void DisplayWarning(const char *fmt, ...); + virtual int TryServerGameDLL(const char *iface); + virtual void Notify_DLLInit_Pre(void *gamedll, + CreateInterfaceFn engineFactory, + CreateInterfaceFn serverFactory); + void Notify_DLLShutdown_Pre(); + virtual void ServerCommand(const char *cmd); + virtual ConVar *CreateConVar(const char *name, + const char *defval, + const char *help, + int flags); + virtual const char *GetConVarString(ConVar *convar); + virtual const char *GetGameDescription(); + virtual IConCommandBaseAccessor *GetConCommandBaseAccessor(); + virtual bool RegisterConCommandBase(ConCommandBase *pCommand); + virtual void UnregisterConCommandBase(ConCommandBase *pCommand); + virtual bool IsConCommandBaseACommand(ConCommandBase *pCommand); + virtual int GetUserMessageCount(); + virtual int FindUserMessage(const char *name, int *size=NULL); + virtual const char *GetUserMessage(int index, int *size=NULL); +}; + +extern IVEngineServer *engine; +extern IServerGameDLL *server; +extern IServerGameClients *gameclients; +extern ICvar *icvar; + +#endif //_INCLUDE_METAMOD_SOURCE_BASE_PROVIDER_H_ + diff --git a/sourcemm/episode2/vsp_listener.cpp b/sourcemm/episode2/vsp_listener.cpp new file mode 100644 index 0000000..3adf2b5 --- /dev/null +++ b/sourcemm/episode2/vsp_listener.cpp @@ -0,0 +1,141 @@ +/** + * vim: set ts=4 : + * ====================================================== + * Metamod:Source + * Copyright (C) 2004-2007 AlliedModders LLC and authors. + * All rights reserved. + * ====================================================== + * + * This software is provided 'as-is', without any express or implied warranty. + * In no event will the authors be held liable for any damages arising from + * the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software in a + * product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + * Version: $Id$ + */ + +#include "vsp_listener.h" +#include "svn_version.h" +#include "metamod.h" + +using namespace SourceMM; + +VSPListener::VSPListener() +{ + m_bLoaded = false; + m_bLoadable = false; +} + +void VSPListener::ClientActive(edict_t *pEntity) +{ +} + +PLUGIN_RESULT VSPListener::ClientCommand(edict_t *pEntity, const CCommand &cmd) +{ + return PLUGIN_CONTINUE; +} + +PLUGIN_RESULT VSPListener::ClientConnect(bool *bAllowConnect, edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen) +{ + return PLUGIN_CONTINUE; +} + +void VSPListener::ClientDisconnect(edict_t *pEntity) +{ +} + +void VSPListener::ClientPutInServer(edict_t *pEntity, char const *playername) +{ +} + +void VSPListener::ClientSettingsChanged(edict_t *pEdict) +{ +} + +void VSPListener::SetCommandClient(int index) +{ +} + +void VSPListener::GameFrame(bool simulating) +{ +} + +const char *VSPListener::GetPluginDescription() +{ + return "Metamod:Source Interface v" SVN_FILE_VERSION_STRING; +} + +bool VSPListener::IsLoaded() +{ + return m_bLoaded; +} + +void VSPListener::LevelInit(char const *pMapName) +{ +} + +void VSPListener::LevelShutdown() +{ +} + +PLUGIN_RESULT VSPListener::NetworkIDValidated(const char *pszUserName, const char *pszNetworkID) +{ + return PLUGIN_CONTINUE; +} + +void VSPListener::Pause() +{ +} + +void VSPListener::UnPause() +{ +} + +void VSPListener::ServerActivate(edict_t *pEdictList, int edictCount, int clientMax) +{ +} + +void VSPListener::Unload() +{ +} + +void VSPListener::SetLoadable(bool set) +{ + m_bLoadable = set; +} + +bool VSPListener::Load(CreateInterfaceFn interfaceFactory, CreateInterfaceFn gameServerFactory) +{ + if (!m_bLoadable) + { + provider->DisplayWarning("Do not manually load Metamod:Source as a Valve Server Plugin\n"); + return false; + } + + if (m_bLoaded) + { + return false; + } + + m_bLoaded = true; + SetLoadable(false); + + g_Metamod.NotifyVSPListening(this); + + return true; +} + +void VSPListener::OnQueryCvarValueFinished(QueryCvarCookie_t iCookie, edict_t *pPlayerEntity, EQueryCvarValueStatus eStatus, const char *pCvarName, const char *pCvarValue ) +{ +} diff --git a/sourcemm/episode2/vsp_listener.h b/sourcemm/episode2/vsp_listener.h new file mode 100644 index 0000000..443606f --- /dev/null +++ b/sourcemm/episode2/vsp_listener.h @@ -0,0 +1,73 @@ +/** + * vim: set ts=4 : + * ====================================================== + * Metamod:Source + * Copyright (C) 2004-2007 AlliedModders LLC and authors. + * All rights reserved. + * ====================================================== + * + * This software is provided 'as-is', without any express or implied warranty. + * In no event will the authors be held liable for any damages arising from + * the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software in a + * product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + * Version: $Id$ + */ + +#ifndef _INCLUDE_METAMOD_SOURCE_VSP_LISTENER_H_ +#define _INCLUDE_METAMOD_SOURCE_VSP_LISTENER_H_ + +#if defined _DEBUG +#define DEBUG2 +#undef _DEBUG +#endif +#include "iserverplugin.h" +#if defined DEBUG2 +#undef DEBUG2 +#define _DEBUG +#endif + +class VSPListener : public IServerPluginCallbacks +{ +public: + VSPListener(); +public: + virtual bool Load(CreateInterfaceFn interfaceFactory, CreateInterfaceFn gameServerFactory); + virtual void Unload(); + virtual void Pause(); + virtual void UnPause(); + virtual const char *GetPluginDescription(); + virtual void LevelInit(char const *pMapName); + virtual void ServerActivate(edict_t *pEdictList, int edictCount, int clientMax); + virtual void GameFrame(bool simulating); + virtual void LevelShutdown(void); + virtual void ClientActive(edict_t *pEntity); + virtual void ClientDisconnect(edict_t *pEntity); + virtual void ClientPutInServer(edict_t *pEntity, char const *playername); + virtual void SetCommandClient(int index); + virtual void ClientSettingsChanged(edict_t *pEdict); + virtual PLUGIN_RESULT ClientConnect(bool *bAllowConnect, edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen); + virtual PLUGIN_RESULT ClientCommand(edict_t *pEntity, const CCommand &cmd); + virtual PLUGIN_RESULT NetworkIDValidated(const char *pszUserName, const char *pszNetworkID); + virtual void OnQueryCvarValueFinished( QueryCvarCookie_t iCookie, edict_t *pPlayerEntity, EQueryCvarValueStatus eStatus, const char *pCvarName, const char *pCvarValue ); +public: + bool IsLoaded(); + void SetLoadable(bool loadable); +private: + bool m_bLoaded; + bool m_bLoadable; +}; + +#endif //_INCLUDE_METAMOD_SOURCE_VSP_LISTENER_H_ + diff --git a/sourcemm/metamod.cpp b/sourcemm/metamod.cpp index 8c6e55e..8097f4d 100644 --- a/sourcemm/metamod.cpp +++ b/sourcemm/metamod.cpp @@ -238,14 +238,7 @@ SMM_API void *CreateInterface(const char *iface, int *ret) /* Get value of -game from command line, defaulting to hl2 as engine seems to do */ game_dir = provider->GetCommandLineValue("-game", "hl2"); - if (strcasecmp(game_dir, "ship") == 0) - { - engine_build = SOURCE_ENGINE_ORIGINAL; - } - else - { - engine_build = SOURCE_ENGINE_EPISODEONE; - } + engine_build = SOURCE_ENGINE_ORANGEBOX; /* Get absolute path */ abspath(game_path, game_dir); @@ -707,6 +700,10 @@ bool Handler_DLLInit(CreateInterfaceFn engineFactory, CreateInterfaceFn physicsF if (!pluginFile) { pluginFile = provider->GetConVarString(mm_pluginsfile); + if (pluginFile == NULL) + { + pluginFile = "addons/metamod/metaplugins.ini"; + } } char full_path[260];