Switch TF2 extension to hook CTFGameRules::IsHolidayActive for holiday forward (bug 6137).
This commit is contained in:
parent
210759907d
commit
151c6d246e
@ -42,6 +42,7 @@
|
||||
#include "teleporter.h"
|
||||
#include "CDetour/detours.h"
|
||||
#include "ISDKHooks.h"
|
||||
#include "ISDKTools.h"
|
||||
|
||||
/**
|
||||
* @file extension.cpp
|
||||
@ -54,6 +55,7 @@ IGameConfig *g_pGameConf = NULL;
|
||||
|
||||
IBinTools *g_pBinTools = NULL;
|
||||
ISDKHooks *g_pSDKHooks = NULL;
|
||||
ISDKTools *g_pSDKTools = NULL;
|
||||
|
||||
SMEXT_LINK(&g_TF2Tools);
|
||||
|
||||
@ -94,6 +96,7 @@ bool TF2Tools::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
||||
|
||||
sharesys->AddDependency(myself, "bintools.ext", true, true);
|
||||
sharesys->AddDependency(myself, "sdkhooks.ext", true, true);
|
||||
sharesys->AddDependency(myself, "sdktools.ext", false, true);
|
||||
|
||||
char conf_error[255] = "";
|
||||
if (!gameconfs->LoadGameConfigFile("sm-tf2.games", &g_pGameConf, conf_error, sizeof(conf_error)))
|
||||
@ -116,7 +119,6 @@ bool TF2Tools::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
||||
playerhelpers->AddClientListener(this);
|
||||
|
||||
g_critForward = forwards->CreateForward("TF2_CalcIsAttackCritical", ET_Hook, 4, NULL, Param_Cell, Param_Cell, Param_String, Param_CellByRef);
|
||||
g_isHolidayForward = forwards->CreateForward("TF2_OnIsHolidayActive", ET_Event, 2, NULL, Param_Cell, Param_CellByRef);
|
||||
g_addCondForward = forwards->CreateForward("TF2_OnConditionAdded", ET_Ignore, 2, NULL, Param_Cell, Param_Cell);
|
||||
g_removeCondForward = forwards->CreateForward("TF2_OnConditionRemoved", ET_Ignore, 2, NULL, Param_Cell, Param_Cell);
|
||||
g_waitingPlayersStartForward = forwards->CreateForward("TF2_OnWaitingForPlayersStart", ET_Ignore, 0, NULL);
|
||||
@ -126,11 +128,13 @@ bool TF2Tools::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
||||
g_pCVar = icvar;
|
||||
|
||||
m_CritDetoursEnabled = false;
|
||||
m_IsHolidayDetourEnabled = false;
|
||||
m_IsHolidayHookEnabled = false;
|
||||
m_CondChecksEnabled = false;
|
||||
m_RulesDetoursEnabled = false;
|
||||
m_TeleportDetourEnabled = false;
|
||||
|
||||
g_HolidayManager.OnSDKLoad(late);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -164,6 +168,8 @@ void TF2Tools::SDK_OnUnload()
|
||||
{
|
||||
SH_REMOVE_HOOK(IServerGameDLL, ServerActivate, gamedll, SH_STATIC(OnServerActivate), true);
|
||||
|
||||
g_HolidayManager.OnSDKUnload();
|
||||
|
||||
g_RegNatives.UnregisterAll();
|
||||
gameconfs->CloseGameConfigFile(g_pGameConf);
|
||||
playerhelpers->UnregisterCommandTargetProcessor(this);
|
||||
@ -172,7 +178,6 @@ void TF2Tools::SDK_OnUnload()
|
||||
plsys->RemovePluginsListener(this);
|
||||
|
||||
forwards->ReleaseForward(g_critForward);
|
||||
forwards->ReleaseForward(g_isHolidayForward);
|
||||
forwards->ReleaseForward(g_addCondForward);
|
||||
forwards->ReleaseForward(g_removeCondForward);
|
||||
forwards->ReleaseForward(g_waitingPlayersStartForward);
|
||||
@ -189,6 +194,7 @@ void TF2Tools::SDK_OnAllLoaded()
|
||||
{
|
||||
SM_GET_LATE_IFACE(BINTOOLS, g_pBinTools);
|
||||
SM_GET_LATE_IFACE(SDKHOOKS, g_pSDKHooks);
|
||||
SM_GET_LATE_IFACE(SDKTOOLS, g_pSDKTools);
|
||||
|
||||
if (g_pSDKHooks != NULL)
|
||||
{
|
||||
@ -227,6 +233,11 @@ bool TF2Tools::QueryInterfaceDrop(SMInterface *pInterface)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pInterface == g_pSDKTools)
|
||||
{
|
||||
g_pSDKTools = NULL;
|
||||
}
|
||||
|
||||
return IExtensionInterface::QueryInterfaceDrop(pInterface);
|
||||
}
|
||||
|
||||
@ -238,6 +249,7 @@ void TF2Tools::NotifyInterfaceDrop(SMInterface *pInterface)
|
||||
void OnServerActivate(edict_t *pEdictList, int edictCount, int clientMax)
|
||||
{
|
||||
g_resourceEntity = FindResourceEntity();
|
||||
g_HolidayManager.OnServerActivated();
|
||||
}
|
||||
|
||||
bool TF2Tools::ProcessCommandTarget(cmd_target_info_t *info)
|
||||
@ -342,11 +354,6 @@ void TF2Tools::OnPluginLoaded(IPlugin *plugin)
|
||||
m_CritDetoursEnabled = g_CritManager.TryEnable();
|
||||
}
|
||||
|
||||
if (!m_IsHolidayDetourEnabled && g_isHolidayForward->GetFunctionCount())
|
||||
{
|
||||
m_IsHolidayDetourEnabled = InitialiseIsHolidayDetour();
|
||||
}
|
||||
|
||||
if (!m_CondChecksEnabled
|
||||
&& ( g_addCondForward->GetFunctionCount() || g_removeCondForward->GetFunctionCount() )
|
||||
)
|
||||
@ -374,11 +381,6 @@ void TF2Tools::OnPluginUnloaded(IPlugin *plugin)
|
||||
g_CritManager.Disable();
|
||||
m_CritDetoursEnabled = false;
|
||||
}
|
||||
if (m_IsHolidayDetourEnabled && !g_isHolidayForward->GetFunctionCount())
|
||||
{
|
||||
RemoveIsHolidayDetour();
|
||||
m_IsHolidayDetourEnabled = false;
|
||||
}
|
||||
if (m_CondChecksEnabled)
|
||||
{
|
||||
if (!g_addCondForward->GetFunctionCount() && !g_removeCondForward->GetFunctionCount())
|
||||
|
@ -42,6 +42,10 @@
|
||||
#include <server_class.h>
|
||||
#include <igameevents.h>
|
||||
|
||||
namespace SourceMod {
|
||||
class ISDKTools;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sample implementation of the SDK Extension.
|
||||
* Note: Uncomment one of the pre-defined virtual functions in order to use it.
|
||||
@ -116,7 +120,7 @@ public:
|
||||
#endif
|
||||
private:
|
||||
bool m_CritDetoursEnabled;
|
||||
bool m_IsHolidayDetourEnabled;
|
||||
bool m_IsHolidayHookEnabled;
|
||||
bool m_CondChecksEnabled;
|
||||
bool m_RulesDetoursEnabled;
|
||||
bool m_TeleportDetourEnabled;
|
||||
@ -139,6 +143,7 @@ enum TFClassType
|
||||
TFClassType ClassnameToType(const char *classname);
|
||||
|
||||
extern IBinTools *g_pBinTools;
|
||||
extern ISDKTools *g_pSDKTools;
|
||||
extern IGameConfig *g_pGameConf;
|
||||
extern sm_sendprop_info_t *playerSharedOffset;
|
||||
|
||||
|
@ -31,49 +31,143 @@
|
||||
|
||||
#include "holiday.h"
|
||||
|
||||
CDetour *isHolidayDetour = NULL;
|
||||
SH_DECL_MANUALHOOK1(IsHolidayActive, 0, 0, 0, bool, int);
|
||||
SH_DECL_HOOK0_void(IServerGameDLL, LevelShutdown, SH_NOATTRIB, 0);
|
||||
|
||||
IForward *g_isHolidayForward = NULL;
|
||||
HolidayManager g_HolidayManager;
|
||||
|
||||
DETOUR_DECL_STATIC1(IsHolidayActive, bool, int, holiday)
|
||||
HolidayManager::HolidayManager() :
|
||||
m_iHookID(0),
|
||||
m_isHolidayForward(NULL),
|
||||
m_bInMap(false)
|
||||
{
|
||||
bool actualres = DETOUR_STATIC_CALL(IsHolidayActive)(holiday);
|
||||
if (!g_isHolidayForward)
|
||||
}
|
||||
|
||||
void HolidayManager::OnSDKLoad(bool bLate)
|
||||
{
|
||||
m_bInMap = bLate;
|
||||
|
||||
plsys->AddPluginsListener(this);
|
||||
m_isHolidayForward = forwards->CreateForward("TF2_OnIsHolidayActive", ET_Event, 2, NULL, Param_Cell, Param_CellByRef);
|
||||
|
||||
SH_ADD_HOOK(IServerGameDLL, LevelShutdown, gamedll, SH_MEMBER(this, &HolidayManager::Hook_LevelShutdown), false);
|
||||
}
|
||||
|
||||
void HolidayManager::OnSDKUnload()
|
||||
{
|
||||
UnhookIfNecessary();
|
||||
SH_REMOVE_HOOK(IServerGameDLL, LevelShutdown, gamedll, SH_MEMBER(this, &HolidayManager::Hook_LevelShutdown), false);
|
||||
|
||||
plsys->RemovePluginsListener(this);
|
||||
forwards->ReleaseForward(m_isHolidayForward);
|
||||
}
|
||||
|
||||
void HolidayManager::OnServerActivated()
|
||||
{
|
||||
m_bInMap = true;
|
||||
|
||||
HookIfNecessary();
|
||||
}
|
||||
|
||||
void HolidayManager::Hook_LevelShutdown()
|
||||
{
|
||||
// GameRules is going away momentarily. Unhook before it does.
|
||||
UnhookIfNecessary();
|
||||
|
||||
m_bInMap = false;
|
||||
}
|
||||
|
||||
void HolidayManager::HookIfNecessary()
|
||||
{
|
||||
// Already hooked
|
||||
if (m_iHookID)
|
||||
return;
|
||||
|
||||
// Nothing wants us
|
||||
if (m_isHolidayForward->GetFunctionCount() == 0)
|
||||
return;
|
||||
|
||||
void *pGameRules = GetGameRules();
|
||||
if (!pGameRules)
|
||||
{
|
||||
if (m_bInMap)
|
||||
{
|
||||
g_pSM->LogError(myself, "Gamerules ptr not found. TF2_OnIsHolidayActive will not be available.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static int offset = -1;
|
||||
if (offset == -1)
|
||||
{
|
||||
if (!g_pGameConf->GetOffset("IsHolidayActive", &offset))
|
||||
{
|
||||
g_pSM->LogError(myself, "IsHolidayActive gamedata offset missing. TF2_OnIsHolidayActive will not be available.");
|
||||
return;
|
||||
}
|
||||
|
||||
SH_MANUALHOOK_RECONFIGURE(IsHolidayActive, offset, 0, 0);
|
||||
}
|
||||
|
||||
m_iHookID = SH_ADD_MANUALHOOK(IsHolidayActive, pGameRules, SH_MEMBER(this, &HolidayManager::Hook_IsHolidayActive), false);
|
||||
}
|
||||
|
||||
void HolidayManager::UnhookIfNecessary()
|
||||
{
|
||||
// Not hooked
|
||||
if (!m_iHookID)
|
||||
return;
|
||||
|
||||
// We're still wanted
|
||||
if (m_isHolidayForward->GetFunctionCount() > 0)
|
||||
return;
|
||||
|
||||
if (m_iHookID)
|
||||
{
|
||||
SH_REMOVE_HOOK_ID(m_iHookID);
|
||||
m_iHookID = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void HolidayManager::OnPluginLoaded(IPlugin *plugin)
|
||||
{
|
||||
HookIfNecessary();
|
||||
}
|
||||
|
||||
void HolidayManager::OnPluginUnloaded(IPlugin *plugin)
|
||||
{
|
||||
UnhookIfNecessary();
|
||||
}
|
||||
|
||||
bool HolidayManager::Hook_IsHolidayActive(int holiday)
|
||||
{
|
||||
void *pGameRules = NULL;
|
||||
if (g_pSDKTools)
|
||||
{
|
||||
pGameRules = g_pSDKTools->GetGameRules();
|
||||
}
|
||||
|
||||
if (pGameRules)
|
||||
{
|
||||
bool actualres = SH_MCALL(pGameRules, IsHolidayActive)(holiday);
|
||||
if (!m_isHolidayForward)
|
||||
{
|
||||
g_pSM->LogMessage(myself, "Invalid Forward");
|
||||
return actualres;
|
||||
RETURN_META_VALUE(MRES_IGNORED, true);
|
||||
}
|
||||
|
||||
cell_t result = 0;
|
||||
cell_t newres = actualres ? 1 : 0;
|
||||
|
||||
g_isHolidayForward->PushCell(holiday);
|
||||
g_isHolidayForward->PushCellByRef(&newres);
|
||||
g_isHolidayForward->Execute(&result);
|
||||
m_isHolidayForward->PushCell(holiday);
|
||||
m_isHolidayForward->PushCellByRef(&newres);
|
||||
m_isHolidayForward->Execute(&result);
|
||||
|
||||
if (result > Pl_Continue)
|
||||
{
|
||||
return (newres == 0) ? false : true;
|
||||
RETURN_META_VALUE(MRES_SUPERCEDE, (newres == 0) ? false : true);
|
||||
}
|
||||
}
|
||||
|
||||
return actualres;
|
||||
}
|
||||
|
||||
bool InitialiseIsHolidayDetour()
|
||||
{
|
||||
isHolidayDetour = DETOUR_CREATE_STATIC(IsHolidayActive, "IsHolidayActive");
|
||||
|
||||
if (isHolidayDetour != NULL)
|
||||
{
|
||||
isHolidayDetour->EnableDetour();
|
||||
return true;
|
||||
}
|
||||
|
||||
g_pSM->LogError(myself, "IsHolidayActive detour failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
void RemoveIsHolidayDetour()
|
||||
{
|
||||
isHolidayDetour->Destroy();
|
||||
RETURN_META_VALUE(MRES_IGNORED, true);
|
||||
}
|
||||
|
@ -33,13 +33,46 @@
|
||||
#define _INCLUDE_SOURCEMOD_HOLIDAY_H_
|
||||
|
||||
#include "extension.h"
|
||||
#include <jit/jit_helpers.h>
|
||||
#include <jit/x86/x86_macros.h>
|
||||
#include "CDetour/detours.h"
|
||||
#include <ISDKTools.h>
|
||||
|
||||
bool InitialiseIsHolidayDetour();
|
||||
void RemoveIsHolidayDetour();
|
||||
class HolidayManager : public IPluginsListener
|
||||
{
|
||||
public:
|
||||
HolidayManager();
|
||||
|
||||
extern IForward *g_isHolidayForward;
|
||||
public:
|
||||
void OnSDKLoad(bool bLate);
|
||||
void OnSDKUnload();
|
||||
void OnServerActivated();
|
||||
|
||||
public: //IPluginsListener
|
||||
void OnPluginLoaded(IPlugin *plugin);
|
||||
void OnPluginUnloaded(IPlugin *plugin);
|
||||
|
||||
public:
|
||||
bool Hook_IsHolidayActive(int holiday);
|
||||
void Hook_LevelShutdown();
|
||||
|
||||
private:
|
||||
bool IsHookEnabled() const { return m_iHookID != 0; }
|
||||
void *GetGameRules();
|
||||
void HookIfNecessary();
|
||||
void UnhookIfNecessary();
|
||||
|
||||
private:
|
||||
int m_iHookID;
|
||||
IForward *m_isHolidayForward;
|
||||
bool m_bInMap;
|
||||
};
|
||||
|
||||
inline void *HolidayManager::GetGameRules()
|
||||
{
|
||||
if (!g_pSDKTools)
|
||||
return NULL;
|
||||
|
||||
return g_pSDKTools->GetGameRules();
|
||||
}
|
||||
|
||||
extern HolidayManager g_HolidayManager;
|
||||
|
||||
#endif //_INCLUDE_SOURCEMOD_HOLIDAY_H_
|
||||
|
@ -78,13 +78,6 @@
|
||||
"linux" "@_ZN15CTFPlayerShared10StunPlayerEffiP9CTFPlayer"
|
||||
"mac" "@_ZN15CTFPlayerShared10StunPlayerEffiP9CTFPlayer"
|
||||
}
|
||||
"IsHolidayActive"
|
||||
{
|
||||
"library" "server"
|
||||
"windows" "\x55\x8B\xEC\xA1\x2A\x2A\x2A\x2A\x83\x78\x30\x00\x74\x04\x32\xC0"
|
||||
"linux" "@_Z18TF_IsHolidayActivei"
|
||||
"mac" "@_Z18TF_IsHolidayActivei"
|
||||
}
|
||||
"MakeBleed"
|
||||
{
|
||||
"library" "server"
|
||||
@ -106,6 +99,15 @@
|
||||
"linux" "@_ZN17CObjectTeleporter21PlayerCanBeTeleportedEP9CTFPlayer"
|
||||
"mac" "@_ZN17CObjectTeleporter21PlayerCanBeTeleportedEP9CTFPlayer"
|
||||
}
|
||||
|
||||
// Obsolete
|
||||
"IsHolidayActive"
|
||||
{
|
||||
"library" "server"
|
||||
"windows" "\x55\x8B\xEC\xA1\x2A\x2A\x2A\x2A\x83\x78\x30\x00\x74\x04\x32\xC0"
|
||||
"linux" "@_Z18TF_IsHolidayActivei"
|
||||
"mac" "@_Z18TF_IsHolidayActivei"
|
||||
}
|
||||
}
|
||||
"Offsets"
|
||||
{
|
||||
@ -127,6 +129,14 @@
|
||||
"linux" "391"
|
||||
"mac" "391"
|
||||
}
|
||||
|
||||
// CTFGameRules::IsHolidayActive
|
||||
"IsHolidayActive"
|
||||
{
|
||||
"windows" "138"
|
||||
"linux" "139"
|
||||
"mac" "139"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user