core/sm_srvcmds.cpp
author Michael McKoy <ferret99gt@gmail.com>
Wed Aug 08 21:32:06 2007 +0000 (2007-08-08)
changeset 1276 501613e0859f
parent 1231 17badaf66ce4
child 1330 ab94316bb52b
permissions -rw-r--r--
Added sm_cancelvote to the base commands, as well as appropriate translations.
dvander@370
     1
/**
ds@653
     2
 * vim: set ts=4 :
dvander@1231
     3
 * ================================================================
dvander@1231
     4
 * SourceMod
dvander@1231
     5
 * Copyright (C) 2004-2007 AlliedModders LLC.  All rights reserved.
dvander@1231
     6
 * ================================================================
dvander@370
     7
 *
dvander@1231
     8
 * This program is free software; you can redistribute it and/or 
dvander@1231
     9
 * modify it under the terms of the GNU General Public License, 
dvander@1231
    10
 * version 3.0, as published by the Free Software Foundation.
dvander@1231
    11
 * 
dvander@1231
    12
 * This program is distributed in the hope that it will be useful,
dvander@1231
    13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
dvander@1231
    14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
dvander@1231
    15
 * GNU General Public License for more details.
dvander@1231
    16
 *
dvander@1231
    17
 * You should have received a copy of the GNU General Public License
dvander@1231
    18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
dvander@1231
    19
 *
dvander@1231
    20
 * As a special exception, AlliedModders LLC gives you permission to 
dvander@1231
    21
 * link the code of this program (as well as its derivative works) to 
dvander@1231
    22
 * "Half-Life 2," the "Source Engine," the "SourcePawn JIT," and any 
dvander@1231
    23
 * Game MODs that run on software by the Valve Corporation.  You must 
dvander@1231
    24
 * obey the GNU General Public License in all respects for all other 
dvander@1231
    25
 * code used. Additionally, AlliedModders LLC grants this exception 
dvander@1231
    26
 * to all derivative works. AlliedModders LLC defines further 
dvander@1231
    27
 * exceptions, found in LICENSE.txt (as of this writing, version 
dvander@1231
    28
 * JULY-31-2007), or <http://www.sourcemod.net/license.php>.
dvander@370
    29
 *
dvander@370
    30
 * Version: $Id$
dvander@370
    31
 */
dvander@370
    32
faluco@216
    33
#include "sm_srvcmds.h"
faluco@270
    34
#include "sm_version.h"
faluco@274
    35
#include "sm_stringutil.h"
dvander@900
    36
#include "HandleSys.h"
dvander@978
    37
#include "CoreConfig.h"
faluco@216
    38
dvander@308
    39
RootConsoleMenu g_RootMenu;
faluco@216
    40
dvander@566
    41
ConVar sourcemod_version("sourcemod_version", SVN_FULL_VERSION, FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY, "SourceMod Version");
dvander@524
    42
dvander@308
    43
RootConsoleMenu::RootConsoleMenu()
faluco@216
    44
{
dvander@308
    45
	m_pCommands = sm_trie_create();
dvander@978
    46
	m_CfgExecDone = false;
faluco@216
    47
}
faluco@216
    48
dvander@308
    49
RootConsoleMenu::~RootConsoleMenu()
dvander@308
    50
{
dvander@308
    51
	sm_trie_destroy(m_pCommands);
dvander@308
    52
dvander@308
    53
	List<ConsoleEntry *>::iterator iter;
dvander@308
    54
	for (iter=m_Menu.begin(); iter!=m_Menu.end(); iter++)
dvander@308
    55
	{
dvander@308
    56
		delete (*iter);
dvander@308
    57
	}
dvander@308
    58
	m_Menu.clear();
dvander@308
    59
}
dvander@308
    60
ds@627
    61
extern void _IntExt_OnHostnameChanged(ConVar *pConVar, char const *oldValue);
ds@627
    62
dvander@308
    63
void RootConsoleMenu::OnSourceModStartup(bool late)
dvander@308
    64
{
dvander@308
    65
	ConCommandBaseMgr::OneTimeInit(this);
dvander@308
    66
	AddRootConsoleCommand("version", "Display version information", this);
dvander@308
    67
	AddRootConsoleCommand("credits", "Display credits listing", this);
ds@627
    68
ds@627
    69
	ConVar *pHost = icvar->FindVar("hostname");
ds@627
    70
	pHost->InstallChangeCallback(_IntExt_OnHostnameChanged);
dvander@308
    71
}
dvander@308
    72
