added the loading changes from the 1.4.3 branch. they're a bit different here but the theory is the same

--HG--
extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/trunk%40595
This commit is contained in:
David Anderson 2007-12-14 04:32:47 +00:00
parent 59bd50c69d
commit a9c61692e8
13 changed files with 295 additions and 64 deletions

View File

@ -14,6 +14,8 @@
- Added API for getting the VSP-simulation interface upon late loading. - Added API for getting the VSP-simulation interface upon late loading.
- Added OnUnlinkConCommandBase to IMetamodListner to notify when Metamod:Source - Added OnUnlinkConCommandBase to IMetamodListner to notify when Metamod:Source
is about to remove a concommand or convar. is about to remove a concommand or convar.
- Added the ability for Metamod:Source to load as a VSP instead of through
gameinfo.txt.
- The output of the "meta list" command has been reformatted in order to allow - The output of the "meta list" command has been reformatted in order to allow
more space for plugins' name, version, and author fields. more space for plugins' name, version, and author fields.

View File

@ -63,7 +63,7 @@
/> />
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="$(HL2SDKOB)\lib\public\tier0.lib $(HL2SDKOB)\lib\public\tier1.lib $(HL2SDKOB)\lib\public\tier2.lib $(HL2SDKOB)\lib\public\vstdlib.lib" AdditionalDependencies="&quot;$(HL2SDKOB)\lib\public\tier0.lib&quot; &quot;$(HL2SDKOB)\lib\public\tier1.lib&quot; &quot;$(HL2SDKOB)\lib\public\tier2.lib&quot; &quot;$(HL2SDKOB)\lib\public\vstdlib.lib&quot;"
OutputFile="$(OutDir)/server.dll" OutputFile="$(OutDir)/server.dll"
LinkIncremental="2" LinkIncremental="2"
IgnoreDefaultLibraryNames="libc.lib;libcd.lib;libcmt.lib" IgnoreDefaultLibraryNames="libc.lib;libcd.lib;libcmt.lib"
@ -150,7 +150,7 @@
/> />
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="$(HL2SDKOB)\lib\public\tier0.lib $(HL2SDKOB)\lib\public\tier1.lib $(HL2SDKOB)\lib\public\tier2.lib $(HL2SDKOB)\lib\public\vstdlib.lib" AdditionalDependencies="&quot;$(HL2SDKOB)\lib\public\tier0.lib&quot; &quot;$(HL2SDKOB)\lib\public\tier1.lib&quot; &quot;$(HL2SDKOB)\lib\public\tier2.lib&quot; &quot;$(HL2SDKOB)\lib\public\vstdlib.lib&quot;"
OutputFile="$(OutDir)/server.dll" OutputFile="$(OutDir)/server.dll"
LinkIncremental="1" LinkIncremental="1"
IgnoreDefaultLibraryNames="libc.lib;libcd.lib;libcmtd.lib" IgnoreDefaultLibraryNames="libc.lib;libcd.lib;libcmtd.lib"

View File

