1
0
mirror of https://github.com/alliedmodders/metamod-source.git synced 2024-11-29 11:24:19 +01:00
HLMetaModOfficial/sample_mm/sample_mm.cpp
MrWaggel bde5403495 Removed deprecated hook NetworkIDValidated
IServerGameClients does not have this function anymore, and declared hook is not being used in the sample anyways.

Should compile on GCC now.
2016-06-27 13:18:35 +02:00

358 lines
12 KiB
C++

/**
* vim: set ts=4 sw=4 tw=99 noet :
* ======================================================
* Metamod:Source Sample Plugin
* Written by AlliedModders LLC.
* ======================================================
*
* 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.
*
* This sample plugin is public domain.
*/
#include <stdio.h>
#include "sample_mm.h"
SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, 0, bool, char const *, char const *, char const *, char const *, bool, bool);
SH_DECL_HOOK3_void(IServerGameDLL, ServerActivate, SH_NOATTRIB, 0, edict_t *, int, int);
SH_DECL_HOOK1_void(IServerGameDLL, GameFrame, SH_NOATTRIB, 0, bool);
SH_DECL_HOOK0_void(IServerGameDLL, LevelShutdown, SH_NOATTRIB, 0);
SH_DECL_HOOK2_void(IServerGameClients, ClientActive, SH_NOATTRIB, 0, edict_t *, bool);
SH_DECL_HOOK1_void(IServerGameClients, ClientDisconnect, SH_NOATTRIB, 0, edict_t *);
SH_DECL_HOOK2_void(IServerGameClients, ClientPutInServer, SH_NOATTRIB, 0, edict_t *, char const *);
SH_DECL_HOOK1_void(IServerGameClients, SetCommandClient, SH_NOATTRIB, 0, int);
SH_DECL_HOOK1_void(IServerGameClients, ClientSettingsChanged, SH_NOATTRIB, 0, edict_t *);
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 SOURCE_ENGINE >= SE_ORANGEBOX
SH_DECL_HOOK2_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, edict_t *, const CCommand &);
#else
SH_DECL_HOOK1_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, edict_t *);
#endif
SamplePlugin g_SamplePlugin;
IServerGameDLL *server = NULL;
IServerGameClients *gameclients = NULL;
IVEngineServer *engine = NULL;
IServerPluginHelpers *helpers = NULL;
IGameEventManager2 *gameevents = NULL;
IServerPluginCallbacks *vsp_callbacks = NULL;
IPlayerInfoManager *playerinfomanager = NULL;
ICvar *icvar = NULL;
CGlobalVars *gpGlobals = 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(SamplePlugin, g_SamplePlugin);
bool SamplePlugin::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late)
{
PLUGIN_SAVEVARS();
GET_V_IFACE_CURRENT(GetEngineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER);
GET_V_IFACE_CURRENT(GetEngineFactory, gameevents, IGameEventManager2, INTERFACEVERSION_GAMEEVENTSMANAGER2);
GET_V_IFACE_CURRENT(GetEngineFactory, helpers, IServerPluginHelpers, INTERFACEVERSION_ISERVERPLUGINHELPERS);
GET_V_IFACE_CURRENT(GetEngineFactory, icvar, ICvar, CVAR_INTERFACE_VERSION);
GET_V_IFACE_ANY(GetServerFactory, server, IServerGameDLL, INTERFACEVERSION_SERVERGAMEDLL);
GET_V_IFACE_ANY(GetServerFactory, gameclients, IServerGameClients, INTERFACEVERSION_SERVERGAMECLIENTS);
GET_V_IFACE_ANY(GetServerFactory, playerinfomanager, IPlayerInfoManager, INTERFACEVERSION_PLAYERINFOMANAGER);
gpGlobals = ismm->GetCGlobals();
META_LOG(g_PLAPI, "Starting plugin.");
/* Load the VSP listener. This is usually needed for IServerPluginHelpers. */
if ((vsp_callbacks = ismm->GetVSPInfo(NULL)) == NULL)
{
ismm->AddListener(this, this);
ismm->EnableVSPListener();
}
SH_ADD_HOOK_MEMFUNC(IServerGameDLL, LevelInit, server, this, &SamplePlugin::Hook_LevelInit, true);
SH_ADD_HOOK_MEMFUNC(IServerGameDLL, ServerActivate, server, this, &SamplePlugin::Hook_ServerActivate, true);
SH_ADD_HOOK_MEMFUNC(IServerGameDLL, GameFrame, server, this, &SamplePlugin::Hook_GameFrame, true);
SH_ADD_HOOK_MEMFUNC(IServerGameDLL, LevelShutdown, server, this, &SamplePlugin::Hook_LevelShutdown, false);
SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientActive, gameclients, this, &SamplePlugin::Hook_ClientActive, true);
SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, gameclients, this, &SamplePlugin::Hook_ClientDisconnect, true);
SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientPutInServer, gameclients, this, &SamplePlugin::Hook_ClientPutInServer, true);
SH_ADD_HOOK_MEMFUNC(IServerGameClients, SetCommandClient, gameclients, this, &SamplePlugin::Hook_SetCommandClient, true);
SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientSettingsChanged, gameclients, this, &SamplePlugin::Hook_ClientSettingsChanged, false);
SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientConnect, gameclients, this, &SamplePlugin::Hook_ClientConnect, false);
SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientCommand, gameclients, this, &SamplePlugin::Hook_ClientCommand, false);
ENGINE_CALL(LogPrint)("All hooks started!\n");
#if SOURCE_ENGINE >= SE_ORANGEBOX
g_pCVar = icvar;
ConVar_Register(0, &s_BaseAccessor);
#else
ConCommandBaseMgr::OneTimeInit(&s_BaseAccessor);
#endif
return true;
}
bool SamplePlugin::Unload(char *error, size_t maxlen)
{
SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, LevelInit, server, this, &SamplePlugin::Hook_LevelInit, true);
SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, ServerActivate, server, this, &SamplePlugin::Hook_ServerActivate, true);
SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, GameFrame, server, this, &SamplePlugin::Hook_GameFrame, true);
SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, LevelShutdown, server, this, &SamplePlugin::Hook_LevelShutdown, false);
SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientActive, gameclients, this, &SamplePlugin::Hook_ClientActive, true);
SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, gameclients, this, &SamplePlugin::Hook_ClientDisconnect, true);
SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientPutInServer, gameclients, this, &SamplePlugin::Hook_ClientPutInServer, true);
SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, SetCommandClient, gameclients, this, &SamplePlugin::Hook_SetCommandClient, true);
SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientSettingsChanged, gameclients, this, &SamplePlugin::Hook_ClientSettingsChanged, false);
SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientConnect, gameclients, this, &SamplePlugin::Hook_ClientConnect, false);
SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientCommand, gameclients, this, &SamplePlugin::Hook_ClientCommand, false);
return true;
}
void SamplePlugin::OnVSPListening(IServerPluginCallbacks *iface)
{
vsp_callbacks = iface;
}
void SamplePlugin::Hook_ServerActivate(edict_t *pEdictList, int edictCount, int clientMax)
{
META_LOG(g_PLAPI, "ServerActivate() called: edictCount = %d, clientMax = %d", edictCount, clientMax);
}
void SamplePlugin::AllPluginsLoaded()
{
/* This is where we'd do stuff that relies on the mod or other plugins
* being initialized (for example, cvars added and events registered).
*/
}
void SamplePlugin::Hook_ClientActive(edict_t *pEntity, bool bLoadGame)
{
META_LOG(g_PLAPI, "Hook_ClientActive(%d, %d)", IndexOfEdict(pEntity), bLoadGame);
}
#if SOURCE_ENGINE >= SE_ORANGEBOX
void SamplePlugin::Hook_ClientCommand(edict_t *pEntity, const CCommand &args)
#else
void SamplePlugin::Hook_ClientCommand(edict_t *pEntity)
#endif
{
#if SOURCE_ENGINE <= SE_DARKMESSIAH
CCommand args;
#endif
if (!pEntity || pEntity->IsFree())
{
return;
}
const char *cmd = args.Arg(0);
if (strcmp(cmd, "menu") == 0)
{
KeyValues *kv = new KeyValues("menu");
kv->SetString("title", "You've got options, hit ESC");
kv->SetInt("level", 1);
kv->SetColor("color", Color(255, 0, 0, 255));
kv->SetInt("time", 20);
kv->SetString("msg", "Pick an option\nOr don't.");
for (int i = 1; i < 9; i++)
{
char num[10], msg[10], cmd[10];
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);
item1->SetString("command", cmd);
}
helpers->CreateMessage(pEntity, DIALOG_MENU, kv, vsp_callbacks);
kv->deleteThis();
RETURN_META(MRES_SUPERCEDE);
}
else if (strcmp(cmd, "rich") == 0)
{
KeyValues *kv = new KeyValues("menu");
kv->SetString("title", "A rich message");
kv->SetInt("level", 1);
kv->SetInt("time", 20);
kv->SetString("msg", "This is a long long long text string.\n\nIt also has line breaks.");
helpers->CreateMessage(pEntity, DIALOG_TEXT, kv, vsp_callbacks);
kv->deleteThis();
RETURN_META(MRES_SUPERCEDE);
}
else if (strcmp(cmd, "msg") == 0)
{
KeyValues *kv = new KeyValues("menu");
kv->SetString("title", "Just a simple hello");
kv->SetInt("level", 1);
kv->SetInt("time", 20);
helpers->CreateMessage(pEntity, DIALOG_MSG, kv, vsp_callbacks);
kv->deleteThis();
RETURN_META(MRES_SUPERCEDE);
}
else if (strcmp(cmd, "entry") == 0)
{
KeyValues *kv = new KeyValues("entry");
kv->SetString("title", "Stuff");
kv->SetString("msg", "Enter something");
kv->SetString("command", "say"); // anything they enter into the dialog turns into a say command
kv->SetInt("level", 1);
kv->SetInt("time", 20);
helpers->CreateMessage(pEntity, DIALOG_ENTRY, kv, vsp_callbacks);
kv->deleteThis();
RETURN_META(MRES_SUPERCEDE);
}
}
void SamplePlugin::Hook_ClientSettingsChanged(edict_t *pEdict)
{
if (playerinfomanager)
{
IPlayerInfo *playerinfo = playerinfomanager->GetPlayerInfo(pEdict);
const char *name = engine->GetClientConVarValue(IndexOfEdict(pEdict), "name");
if (playerinfo != NULL
&& name != NULL
&& strcmp(engine->GetPlayerNetworkIDString(pEdict), "BOT") != 0
&& playerinfo->GetName() != NULL
&& strcmp(name, playerinfo->GetName()) == 0)
{
char msg[128];
MM_Format(msg, sizeof(msg), "Your name changed to \"%s\" (from \"%s\")\n", name, playerinfo->GetName());
engine->ClientPrintf(pEdict, msg);
}
}
}
bool SamplePlugin::Hook_ClientConnect(edict_t *pEntity,
const char *pszName,
const char *pszAddress,
char *reject,
int maxrejectlen)
{
META_LOG(g_PLAPI, "Hook_ClientConnect(%d, \"%s\", \"%s\")", IndexOfEdict(pEntity), pszName, pszAddress);
return true;
}
void SamplePlugin::Hook_ClientPutInServer(edict_t *pEntity, char const *playername)
{
KeyValues *kv = new KeyValues( "msg" );
kv->SetString( "title", "Hello" );
kv->SetString( "msg", "Hello there" );
kv->SetColor( "color", Color( 255, 0, 0, 255 ));
kv->SetInt( "level", 5);
kv->SetInt( "time", 10);
helpers->CreateMessage(pEntity, DIALOG_MSG, kv, vsp_callbacks);
kv->deleteThis();
}
void SamplePlugin::Hook_ClientDisconnect(edict_t *pEntity)
{
META_LOG(g_PLAPI, "Hook_ClientDisconnect(%d)", IndexOfEdict(pEntity));
}
void SamplePlugin::Hook_GameFrame(bool simulating)
{
/**
* simulating:
* ***********
* true | game is ticking
* false | game is not ticking
*/
}
bool SamplePlugin::Hook_LevelInit(const char *pMapName,
char const *pMapEntities,
char const *pOldLevel,
char const *pLandmarkName,
bool loadGame,
bool background)
{
META_LOG(g_PLAPI, "Hook_LevelInit(%s)", pMapName);
return true;
}
void SamplePlugin::Hook_LevelShutdown()
{
META_LOG(g_PLAPI, "Hook_LevelShutdown()");
}
void SamplePlugin::Hook_SetCommandClient(int index)
{
META_LOG(g_PLAPI, "Hook_SetCommandClient(%d)", index);
}
bool SamplePlugin::Pause(char *error, size_t maxlen)
{
return true;
}
bool SamplePlugin::Unpause(char *error, size_t maxlen)
{
return true;
}
const char *SamplePlugin::GetLicense()
{
return "Public Domain";
}
const char *SamplePlugin::GetVersion()
{
return "1.0.0.0";
}
const char *SamplePlugin::GetDate()
{
return __DATE__;
}
const char *SamplePlugin::GetLogTag()
{
return "SAMPLE";
}
const char *SamplePlugin::GetAuthor()
{
return "AlliedModders LLC";
}
const char *SamplePlugin::GetDescription()
{
return "Sample basic plugin";
}
const char *SamplePlugin::GetName()
{
return "Sample Plugin";
}
const char *SamplePlugin::GetURL()
{
return "http://www.sourcemm.net/";
}