core/sm_srvcmds.cpp
author David Anderson <dvander@alliedmods.net>
Tue Jul 03 20:46:17 2007 +0000 (2007-07-03)
changeset 1036 2a073d5b3454
parent 978 54782a83a1ef
child 1231 17badaf66ce4
permissions -rw-r--r--
added amb505
     1 /**
     2  * vim: set ts=4 :
     3  * ===============================================================
     4  * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
     5  * ===============================================================
     6  *
     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
    11  *
    12  * Version: $Id$
    13  */
    14 
    15 #include "sm_srvcmds.h"
    16 #include "sm_version.h"
    17 #include "sm_stringutil.h"
    18 #include "HandleSys.h"
    19 #include "CoreConfig.h"
    20 
    21 RootConsoleMenu g_RootMenu;
    22 
    23 ConVar sourcemod_version("sourcemod_version", SVN_FULL_VERSION, FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY, "SourceMod Version");
    24 
    25 RootConsoleMenu::RootConsoleMenu()
    26 {
    27 	m_pCommands = sm_trie_create();
    28 	m_CfgExecDone = false;
    29 }
    30 
    31 RootConsoleMenu::~RootConsoleMenu()
    32 {
    33 	sm_trie_destroy(m_pCommands);
    34 
    35 	List<ConsoleEntry *>::iterator iter;
    36 	for (iter=m_Menu.begin(); iter!=m_Menu.end(); iter++)
    37 	{
    38 		delete (*iter);
    39 	}
    40 	m_Menu.clear();
    41 }
    42 
    43 extern void _IntExt_OnHostnameChanged(ConVar *pConVar, char const *oldValue);
    44 
    45 void RootConsoleMenu::OnSourceModStartup(bool late)
    46 {
    47 	ConCommandBaseMgr::OneTimeInit(this);
    48 	AddRootConsoleCommand("version", "Display version information", this);
    49 	AddRootConsoleCommand("credits", "Display credits listing", this);
    50 
    51 	ConVar *pHost = icvar->FindVar("hostname");
    52 	pHost->InstallChangeCallback(_IntExt_OnHostnameChanged);
    53 }
    54 
    55 void RootConsoleMenu::OnSourceModShutdown()
    56 {
    57 	RemoveRootConsoleCommand("credits", this);
    58 	RemoveRootConsoleCommand("version", this);
    59 }
    60 
    61 bool RootConsoleMenu::RegisterConCommandBase(ConCommandBase *pCommand)
    62 {
    63 	META_REGCVAR(pCommand);
    64 
    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())
    68 	{
    69 		static_cast<ConVar *>(pCommand)->SetValue(cmdLineValue);
    70 	}
    71 
    72 	return true;
    73 }
    74 
    75 void RootConsoleMenu::ConsolePrint(const char *fmt, ...)
    76 {
    77 	char buffer[512];
    78 
    79 	va_list ap;
    80 	va_start(ap, fmt);
    81 	size_t len = vsnprintf(buffer, sizeof(buffer), fmt, ap);
    82 	va_end(ap);
    83 
    84 	if (len >= sizeof(buffer) - 1)
    85 	{
    86 		buffer[510] = '\n';
    87 		buffer[511] = '\0';
    88 	} else {
    89 		buffer[len++] = '\n';
    90 		buffer[len] = '\0';
    91 	}
    92 	
    93 	META_CONPRINT(buffer);
    94 }
    95 
    96 bool RootConsoleMenu::AddRootConsoleCommand(const char *cmd, const char *text, IRootConsoleCommand *pHandler)
    97 {
    98 	if (sm_trie_retrieve(m_pCommands, cmd, NULL))
    99 	{
   100 		return false;
   101 	}
   102 
   103 	sm_trie_insert(m_pCommands, cmd, pHandler);
   104 
   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())
   110 	{
   111 		pEntry = (*iter);
   112 		if (strcmp(cmd, pEntry->command.c_str()) < 0)
   113 		{
   114 			ConsoleEntry *pNew = new ConsoleEntry;
   115 			pNew->command.assign(cmd);
   116 			pNew->description.assign(text);
   117 			m_Menu.insert(iter, pNew);
   118 			inserted = true;
   119 			break;
   120 		}
   121 		iter++;
   122 	}
   123 
   124 	if (!inserted)
   125 	{
   126 		ConsoleEntry *pNew = new ConsoleEntry;
   127 		pNew->command.assign(cmd);
   128 		pNew->description.assign(text);
   129 		m_Menu.push_back(pNew);
   130 	}
   131 
   132 	return true;
   133 }
   134 
   135 bool RootConsoleMenu::RemoveRootConsoleCommand(const char *cmd, IRootConsoleCommand *pHandler)
   136 {
   137 	/* Sanity tests */
   138 	IRootConsoleCommand *object;
   139 	if (sm_trie_retrieve(m_pCommands, cmd, (void **)&object))
   140 	{
   141 		if (object != pHandler)
   142 		{
   143 			return false;
   144 		}
   145 	} else {
   146 		return false;
   147 	}
   148 
   149 	sm_trie_delete(m_pCommands, cmd);
   150 
   151 	List<ConsoleEntry *>::iterator iter;
   152 	ConsoleEntry *pEntry;
   153 	for (iter=m_Menu.begin(); iter!=m_Menu.end(); iter++)
   154 	{
   155 		pEntry = (*iter);
   156 		if (pEntry->command.compare(cmd) == 0)
   157 		{
   158 			delete pEntry;
   159 			m_Menu.erase(iter);
   160 			break;
   161 		}
   162 	}
   163 
   164 	return true;
   165 }
   166 
   167 void RootConsoleMenu::DrawGenericOption(const char *cmd, const char *text)
   168 {
   169 	char buffer[255];
   170 	size_t len, cmdlen = strlen(cmd);
   171 
   172 	len = UTIL_Format(buffer, sizeof(buffer), "    %s", cmd);
   173 	if (cmdlen < 16)
   174 	{
   175 		size_t num = 16 - cmdlen;
   176 		for (size_t i = 0; i < num; i++)
   177 		{
   178 			buffer[len++] = ' ';
   179 		}
   180 		len += snprintf(&buffer[len], sizeof(buffer) - len, " - %s", text);
   181 		ConsolePrint("%s", buffer);
   182 	}
   183 }
   184 
   185 extern void _IntExt_EnableYams();
   186 
   187 void RootConsoleMenu::GotRootCmd()
   188 {
   189 	unsigned int argnum = GetArgumentCount();
   190 
   191 	if (argnum >= 2)
   192 	{
   193 		const char *cmd = GetArgument(1);
   194 		if (strcmp(cmd, "text") == 0)
   195 		{
   196 			_IntExt_EnableYams();
   197 			return;
   198 		} else if (strcmp(cmd, "internal") == 0) {
   199 			if (argnum >= 3)
   200 			{
   201 				const char *arg = GetArgument(2);
   202 				if (strcmp(arg, "1") == 0)
   203 				{
   204 					SM_ConfigsExecuted_Global();
   205 				} else if (strcmp(arg, "2") == 0) {
   206 					if (argnum >= 4)
   207 					{
   208 						SM_ConfigsExecuted_Plugin(atoi(GetArgument(3)));
   209 					}
   210 				}
   211 			}
   212 			return;
   213 		}
   214 
   215 		IRootConsoleCommand *pHandler;
   216 		if (sm_trie_retrieve(m_pCommands, cmd, (void **)&pHandler))
   217 		{
   218 			pHandler->OnRootConsoleCommand(cmd, argnum);
   219 			return;
   220 		}
   221 	}
   222 
   223 	ConsolePrint("SourceMod Menu:");
   224 	ConsolePrint("Usage: sm <command> [arguments]");
   225 
   226 	List<ConsoleEntry *>::iterator iter;
   227 	ConsoleEntry *pEntry;
   228 	for (iter=m_Menu.begin(); iter!=m_Menu.end(); iter++)
   229 	{
   230 		pEntry = (*iter);
   231 		DrawGenericOption(pEntry->command.c_str(), pEntry->description.c_str());
   232 	}
   233 }
   234 
   235 const char *RootConsoleMenu::GetArgument(unsigned int argno)
   236 {
   237 	return engine->Cmd_Argv(argno);
   238 }
   239 
   240 const char *RootConsoleMenu::GetArguments()
   241 {
   242 	return engine->Cmd_Args();
   243 }
   244 
   245 unsigned int RootConsoleMenu::GetArgumentCount()
   246 {
   247 	return engine->Cmd_Argc();
   248 }
   249 
   250 void RootConsoleMenu::OnRootConsoleCommand(const char *cmd, unsigned int argcount)
   251 {
   252 	if (strcmp(cmd, "credits") == 0)
   253 	{
   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/");
   269 	}
   270 }
   271 
   272 CON_COMMAND(sm, "SourceMod Menu")
   273 {
   274 	g_RootMenu.GotRootCmd();
   275 }
   276 
   277 CON_COMMAND(sm_dump_handles, "Dumps Handle usage to a file for finding Handle leaks")
   278 {
   279 	if (engine->Cmd_Argc() < 2)
   280 	{
   281 		g_RootMenu.ConsolePrint("Usage: sm_dump_handles <file>");
   282 		return;
   283 	}
   284 
   285 	const char *arg = engine->Cmd_Argv(1);
   286 	FILE *fp = fopen(arg, "wt");
   287 	if (!fp)
   288 	{
   289 		g_RootMenu.ConsolePrint("Could not find file \"%s\"", arg);
   290 		return;
   291 	}
   292 
   293 	g_HandleSys.Dump(fp);
   294 
   295 	fclose(fp);
   296 }