extensions/sdktools/extension.cpp
author Nicholas Hastings <skamonkey@gmail.com>
Wed Jun 27 22:42:23 2012 -0400 (2012-06-27)
changeset 3564 48c4e173997f
parent 3414 3d224fc6dca6
child 3630 b72450a8be42
permissions -rw-r--r--
Updated Core and SDK Tools for ep2v EmitSound sdk change.
ds@783
     1
/**
ds@783
     2
 * vim: set ts=4 :
ds@1330
     3
 * =============================================================================
dvander@1233
     4
 * SourceMod SDKTools Extension
fyrenmoo@3089
     5
 * Copyright (C) 2004-2010 AlliedModders LLC.  All rights reserved.
ds@1330
     6
 * =============================================================================
ds@783
     7
 *
ds@1330
     8
 * This program is free software; you can redistribute it and/or modify it under
ds@1330
     9
 * the terms of the GNU General Public License, version 3.0, as published by the
ds@1330
    10
 * Free Software Foundation.
dvander@1233
    11
 * 
ds@1330
    12
 * This program is distributed in the hope that it will be useful, but WITHOUT
ds@1330
    13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
ds@1330
    14
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
ds@1330
    15
 * details.
dvander@1233
    16
 *
ds@1330
    17
 * You should have received a copy of the GNU General Public License along with
ds@1330
    18
 * this program.  If not, see <http://www.gnu.org/licenses/>.
dvander@1233
    19
 *
ds@1330
    20
 * As a special exception, AlliedModders LLC gives you permission to link the
ds@1330
    21
 * code of this program (as well as its derivative works) to "Half-Life 2," the
ds@1330
    22
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
ds@1330
    23
 * by the Valve Corporation.  You must obey the GNU General Public License in
ds@1330
    24
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
ds@1330
    25
 * this exception to all derivative works.  AlliedModders LLC defines further
ds@1330
    26
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
ds@1330
    27
 * or <http://www.sourcemod.net/license.php>.
ds@783
    28
 *
ds@783
    29
 * Version: $Id$
ds@783
    30
 */
ds@783
    31
dvander@2783
    32
#include <sourcemod_version.h>
ds@783
    33
#include "extension.h"
ds@2400
    34
#include <compat_wrappers.h>
dvander@950
    35
#include "vcallbuilder.h"
dvander@954
    36
#include "vnatives.h"
dvander@1169
    37
#include "vhelpers.h"
ds@1240
    38
#include "vglobals.h"
faluco@1031
    39
#include "tempents.h"
faluco@1735
    40
#include "vsound.h"
pred@1958
    41
#include "output.h"
pred@2711
    42
#include "hooks.h"
skamonkey@3333
    43
#include "gamerulesnatives.h"
dvander@2503
    44
#include <ISDKTools.h>
bluebriansimon@3339
    45
#include "clientnatives.h"
ds@783
    46
/**
ds@783
    47
 * @file extension.cpp
ds@995
    48
 * @brief Implements SDK Tools extension code.
ds@783
    49
 */
ds@783
    50
faluco@1262
    51
SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, false, bool, const char *, const char *, const char *, const char *, bool, bool);
faluco@1262
    52
ds@783
    53
SDKTools g_SdkTools;		/**< Global singleton for extension's main interface */
ds@783
    54
IServerGameEnts *gameents = NULL;
faluco@1075
    55
IEngineTrace *enginetrace = NULL;
ds@1114
    56
IEngineSound *engsound = NULL;
ds@1114
    57
INetworkStringTableContainer *netstringtables = NULL;
dvander@1169
    58
IServerPluginHelpers *pluginhelpers = NULL;
ds@783
    59
IBinTools *g_pBinTools = NULL;
dvander@950
    60
IGameConfig *g_pGameConf = NULL;
faluco@1031
    61
IGameHelpers *g_pGameHelpers = NULL;
faluco@1219
    62
IServerGameClients *serverClients = NULL;
ds@1240
    63
IVoiceServer *voiceserver = NULL;
teame06@1239
    64
