1
0
mirror of https://github.com/alliedmodders/metamod-source.git synced 2024-12-04 16:24:16 +01:00
HLMetaModOfficial/sourcemm/sample_mm/SamplePlugin.cpp
Scott Ehlert 3d7ae5c6ed Wow, lots of stuff here
1) Bumped version to 1.3
2) Fixed MSVC project files to compile and link against latest SDK
3) Fixed Linux compilation of stub_mm and sample_mm against new SDK (added -msse to makefiles)
4) Removed -fpermissive and -Wno-deprecated from Linux makefiles
5) Added -Wall -Wno-non-virtual-dtor -Werror to Linux makefiles
6) Stub_mm and sample_mm no longer dynamically link to libstdc++
7) SourceMM, stub_mm, and sample_mm compile cleanly (no warnings) with GCC 3.4.x and 4.x

--HG--
extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/trunk%40269
2006-08-13 11:34:30 +00:00

242 lines
9.7 KiB
C++

/* ======== sample_mm ========
* Copyright (C) 2004-2005 Metamod:Source Development Team
* No warranties of any kind
*
* License: zlib/libpng
*
* Author(s): David "BAILOPAN" Anderson
* ============================
*/
#include <oslink.h>
#include "SamplePlugin.h"
#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_var = 0; \
break; \
} \
if (num_var >= 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);
RETURN_META_VALUE(MRES_IGNORED, true);
}
void SamplePlugin::OnLevelShutdown()
{
META_LOG(g_PLAPI, "OnLevelShutdown() called from listener");
}
void SamplePlugin::ServerActivate(edict_t *pEdictList, int edictCount, int clientMax)
{
META_LOG(g_PLAPI, "ServerActivate() called: edictCount=%d, clientMax=%d", edictCount, clientMax);
RETURN_META(MRES_IGNORED);
}
void SamplePlugin::GameFrame(bool simulating)
{
//don't log this, it just pumps stuff to the screen ;]
//META_LOG(g_PLAPI, "GameFrame() called: simulating=%d", simulating);
RETURN_META(MRES_IGNORED);
}
void SamplePlugin::LevelShutdown( void )
{
META_LOG(g_PLAPI, "LevelShutdown() called");
RETURN_META(MRES_IGNORED);
}
void SamplePlugin::ClientActive(edict_t *pEntity, bool bLoadGame)
{
META_LOG(g_PLAPI, "ClientActive called: pEntity=%d", pEntity ? m_Engine->IndexOfEdict(pEntity) : 0);
RETURN_META(MRES_IGNORED);
}
void SamplePlugin::ClientDisconnect(edict_t *pEntity)
{
META_LOG(g_PLAPI, "ClientDisconnect called: pEntity=%d", pEntity ? m_Engine->IndexOfEdict(pEntity) : 0);
RETURN_META(MRES_IGNORED);
}
void SamplePlugin::ClientPutInServer(edict_t *pEntity, char const *playername)
{
META_LOG(g_PLAPI, "ClientPutInServer called: pEntity=%d, playername=%s", pEntity ? m_Engine->IndexOfEdict(pEntity) : 0, playername);
RETURN_META(MRES_IGNORED);
}
void SamplePlugin::SetCommandClient(int index)
{
META_LOG(g_PLAPI, "SetCommandClient() called: index=%d", index);
RETURN_META(MRES_IGNORED);
}
void SamplePlugin::ClientSettingsChanged(edict_t *pEdict)
{
META_LOG(g_PLAPI, "ClientSettingsChanged called: pEdict=%d", pEdict ? m_Engine->IndexOfEdict(pEdict) : 0);
RETURN_META(MRES_IGNORED);
}
bool SamplePlugin::ClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen)
{
META_LOG(g_PLAPI, "ClientConnect called: pEntity=%d, pszName=%s, pszAddress=%s", pEntity ? m_Engine->IndexOfEdict(pEntity) : 0, pszName, pszAddress);
RETURN_META_VALUE(MRES_IGNORED, true);
}
void SamplePlugin::ClientCommand(edict_t *pEntity)
{
META_LOG(g_PLAPI, "ClientCommand called: pEntity=%d (commandString=%s)", pEntity ? m_Engine->IndexOfEdict(pEntity) : 0, m_Engine->Cmd_Args() ? m_Engine->Cmd_Args() : "");
RETURN_META(MRES_IGNORED);
}
bool FireEvent_Handler(IGameEvent *event, bool bDontBroadcast)
{
if (!event || !event->GetName())
RETURN_META_VALUE(MRES_IGNORED, false);
const char *name = event->GetName();
META_LOG(g_PLAPI, "FireGameEvent called: name=%s", name);
RETURN_META_VALUE(MRES_IGNORED, true);
}
bool SamplePlugin::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late)
{
PLUGIN_SAVEVARS();
char iface_buffer[255];
int num = 0;
strcpy(iface_buffer, "ServerGameDLL003");
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);
//We're hooking the following things as POST, in order to seem like Server Plugins.
//However, I don't actually know if Valve has done server plugins as POST or not.
//Change the last parameter to 'false' in order to change this to PRE.
//SH_ADD_HOOK_MEMFUNC means "SourceHook, Add Hook, Member Function".
//Hook LevelInit to our function
SH_ADD_HOOK_MEMFUNC(IServerGameDLL, LevelInit, m_ServerDll, &g_SamplePlugin, &SamplePlugin::LevelInit, true);
//Hook ServerActivate to our function
SH_ADD_HOOK_MEMFUNC(IServerGameDLL, ServerActivate, m_ServerDll, &g_SamplePlugin, &SamplePlugin::ServerActivate, true);
//Hook GameFrame to our function
SH_ADD_HOOK_MEMFUNC(IServerGameDLL, GameFrame, m_ServerDll, &g_SamplePlugin, &SamplePlugin::GameFrame, true);
//Hook LevelShutdown to our function -- this makes more sense as pre I guess
SH_ADD_HOOK_MEMFUNC(IServerGameDLL, LevelShutdown, m_ServerDll, &g_SamplePlugin, &SamplePlugin::LevelShutdown, false);
//Hook ClientActivate to our function
SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientActive, m_ServerClients, &g_SamplePlugin, &SamplePlugin::ClientActive, true);
//Hook ClientDisconnect to our function
SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, m_ServerClients, &g_SamplePlugin, &SamplePlugin::ClientDisconnect, true);
//Hook ClientPutInServer to our function
SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientPutInServer, m_ServerClients, &g_SamplePlugin, &SamplePlugin::ClientPutInServer, true);
//Hook SetCommandClient to our function
SH_ADD_HOOK_MEMFUNC(IServerGameClients, SetCommandClient, m_ServerClients, &g_SamplePlugin, &SamplePlugin::SetCommandClient, true);
//Hook ClientSettingsChanged to our function
SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientSettingsChanged, m_ServerClients, &g_SamplePlugin, &SamplePlugin::ClientSettingsChanged, true);
//The following functions are pre handled, because that's how they are in IServerPluginCallbacks
//Hook ClientConnect to our function
SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientConnect, m_ServerClients, &g_SamplePlugin, &SamplePlugin::ClientConnect, false);
//Hook ClientCommand to our function
SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientCommand, m_ServerClients, &g_SamplePlugin, &SamplePlugin::ClientCommand, false);
//This hook is a static hook, no member function
SH_ADD_HOOK_STATICFUNC(IGameEventManager2, FireEvent, m_GameEventManager, FireEvent_Handler, false);
//Get the call class for IVServerEngine so we can safely call functions without
// invoking their hooks (when needed).
m_Engine_CC = SH_GET_CALLCLASS(m_Engine);
SH_CALL(m_Engine_CC, &IVEngineServer::LogPrint)("All hooks started!\n");
g_SMAPI->AddListener(g_PLAPI, this);
return true;
}
bool SamplePlugin::Unload(char *error, size_t maxlen)
{
//IT IS CRUCIAL THAT YOU REMOVE CVARS.
//As of Metamod:Source 1.00-RC2, it will automatically remove them for you.
//But this is only if you've registered them correctly!
//Make sure we remove any hooks we did... this may not be necessary since
//SourceHook is capable of unloading plugins' hooks itself, but just to be safe.
SH_REMOVE_HOOK_STATICFUNC(IGameEventManager2, FireEvent, m_GameEventManager, FireEvent_Handler, false);
SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, LevelInit, m_ServerDll, &g_SamplePlugin, &SamplePlugin::LevelInit, true);
SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, ServerActivate, m_ServerDll, &g_SamplePlugin, &SamplePlugin::ServerActivate, true);
SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, GameFrame, m_ServerDll, &g_SamplePlugin, &SamplePlugin::GameFrame, true);
SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, LevelShutdown, m_ServerDll, &g_SamplePlugin, &SamplePlugin::LevelShutdown, false);
SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientActive, m_ServerClients, &g_SamplePlugin, &SamplePlugin::ClientActive, true);
SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, m_ServerClients, &g_SamplePlugin, &SamplePlugin::ClientDisconnect, true);
SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientPutInServer, m_ServerClients, &g_SamplePlugin, &SamplePlugin::ClientPutInServer, true);
SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, SetCommandClient, m_ServerClients, &g_SamplePlugin, &SamplePlugin::SetCommandClient, true);
SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientSettingsChanged, m_ServerClients, &g_SamplePlugin, &SamplePlugin::ClientSettingsChanged, true);
SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientConnect, m_ServerClients, &g_SamplePlugin, &SamplePlugin::ClientConnect, false);
SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientCommand, m_ServerClients, &g_SamplePlugin, &SamplePlugin::ClientCommand, false);
//this, sourcehook does not keep track of. we must do this.
SH_RELEASE_CALLCLASS(m_Engine_CC);
return true;
}
void SamplePlugin::AllPluginsLoaded()
{
//we don't really need this for anything other than interplugin communication
//and that's not used in this plugin.
//If we really wanted, we could override the factories so other plugins can request
// 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;
}