dvander@308
    73
void RootConsoleMenu::OnSourceModShutdown()
dvander@308
    74
{
dvander@308
    75
	RemoveRootConsoleCommand("credits", this);
dvander@308
    76
	RemoveRootConsoleCommand("version", this);
dvander@308
    77
}
dvander@308
    78
dvander@308
    79
bool RootConsoleMenu::RegisterConCommandBase(ConCommandBase *pCommand)
faluco@216
    80
{
faluco@216
    81
	META_REGCVAR(pCommand);
faluco@216
    82
ds@657
    83
	/* Override values of convars created by SourceMod convar manager if specified on command line */
ds@657
    84
	const char *cmdLineValue = icvar->GetCommandLineValue(pCommand->GetName());
ds@657
    85
	if (cmdLineValue && !pCommand->IsCommand())
ds@657
    86
	{
ds@657
    87
		static_cast<ConVar *>(pCommand)->SetValue(cmdLineValue);
ds@657
    88
	}
ds@657
    89
faluco@216
    90
	return true;
faluco@216
    91
}
faluco@216
    92
dvander@308
    93
void RootConsoleMenu::ConsolePrint(const char *fmt, ...)
dvander@308
    94
{
dvander@308
    95
	char buffer[512];
dvander@308
    96
dvander@308
    97
	va_list ap;
dvander@308
    98
	va_start(ap, fmt);
dvander@308
    99
	size_t len = vsnprintf(buffer, sizeof(buffer), fmt, ap);
dvander@308
   100
	va_end(ap);
dvander@308
   101
dvander@324
   102
	if (len >= sizeof(buffer) - 1)
dvander@308
   103
	{
dvander@308
   104
		buffer[510] = '\n';
dvander@308
   105
		buffer[511] = '\0';
dvander@308
   106
	} else {
dvander@308
   107
		buffer[len++] = '\n';
dvander@308
   108
		buffer[len] = '\0';
dvander@308
   109
	}
dvander@308
   110
	
dvander@308
   111
	META_CONPRINT(buffer);
dvander@308
   112
}
dvander@308
   113
dvander@308
   114
bool RootConsoleMenu::AddRootConsoleCommand(const char *cmd, const char *text, IRootConsoleCommand *pHandler)
faluco@216
   115
{
dvander@308
   116
	if (sm_trie_retrieve(m_pCommands, cmd, NULL))
dvander@308
   117
	{
dvander@308
   118
		return false;
dvander@308
   119
	}
dvander@308
   120
dvander@308
   121
	sm_trie_insert(m_pCommands, cmd, pHandler);
dvander@308
   122
dvander@308
   123
	/* Sort this into the menu */
dvander@308
   124
	List<ConsoleEntry *>::iterator iter = m_Menu.begin();
dvander@308
   125
	ConsoleEntry *pEntry;
dvander@308
   126
	bool inserted = false;
dvander@308
   127
	while (iter != m_Menu.end())
dvander@308
   128
	{
dvander@308
   129
		pEntry = (*iter);
dvander@308
   130
		if (strcmp(cmd, pEntry->command.c_str()) < 0)
dvander@308
   131
		{
dvander@308
   132
			ConsoleEntry *pNew = new ConsoleEntry;
dvander@308
   133
			pNew->command.assign(cmd);
dvander@308
   134
			pNew->description.assign(text);
dvander@308
   135
			m_Menu.insert(iter, pNew);
dvander@308
   136
			inserted = true;
dvander@308
   137
			break;
dvander@308
   138
		}
dvander@308
   139
		iter++;
dvander@308
   140
	}
dvander@308
   141
dvander@308
   142
	if (!inserted)
dvander@308
   143
	{
dvander@308
   144
		ConsoleEntry *pNew = new ConsoleEntry;
dvander@308
   145
		pNew->command.assign(cmd);
dvander@308
   146
		pNew->description.assign(text);
dvander@308
   147
		m_Menu.push_back(pNew);
dvander@308
   148
	}
dvander@308
   149
dvander@308
   150
	return true;
dvander@308
   151
}
dvander@308
   152
dvander@308
   153
