3 * ===============================================================
4 * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
5 * ===============================================================
7 * This file is not open source and may not be copied without explicit
8 * written permission of AlliedModders LLC. This file may not be redistributed
9 * in whole or significant part.
10 * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
15 #include "sm_srvcmds.h"
16 #include "sm_version.h"
17 #include "sm_stringutil.h"
18 #include "HandleSys.h"
19 #include "CoreConfig.h"
21 RootConsoleMenu g_RootMenu;
23 ConVar sourcemod_version("sourcemod_version", SVN_FULL_VERSION, FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY, "SourceMod Version");
25 RootConsoleMenu::RootConsoleMenu()
27 m_pCommands = sm_trie_create();
28 m_CfgExecDone = false;
31 RootConsoleMenu::~RootConsoleMenu()
33 sm_trie_destroy(m_pCommands);
35 List<ConsoleEntry *>::iterator iter;
36 for (iter=m_Menu.begin(); iter!=m_Menu.end(); iter++)
43 extern void _IntExt_OnHostnameChanged(ConVar *pConVar, char const *oldValue);
45 void RootConsoleMenu::OnSourceModStartup(bool late)
47 ConCommandBaseMgr::OneTimeInit(this);
48 AddRootConsoleCommand("version", "Display version information", this);
49 AddRootConsoleCommand("credits", "Display credits listing", this);
51 ConVar *pHost = icvar->FindVar("hostname");
52 pHost->InstallChangeCallback(_IntExt_OnHostnameChanged);
55 void RootConsoleMenu::OnSourceModShutdown()
57 RemoveRootConsoleCommand("credits", this);
58 RemoveRootConsoleCommand("version", this);
61 bool RootConsoleMenu::RegisterConCommandBase(ConCommandBase *pCommand)
63 META_REGCVAR(pCommand);
65 /* Override values of convars created by SourceMod convar manager if specified on command line */
66 const char *cmdLineValue = icvar->GetCommandLineValue(pCommand->GetName());
67 if (cmdLineValue && !pCommand->IsCommand())
69 static_cast<ConVar *>(pCommand)->SetValue(cmdLineValue);
75 void RootConsoleMenu::ConsolePrint(const char *fmt, ...)
81 size_t len = vsnprintf(buffer, sizeof(buffer), fmt, ap);
84 if (len >= sizeof(buffer) - 1)
93 META_CONPRINT(buffer);
96 bool RootConsoleMenu::AddRootConsoleCommand(const char *cmd, const char *text, IRootConsoleCommand *pHandler)
98 if (sm_trie_retrieve(m_pCommands, cmd, NULL))
103 sm_trie_insert(m_pCommands, cmd, pHandler);
105 /* Sort this into the menu */
106 List<ConsoleEntry *>::iterator iter = m_Menu.begin();
107 ConsoleEntry *pEntry;
108 bool inserted = false;
109 while (iter != m_Menu.end())
112 if (strcmp(cmd, pEntry->command.c_str()) < 0)
114 ConsoleEntry *pNew = new ConsoleEntry;
115 pNew->command.assign(cmd);
116 pNew->description.assign(text);
117 m_Menu.insert(iter, pNew);
126 ConsoleEntry *pNew = new ConsoleEntry;
127 pNew->command.assign(cmd);
128 pNew->description.assign(text);
129 m_Menu.push_back(pNew);
135 bool RootConsoleMenu::RemoveRootConsoleCommand(const char *cmd, IRootConsoleCommand *pHandler)
138 IRootConsoleCommand *object;
139 if (sm_trie_retrieve(m_pCommands, cmd, (void **)&object))
141 if (object != pHandler)
149 sm_trie_delete(m_pCommands, cmd);
151 List<ConsoleEntry *>::iterator iter;
152 ConsoleEntry *pEntry;
153 for (iter=m_Menu.begin(); iter!=m_Menu.end(); iter++)
156 if (pEntry->command.compare(cmd) == 0)
167 void RootConsoleMenu::DrawGenericOption(const char *cmd, const char *text)
170 size_t len, cmdlen = strlen(cmd);
172 len = UTIL_Format(buffer, sizeof(buffer), " %s", cmd);
175 size_t num = 16 - cmdlen;
176 for (size_t i = 0; i < num; i++)
180 len += snprintf(&buffer[len], sizeof(buffer) - len, " - %s", text);
181 ConsolePrint("%s", buffer);
185 extern void _IntExt_EnableYams();
187 void RootConsoleMenu::GotRootCmd()
189 unsigned int argnum = GetArgumentCount();
193 const char *cmd = GetArgument(1);
194 if (strcmp(cmd, "text") == 0)
196 _IntExt_EnableYams();
198 } else if (strcmp(cmd, "internal") == 0) {
201 const char *arg = GetArgument(2);
202 if (strcmp(arg, "1") == 0)
204 SM_ConfigsExecuted_Global();
205 } else if (strcmp(arg, "2") == 0) {
208 SM_ConfigsExecuted_Plugin(atoi(GetArgument(3)));
215 IRootConsoleCommand *pHandler;
216 if (sm_trie_retrieve(m_pCommands, cmd, (void **)&pHandler))
218 pHandler->OnRootConsoleCommand(cmd, argnum);
223 ConsolePrint("SourceMod Menu:");
224 ConsolePrint("Usage: sm <command> [arguments]");
226 List<ConsoleEntry *>::iterator iter;
227 ConsoleEntry *pEntry;
228 for (iter=m_Menu.begin(); iter!=m_Menu.end(); iter++)
231 DrawGenericOption(pEntry->command.c_str(), pEntry->description.c_str());
235 const char *RootConsoleMenu::GetArgument(unsigned int argno)
237 return engine->Cmd_Argv(argno);
240 const char *RootConsoleMenu::GetArguments()
242 return engine->Cmd_Args();
245 unsigned int RootConsoleMenu::GetArgumentCount()
247 return engine->Cmd_Argc();
250 void RootConsoleMenu::OnRootConsoleCommand(const char *cmd, unsigned int argcount)
252 if (strcmp(cmd, "credits") == 0)
254 ConsolePrint(" SourceMod was developed by AlliedModders, LLC.");
255 ConsolePrint(" Development would not have been possible without the following people:");
256 ConsolePrint(" David \"BAILOPAN\" Anderson, lead developer");
257 ConsolePrint(" Borja \"faluco\" Ferrer, Core developer");
258 ConsolePrint(" Scott \"Damaged Soul\" Ehlert, Core developer");
259 ConsolePrint(" Pavol \"PM OnoTo\" Marko, SourceHook developer");
260 ConsolePrint(" Special thanks to Viper of GameConnect");
261 ConsolePrint(" Special thanks to Mani of Mani-Admin-Plugin");
262 ConsolePrint(" http://www.sourcemod.net/");
263 } else if (strcmp(cmd, "version") == 0) {
264 ConsolePrint(" SourceMod Version Information:");
265 ConsolePrint(" SourceMod Version: %s", SVN_FULL_VERSION);
266 ConsolePrint(" JIT Version: %s, %s", g_pVM->GetVMName(), g_pVM->GetVersionString());
267 ConsolePrint(" JIT Settings: %s", g_pVM->GetCPUOptimizations());
268 ConsolePrint(" http://www.sourcemod.net/");
272 CON_COMMAND(sm, "SourceMod Menu")
274 g_RootMenu.GotRootCmd();
277 CON_COMMAND(sm_dump_handles, "Dumps Handle usage to a file for finding Handle leaks")
279 if (engine->Cmd_Argc() < 2)
281 g_RootMenu.ConsolePrint("Usage: sm_dump_handles <file>");
285 const char *arg = engine->Cmd_Argv(1);
286 FILE *fp = fopen(arg, "wt");
289 g_RootMenu.ConsolePrint("Could not find file \"%s\"", arg);
293 g_HandleSys.Dump(fp);