2
0
mirror of https://github.com/rehlds/metamod-r.git synced 2024-12-27 07:05:34 +03:00

Refactoring.

Fix load gamedll.
Backport: setting gamedll
This commit is contained in:
s1lentq 2017-01-18 22:14:02 +07:00
parent 20d3b65cdf
commit 5e0e048cff
8 changed files with 139 additions and 76 deletions

View File

@ -1,7 +1,8 @@
#include "precompiled.h" #include "precompiled.h"
MConfig::MConfig() : m_debuglevel(0), m_plugins_file(nullptr), m_exec_cfg(nullptr), m_list(nullptr), m_filename(nullptr) MConfig::MConfig() : m_debuglevel(0), m_gamedll(nullptr), m_exec_cfg(nullptr), m_list(nullptr), m_filename(nullptr)
{ {
set_directory();
} }
// Initialize default values from the stored options struct. Has to happen // Initialize default values from the stored options struct. Has to happen
@ -17,7 +18,7 @@ option_t *MConfig::find(const char* lookup) const
{ {
for (auto optp = m_list; optp->name; optp++) for (auto optp = m_list; optp->name; optp++)
{ {
if (!strcmp(optp->name, lookup)) { if (!Q_strcmp(optp->name, lookup)) {
return optp; return optp;
} }
} }
@ -178,3 +179,27 @@ void MConfig::show() const
} }
} }
} }
void MConfig::set_directory()
{
#ifdef _WIN32
HMODULE hModule = NULL;
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCTSTR)GiveFnptrsToDll, &hModule);
GetModuleFileName(hModule, m_directory, sizeof m_directory);
#else
Dl_info addrInfo;
if (dladdr((void *)GiveFnptrsToDll, &addrInfo))
{
Q_strncpy(m_directory, addrInfo.dli_fname, sizeof m_directory - 1);
m_directory[sizeof m_directory - 1] = '\0';
}
#endif
normalize_pathname(m_directory);
// get directory
char *dir = Q_strrchr(m_directory, '/');
if (dir) {
*dir = '\0';
}
}

View File

@ -30,14 +30,17 @@ public:
bool load(const char *filename); bool load(const char *filename);
bool set(const char *key, const char *value) const; bool set(const char *key, const char *value) const;
void show() const; void show() const;
void set_directory();
const char *directory() const;
int m_debuglevel; // to use for meta_debug int m_debuglevel; // to use for meta_debug
char *m_plugins_file; // ie metamod.ini, plugins.ini char *m_gamedll; // string if specified in config.ini
char *m_exec_cfg; // ie metaexec.cfg, exec.cfg char *m_exec_cfg; // ie exec.cfg
private: private:
option_t *m_list; option_t *m_list;
char *m_filename; char *m_filename;
char m_directory[MAX_PATH];
option_t *find(const char *lookup) const; option_t *find(const char *lookup) const;
static bool set(option_t *setp, const char *value); static bool set(option_t *setp, const char *value);
@ -46,3 +49,8 @@ private:
void operator=(const MConfig &src); void operator=(const MConfig &src);
MConfig(const MConfig &src); MConfig(const MConfig &src);
}; };
inline const char *MConfig::directory() const
{
return m_directory;
}

View File

