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
dvander@370
     1
/**
ds@653
     2
 * vim: set ts=4 :
dvander@370
     3
 * ===============================================================
dvander@370
     4
 * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
dvander@370
     5
 * ===============================================================
dvander@370
     6
 *
dvander@370
     7
 * This file is not open source and may not be copied without explicit
dvander@370
     8
 * written permission of AlliedModders LLC.  This file may not be redistributed 
dvander@370
     9
 * in whole or significant part.
dvander@370
    10
 * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
dvander@370
    11
 *
dvander@370
    12
 * Version: $Id$
dvander@370
    13
 */
dvander@370
    14
faluco@216
    15
#include "sm_srvcmds.h"
faluco@270
    16
#include "sm_version.h"
faluco@274
    17
#include "sm_stringutil.h"
dvander@900
    18
#include "HandleSys.h"
dvander@978
    19
#include "CoreConfig.h"
faluco@216
    20
dvander@308
    21
RootConsoleMenu g_RootMenu;
faluco@216
    22
dvander@566
    23
ConVar sourcemod_version("sourcemod_version", SVN_FULL_VERSION, FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY, "SourceMod Version");
dvander@524
    24
dvander@308
    25
RootConsoleMenu::RootConsoleMenu()
faluco@216
    26
{
dvander@308
    27
	m_pCommands = sm_trie_create();
dvander@978
    28
	m_CfgExecDone = false;
faluco@216
    29
}
faluco@216
    30
dvander@308
    31
RootConsoleMenu::~RootConsoleMenu()
dvander@308
    32
{
dvander@308
    33
	sm_trie_destroy(m_pCommands);
dvander@308
    34
dvander@308
    35
	List<ConsoleEntry *>::iterator iter;
dvander@308
    36
	for (iter=m_Menu.begin(); iter!=m_Menu.end(); iter++)
dvander@308
    37
	{
dvander@308
    38
		delete (*iter);
dvander@308
    39
	}
dvander@308
    40
	m_Menu.clear();
dvander@308
    41
}
dvander@308
    42
ds@627
    43
extern void _IntExt_OnHostnameChanged(ConVar *pConVar, char const *oldValue);
ds@627
    44
dvander@308
    45
void RootConsoleMenu::OnSourceModStartup(bool late)
dvander@308
    46
{
dvander@308
    47
	ConCommandBaseMgr::OneTimeInit(this);
dvander@308
    48
	AddRootConsoleCommand("version", "Display version information", this);
dvander@308
    49
	AddRootConsoleCommand("credits", "Display credits listing", this);
ds@627
    50
ds@627
    51
	ConVar *pHost = icvar->FindVar("hostname");
ds@627
    52
	pHost->InstallChangeCallback(_IntExt_OnHostnameChanged);
dvander@308
    53
}
dvander@308
    54
dvander@308
    55
void RootConsoleMenu::OnSourceModShutdown()
dvander@308
    56
{
dvander@308
    57
	RemoveRootConsoleCommand("credits", this);
dvander@308
    58
	RemoveRootConsoleCommand("version", this);
dvander@308
    59
}
dvander@308
    60
dvander@308
    61
bool RootConsoleMenu::RegisterConCommandBase(ConCommandBase *pCommand)
faluco@216
    62
{
faluco@216
    63
	META_REGCVAR(pCommand);
faluco@216
    64
ds@657
    65
	/* Override values of convars created by SourceMod convar manager if specified on command line */
ds@657
    66
	const char *cmdLineValue = icvar->GetCommandLineValue(pCommand->GetName());
ds@657
    67
	if (cmdLineValue && !pCommand->IsCommand())
ds@657
    68
	{
ds@657
    69
		static_cast<ConVar *>(pCommand)->SetValue(cmdLineValue);
ds@657
    70
	}
ds@657
    71
faluco@216
    72
	return true;
faluco@216
    73
}
faluco@216
    74
dvander@308
    75