bool RootConsoleMenu::RemoveRootConsoleCommand(const char *cmd, IRootConsoleCommand *pHandler)
dvander@308
   154
{
dvander@308
   155
	/* Sanity tests */
dvander@308
   156
	IRootConsoleCommand *object;
dvander@308
   157
	if (sm_trie_retrieve(m_pCommands, cmd, (void **)&object))
dvander@308
   158
	{
dvander@308
   159
		if (object != pHandler)
dvander@308
   160
		{
dvander@308
   161
			return false;
dvander@308
   162
		}
dvander@308
   163
	} else {
dvander@308
   164
		return false;
dvander@308
   165
	}
dvander@308
   166
dvander@308
   167
	sm_trie_delete(m_pCommands, cmd);
dvander@308
   168
dvander@308
   169
	List<ConsoleEntry *>::iterator iter;
dvander@308
   170
	ConsoleEntry *pEntry;
dvander@308
   171
	for (iter=m_Menu.begin(); iter!=m_Menu.end(); iter++)
dvander@308
   172
	{
dvander@308
   173
		pEntry = (*iter);
dvander@308
   174
		if (pEntry->command.compare(cmd) == 0)
dvander@308
   175
		{
dvander@308
   176
			delete pEntry;
dvander@308
   177
			m_Menu.erase(iter);
dvander@308
   178
			break;
dvander@308
   179
		}
dvander@308
   180
	}
dvander@308
   181
dvander@308
   182
	return true;
dvander@308
   183
}
dvander@308
   184
dvander@309
   185
void RootConsoleMenu::DrawGenericOption(const char *cmd, const char *text)
dvander@309
   186
{
dvander@309
   187
	char buffer[255];
dvander@309
   188
	size_t len, cmdlen = strlen(cmd);
dvander@309
   189
faluco@651
   190
	len = UTIL_Format(buffer, sizeof(buffer), "    %s", cmd);
dvander@309
   191
	if (cmdlen < 16)
dvander@309
   192
	{
dvander@309
   193
		size_t num = 16 - cmdlen;
dvander@309
   194
		for (size_t i = 0; i < num; i++)
dvander@309
   195
		{
dvander@309
   196
			buffer[len++] = ' ';
dvander@309
   197
		}
dvander@309
   198
		len += snprintf(&buffer[len], sizeof(buffer) - len, " - %s", text);
dvander@309
   199
		ConsolePrint("%s", buffer);
dvander@309
   200
	}
dvander@309
   201
}
dvander@309
   202
dvander@614
   203
extern void _IntExt_EnableYams();
dvander@614
   204
dvander@308
   205
void RootConsoleMenu::GotRootCmd()
dvander@308
   206
{
dvander@308
   207
	unsigned int argnum = GetArgumentCount();
faluco@216
   208
faluco@216
   209
	if (argnum >= 2)
faluco@216
   210
	{
dvander@308
   211
		const char *cmd = GetArgument(1);
dvander@614
   212
		if (strcmp(cmd, "text") == 0)
dvander@614
   213
		{
dvander@614
   214
			_IntExt_EnableYams();
dvander@614
   215
			return;
dvander@978
   216
		} else if (strcmp(cmd, "internal") == 0) {
dvander@978
   217
			if (argnum >= 3)
dvander@978
   218
			{
dvander@978
   219
				const char *arg = GetArgument(2);
dvander@978
   220
				if (strcmp(arg, "1") == 0)
dvander@978
   221
				{
dvander@978
   222
					SM_ConfigsExecuted_Global();
dvander@978
   223
				} else if (strcmp(arg, "2") == 0) {
dvander@978
   224
					if (argnum >= 4)
dvander@978
   225
					{
dvander@978
   226
						SM_ConfigsExecuted_Plugin(atoi(GetArgument(3)));
dvander@978
   227
					}
dvander@978
   228
				}
dvander@978
   229
			}
dvander@978
   230
			return;
dvander@614
   231
		}
dvander@978
   232
dvander@308
   233
		IRootConsoleCommand *pHandler;
dvander@308
   234
		if (sm_trie_retrieve(m_pCommands, cmd, (void **)&pHandler))
faluco@216
   235
		{
dvander@308
   236
			pHandler->OnRootConsoleCommand(cmd, argnum);
faluco@270
   237
			return;
faluco@216
   238
		}
faluco@216
   239
	}
dvander@308
   240
dvander@308
   241
	ConsolePrint("SourceMod Menu:");
dvander@308
   242
	ConsolePrint("Usage: sm <command> [arguments]");
dvander@308
   243
dvander@308
   244
	List<ConsoleEntry *>::iterator iter;
dvander@308
   245
	ConsoleEntry *pEntry;
dvander@308
   246
	for (iter=m_Menu.begin(); iter!=m_Menu.end(); iter++)
dvander@308
   247
	{
dvander@308
   248
		pEntry = (*iter);
dvander@309
   249
		DrawGenericOption(pEntry->command.c_str(), pEntry->description.c_str());
dvander@308
   250
	}
dvander@308
   251
}
dvander@308
   252
