diff --git a/extensions/sdktools/Makefile b/extensions/sdktools/Makefile index 3023bc40..eb92d33c 100644 --- a/extensions/sdktools/Makefile +++ b/extensions/sdktools/Makefile @@ -14,9 +14,9 @@ PROJECT = sdktools #Uncomment for SourceMM-enabled extensions LINK_HL2 = $(HL2LIB)/tier1_i486.a $(HL2LIB)/mathlib_i486.a vstdlib_i486.so tier0_i486.so -OBJECTS = sdk/smsdk_ext.cpp extension.cpp gamerules.cpp vdecoder.cpp vcallbuilder.cpp \ - vcaller.cpp vnatives.cpp vsound.cpp tenatives.cpp trnatives.cpp tempents.cpp vstringtable.cpp \ - vhelpers.cpp voice.cpp +OBJECTS = sdk/smsdk_ext.cpp extension.cpp vdecoder.cpp vcallbuilder.cpp vcaller.cpp \ + vnatives.cpp vsound.cpp tenatives.cpp trnatives.cpp tempents.cpp vstringtable.cpp \ + vhelpers.cpp vglobals.cpp voice.cpp ############################################## ### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ### diff --git a/extensions/sdktools/extension.cpp b/extensions/sdktools/extension.cpp index ea11b22c..eae9bd95 100644 --- a/extensions/sdktools/extension.cpp +++ b/extensions/sdktools/extension.cpp @@ -34,8 +34,8 @@ #include "vcallbuilder.h" #include "vnatives.h" #include "vhelpers.h" +#include "vglobals.h" #include "tempents.h" -#include "gamerules.h" /** * @file extension.cpp @@ -52,10 +52,10 @@ IBinTools *g_pBinTools = NULL; IGameConfig *g_pGameConf = NULL; IGameHelpers *g_pGameHelpers = NULL; IServerGameClients *serverClients = NULL; +IVoiceServer *voiceserver = NULL; IPlayerInfoManager *playerinfomngr = NULL; HandleType_t g_CallHandle = 0; HandleType_t g_TraceHandle = 0; -IVoiceServer *voiceserver = NULL; SMEXT_LINK(&g_SdkTools); @@ -143,7 +143,7 @@ void SDKTools::SDK_OnAllLoaded() SM_GET_LATE_IFACE(BINTOOLS, g_pBinTools); g_TEManager.Initialize(); - InitializeGameRules(); + InitializeValveGlobals(); } bool SDKTools::QueryRunning(char *error, size_t maxlength) diff --git a/extensions/sdktools/gamerules.h b/extensions/sdktools/gamerules.h deleted file mode 100644 index e39801b2..00000000 --- a/extensions/sdktools/gamerules.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * vim: set ts=4 : - * ================================================================ - * SourceMod SDKTools Extension - * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved. - * ================================================================ - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License, - * version 3.0, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to - * link the code of this program (as well as its derivative works) to - * "Half-Life 2," the "Source Engine," the "SourcePawn JIT," and any - * Game MODs that run on software by the Valve Corporation. You must - * obey the GNU General Public License in all respects for all other - * code used. Additionally, AlliedModders LLC grants this exception - * to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version - * JULY-31-2007), or . - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SDKTOOLS_GAMERULES_H_ -#define _INCLUDE_SDKTOOLS_GAMERULES_H_ - -extern void **g_pGameRules; - -void InitializeGameRules(); - -#endif // _INCLUDE_SDKTOOLS_GAMERULES_H_ diff --git a/extensions/sdktools/msvc8/sdktools.vcproj b/extensions/sdktools/msvc8/sdktools.vcproj index ba77f491..b218dd4f 100644 --- a/extensions/sdktools/msvc8/sdktools.vcproj +++ b/extensions/sdktools/msvc8/sdktools.vcproj @@ -187,10 +187,6 @@ RelativePath="..\extension.cpp" > - - @@ -215,6 +211,10 @@ RelativePath="..\vdecoder.cpp" > + + @@ -249,10 +249,6 @@ RelativePath="..\extension.h" > - - @@ -265,6 +261,10 @@ RelativePath="..\vdecoder.h" > + + diff --git a/extensions/sdktools/vcallbuilder.cpp b/extensions/sdktools/vcallbuilder.cpp index 15ea6444..7288ba4e 100644 --- a/extensions/sdktools/vcallbuilder.cpp +++ b/extensions/sdktools/vcallbuilder.cpp @@ -156,10 +156,11 @@ ValveCall *CreateValveCall(void *addr, thisinfo->flags = PASSFLAG_BYVAL; thisinfo->decflags = 0; break; - case ValveCall_GameRules: + default: thisinfo->vtype = Valve_POD; thisinfo->flags = PASSFLAG_ASPOINTER; thisinfo->decflags = 0; + break; } thisinfo->encflags = 0; thisinfo->offset = 0; @@ -340,7 +341,7 @@ ValveCall *CreateValveVCall(unsigned int vtableIdx, vc->thisinfo->flags = PASSFLAG_BYVAL; vc->thisinfo->decflags = 0; break; - case ValveCall_GameRules: + default: vc->thisinfo->vtype = Valve_POD; vc->thisinfo->flags = PASSFLAG_ASPOINTER; vc->thisinfo->decflags = 0; diff --git a/extensions/sdktools/vcaller.cpp b/extensions/sdktools/vcaller.cpp index 5d0453dc..df7c38f6 100644 --- a/extensions/sdktools/vcaller.cpp +++ b/extensions/sdktools/vcaller.cpp @@ -32,7 +32,7 @@ #include "extension.h" #include "vcallbuilder.h" -#include "gamerules.h" +#include "vglobals.h" enum SDKLibrary { @@ -296,6 +296,17 @@ static cell_t SDKCall(IPluginContext *pContext, const cell_t *params) *(void **)ptr = gamerules; } break; + case ValveCall_EntityList: + { + if (g_EntList == NULL) + { + vc->stk_put(ptr); + return pContext->ThrowNativeError("EntityList unsupported or not available; file a bug report"); + } + + *(void **)ptr = g_EntList; + } + break; } } diff --git a/extensions/sdktools/vdecoder.h b/extensions/sdktools/vdecoder.h index 4934f22b..34116d05 100644 --- a/extensions/sdktools/vdecoder.h +++ b/extensions/sdktools/vdecoder.h @@ -80,6 +80,7 @@ enum ValveCallType ValveCall_Entity, /**< Thiscall (CBaseEntity implicit first parameter) */ ValveCall_Player, /**< Thiscall (CBasePlayer implicit first parameter) */ ValveCall_GameRules, /**< Thiscall (CGameRules implicit first paramater) */ + ValveCall_EntityList, /**< Thiscall (CGlobalEntityList implicit first paramater) */ }; /** diff --git a/extensions/sdktools/gamerules.cpp b/extensions/sdktools/vglobals.cpp similarity index 51% rename from extensions/sdktools/gamerules.cpp rename to extensions/sdktools/vglobals.cpp index 848754ec..35dcb58d 100644 --- a/extensions/sdktools/gamerules.cpp +++ b/extensions/sdktools/vglobals.cpp @@ -1,46 +1,38 @@ -/** - * vim: set ts=4 : - * ================================================================ - * SourceMod SDKTools Extension - * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved. - * ================================================================ - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License, - * version 3.0, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to - * link the code of this program (as well as its derivative works) to - * "Half-Life 2," the "Source Engine," the "SourcePawn JIT," and any - * Game MODs that run on software by the Valve Corporation. You must - * obey the GNU General Public License in all respects for all other - * code used. Additionally, AlliedModders LLC grants this exception - * to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version - * JULY-31-2007), or . - * - * Version: $Id$ +/** + * vim: set ts=4 : + * =============================================================== + * SourceMod SDK Tools Extension + * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved. + * =============================================================== + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Version: $Id$ */ #include "extension.h" void **g_pGameRules = NULL; - -void InitializeGameRules() -{ - char *addr = NULL; +void *g_EntList = NULL; #ifdef PLATFORM_WINDOWS - int offset = 0; +void InitializeValveGlobals() +{ + char *addr = NULL; + int offset; + /* g_pGameRules */ if (!g_pGameConf->GetMemSig("CreateGameRulesObject", (void **)&addr) || !addr) { return; @@ -49,14 +41,36 @@ void InitializeGameRules() { return; } - g_pGameRules = *reinterpret_cast(addr + offset); + + /* gEntList and/or g_pEntityList */ + if (!g_pGameConf->GetMemSig("LevelShutdown", (void **)&addr) || !addr) + { + return; + } + if (!g_pGameConf->GetOffset("gEntList", &offset) || !offset) + { + return; + } + g_EntList = *reinterpret_cast(addr + offset); +} #elif defined PLATFORM_LINUX +void InitializeValveGlobals() +{ + char *addr = NULL; + + /* g_pGameRules */ if (!g_pGameConf->GetMemSig("g_pGameRules", (void **)&addr) || !addr) { return; } - g_pGameRules = reinterpret_cast(addr); -#endif + + /* gEntList and/or g_pEntityList */ + if (!g_pGameConf->GetMemSig("gEntList", (void **)&addr) || !addr) + { + return; + } + g_EntList = reinterpret_cast(addr); } +#endif diff --git a/extensions/sdktools/vglobals.h b/extensions/sdktools/vglobals.h new file mode 100644 index 00000000..0b26c59a --- /dev/null +++ b/extensions/sdktools/vglobals.h @@ -0,0 +1,32 @@ +/** + * vim: set ts=4 : + * =============================================================== + * SourceMod SDK Tools Extension + * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved. + * =============================================================== + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Version: $Id$ + */ + +#ifndef _INCLUDE_SDKTOOLS_VGLOBALS_H_ +#define _INCLUDE_SDKTOOLS_VGLOBALS_H_ + +extern void **g_pGameRules; +extern void *g_EntList; + +void InitializeValveGlobals(); + +#endif // _INCLUDE_SDKTOOLS_VGLOBALS_H_ diff --git a/extensions/sdktools/vnatives.cpp b/extensions/sdktools/vnatives.cpp index 13e3e277..ad9e8ed7 100644 --- a/extensions/sdktools/vnatives.cpp +++ b/extensions/sdktools/vnatives.cpp @@ -36,6 +36,7 @@ #include "vcallbuilder.h" #include "vnatives.h" #include "vhelpers.h" +#include "vglobals.h" #include "CellRecipientFilter.h" List g_RegCalls; @@ -212,7 +213,7 @@ static cell_t GetPlayerWeaponSlot(IPluginContext *pContext, const cell_t *params return engine->IndexOfEdict(pEdict); } -static cell_t IgnitePlayer(IPluginContext *pContext, const cell_t *params) +static cell_t IgniteEntity(IPluginContext *pContext, const cell_t *params) { static ValveCall *pCall = NULL; if (!pCall) @@ -241,7 +242,7 @@ static cell_t IgnitePlayer(IPluginContext *pContext, const cell_t *params) return 1; } -static cell_t ExtinguishPlayer(IPluginContext *pContext, const cell_t *params) +static cell_t ExtinguishEntity(IPluginContext *pContext, const cell_t *params) { static ValveCall *pCall = NULL; if (!pCall) @@ -261,7 +262,7 @@ static cell_t ExtinguishPlayer(IPluginContext *pContext, const cell_t *params) return 1; } -static cell_t TeleportPlayer(IPluginContext *pContext, const cell_t *params) +static cell_t TeleportEntity(IPluginContext *pContext, const cell_t *params) { static ValveCall *pCall = NULL; if (!pCall) @@ -564,6 +565,44 @@ static cell_t GetClientEyeAngles(IPluginContext *pContext, const cell_t *params) return 1; } +static cell_t FindEntityByClassname(IPluginContext *pContext, const cell_t *params) +{ + static ValveCall *pCall = NULL; + if (!pCall) + { + ValvePassInfo pass[3]; + InitPass(pass[0], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL, VDECODE_FLAG_ALLOWNULL|VDECODE_FLAG_ALLOWWORLD); + InitPass(pass[1], Valve_String, PassType_Basic, PASSFLAG_BYVAL); + InitPass(pass[2], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL); + if (!CreateBaseCall("FindEntityByClassname", ValveCall_EntityList, &pass[2], pass, 2, &pCall)) + { + return pContext->ThrowNativeError("\"FindEntityByClassname\" not supported by this mod"); + } else if (!pCall) { + return pContext->ThrowNativeError("\"FindEntityByClassname\" wrapper failed to initialized"); + } + } + + CBaseEntity *pEntity; + START_CALL(); + *(void **)vptr = g_EntList; + DECODE_VALVE_PARAM(1, vparams, 0); + DECODE_VALVE_PARAM(2, vparams, 1); + FINISH_CALL_SIMPLE(&pEntity); + + if (pEntity == NULL) + { + return -1; + } + + edict_t *pEdict = gameents->BaseEntityToEdict(pEntity); + if (!pEdict) + { + return -1; + } + + return engine->IndexOfEdict(pEdict); +} + static cell_t IsPlayerAlive(IPluginContext *pContext, const cell_t *params) { IGamePlayer *player = playerhelpers->GetGamePlayer(params[1]); @@ -600,21 +639,22 @@ static cell_t IsPlayerAlive(IPluginContext *pContext, const cell_t *params) sp_nativeinfo_t g_Natives[] = { - {"ExtinguishPlayer", ExtinguishPlayer}, - {"ExtinguishEntity", ExtinguishPlayer}, + {"ExtinguishPlayer", ExtinguishEntity}, + {"ExtinguishEntity", ExtinguishEntity}, {"ForcePlayerSuicide", ForcePlayerSuicide}, {"GivePlayerItem", GiveNamedItem}, {"GetPlayerWeaponSlot", GetPlayerWeaponSlot}, - {"IgnitePlayer", IgnitePlayer}, - {"IgniteEntity", IgnitePlayer}, + {"IgnitePlayer", IgniteEntity}, + {"IgniteEntity", IgniteEntity}, {"RemovePlayerItem", RemovePlayerItem}, - {"TeleportPlayer", TeleportPlayer}, - {"TeleportEntity", TeleportPlayer}, + {"TeleportPlayer", TeleportEntity}, + {"TeleportEntity", TeleportEntity}, {"SetClientViewEntity", SetClientViewEntity}, {"SetLightStyle", SetLightStyle}, {"SlapPlayer", SlapPlayer}, {"GetClientEyePosition", GetClientEyePosition}, {"GetClientEyeAngles", GetClientEyeAngles}, + {"FindEntityByClassname", FindEntityByClassname}, {"IsPlayerAlive", IsPlayerAlive}, {NULL, NULL}, }; diff --git a/gamedata/sdktools.games.txt b/gamedata/sdktools.games.txt index 81cc68f9..d9e1910d 100644 --- a/gamedata/sdktools.games.txt +++ b/gamedata/sdktools.games.txt @@ -124,6 +124,53 @@ } } } + + /* CGlobalEntityList */ + "#default" + { + "#supported" + { + "game" "cstrike" + "game" "dod" + "game" "garrysmod" + "game" "hl2mp" + "game" "ship" + "game" "!Insurgency" + "game" "!Pirates, Vikings and Knights II" + "game" "!SourceForts v1.9.2" + } + + "Offsets" + { + /* Offset into LevelShutdown */ + "gEntList" + { + "windows" "11" + } + } + + "Signatures" + { + "LevelShutdown" + { + "library" "server" + "windows" "\xE8\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xB9\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xE8" + } + "gEntList" + { + "library" "server" + "linux" "@gEntList" + } + + /* Functions in CGlobalEntityList */ + "FindEntityByClassname" + { + "library" "server" + "windows" "\x53\x55\x56\x8B\xF1\x8B\x4C\x24\x2A\x85\xC9\x57\x74\x2A\x8B\x01\xFF\x50\x2A\x8B\x08\x81\xE1\x2A\x2A\x2A\x2A\x83\xC1\x2A\xC1\xE1\x2A\x8B\x3C\x31\xEB\x2A\x8B\xBE\x2A\x2A\x2A\x2A\x85\xFF\x74\x2A\x8B\x5C\x24\x2A\x8B\x2D\x2A\x2A\x2A\x2A\x8D\x9B\x00\x00\x00\x00\x8B\x37\x85\xF6\x75\x2A\x68\x2A\x2A\x2A\x2A\xFF\x2A\x83\xC4\x2A\xEB\x2A\x39" + "linux" "@_ZN17CGlobalEntityList21FindEntityByClassnameEP11CBaseEntityPKc" + } + } + } /* Counter-Strike: Source */ "cstrike" diff --git a/plugins/include/sdktools.inc b/plugins/include/sdktools.inc index 272e5194..8664b91b 100644 --- a/plugins/include/sdktools.inc +++ b/plugins/include/sdktools.inc @@ -36,6 +36,7 @@ enum SDKCallType SDKCall_Entity, /**< CBaseEntity call */ SDKCall_Player, /**< CBasePlayer call */ SDKCall_GameRules, /**< CGameRules call */ + SDKCall_EntityList, /**< CGlobalEntityList call */ }; enum SDKLibrary diff --git a/plugins/include/sdktools_functions.inc b/plugins/include/sdktools_functions.inc index 6f2b8c55..f5687287 100644 --- a/plugins/include/sdktools_functions.inc +++ b/plugins/include/sdktools_functions.inc @@ -104,6 +104,17 @@ native ForcePlayerSuicide(client); */ native SlapPlayer(client, health=5, bool:sound=true); +/** + * Searches for an entity by classname. + * + * @param startEnt The entity index to begin searching from. + * Use -1 to start from the first entity. + * @param classname Classname of the entity to find. + * @return Entity index >= 0 if found, -1 otherwise. + * @error Lack of mod support. + */ +native FindEntityByClassname(startEnt, const String:classname[]); + /** * Returns the client's eye angles. *