void RootConsoleMenu::ConsolePrint(const char *fmt, ...)
dvander@308
    76
{
dvander@308
    77
	char buffer[512];
dvander@308
    78
dvander@308
    79
	va_list ap;
dvander@308
    80
	va_start(ap, fmt);
dvander@308
    81
	size_t len = vsnprintf(buffer, sizeof(buffer), fmt, ap);
dvander@308
    82
	va_end(ap);
dvander@308
    83
dvander@324
    84
	if (len >= sizeof(buffer) - 1)
dvander@308
    85
	{
dvander@308
    86
		buffer[510] = '\n';
dvander@308
    87
		buffer[511] = '\0';
dvander@308
    88
	} else {
dvander@308
    89
		buffer[len++] = '\n';
dvander@308
    90
		buffer[len] = '\0';
dvander@308
    91
	}
dvander@308
    92
	
dvander@308
    93
	META_CONPRINT(buffer);
dvander@308
    94
}
dvander@308
    95
dvander@308
    96
bool RootConsoleMenu::AddRootConsoleCommand(const char *cmd, const char *text, IRootConsoleCommand *pHandler)
faluco@216
    97
{
dvander@308
    98
	if (sm_trie_retrieve(m_pCommands, cmd, NULL))
dvander@308
    99
	{
dvander@308
   100
		return false;
dvander@308
   101
	}
dvander@308
   102
dvander@308
   103
	sm_trie_insert(m_pCommands, cmd, pHandler);
dvander@308
   104
dvander@308
   105
	/* Sort this into the menu */
dvander@308
   106
	List<ConsoleEntry *>::iterator iter = m_Menu.begin();
dvander@308
   107
	ConsoleEntry *pEntry;
dvander@308
   108
	bool inserted = false;
dvander@308
   109
	while (iter != m_Menu.end())
dvander@308
   110
	{
dvander@308
   111
		pEntry = (*iter);
dvander@308
   112
		if (strcmp(cmd, pEntry->command.c_str()) < 0)
dvander@308
   113
		{
dvander@308
   114
			ConsoleEntry *pNew = new ConsoleEntry;
dvander@308
   115
			pNew->command.assign(cmd);
dvander@308
   116
			pNew->description.assign(text);
dvander@308
   117
			m_Menu.insert(iter, pNew);
dvander@308
   118
			inserted = true;
dvander@308
   119
			break;
dvander@308
   120
		}
dvander@308
   121
		iter++;
dvander@308
   122
	}
dvander@308
   123
dvander@308
   124
	if (!inserted)
dvander@308
   125
	{
dvander@308
   126
		ConsoleEntry *pNew = new ConsoleEntry;
dvander@308
   127
		pNew->command.assign(cmd);
dvander@308
   128
		pNew->description.assign(text);
dvander@308
   129
		m_Menu.push_back(pNew);
dvander@308
   130
	}
dvander@308
   131
dvander@308
   132
	return true;
dvander@308
   133
}
dvander@308
   134
dvander@308
   135
bool RootConsoleMenu::RemoveRootConsoleCommand(const char *cmd, IRootConsoleCommand *pHandler)
dvander@308
   136
{
dvander@308
   137
	/* Sanity tests */
dvander@308
   138
	IRootConsoleCommand *object;
dvander@308
   139
	if (sm_trie_retrieve(m_pCommands, cmd, (void **)&object))
dvander@308
   140
	{
dvander@308
   141
		if (object != pHandler)
dvander@308
   142
		{
dvander@308
   143
			return false;
dvander@308
   144
		}
dvander@308
   145
	} else {
dvander@308
   146
		return false;
dvander@308
   147
	}
dvander@308
   148
dvander@308
   149
	sm_trie_delete(m_pCommands, cmd);
dvander@308
   150
dvander@308
   151
	List<ConsoleEntry *>::iterator iter;
dvander@308
   152
	ConsoleEntry *pEntry;
dvander@308
   153
	for (iter=m_Menu.begin(); iter!=m_Menu.end(); iter++)
dvander@308
   154
	{
dvander@308
   155
		pEntry = (*iter);
dvander@308
   156
		if (pEntry->command.compare(cmd) == 0)
dvander@308
   157
		{
dvander@308
   158
			delete pEntry;
dvander@308
   159
			m_Menu.erase(iter);
dvander@308
   160
			break;
dvander@308
   161
		}
dvander@308
   162
	}
dvander@308
   163
dvander@308
   164
	return true;
dvander@308
   165
}
dvander@308
   166
