From c9002c2011ea05cd8e5530ef4fc640ea4e484853 Mon Sep 17 00:00:00 2001 From: Borja Ferrer Date: Sat, 16 Dec 2006 02:16:21 +0000 Subject: [PATCH] Added initial console commands for plugins fixed crash in plugin destructor fixed compilation not being freed causing a crash fixed small issues in plugin system fixed plugin iterator not being reseted when freed and not being initialized it's current pointer. fixed a bug where insertion of a prefixed string would not check whether a value could be set. --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40221 --- core/msvc8/sourcemod_mm.vcproj | 14 ++- core/sm_srvcmds.cpp | 171 +++++++++++++++++++++++++++++++++ core/sm_srvcmds.h | 16 +++ core/sm_trie.cpp | 6 ++ core/sourcemm_api.cpp | 1 + core/systems/PluginSys.cpp | 23 +++-- 6 files changed, 219 insertions(+), 12 deletions(-) create mode 100644 core/sm_srvcmds.cpp create mode 100644 core/sm_srvcmds.h diff --git a/core/msvc8/sourcemod_mm.vcproj b/core/msvc8/sourcemod_mm.vcproj index 59d92a39..3c946012 100644 --- a/core/msvc8/sourcemod_mm.vcproj +++ b/core/msvc8/sourcemod_mm.vcproj @@ -1,7 +1,7 @@ + + @@ -220,6 +224,10 @@ RelativePath="..\sm_platform.h" > + + diff --git a/core/sm_srvcmds.cpp b/core/sm_srvcmds.cpp new file mode 100644 index 00000000..c668067e --- /dev/null +++ b/core/sm_srvcmds.cpp @@ -0,0 +1,171 @@ +#include "sm_srvcmds.h" + +ConVarAccessor g_ConCmdAccessor; + +void ConVarAccessor::OnSourceModStartup(bool late) +{ + ConCommandBaseMgr::OneTimeInit(&g_ConCmdAccessor); +} + +bool ConVarAccessor::RegisterConCommandBase(ConCommandBase *pCommand) +{ + META_REGCVAR(pCommand); + + return true; +} + +CON_COMMAND(sm, "SourceMod Menu") +{ + int argnum = engine->Cmd_Argc(); + + if (argnum >= 2) + { + const char *cmd = engine->Cmd_Argv(1); + if (!strcmp("plugins", cmd)) + { + if (argnum >= 3) + { + const char *cmd2 = engine->Cmd_Argv(2); + if (!strcmp("list", cmd2)) + { + char buffer[256]; + unsigned int id = 1; + int plnum = g_PluginSys.GetPluginCount(); + + if (!plnum) + { + META_CONPRINT("[SM] No plugins loaded\n"); + return; + } else { + META_CONPRINTF("[SM] Displaying %d plugin%s:\n", g_PluginSys.GetPluginCount(), (plnum > 1) ? "s" : ""); + } + + IPluginIterator *iter = g_PluginSys.GetPluginIterator(); + for (; iter->MorePlugins(); iter->NextPlugin(), id++) + { + assert(iter->GetPlugin()->GetStatus() != Plugin_Created); + int len = 0; + const sm_plugininfo_t *info = iter->GetPlugin()->GetPublicInfo(); + + len += snprintf(&buffer[len], sizeof(buffer)-len, " %02d <%s>", id, "status"); //:TODO: status + len += snprintf(&buffer[len], sizeof(buffer)-len, " \"%s\"", (info->name) ? info->name : iter->GetPlugin()->GetFilename()); + if (info->version) + { + len += snprintf(&buffer[len], sizeof(buffer)-len, " (%s)", info->version); + } + if (info->author) + { + snprintf(&buffer[len], sizeof(buffer)-len, " by %s", info->author); + } + META_CONPRINTF("%s\n", buffer); + } + + iter->Release(); + return; + } else if (!strcmp("load", cmd2)) { + if (argnum < 4) + { + META_CONPRINT("Usage: sm plugins load \n"); + return; + } + + char error[100]; + const char *filename = engine->Cmd_Argv(3); + IPlugin *pl = g_PluginSys.LoadPlugin(filename, false, PluginType_MapUpdated, error, sizeof(error)); + + if (pl) + { + META_CONPRINTF("Loaded plugin %s successfully.\n", filename); + } else { + META_CONPRINTF("Plugin %s failed to load: %s.\n", filename, error); + } + + return; + + } else if (!strcmp("unload", cmd2)) { + if (argnum < 4) + { + META_CONPRINT("Usage: sm plugins unload <#>\n"); + return; + } + + IPlugin *pl = NULL; + int id = 1; + int num = atoi(engine->Cmd_Argv(3)); + if (num < 1 || num > (int)g_PluginSys.GetPluginCount()) + { + META_CONPRINT("Plugin index not found.\n"); + return; + } + + IPluginIterator *iter = g_PluginSys.GetPluginIterator(); + for (; iter->MorePlugins() && idNextPlugin(), id++) {} + pl = iter->GetPlugin(); + + char name[64]; + const sm_plugininfo_t *info = pl->GetPublicInfo(); + strcpy(name, (info->name) ? info->name : pl->GetFilename()); + + if (g_PluginSys.UnloadPlugin(pl)) + { + META_CONPRINTF("Plugin %s unloaded successfully.\n", name); + } else { + META_CONPRINTF("Failed to unload plugin %s.\n", name); + } + + iter->Release(); + return; + + } else if (!strcmp("info", cmd2)) { + if (argnum < 4) + { + META_CONPRINT("Usage: sm plugins info <#>\n"); + return; + } + + IPlugin *pl = NULL; + int id = 1; + int num = atoi(engine->Cmd_Argv(3)); + if (num < 1 || num > (int)g_PluginSys.GetPluginCount()) + { + META_CONPRINT("Plugin index not found.\n"); + return; + } + + IPluginIterator *iter = g_PluginSys.GetPluginIterator(); + for (; iter->MorePlugins() && idNextPlugin(), id++) {} + pl = iter->GetPlugin(); + const sm_plugininfo_t *info = pl->GetPublicInfo(); + + META_CONPRINTF(" Filename: %s\n", pl->GetFilename()); + if (info->name) + { + META_CONPRINTF(" Title: %s\n", info->name); + } + if (info->author) + { + META_CONPRINTF(" Author: %s\n", info->author); + } + if (info->version) + { + META_CONPRINTF(" Version: %s\n", info->version); + } + if (info->description) + { + META_CONPRINTF(" Description: %s\n", info->description); + } + if (info->url) + { + META_CONPRINTF(" URL: %s\n", info->url); + } + //:TODO: write if it's in debug mode, or do it inside LIST ? + + iter->Release(); + return; + } + } + //:TODO: print plugins cmd list + } + } + //:TODO: print cmd list or something +} \ No newline at end of file diff --git a/core/sm_srvcmds.h b/core/sm_srvcmds.h new file mode 100644 index 00000000..62670c3e --- /dev/null +++ b/core/sm_srvcmds.h @@ -0,0 +1,16 @@ +#include "sourcemm_api.h" +#include +#include "sourcemod.h" +#include "PluginSys.h" + +using namespace SourceMod; + +class ConVarAccessor : + public IConCommandBaseAccessor, + public SMGlobalClass +{ +public: // IConCommandBaseAccessor + virtual bool RegisterConCommandBase(ConCommandBase *pCommand); +public: // SMGlobalClass + virtual void OnSourceModStartup(bool late); +}; \ No newline at end of file diff --git a/core/sm_trie.cpp b/core/sm_trie.cpp index 7e92c5d9..c450d079 100644 --- a/core/sm_trie.cpp +++ b/core/sm_trie.cpp @@ -603,6 +603,12 @@ bool sm_trie_insert(Trie *trie, const char *key, void *value) /* Do an initial browsing to make sure they're not the same string */ if (strcmp(keyptr, term) == 0) { + if (!node->valset) + { + node->valset = true; + node->value = value; + return true; + } /* Same string. We can't insert. */ return false; } diff --git a/core/sourcemm_api.cpp b/core/sourcemm_api.cpp index 75652a00..7c701977 100644 --- a/core/sourcemm_api.cpp +++ b/core/sourcemm_api.cpp @@ -14,6 +14,7 @@ bool SourceMod_Core::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen PLUGIN_SAVEVARS(); GET_V_IFACE_ANY(serverFactory, gamedll, IServerGameDLL, INTERFACEVERSION_SERVERGAMEDLL); + GET_V_IFACE_CURRENT(engineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER); return g_SourceMod.InitializeSourceMod(error, maxlen, late); } diff --git a/core/systems/PluginSys.cpp b/core/systems/PluginSys.cpp index db274911..86f1421a 100644 --- a/core/systems/PluginSys.cpp +++ b/core/systems/PluginSys.cpp @@ -40,12 +40,6 @@ CPlugin::~CPlugin() m_ctx.co = NULL; } - if (m_plugin) - { - g_pSourcePawn->FreeFromMemory(m_plugin); - m_plugin = NULL; - } - if (m_pub_funcs) { for (uint32_t i=0; iinfo.publics_num; i++) @@ -56,6 +50,12 @@ CPlugin::~CPlugin() m_pub_funcs = NULL; } + if (m_plugin) + { + g_pSourcePawn->FreeFromMemory(m_plugin); + m_plugin = NULL; + } + if (m_priv_funcs) { for (unsigned int i=0; i *_mylist) { mylist = _mylist; + Reset(); } IPlugin *CPluginManager::CPluginIterator::GetPlugin() @@ -500,6 +502,7 @@ void CPluginManager::LoadAll_FirstPass(const char *config, const char *basedir) /* First read in the database of plugin settings */ SMCParseError err; unsigned int line, col; + m_AllPluginsLoaded = false; if ((err=g_TextParse.ParseFile_SMC(config, &m_PluginInfo, &line, &col)) != SMCParse_Okay) { /* :TODO: log the error, don't bail out though */ @@ -668,7 +671,7 @@ IPlugin *CPluginManager::LoadPlugin(const char *path, bool debug, PluginType typ CPlugin *pPlugin; if (sm_trie_retrieve(m_LoadLookup, checkpath, (void **)&pPlugin)) { - snprintf(error, err_max, "Plugin file is alread loaded"); + snprintf(error, err_max, "Plugin file is already loaded"); return NULL; } @@ -743,6 +746,7 @@ void CPluginManager::LoadAll_SecondPass() RunSecondPass(pPlugin); } } + m_AllPluginsLoaded = true; } void CPluginManager::RunSecondPass(CPlugin *pPlugin) @@ -828,6 +832,7 @@ IPluginIterator *CPluginManager::GetPluginIterator() } else { CPluginIterator *iter = m_iters.front(); m_iters.pop(); + iter->Reset(); return iter; } }