IPlayerInfoManager *playerinfomngr = NULL;
faluco@1560
    65
ICvar *icvar = NULL;
faluco@1769
    66
IServer *iserver = NULL;
ds@2400
    67
CGlobalVars *gpGlobals;
skamonkey@3280
    68
skamonkey@3280
    69
#if SOURCE_ENGINE >= SE_ORANGEBOX
skamonkey@3280
    70
IServerTools *servertools = NULL;
skamonkey@3280
    71
#endif
skamonkey@3280
    72
faluco@1735
    73
SourceHook::CallClass<IVEngineServer> *enginePatch = NULL;
faluco@1735
    74
SourceHook::CallClass<IEngineSound> *enginesoundPatch = NULL;
dvander@950
    75
HandleType_t g_CallHandle = 0;
faluco@1075
    76
HandleType_t g_TraceHandle = 0;
dvander@2503
    77
ISDKTools *g_pSDKTools;
ds@783
    78
ds@783
    79
SMEXT_LINK(&g_SdkTools);
ds@783
    80
dvander@950
    81
extern sp_nativeinfo_t g_CallNatives[];
faluco@1031
    82
extern sp_nativeinfo_t g_TENatives[];
faluco@1075
    83
extern sp_nativeinfo_t g_TRNatives[];
ds@1114
    84
extern sp_nativeinfo_t g_StringTableNatives[];
teame06@1235
    85
extern sp_nativeinfo_t g_VoiceNatives[];
faluco@1498
    86
extern sp_nativeinfo_t g_EntInputNatives[];
faluco@1613
    87
extern sp_nativeinfo_t g_TeamNatives[];
skamonkey@3333
    88
extern sp_nativeinfo_t g_GameRulesNatives[];
bluebriansimon@3339
    89
extern sp_nativeinfo_t g_ClientNatives[];
dvander@950
    90
dvander@2503
    91
static void InitSDKToolsAPI();
dvander@2503
    92
ds@783
    93