dvander@308
   253
const char *RootConsoleMenu::GetArgument(unsigned int argno)
dvander@308
   254
{
dvander@308
   255
	return engine->Cmd_Argv(argno);
dvander@308
   256
}
dvander@308
   257
dvander@308
   258
const char *RootConsoleMenu::GetArguments()
dvander@308
   259
{
dvander@308
   260
	return engine->Cmd_Args();
dvander@282
   261
}
dvander@308
   262
dvander@308
   263
unsigned int RootConsoleMenu::GetArgumentCount()
dvander@308
   264
{
dvander@308
   265
	return engine->Cmd_Argc();
dvander@308
   266
}
dvander@308
   267
dvander@308
   268
void RootConsoleMenu::OnRootConsoleCommand(const char *cmd, unsigned int argcount)
dvander@308
   269
{
dvander@308
   270
	if (strcmp(cmd, "credits") == 0)
dvander@308
   271
	{
dvander@308
   272
		ConsolePrint(" SourceMod was developed by AlliedModders, LLC.");
dvander@308
   273
		ConsolePrint(" Development would not have been possible without the following people:");
dvander@308
   274
		ConsolePrint("  David \"BAILOPAN\" Anderson, lead developer");
dvander@308
   275
		ConsolePrint("  Borja \"faluco\" Ferrer, Core developer");
ds@626
   276
		ConsolePrint("  Scott \"Damaged Soul\" Ehlert, Core developer");
dvander@308
   277
		ConsolePrint("  Pavol \"PM OnoTo\" Marko, SourceHook developer");
dvander@308
   278
		ConsolePrint(" Special thanks to Viper of GameConnect");
dvander@308
   279
		ConsolePrint(" Special thanks to Mani of Mani-Admin-Plugin");
dvander@308
   280
		ConsolePrint(" http://www.sourcemod.net/");
dvander@308
   281
	} else if (strcmp(cmd, "version") == 0) {
dvander@308
   282
		ConsolePrint(" SourceMod Version Information:");
dvander@566
   283
		ConsolePrint("    SourceMod Version: %s", SVN_FULL_VERSION);
dvander@308
   284
		ConsolePrint("    JIT Version: %s, %s", g_pVM->GetVMName(), g_pVM->GetVersionString());
dvander@308
   285
		ConsolePrint("    JIT Settings: %s", g_pVM->GetCPUOptimizations());
dvander@308
   286
		ConsolePrint("    http://www.sourcemod.net/");
dvander@308
   287
	}
dvander@308
   288
}
dvander@308
   289
dvander@308
   290
CON_COMMAND(sm, "SourceMod Menu")
dvander@308
   291
{
dvander@308
   292
	g_RootMenu.GotRootCmd();
dvander@308
   293
}
dvander@900
   294
dvander@900
   295
CON_COMMAND(sm_dump_handles, "Dumps Handle usage to a file for finding Handle leaks")
dvander@900
   296
{
dvander@900
   297
	if (engine->Cmd_Argc() < 2)
dvander@900
   298
	{
dvander@900
   299
		g_RootMenu.ConsolePrint("Usage: sm_dump_handles <file>");
dvander@900
   300
		return;
dvander@900
   301
	}
dvander@900
   302
dvander@900
   303
	const char *arg = engine->Cmd_Argv(1);
dvander@900
   304
	FILE *fp = fopen(arg, "wt");
dvander@900
   305
	if (!fp)
dvander@900
   306
	{
dvander@900
   307
		g_RootMenu.ConsolePrint("Could not find file \"%s\"", arg);
dvander@900
   308
		return;
dvander@900
   309
	}
dvander@900
   310
dvander@900
   311
	g_HandleSys.Dump(fp);
dvander@900
   312
dvander@900
   313
	fclose(fp);
dvander@900
   314
}