2
0
mirror of https://github.com/rehlds/metamod-r.git synced 2025-01-13 23:28:23 +03:00

Refactoring

Fix parse plugins.ini (Load the plugins for a appropriate platform only)
Fix crash for meta-plugins using UPX
This commit is contained in:
s1lent 2017-11-15 07:22:48 +07:00
parent a6ab7cea5d
commit 1be6696e6b
No known key found for this signature in database
GPG Key ID: 0FE401DC73916B5C
5 changed files with 70 additions and 28 deletions

View File

@ -87,7 +87,7 @@ MPlugin* MPluginList::find(const char* findpath)
MPlugin* MPluginList::find_memloc(void* memptr)
{
for (auto p : m_plugins) {
if (p->m_sys_module.contain(memptr))
if (p->m_sys_module.load(memptr))
return p;
}
@ -136,8 +136,7 @@ MPlugin* MPluginList::find_match(MPlugin* pmatch)
for (auto p : m_plugins) {
auto plug = p;
if (pmatch->platform_match(plug)) {
if (plug->platform_match(pmatch)) {
return plug;
}
}
@ -188,7 +187,6 @@ MPlugin* MPluginList::plugin_addload(plid_t plid, const char* fname, PLUG_LOADTI
}
META_DEBUG(1, "Loaded plugin '%s' successfully", pl_added->m_desc);
return pl_added;
}
@ -245,10 +243,8 @@ bool MPluginList::ini_startup()
}
META_LOG("ini: Begin reading plugins list: %s", m_inifile);
for (n = 0 , ln = 1; !feof(fp) && fgets(line, sizeof line, fp); ln++) {
auto plug = new MPlugin();
memset(plug, 0, sizeof(MPlugin));
for (n = 0 , ln = 1; !feof(fp) && fgets(line, sizeof line, fp); ln++)
{
// Remove line terminations.
char* cp;
if ((cp = Q_strrchr(line, '\r')))
@ -257,6 +253,20 @@ bool MPluginList::ini_startup()
if ((cp = Q_strrchr(line, '\n')))
*cp = '\0';
trimbuf(line);
// skip empty lines
if (line[0] == '\0') {
continue;
}
// skip comments
if (line[0] == '#' || line[0] == ';' || !Q_strncmp(line, "//", 2)) {
continue;
}
auto plug = new MPlugin();
// Parse directly into next entry in array
if (!plug->ini_parseline(line)) {
delete plug;
@ -267,12 +277,11 @@ bool MPluginList::ini_startup()
if (find(plug->m_pathname)) {
// Should we check platform specific level here?
META_INFO("ini: Skipping duplicate plugin, line %d of %s: %s", ln, m_inifile, plug->m_pathname);
delete plug;
delete plug;
continue;
}
// Check for a matching platform with different platform specifics
// level.
// Check for a matching platform with different platform specifics level.
auto pmatch = find_match(plug); // TODO: check it
if (pmatch) {
META_DEBUG(1, "ini: Plugin in line %d overrides existing plugin", ln);
@ -462,7 +471,7 @@ bool MPluginList::load()
if (p->load(PT_STARTUP, delayed))
n++;
else
// all plugins should be loadable at startup->..
// all plugins should be loadable at startup->..
META_ERROR("dll: Failed to load plugin '%s'", p->m_file);
}

View File

@ -12,6 +12,41 @@ const char *MPlugin::s_rPrintLoadTime[][4] = {
// ReSharper disable once CppPossiblyUninitializedMember
MPlugin::MPlugin()
{
m_status = PL_EMPTY;
m_action = PA_NULL;
m_source = PS_INI;
m_platform = SP_WINDOWS;
m_index = 0;
m_info = nullptr;
m_file = nullptr;
m_time_loaded = 0;
m_source_plugin_index = 0;
m_unloader_index = 0;
m_is_unloader = false;
m_dllapi_table = nullptr;
m_dllapi_post_table = nullptr;
m_newapi_table = nullptr;
m_newapi_post_table = nullptr;
m_engine_table = nullptr;
m_engine_post_table = nullptr;
m_gamedll_funcs.dllapi_table = nullptr;
m_gamedll_funcs.newapi_table = nullptr;
Q_memset(m_desc, 0, sizeof(m_desc));
Q_memset(m_filename, 0, sizeof(m_filename));
Q_memset(m_pathname, 0, sizeof(m_pathname));
Q_memset(&m_mutil_funcs, 0, sizeof(m_mutil_funcs));
}
MPlugin::~MPlugin()
{
;
}
// Parse a line from plugins.ini into a plugin.
@ -21,18 +56,6 @@ bool MPlugin::ini_parseline(char *line)
strncpy(buf, line, sizeof buf - 1);
buf[sizeof buf - 1] = '\0';
trimbuf(buf);
// skip empty lines
if (buf[0] == '\0') {
return false;
}
// skip comments
if (buf[0] == '#' || buf[0] == ';' || !Q_strncmp(buf, "//", 2)) {
return false;
}
// grab platform ("win32" or "linux")
char* ptr_token;
char* token = strtok_r(buf, " \t", &ptr_token);
@ -40,10 +63,16 @@ bool MPlugin::ini_parseline(char *line)
return false;
}
if (!strcmp(token, "linux"))
#ifdef _WIN32
if (!Q_strcmp(token, "win32"))
m_platform = SP_WINDOWS;
else
#else
if (!Q_strcmp(token, "linux"))
m_platform = SP_LINUX;
else
m_platform = SP_WINDOWS;
#endif
return false;
// grab filename
token = strtok_r(nullptr, " \t\r\n", &ptr_token);

View File

@ -82,6 +82,7 @@ class MPlugin
{
public:
MPlugin();
~MPlugin();
bool ini_parseline(char *line); // parse line from .ini file
bool cmd_parseline(const char *line); // parse from console command

View File

@ -32,6 +32,7 @@ void EXT_FUNC meta_AddServerCommand(const char* cmd_name, void (*function)())
if (!plug) {
META_ERROR("Failed to find memloc for regcmd '%s'", cmd_name);
return;
}
// See if this command was previously registered, ie a "reloaded" plugin.
@ -63,7 +64,8 @@ void EXT_FUNC meta_CVarRegister(cvar_t* pCvar)
// try to find which plugin is registering this cvar
if (!plug) {
META_DEBUG(1, "Failed to find memloc for regcvar '%s'", pCvar->name);
META_ERROR("Failed to find memloc for regcvar '%s'", pCvar->name);
return;
}
// See if this cvar was previously registered, ie a "reloaded" plugin.

View File

@ -118,6 +118,7 @@ module_handle_t CSysModule::load(void *addr)
m_size = (size_t)dlsize(dlinfo.dli_fbase);
m_handle = dlopen(dlinfo.dli_fname, RTLD_NOW | RTLD_NOLOAD);
return m_handle;
}
module_handle_t CSysModule::load(const char *filepath)
@ -192,7 +193,7 @@ size_t CSysModule::getsize() const
bool CSysModule::contain(void *addr) const
{
return addr && uintptr_t(addr) > m_base && uintptr_t(addr) < m_base + m_size;
return addr && uintptr_t(addr) >= m_base && uintptr_t(addr) < m_base + m_size;
}
const char *CSysModule::getloaderror()