bool SDKTools::SDK_OnLoad(char *error, size_t maxlength, bool late)
ds@783
    94
{
dvander@2306
    95
	HandleError err;
dvander@2306
    96
dvander@2529
    97
	if (!gameconfs->LoadGameConfigFile("sdktools.games", &g_pGameConf, error, maxlength))
pred@2124
    98
	{
pred@2124
    99
		return false;
pred@2124
   100
	}
pred@2124
   101
dvander@950
   102
	sharesys->AddDependency(myself, "bintools.ext", true, true);
dvander@950
   103
	sharesys->AddNatives(myself, g_CallNatives);
dvander@954
   104
	sharesys->AddNatives(myself, g_Natives);
faluco@1031
   105
	sharesys->AddNatives(myself, g_TENatives);
dvander@1047
   106
	sharesys->AddNatives(myself, g_SoundNatives);
faluco@1075
   107
	sharesys->AddNatives(myself, g_TRNatives);
ds@1114
   108
	sharesys->AddNatives(myself, g_StringTableNatives);
teame06@1235
   109
	sharesys->AddNatives(myself, g_VoiceNatives);
faluco@1498
   110
	sharesys->AddNatives(myself, g_EntInputNatives);
faluco@1613
   111
	sharesys->AddNatives(myself, g_TeamNatives);
pred@1958
   112
	sharesys->AddNatives(myself, g_EntOutputNatives);
skamonkey@3333
   113
	sharesys->AddNatives(myself, g_GameRulesNatives);
bluebriansimon@3339
   114
	sharesys->AddNatives(myself, g_ClientNatives);
faluco@1031
   115
faluco@1031
   116
	SM_GET_IFACE(GAMEHELPERS, g_pGameHelpers);
ds@783
   117
teame06@1235
   118
	playerhelpers->AddClientListener(&g_SdkTools);
dvander@2306
   119
	g_CallHandle = handlesys->CreateType("ValveCall", this, 0, NULL, NULL, myself->GetIdentity(), &err);
dvander@2306
   120
	if (g_CallHandle == 0)
dvander@2306
   121
	{
dvander@2306
   122
		snprintf(error, maxlength, "Could not create call handle type (err: %d)", err);	
dvander@2306
   123
		return false;
dvander@2306
   124
	}
pred@2108
   125
pred@2108
   126
	TypeAccess TraceAccess;
pred@2108
   127
	handlesys->InitAccessDefaults(&TraceAccess, NULL);
pred@2116
   128
	TraceAccess.ident = myself->GetIdentity();
pred@2108
   129
	TraceAccess.access[HTypeAccess_Create] = true;
pred@2116
   130
	TraceAccess.access[HTypeAccess_Inherit] = true;
dvander@2306
   131
	g_TraceHandle = handlesys->CreateType("TraceRay", this, 0, &TraceAccess, NULL, myself->GetIdentity(), &err);
dvander@2306
   132
	if (g_TraceHandle == 0)
dvander@2306
   133
	{
dvander@2306
   134
		handlesys->RemoveType(g_CallHandle, myself->GetIdentity());
dvander@2306
   135
		g_CallHandle = 0;
dvander@2306
   136
		snprintf(error, maxlength, "Could not create traceray handle type (err: %d)", err);
dvander@2306
   137
		return false;
dvander@2306
   138
	}
ds@783
   139
ds@2400
   140
#if SOURCE_ENGINE >= SE_ORANGEBOX
faluco@1560
   141
	g_pCVar = icvar;
faluco@1560
   142
#endif
faluco@1560
   143
	CONVAR_REGISTER(this);
dvander@1052
   144
faluco@1262
   145
	SH_ADD_HOOK_MEMFUNC(IServerGameDLL, LevelInit, gamedll, this, &SDKTools::LevelInit, true);
faluco@1262
   146
dvander@1628
   147
	playerhelpers->RegisterCommandTargetProcessor(this);
dvander@1628
   148
dvander@1611
   149
	MathLib_Init(2.2f, 2.2f, 0.0f, 2);
dvander@1611
   150
pred@1958
   151
	spengine = g_pSM->GetScriptingEngine();
pred@1958
   152
pred@1958
   153
	plsys->AddPluginsListener(&g_OutputManager);
pred@1958
   154
fyrenmoo@3089
   155
	CDetourManager::Init(g_pSM->GetScriptingEngine(), g_pGameConf);
pred@1958
   156
	g_OutputManager.Init();
pred@1958
   157
dvander@2044
   158
	VoiceInit();
dvander@2044
   159
dvander@2503
   160
	GetIServer();
dvander@2503
   161
skamonkey@3333
   162
	GameRulesNativesInit();
skamonkey@3333
   163
dvander@2503
   164
	InitSDKToolsAPI();
dvander@2503
   165
ds@783
   166
	return true;
ds@783
   167
}
ds@783
   168
dvander@950
   169
void SDKTools::OnHandleDestroy(HandleType_t type, void *object)
dvander@950
   170
{
dvander@950
   171
	if (type == g_CallHandle)
dvander@950
   172
	{
dvander@950
   173
		ValveCall *v = (ValveCall *)object;
dvander@950
   174
		delete v;
dvander@1628
   175
	}
dvander@1628
   176
	else if (type == g_TraceHandle)
dvander@1628
   177
	{
faluco@1075
   178
		trace_t *tr = (trace_t *)object;
faluco@1075
   179
		delete tr;
faluco@1075
   180
	}
dvander@950
   181
}
dvander@950
   182
dvander@950
   183
