diff --git a/core/msvc8/sourcemod_mm.vcproj b/core/msvc8/sourcemod_mm.vcproj
index 59d92a392..3c946012f 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 000000000..c668067eb
--- /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 000000000..62670c3e6
--- /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 7e92c5d9a..c450d079c 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 75652a001..7c7019774 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 db2749118..86f1421a0 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;
}
}