@ -90,15 +90,10 @@ bool install_gamedll(char *from, const char *to)
// - ME_NOTFOUND couldn't recognize game // - ME_NOTFOUND couldn't recognize game
bool setup_gamedll(gamedll_t *gamedll) bool setup_gamedll(gamedll_t *gamedll)
{ {
bool override = false;
const game_modinfo_t *known; const game_modinfo_t *known;
const char *knownfn = nullptr; const char *knownfn = nullptr;
// Check for old-style "metagame.ini" file and complain.
if (valid_gamedir_file(OLD_GAMEDLL_TXT))
{
META_WARNING("File '%s' is no longer supported; instead, specify override gamedll in %s or with '+localinfo mm_gamedll <dllfile>'", OLD_GAMEDLL_TXT, CONFIG_INI);
}
// First, look for a known game, based on gamedir. // First, look for a known game, based on gamedir.
if ((known = lookup_game(gamedll->name))) if ((known = lookup_game(gamedll->name)))
{ {
@ -107,25 +102,46 @@ bool setup_gamedll(gamedll_t *gamedll)
#else #else
knownfn = known->linux_so; knownfn = known->linux_so;
#endif #endif
META_DEBUG(4, "Checking for old version game DLL name '%s'.\n", knownfn);
Q_snprintf(gamedll->pathname, sizeof gamedll->pathname, "dlls/%s", knownfn);
// Check if the gamedll file exists. If not, try to install it from the cache.
if (!valid_gamedir_file(gamedll->pathname))
{
Q_snprintf(gamedll->real_pathname, sizeof gamedll->real_pathname, "%s/dlls/%s", gamedll->gamedir, knownfn);
install_gamedll(gamedll->pathname, gamedll->real_pathname);
} }
// Neither override nor known-list found a gamedll.
if (!known && !g_config->m_gamedll)
return false;
// Use override-dll if specified.
if (g_config->m_gamedll)
{
Q_strncpy(gamedll->pathname, g_config->m_gamedll, sizeof gamedll->pathname - 1);
gamedll->pathname[sizeof gamedll->pathname - 1] = '\0';
// If the path is relative, the gamedll file will be missing and
// it might be found in the cache file.
if (!is_absolute_path(gamedll->pathname))
{
char szInstallPath[MAX_PATH];
Q_snprintf(szInstallPath, sizeof(szInstallPath), "%s/%s", gamedll->gamedir, gamedll->pathname);
// If we could successfully install the gamedll from the cache we
// rectify the pathname to be a full pathname.
if (install_gamedll(gamedll->pathname, szInstallPath))
{
Q_strncpy(gamedll->pathname, szInstallPath, sizeof(gamedll->pathname));
}
}
override = true;
}
// Else use Known-list dll.
else if (known)
{
Q_snprintf(gamedll->pathname, sizeof(gamedll->pathname), "%s/dlls/%s", gamedll->gamedir, knownfn);
} }
else else
{ {
// Neither known-list found a gamedll. // Neither override nor known-list found a gamedll.
return false; return false;
} }
Q_snprintf(gamedll->pathname, sizeof gamedll->pathname, "%s/dlls/%s", gamedll->gamedir, knownfn);
// get filename from pathname // get filename from pathname
char *cp = Q_strrchr(gamedll->pathname, '/'); char *cp = Q_strrchr(gamedll->pathname, '/');
if (cp) if (cp)
@ -135,11 +151,33 @@ bool setup_gamedll(gamedll_t *gamedll)
gamedll->file = cp; gamedll->file = cp;
// If found, store also the supposed "real" dll path based on the
// gamedir, in case it differs from the "override" dll path.
if (known && override)
{
Q_snprintf(gamedll->real_pathname, sizeof(gamedll->real_pathname), "%s/dlls/%s", gamedll->gamedir, knownfn);
}
else
{
Q_strncpy(gamedll->real_pathname, gamedll->pathname, sizeof gamedll->real_pathname - 1); Q_strncpy(gamedll->real_pathname, gamedll->pathname, sizeof gamedll->real_pathname - 1);
gamedll->real_pathname[sizeof gamedll->real_pathname - 1] = '\0'; gamedll->real_pathname[sizeof gamedll->real_pathname - 1] = '\0';
}
if (override)
{
// generate a desc
Q_snprintf(gamedll->desc, sizeof(gamedll->desc), "%s (override)", gamedll->file);
// log result
META_LOG("Overriding game '%s' with dllfile '%s'", gamedll->name, gamedll->file);
}
else if (known)
{
Q_strncpy(gamedll->desc, known->desc, sizeof gamedll->desc - 1);
gamedll->desc[sizeof gamedll->desc - 1] = '\0';
gamedll->desc = known->desc;
META_LOG("Recognized game '%s'; using dllfile '%s'", gamedll->name, gamedll->file); META_LOG("Recognized game '%s'; using dllfile '%s'", gamedll->name, gamedll->file);
}
return true; return true;
} }

View File

@ -8,7 +8,6 @@ struct game_modinfo_t
const char *name; // name (the game dir) const char *name; // name (the game dir)
const char *linux_so; // filename of linux shared lib const char *linux_so; // filename of linux shared lib
const char *win_dll; // filename of win32 dll const char *win_dll; // filename of win32 dll
const char *osx_dylib; // filename os osx dylib
const char *desc; // our long-name description const char *desc; // our long-name description
}; };

View File

