Redesigned how server commands work. The "plugins" command will be back soon.
authorDavid Anderson <dvander@alliedmods.net>
Wed Jan 17 06:49:59 2007 +0000 (2007-01-17)
changeset 308f0e65f92cb34
parent 307 cab87ea66ab1
child 309 51e67f50830e
Redesigned how server commands work. The "plugins" command will be back soon.
core/interfaces/IRootConsoleMenu.h
core/msvc8/sourcemod_mm.vcproj
core/sm_srvcmds.cpp
core/sm_srvcmds.h
core/sm_version.h
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/core/interfaces/IRootConsoleMenu.h	Wed Jan 17 06:49:59 2007 +0000
     1.3 @@ -0,0 +1,77 @@
     1.4 +#ifndef _INCLUDE_SOURCEMOD_ROOT_CONSOLE_MENU_H_
     1.5 +#define _INCLUDE_SOURCEMOD_ROOT_CONSOLE_MENU_H_
     1.6 +
     1.7 +/**
     1.8 + * @brief Note: This interface is not exposed.
     1.9 + * The reason should be obvious: we do not want users touching the "root" console menu.
    1.10 + */
    1.11 +
    1.12 +namespace SourceMod
    1.13 +{
    1.14 +	/**
    1.15 +	 * @brief Handles a root console menu action.
    1.16 +	 */
    1.17 +	class IRootConsoleCommand
    1.18 +	{
    1.19 +	public:
    1.20 +		virtual void OnRootConsoleCommand(const char *command, unsigned int argcount) =0;
    1.21 +	};
    1.22 +
    1.23 +	/**
    1.24 +	 * @brief Manages the root console menu.
    1.25 +	 */
    1.26 +	class IRootConsole
    1.27 +	{
    1.28 +	public:
    1.29 +		/**
    1.30 +		 * @brief Adds a root console command handler.  The command must be unique.
    1.31 +		 *
    1.32 +		 * @param cmd			String containing the console command.
    1.33 +		 * @param text			Description text.
    1.34 +		 * @param pHandler		An IRootConsoleCommand pointer to handle the command.
    1.35 +		 * @return				True on success, false on too many commands or duplicate command.
    1.36 +		 */
    1.37 +		virtual bool AddRootConsoleCommand(const char *cmd, const char *text, IRootConsoleCommand *pHandler) =0;
    1.38 +
    1.39 +		/**
    1.40 +		 * @brief Removes a root console command handler.
    1.41 +		 *
    1.42 +		 * @param cmd			String containing the console command.
    1.43 +		 * @param pHandler		An IRootConsoleCommand pointer for verification.
    1.44 +		 * @return				True on success, false otherwise.
    1.45 +		 */
    1.46 +		virtual bool RemoveRootConsoleCommand(const char *cmd, IRootConsoleCommand *pHandler) =0;
    1.47 +
    1.48 +		/**
    1.49 +		 * @brief Prints text back to the console.
    1.50 +		 *
    1.51 +		 * @param fmt			Format of string.
    1.52 +		 * @param ...			Format arguments.
    1.53 +		 */
    1.54 +		virtual void ConsolePrint(const char *fmt, ...) =0;
    1.55 +
    1.56 +		/**
    1.57 +		 * @brief Returns the string of an argument.
    1.58 +		 *
    1.59 +		 * @param argno			The index of the argument.
    1.60 +		 * @return				A string containing the argument, or nothing if invalid.
    1.61 +		 */
    1.62 +		virtual const char *GetArgument(unsigned int argno) =0;
    1.63 +
    1.64 +		/**
    1.65 +		 * @brief Returns the number of arguments.
    1.66 +		 *
    1.67 +		 * @return				Number of arguments.
    1.68 +		 */
    1.69 +		virtual unsigned int GetArgumentCount() =0;
    1.70 +
    1.71 +		/** 
    1.72 +		 * @brief Returns the entire argument string.
    1.73 +		 *
    1.74 +		 * @return				String containing all arguments.
    1.75 +		 */
    1.76 +		virtual const char *GetArguments() =0;
    1.77 +	};
    1.78 +};
    1.79 +
    1.80 +#endif //_INCLUDE_SOURCEMOD_ROOT_CONSOLE_MENU_H_
     2.1 --- a/core/msvc8/sourcemod_mm.vcproj	Wed Jan 17 06:49:40 2007 +0000
     2.2 +++ b/core/msvc8/sourcemod_mm.vcproj	Wed Jan 17 06:49:59 2007 +0000
     2.3 @@ -326,6 +326,10 @@
     2.4  			Name="Interfaces"
     2.5  			>
     2.6  			<File
     2.7 +				RelativePath="..\interfaces\IRootConsoleMenu.h"
     2.8 +				>
     2.9 +			</File>
    2.10 +			<File
    2.11  				RelativePath="..\interfaces\ITextParsers.h"
    2.12  				>
    2.13  			</File>
     3.1 --- a/core/sm_srvcmds.cpp	Wed Jan 17 06:49:40 2007 +0000
     3.2 +++ b/core/sm_srvcmds.cpp	Wed Jan 17 06:49:59 2007 +0000
     3.3 @@ -2,14 +2,39 @@
     3.4  #include "sm_version.h"
     3.5  #include "sm_stringutil.h"
     3.6  
     3.7 -ConVarAccessor g_ConCmdAccessor;
     3.8 +RootConsoleMenu g_RootMenu;
     3.9  
    3.10 -void ConVarAccessor::OnSourceModStartup(bool late)
    3.11 +RootConsoleMenu::RootConsoleMenu()
    3.12  {
    3.13 -	ConCommandBaseMgr::OneTimeInit(&g_ConCmdAccessor);
    3.14 +	m_pCommands = sm_trie_create();
    3.15  }
    3.16  
    3.17 -bool ConVarAccessor::RegisterConCommandBase(ConCommandBase *pCommand)
    3.18 +RootConsoleMenu::~RootConsoleMenu()
    3.19 +{
    3.20 +	sm_trie_destroy(m_pCommands);
    3.21 +
    3.22 +	List<ConsoleEntry *>::iterator iter;
    3.23 +	for (iter=m_Menu.begin(); iter!=m_Menu.end(); iter++)
    3.24 +	{
    3.25 +		delete (*iter);
    3.26 +	}
    3.27 +	m_Menu.clear();
    3.28 +}
    3.29 +
    3.30 +void RootConsoleMenu::OnSourceModStartup(bool late)
    3.31 +{
    3.32 +	ConCommandBaseMgr::OneTimeInit(this);
    3.33 +	AddRootConsoleCommand("version", "Display version information", this);
    3.34 +	AddRootConsoleCommand("credits", "Display credits listing", this);
    3.35 +}
    3.36 +
    3.37 +void RootConsoleMenu::OnSourceModShutdown()
    3.38 +{
    3.39 +	RemoveRootConsoleCommand("credits", this);
    3.40 +	RemoveRootConsoleCommand("version", this);
    3.41 +}
    3.42 +
    3.43 +bool RootConsoleMenu::RegisterConCommandBase(ConCommandBase *pCommand)
    3.44  {
    3.45  	META_REGCVAR(pCommand);
    3.46  
    3.47 @@ -38,234 +63,176 @@
    3.48  	}
    3.49  }
    3.50  
    3.51 -#define IS_STR_FILLED(var) (var[0] != '\0')
    3.52 -CON_COMMAND(sm, "SourceMod Menu")
    3.53 +void RootConsoleMenu::ConsolePrint(const char *fmt, ...)
    3.54 +{
    3.55 +	char buffer[512];
    3.56 +
    3.57 +	va_list ap;
    3.58 +	va_start(ap, fmt);
    3.59 +	size_t len = vsnprintf(buffer, sizeof(buffer), fmt, ap);
    3.60 +	va_end(ap);
    3.61 +
    3.62 +	if (len >= sizeof(buffer))
    3.63 +	{
    3.64 +		buffer[510] = '\n';
    3.65 +		buffer[511] = '\0';
    3.66 +	} else {
    3.67 +		buffer[len++] = '\n';
    3.68 +		buffer[len] = '\0';
    3.69 +	}
    3.70 +	
    3.71 +	META_CONPRINT(buffer);
    3.72 +}
    3.73 +
    3.74 +bool RootConsoleMenu::AddRootConsoleCommand(const char *cmd, const char *text, IRootConsoleCommand *pHandler)
    3.75  {
    3.76 -	int argnum = engine->Cmd_Argc();
    3.77 +	if (sm_trie_retrieve(m_pCommands, cmd, NULL))
    3.78 +	{
    3.79 +		return false;
    3.80 +	}
    3.81 +
    3.82 +	sm_trie_insert(m_pCommands, cmd, pHandler);
    3.83 +
    3.84 +	/* Sort this into the menu */
    3.85 +	List<ConsoleEntry *>::iterator iter = m_Menu.begin();
    3.86 +	ConsoleEntry *pEntry;
    3.87 +	bool inserted = false;
    3.88 +	while (iter != m_Menu.end())
    3.89 +	{
    3.90 +		pEntry = (*iter);
    3.91 +		if (strcmp(cmd, pEntry->command.c_str()) < 0)
    3.92 +		{
    3.93 +			ConsoleEntry *pNew = new ConsoleEntry;
    3.94 +			pNew->command.assign(cmd);
    3.95 +			pNew->description.assign(text);
    3.96 +			m_Menu.insert(iter, pNew);
    3.97 +			inserted = true;
    3.98 +			break;
    3.99 +		}
   3.100 +		iter++;
   3.101 +	}
   3.102 +
   3.103 +	if (!inserted)
   3.104 +	{
   3.105 +		ConsoleEntry *pNew = new ConsoleEntry;
   3.106 +		pNew->command.assign(cmd);
   3.107 +		pNew->description.assign(text);
   3.108 +		m_Menu.push_back(pNew);
   3.109 +	}
   3.110 +
   3.111 +	return true;
   3.112 +}
   3.113 +
   3.114 +bool RootConsoleMenu::RemoveRootConsoleCommand(const char *cmd, IRootConsoleCommand *pHandler)
   3.115 +{
   3.116 +	/* Sanity tests */
   3.117 +	IRootConsoleCommand *object;
   3.118 +	if (sm_trie_retrieve(m_pCommands, cmd, (void **)&object))
   3.119 +	{
   3.120 +		if (object != pHandler)
   3.121 +		{
   3.122 +			return false;
   3.123 +		}
   3.124 +	} else {
   3.125 +		return false;
   3.126 +	}
   3.127 +
   3.128 +	sm_trie_delete(m_pCommands, cmd);
   3.129 +
   3.130 +	List<ConsoleEntry *>::iterator iter;
   3.131 +	ConsoleEntry *pEntry;
   3.132 +	for (iter=m_Menu.begin(); iter!=m_Menu.end(); iter++)
   3.133 +	{
   3.134 +		pEntry = (*iter);
   3.135 +		if (pEntry->command.compare(cmd) == 0)
   3.136 +		{
   3.137 +			delete pEntry;
   3.138 +			m_Menu.erase(iter);
   3.139 +			break;
   3.140 +		}
   3.141 +	}
   3.142 +
   3.143 +	return true;
   3.144 +}
   3.145 +
   3.146 +void RootConsoleMenu::GotRootCmd()
   3.147 +{
   3.148 +	unsigned int argnum = GetArgumentCount();
   3.149  
   3.150  	if (argnum >= 2)
   3.151  	{
   3.152 -		const char *cmd = engine->Cmd_Argv(1);
   3.153 -		if (!strcmp("plugins", cmd))
   3.154 +		const char *cmd = GetArgument(1);
   3.155 +		IRootConsoleCommand *pHandler;
   3.156 +		if (sm_trie_retrieve(m_pCommands, cmd, (void **)&pHandler))
   3.157  		{
   3.158 -			if (argnum >= 3)
   3.159 -			{
   3.160 -				const char *cmd2 = engine->Cmd_Argv(2);
   3.161 -				if (!strcmp("list", cmd2))
   3.162 -				{
   3.163 -					char buffer[256];
   3.164 -					unsigned int id = 1;
   3.165 -					int plnum = g_PluginSys.GetPluginCount();
   3.166 -
   3.167 -					if (!plnum)
   3.168 -					{
   3.169 -						META_CONPRINT("[SM] No plugins loaded\n");
   3.170 -						return;
   3.171 -					} else {
   3.172 -						META_CONPRINTF("[SM] Displaying %d plugin%s:\n", g_PluginSys.GetPluginCount(), (plnum > 1) ? "s" : "");
   3.173 -					}
   3.174 -
   3.175 -					IPluginIterator *iter = g_PluginSys.GetPluginIterator();
   3.176 -					for (; iter->MorePlugins(); iter->NextPlugin(), id++)
   3.177 -					{
   3.178 -						IPlugin *pl = iter->GetPlugin();
   3.179 -						assert(pl->GetStatus() != Plugin_Created);
   3.180 -						int len = 0;
   3.181 -						const sm_plugininfo_t *info = pl->GetPublicInfo();
   3.182 -
   3.183 -						len += UTIL_Format(buffer, sizeof(buffer), "  %02d <%s>", id, StatusToStr(pl->GetStatus()));
   3.184 -						len += UTIL_Format(&buffer[len], sizeof(buffer)-len, " \"%s\"", (IS_STR_FILLED(info->name)) ? info->name : pl->GetFilename());
   3.185 -						if (IS_STR_FILLED(info->version))
   3.186 -						{
   3.187 -							len += UTIL_Format(&buffer[len], sizeof(buffer)-len, " (%s)", info->version);
   3.188 -						}
   3.189 -						if (IS_STR_FILLED(info->author))
   3.190 -						{
   3.191 -							UTIL_Format(&buffer[len], sizeof(buffer)-len, " by %s", info->author);
   3.192 -						}
   3.193 -						META_CONPRINTF("%s\n", buffer);
   3.194 -					}
   3.195 -
   3.196 -					iter->Release();
   3.197 -					return;
   3.198 -				} else if (!strcmp("load", cmd2)) {
   3.199 -					if (argnum < 4)
   3.200 -					{
   3.201 -						META_CONPRINT("Usage: sm plugins load <file>\n");
   3.202 -						return;
   3.203 -					}
   3.204 -
   3.205 -					char error[128];
   3.206 -					const char *filename = engine->Cmd_Argv(3);
   3.207 -					IPlugin *pl = g_PluginSys.LoadPlugin(filename, false, PluginType_MapUpdated, error, sizeof(error));
   3.208 -
   3.209 -					if (pl)
   3.210 -					{
   3.211 -						META_CONPRINTF("Loaded plugin %s successfully.\n", filename);
   3.212 -					} else {
   3.213 -						META_CONPRINTF("Plugin %s failed to load: %s.\n", filename, error);
   3.214 -					}
   3.215 -
   3.216 -					return;
   3.217 -				} else if (!strcmp("unload", cmd2)) {
   3.218 -					if (argnum < 4)
   3.219 -					{
   3.220 -						META_CONPRINT("Usage: sm plugins unload <#>\n");
   3.221 -						return;
   3.222 -					}
   3.223 -
   3.224 -					int id = 1;
   3.225 -					int num = atoi(engine->Cmd_Argv(3));
   3.226 -					if (num < 1 || num > (int)g_PluginSys.GetPluginCount())
   3.227 -					{
   3.228 -						META_CONPRINT("Plugin index not found.\n");
   3.229 -						return;
   3.230 -					}
   3.231 -
   3.232 -					IPluginIterator *iter = g_PluginSys.GetPluginIterator();
   3.233 -					for (; iter->MorePlugins() && id<num; iter->NextPlugin(), id++) {}
   3.234 -					IPlugin *pl = iter->GetPlugin();
   3.235 -
   3.236 -					char name[64];
   3.237 -					const sm_plugininfo_t *info = pl->GetPublicInfo();
   3.238 -					strcpy(name, (IS_STR_FILLED(info->name)) ? info->name : pl->GetFilename());
   3.239 -
   3.240 -					if (g_PluginSys.UnloadPlugin(pl))
   3.241 -					{
   3.242 -						META_CONPRINTF("Plugin %s unloaded successfully.\n", name);
   3.243 -					} else {
   3.244 -						META_CONPRINTF("Failed to unload plugin %s.\n", name);
   3.245 -					}
   3.246 -
   3.247 -					iter->Release();
   3.248 -					return;
   3.249 -				} else if (!strcmp("info", cmd2)) {
   3.250 -					if (argnum < 4)
   3.251 -					{
   3.252 -						META_CONPRINT("Usage: sm plugins info <#>\n");
   3.253 -						return;
   3.254 -					}
   3.255 -
   3.256 -					int id = 1;
   3.257 -					int num = atoi(engine->Cmd_Argv(3));
   3.258 -					if (num < 1 || num > (int)g_PluginSys.GetPluginCount())
   3.259 -					{
   3.260 -						META_CONPRINT("Plugin index not found.\n");
   3.261 -						return;
   3.262 -					}
   3.263 -
   3.264 -					IPluginIterator *iter = g_PluginSys.GetPluginIterator();
   3.265 -					for (; iter->MorePlugins() && id<num; iter->NextPlugin(), id++) {}
   3.266 -
   3.267 -					IPlugin *pl = iter->GetPlugin();
   3.268 -					const sm_plugininfo_t *info = pl->GetPublicInfo();
   3.269 -
   3.270 -					META_CONPRINTF("  Filename: %s\n", pl->GetFilename());
   3.271 -					if (IS_STR_FILLED(info->name))
   3.272 -					{
   3.273 -						META_CONPRINTF("  Title: %s\n", info->name);
   3.274 -					}
   3.275 -					if (IS_STR_FILLED(info->author))
   3.276 -					{
   3.277 -						META_CONPRINTF("  Author: %s\n", info->author);
   3.278 -					}
   3.279 -					if (IS_STR_FILLED(info->version))
   3.280 -					{
   3.281 -						META_CONPRINTF("  Version: %s\n", info->version);
   3.282 -					}
   3.283 -					if (IS_STR_FILLED(info->description))
   3.284 -					{
   3.285 -						META_CONPRINTF("  Description: %s\n", info->description);
   3.286 -					}
   3.287 -					if (IS_STR_FILLED(info->url))
   3.288 -					{
   3.289 -						META_CONPRINTF("  URL: %s\n", info->url);
   3.290 -					}
   3.291 -					//:TODO: write if it's in debug mode, or do it inside LIST ?
   3.292 -
   3.293 -					iter->Release();
   3.294 -					return;
   3.295 -				} else if (!strcmp("debug", cmd2)) {
   3.296 -					if (argnum < 5)
   3.297 -					{
   3.298 -						META_CONPRINT("Usage: sm plugins debug <#> [on|off]\n");
   3.299 -						return;
   3.300 -					}
   3.301 -
   3.302 -					int num = atoi(engine->Cmd_Argv(3));
   3.303 -					if (num < 1 || num > (int)g_PluginSys.GetPluginCount())
   3.304 -					{
   3.305 -						META_CONPRINT("Plugin index not found.\n");
   3.306 -						return;
   3.307 -					}
   3.308 -
   3.309 -					int res;
   3.310 -					char *mode = engine->Cmd_Argv(4);
   3.311 -					if ((res=strcmp("on", mode)) && strcmp("off", mode))
   3.312 -					{
   3.313 -						META_CONPRINT("The only possible options are on and off.\n");
   3.314 -						return;
   3.315 -					}
   3.316 -
   3.317 -					bool debug;
   3.318 -					if (!res)
   3.319 -					{
   3.320 -						debug = true;
   3.321 -					} else {
   3.322 -						debug = false;
   3.323 -					}
   3.324 -
   3.325 -					CPlugin *pl = g_PluginSys.GetPluginByOrder(num);
   3.326 -					if (debug && pl->IsDebugging())
   3.327 -					{
   3.328 -						META_CONPRINT("This plugin is already in debug mode.\n");
   3.329 -						return;
   3.330 -					} else if (!debug && !pl->IsDebugging()) {
   3.331 -						META_CONPRINT("Debug mode is already disabled in this plugin.\n");
   3.332 -						return;
   3.333 -					}
   3.334 -
   3.335 -					if (pl->ToggleDebugMode(debug))
   3.336 -					{
   3.337 -						META_CONPRINTF("Successfully toggled debug mode on plugin %s.\n", pl->GetFilename());
   3.338 -						return;
   3.339 -					} else {
   3.340 -						/* :TODO: ... we should be getting an actual error message here */
   3.341 -						META_CONPRINTF("Could not toggle debug mode on plugin %s.\n", pl->GetFilename());
   3.342 -						return;
   3.343 -					}
   3.344 -				}
   3.345 -			}
   3.346 -
   3.347 -			META_CONPRINT(" SourceMod Plugin Menu:\n");
   3.348 -			META_CONPRINT("    list   - Show loaded plugins\n");
   3.349 -			META_CONPRINT("    load   - Load a plugin\n");
   3.350 -			META_CONPRINT("    unload - Unload a plugin\n");
   3.351 -			META_CONPRINT("    info   - Information about a plugin\n");
   3.352 -			META_CONPRINT("    debug  - Toggles debug mode in a plugin\n");
   3.353 -			return;
   3.354 -		} else if (!strcmp("credits", cmd)) {
   3.355 -			META_CONPRINT(" SourceMod was developed by AlliedModders, LLC.\n");
   3.356 -			META_CONPRINT(" Development would not have been possible without the following people:\n");
   3.357 -			META_CONPRINT("  David \"BAILOPAN\" Anderson, lead developer\n");
   3.358 -			META_CONPRINT("  Borja \"faluco\" Ferrer, Core developer\n");
   3.359 -			META_CONPRINT("  Scott \"Damaged Soul\" Ehlert, SourceMM developer\n");
   3.360 -			META_CONPRINT("  Pavol \"PM OnoTo\" Marko, SourceHook developer\n");
   3.361 -			META_CONPRINT(" Special thanks to Viper of GameConnect, and Mani\n");
   3.362 -			META_CONPRINT(" http://www.sourcemod.net/\n");
   3.363 -			return;
   3.364 -		} else if (!strcmp("version", cmd)) {
   3.365 -			META_CONPRINT(" SourceMod Version Information:\n");
   3.366 -			META_CONPRINTF("    SourceMod Version: \"%s\"\n", SOURCEMOD_VERSION);
   3.367 -			META_CONPRINTF("    JIT Version: %s (%s)\n", g_pVM->GetVMName(), g_pVM->GetVersionString());
   3.368 -			META_CONPRINTF("    JIT Settings: %s\n", g_pVM->GetCPUOptimizations());
   3.369 -			META_CONPRINT("    http://www.sourcemod.net/\n");
   3.370 +			pHandler->OnRootConsoleCommand(cmd, argnum);
   3.371  			return;
   3.372  		}
   3.373  	}
   3.374 -	META_CONPRINT(" SourceMod Menu:\n");
   3.375 -	META_CONPRINT(" Usage: sm <command> [arguments]\n");
   3.376 -	META_CONPRINT("    credits - Credits listing\n");
   3.377 -	META_CONPRINT("    plugins - Plugins menu\n");
   3.378 -	META_CONPRINT("    version - Display version information\n");
   3.379 +
   3.380 +	ConsolePrint("SourceMod Menu:");
   3.381 +	ConsolePrint("Usage: sm <command> [arguments]");
   3.382 +
   3.383 +	List<ConsoleEntry *>::iterator iter;
   3.384 +	ConsoleEntry *pEntry;
   3.385 +	char buffer[255];
   3.386 +	size_t len;
   3.387 +	for (iter=m_Menu.begin(); iter!=m_Menu.end(); iter++)
   3.388 +	{
   3.389 +		pEntry = (*iter);
   3.390 +		len = snprintf(buffer, sizeof(buffer), "    %s", pEntry->command.c_str());
   3.391 +		if (pEntry->command.size() < 16)
   3.392 +		{
   3.393 +			size_t num = 16 - pEntry->command.size();
   3.394 +			for (size_t i = 0; i < num; i++)
   3.395 +			{
   3.396 +				buffer[len++] = ' ';
   3.397 +			}
   3.398 +		}
   3.399 +		len += snprintf(&buffer[len], sizeof(buffer) - len, " - %s", pEntry->description.c_str());
   3.400 +		ConsolePrint("%s", buffer);
   3.401 +	}
   3.402 +}
   3.403 +
   3.404 +const char *RootConsoleMenu::GetArgument(unsigned int argno)
   3.405 +{
   3.406 +	return engine->Cmd_Argv(argno);
   3.407 +}
   3.408 +
   3.409 +const char *RootConsoleMenu::GetArguments()
   3.410 +{
   3.411 +	return engine->Cmd_Args();
   3.412  }
   3.413 +
   3.414 +unsigned int RootConsoleMenu::GetArgumentCount()
   3.415 +{
   3.416 +	return engine->Cmd_Argc();
   3.417 +}
   3.418 +
   3.419 +void RootConsoleMenu::OnRootConsoleCommand(const char *cmd, unsigned int argcount)
   3.420 +{
   3.421 +	if (strcmp(cmd, "credits") == 0)
   3.422 +	{
   3.423 +		ConsolePrint(" SourceMod was developed by AlliedModders, LLC.");
   3.424 +		ConsolePrint(" Development would not have been possible without the following people:");
   3.425 +		ConsolePrint("  David \"BAILOPAN\" Anderson, lead developer");
   3.426 +		ConsolePrint("  Borja \"faluco\" Ferrer, Core developer");
   3.427 +		ConsolePrint("  Scott \"Damaged Soul\" Ehlert, SourceMM developer");
   3.428 +		ConsolePrint("  Pavol \"PM OnoTo\" Marko, SourceHook developer");
   3.429 +		ConsolePrint(" Special thanks to Viper of GameConnect");
   3.430 +		ConsolePrint(" Special thanks to Mani of Mani-Admin-Plugin");
   3.431 +		ConsolePrint(" http://www.sourcemod.net/");
   3.432 +	} else if (strcmp(cmd, "version") == 0) {
   3.433 +		ConsolePrint(" SourceMod Version Information:");
   3.434 +		ConsolePrint("    SourceMod Version: %s", SOURCEMOD_VERSION);
   3.435 +		ConsolePrint("    JIT Version: %s, %s", g_pVM->GetVMName(), g_pVM->GetVersionString());
   3.436 +		ConsolePrint("    JIT Settings: %s", g_pVM->GetCPUOptimizations());
   3.437 +		ConsolePrint("    http://www.sourcemod.net/");
   3.438 +	}
   3.439 +}
   3.440 +
   3.441 +#define IS_STR_FILLED(var) (var[0] != '\0')
   3.442 +CON_COMMAND(sm, "SourceMod Menu")
   3.443 +{
   3.444 +	g_RootMenu.GotRootCmd();
   3.445 +}
     4.1 --- a/core/sm_srvcmds.h	Wed Jan 17 06:49:40 2007 +0000
     4.2 +++ b/core/sm_srvcmds.h	Wed Jan 17 06:49:59 2007 +0000
     4.3 @@ -2,20 +2,53 @@
     4.4  #define _INCLUDE_SOURCEMOD_SERVERCOMMANDS_H_
     4.5  
     4.6  #include "sourcemod.h"
     4.7 +#include <IRootConsoleMenu.h>
     4.8  #include "PluginSys.h"
     4.9  #include "sourcemm_api.h"
    4.10  #include <convar.h>
    4.11 +#include <sh_list.h>
    4.12 +#include <sh_string.h>
    4.13 +#include "sm_trie.h"
    4.14  
    4.15  using namespace SourceMod;
    4.16 +using namespace SourceHook;
    4.17  
    4.18 -class ConVarAccessor : 
    4.19 -	public IConCommandBaseAccessor,
    4.20 -	public SMGlobalClass
    4.21 +struct ConsoleEntry
    4.22  {
    4.23 -public: // IConCommandBaseAccessor
    4.24 -	virtual bool RegisterConCommandBase(ConCommandBase *pCommand);
    4.25 -public: // SMGlobalClass
    4.26 -	virtual void OnSourceModStartup(bool late);
    4.27 +	String command;
    4.28 +	String description;
    4.29  };
    4.30  
    4.31 +class RootConsoleMenu : 
    4.32 +	public IConCommandBaseAccessor,
    4.33 +	public SMGlobalClass,
    4.34 +	public IRootConsoleCommand,
    4.35 +	public IRootConsole
    4.36 +{
    4.37 +public:
    4.38 +	RootConsoleMenu();
    4.39 +	~RootConsoleMenu();
    4.40 +public: //IConCommandBaseAccessor
    4.41 +	bool RegisterConCommandBase(ConCommandBase *pCommand);
    4.42 +public: //SMGlobalClass
    4.43 +	void OnSourceModStartup(bool late);
    4.44 +	void OnSourceModShutdown();
    4.45 +public: //IRootConsoleCommand
    4.46 +	void OnRootConsoleCommand(const char *cmd, unsigned int argcount);
    4.47 +public: //IRootConsole
    4.48 +	bool AddRootConsoleCommand(const char *cmd, const char *text, IRootConsoleCommand *pHandler);
    4.49 +	bool RemoveRootConsoleCommand(const char *cmd, IRootConsoleCommand *pHandler);
    4.50 +	void ConsolePrint(const char *fmt, ...);
    4.51 +	const char *GetArgument(unsigned int argno);
    4.52 +	unsigned int GetArgumentCount();
    4.53 +	const char *GetArguments();
    4.54 +public:
    4.55 +	void GotRootCmd();
    4.56 +private:
    4.57 +	Trie *m_pCommands;
    4.58 +	List<ConsoleEntry *> m_Menu;
    4.59 +};
    4.60 +
    4.61 +extern RootConsoleMenu g_RootMenu;
    4.62 +
    4.63  #endif //_INCLUDE_SOURCEMOD_SERVERCOMMANDS_H_
     5.1 --- a/core/sm_version.h	Wed Jan 17 06:49:40 2007 +0000
     5.2 +++ b/core/sm_version.h	Wed Jan 17 06:49:59 2007 +0000
     5.3 @@ -5,10 +5,11 @@
     5.4   * @file Contains SourceMod version information.
     5.5   */
     5.6  
     5.7 -#define SOURCEMOD_VERSION	"1.0.0.$Id$"
     5.8  #define SOURCEMOD_V_MAJOR	1
     5.9  #define SOURCEMOD_V_MINOR	0
    5.10  #define SOURCEMOD_V_REV		0
    5.11 -#define SOURCEMOD_V_BUILD	$Id$
    5.12 +#define SOURCEMOD_V_BUILD	308
    5.13 +
    5.14 +#define SOURCEMOD_VERSION	"1.0.0.308"
    5.15  
    5.16  #endif //_INCLUDE_SOURCEMOD_VERSION_H_