void SDKTools::SDK_OnUnload()
dvander@950
   184
{
faluco@1560
   185
	SourceHook::List<ValveCall *>::iterator iter;
dvander@954
   186
	for (iter = g_RegCalls.begin();
dvander@954
   187
		 iter != g_RegCalls.end();
dvander@954
   188
		 iter++)
dvander@954
   189
	{
dvander@954
   190
		delete (*iter);
dvander@954
   191
	}
dvander@954
   192
	g_RegCalls.clear();
dvander@1169
   193
	ShutdownHelpers();
dvander@954
   194
faluco@1498
   195
	if (g_pAcceptInput)
faluco@1498
   196
	{
faluco@1498
   197
		g_pAcceptInput->Destroy();
faluco@1498
   198
		g_pAcceptInput = NULL;
faluco@1498
   199
	}
faluco@1498
   200
faluco@1031
   201
	g_TEManager.Shutdown();
faluco@1255
   202
	s_TempEntHooks.Shutdown();
faluco@1735
   203
	s_SoundHooks.Shutdown();
pred@2711
   204
	g_Hooks.Shutdown();
dvander@3414
   205
	g_OutputManager.Shutdown();
faluco@1031
   206
dvander@950
   207
	gameconfs->CloseGameConfigFile(g_pGameConf);
teame06@1235
   208
	playerhelpers->RemoveClientListener(&g_SdkTools);
dvander@1628
   209
	playerhelpers->UnregisterCommandTargetProcessor(this);
dvander@2060
   210
	plsys->RemovePluginsListener(&g_OutputManager);
faluco@1262
   211
faluco@1262
   212
	SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, LevelInit, gamedll, this, &SDKTools::LevelInit, true);
faluco@1735
   213
faluco@1735
   214
	if (enginePatch)
faluco@1735
   215
	{
faluco@1735
   216
		SH_RELEASE_CALLCLASS(enginePatch);
faluco@1735
   217
		enginePatch = NULL;
faluco@1735
   218
	}
faluco@1735
   219
	if (enginesoundPatch)
faluco@1735
   220
	{
faluco@1735
   221
		SH_RELEASE_CALLCLASS(enginesoundPatch);
faluco@1735
   222
		enginesoundPatch = NULL;
faluco@1735
   223
	}
dvander@2306
   224
dvander@2306
   225
	bool err;
dvander@2306
   226
	if (g_CallHandle != 0)
dvander@2306
   227
	{
dvander@2306
   228
		if ((err = handlesys->RemoveType(g_CallHandle, myself->GetIdentity())) != true)
dvander@2306
   229
		{
dvander@2306
   230
			g_pSM->LogError(myself, "Could not remove call handle (type=%x, err=%d)", g_CallHandle, err);
dvander@2306
   231
		}
dvander@2306
   232
	}
dvander@2306
   233
dvander@2306
   234
	if (g_TraceHandle != 0)
dvander@2306
   235
	{
dvander@2306
   236
		if ((err = handlesys->RemoveType(g_TraceHandle, myself->GetIdentity())) != true)
dvander@2306
   237
		{
dvander@2306
   238
			g_pSM->LogError(myself, "Could not remove trace handle (type=%x, err=%d)", g_TraceHandle, err);
dvander@2306
   239
		}
dvander@2306
   240
	}
dvander@950
   241
}
dvander@950
   242
ds@783
   243
bool SDKTools::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlen, bool late)
ds@783
   244
{
faluco@1560
   245
	GET_V_IFACE_ANY(GetServerFactory, gameents, IServerGameEnts, INTERFACEVERSION_SERVERGAMEENTS);
faluco@1560
   246
	GET_V_IFACE_ANY(GetEngineFactory, engsound, IEngineSound, IENGINESOUND_SERVER_INTERFACE_VERSION);
faluco@1560
   247
	GET_V_IFACE_ANY(GetEngineFactory, enginetrace, IEngineTrace, INTERFACEVERSION_ENGINETRACE_SERVER);
faluco@1560
   248
	GET_V_IFACE_ANY(GetEngineFactory, netstringtables, INetworkStringTableContainer, INTERFACENAME_NETWORKSTRINGTABLESERVER);
faluco@1560
   249
	GET_V_IFACE_ANY(GetEngineFactory, pluginhelpers, IServerPluginHelpers, INTERFACEVERSION_ISERVERPLUGINHELPERS);
faluco@1560
   250
	GET_V_IFACE_ANY(GetServerFactory, serverClients, IServerGameClients, INTERFACEVERSION_SERVERGAMECLIENTS);
faluco@1560
   251
	GET_V_IFACE_ANY(GetEngineFactory, voiceserver, IVoiceServer, INTERFACEVERSION_VOICESERVER);
faluco@1560
   252
	GET_V_IFACE_ANY(GetServerFactory, playerinfomngr, IPlayerInfoManager, INTERFACEVERSION_PLAYERINFOMANAGER);
faluco@1560
   253
	GET_V_IFACE_CURRENT(GetEngineFactory, icvar, ICvar, CVAR_INTERFACE_VERSION);
ds@783
   254
skamonkey@3280
   255
#if SOURCE_ENGINE >= SE_ORANGEBOX
skamonkey@3280
   256
	GET_V_IFACE_ANY(GetServerFactory, servertools, IServerTools, VSERVERTOOLS_INTERFACE_VERSION);
skamonkey@3280
   257
#endif
skamonkey@3280
   258
ds@2400
   259
	gpGlobals = ismm->GetCGlobals();
faluco@1735
   260
	enginePatch = SH_GET_CALLCLASS(engine);
faluco@1735
   261
	enginesoundPatch = SH_GET_CALLCLASS(engsound);
faluco@1735
   262
ds@783
   263
	return true;
ds@783
   264
}
ds@783
   265
