faluco@1441: /** faluco@1441: * vim: set ts=4 : faluco@1441: * ============================================================================= faluco@1441: * SourceMod Counter-Strike:Source Extension ds@1947: * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. faluco@1441: * ============================================================================= faluco@1441: * faluco@1441: * This program is free software; you can redistribute it and/or modify it under faluco@1441: * the terms of the GNU General Public License, version 3.0, as published by the faluco@1441: * Free Software Foundation. faluco@1441: * faluco@1441: * This program is distributed in the hope that it will be useful, but WITHOUT faluco@1441: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS faluco@1441: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more faluco@1441: * details. faluco@1441: * faluco@1441: * You should have received a copy of the GNU General Public License along with faluco@1441: * this program. If not, see . faluco@1441: * faluco@1441: * As a special exception, AlliedModders LLC gives you permission to link the faluco@1441: * code of this program (as well as its derivative works) to "Half-Life 2," the faluco@1441: * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software faluco@1441: * by the Valve Corporation. You must obey the GNU General Public License in faluco@1441: * all respects for all other code used. Additionally, AlliedModders LLC grants faluco@1441: * this exception to all derivative works. AlliedModders LLC defines further faluco@1441: * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), faluco@1441: * or . faluco@1441: * faluco@1441: * Version: $Id$ faluco@1441: */ faluco@1441: dvander@2783: #include faluco@1441: #include "extension.h" faluco@1441: #include "RegNatives.h" dvander@1459: #include "timeleft.h" dvander@1756: #include "iplayerinfo.h" faluco@1441: faluco@1441: /** faluco@1441: * @file extension.cpp faluco@1441: * @brief Implement extension code here. faluco@1441: */ faluco@1441: dvander@1459: SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, false, bool, const char *, const char *, const char *, const char *, bool, bool); dvander@1459: faluco@1441: CStrike g_CStrike; /**< Global singleton for extension's main interface */ faluco@1441: IBinTools *g_pBinTools = NULL; faluco@1441: IGameConfig *g_pGameConf = NULL; dvander@1459: IGameEventManager2 *gameevents = NULL; dvander@1459: bool hooked_everything = false; dvander@1692: int g_msgHintText = -1; faluco@1441: faluco@1441: SMEXT_LINK(&g_CStrike); faluco@1441: faluco@1441: extern sp_nativeinfo_t g_CSNatives[]; faluco@1441: faluco@1441: bool CStrike::SDK_OnLoad(char *error, size_t maxlength, bool late) faluco@1441: { skamonkey@3053: if (strcmp(g_pSM->GetGameFolderName(), "cstrike") != 0) pred@2069: { pred@2069: snprintf(error, maxlength, "Cannot Load Cstrike Extension on mods other than CS:S"); pred@2069: return false; pred@2069: } pred@2069: faluco@1441: sharesys->AddDependency(myself, "bintools.ext", true, true); faluco@1441: dvander@1459: char conf_error[255]; dvander@1459: if (!gameconfs->LoadGameConfigFile("sm-cstrike.games", &g_pGameConf, conf_error, sizeof(conf_error))) faluco@1441: { dvander@1459: if (error) dvander@1459: { dvander@1459: snprintf(error, maxlength, "Could not read sm-cstrike.games.txt: %s", conf_error); dvander@1459: } faluco@1441: return false; faluco@1441: } faluco@1441: faluco@1441: sharesys->AddNatives(myself, g_CSNatives); dvander@1573: sharesys->RegisterLibrary(myself, "cstrike"); faluco@1441: dvander@1756: playerhelpers->RegisterCommandTargetProcessor(this); dvander@1756: faluco@1441: return true; faluco@1441: } faluco@1441: dvander@1459: bool CStrike::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlen, bool late) dvander@1459: { faluco@1552: GET_V_IFACE_CURRENT(GetEngineFactory, gameevents, IGameEventManager2, INTERFACEVERSION_GAMEEVENTSMANAGER2); faluco@1552: GET_V_IFACE_CURRENT(GetEngineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER); dvander@1459: dvander@1459: return true; dvander@1459: } dvander@1459: faluco@1441: void CStrike::SDK_OnUnload() faluco@1441: { dvander@1459: if (hooked_everything) dvander@1459: { dvander@1459: gameevents->RemoveListener(&g_TimeLeftEvents); dvander@1459: SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, LevelInit, gamedll, &g_TimeLeftEvents, &TimeLeftEvents::LevelInit, true); dvander@1459: hooked_everything = false; dvander@1459: } faluco@1441: g_RegNatives.UnregisterAll(); faluco@1441: gameconfs->CloseGameConfigFile(g_pGameConf); dvander@1756: playerhelpers->UnregisterCommandTargetProcessor(this); faluco@1441: } faluco@1441: faluco@1441: void CStrike::SDK_OnAllLoaded() faluco@1441: { dvander@1459: gameevents->AddListener(&g_TimeLeftEvents, "round_start", true); dvander@1459: gameevents->AddListener(&g_TimeLeftEvents, "round_end", true); dvander@1459: SH_ADD_HOOK_MEMFUNC(IServerGameDLL, LevelInit, gamedll, &g_TimeLeftEvents, &TimeLeftEvents::LevelInit, true); dvander@1459: hooked_everything = true; dvander@1459: faluco@1441: SM_GET_LATE_IFACE(BINTOOLS, g_pBinTools); faluco@1441: } faluco@1441: faluco@1441: bool CStrike::QueryRunning(char *error, size_t maxlength) faluco@1441: { faluco@1441: SM_CHECK_IFACE(BINTOOLS, g_pBinTools); faluco@1441: faluco@1441: return true; faluco@1441: } faluco@1441: faluco@1441: bool CStrike::QueryInterfaceDrop(SMInterface *pInterface) faluco@1441: { faluco@1441: if (pInterface == g_pBinTools) faluco@1441: { faluco@1441: return false; faluco@1441: } faluco@1441: faluco@1441: return IExtensionInterface::QueryInterfaceDrop(pInterface); faluco@1441: } faluco@1441: faluco@1441: void CStrike::NotifyInterfaceDrop(SMInterface *pInterface) faluco@1441: { faluco@1441: g_RegNatives.UnregisterAll(); faluco@1441: } dvander@1756: dvander@1756: size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...) dvander@1756: { dvander@1756: va_list ap; dvander@1756: va_start(ap, fmt); dvander@1756: size_t len = vsnprintf(buffer, maxlength, fmt, ap); dvander@1756: va_end(ap); dvander@1756: dvander@1756: if (len >= maxlength) dvander@1756: { dvander@1756: buffer[maxlength - 1] = '\0'; dvander@1756: return (maxlength - 1); dvander@1756: } dvander@1756: else dvander@1756: { dvander@1756: return len; dvander@1756: } dvander@1756: } dvander@1756: dvander@1756: bool CStrike::ProcessCommandTarget(cmd_target_info_t *info) dvander@1756: { dvander@1756: int max_clients; dvander@1756: IPlayerInfo *pInfo; dvander@1756: unsigned int team_index = 0; dvander@1756: IGamePlayer *pPlayer, *pAdmin; dvander@1756: dvander@1756: if ((info->flags & COMMAND_FILTER_NO_MULTI) == COMMAND_FILTER_NO_MULTI) dvander@1756: { dvander@1756: return false; dvander@1756: } dvander@1756: dvander@1756: if (info->admin) dvander@1756: { dvander@1756: if ((pAdmin = playerhelpers->GetGamePlayer(info->admin)) == NULL) dvander@1756: { dvander@1756: return false; dvander@1756: } dvander@1756: if (!pAdmin->IsInGame()) dvander@1756: { dvander@1756: return false; dvander@1756: } dvander@1756: } dvander@1756: else dvander@1756: { dvander@1756: pAdmin = NULL; dvander@1756: } dvander@1756: dvander@1756: if (strcmp(info->pattern, "@ct") == 0 || strcmp(info->pattern, "@cts") == 0) dvander@1756: { dvander@1756: team_index = 3; dvander@1756: } dvander@1756: else if (strcmp(info->pattern, "@t") == 0 || strcmp(info->pattern, "@ts") == 0) dvander@1756: { dvander@1756: team_index = 2; dvander@1756: } dvander@1781: else dvander@1781: { dvander@1781: return false; dvander@1781: } dvander@1756: dvander@1756: info->num_targets = 0; dvander@1756: dvander@1756: max_clients = playerhelpers->GetMaxClients(); dvander@1756: for (int i = 1; dvander@1756: i <= max_clients && (cell_t)info->num_targets < info->max_targets; dvander@1756: i++) dvander@1756: { dvander@1756: if ((pPlayer = playerhelpers->GetGamePlayer(i)) == NULL) dvander@1756: { dvander@1756: continue; dvander@1756: } dvander@1756: if (!pPlayer->IsInGame()) dvander@1756: { dvander@1756: continue; dvander@1756: } dvander@1756: if ((pInfo = pPlayer->GetPlayerInfo()) == NULL) dvander@1756: { dvander@1756: continue; dvander@1756: } dvander@1758: if (pInfo->GetTeamIndex() != (int)team_index) dvander@1756: { dvander@1756: continue; dvander@1756: } dvander@1756: if (playerhelpers->FilterCommandTarget(pAdmin, pPlayer, info->flags) dvander@1756: != COMMAND_TARGET_VALID) dvander@1756: { dvander@1756: continue; dvander@1756: } dvander@1756: info->targets[info->num_targets] = i; dvander@1756: info->num_targets++; dvander@1756: } dvander@1756: dvander@1756: if (info->num_targets == 0) dvander@1756: { dvander@1756: info->reason = COMMAND_TARGET_EMPTY_FILTER; dvander@1756: } dvander@1756: else dvander@1756: { dvander@1756: info->reason = COMMAND_TARGET_VALID; dvander@1756: } dvander@1756: dvander@1756: info->target_name_style = COMMAND_TARGETNAME_RAW; dvander@1756: if (team_index == 2) dvander@1756: { dvander@1756: UTIL_Format(info->target_name, info->target_name_maxlength, "Terrorists"); dvander@1756: } dvander@1756: else if (team_index == 3) dvander@1756: { dvander@1756: UTIL_Format(info->target_name, info->target_name_maxlength, "CTs"); dvander@1756: } dvander@1756: dvander@1756: return true; dvander@1756: } dvander@2783: dvander@2790: const char *CStrike::GetExtensionVerString() dvander@2783: { dvander@2783: return SM_FULL_VERSION; dvander@2783: } dvander@2783: dvander@2790: const char *CStrike::GetExtensionDateString() dvander@2783: { dvander@2783: return SM_BUILD_TIMESTAMP; dvander@2783: } dvander@2783: