From 581a0dc7a870428107a2ffd4805287c49bb52e69 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Thu, 25 May 2006 04:49:47 +0000 Subject: [PATCH] added alias ability fixed gamedll version finding fall through --HG-- extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/trunk%40206 --- sourcemm/CPlugin.cpp | 75 +++++++++++++++++++++++++-- sourcemm/CPlugin.h | 12 +++++ sourcemm/concommands.cpp | 107 +++++++++++++++++++++++++++++++++++++-- sourcemm/sourcemm.cpp | 76 ++++++++++++++++++++++----- sourcemm/sourcemm.h | 4 +- 5 files changed, 250 insertions(+), 24 deletions(-) diff --git a/sourcemm/CPlugin.cpp b/sourcemm/CPlugin.cpp index 3fdecf2..db1d871 100644 --- a/sourcemm/CPlugin.cpp +++ b/sourcemm/CPlugin.cpp @@ -44,11 +44,73 @@ CPluginManager::CPluginManager() CPluginManager::~CPluginManager() { - /*if (m_Plugins.size()) + SourceHook::List::iterator iter; + + for (iter=m_Aliases.begin(); iter!=m_Aliases.end(); iter++) { - UnloadAll(); - m_Plugins.clear(); - }*/ + delete (*iter); + } + + m_Aliases.clear(); +} + +const char *CPluginManager::LookupAlias(const char *alias) +{ + SourceHook::List::iterator iter; + CNameAlias *p; + + for (iter=m_Aliases.begin(); iter!=m_Aliases.end(); iter++) + { + p = (*iter); + if (p->alias.compare(alias) == 0) + { + return p->value.c_str(); + } + } + + return NULL; +} + +SourceHook::List::iterator CPluginManager::_alias_begin() +{ + return m_Aliases.begin(); +} + +SourceHook::List::iterator CPluginManager::_alias_end() +{ + return m_Aliases.end(); +} + +void CPluginManager::SetAlias(const char *alias, const char *value) +{ + SourceHook::List::iterator iter; + CNameAlias *p; + + for (iter=m_Aliases.begin(); iter!=m_Aliases.end(); iter++) + { + p = (*iter); + if (p->alias.compare(alias) == 0) + { + if (value[0] == '\0') + { + iter = m_Aliases.erase(iter); + return; + } else { + p->value.assign(value); + return; + } + } + } + + if (value[0] != '\0') + { + p = new CNameAlias; + + p->alias.assign(alias); + p->value.assign(value); + + m_Aliases.push_back(p); + } } CPluginManager::CPlugin::CPlugin() : m_Lib(NULL), m_API(NULL), m_Id(0), m_Source(0) @@ -261,7 +323,10 @@ CPluginManager::CPlugin *CPluginManager::_Load(const char *file, PluginId source if (error) snprintf(error, maxlen, "File not found: %s", file); pl->m_Status = Pl_NotFound; - } else { + } + + if (fp) + { fclose(fp); fp = NULL; diff --git a/sourcemm/CPlugin.h b/sourcemm/CPlugin.h index 1fe9701..74c8827 100644 --- a/sourcemm/CPlugin.h +++ b/sourcemm/CPlugin.h @@ -43,6 +43,11 @@ namespace SourceMM { + struct CNameAlias + { + SourceHook::String alias; + SourceHook::String value; + }; /** * @brief Implements Plugin Manager API */ @@ -77,6 +82,7 @@ namespace SourceMM bool Pause(PluginId id, char *error, size_t maxlen); bool Unpause(PluginId id, char *error, size_t maxlen); bool UnloadAll(); + void SetAlias(const char *alias, const char *value); public: bool Query(PluginId id, const char *&file, Pl_Status &status, PluginId &source); bool QueryRunning(PluginId id, char *error, size_t maxlength); @@ -106,6 +112,11 @@ namespace SourceMM */ bool Retry(PluginId id, char *error, size_t len); + //get alias info + const char *LookupAlias(const char *alias); + SourceHook::List::iterator _alias_begin(); + SourceHook::List::iterator _alias_end(); + //Internal iterators SourceHook::List::iterator _begin(); SourceHook::List::iterator _end(); @@ -119,6 +130,7 @@ namespace SourceMM private: PluginId m_LastId; SourceHook::List m_Plugins; + SourceHook::List m_Aliases; bool m_AllLoaded; }; }; diff --git a/sourcemm/concommands.cpp b/sourcemm/concommands.cpp index 2d2fff3..056d129 100644 --- a/sourcemm/concommands.cpp +++ b/sourcemm/concommands.cpp @@ -371,6 +371,12 @@ CON_COMMAND(meta, "Metamod:Source Menu") const char *file = e->Cmd_Argv(2); char full_path[255]; + const char *alias = g_PluginMngr.LookupAlias(file); + if (alias) + { + file = alias; + } + if (file[0] == '/' || strcmp(&(file[1]), ":\\") == 0) { g_SmmAPI.PathFormat(full_path, sizeof(full_path)-1, "%s", file); @@ -410,12 +416,105 @@ CON_COMMAND(meta, "Metamod:Source Menu") return; } + } else if ( (strcmp(command, "alias") == 0) || + (strcmp(command, "aliases") == 0) ) { + if (args >= 4) + { + const char *alias = e->Cmd_Argv(2); + const char *value = e->Cmd_Argv(3); + + g_PluginMngr.SetAlias(alias, value); + if (value[0] == '\0') + { + CONMSG("Deleted alias: %s.\n", alias); + } else { + CONMSG("Set alias \"%s\" to: %s\n", alias, value); + } + } else if (args >= 3) { + const char *alias = e->Cmd_Argv(2); + const char *value = g_PluginMngr.LookupAlias(alias); + if (value) + { + CONMSG("Alias \"%s\" is set to: %s\n", alias, value); + } else { + CONMSG("Alias \"%s\" was not found.\n", alias); + } + } else { + SourceHook::List::iterator iter, end; + SourceMM::CNameAlias *p; + + iter = g_PluginMngr._alias_begin(); + end = g_PluginMngr._alias_end(); + size_t total = 0; + if (iter != end) + { + CONMSG("%-10.9s %s\n", "Alias", "File"); + CONMSG(" --- \n"); + for (; iter!=end; iter++) + { + p = (*iter); + CONMSG("%-10.9s %s\n", p->alias.c_str(), p->value.c_str()); + total++; + } + CONMSG(" --- \n"); + CONMSG("%d aliases total.\n", total); + } else { + CONMSG("No aliases found.\n"); + } + } + return; } else if (strcmp(command, "unload") == 0) { if (args >= 3) { - int id = atoi(e->Cmd_Argv(2)); + const char *file = e->Cmd_Argv(2); + int id = atoi(file); char error[255]={0}; + if (id == 0 && isalpha(file[0])) + { + char full_path[255]; + const char *alias = g_PluginMngr.LookupAlias(file); + + if (alias) + { + file = alias; + } + + /* first check if it's a known filename */ + if (file[0] == '/' || strcmp(&(file[1]), ":\\") == 0) + { + g_SmmAPI.PathFormat(full_path, sizeof(full_path)-1, "%s", file); + snprintf(full_path, sizeof(full_path)-1, "%s", file); + } else { + const char *ext = UTIL_GetExtension(file); +#if defined WIN32 || defined _WIN32 + ext = ext ? "" : ".dll"; +#else + ext = ext ? "" : "_i486.so"; +#endif + g_SmmAPI.PathFormat(full_path, sizeof(full_path)-1, "%s/%s%s", g_ModPath.c_str(), file, ext); + } + + SourceHook::List::iterator iter, end; + SourceMM::CPluginManager::CPlugin *pl; + iter = g_PluginMngr._begin(); + end = g_PluginMngr._end(); + for (; iter!=end; iter++) + { + pl = (*iter); + if (strcmp(pl->m_File.c_str(), full_path) == 0) + { + id = pl->m_Id; + break; + } + } + if (id == 0) + { + CONMSG("Plugin \"%s\" not found.\n", full_path); + return; + } + } + if (!g_PluginMngr.Unload(id, false, error, sizeof(error)-1)) { CONMSG("Unload failed: %s\n", error); @@ -423,13 +522,10 @@ CON_COMMAND(meta, "Metamod:Source Menu") } CONMSG("Plugin %d unloaded.\n", id); - - return; } else { CONMSG("Usage: meta unload \n"); - - return; } + return; } else if (strcmp(command, "force_unload") == 0) { if (args >= 3) { @@ -485,6 +581,7 @@ CON_COMMAND(meta, "Metamod:Source Menu") CONMSG("Metamod:Source Menu\n"); CONMSG("usage: meta [arguments]\n"); + CONMSG(" alias - list or set an alias\n"); CONMSG(" clear - Unload all plugins forcefully\n"); CONMSG(" cmds - Show plugin commands\n"); CONMSG(" cvars - Show plugin cvars\n"); diff --git a/sourcemm/sourcemm.cpp b/sourcemm/sourcemm.cpp index dcbdfbe..3082a4c 100644 --- a/sourcemm/sourcemm.cpp +++ b/sourcemm/sourcemm.cpp @@ -376,10 +376,13 @@ SMM_API void *CreateInterface(const char *iface, int *ret) { //This is the interface we want! Right now we support versions 3 and 4. int version = atoi(&(iface[len])); + int sizeTooBig = 0; //rename this to sizeWrong in the future! if (version < MIN_GAMEDLL_VERSION || version > MAX_GAMEDLL_VERSION) { - Error("GameDLL version %d is not supported by Metamod!", version); - return NULL; + //maybe this will get used in the future + sizeTooBig = version; + if (ret) + *ret = IFACE_FAILED; } SourceHook::List::iterator iter; GameDllInfo *pInfo = NULL; @@ -401,8 +404,17 @@ SMM_API void *CreateInterface(const char *iface, int *ret) } if (g_GameDll.loaded) { - InitMainStates(); + if (sizeTooBig) + { + Error("This mod version requires a SourceMM update (ServerGameDLL%03d)!", sizeTooBig); + if (ret) + *ret = IFACE_FAILED; + return NULL; + } else { + InitMainStates(); + } } else { + sizeTooBig = 0; if (ret) *ret = IFACE_FAILED; return NULL; @@ -457,22 +469,22 @@ void DLLShutdown_handler() RETURN_META(MRES_SUPERCEDE); } -int LoadPluginsFromFile(const char *file) +int LoadPluginsFromFile(const char *_file) { FILE *fp; int total = 0, skipped=0; PluginId id; bool already; - fp = fopen(file, "rt"); + fp = fopen(_file, "rt"); if (!fp) { - LogMessage("[META] Could not open plugins file %s\n", file); + LogMessage("[META] Could not open plugins file %s\n", _file); return -1; } char buffer[255], error[255], full_path[128]; - const char *ptr, *ext; + const char *ptr, *ext, *file; size_t length; while (!feof(fp)) { @@ -482,18 +494,58 @@ int LoadPluginsFromFile(const char *file) if (!length) continue; if (buffer[length-1] == '\n') - buffer[length-1] = '\0'; + buffer[--length] = '\0'; UTIL_TrimLeft(buffer); UTIL_TrimRight(buffer); if (buffer[0] == '\0' || buffer[0] == ';' || strncmp(buffer, "//", 2) == 0) continue; + file = buffer; + if (buffer[0] == '"') + { + char *cptr = buffer; + file = ++cptr; + + while (*cptr) + { + if (*cptr == '"') + { + *cptr = '\0'; + break; + } + cptr++; + } + } else { + char *cptr = buffer; + while (*cptr) + { + if (isspace(*cptr)) + { + char *optr = cptr; + while (*cptr && isspace(*cptr)) + cptr++; + *optr = '\0'; + UTIL_TrimRight(cptr); + if (*cptr && isalpha(*cptr)) + { + g_PluginMngr.SetAlias(buffer, cptr); + file = cptr; + } + break; + } + cptr++; + } + } + if (!file[0]) + { + continue; + } //First find if it's an absolute path or not... - if (buffer[0] == '/' || strncmp(&(buffer[1]), ":\\", 2) == 0) + if (file[0] == '/' || strncmp(&(file[1]), ":\\", 2) == 0) { //If we're in an absolute path, ignore our normal heuristics - id = g_PluginMngr.Load(buffer, Pl_File, already, error, sizeof(error)-1); + id = g_PluginMngr.Load(file, Pl_File, already, error, sizeof(error)-1); if (id < Pl_MinId || g_PluginMngr.FindById(id)->m_Status < Pl_Paused) { LogMessage("[META] Failed to load plugin %s. %s", buffer, error); @@ -505,7 +557,7 @@ int LoadPluginsFromFile(const char *file) } } else { //Attempt to find a file extension - ptr = UTIL_GetExtension(buffer); + ptr = UTIL_GetExtension(file); //Add an extension if there's none there if (!ptr) { @@ -518,7 +570,7 @@ int LoadPluginsFromFile(const char *file) ext = ""; } //Format the new path - g_SmmAPI.PathFormat(full_path, sizeof(full_path)-1, "%s/%s%s", g_ModPath.c_str(), buffer, ext); + g_SmmAPI.PathFormat(full_path, sizeof(full_path)-1, "%s/%s%s", g_ModPath.c_str(), file, ext); id = g_PluginMngr.Load(full_path, Pl_File, already, error, sizeof(error)-1); if (id < Pl_MinId || g_PluginMngr.FindById(id)->m_Status < Pl_Paused) { diff --git a/sourcemm/sourcemm.h b/sourcemm/sourcemm.h index 58c9885..c88c172 100644 --- a/sourcemm/sourcemm.h +++ b/sourcemm/sourcemm.h @@ -39,11 +39,11 @@ #define SM_MAJOR_VERSION 1 //never need to increase this #define SM_VERS_API_MAJOR 1 //increase this on a breaking change #define SM_VERS_API_MINOR 3 //increase this on a non-breaking API change -#define SM_VERS_RELEASE 1 //increase this on a bug-fix release. +#define SM_VERS_RELEASE 2 //increase this on a bug-fix release. //We need a good CServerGameDLL version to work properly. We support these inclusively. #define MIN_GAMEDLL_VERSION 3 -#define MAX_GAMEDLL_VERSION 5 +#define MAX_GAMEDLL_VERSION 4 /** * @brief Entry point for HL2 Engine