mirror of
https://github.com/alliedmodders/metamod-source.git
synced 2024-12-01 13:24:25 +01:00
mirrored VDF/VSP fixes from the 1.4.3 branch
--HG-- extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/trunk%40605
This commit is contained in:
parent
50ac19a53b
commit
d58e12d25c
@ -385,6 +385,11 @@ namespace SourceMM
|
||||
* loading plugin should use ISmmAPI::GetVSPInfo() before relying on
|
||||
* this callback.
|
||||
*
|
||||
* This callback is never called if Metamod:Source is in VSP mode.
|
||||
* If in VSP mode, a VSP instance is automatically and always available
|
||||
* via ISmmAPI::GetVSPInfo(), which should be called anyway (to handle
|
||||
* late loading cases).
|
||||
*
|
||||
* @param iface Interface pointer. If NULL, then the VSP
|
||||
* listening construct failed to initialize and
|
||||
* is not available.
|
||||
|
@ -8,6 +8,9 @@
|
||||
instance pointer rather than a callclass pointer.
|
||||
- Metamod:Source has now received a large internal rewrite to improve coding
|
||||
standards and to separate internal logic from engine specifics.
|
||||
- Added ability to load from a VDF file instead of gameinfo.txt.
|
||||
- Added ability to load MM:S plugins from VDF files.
|
||||
- Added mm_basedir cvar to specify Metamod's base folder.
|
||||
- Added API for getting highest supported IServerPluginCallbacks interface
|
||||
version.
|
||||
- Added API for detecting the engine version.
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "console.h"
|
||||
#include "metamod_console.h"
|
||||
#include "vsp_listener.h"
|
||||
#include <filesystem.h>
|
||||
#if defined DEBUG2
|
||||
#undef DEBUG2
|
||||
#define _DEBUG
|
||||
@ -74,6 +75,7 @@ VSPListener g_VspListener;
|
||||
BaseProvider g_Ep1Provider;
|
||||
IMetamodSourceProvider *provider = &g_Ep1Provider;
|
||||
List<ConCommandBase *> conbases_unreg;
|
||||
IFileSystem *baseFs = NULL;
|
||||
ConCommand meta_local_cmd("meta", LocalCommand_Meta, "Metamod:Source control options");
|
||||
|
||||
SH_DECL_HOOK2_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, edict_t *, const CCommand &);
|
||||
@ -106,6 +108,13 @@ void BaseProvider::Notify_DLLInit_Pre(CreateInterfaceFn engineFactory,
|
||||
gameclients = (IServerGameClients *)(serverFactory("ServerGameClients004", NULL));
|
||||
}
|
||||
|
||||
baseFs = (IFileSystem *)((engineFactory)(FILESYSTEM_INTERFACE_VERSION, NULL));
|
||||
if (baseFs == NULL)
|
||||
{
|
||||
::LogMessage("Unable to find \"%s\": .vdf files will not be parsed", FILESYSTEM_INTERFACE_VERSION);
|
||||
return;
|
||||
}
|
||||
|
||||
RegisterConCommandBase(&meta_local_cmd);
|
||||
conbases_unreg.push_back(&meta_local_cmd);
|
||||
|
||||
@ -154,6 +163,11 @@ const char *BaseProvider::GetConVarString(ConVar *convar)
|
||||
return convar->GetString();
|
||||
}
|
||||
|
||||
void BaseProvider::SetConVarString(ConVar *convar, const char *str)
|
||||
{
|
||||
convar->SetValue(str);
|
||||
}
|
||||
|
||||
bool BaseProvider::IsConCommandBaseACommand(ConCommandBase *pCommand)
|
||||
{
|
||||
return pCommand->IsCommand();
|
||||
@ -367,6 +381,68 @@ bool BaseProvider::IsAlternatelyLoaded()
|
||||
return g_VspListener.IsRootLoadMethod();
|
||||
}
|
||||
|
||||
bool BaseProvider::ProcessVDF(const char *file, char path[], size_t path_len, char alias[], size_t alias_len)
|
||||
{
|
||||
if (baseFs == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
KeyValues *pValues;
|
||||
const char *plugin_file, *p_alias;
|
||||
|
||||
pValues = new KeyValues("Metamod Plugin");
|
||||
|
||||
if (!pValues->LoadFromFile(baseFs, file))
|
||||
{
|
||||
pValues->deleteThis();
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((plugin_file = pValues->GetString("file", NULL)) == NULL)
|
||||
{
|
||||
pValues->deleteThis();
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((p_alias = pValues->GetString("alias", NULL)) != NULL)
|
||||
{
|
||||
UTIL_Format(alias, alias_len, "%s", p_alias);
|
||||
}
|
||||
else
|
||||
{
|
||||
UTIL_Format(alias, alias_len, "");
|
||||
}
|
||||
|
||||
/* Attempt to find a file extension */
|
||||
if (UTIL_GetExtension(plugin_file) == NULL)
|
||||
{
|
||||
g_pMetamod->PathFormat(path,
|
||||
path_len,
|
||||
"%s/%s%s",
|
||||
g_pMetamod->GetBaseDir(),
|
||||
plugin_file,
|
||||
#if defined WIN32 || defined _WIN32
|
||||
".dll"
|
||||
#else
|
||||
"_i486.so"
|
||||
#endif
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pMetamod->PathFormat(path,
|
||||
path_len,
|
||||
"%s/%s",
|
||||
g_pMetamod->GetBaseDir(),
|
||||
plugin_file);
|
||||
}
|
||||
|
||||
pValues->deleteThis();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
class GlobCommand : public IMetamodSourceCommandInfo
|
||||
{
|
||||
public:
|
||||
|
@ -68,6 +68,7 @@ public:
|
||||
const char *help,
|
||||
int flags);
|
||||
virtual const char *GetConVarString(ConVar *convar);
|
||||
virtual void SetConVarString(ConVar *convar, const char *str);
|
||||
virtual const char *GetGameDescription();
|
||||
virtual IConCommandBaseAccessor *GetConCommandBaseAccessor();
|
||||
virtual bool RegisterConCommandBase(ConCommandBase *pCommand);
|
||||
@ -78,6 +79,7 @@ public:
|
||||
virtual const char *GetUserMessage(int index, int *size=NULL);
|
||||
virtual int DetermineSourceEngine(const char *game);
|
||||
virtual bool IsAlternatelyLoaded();
|
||||
virtual bool ProcessVDF(const char *file, char path[], size_t path_len, char alias[], size_t alias_len);
|
||||
};
|
||||
|
||||
extern IVEngineServer *engine;
|
||||
|
@ -218,6 +218,7 @@ bool VSPListener::Load(CreateInterfaceFn interfaceFactory, CreateInterfaceFn gam
|
||||
|
||||
InitializeForLoad();
|
||||
InitializeGlobals(interfaceFactory, interfaceFactory, interfaceFactory, pGlobals);
|
||||
StartupMetamod(true);
|
||||
|
||||
const ConCommandBase *pBase = icvar->GetCommands();
|
||||
while (pBase != NULL)
|
||||
@ -240,7 +241,10 @@ bool VSPListener::Load(CreateInterfaceFn interfaceFactory, CreateInterfaceFn gam
|
||||
m_bLoaded = true;
|
||||
SetLoadable(false);
|
||||
|
||||
if (!m_bIsRootLoadMethod)
|
||||
{
|
||||
g_Metamod.NotifyVSPListening(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -64,6 +64,7 @@ void Handler_LevelShutdown();
|
||||
bool Handler_LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background);
|
||||
bool Handler_GameInit();
|
||||
void InitializeVSP();
|
||||
void LookForVDFs(const char *dir);
|
||||
|
||||
struct game_dll_t
|
||||
{
|
||||
@ -88,6 +89,7 @@ bool vsp_loaded = false;
|
||||
game_dll_t gamedll_info;
|
||||
ConVar *metamod_version = NULL;
|
||||
ConVar *mm_pluginsfile = NULL;
|
||||
ConVar *mm_basedir = NULL;
|
||||
IServerGameDLL *server = NULL;
|
||||
CreateInterfaceFn engine_factory = NULL;
|
||||
CreateInterfaceFn physics_factory = NULL;
|
||||
@ -102,6 +104,7 @@ IServerPluginCallbacks *vsp_callbacks = NULL;
|
||||
bool were_plugins_loaded = false;
|
||||
|
||||
MetamodSource g_Metamod;
|
||||
SourceMM::ISmmAPI *g_pMetamod = &g_Metamod;
|
||||
|
||||
void ClearGamedllList();
|
||||
|
||||
@ -699,6 +702,7 @@ void LogMessage(const char *msg, ...)
|
||||
void DoInitialPluginLoads()
|
||||
{
|
||||
const char *pluginFile = provider->GetCommandLineValue("mm_pluginsfile", NULL);
|
||||
const char *mmBaseDir = provider->GetCommandLineValue("mm_basedir", NULL);
|
||||
if (!pluginFile)
|
||||
{
|
||||
pluginFile = provider->GetConVarString(mm_pluginsfile);
|
||||
@ -707,20 +711,41 @@ void DoInitialPluginLoads()
|
||||
pluginFile = "addons/metamod/metaplugins.ini";
|
||||
}
|
||||
}
|
||||
|
||||
char full_path[260];
|
||||
g_Metamod.PathFormat(full_path, sizeof(full_path), "%s/%s", mod_path.c_str(), pluginFile);
|
||||
|
||||
LoadPluginsFromFile(full_path);
|
||||
if (!mmBaseDir)
|
||||
{
|
||||
mmBaseDir = provider->GetConVarString(mm_basedir);
|
||||
if (mmBaseDir == NULL)
|
||||
{
|
||||
mmBaseDir = "addons/metamod";
|
||||
}
|
||||
}
|
||||
|
||||
void StartupMetamod(bool bWaitForGameInit)
|
||||
char full_path[260];
|
||||
|
||||
g_Metamod.PathFormat(full_path, sizeof(full_path), "%s/%s", mod_path.c_str(), pluginFile);
|
||||
LoadPluginsFromFile(full_path);
|
||||
|
||||
g_Metamod.PathFormat(full_path, sizeof(full_path), "%s/%s", mod_path.c_str(), mmBaseDir);
|
||||
LookForVDFs(full_path);
|
||||
}
|
||||
|
||||
void StartupMetamod(bool is_vsp_load)
|
||||
{
|
||||
char buffer[255];
|
||||
|
||||
UTIL_Format(buffer,
|
||||
sizeof(buffer),
|
||||
"%s%s",
|
||||
SOURCEMM_VERSION,
|
||||
is_vsp_load ? "V" : "");
|
||||
|
||||
metamod_version = provider->CreateConVar("metamod_version",
|
||||
SOURCEMM_VERSION,
|
||||
"Metamod:Source Version",
|
||||
ConVarFlag_Notify|ConVarFlag_Replicated|ConVarFlag_SpOnly);
|
||||
|
||||
provider->SetConVarString(metamod_version, buffer);
|
||||
|
||||
mm_pluginsfile = provider->CreateConVar("mm_pluginsfile",
|
||||
#if defined WIN32 || defined _WIN32
|
||||
"addons\\metamod\\metaplugins.ini",
|
||||
@ -730,7 +755,16 @@ void StartupMetamod(bool bWaitForGameInit)
|
||||
"Metamod:Source Plugins File",
|
||||
ConVarFlag_SpOnly);
|
||||
|
||||
if (!bWaitForGameInit)
|
||||
mm_basedir = provider->CreateConVar("mm_basedir",
|
||||
#if defined __linux__
|
||||
"addons/metamod",
|
||||
#else
|
||||
"addons\\metamod",
|
||||
#endif
|
||||
"Metamod:Source Base Folder",
|
||||
ConVarFlag_SpOnly);
|
||||
|
||||
if (!is_vsp_load)
|
||||
{
|
||||
DoInitialPluginLoads();
|
||||
in_first_level = true;
|
||||
@ -827,13 +861,20 @@ void Handler_LevelShutdown(void)
|
||||
if (!in_first_level)
|
||||
{
|
||||
char full_path[255];
|
||||
|
||||
g_Metamod.PathFormat(full_path,
|
||||
sizeof(full_path),
|
||||
"%s/%s",
|
||||
mod_path.c_str(),
|
||||
provider->GetConVarString(mm_pluginsfile));
|
||||
|
||||
LoadPluginsFromFile(full_path);
|
||||
|
||||
g_Metamod.PathFormat(full_path,
|
||||
sizeof(full_path),
|
||||
"%s/%s",
|
||||
mod_path.c_str(),
|
||||
provider->GetConVarString(mm_basedir));
|
||||
LookForVDFs(full_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1347,3 +1388,95 @@ bool MetamodSource::IsAlternateLoadComplete()
|
||||
{
|
||||
return were_plugins_loaded;
|
||||
}
|
||||
|
||||
void ProcessVDF(const char *path)
|
||||
{
|
||||
PluginId id;
|
||||
bool already;
|
||||
char alias[24], file[255], error[255];
|
||||
|
||||
if (!provider->ProcessVDF(path, file, sizeof(file), alias, sizeof(alias)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (alias[0] != '\0')
|
||||
{
|
||||
g_PluginMngr.SetAlias(alias, file);
|
||||
}
|
||||
|
||||
id = g_PluginMngr.Load(file, Pl_File, already, error, sizeof(error));
|
||||
if (id < Pl_MinId || g_PluginMngr.FindById(id)->m_Status < Pl_Paused)
|
||||
{
|
||||
LogMessage("[META] Failed to load plugin %s: %s", file, error);
|
||||
}
|
||||
}
|
||||
|
||||
void LookForVDFs(const char *dir)
|
||||
{
|
||||
char path[MAX_PATH];
|
||||
|
||||
#if defined _MSC_VER
|
||||
HANDLE hFind;
|
||||
WIN32_FIND_DATA fd;
|
||||
char error[255];
|
||||
|
||||
g_Metamod.PathFormat(path, sizeof(path), "%s\\*.*", dir);
|
||||
if ((hFind = FindFirstFile(path, &fd)) == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
DWORD dw = GetLastError();
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
dw,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
error,
|
||||
sizeof(error),
|
||||
NULL);
|
||||
LogMessage("[META] Could not open folder \"%s\" (%s)", dir, error);
|
||||
return;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if (strcmp(fd.cFileName, ".") == 0
|
||||
|| strcmp(fd.cFileName, "..") == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (strstr(fd.cFileName, ".vdf") == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
g_Metamod.PathFormat(path, sizeof(path), "%s\\%s", dir, fd.cFileName);
|
||||
ProcessVDF(path);
|
||||
} while (FindNextFile(hFind, &fd));
|
||||
|
||||
FindClose(hFind);
|
||||
#else
|
||||
DIR *pDir;
|
||||
struct dirent *pEnt;
|
||||
|
||||
if ((pDir = opendir(dir)) == NULL)
|
||||
{
|
||||
LogMessage("[META] Could not open folder \"%s\" (%s)", dir, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
while ((pEnt = readdir(pDir)) != NULL)
|
||||
{
|
||||
if (strcmp(pEnt->d_name, ".") == 0
|
||||
|| strcmp(pEnt->d_name, "..") == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (strstr(pEnt->d_name, ".vdf") == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
g_SmmAPI.PathFormat(path, sizeof(path), "%s/%s", dir, pEnt->d_name);
|
||||
ProcessVDF(path);
|
||||
}
|
||||
|
||||
closedir(pDir);
|
||||
#endif
|
||||
}
|
||||
|
@ -110,6 +110,7 @@ void InitializeGlobals(CreateInterfaceFn engineFactory,
|
||||
CreateInterfaceFn physicsFactory,
|
||||
CreateInterfaceFn filesystemFactory,
|
||||
CGlobalVars *pGlobals);
|
||||
void StartupMetamod(bool is_vsp_load);
|
||||
void UnloadMetamod();
|
||||
|
||||
extern MetamodSource g_Metamod;
|
||||
|
@ -219,6 +219,14 @@ namespace SourceMM
|
||||
*/
|
||||
virtual const char *GetConVarString(ConVar *convar) =0;
|
||||
|
||||
/**
|
||||
* @brief Sets a ConVar string.
|
||||
*
|
||||
* @param convar ConVar pointer.
|
||||
* @param str String pointer.
|
||||
*/
|
||||
virtual void SetConVarString(ConVar *convar, const char *str) =0;
|
||||
|
||||
/**
|
||||
* @brief Retrieves the game description.
|
||||
*
|
||||
@ -297,12 +305,19 @@ namespace SourceMM
|
||||
* @return True if loaded, false otherwise.
|
||||
*/
|
||||
virtual bool IsAlternatelyLoaded() =0;
|
||||
|
||||
/**
|
||||
* @brief Processes a VDF plugin file.
|
||||
*
|
||||
*/
|
||||
virtual bool ProcessVDF(const char *file, char path[], size_t path_len, char alias[], size_t alias_len) =0;
|
||||
};
|
||||
};
|
||||
|
||||
extern PluginId g_PLID;
|
||||
extern SourceHook::ISourceHook *g_SHPtr;
|
||||
extern SourceMM::IMetamodSourceProvider *provider;
|
||||
extern SourceMM::ISmmAPI *g_pMetamod;
|
||||
|
||||
#endif //_INCLUDE_METAMOD_SOURCE_SUPPORT_H_
|
||||
|
||||
|
@ -95,4 +95,6 @@ bool UTIL_Relatize(char buffer[],
|
||||
const char *relTo,
|
||||
const char *relFrom);
|
||||
|
||||
void LogMessage(const char *msg, ...);
|
||||
|
||||
#endif //_INCLUDE_UTIL_H
|
||||
|
Loading…
Reference in New Issue
Block a user