1
0
mirror of https://github.com/alliedmodders/metamod-source.git synced 2025-02-26 19:54:14 +01: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:
David Anderson 2007-11-29 00:13:08 +00:00
parent 09b4abab9c
commit 41d6c2c37e
5 changed files with 133 additions and 31 deletions

View File

@ -487,7 +487,7 @@ void CSmmAPI::LoadAsVSP()
void CSmmAPI::EnableVSPListener()
{
/* 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();
}

View File

@ -19,6 +19,7 @@
#include "CPlugin.h"
#include "util.h"
#include "vsp_listener.h"
#include "iplayerinfo.h"
#include <filesystem.h>
using namespace SourceMM;
@ -63,7 +64,7 @@ int g_GameDllVersion = 0;
const char VSPIFACE_001[] = "ISERVERPLUGINCALLBACKS001";
const char VSPIFACE_002[] = "ISERVERPLUGINCALLBACKS002";
const char GAMEINFO_PATH[] = "|gameinfo_path|";
IBaseFileSystem *baseFs = NULL;
IFileSystem *baseFs = NULL;
void ClearGamedllList();
@ -125,14 +126,10 @@ void InitMainStates()
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));
if (!g_Engine.engine)
{
Error("Could not find IVEngineServer! Metamod cannot load.");
@ -147,7 +144,6 @@ bool DLLInit(CreateInterfaceFn engineFactory, CreateInterfaceFn physicsFactory,
g_Engine.loaded = true;
/* Initialize our console hooks */
ConCommandBaseMgr::OneTimeInit(static_cast<IConCommandBaseAccessor *>(&g_SMConVarAccessor));
g_GameDllPatch = SH_GET_CALLCLASS(g_GameDll.pGameDLL);
@ -155,7 +151,9 @@ bool DLLInit(CreateInterfaceFn engineFactory, CreateInterfaceFn physicsFactory,
if (g_GameDll.pGameClients)
{
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... */
LogMessage("[META] Warning: Could not find IServerGameClients!");
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())
{
/* 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: 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)
{
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;
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);
}
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()
{
if (bGameInit)
@ -212,7 +291,7 @@ bool GameInit_handler()
return true;
}
if (g_SmmAPI.VSPEnabled())
if (g_SmmAPI.VSPEnabled() && !g_VspListener.IsRootLoadMethod())
{
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 */
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)
{
@ -257,6 +336,12 @@ SMM_API void *CreateInterface(const char *iface, int *ret)
return &g_VspListener;
}
/* If we're a VSP, bypass this by default */
if (g_VspListener.IsRootLoadMethod())
{
IFACE_MACRO(g_GameDll.factory, GameDLL);
}
if (!gParsedGameInfo)
{
gParsedGameInfo = true;
@ -490,7 +575,7 @@ void ClearGamedllList()
gamedll_list.clear();
}
void DLLShutdown_handler()
void UnloadMetamod()
{
/* Unload plugins */
g_PluginMngr.UnloadAll();
@ -507,9 +592,15 @@ void DLLShutdown_handler()
g_SourceHook.CompleteShutdown();
if (g_GameDll.lib && g_GameDll.loaded)
{
dlclose(g_GameDll.lib);
}
memset(&g_GameDll, 0, sizeof(GameDllInfo));
}
void DLLShutdown_handler()
{
UnloadMetamod();
RETURN_META(MRES_SUPERCEDE);
}
@ -586,7 +677,7 @@ void LookForVDFs(const char *dir)
if ((hFind = FindFirstFile(path, &fd)) == INVALID_HANDLE_VALUE)
{
DWORD dw = GetLastError();
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),

View File

@ -87,6 +87,8 @@ struct EngineInfo
IVEngineServer *engine;
};
bool AlternatelyLoadMetamod(CreateInterfaceFn ifaceFactory, CreateInterfaceFn serverFactory);
/** @brief Global variable for GameDLL info */
extern GameDllInfo g_GameDll;
@ -116,6 +118,8 @@ extern int g_GameDllVersion;
extern bool bGameInit;
void UnloadMetamod();
/** @brief Global CallClass for IServerGameDLL */
extern SourceHook::CallClass<IServerGameDLL> *g_GameDllPatch;

View File

@ -19,6 +19,7 @@ VSPListener::VSPListener()
{
m_Loaded = false;
m_Loadable = false;
m_bIsRootLoadMethod = false;
}
void VSPListener::ClientActive(edict_t *pEntity)
@ -92,6 +93,7 @@ void VSPListener::ServerActivate(edict_t *pEdictList, int edictCount, int client
void VSPListener::Unload()
{
UnloadMetamod();
}
void VSPListener::SetLoadable(bool set)
@ -99,27 +101,30 @@ void VSPListener::SetLoadable(bool set)
m_Loadable = set;
}
bool VSPListener::IsRootLoadMethod()
{
return m_bIsRootLoadMethod;
}
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)
{
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;
SetLoadable(false);

View File

@ -39,9 +39,11 @@ public:
public:
bool IsLoaded();
void SetLoadable(bool loadable);
bool IsRootLoadMethod();
private:
bool m_Loaded;
bool m_Loadable;
bool m_bIsRootLoadMethod;
};
extern VSPListener g_VspListener;