ds@783
   266
void SDKTools::SDK_OnAllLoaded()
ds@783
   267
{
ds@783
   268
	SM_GET_LATE_IFACE(BINTOOLS, g_pBinTools);
ds@1065
   269
dvander@1757
   270
	if (!g_pBinTools)
dvander@1757
   271
	{
dvander@1757
   272
		return;
dvander@1757
   273
	}
dvander@1757
   274
faluco@1031
   275
	g_TEManager.Initialize();
faluco@1255
   276
	s_TempEntHooks.Initialize();
faluco@1735
   277
	s_SoundHooks.Initialize();
pred@2711
   278
	g_Hooks.Initialize();
ds@1240
   279
	InitializeValveGlobals();
ds@783
   280
}
ds@783
   281
ds@783
   282
bool SDKTools::QueryRunning(char *error, size_t maxlength)
ds@783
   283
{
ds@783
   284
	SM_CHECK_IFACE(BINTOOLS, g_pBinTools);
ds@783
   285
ds@783
   286
	return true;
ds@783
   287
}
dvander@1023
   288
dvander@1023
   289
bool SDKTools::QueryInterfaceDrop(SMInterface *pInterface)
dvander@1023
   290
{
dvander@1023
   291
	if (pInterface == g_pBinTools)
dvander@1023
   292
	{
dvander@1023
   293
		return false;
dvander@1023
   294
	}
dvander@1023
   295
dvander@1023
   296
	return IExtensionInterface::QueryInterfaceDrop(pInterface);
dvander@1023
   297
}
dvander@1023
   298
dvander@1023
   299
void SDKTools::NotifyInterfaceDrop(SMInterface *pInterface)
dvander@1023
   300
{
faluco@1560
   301
	SourceHook::List<ValveCall *>::iterator iter;
dvander@1023
   302
	for (iter = g_RegCalls.begin();
dvander@1023
   303
		iter != g_RegCalls.end();
dvander@1023
   304
		iter++)
dvander@1023
   305
	{
dvander@1023
   306
		delete (*iter);
dvander@1023
   307
	}
dvander@1023
   308
	g_RegCalls.clear();
dvander@1169
   309
	ShutdownHelpers();
dvander@1023
   310
faluco@1031
   311
	g_TEManager.Shutdown();
faluco@1255
   312
	s_TempEntHooks.Shutdown();
faluco@1498
   313
faluco@1498
   314
	if (g_pAcceptInput)
faluco@1498
   315
	{
faluco@1498
   316
		g_pAcceptInput->Destroy();
faluco@1498
   317
		g_pAcceptInput = NULL;
faluco@1498
   318
	}
dvander@1023
   319
}
dvander@1052
   320
dvander@1052
   321
bool SDKTools::RegisterConCommandBase(ConCommandBase *pVar)
dvander@1052
   322
{
faluco@1560
   323
#if defined METAMOD_PLAPI_VERSION
faluco@1560
   324
	return g_SMAPI->RegisterConCommandBase(g_PLAPI, pVar);
faluco@1560
   325
#else
dvander@1052
   326
	return g_SMAPI->RegisterConCmdBase(g_PLAPI, pVar);
faluco@1560
   327
#endif
dvander@1052
   328
}
faluco@1262
   329
