3 * =============================================================================
5 * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
6 * =============================================================================
8 * This program is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, version 3.0, as published by the
10 * Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
20 * As a special exception, AlliedModders LLC gives you permission to link the
21 * code of this program (as well as its derivative works) to "Half-Life 2," the
22 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
23 * by the Valve Corporation. You must obey the GNU General Public License in
24 * all respects for all other code used. Additionally, AlliedModders LLC grants
25 * this exception to all derivative works. AlliedModders LLC defines further
26 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
27 * or <http://www.sourcemod.net/license.php>.
32 #include "sm_srvcmds.h"
33 #include "sm_version.h"
34 #include "sm_stringutil.h"
35 #include "HandleSys.h"
36 #include "CoreConfig.h"
38 RootConsoleMenu g_RootMenu;
40 ConVar sourcemod_version("sourcemod_version", SVN_FULL_VERSION, FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY, "SourceMod Version");
42 RootConsoleMenu::RootConsoleMenu()
44 m_pCommands = sm_trie_create();
45 m_CfgExecDone = false;
48 RootConsoleMenu::~RootConsoleMenu()
50 sm_trie_destroy(m_pCommands);
52 List<ConsoleEntry *>::iterator iter;
53 for (iter=m_Menu.begin(); iter!=m_Menu.end(); iter++)
60 extern void _IntExt_OnHostnameChanged(ConVar *pConVar, char const *oldValue);
62 void RootConsoleMenu::OnSourceModStartup(bool late)
64 ConCommandBaseMgr::OneTimeInit(this);
65 AddRootConsoleCommand("version", "Display version information", this);
66 AddRootConsoleCommand("credits", "Display credits listing", this);
68 ConVar *pHost = icvar->FindVar("hostname");
69 pHost->InstallChangeCallback(_IntExt_OnHostnameChanged);
72 void RootConsoleMenu::OnSourceModShutdown()
74 RemoveRootConsoleCommand("credits", this);
75 RemoveRootConsoleCommand("version", this);
78 bool RootConsoleMenu::RegisterConCommandBase(ConCommandBase *pCommand)
80 META_REGCVAR(pCommand);
82 /* Override values of convars created by SourceMod convar manager if specified on command line */
83 const char *cmdLineValue = icvar->GetCommandLineValue(pCommand->GetName());
84 if (cmdLineValue && !pCommand->IsCommand())
86 static_cast<ConVar *>(pCommand)->SetValue(cmdLineValue);
92 void RootConsoleMenu::ConsolePrint(const char *fmt, ...)
98 size_t len = vsnprintf(buffer, sizeof(buffer), fmt, ap);
101 if (len >= sizeof(buffer) - 1)
106 buffer[len++] = '\n';
110 META_CONPRINT(buffer);
113 bool RootConsoleMenu::AddRootConsoleCommand(const char *cmd, const char *text, IRootConsoleCommand *pHandler)
115 if (sm_trie_retrieve(m_pCommands, cmd, NULL))
120 sm_trie_insert(m_pCommands, cmd, pHandler);
122 /* Sort this into the menu */
123 List<ConsoleEntry *>::iterator iter = m_Menu.begin();
124 ConsoleEntry *pEntry;
125 bool inserted = false;
126 while (iter != m_Menu.end())
129 if (strcmp(cmd, pEntry->command.c_str()) < 0)
131 ConsoleEntry *pNew = new ConsoleEntry;
132 pNew->command.assign(cmd);
133 pNew->description.assign(text);
134 m_Menu.insert(iter, pNew);
143 ConsoleEntry *pNew = new ConsoleEntry;
144 pNew->command.assign(cmd);
145 pNew->description.assign(text);
146 m_Menu.push_back(pNew);
152 bool RootConsoleMenu::RemoveRootConsoleCommand(const char *cmd, IRootConsoleCommand *pHandler)
155 IRootConsoleCommand *object;
156 if (sm_trie_retrieve(m_pCommands, cmd, (void **)&object))
158 if (object != pHandler)
166 sm_trie_delete(m_pCommands, cmd);
168 List<ConsoleEntry *>::iterator iter;
169 ConsoleEntry *pEntry;
170 for (iter=m_Menu.begin(); iter!=m_Menu.end(); iter++)
173 if (pEntry->command.compare(cmd) == 0)
184 void RootConsoleMenu::DrawGenericOption(const char *cmd, const char *text)
187 size_t len, cmdlen = strlen(cmd);
189 len = UTIL_Format(buffer, sizeof(buffer), " %s", cmd);
192 size_t num = 16 - cmdlen;
193 for (size_t i = 0; i < num; i++)
197 len += snprintf(&buffer[len], sizeof(buffer) - len, " - %s", text);
198 ConsolePrint("%s", buffer);
202 extern void _IntExt_EnableYams();
204 void RootConsoleMenu::GotRootCmd()
206 unsigned int argnum = GetArgumentCount();
210 const char *cmd = GetArgument(1);
211 if (strcmp(cmd, "text") == 0)
213 _IntExt_EnableYams();
215 } else if (strcmp(cmd, "internal") == 0) {
218 const char *arg = GetArgument(2);
219 if (strcmp(arg, "1") == 0)
221 SM_ConfigsExecuted_Global();
222 } else if (strcmp(arg, "2") == 0) {
225 SM_ConfigsExecuted_Plugin(atoi(GetArgument(3)));
232 IRootConsoleCommand *pHandler;
233 if (sm_trie_retrieve(m_pCommands, cmd, (void **)&pHandler))
235 pHandler->OnRootConsoleCommand(cmd, argnum);
240 ConsolePrint("SourceMod Menu:");
241 ConsolePrint("Usage: sm <command> [arguments]");
243 List<ConsoleEntry *>::iterator iter;
244 ConsoleEntry *pEntry;
245 for (iter=m_Menu.begin(); iter!=m_Menu.end(); iter++)
248 DrawGenericOption(pEntry->command.c_str(), pEntry->description.c_str());
252 const char *RootConsoleMenu::GetArgument(unsigned int argno)
254 return engine->Cmd_Argv(argno);
257 const char *RootConsoleMenu::GetArguments()
259 return engine->Cmd_Args();
262 unsigned int RootConsoleMenu::GetArgumentCount()
264 return engine->Cmd_Argc();
267 void RootConsoleMenu::OnRootConsoleCommand(const char *cmd, unsigned int argcount)
269 if (strcmp(cmd, "credits") == 0)
271 ConsolePrint(" SourceMod was developed by AlliedModders, LLC.");
272 ConsolePrint(" Development would not have been possible without the following people:");
273 ConsolePrint(" David \"BAILOPAN\" Anderson, lead developer");
274 ConsolePrint(" Borja \"faluco\" Ferrer, Core developer");
275 ConsolePrint(" Scott \"Damaged Soul\" Ehlert, Core developer");
276 ConsolePrint(" Pavol \"PM OnoTo\" Marko, SourceHook developer");
277 ConsolePrint(" Special thanks to Viper of GameConnect");
278 ConsolePrint(" Special thanks to Mani of Mani-Admin-Plugin");
279 ConsolePrint(" http://www.sourcemod.net/");
280 } else if (strcmp(cmd, "version") == 0) {
281 ConsolePrint(" SourceMod Version Information:");
282 ConsolePrint(" SourceMod Version: %s", SVN_FULL_VERSION);
283 ConsolePrint(" JIT Version: %s, %s", g_pVM->GetVMName(), g_pVM->GetVersionString());
284 ConsolePrint(" JIT Settings: %s", g_pVM->GetCPUOptimizations());
285 ConsolePrint(" http://www.sourcemod.net/");
289 CON_COMMAND(sm, "SourceMod Menu")
291 g_RootMenu.GotRootCmd();
294 CON_COMMAND(sm_dump_handles, "Dumps Handle usage to a file for finding Handle leaks")
296 if (engine->Cmd_Argc() < 2)
298 g_RootMenu.ConsolePrint("Usage: sm_dump_handles <file>");
302 const char *arg = engine->Cmd_Argv(1);
303 FILE *fp = fopen(arg, "wt");
306 g_RootMenu.ConsolePrint("Could not find file \"%s\"", arg);
310 g_HandleSys.Dump(fp);