@ -30,6 +30,7 @@
#define DEBUG2 #define DEBUG2
#undef _DEBUG #undef _DEBUG
#endif #endif
#include "../metamod_oslink.h"
#include <sourcehook.h> #include <sourcehook.h>
#include <convar.h> #include <convar.h>
#include <eiface.h> #include <eiface.h>
@ -82,11 +83,9 @@ void BaseProvider::ConsolePrint(const char *str)
ConMsg("%s", str); ConMsg("%s", str);
} }
void BaseProvider::Notify_DLLInit_Pre(void *gamedll, void BaseProvider::Notify_DLLInit_Pre(CreateInterfaceFn engineFactory,
CreateInterfaceFn engineFactory,
CreateInterfaceFn serverFactory) CreateInterfaceFn serverFactory)
{ {
server = (IServerGameDLL *)gamedll;
engine = (IVEngineServer *)((engineFactory)(INTERFACEVERSION_VENGINESERVER, NULL)); engine = (IVEngineServer *)((engineFactory)(INTERFACEVERSION_VENGINESERVER, NULL));
if (!engine) if (!engine)
{ {
@ -363,6 +362,11 @@ IServerPluginCallbacks *BaseProvider::GetVSPCallbacks(const char *iface)
return &g_VspListener; return &g_VspListener;
} }
bool BaseProvider::IsAlternatelyLoaded()
{
return g_VspListener.IsRootLoadMethod();
}
class GlobCommand : public IMetamodSourceCommandInfo class GlobCommand : public IMetamodSourceCommandInfo
{ {
public: public:

View File

@ -60,9 +60,7 @@ public:
virtual void DisplayError(const char *fmt, ...); virtual void DisplayError(const char *fmt, ...);
virtual void DisplayWarning(const char *fmt, ...); virtual void DisplayWarning(const char *fmt, ...);
virtual int TryServerGameDLL(const char *iface); virtual int TryServerGameDLL(const char *iface);
virtual void Notify_DLLInit_Pre(void *gamedll, virtual void Notify_DLLInit_Pre(CreateInterfaceFn engineFactory, CreateInterfaceFn serverFactory);
CreateInterfaceFn engineFactory,
CreateInterfaceFn serverFactory);
void Notify_DLLShutdown_Pre(); void Notify_DLLShutdown_Pre();
virtual void ServerCommand(const char *cmd); virtual void ServerCommand(const char *cmd);
virtual ConVar *CreateConVar(const char *name, virtual ConVar *CreateConVar(const char *name,
@ -79,6 +77,7 @@ public:
virtual int FindUserMessage(const char *name, int *size=NULL); virtual int FindUserMessage(const char *name, int *size=NULL);
virtual const char *GetUserMessage(int index, int *size=NULL); virtual const char *GetUserMessage(int index, int *size=NULL);
virtual int DetermineSourceEngine(const char *game); virtual int DetermineSourceEngine(const char *game);
virtual bool IsAlternatelyLoaded();
}; };
extern IVEngineServer *engine; extern IVEngineServer *engine;

View File

@ -25,16 +25,46 @@
* Version: $Id$ * Version: $Id$
*/ */
#if defined _DEBUG
#define DEBUG2
#undef _DEBUG
#endif
#include "../metamod_oslink.h"
#include <sourcehook.h>
#include <convar.h>
#include <eiface.h>
#include "iplayerinfo.h"
#if defined DEBUG2
#undef DEBUG2
#define _DEBUG
#endif
#include "vsp_listener.h" #include "vsp_listener.h"
#include "svn_version.h" #include "svn_version.h"
#include "metamod.h" #include "metamod.h"
#include "provider_ep2.h"
SH_DECL_HOOK1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &);
using namespace SourceMM; using namespace SourceMM;
ConCommand *g_plugin_unload = NULL;
bool g_bIsTryingToUnload;
void InterceptPluginUnloads(const CCommand &args)
{
g_bIsTryingToUnload = true;
}
void InterceptPluginUnloads_Post(const CCommand &args)
{
g_bIsTryingToUnload = false;
}
VSPListener::VSPListener() VSPListener::VSPListener()
{ {
m_bLoaded = false; m_bLoaded = false;
m_bLoadable = false; m_bLoadable = false;
m_bIsRootLoadMethod = false;
} }
void VSPListener::ClientActive(edict_t *pEntity) void VSPListener::ClientActive(edict_t *pEntity)
@ -108,6 +138,24 @@ void VSPListener::ServerActivate(edict_t *pEdictList, int edictCount, int client
void VSPListener::Unload() void VSPListener::Unload()
{ {
if (g_bIsTryingToUnload)
{
Error("Metamod:Source cannot be unloaded from VSP mode. Use \"meta unload\" to unload specific plugins.\n");
return;
}
if (IsRootLoadMethod())
{
if (g_plugin_unload != NULL)
{
SH_REMOVE_HOOK_STATICFUNC(ConCommand, Dispatch, g_plugin_unload, InterceptPluginUnloads, false);
SH_REMOVE_HOOK_STATICFUNC(ConCommand, Dispatch, g_plugin_unload, InterceptPluginUnloads_Post, true);
g_plugin_unload = NULL;
}
UnloadMetamod();
}
m_bLoaded = false;
m_bLoadable = true;
m_bIsRootLoadMethod = false;
} }
void VSPListener::SetLoadable(bool set) void VSPListener::SetLoadable(bool set)
@ -117,15 +165,76 @@ void VSPListener::SetLoadable(bool set)
bool VSPListener::Load(CreateInterfaceFn interfaceFactory, CreateInterfaceFn gameServerFactory) bool VSPListener::Load(CreateInterfaceFn interfaceFactory, CreateInterfaceFn gameServerFactory)
{ {
if (!m_bLoadable) if (!g_Metamod.IsLoadedAsGameDLL())
{ {
provider->DisplayWarning("Do not manually load Metamod:Source as a Valve Server Plugin\n"); CGlobalVars *pGlobals;
return false; IPlayerInfoManager *playerInfoManager;
}
if (m_bLoaded) playerInfoManager = (IPlayerInfoManager *)gameServerFactory("PlayerInfoManager002", NULL);
{ if (playerInfoManager == NULL)
return false; {
Msg("Metamod:Source requires gameinfo.txt modification to load on this game.\n");
return false;
}
pGlobals = playerInfoManager->GetGlobalVars();
char gamedll_iface[] = "ServerGameDLL000";
for (unsigned int i = 5; i <= 50; i++)
{
gamedll_iface[15] = '0' + i;
if ((server = (IServerGameDLL *)gameServerFactory(gamedll_iface, NULL)) != NULL)
{
g_Metamod.SetGameDLLInfo(gameServerFactory, i);
break;
}
}
if (server == NULL)
{
Msg("Metamod:Source could not load (GameDLL version not compatible).\n");
return false;
}
char gameclients_iface[] = "ServerGameClients000";
for (unsigned int i = 3; i <= 4; i++)
{
gameclients_iface[19] = '0' + i;
if ((gameclients = (IServerGameClients *)gameServerFactory(gameclients_iface, NULL)) == NULL)
{
break;
}
}
if (!DetectGameInformation())
{
Msg("Metamod:Source failed to detect game paths; cannot load.\n");
return false;
}
m_bIsRootLoadMethod = true;
m_bLoaded = true;
SetLoadable(false);
InitializeForLoad();
InitializeGlobals(interfaceFactory, interfaceFactory, interfaceFactory, pGlobals);
const ConCommandBase *pBase = icvar->GetCommands();
while (pBase != NULL)
{
if (pBase->IsCommand() && strcmp(pBase->GetName(), "plugin_unload") == 0)
{
g_plugin_unload = (ConCommand *)pBase;
break;
}
pBase = pBase->GetNext();
}
if (g_plugin_unload != NULL)
{
SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, g_plugin_unload, InterceptPluginUnloads, false);
SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, g_plugin_unload, InterceptPluginUnloads_Post, true);
}
} }
m_bLoaded = true; m_bLoaded = true;
@ -139,3 +248,8 @@ bool VSPListener::Load(CreateInterfaceFn interfaceFactory, CreateInterfaceFn gam
void VSPListener::OnQueryCvarValueFinished(QueryCvarCookie_t iCookie, edict_t *pPlayerEntity, EQueryCvarValueStatus eStatus, const char *pCvarName, const char *pCvarValue ) void VSPListener::OnQueryCvarValueFinished(QueryCvarCookie_t iCookie, edict_t *pPlayerEntity, EQueryCvarValueStatus eStatus, const char *pCvarName, const char *pCvarValue )
{ {
} }
bool VSPListener::IsRootLoadMethod()
{
return m_bIsRootLoadMethod;
}

View File

@ -63,10 +63,12 @@ public:
virtual void OnQueryCvarValueFinished( QueryCvarCookie_t iCookie, edict_t *pPlayerEntity, EQueryCvarValueStatus eStatus, const char *pCvarName, const char *pCvarValue ); virtual void OnQueryCvarValueFinished( QueryCvarCookie_t iCookie, edict_t *pPlayerEntity, EQueryCvarValueStatus eStatus, const char *pCvarName, const char *pCvarValue );
public: public:
bool IsLoaded(); bool IsLoaded();
bool IsRootLoadMethod();
void SetLoadable(bool loadable); void SetLoadable(bool loadable);
private: private:
bool m_bLoaded; bool m_bLoaded;
bool m_bLoadable; bool m_bLoadable;
bool m_bIsRootLoadMethod;
}; };
#endif //_INCLUDE_METAMOD_SOURCE_VSP_LISTENER_H_ #endif //_INCLUDE_METAMOD_SOURCE_VSP_LISTENER_H_

View File

@ -25,6 +25,7 @@
* Version: $Id$ * Version: $Id$
*/ */
#include "metamod_oslink.h"
#if defined _DEBUG #if defined _DEBUG
#define DEBUG2 #define DEBUG2
#undef _DEBUG #undef _DEBUG
@ -36,7 +37,6 @@
#include "metamod_plugins.h" #include "metamod_plugins.h"
#include "metamod_util.h" #include "metamod_util.h"
#include "metamod_console.h" #include "metamod_console.h"
#include "metamod_oslink.h"
#if defined DEBUG2 #if defined DEBUG2
#undef DEBUG2 #undef DEBUG2
#define _DEBUG #define _DEBUG
@ -99,6 +99,7 @@ ISourceHook *g_SHPtr = &g_SourceHook;
PluginId g_PLID = Pl_Console; PluginId g_PLID = Pl_Console;
META_RES last_meta_res; META_RES last_meta_res;
IServerPluginCallbacks *vsp_callbacks = NULL; IServerPluginCallbacks *vsp_callbacks = NULL;
bool were_plugins_loaded = false;
MetamodSource g_Metamod; MetamodSource g_Metamod;
@ -137,7 +138,7 @@ void ClearGamedllList();
} }
/* Initialize everything here */ /* Initialize everything here */
void InitMainStates() void InitializeForLoad()
{ {
char full_path[PATH_SIZE] = {0}; char full_path[PATH_SIZE] = {0};
GetFileOfAddress((void *)gamedll_info.factory, full_path, sizeof(full_path)); GetFileOfAddress((void *)gamedll_info.factory, full_path, sizeof(full_path));
@ -188,6 +189,31 @@ void InitMainStates()
SH_ADD_MANUALHOOK_STATICFUNC(SGD_DLLShutdown, server, Handler_DLLShutdown, false); SH_ADD_MANUALHOOK_STATICFUNC(SGD_DLLShutdown, server, Handler_DLLShutdown, false);
} }
bool DetectGameInformation()
{
char mm_path[PATH_SIZE];
char game_path[PATH_SIZE];
/* Get path to SourceMM DLL */
if (!GetFileOfAddress((void *)InitializeForLoad, mm_path, sizeof(mm_path)))
{
return false;
}
metamod_path.assign(mm_path);
/* Get value of -game from command line, defaulting to hl2 as engine seems to do */
const char *game_dir = provider->GetCommandLineValue("-game", "hl2");
/* Get absolute path */
abspath(game_path, game_dir);
mod_path.assign(game_path);
engine_build = provider->DetermineSourceEngine(game_dir);;
return true;
}
/* This is where the magic happens */ /* This is where the magic happens */
SMM_API void *CreateInterface(const char *iface, int *ret) SMM_API void *CreateInterface(const char *iface, int *ret)
{ {
@ -221,31 +247,22 @@ SMM_API void *CreateInterface(const char *iface, int *ret)
return vsp_callbacks; return vsp_callbacks;
} }
if (provider->IsAlternatelyLoaded())
{
IFACE_MACRO(gamedll_info.factory, GameDLL);
}
if (!parsed_game_info) if (!parsed_game_info)
{ {
parsed_game_info = true; parsed_game_info = true;
const char *game_dir = NULL; const char *game_dir = NULL;
char game_path[PATH_SIZE];
char mm_path[PATH_SIZE];
/* Get path to SourceMM DLL */ if (!DetectGameInformation())
if (!GetFileOfAddress((void *)CreateInterface, mm_path, sizeof(mm_path)))
{ {
provider->DisplayError("GetFileOfAddress() failed! Metamod cannot load.\n"); provider->DisplayError("GetFileOfAddress() failed! Metamod cannot load.\n");
return NULL; return NULL;
} }
metamod_path.assign(mm_path);
/* Get value of -game from command line, defaulting to hl2 as engine seems to do */
game_dir = provider->GetCommandLineValue("-game", "hl2");
engine_build = provider->DetermineSourceEngine(game_dir);;
/* Get absolute path */
abspath(game_path, game_dir);
mod_path.assign(game_path);
char temp_path[PATH_SIZE]; char temp_path[PATH_SIZE];
/* Path to gameinfo.txt */ /* Path to gameinfo.txt */
@ -331,7 +348,7 @@ SMM_API void *CreateInterface(const char *iface, int *ret)
} }
/* If not path to SourceMM... */ /* If not path to SourceMM... */
if (!UTIL_PathCmp(mm_path, temp_path)) if (!UTIL_PathCmp(metamod_path.c_str(), temp_path))
{ {
FILE *temp_fp = fopen(temp_path, "rb"); FILE *temp_fp = fopen(temp_path, "rb");
if (!temp_fp) if (!temp_fp)
@ -413,7 +430,7 @@ SMM_API void *CreateInterface(const char *iface, int *ret)
if (is_gamedll_loaded) if (is_gamedll_loaded)
{ {
ClearGamedllList(); ClearGamedllList();
InitMainStates(); InitializeForLoad();
} }
else else
{ {
@ -603,6 +620,11 @@ int LoadPluginsFromFile(const char *_file)
void InitializeVSP() void InitializeVSP()
{ {
if (provider->IsAlternatelyLoaded())
{
return;
}
size_t len; size_t len;
char engine_file[PATH_SIZE]; char engine_file[PATH_SIZE];
char engine_path[PATH_SIZE]; char engine_path[PATH_SIZE];
@ -675,29 +697,8 @@ void LogMessage(const char *msg, ...)
} }
} }
bool Handler_DLLInit(CreateInterfaceFn engineFactory, CreateInterfaceFn physicsFactory, CreateInterfaceFn filesystemFactory, CGlobalVars *pGlobals) void DoInitialPluginLoads()
{ {
engine_factory = engineFactory;
filesystem_factory = filesystemFactory;
physics_factory = physicsFactory;
gpGlobals = pGlobals;
provider->Notify_DLLInit_Pre(server, engineFactory, gamedll_info.factory);
metamod_version = provider->CreateConVar("metamod_version",
SOURCEMM_VERSION,
"Metamod:Source Version",
ConVarFlag_Notify|ConVarFlag_Replicated|ConVarFlag_SpOnly);
mm_pluginsfile = provider->CreateConVar("mm_pluginsfile",
#if defined WIN32 || defined _WIN32
"addons\\metamod\\metaplugins.ini",
#else
"addons/metamod/metaplugins.ini",
#endif
"Metamod:Source Plugins File",
ConVarFlag_SpOnly);
const char *pluginFile = provider->GetCommandLineValue("mm_pluginsfile", NULL); const char *pluginFile = provider->GetCommandLineValue("mm_pluginsfile", NULL);
if (!pluginFile) if (!pluginFile)
{ {
@ -712,8 +713,47 @@ bool Handler_DLLInit(CreateInterfaceFn engineFactory, CreateInterfaceFn physicsF
g_Metamod.PathFormat(full_path, sizeof(full_path), "%s/%s", mod_path.c_str(), pluginFile); g_Metamod.PathFormat(full_path, sizeof(full_path), "%s/%s", mod_path.c_str(), pluginFile);
LoadPluginsFromFile(full_path); LoadPluginsFromFile(full_path);
}
in_first_level = true; void StartupMetamod(bool bWaitForGameInit)
{
metamod_version = provider->CreateConVar("metamod_version",
SOURCEMM_VERSION,
"Metamod:Source Version",
ConVarFlag_Notify|ConVarFlag_Replicated|ConVarFlag_SpOnly);
mm_pluginsfile = provider->CreateConVar("mm_pluginsfile",
#if defined WIN32 || defined _WIN32
"addons\\metamod\\metaplugins.ini",
#else
"addons/metamod/metaplugins.ini",
#endif
"Metamod:Source Plugins File",
ConVarFlag_SpOnly);
if (!bWaitForGameInit)
{
DoInitialPluginLoads();
in_first_level = true;
}
}
void InitializeGlobals(CreateInterfaceFn engineFactory,
CreateInterfaceFn physicsFactory,
CreateInterfaceFn filesystemFactory,
CGlobalVars *pGlobals)
{
engine_factory = engineFactory;
physics_factory = physicsFactory;
filesystem_factory = filesystemFactory;
gpGlobals = pGlobals;
provider->Notify_DLLInit_Pre(engineFactory, gamedll_info.factory);
}
bool Handler_DLLInit(CreateInterfaceFn engineFactory, CreateInterfaceFn physicsFactory, CreateInterfaceFn filesystemFactory, CGlobalVars *pGlobals)
{
InitializeGlobals(engineFactory, physicsFactory, filesystemFactory, pGlobals);
StartupMetamod(false);
RETURN_META_VALUE(MRES_IGNORED, true); RETURN_META_VALUE(MRES_IGNORED, true);
} }
@ -730,6 +770,13 @@ bool Handler_GameInit()
InitializeVSP(); InitializeVSP();
} }
if (provider->IsAlternatelyLoaded() && !were_plugins_loaded)
{
DoInitialPluginLoads();
g_PluginMngr.SetAllLoaded();
were_plugins_loaded = true;
}
is_game_init = true; is_game_init = true;
RETURN_META_VALUE(MRES_IGNORED, true); RETURN_META_VALUE(MRES_IGNORED, true);
@ -741,14 +788,17 @@ bool Handler_DLLInit_Post(CreateInterfaceFn engineFactory, CreateInterfaceFn phy
RETURN_META_VALUE(MRES_IGNORED, true); RETURN_META_VALUE(MRES_IGNORED, true);
} }
void Handler_DLLShutdown() void UnloadMetamod()
{ {
/* Unload plugins */ /* Unload plugins */
g_PluginMngr.UnloadAll(); g_PluginMngr.UnloadAll();
provider->Notify_DLLShutdown_Pre(); provider->Notify_DLLShutdown_Pre();
SH_CALL(server, &IServerGameDLL::DLLShutdown)(); if (is_gamedll_loaded)
{
SH_CALL(server, &IServerGameDLL::DLLShutdown)();
}
g_SourceHook.CompleteShutdown(); g_SourceHook.CompleteShutdown();
@ -757,12 +807,24 @@ void Handler_DLLShutdown()
dlclose(gamedll_info.lib); dlclose(gamedll_info.lib);
is_gamedll_loaded = false; is_gamedll_loaded = false;
} }
}
void Handler_DLLShutdown()
{
UnloadMetamod();
RETURN_META(MRES_SUPERCEDE); RETURN_META(MRES_SUPERCEDE);
} }
void Handler_LevelShutdown(void) void Handler_LevelShutdown(void)
{ {
if (provider->IsAlternatelyLoaded() && !were_plugins_loaded)
{
g_PluginMngr.SetAllLoaded();
DoInitialPluginLoads();
were_plugins_loaded = true;
in_first_level = true;
}
if (!in_first_level) if (!in_first_level)
{ {
char full_path[255]; char full_path[255];
@ -1270,3 +1332,19 @@ size_t MetamodSource::FormatArgs(char *buffer, size_t maxlength, const char *for
{ {
return UTIL_FormatArgs(buffer, maxlength, format, ap); return UTIL_FormatArgs(buffer, maxlength, format, ap);
} }
bool MetamodSource::IsLoadedAsGameDLL()
{
return is_gamedll_loaded;
}
void MetamodSource::SetGameDLLInfo(CreateInterfaceFn serverFactory, int version)
{
gamedll_info.factory = serverFactory;
gamedll_version = version;
}
bool MetamodSource::IsAlternateLoadComplete()
{
return were_plugins_loaded;
}

View File

@ -93,14 +93,24 @@ public:
size_t Format(char *buffer, size_t maxlength, const char *format, ...); size_t Format(char *buffer, size_t maxlength, const char *format, ...);
size_t FormatArgs(char *buffer, size_t maxlength, const char *format, va_list ap); size_t FormatArgs(char *buffer, size_t maxlength, const char *format, va_list ap);
public: public:
bool IsLoadedAsGameDLL();
const char *GetGameBinaryPath(); const char *GetGameBinaryPath();
const char *GetPluginsFile(); const char *GetPluginsFile();
void UnregisterConCommandBase(PluginId id, ConCommandBase *pCommand); void UnregisterConCommandBase(PluginId id, ConCommandBase *pCommand);
void NotifyVSPListening(IServerPluginCallbacks *callbacks); void NotifyVSPListening(IServerPluginCallbacks *callbacks);
void SetGameDLLInfo(CreateInterfaceFn serverFactory, int version);
bool IsAlternateLoadComplete();
}; };
bool DetectGameInformation();
void LogMessage(const char *msg, ...); void LogMessage(const char *msg, ...);
int LoadPluginsFromFile(const char *_file); int LoadPluginsFromFile(const char *_file);
void InitializeForLoad();
void InitializeGlobals(CreateInterfaceFn engineFactory,
CreateInterfaceFn physicsFactory,
CreateInterfaceFn filesystemFactory,
CGlobalVars *pGlobals);
void UnloadMetamod();
extern MetamodSource g_Metamod; extern MetamodSource g_Metamod;
extern SourceHook::Impl::CSourceHookImpl g_SourceHook; extern SourceHook::Impl::CSourceHookImpl g_SourceHook;

View File

@ -25,6 +25,7 @@
* Version: $Id$ * Version: $Id$
*/ */
#include "metamod_oslink.h"
#if defined _DEBUG #if defined _DEBUG
#define DEBUG2 #define DEBUG2
#undef _DEBUG #undef _DEBUG
@ -54,6 +55,12 @@ bool Command_Meta(IMetamodSourceCommandInfo *info)
{ {
unsigned int args = info->GetArgCount(); unsigned int args = info->GetArgCount();
if (provider->IsAlternatelyLoaded() && !g_Metamod.IsAlternateLoadComplete())
{
CONMSG("You must change the map to activate Metamod:Source.\n");
return true;
}
if (args >= 1) if (args >= 1)
{ {
const char *command = info->GetArg(1); const char *command = info->GetArg(1);

View File

@ -76,7 +76,7 @@
#endif #endif
#if defined __linux__ #if defined __linux__
extern int errno; #include <errno.h>
int GetLastError(); int GetLastError();
#endif #endif

View File

@ -25,6 +25,7 @@
* Version: $Id$ * Version: $Id$
*/ */
#include "metamod_oslink.h"
#if defined _DEBUG #if defined _DEBUG
#define DEBUG2 #define DEBUG2
#undef _DEBUG #undef _DEBUG
@ -210,6 +211,11 @@ CPluginManager::CPlugin *CPluginManager::FindById(PluginId id)
void CPluginManager::SetAllLoaded() void CPluginManager::SetAllLoaded()
{ {
if (m_AllLoaded)
{
return;
}
m_AllLoaded = true; m_AllLoaded = true;
PluginIter i; PluginIter i;

View File

@ -186,9 +186,7 @@ namespace SourceMM
/** /**
* @brief Notifies the provider that the DLLInit pre-hook is almost done. * @brief Notifies the provider that the DLLInit pre-hook is almost done.
*/ */
virtual void Notify_DLLInit_Pre(void *gamedll, virtual void Notify_DLLInit_Pre(CreateInterfaceFn engineFactory, CreateInterfaceFn serverFactory) =0;
CreateInterfaceFn engineFactory,
CreateInterfaceFn serverFactory) =0;
virtual void Notify_DLLShutdown_Pre() =0; virtual void Notify_DLLShutdown_Pre() =0;
@ -291,6 +289,14 @@ namespace SourceMM
* @return SOURCE_ENGINE constant. * @return SOURCE_ENGINE constant.
*/ */
virtual int DetermineSourceEngine(const char *game) =0; virtual int DetermineSourceEngine(const char *game) =0;
/**
* @brief Returns if the provider has loaded itself through an
* alternate means (that is, not through gameinfo.txt.
*
* @return True if loaded, false otherwise.
*/
virtual bool IsAlternatelyLoaded() =0;
}; };
}; };

View File

@ -221,7 +221,10 @@ bool UTIL_PathCmp(const char *path1, const char *path2)
} }
/* If we're at a different non-alphanumeric, the next character MUST match */ /* If we're at a different non-alphanumeric, the next character MUST match */
if (!isalpha(path1[pos1]) && (path1[pos1] != path2[pos2])) if ((((unsigned)path1[pos1] & 0x80) && path1[pos1] != path2[pos2])
||
!isalpha(path1[pos1]) && (path1[pos1] != path2[pos2])
)
{ {
return false; return false;
} }