faluco@1262
   330
bool SDKTools::LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background)
faluco@1262
   331
{
faluco@1262
   332
	const char *name;
faluco@1262
   333
	char key[32];
faluco@1262
   334
	int count, n = 1;
faluco@1262
   335
faluco@1262
   336
	if (!(name=g_pGameConf->GetKeyValue("SlapSoundCount")))
faluco@1262
   337
	{
faluco@1262
   338
		RETURN_META_VALUE(MRES_IGNORED, true);
faluco@1262
   339
	}
faluco@1262
   340
faluco@1262
   341
	count = atoi(name);
faluco@1262
   342
faluco@1262
   343
	while (n <= count)
faluco@1262
   344
	{
faluco@1262
   345
		snprintf(key, sizeof(key), "SlapSound%d", n);
faluco@1262
   346
		if ((name=g_pGameConf->GetKeyValue(key)))
faluco@1262
   347
		{
faluco@1262
   348
			engsound->PrecacheSound(name, true);
faluco@1262
   349
		}
faluco@1262
   350
		n++;
faluco@1262
   351
	}
faluco@1262
   352
faluco@1262
   353
	RETURN_META_VALUE(MRES_IGNORED, true);
faluco@1262
   354
}
dvander@1628
   355
dvander@1628
   356
bool SDKTools::ProcessCommandTarget(cmd_target_info_t *info)
dvander@1628
   357
{
dvander@1628
   358
	IGamePlayer *pAdmin = info->admin ? playerhelpers->GetGamePlayer(info->admin) : NULL;
dvander@1628
   359
dvander@2838
   360
	if (strcmp(info->pattern, "@aim") == 0)
dvander@1628
   361
	{
dvander@2838
   362
		/* The server can't aim, of course. */
dvander@2838
   363
		if (pAdmin == NULL)
dvander@2838
   364
		{
dvander@2838
   365
			return false;
dvander@2838
   366
		}
dvander@2838
   367
dvander@2838
   368
		int player_index;
dvander@2838
   369
		if ((player_index = GetClientAimTarget(pAdmin->GetEdict(), true)) < 1)
dvander@2838
   370
		{
dvander@2838
   371
			info->reason = COMMAND_TARGET_NONE;
dvander@2838
   372
			info->num_targets = 0;
dvander@2838
   373
			return true;
dvander@2838
   374
		}
dvander@2838
   375
dvander@2838
   376
		IGamePlayer *pTarget = playerhelpers->GetGamePlayer(player_index);
dvander@2838
   377
dvander@2838
   378
		if (pTarget == NULL)
dvander@2838
   379
		{
dvander@2838
   380
			info->reason = COMMAND_TARGET_NONE;
dvander@2838
   381
			info->num_targets = 0;
dvander@2838
   382
			return true;
dvander@2838
   383
		}
dvander@2838
   384
dvander@2838
   385
		info->reason = playerhelpers->FilterCommandTarget(pAdmin, pTarget, info->flags);
dvander@2838
   386
		if (info->reason != COMMAND_TARGET_VALID)
dvander@2838
   387
		{
dvander@2838
   388
			info->num_targets = 0;
dvander@2838
   389
			return true;
dvander@2838
   390
		}
dvander@1628
   391
dvander@2838
   392
		info->targets[0] = player_index;
dvander@2838
   393
		info->num_targets = 1;
dvander@2838
   394
		info->reason = COMMAND_TARGET_VALID;
dvander@2838
   395
		info->target_name_style = COMMAND_TARGETNAME_RAW;
dvander@2838
   396
		snprintf(info->target_name, info->target_name_maxlength, "%s", pTarget->GetName());
dvander@2838
   397
		return true;
dvander@2838
   398
	}
dvander@2838
   399
	else if (strcmp(info->pattern, "@spec") == 0)
dvander@1628
   400
	{
dvander@2838
   401
		const char *teamname = tools_GetTeamName(1);
dvander@2838
   402
		if (strcasecmp(teamname, "spectator") != 0)
dvander@2838
   403
			return false;
dvander@1757
   404
		info->num_targets = 0;
dvander@2838
   405
		for (int i = 1; i <= playerhelpers->GetMaxClients(); i++)
dvander@2838
   406
		{
dvander@2838
   407
			IGamePlayer *player = playerhelpers->GetGamePlayer(i);
dvander@2838
   408
			if (player == NULL || !player->IsInGame())
dvander@2838
   409
				continue;
dvander@2838
   410
			IPlayerInfo *plinfo = player->GetPlayerInfo();
dvander@2838
   411
			if (plinfo == NULL)
dvander@2838
   412
				continue;
dvander@2838
   413
			if (plinfo->GetTeamIndex() == 1 &&
dvander@2838
   414
			    playerhelpers->FilterCommandTarget(pAdmin, player, info->flags) ==
dvander@2838
   415
				COMMAND_TARGET_VALID)
dvander@2838
   416
			{
dvander@2838
   417
				info->targets[info->num_targets++] = i;
dvander@2838
   418
			}
dvander@2838
   419
		}
dvander@2838
   420
		info->reason = info->num_targets > 0 ? COMMAND_TARGET_VALID : COMMAND_TARGET_EMPTY_FILTER;
dvander@2838
   421
		info->target_name_style = COMMAND_TARGETNAME_ML;
dvander@2838
   422
		snprintf(info->target_name, info->target_name_maxlength, "all spectators");
dvander@1757
   423
		return true;
dvander@1628
   424
	}
dvander@1628
   425
dvander@2838
   426
	return false;
dvander@1628
   427
}
dvander@2503
   428
