mirror of
https://github.com/alliedmodders/metamod-source.git
synced 2025-02-17 10:54:14 +01:00
Initial version of GameInit, LevelInit, LevelShutdown hookup; removed cmds to manually trigger them.
This commit is contained in:
parent
1c7fb146ff
commit
a73b63cb51
238
core/metamod.cpp
238
core/metamod.cpp
@ -37,6 +37,9 @@
|
||||
#if defined __linux__
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#if SOURCE_ENGINE == SE_SOURCE2
|
||||
#include <iserver.h>
|
||||
#endif
|
||||
|
||||
using namespace SourceMM;
|
||||
using namespace SourceHook;
|
||||
@ -47,6 +50,35 @@ using namespace SourceHook::Impl;
|
||||
* @file sourcemm.cpp
|
||||
*/
|
||||
|
||||
#if SOURCE_ENGINE == SE_SOURCE2
|
||||
// Hack to make hook decl compile when only having forward decl in header.
|
||||
// (we have class structure but it requires protobuf which we don't want to include here)
|
||||
class GameSessionConfiguration_t { };
|
||||
|
||||
SH_DECL_MANUALHOOK4_void(SGD_StartupServer, 0, 0, 0, const GameSessionConfiguration_t &, INetworkGameServerFactory *, ISource2WorldSession *, const char *);
|
||||
SH_DECL_MANUALHOOK2_void(SGD_Init, 0, 0, 0, GameSessionConfiguration_t *, const char *);
|
||||
SH_DECL_MANUALHOOK0(SGD_StartChangeLevel, 0, 0, 0, CUtlVector<INetworkGameClient *> *);
|
||||
SH_DECL_MANUALHOOK5_void(SGD_SwitchToLoop, 0, 0, 0, const char *, KeyValues *, uint32, const char *, bool);
|
||||
SH_DECL_MANUALHOOK3(SGD_AllocateServer, 0, 0, 0, INetworkGameServer *, int, INetworkServerService *, ISource2WorldSession *);
|
||||
|
||||
static INetworkGameServer *
|
||||
Handler_AllocateServer(int, INetworkServerService *, ISource2WorldSession *);
|
||||
|
||||
static void
|
||||
Handler_SwitchToLoop(const char *, KeyValues *, uint32, const char *, bool);
|
||||
|
||||
static void
|
||||
Handler_StartupServer(const GameSessionConfiguration_t &, INetworkGameServerFactory *, ISource2WorldSession *, const char *);
|
||||
|
||||
static void
|
||||
Handler_StartupServer_Post(const GameSessionConfiguration_t &, INetworkGameServerFactory *, ISource2WorldSession *, const char *);
|
||||
|
||||
static void
|
||||
Handler_Init(GameSessionConfiguration_t *, const char *);
|
||||
|
||||
static CUtlVector<INetworkGameClient *> *
|
||||
Handler_StartChangeLevel();
|
||||
#else
|
||||
SH_DECL_MANUALHOOK0(SGD_GameInit, 0, 0, 0, bool);
|
||||
SH_DECL_MANUALHOOK6(SGD_LevelInit, 0, 0, 0, bool, const char *, const char *, const char *, const char *, bool, bool);
|
||||
SH_DECL_MANUALHOOK0_void(SGD_LevelShutdown, 0, 0, 0);
|
||||
@ -64,6 +96,7 @@ Handler_LevelInit(char const *pMapName,
|
||||
|
||||
static bool
|
||||
Handler_GameInit();
|
||||
#endif
|
||||
|
||||
static void
|
||||
InitializeVSP();
|
||||
@ -142,21 +175,6 @@ SourceMM::ISmmAPI *g_pMetamod = &g_Metamod;
|
||||
} \
|
||||
}
|
||||
|
||||
#if SOURCE_ENGINE == SE_SOURCE2
|
||||
void meta_game_init(const CCommand &args)
|
||||
{
|
||||
Handler_GameInit();
|
||||
}
|
||||
void meta_level_init(const CCommand &args)
|
||||
{
|
||||
Handler_LevelInit("dummy_level", "", "", "", false, false);
|
||||
}
|
||||
void meta_level_shutdown(const CCommand &args)
|
||||
{
|
||||
Handler_LevelShutdown();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Initialize everything here */
|
||||
void
|
||||
mm_InitializeForLoad()
|
||||
@ -171,7 +189,24 @@ mm_InitializeForLoad()
|
||||
*/
|
||||
in_first_level = true;
|
||||
|
||||
#if SOURCE_ENGINE != SE_SOURCE2
|
||||
#if SOURCE_ENGINE == SE_SOURCE2
|
||||
SourceHook::MemFuncInfo info;
|
||||
|
||||
if (!provider->GetHookInfo(ProvidedHook_StartupServer, &info))
|
||||
{
|
||||
provider->DisplayError("Metamod:Source could not find a valid hook for INetworkServerService::StartupServer");
|
||||
}
|
||||
SH_MANUALHOOK_RECONFIGURE(SGD_StartupServer, info.vtblindex, info.vtbloffs, info.thisptroffs);
|
||||
SH_ADD_MANUALHOOK(SGD_StartupServer, netservice, SH_STATIC(Handler_StartupServer), false);
|
||||
SH_ADD_MANUALHOOK(SGD_StartupServer, netservice, SH_STATIC(Handler_StartupServer_Post), true);
|
||||
|
||||
if (!provider->GetHookInfo(ProvidedHook_SwitchToLoop, &info))
|
||||
{
|
||||
provider->DisplayError("Metamod:Source could not find a valid hook for IEngineServiceMgr::SwitchToLoop");
|
||||
}
|
||||
SH_MANUALHOOK_RECONFIGURE(SGD_SwitchToLoop, info.vtblindex, info.vtbloffs, info.thisptroffs);
|
||||
SH_ADD_MANUALHOOK(SGD_SwitchToLoop, enginesvcmgr, SH_STATIC(Handler_SwitchToLoop), false);
|
||||
#else
|
||||
SourceHook::MemFuncInfo info;
|
||||
|
||||
if (!provider->GetHookInfo(ProvidedHook_GameInit, &info))
|
||||
@ -485,30 +520,6 @@ mm_InitializeGlobals(CreateInterfaceFn engineFactory,
|
||||
provider->Notify_DLLInit_Pre(engineFactory, gamedll_info.factory);
|
||||
}
|
||||
|
||||
static bool
|
||||
Handler_GameInit()
|
||||
{
|
||||
if (is_game_init)
|
||||
return true;
|
||||
|
||||
if (vsp_load_requested)
|
||||
InitializeVSP();
|
||||
|
||||
if (g_bIsVspBridged && !were_plugins_loaded)
|
||||
{
|
||||
DoInitialPluginLoads();
|
||||
g_PluginMngr.SetAllLoaded();
|
||||
were_plugins_loaded = true;
|
||||
}
|
||||
|
||||
is_game_init = true;
|
||||
#if SOURCE_ENGINE == SE_SOURCE2
|
||||
return true;
|
||||
#else
|
||||
RETURN_META_VALUE(MRES_IGNORED, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
mm_UnloadMetamod()
|
||||
{
|
||||
@ -521,8 +532,35 @@ mm_UnloadMetamod()
|
||||
}
|
||||
|
||||
static void
|
||||
Handler_LevelShutdown(void)
|
||||
mm_HandleGameInit()
|
||||
{
|
||||
if (is_game_init)
|
||||
return;
|
||||
|
||||
#if SOURCE_ENGINE == SE_SOURCE2
|
||||
Msg("MMS: GameInit\n");
|
||||
#endif
|
||||
|
||||
if (vsp_load_requested)
|
||||
InitializeVSP();
|
||||
|
||||
if (g_bIsVspBridged && !were_plugins_loaded)
|
||||
{
|
||||
DoInitialPluginLoads();
|
||||
g_PluginMngr.SetAllLoaded();
|
||||
were_plugins_loaded = true;
|
||||
}
|
||||
|
||||
is_game_init = true;
|
||||
}
|
||||
|
||||
static void
|
||||
mm_HandleLevelShutdown()
|
||||
{
|
||||
#if SOURCE_ENGINE == SE_SOURCE2
|
||||
Msg("MMS: LevelShutdown\n");
|
||||
#endif
|
||||
|
||||
if (g_bIsVspBridged && !were_plugins_loaded)
|
||||
{
|
||||
DoInitialPluginLoads();
|
||||
@ -553,11 +591,120 @@ Handler_LevelShutdown(void)
|
||||
}
|
||||
|
||||
ITER_EVENT(OnLevelShutdown, ());
|
||||
}
|
||||
|
||||
static void
|
||||
mm_HandleLevelInit(char const *pMapName,
|
||||
char const *pMapEntities,
|
||||
char const *pOldLevel,
|
||||
char const *pLandmarkName,
|
||||
bool loadGame,
|
||||
bool background)
|
||||
{
|
||||
#if SOURCE_ENGINE == SE_SOURCE2
|
||||
#else
|
||||
RETURN_META(MRES_IGNORED);
|
||||
Msg("MMS: LevelInit\n");
|
||||
#endif
|
||||
|
||||
ITER_EVENT(OnLevelInit, (pMapName, pMapEntities, pOldLevel, pLandmarkName, loadGame, background));
|
||||
}
|
||||
#include <utlbuffer.h>
|
||||
#if SOURCE_ENGINE == SE_SOURCE2
|
||||
static void
|
||||
Handler_SwitchToLoop(const char *pszLoopName, KeyValues *pKV, uint32 nId, const char *pszUnk, bool bUnk)
|
||||
{
|
||||
if (strcmp(pszLoopName, "levelload") == 0)
|
||||
{
|
||||
mm_HandleGameInit();
|
||||
}
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
static void
|
||||
Handler_StartupServer(const GameSessionConfiguration_t &config, INetworkGameServerFactory *pFactory, ISource2WorldSession *, const char *)
|
||||
{
|
||||
SourceHook::MemFuncInfo info;
|
||||
if (!provider->GetHookInfo(ProvidedHook_AllocateServer, &info))
|
||||
{
|
||||
provider->DisplayError("Metamod:Source could not find a valid hook for INetworkGameServerFactory::Allocate");
|
||||
}
|
||||
SH_MANUALHOOK_RECONFIGURE(SGD_AllocateServer, info.vtblindex, info.vtbloffs, info.thisptroffs);
|
||||
SH_ADD_MANUALHOOK(SGD_AllocateServer, pFactory, SH_STATIC(Handler_AllocateServer), true);
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
static void
|
||||
Handler_StartupServer_Post(const GameSessionConfiguration_t &config, INetworkGameServerFactory *pFactory, ISource2WorldSession *, const char *)
|
||||
{
|
||||
SH_REMOVE_MANUALHOOK(SGD_AllocateServer, pFactory, SH_STATIC(Handler_AllocateServer), true);
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
static INetworkGameServer *
|
||||
Handler_AllocateServer(int, INetworkServerService *, ISource2WorldSession *)
|
||||
{
|
||||
static bool bGameServerHooked = false;
|
||||
if (!bGameServerHooked)
|
||||
{
|
||||
INetworkGameServer *netserver = META_RESULT_ORIG_RET(INetworkGameServer *);
|
||||
|
||||
SourceHook::MemFuncInfo info;
|
||||
if (!provider->GetHookInfo(ProvidedHook_Init, &info))
|
||||
{
|
||||
provider->DisplayError("Metamod:Source could not find a valid hook for INetworkGameServer::Init");
|
||||
}
|
||||
SH_MANUALHOOK_RECONFIGURE(SGD_Init, info.vtblindex, info.vtbloffs, info.thisptroffs);
|
||||
SH_ADD_MANUALVPHOOK(SGD_Init, netserver, SH_STATIC(Handler_Init), false);
|
||||
|
||||
if (!provider->GetHookInfo(ProvidedHook_StartChangeLevel, &info))
|
||||
{
|
||||
provider->DisplayError("Metamod:Source could not find a valid hook for INetworkGameServer::StartChangeLevel");
|
||||
}
|
||||
SH_MANUALHOOK_RECONFIGURE(SGD_StartChangeLevel, info.vtblindex, info.vtbloffs, info.thisptroffs);
|
||||
SH_ADD_MANUALVPHOOK(SGD_StartChangeLevel, netserver, SH_STATIC(Handler_StartChangeLevel), false);
|
||||
|
||||
bGameServerHooked = true;
|
||||
}
|
||||
|
||||
RETURN_META_VALUE(MRES_IGNORED, nullptr);
|
||||
}
|
||||
|
||||
static void
|
||||
Handler_Init(GameSessionConfiguration_t *pConfig, const char *pszMapName)
|
||||
{
|
||||
static char szLastMap[260] = "";
|
||||
mm_HandleLevelInit(pszMapName, "", szLastMap, "", false, false);
|
||||
UTIL_Format(szLastMap, sizeof(szLastMap), "%s", pszMapName);
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
static CUtlVector<INetworkGameClient *> *
|
||||
Handler_StartChangeLevel()
|
||||
{
|
||||
mm_HandleLevelShutdown();
|
||||
|
||||
RETURN_META_VALUE(MRES_IGNORED, nullptr);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static bool
|
||||
Handler_GameInit()
|
||||
{
|
||||
mm_HandleGameInit();
|
||||
|
||||
RETURN_META_VALUE(MRES_IGNORED, true);
|
||||
}
|
||||
|
||||
static void
|
||||
Handler_LevelShutdown(void)
|
||||
{
|
||||
mm_HandleLevelShutdown();
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -570,12 +717,9 @@ Handler_LevelInit(char const *pMapName,
|
||||
{
|
||||
ITER_EVENT(OnLevelInit, (pMapName, pMapEntities, pOldLevel, pLandmarkName, loadGame, background));
|
||||
|
||||
#if SOURCE_ENGINE == SE_SOURCE2
|
||||
return false;
|
||||
#else
|
||||
RETURN_META_VALUE(MRES_IGNORED, false);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
void MetamodSource::LogMsg(ISmmPlugin *pl, const char *msg, ...)
|
||||
{
|
||||
|
@ -37,9 +37,17 @@ namespace SourceMM
|
||||
|
||||
enum ProvidedHooks
|
||||
{
|
||||
#if SOURCE_ENGINE == SE_SOURCE2
|
||||
ProvidedHook_StartChangeLevel = 0,
|
||||
ProvidedHook_Init = 1,
|
||||
ProvidedHook_StartupServer = 2,
|
||||
ProvidedHook_SwitchToLoop = 3,
|
||||
ProvidedHook_AllocateServer = 4,
|
||||
#else
|
||||
ProvidedHook_LevelInit = 0, /**< IServerGameDLL::LevelInit */
|
||||
ProvidedHook_LevelShutdown = 1, /**< IServerGameDLL::LevelShutdown */
|
||||
ProvidedHook_GameInit = 4, /**< IServerGameDLL::GameInit */
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -39,6 +39,9 @@
|
||||
#include <filesystem.h>
|
||||
#include "metamod.h"
|
||||
#include <tier1/KeyValues.h>
|
||||
#if SOURCE_ENGINE == SE_SOURCE2
|
||||
#include <iserver.h>
|
||||
#endif
|
||||
|
||||
#if SOURCE_ENGINE == SE_SOURCE2
|
||||
SH_DECL_HOOK1(ISource2ServerConfig, AllowDedicatedServers, const, 0, bool, EUniverse);
|
||||
@ -103,17 +106,14 @@ IFileSystem *baseFs = NULL;
|
||||
IServerGameDLL *server = NULL;
|
||||
#if SOURCE_ENGINE == SE_SOURCE2
|
||||
static ISource2ServerConfig *serverconfig = NULL;
|
||||
INetworkServerService *netservice = NULL;
|
||||
IEngineServiceMgr *enginesvcmgr = NULL;
|
||||
#endif
|
||||
IVEngineServer *engine = NULL;
|
||||
IServerGameClients *gameclients = NULL;
|
||||
CGlobalVars *gpGlobals = NULL;
|
||||
IMetamodSourceProvider *provider = &g_Ep1Provider;
|
||||
ConCommand meta_local_cmd("meta", LocalCommand_Meta, "Metamod:Source control options");
|
||||
#if SOURCE_ENGINE == SE_SOURCE2
|
||||
ConCommand _meta_game_init("meta_game_init", meta_game_init);
|
||||
ConCommand _meta_level_init("meta_level_init", meta_level_init);
|
||||
ConCommand _meta_level_shutdown("meta_level_shutdown", meta_level_shutdown);
|
||||
#endif
|
||||
|
||||
#if SOURCE_ENGINE == SE_DOTA || SOURCE_ENGINE == SE_SOURCE2
|
||||
SH_DECL_HOOK2_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, CEntityIndex, const CCommand &);
|
||||
@ -144,6 +144,8 @@ void BaseProvider::Notify_DLLInit_Pre(CreateInterfaceFn engineFactory,
|
||||
#if SOURCE_ENGINE == SE_SOURCE2
|
||||
gpGlobals = engine->GetServerGlobals();
|
||||
serverconfig = (ISource2ServerConfig *) ((serverFactory) (INTERFACEVERSION_SERVERCONFIG, NULL));
|
||||
netservice = (INetworkServerService *) ((engineFactory) (NETWORKSERVERSERVICE_INTERFACE_VERSION, NULL));
|
||||
enginesvcmgr = (IEngineServiceMgr *) ((engineFactory) (ENGINESERVICEMGR_INTERFACE_VERSION, NULL));
|
||||
#endif
|
||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||
icvar = (ICvar *)((engineFactory)(CVAR_INTERFACE_VERSION, NULL));
|
||||
@ -177,11 +179,6 @@ void BaseProvider::Notify_DLLInit_Pre(CreateInterfaceFn engineFactory,
|
||||
#endif
|
||||
|
||||
g_SMConVarAccessor.RegisterConCommandBase(&meta_local_cmd);
|
||||
#if SOURCE_ENGINE == SE_SOURCE2
|
||||
g_SMConVarAccessor.RegisterConCommandBase(&_meta_game_init);
|
||||
g_SMConVarAccessor.RegisterConCommandBase(&_meta_level_init);
|
||||
g_SMConVarAccessor.RegisterConCommandBase(&_meta_level_shutdown);
|
||||
#endif
|
||||
|
||||
CacheUserMessages();
|
||||
|
||||
@ -308,7 +305,34 @@ bool BaseProvider::LogMessage(const char *buffer)
|
||||
|
||||
bool BaseProvider::GetHookInfo(ProvidedHooks hook, SourceHook::MemFuncInfo *pInfo)
|
||||
{
|
||||
#if SOURCE_ENGINE != SE_SOURCE2
|
||||
#if SOURCE_ENGINE == SE_SOURCE2
|
||||
SourceHook::MemFuncInfo mfi = {true, -1, 0, 0};
|
||||
|
||||
switch (hook)
|
||||
{
|
||||
case ProvidedHook_StartupServer:
|
||||
SourceHook::GetFuncInfo(&INetworkServerService::StartupServer, mfi);
|
||||
break;
|
||||
case ProvidedHook_StartChangeLevel:
|
||||
SourceHook::GetFuncInfo(&INetworkGameServer::StartChangeLevel, mfi);
|
||||
break;
|
||||
case ProvidedHook_Init:
|
||||
SourceHook::GetFuncInfo(&INetworkGameServer::Init, mfi);
|
||||
break;
|
||||
case ProvidedHook_SwitchToLoop:
|
||||
SourceHook::GetFuncInfo(&IEngineServiceMgr::SwitchToLoop, mfi);
|
||||
break;
|
||||
case ProvidedHook_AllocateServer:
|
||||
SourceHook::GetFuncInfo(&INetworkGameServerFactory::Allocate, mfi);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
*pInfo = mfi;
|
||||
|
||||
return (mfi.thisptroffs >= 0);
|
||||
#else
|
||||
SourceHook::MemFuncInfo mfi = {true, -1, 0, 0};
|
||||
|
||||
if (hook == ProvidedHook_LevelInit)
|
||||
@ -327,8 +351,6 @@ bool BaseProvider::GetHookInfo(ProvidedHooks hook, SourceHook::MemFuncInfo *pInf
|
||||
*pInfo = mfi;
|
||||
|
||||
return (mfi.thisptroffs >= 0);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -46,6 +46,8 @@
|
||||
using namespace SourceMM;
|
||||
using namespace SourceHook;
|
||||
|
||||
class INetworkGameServer;
|
||||
|
||||
class BaseProvider : public IMetamodSourceProvider
|
||||
{
|
||||
public:
|
||||
@ -89,6 +91,10 @@ extern IServerGameDLL *server;
|
||||
extern IServerGameClients *gameclients;
|
||||
extern ICvar *icvar;
|
||||
extern CGlobalVars *gpGlobals;
|
||||
#if SOURCE_ENGINE == SE_SOURCE2
|
||||
extern INetworkServerService *netservice;
|
||||
extern IEngineServiceMgr *enginesvcmgr;
|
||||
#endif
|
||||
|
||||
#endif //_INCLUDE_METAMOD_SOURCE_BASE_PROVIDER_H_
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user