dvander@309
   167
void RootConsoleMenu::DrawGenericOption(const char *cmd, const char *text)
dvander@309
   168
{
dvander@309
   169
	char buffer[255];
dvander@309
   170
	size_t len, cmdlen = strlen(cmd);
dvander@309
   171
faluco@651
   172
	len = UTIL_Format(buffer, sizeof(buffer), "    %s", cmd);
dvander@309
   173
	if (cmdlen < 16)
dvander@309
   174
	{
dvander@309
   175
		size_t num = 16 - cmdlen;
dvander@309
   176
		for (size_t i = 0; i < num; i++)
dvander@309
   177
		{
dvander@309
   178
			buffer[len++] = ' ';
dvander@309
   179
		}
dvander@309
   180
		len += snprintf(&buffer[len], sizeof(buffer) - len, " - %s", text);
dvander@309
   181
		ConsolePrint("%s", buffer);
dvander@309
   182
	}
dvander@309
   183
}
dvander@309
   184
dvander@614
   185
extern void _IntExt_EnableYams();
dvander@614
   186
dvander@308
   187
void RootConsoleMenu::GotRootCmd()
dvander@308
   188
{
dvander@308
   189
	unsigned int argnum = GetArgumentCount();
faluco@216
   190
faluco@216
   191
	if (argnum >= 2)
faluco@216
   192
	{
dvander@308
   193
		const char *cmd = GetArgument(1);
dvander@614
   194
		if (strcmp(cmd, "text") == 0)
dvander@614
   195
		{
dvander@614
   196
			_IntExt_EnableYams();
dvander@614
   197
			return;
dvander@978
   198
		} else if (strcmp(cmd, "internal") == 0) {
dvander@978
   199
			if (argnum >= 3)
dvander@978
   200
			{
dvander@978
   201
				const char *arg = GetArgument(2);
dvander@978
   202
				if (strcmp(arg, "1") == 0)
dvander@978
   203
				{
dvander@978
   204
					SM_ConfigsExecuted_Global();
dvander@978
   205
				} else if (strcmp(arg, "2") == 0) {
dvander@978
   206
					if (argnum >= 4)
dvander@978
   207
					{
dvander@978
   208
						SM_ConfigsExecuted_Plugin(atoi(GetArgument(3)));
dvander@978
   209
					}
dvander@978
   210
				}
dvander@978
   211
			}
dvander@978
   212
			return;
dvander@614
   213
		}
dvander@978
   214
dvander@308
   215
		IRootConsoleCommand *pHandler;
dvander@308
   216
		if (sm_trie_retrieve(m_pCommands, cmd, (void **)&pHandler))
faluco@216
   217
		{
dvander@308
   218
			pHandler->OnRootConsoleCommand(cmd, argnum);
faluco@270
   219
			return;
faluco@216
   220
		}
faluco@216
   221
	}
dvander@308
   222
dvander@308
   223
	ConsolePrint("SourceMod Menu:");
dvander@308
   224
	ConsolePrint("Usage: sm <command> [arguments]");
dvander@308
   225
dvander@308
   226
	List<ConsoleEntry *>::iterator iter;
dvander@308
   227
	ConsoleEntry *pEntry;
dvander@308
   228
	for (iter=m_Menu.begin(); iter!=m_Menu.end(); iter++)
dvander@308
   229
	{
dvander@308
   230
		pEntry = (*iter);
dvander@309
   231
		DrawGenericOption(pEntry->command.c_str(), pEntry->description.c_str());
dvander@308
   232
	}
dvander@308
   233
}
dvander@308
   234
