diff --git a/sourcemm/concommands.cpp b/sourcemm/concommands.cpp
index 4a3344f..b79f128 100644
--- a/sourcemm/concommands.cpp
+++ b/sourcemm/concommands.cpp
@@ -118,8 +118,10 @@ void SMConVarAccessor::UnregisterGameDLLCommands()
ConVar metamod_version("metamod_version", SOURCEMM_VERSION, FCVAR_REPLICATED | FCVAR_SPONLY | FCVAR_NOTIFY, "Metamod:Source Version");
#if defined WIN32 || defined _WIN32
ConVar mm_pluginsfile("mm_pluginsfile", "addons\\metamod\\metaplugins.ini", FCVAR_SPONLY, "Metamod:Source Plugins File");
+ConVar mm_basedir("mm_basedir", "addons\\metamod", FCVAR_SPONLY, "Metamod:Source base folder");
#else
ConVar mm_pluginsfile("mm_pluginsfile", "addons/metamod/metaplugins.ini", FCVAR_SPONLY, "Metamod:Source Plugins File");
+ConVar mm_basedir("mm_basedir", "addons/metamod", FCVAR_SPONLY, "Metamod:Source base folder");
#endif
CON_COMMAND(meta, "Metamod:Source Menu")
@@ -762,3 +764,8 @@ const char *GetPluginsFile()
{
return mm_pluginsfile.GetString();
}
+
+const char *GetMetamodBaseDir()
+{
+ return mm_basedir.GetString();
+}
diff --git a/sourcemm/concommands.h b/sourcemm/concommands.h
index 56ca953..99640f5 100644
--- a/sourcemm/concommands.h
+++ b/sourcemm/concommands.h
@@ -47,6 +47,7 @@ public:
void ClientCommand_handler(edict_t *client);
const char *GetPluginsFile();
+const char *GetMetamodBaseDir();
extern SMConVarAccessor g_SMConVarAccessor;
diff --git a/sourcemm/msvc8/sourcemm.vcproj b/sourcemm/msvc8/sourcemm.vcproj
index 615c8d1..aa5015f 100644
--- a/sourcemm/msvc8/sourcemm.vcproj
+++ b/sourcemm/msvc8/sourcemm.vcproj
@@ -41,6 +41,7 @@
+
+
diff --git a/sourcemm/sourcemm.cpp b/sourcemm/sourcemm.cpp
index 664e527..61311af 100644
--- a/sourcemm/sourcemm.cpp
+++ b/sourcemm/sourcemm.cpp
@@ -19,6 +19,7 @@
#include "CPlugin.h"
#include "util.h"
#include "vsp_listener.h"
+#include
using namespace SourceMM;
@@ -43,6 +44,7 @@ void DLLShutdown_handler();
void LevelShutdown_handler();
bool LevelInit_handler(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background);
bool GameInit_handler();
+void LookForVDFs(const char *dir);
GameDllInfo g_GameDll = {false, NULL, NULL, NULL, NULL};
EngineInfo g_Engine;
@@ -61,6 +63,8 @@ int g_GameDllVersion = 0;
const char VSPIFACE_001[] = "ISERVERPLUGINCALLBACKS001";
const char VSPIFACE_002[] = "ISERVERPLUGINCALLBACKS002";
const char GAMEINFO_PATH[] = "|gameinfo_path|";
+IBaseFileSystem *baseFs = NULL;
+
void ClearGamedllList();
@@ -172,16 +176,29 @@ bool DLLInit(CreateInterfaceFn engineFactory, CreateInterfaceFn physicsFactory,
LogMessage("[META] Warning: The 'meta game' command will not display user messages.");
}
+ baseFs = (IBaseFileSystem *)((filesystemFactory)(BASEFILESYSTEM_INTERFACE_VERSION, NULL));
+ if (baseFs == NULL)
+ {
+ LogMessage("[META] Failed to find filesystem interface, .vdf files will not be parsed.");
+ }
+
const char *pluginFile = g_Engine.icvar->GetCommandLineValue("mm_pluginsfile");
+ const char *mmBaseDir = g_Engine.icvar->GetCommandLineValue("mm_basedir");
if (!pluginFile)
{
pluginFile = GetPluginsFile();
}
+ if (!mmBaseDir)
+ {
+ mmBaseDir = GetMetamodBaseDir();
+ }
char full_path[260];
- g_SmmAPI.PathFormat(full_path, sizeof(full_path), "%s/%s", g_ModPath.c_str(), pluginFile);
+ g_SmmAPI.PathFormat(full_path, sizeof(full_path), "%s/%s", g_ModPath.c_str(), pluginFile);
LoadPluginsFromFile(full_path);
+ g_SmmAPI.PathFormat(full_path, sizeof(full_path), "%s/%s", g_ModPath.c_str(), mmBaseDir);
+ LookForVDFs(full_path);
bInFirstLevel = true;
@@ -496,6 +513,136 @@ void DLLShutdown_handler()
RETURN_META(MRES_SUPERCEDE);
}
+void LoadFromVDF(const char *file)
+{
+ PluginId id;
+ bool already;
+ KeyValues *pValues;
+ const char *plugin_file, *alias;
+ char full_path[256], error[256];
+
+ pValues = new KeyValues("Metamod Plugin");
+
+ if (!pValues->LoadFromFile(baseFs, file))
+ {
+ pValues->deleteThis();
+ return;
+ }
+
+ if ((plugin_file = pValues->GetString("file", NULL)) == NULL)
+ {
+ pValues->deleteThis();
+ return;
+ }
+
+ if ((alias = pValues->GetString("alias", NULL)) != NULL)
+ {
+ g_PluginMngr.SetAlias(alias, plugin_file);
+ }
+
+ /* Attempt to find a file extension */
+ if (UTIL_GetExtension(plugin_file) == NULL)
+ {
+ g_SmmAPI.PathFormat(full_path,
+ sizeof(full_path),
+ "%s/%s%s",
+ g_ModPath.c_str(),
+ plugin_file,
+#if defined WIN32 || defined _WIN32
+ ".dll"
+#else
+ "_i486.so"
+#endif
+ );
+ }
+ else
+ {
+ g_SmmAPI.PathFormat(full_path,
+ sizeof(full_path),
+ "%s/%s",
+ g_ModPath.c_str(),
+ plugin_file);
+ }
+
+ id = g_PluginMngr.Load(full_path, 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", plugin_file, error);
+ }
+
+ pValues->deleteThis();
+}
+
+void LookForVDFs(const char *dir)
+{
+ char path[MAX_PATH];
+
+#if defined _MSC_VER
+ HANDLE hFind;
+ WIN32_FIND_DATA fd;
+ char error[255];
+
+ g_SmmAPI.PathFormat(path, sizeof(path), "%s\\*.*", dir);
+ if ((hFind = FindFirstFile(path, &fd)) == INVALID_HANDLE_VALUE)
+ {
+ DWORD dw = GetLastError();
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
+ 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_SmmAPI.PathFormat(path, sizeof(path), "%s\\%s", dir, fd.cFileName);
+ LoadFromVDF(path);
+ } while (FindNextFile(hFind, &fd));
+
+ FindClose(hFind);
+#else
+ DIR *pDir;
+ char error[255];
+ 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);
+ LoadFromVDF(path);
+ }
+
+ closedir(pDir);
+#endif
+}
+
int LoadPluginsFromFile(const char *_file)
{
FILE *fp;
@@ -671,10 +818,15 @@ void LevelShutdown_handler(void)
if (!bInFirstLevel)
{
char full_path[255];
- g_SmmAPI.PathFormat(full_path, sizeof(full_path), "%s/%s", g_ModPath.c_str(), GetPluginsFile());
+ g_SmmAPI.PathFormat(full_path, sizeof(full_path), "%s/%s", g_ModPath.c_str(), GetPluginsFile());
LoadPluginsFromFile(full_path);
- } else {
+
+ g_SmmAPI.PathFormat(full_path, sizeof(full_path), "%s/%s", g_ModPath.c_str(), GetMetamodBaseDir());
+ LookForVDFs(full_path);
+ }
+ else
+ {
bInFirstLevel = false;
}
diff --git a/sourcemm/svn_version.h b/sourcemm/svn_version.h
index faeca49..562168c 100644
--- a/sourcemm/svn_version.h
+++ b/sourcemm/svn_version.h
@@ -3,11 +3,11 @@
#ifndef _INCLUDE_SVN_VERSION_H_
#define _INCLUDE_SVN_VERSION_H_
-#define SVN_PRODUCT_VERSION "1.4.2"
+#define SVN_PRODUCT_VERSION "1.4.3"
#define SVN_REVISION 414
#define SVN_REVISION_STRING "414"
-#define SVN_FILE_VERSION 1,4,2,414
-#define SVN_FILE_VERSION_STRING "1.4.2.414"
+#define SVN_FILE_VERSION 1,4,3,414
+#define SVN_FILE_VERSION_STRING "1.4.3.414"
#endif //_INCLUDE_SVN_VERSION_H_