From 3d25938dd79fd5e21fe223968e24cff3f26be549 Mon Sep 17 00:00:00 2001 From: Ryan Stecker Date: Mon, 28 May 2012 01:14:46 +0100 Subject: [PATCH] Added TF2_CanPlayerTeleport forward to the TF2 game extension (bug 5283, r=asherkin). --- extensions/tf2/AMBuilder | 1 + extensions/tf2/Makefile | 2 +- extensions/tf2/extension.cpp | 14 ++++ extensions/tf2/extension.h | 1 + extensions/tf2/msvc10/tf2.vcxproj | 2 + extensions/tf2/msvc10/tf2.vcxproj.filters | 6 ++ extensions/tf2/msvc9/tf2.vcproj | 8 ++ extensions/tf2/teleporter.cpp | 96 +++++++++++++++++++++++ extensions/tf2/teleporter.h | 43 ++++++++++ gamedata/sm-tf2.games.txt | 7 ++ plugins/include/tf2.inc | 13 +++ 11 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 extensions/tf2/teleporter.cpp create mode 100644 extensions/tf2/teleporter.h diff --git a/extensions/tf2/AMBuilder b/extensions/tf2/AMBuilder index 40d1891a..e68d3a54 100644 --- a/extensions/tf2/AMBuilder +++ b/extensions/tf2/AMBuilder @@ -17,6 +17,7 @@ binary.AddSourceFiles('extensions/tf2', [ 'util.cpp', 'criticals.cpp', 'holiday.cpp', + 'teleporter.cpp', 'gameplayrules.cpp', 'conditions.cpp', 'CDetour/detours.cpp', diff --git a/extensions/tf2/Makefile b/extensions/tf2/Makefile index 80d80cf2..3d4fc458 100644 --- a/extensions/tf2/Makefile +++ b/extensions/tf2/Makefile @@ -19,7 +19,7 @@ PROJECT = game.tf2 USEMETA = true OBJECTS = sdk/smsdk_ext.cpp extension.cpp natives.cpp RegNatives.cpp criticals.cpp \ - holiday.cpp gameplayrules.cpp conditions.cpp util.cpp CDetour/detours.cpp asm/asm.c + holiday.cpp gameplayrules.cpp conditions.cpp util.cpp teleporter.cpp CDetour/detours.cpp asm/asm.c ############################################## ### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ### diff --git a/extensions/tf2/extension.cpp b/extensions/tf2/extension.cpp index e38d9176..3473d4ab 100644 --- a/extensions/tf2/extension.cpp +++ b/extensions/tf2/extension.cpp @@ -39,6 +39,7 @@ #include "holiday.h" #include "conditions.h" #include "gameplayrules.h" +#include "teleporter.h" #include "CDetour/detours.h" /** @@ -117,6 +118,7 @@ bool TF2Tools::SDK_OnLoad(char *error, size_t maxlength, bool late) g_removeCondForward = forwards->CreateForward("TF2_OnConditionRemoved", ET_Ignore, 2, NULL, Param_Cell, Param_Cell); g_waitingPlayersStartForward = forwards->CreateForward("TF2_OnWaitingForPlayersStart", ET_Ignore, 0, NULL); g_waitingPlayersEndForward = forwards->CreateForward("TF2_OnWaitingForPlayersEnd", ET_Ignore, 0, NULL); + g_teleportForward = forwards->CreateForward("TF2_OnPlayerTeleport", ET_Hook, 3, NULL, Param_Cell, Param_Cell, Param_CellByRef); g_pCVar = icvar; @@ -124,6 +126,7 @@ bool TF2Tools::SDK_OnLoad(char *error, size_t maxlength, bool late) m_IsHolidayDetourEnabled = false; m_CondChecksEnabled = false; m_RulesDetoursEnabled = false; + m_TeleportDetourEnabled = false; return true; } @@ -173,6 +176,7 @@ void TF2Tools::SDK_OnUnload() forwards->ReleaseForward(g_removeCondForward); forwards->ReleaseForward(g_waitingPlayersStartForward); forwards->ReleaseForward(g_waitingPlayersEndForward); + forwards->ReleaseForward(g_teleportForward); } void TF2Tools::SDK_OnAllLoaded() @@ -338,6 +342,11 @@ void TF2Tools::OnPluginLoaded(IPlugin *plugin) { m_RulesDetoursEnabled = InitialiseRulesDetours(); } + + if (!m_TeleportDetourEnabled && g_teleportForward->GetFunctionCount()) + { + m_TeleportDetourEnabled = InitialiseTeleporterDetour(); + } } void TF2Tools::OnPluginUnloaded(IPlugin *plugin) @@ -368,6 +377,11 @@ void TF2Tools::OnPluginUnloaded(IPlugin *plugin) m_RulesDetoursEnabled = false; } } + if (m_TeleportDetourEnabled && !g_teleportForward->GetFunctionCount()) + { + RemoveTeleporterDetour(); + m_TeleportDetourEnabled = false; + } } void TF2Tools::OnClientPutInServer(int client) diff --git a/extensions/tf2/extension.h b/extensions/tf2/extension.h index 71187733..4fefd35b 100644 --- a/extensions/tf2/extension.h +++ b/extensions/tf2/extension.h @@ -121,6 +121,7 @@ private: bool m_IsHolidayDetourEnabled; bool m_CondChecksEnabled; bool m_RulesDetoursEnabled; + bool m_TeleportDetourEnabled; }; enum TFClassType diff --git a/extensions/tf2/msvc10/tf2.vcxproj b/extensions/tf2/msvc10/tf2.vcxproj index 40ca0dc4..600742e1 100644 --- a/extensions/tf2/msvc10/tf2.vcxproj +++ b/extensions/tf2/msvc10/tf2.vcxproj @@ -114,6 +114,7 @@ + @@ -126,6 +127,7 @@ + diff --git a/extensions/tf2/msvc10/tf2.vcxproj.filters b/extensions/tf2/msvc10/tf2.vcxproj.filters index b3c7ce85..464dbac1 100644 --- a/extensions/tf2/msvc10/tf2.vcxproj.filters +++ b/extensions/tf2/msvc10/tf2.vcxproj.filters @@ -57,6 +57,9 @@ asm + + Source Files + @@ -95,5 +98,8 @@ asm + + Header Files + \ No newline at end of file diff --git a/extensions/tf2/msvc9/tf2.vcproj b/extensions/tf2/msvc9/tf2.vcproj index 6c723002..63651933 100644 --- a/extensions/tf2/msvc9/tf2.vcproj +++ b/extensions/tf2/msvc9/tf2.vcproj @@ -215,6 +215,10 @@ RelativePath="..\RegNatives.cpp" > + + @@ -249,6 +253,10 @@ RelativePath="..\RegNatives.h" > + + diff --git a/extensions/tf2/teleporter.cpp b/extensions/tf2/teleporter.cpp new file mode 100644 index 00000000..6a308a14 --- /dev/null +++ b/extensions/tf2/teleporter.cpp @@ -0,0 +1,96 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod Team Fortress 2 Extension + * Copyright (C) 2004-2008 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$ + */ + +#include "teleporter.h" + +CDetour *canPlayerTeleportDetour = NULL; + +IForward *g_teleportForward = NULL; + +class CTFPlayer; + +DETOUR_DECL_MEMBER1(CanPlayerBeTeleported, bool, CTFPlayer *, pPlayer) +{ + bool origCanTeleport = DETOUR_MEMBER_CALL(CanPlayerBeTeleported)(pPlayer); + + cell_t teleporterCell = gamehelpers->EntityToBCompatRef((CBaseEntity *)this); + cell_t playerCell = gamehelpers->EntityToBCompatRef((CBaseEntity *)pPlayer); + + if (!g_teleportForward) + { + g_pSM->LogMessage(myself, "Teleport forward is invalid"); + return origCanTeleport; + } + + cell_t returnValue = origCanTeleport ? 1 : 0; + + g_teleportForward->PushCell(playerCell); // client + g_teleportForward->PushCell(teleporterCell); // teleporter + g_teleportForward->PushCellByRef(&returnValue); // return value + + cell_t result = 0; + + g_teleportForward->Execute(&result); + + if (result > Pl_Continue) + { + // plugin wants to override the game (returned something other than Plugin_Continue) + return returnValue == 1; + } + else + { + return origCanTeleport; // let the game decide + } +} + +bool InitialiseTeleporterDetour() +{ + canPlayerTeleportDetour = DETOUR_CREATE_MEMBER(CanPlayerBeTeleported, "CanPlayerTeleport"); + + if (canPlayerTeleportDetour != NULL) + { + canPlayerTeleportDetour->EnableDetour(); + return true; + } + + g_pSM->LogError(myself, "Teleport forward could not be initialized - Disabled hook"); + + return false; +} + +void RemoveTeleporterDetour() +{ + if (canPlayerTeleportDetour != NULL) + { + canPlayerTeleportDetour->Destroy(); + canPlayerTeleportDetour = NULL; + } +} diff --git a/extensions/tf2/teleporter.h b/extensions/tf2/teleporter.h new file mode 100644 index 00000000..ae28037f --- /dev/null +++ b/extensions/tf2/teleporter.h @@ -0,0 +1,43 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod Team Fortress 2 Extension + * Copyright (C) 2004-2008 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_SOURCEMOD_TELEPORTER_H_ +#define _INCLUDE_SOURCEMOD_TELEPORTER_H_ + +#include "extension.h" +#include "CDetour/detours.h" + +bool InitialiseTeleporterDetour(); +void RemoveTeleporterDetour(); + +extern IForward *g_teleportForward; + +#endif //_INCLUDE_SOURCEMOD_TELEPORTER_H_ diff --git a/gamedata/sm-tf2.games.txt b/gamedata/sm-tf2.games.txt index 1273d37d..d68d9b3f 100644 --- a/gamedata/sm-tf2.games.txt +++ b/gamedata/sm-tf2.games.txt @@ -120,6 +120,13 @@ "linux" "@_Z21DuelMiniGame_IsInDuelP9CTFPlayer" "mac" "@_Z21DuelMiniGame_IsInDuelP9CTFPlayer" } + "CanPlayerTeleport" + { + "library" "server" + "windows" "\x55\x8b\xec\x53\x8b\x5d\x08\x85\xdb\x56\x8b\xf1\x74\x2A\x8b\xcb\xe8\x2A\x2A\x2A\x2A\x84\xc0" + "linux" "@_ZN17CObjectTeleporter21PlayerCanBeTeleportedEP9CTFPlayer" + "mac" "@_ZN17CObjectTeleporter21PlayerCanBeTeleportedEP9CTFPlayer" + } } "Offsets" { diff --git a/plugins/include/tf2.inc b/plugins/include/tf2.inc index 6017c09e..cc7d6baa 100644 --- a/plugins/include/tf2.inc +++ b/plugins/include/tf2.inc @@ -339,6 +339,19 @@ forward TF2_OnWaitingForPlayersStart(); */ forward TF2_OnWaitingForPlayersEnd(); +/** + * Called when a player attempts to use a teleporter to decide if the player should be allowed to teleport. + * Return Plugin_Continue to let the original calculation or return a higher + * action to override the decision with the value of 'result' + * + * @param client Client index. + * @param teleporter Teleporter entity index. + * @param result Buffer param for the result of the decision. + * This is prepopulated with the game's original decision to let a player teleport. + * @return Plugin_Continue for original calculation, higher value to use 'result'. + */ +forward Action:TF2_OnPlayerTeleport(client, teleporter, &bool:result); + /** * Do not edit below this line! */