dvander@308
   235
const char *RootConsoleMenu::GetArgument(unsigned int argno)
dvander@308
   236
{
dvander@308
   237
	return engine->Cmd_Argv(argno);
dvander@308
   238
}
dvander@308
   239
dvander@308
   240
const char *RootConsoleMenu::GetArguments()
dvander@308
   241
{
dvander@308
   242
	return engine->Cmd_Args();
dvander@282
   243
}
dvander@308
   244
dvander@308
   245
unsigned int RootConsoleMenu::GetArgumentCount()
dvander@308
   246
{
dvander@308
   247
	return engine->Cmd_Argc();
dvander@308
   248
}
dvander@308
   249
dvander@308
   250
void RootConsoleMenu::OnRootConsoleCommand(const char *cmd, unsigned int argcount)
dvander@308
   251
{
dvander@308
   252
	if (strcmp(cmd, "credits") == 0)
dvander@308
   253
	{
dvander@308
   254
		ConsolePrint(" SourceMod was developed by AlliedModders, LLC.");
dvander@308
   255
		ConsolePrint(" Development would not have been possible without the following people:");
dvander@308
   256
		ConsolePrint("  David \"BAILOPAN\" Anderson, lead developer");
dvander@308
   257
		ConsolePrint("  Borja \"faluco\" Ferrer, Core developer");
ds@626
   258
		ConsolePrint("  Scott \"Damaged Soul\" Ehlert, Core developer");
dvander@308
   259
		ConsolePrint("  Pavol \"PM OnoTo\" Marko, SourceHook developer");
dvander@308
   260
		ConsolePrint(" Special thanks to Viper of GameConnect");
dvander@308
   261
		ConsolePrint(" Special thanks to Mani of Mani-Admin-Plugin");
dvander@308
   262
		ConsolePrint(" http://www.sourcemod.net/");
dvander@308
   263
	} else if (strcmp(cmd, "version") == 0) {
dvander@308
   264
		ConsolePrint(" SourceMod Version Information:");
dvander@566
   265
		ConsolePrint("    SourceMod Version: %s", SVN_FULL_VERSION);
dvander@308
   266
		ConsolePrint("    JIT Version: %s, %s", g_pVM->GetVMName(), g_pVM->GetVersionString());
dvander@308
   267
		ConsolePrint("    JIT Settings: %s", g_pVM->GetCPUOptimizations());
dvander@308
   268
		ConsolePrint("    http://www.sourcemod.net/");
dvander@308
   269
	}
dvander@308
   270
}
dvander@308
   271
dvander@308
   272
CON_COMMAND(sm, "SourceMod Menu")
dvander@308
   273
{
dvander@308
   274
	g_RootMenu.GotRootCmd();
dvander@308
   275
}
dvander@900
   276
dvander@900
   277
CON_COMMAND(sm_dump_handles, "Dumps Handle usage to a file for finding Handle leaks")
dvander@900
   278
{
dvander@900
   279
	if (engine->Cmd_Argc() < 2)
dvander@900
   280
	{
dvander@900
   281
		g_RootMenu.ConsolePrint("Usage: sm_dump_handles <file>");
dvander@900
   282
		return;
dvander@900
   283
	}
dvander@900
   284
dvander@900
   285
	const char *arg = engine->Cmd_Argv(1);
dvander@900
   286
	FILE *fp = fopen(arg, "wt");
dvander@900
   287
	if (!fp)
dvander@900
   288
	{
dvander@900
   289
		g_RootMenu.ConsolePrint("Could not find file \"%s\"", arg);
dvander@900
   290
		return;
dvander@900
   291
	}
dvander@900
   292
dvander@900
   293
	g_HandleSys.Dump(fp);
dvander@900
   294
dvander@900
   295
	fclose(fp);
dvander@900
   296
}