dvander@2790
   429
const char *SDKTools::GetExtensionVerString()
pred@2711
   430
{
dvander@2783
   431
	return SM_FULL_VERSION;
dvander@2783
   432
}
dvander@2783
   433
dvander@2790
   434
const char *SDKTools::GetExtensionDateString()
dvander@2783
   435
{
dvander@2783
   436
	return SM_BUILD_TIMESTAMP;
pred@2711
   437
}
pred@2711
   438
dvander@2786
   439
void SDKTools::OnClientPutInServer(int client)
dvander@2786
   440
{
dvander@2786
   441
	g_Hooks.OnClientPutInServer(client);
dvander@2786
   442
}
dvander@2786
   443
dvander@2503
   444
class SDKTools_API : public ISDKTools
dvander@2503
   445
{
dvander@2503
   446
public:
dvander@2503
   447
	virtual const char *GetInterfaceName()
dvander@2503
   448
	{
dvander@2503
   449
		return SMINTERFACE_SDKTOOLS_NAME;
dvander@2503
   450
	}
dvander@2503
   451
dvander@2503
   452
	virtual unsigned int GetInterfaceVersion()
dvander@2503
   453
	{
dvander@2503
   454
		return SMINTERFACE_SDKTOOLS_VERSION;
dvander@2503
   455
	}
dvander@2503
   456
dvander@2503
   457
	virtual IServer *GetIServer()
dvander@2503
   458
	{
dvander@2503
   459
		return iserver;
dvander@2503
   460
	}
skamonkey@3157
   461
	
skamonkey@3157
   462
	virtual void *GetGameRules()
skamonkey@3157
   463
	{
skamonkey@3157
   464
		if (!g_pGameRules)
skamonkey@3157
   465
			return NULL;
skamonkey@3157
   466
		
skamonkey@3157
   467
		return *g_pGameRules;
skamonkey@3157
   468
	}
dvander@2503
   469
} g_SDKTools_API;
dvander@2503
   470
dvander@2503
   471
static void InitSDKToolsAPI()
dvander@2503
   472
{
dvander@2503
   473
	g_pSDKTools = &g_SDKTools_API;
dvander@2503
   474
	sharesys->AddInterface(myself, g_pSDKTools);
dvander@2503
   475
}