mirror of
https://github.com/alliedmodders/metamod-source.git
synced 2025-12-09 03:18:29 +00:00
experimental commit of a new feature
--HG-- branch : sourcemm-1.4.3 extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/sourcemm-1.4.3%40586
This commit is contained in:
parent
09b4abab9c
commit
41d6c2c37e
@ -487,7 +487,7 @@ void CSmmAPI::LoadAsVSP()
|
|||||||
void CSmmAPI::EnableVSPListener()
|
void CSmmAPI::EnableVSPListener()
|
||||||
{
|
{
|
||||||
/* If GameInit already passed and we're not already enabled or loaded, go ahead and LoadAsVSP load */
|
/* If GameInit already passed and we're not already enabled or loaded, go ahead and LoadAsVSP load */
|
||||||
if (bGameInit && !m_VSP && !g_VspListener.IsLoaded())
|
if (bGameInit && !m_VSP && !g_VspListener.IsLoaded() && !g_VspListener.IsRootLoadMethod())
|
||||||
{
|
{
|
||||||
LoadAsVSP();
|
LoadAsVSP();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,6 +19,7 @@
|
|||||||
#include "CPlugin.h"
|
#include "CPlugin.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "vsp_listener.h"
|
#include "vsp_listener.h"
|
||||||
|
#include "iplayerinfo.h"
|
||||||
#include <filesystem.h>
|
#include <filesystem.h>
|
||||||
|
|
||||||
using namespace SourceMM;
|
using namespace SourceMM;
|
||||||
@ -63,7 +64,7 @@ int g_GameDllVersion = 0;
|
|||||||
const char VSPIFACE_001[] = "ISERVERPLUGINCALLBACKS001";
|
const char VSPIFACE_001[] = "ISERVERPLUGINCALLBACKS001";
|
||||||
const char VSPIFACE_002[] = "ISERVERPLUGINCALLBACKS002";
|
const char VSPIFACE_002[] = "ISERVERPLUGINCALLBACKS002";
|
||||||
const char GAMEINFO_PATH[] = "|gameinfo_path|";
|
const char GAMEINFO_PATH[] = "|gameinfo_path|";
|
||||||
IBaseFileSystem *baseFs = NULL;
|
IFileSystem *baseFs = NULL;
|
||||||
|
|
||||||
|
|
||||||
void ClearGamedllList();
|
void ClearGamedllList();
|
||||||
@ -125,14 +126,10 @@ void InitMainStates()
|
|||||||
SH_ADD_HOOK_STATICFUNC(IServerGameDLL, GameInit, g_GameDll.pGameDLL, GameInit_handler, false);
|
SH_ADD_HOOK_STATICFUNC(IServerGameDLL, GameInit, g_GameDll.pGameDLL, GameInit_handler, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DLLInit(CreateInterfaceFn engineFactory, CreateInterfaceFn physicsFactory, CreateInterfaceFn filesystemFactory, CGlobalVars *pGlobals)
|
bool StartupMetamod(CreateInterfaceFn engineFactory)
|
||||||
{
|
{
|
||||||
g_Engine.engineFactory = engineFactory;
|
|
||||||
g_Engine.fileSystemFactory = filesystemFactory;
|
|
||||||
g_Engine.physicsFactory = physicsFactory;
|
|
||||||
g_Engine.pGlobals = pGlobals;
|
|
||||||
|
|
||||||
g_Engine.engine = (IVEngineServer *)((engineFactory)(INTERFACEVERSION_VENGINESERVER, NULL));
|
g_Engine.engine = (IVEngineServer *)((engineFactory)(INTERFACEVERSION_VENGINESERVER, NULL));
|
||||||
|
|
||||||
if (!g_Engine.engine)
|
if (!g_Engine.engine)
|
||||||
{
|
{
|
||||||
Error("Could not find IVEngineServer! Metamod cannot load.");
|
Error("Could not find IVEngineServer! Metamod cannot load.");
|
||||||
@ -147,7 +144,6 @@ bool DLLInit(CreateInterfaceFn engineFactory, CreateInterfaceFn physicsFactory,
|
|||||||
|
|
||||||
g_Engine.loaded = true;
|
g_Engine.loaded = true;
|
||||||
|
|
||||||
/* Initialize our console hooks */
|
|
||||||
ConCommandBaseMgr::OneTimeInit(static_cast<IConCommandBaseAccessor *>(&g_SMConVarAccessor));
|
ConCommandBaseMgr::OneTimeInit(static_cast<IConCommandBaseAccessor *>(&g_SMConVarAccessor));
|
||||||
|
|
||||||
g_GameDllPatch = SH_GET_CALLCLASS(g_GameDll.pGameDLL);
|
g_GameDllPatch = SH_GET_CALLCLASS(g_GameDll.pGameDLL);
|
||||||
@ -155,7 +151,9 @@ bool DLLInit(CreateInterfaceFn engineFactory, CreateInterfaceFn physicsFactory,
|
|||||||
if (g_GameDll.pGameClients)
|
if (g_GameDll.pGameClients)
|
||||||
{
|
{
|
||||||
SH_ADD_HOOK_STATICFUNC(IServerGameClients, ClientCommand, g_GameDll.pGameClients, ClientCommand_handler, false);
|
SH_ADD_HOOK_STATICFUNC(IServerGameClients, ClientCommand, g_GameDll.pGameClients, ClientCommand_handler, false);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* If IServerGameClients isn't found, this really isn't a fatal error so... */
|
/* If IServerGameClients isn't found, this really isn't a fatal error so... */
|
||||||
LogMessage("[META] Warning: Could not find IServerGameClients!");
|
LogMessage("[META] Warning: Could not find IServerGameClients!");
|
||||||
LogMessage("[META] Warning: The 'meta' command will not be available to clients.");
|
LogMessage("[META] Warning: The 'meta' command will not be available to clients.");
|
||||||
@ -170,13 +168,13 @@ bool DLLInit(CreateInterfaceFn engineFactory, CreateInterfaceFn physicsFactory,
|
|||||||
if (!g_SmmAPI.CacheUserMessages())
|
if (!g_SmmAPI.CacheUserMessages())
|
||||||
{
|
{
|
||||||
/* Don't know of a mod that has stripped out user messages completely,
|
/* Don't know of a mod that has stripped out user messages completely,
|
||||||
* but perhaps should do something different here?
|
* but perhaps should do something different here?
|
||||||
*/
|
*/
|
||||||
LogMessage("[META] Warning: Failed to get list of user messages.");
|
LogMessage("[META] Warning: Failed to get list of user messages.");
|
||||||
LogMessage("[META] Warning: The 'meta game' command will not display user messages.");
|
LogMessage("[META] Warning: The 'meta game' command will not display user messages.");
|
||||||
}
|
}
|
||||||
|
|
||||||
baseFs = (IBaseFileSystem *)((filesystemFactory)(BASEFILESYSTEM_INTERFACE_VERSION, NULL));
|
baseFs = (IFileSystem *)((engineFactory)(FILESYSTEM_INTERFACE_VERSION, NULL));
|
||||||
if (baseFs == NULL)
|
if (baseFs == NULL)
|
||||||
{
|
{
|
||||||
LogMessage("[META] Failed to find filesystem interface, .vdf files will not be parsed.");
|
LogMessage("[META] Failed to find filesystem interface, .vdf files will not be parsed.");
|
||||||
@ -202,9 +200,90 @@ bool DLLInit(CreateInterfaceFn engineFactory, CreateInterfaceFn physicsFactory,
|
|||||||
|
|
||||||
bInFirstLevel = true;
|
bInFirstLevel = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DLLInit(CreateInterfaceFn engineFactory, CreateInterfaceFn physicsFactory, CreateInterfaceFn filesystemFactory, CGlobalVars *pGlobals)
|
||||||
|
{
|
||||||
|
g_Engine.engineFactory = engineFactory;
|
||||||
|
g_Engine.fileSystemFactory = filesystemFactory;
|
||||||
|
g_Engine.physicsFactory = physicsFactory;
|
||||||
|
g_Engine.pGlobals = pGlobals;
|
||||||
|
|
||||||
|
StartupMetamod(engineFactory);
|
||||||
|
|
||||||
RETURN_META_VALUE(MRES_IGNORED, true);
|
RETURN_META_VALUE(MRES_IGNORED, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AlternatelyLoadMetamod(CreateInterfaceFn ifaceFactory, CreateInterfaceFn serverFactory)
|
||||||
|
{
|
||||||
|
g_Engine.engineFactory = ifaceFactory;
|
||||||
|
g_Engine.fileSystemFactory = ifaceFactory;
|
||||||
|
g_Engine.physicsFactory = ifaceFactory;
|
||||||
|
|
||||||
|
IPlayerInfoManager *playerInfoManager = (IPlayerInfoManager *)serverFactory("PlayerInfoManager002", NULL);
|
||||||
|
if (playerInfoManager == NULL)
|
||||||
|
{
|
||||||
|
Error("Metamod:Source requires gameinfo.txt modification to load on this game.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_Engine.pGlobals = playerInfoManager->GetGlobalVars();
|
||||||
|
|
||||||
|
/* Now find the server */
|
||||||
|
g_GameDll.factory = serverFactory;
|
||||||
|
g_GameDll.lib = NULL;
|
||||||
|
|
||||||
|
char gamedll_iface[] = "ServerGameDLL000";
|
||||||
|
for (unsigned int i = 3; i <= 50; i++)
|
||||||
|
{
|
||||||
|
gamedll_iface[15] = '0' + i;
|
||||||
|
g_GameDll.pGameDLL = (IServerGameDLL *)serverFactory(gamedll_iface, NULL);
|
||||||
|
if (g_GameDll.pGameDLL != NULL)
|
||||||
|
{
|
||||||
|
g_GameDllVersion = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_GameDll.pGameDLL == NULL)
|
||||||
|
{
|
||||||
|
Error("Metamod:Source requires gameinfo.txt modification to load on this game.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
char gameclients_iface[] = "ServerGameClients000";
|
||||||
|
for (unsigned int i = 3; i <= 4; i++)
|
||||||
|
{
|
||||||
|
gameclients_iface[19] = '0' + i;
|
||||||
|
g_GameDll.pGameClients = (IServerGameClients *)serverFactory(gameclients_iface, NULL);
|
||||||
|
if (g_GameDll.pGameClients != NULL)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char smm_path[PATH_SIZE];
|
||||||
|
const char *game_dir;
|
||||||
|
GetFileOfAddress((void *)AlternatelyLoadMetamod, smm_path, sizeof(smm_path));
|
||||||
|
g_SmmPath.assign(smm_path);
|
||||||
|
|
||||||
|
game_dir = CommandLine()->ParmValue("-game", "hl2");
|
||||||
|
abspath(smm_path, game_dir);
|
||||||
|
g_ModPath.assign(smm_path);
|
||||||
|
|
||||||
|
InitMainStates();
|
||||||
|
|
||||||
|
if (!StartupMetamod(ifaceFactory))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_PluginMngr.SetAllLoaded();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool GameInit_handler()
|
bool GameInit_handler()
|
||||||
{
|
{
|
||||||
if (bGameInit)
|
if (bGameInit)
|
||||||
@ -212,7 +291,7 @@ bool GameInit_handler()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_SmmAPI.VSPEnabled())
|
if (g_SmmAPI.VSPEnabled() && !g_VspListener.IsRootLoadMethod())
|
||||||
{
|
{
|
||||||
g_SmmAPI.LoadAsVSP();
|
g_SmmAPI.LoadAsVSP();
|
||||||
}
|
}
|
||||||
@ -234,7 +313,7 @@ SMM_API void *CreateInterface(const char *iface, int *ret)
|
|||||||
/* Prevent loading of self as a SourceMM plugin or Valve server plugin :x */
|
/* Prevent loading of self as a SourceMM plugin or Valve server plugin :x */
|
||||||
if (strcmp(iface, PLAPI_NAME) == 0)
|
if (strcmp(iface, PLAPI_NAME) == 0)
|
||||||
{
|
{
|
||||||
Warning("Do not try loading Metamod:Source as a SourceMM or Valve server plugin.\n");
|
Warning("Do not try loading Metamod:Source as a Metamod:Source plugin");
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
@ -257,6 +336,12 @@ SMM_API void *CreateInterface(const char *iface, int *ret)
|
|||||||
return &g_VspListener;
|
return &g_VspListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we're a VSP, bypass this by default */
|
||||||
|
if (g_VspListener.IsRootLoadMethod())
|
||||||
|
{
|
||||||
|
IFACE_MACRO(g_GameDll.factory, GameDLL);
|
||||||
|
}
|
||||||
|
|
||||||
if (!gParsedGameInfo)
|
if (!gParsedGameInfo)
|
||||||
{
|
{
|
||||||
gParsedGameInfo = true;
|
gParsedGameInfo = true;
|
||||||
@ -490,7 +575,7 @@ void ClearGamedllList()
|
|||||||
gamedll_list.clear();
|
gamedll_list.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DLLShutdown_handler()
|
void UnloadMetamod()
|
||||||
{
|
{
|
||||||
/* Unload plugins */
|
/* Unload plugins */
|
||||||
g_PluginMngr.UnloadAll();
|
g_PluginMngr.UnloadAll();
|
||||||
@ -507,9 +592,15 @@ void DLLShutdown_handler()
|
|||||||
g_SourceHook.CompleteShutdown();
|
g_SourceHook.CompleteShutdown();
|
||||||
|
|
||||||
if (g_GameDll.lib && g_GameDll.loaded)
|
if (g_GameDll.lib && g_GameDll.loaded)
|
||||||
|
{
|
||||||
dlclose(g_GameDll.lib);
|
dlclose(g_GameDll.lib);
|
||||||
|
}
|
||||||
memset(&g_GameDll, 0, sizeof(GameDllInfo));
|
memset(&g_GameDll, 0, sizeof(GameDllInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DLLShutdown_handler()
|
||||||
|
{
|
||||||
|
UnloadMetamod();
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
RETURN_META(MRES_SUPERCEDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -586,7 +677,7 @@ void LookForVDFs(const char *dir)
|
|||||||
if ((hFind = FindFirstFile(path, &fd)) == INVALID_HANDLE_VALUE)
|
if ((hFind = FindFirstFile(path, &fd)) == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
DWORD dw = GetLastError();
|
DWORD dw = GetLastError();
|
||||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
|
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
NULL,
|
NULL,
|
||||||
dw,
|
dw,
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
|
|||||||
@ -87,6 +87,8 @@ struct EngineInfo
|
|||||||
IVEngineServer *engine;
|
IVEngineServer *engine;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool AlternatelyLoadMetamod(CreateInterfaceFn ifaceFactory, CreateInterfaceFn serverFactory);
|
||||||
|
|
||||||
/** @brief Global variable for GameDLL info */
|
/** @brief Global variable for GameDLL info */
|
||||||
extern GameDllInfo g_GameDll;
|
extern GameDllInfo g_GameDll;
|
||||||
|
|
||||||
@ -116,6 +118,8 @@ extern int g_GameDllVersion;
|
|||||||
|
|
||||||
extern bool bGameInit;
|
extern bool bGameInit;
|
||||||
|
|
||||||
|
void UnloadMetamod();
|
||||||
|
|
||||||
/** @brief Global CallClass for IServerGameDLL */
|
/** @brief Global CallClass for IServerGameDLL */
|
||||||
extern SourceHook::CallClass<IServerGameDLL> *g_GameDllPatch;
|
extern SourceHook::CallClass<IServerGameDLL> *g_GameDllPatch;
|
||||||
|
|
||||||
|
|||||||
@ -19,6 +19,7 @@ VSPListener::VSPListener()
|
|||||||
{
|
{
|
||||||
m_Loaded = false;
|
m_Loaded = false;
|
||||||
m_Loadable = false;
|
m_Loadable = false;
|
||||||
|
m_bIsRootLoadMethod = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VSPListener::ClientActive(edict_t *pEntity)
|
void VSPListener::ClientActive(edict_t *pEntity)
|
||||||
@ -92,6 +93,7 @@ void VSPListener::ServerActivate(edict_t *pEdictList, int edictCount, int client
|
|||||||
|
|
||||||
void VSPListener::Unload()
|
void VSPListener::Unload()
|
||||||
{
|
{
|
||||||
|
UnloadMetamod();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VSPListener::SetLoadable(bool set)
|
void VSPListener::SetLoadable(bool set)
|
||||||
@ -99,27 +101,30 @@ void VSPListener::SetLoadable(bool set)
|
|||||||
m_Loadable = set;
|
m_Loadable = set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VSPListener::IsRootLoadMethod()
|
||||||
|
{
|
||||||
|
return m_bIsRootLoadMethod;
|
||||||
|
}
|
||||||
|
|
||||||
bool VSPListener::Load(CreateInterfaceFn interfaceFactory, CreateInterfaceFn gameServerFactory)
|
bool VSPListener::Load(CreateInterfaceFn interfaceFactory, CreateInterfaceFn gameServerFactory)
|
||||||
{
|
{
|
||||||
if (!g_GameDll.loaded)
|
|
||||||
{
|
|
||||||
Error("Metamod:Source is not a Valve Server Plugin\n");
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_Loadable)
|
|
||||||
{
|
|
||||||
Warning("Do not manually load Metamod:Source as a Valve Server Plugin\n");
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_Loaded)
|
if (m_Loaded)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!m_Loadable && !g_GameDll.loaded)
|
||||||
|
{
|
||||||
|
/* New loading mechanism, do a bunch o' stuff! */
|
||||||
|
m_bIsRootLoadMethod = true;
|
||||||
|
m_Loaded = true;
|
||||||
|
SetLoadable(false);
|
||||||
|
if (!AlternatelyLoadMetamod(interfaceFactory, gameServerFactory))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_Loaded = true;
|
m_Loaded = true;
|
||||||
SetLoadable(false);
|
SetLoadable(false);
|
||||||
|
|
||||||
|
|||||||
@ -39,9 +39,11 @@ public:
|
|||||||
public:
|
public:
|
||||||
bool IsLoaded();
|
bool IsLoaded();
|
||||||
void SetLoadable(bool loadable);
|
void SetLoadable(bool loadable);
|
||||||
|
bool IsRootLoadMethod();
|
||||||
private:
|
private:
|
||||||
bool m_Loaded;
|
bool m_Loaded;
|
||||||
bool m_Loadable;
|
bool m_Loadable;
|
||||||
|
bool m_bIsRootLoadMethod;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern VSPListener g_VspListener;
|
extern VSPListener g_VspListener;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user