@ -7,8 +7,8 @@ MConfig *g_config = &g_static_config;
option_t g_global_options[] = option_t g_global_options[] =
{ {
{ "debuglevel", CF_INT, &g_config->m_debuglevel, "0" }, { "debuglevel", CF_INT, &g_config->m_debuglevel, "0" },
{ "plugins_file", CF_PATH, &g_config->m_plugins_file, PLUGINS_INI }, { "gamedll", CF_PATH, &g_config->m_gamedll, NULL },
{ "exec_cfg", CF_STR, &g_config->m_exec_cfg, EXEC_CFG }, { "exec_cfg", CF_STR, &g_config->m_exec_cfg, NULL },
// list terminator // list terminator
{ NULL, CF_NONE, NULL, NULL } { NULL, CF_NONE, NULL, NULL }
@ -35,10 +35,16 @@ int g_requestid_counter = 0;
// Do startup operations... // Do startup operations...
void metamod_startup() void metamod_startup()
{ {
const char *mmfile = nullptr;
const char *cfile = nullptr;
const char *cp; const char *cp;
char configFile[MAX_PATH];
char pluginFile[MAX_PATH];
char execFile[MAX_PATH];
Q_snprintf(configFile, sizeof configFile, "%s/%s", g_config->directory(), CONFIG_INI);
Q_snprintf(pluginFile, sizeof pluginFile, "%s/%s", g_config->directory(), PLUGINS_INI);
Q_snprintf(execFile, sizeof execFile, "%s/%s", g_config->directory(), EXEC_CFG);
META_CONS(" "); META_CONS(" ");
META_CONS(" Metamod-r version %s Copyright (c) 2016-2017 ReHlds Team (rebuild of original Metamod by Will Day)", APP_VERSION_STRD); META_CONS(" Metamod-r version %s Copyright (c) 2016-2017 ReHlds Team (rebuild of original Metamod by Will Day)", APP_VERSION_STRD);
META_CONS(" Metamod-r comes with ABSOLUTELY NO WARRANTY; for details type `meta gpl'."); META_CONS(" Metamod-r comes with ABSOLUTELY NO WARRANTY; for details type `meta gpl'.");
@ -72,18 +78,22 @@ void metamod_startup()
g_config->init(g_global_options); g_config->init(g_global_options);
// Find config file // Find config file
cfile = CONFIG_INI;
if ((cp = LOCALINFO("mm_configfile")) && *cp != '\0') if ((cp = LOCALINFO("mm_configfile")) && *cp != '\0')
{ {
META_LOG("Configfile specified via localinfo: %s", cp); META_LOG("Configfile specified via localinfo: %s", cp);
if (valid_gamedir_file(cp)) if (valid_gamedir_file(cp))
cfile = cp; {
else Q_strncpy(configFile, cp, sizeof configFile - 1);
META_ERROR("Empty/missing config.ini file: %s; falling back to %s", cp, cfile); configFile[sizeof configFile - 1] = '\0';
} }
else
META_ERROR("Empty/missing config.ini file: %s; falling back to %s", cp, configFile);
}
// Load config file // Load config file
if (valid_gamedir_file(cfile)) if (valid_gamedir_file(configFile))
g_config->load(cfile); g_config->load(configFile);
else else
META_DEBUG(2, "No config.ini file found: %s", CONFIG_INI); META_DEBUG(2, "No config.ini file found: %s", CONFIG_INI);
@ -93,16 +103,19 @@ void metamod_startup()
META_LOG("Debuglevel specified via localinfo: %s", cp); META_LOG("Debuglevel specified via localinfo: %s", cp);
g_config->set("debuglevel", cp); g_config->set("debuglevel", cp);
} }
if ((cp = LOCALINFO("mm_gamedll")) && *cp != '\0') if ((cp = LOCALINFO("mm_gamedll")) && *cp != '\0')
{ {
META_LOG("Gamedll specified via localinfo: %s", cp); META_LOG("Gamedll specified via localinfo: %s", cp);
g_config->set("gamedll", cp); g_config->set("gamedll", cp);
} }
if ((cp = LOCALINFO("mm_pluginsfile")) && *cp != '\0') if ((cp = LOCALINFO("mm_pluginsfile")) && *cp != '\0')
{ {
META_LOG("Pluginsfile specified via localinfo: %s", cp); META_LOG("Pluginsfile specified via localinfo: %s", cp);
g_config->set("plugins_file", cp); g_config->set("plugins_file", cp);
} }
if ((cp = LOCALINFO("mm_execcfg")) && *cp != '\0') if ((cp = LOCALINFO("mm_execcfg")) && *cp != '\0')
{ {
META_LOG("Execcfg specified via localinfo: %s", cp); META_LOG("Execcfg specified via localinfo: %s", cp);
@ -158,16 +171,8 @@ void metamod_startup()
// In fact, we need gamedir even earlier, so moved up above. // In fact, we need gamedir even earlier, so moved up above.
// Fall back to old plugins filename, if configured one isn't found. // Fall back to old plugins filename, if configured one isn't found.
mmfile = PLUGINS_INI;
if (!valid_gamedir_file(PLUGINS_INI) && valid_gamedir_file(OLD_PLUGINS_INI)) g_plugins = new MPluginList(pluginFile);
mmfile = OLD_PLUGINS_INI;
if (valid_gamedir_file(g_config->m_plugins_file))
mmfile = g_config->m_plugins_file;
else
META_ERROR("g_plugins file is empty/missing: %s; falling back to %s", g_config->m_plugins_file, mmfile);
g_plugins = new MPluginList(mmfile);
if (!meta_load_gamedll()) if (!meta_load_gamedll())
{ {
@ -189,23 +194,21 @@ void metamod_startup()
// Only attempt load if the file appears to exist and be non-empty, to // Only attempt load if the file appears to exist and be non-empty, to
// avoid confusing users with "couldn't exec exec.cfg" console // avoid confusing users with "couldn't exec exec.cfg" console
// messages. // messages.
if (valid_gamedir_file(g_config->m_exec_cfg)) if (g_config->m_exec_cfg)
mmfile = g_config->m_exec_cfg;
else if (valid_gamedir_file(OLD_EXEC_CFG))
mmfile = OLD_EXEC_CFG;
else
mmfile = NULL;
if (mmfile)
{ {
if (mmfile[0] == '/') Q_strncpy(execFile, g_config->m_exec_cfg, sizeof execFile - 1);
META_ERROR("Cannot exec absolute pathnames: %s", mmfile); execFile[sizeof execFile - 1] = '\0';
}
if (valid_gamedir_file(execFile))
{
if (execFile[0] == '/')
META_ERROR("Cannot exec absolute pathnames: %s", execFile);
else else
{ {
char cmd[NAME_MAX]; char cmd[NAME_MAX];
META_LOG("Exec'ing metamod exec.cfg: %s...", mmfile); META_LOG("Exec'ing metamod exec.cfg: %s...", execFile);
Q_snprintf(cmd, sizeof cmd, "exec %s\n", mmfile); Q_snprintf(cmd, sizeof cmd, "exec %s\n", execFile);
SERVER_COMMAND(cmd); SERVER_COMMAND(cmd);
} }
} }

View File

@ -9,19 +9,9 @@
#include "meta_eiface.h" // HL_enginefuncs_t, meta_enginefuncs_t #include "meta_eiface.h" // HL_enginefuncs_t, meta_enginefuncs_t
#include "engine_t.h" // engine_t, Engine #include "engine_t.h" // engine_t, Engine
// file that lists plugins to load at startup #define PLUGINS_INI "plugins.ini" // file that lists plugins to load at startup
#define PLUGINS_INI "addons/metamod/plugins.ini" #define EXEC_CFG "exec.cfg" // file that contains commands to metamod plugins at startup
#define OLD_PLUGINS_INI "metamod.ini" #define CONFIG_INI "config.ini" // generic config file
// file that contains commands to metamod plugins at startup
#define EXEC_CFG "addons/metamod/exec.cfg"
#define OLD_EXEC_CFG "metaexec.cfg"
// previously, file that contained path for an override-gamedll
#define OLD_GAMEDLL_TXT "metagame.ini"
// generic config file
#define CONFIG_INI "addons/metamod/config.ini"
// cvar to contain version // cvar to contain version
extern cvar_t g_meta_version; extern cvar_t g_meta_version;
@ -30,7 +20,7 @@ extern cvar_t g_meta_version;
struct gamedll_t struct gamedll_t
{ {
char name[NAME_MAX]; // ie "cstrike" (from gamedir) char name[NAME_MAX]; // ie "cstrike" (from gamedir)
const char *desc; // ie "Counter-Strike" char desc[NAME_MAX]; // ie "Counter-Strike"
char gamedir[PATH_MAX]; // ie "/home/willday/half-life/cstrike" char gamedir[PATH_MAX]; // ie "/home/willday/half-life/cstrike"
char pathname[PATH_MAX]; // ie "/home/willday/half-life/cstrike/dlls/cs_i386.so" char pathname[PATH_MAX]; // ie "/home/willday/half-life/cstrike/dlls/cs_i386.so"
char const *file; // ie "cs_i386.so" char const *file; // ie "cs_i386.so"