Clean up TF2 ext CalcCritical code (bug 5894, r=voided).
1.1 --- a/extensions/tf2/criticals.cpp Wed Aug 28 13:46:34 2013 -0400
1.2 +++ b/extensions/tf2/criticals.cpp Thu Aug 29 09:27:35 2013 -0400
1.3 @@ -32,330 +32,169 @@
1.4 #include "criticals.h"
1.5 #include "util.h"
1.6
1.7 -IServerGameEnts *gameents = NULL;
1.8 +CritManager g_CritManager;
1.9 +
1.10 +IForward *g_critForward = nullptr;
1.11 +
1.12 +SH_DECL_MANUALHOOK0(CalcIsAttackCriticalHelper, 0, 0, 0, bool);
1.13 +SH_DECL_MANUALHOOK0(CalcIsAttackCriticalHelperNoCrits, 0, 0, 0, bool);
1.14 +
1.15 +const char TF_WEAPON_DATATABLE[] = "DT_TFWeaponBase";
1.16
1.17 -CDetour *calcIsAttackCriticalDetour = NULL;
1.18 -CDetour *calcIsAttackCriticalMeleeDetour = NULL;
1.19 -CDetour *calcIsAttackCriticalBowDetour = NULL;
1.20 -CDetour *calcIsAttackCriticalKnifeDetour = NULL;
1.21 -CDetour *calcIsAttackCriticalNoCritsDetour = NULL;
1.22 -CDetour *calcIsAttackCriticalNoCritsMeleeDetour = NULL;
1.23 +CritManager::CritManager() :
1.24 + m_enabled(false),
1.25 + m_hooksSetup(false)
1.26 +{
1.27 + m_entsHooked.Init();
1.28 +}
1.29
1.30 -int nextMeleeCritOffset = -1;
1.31 +bool CritManager::TryEnable()
1.32 +{
1.33 + if (!m_hooksSetup)
1.34 + {
1.35 + int offset;
1.36
1.37 -IForward *g_critForward = NULL;
1.38 + if (!g_pGameConf->GetOffset("CalcIsAttackCriticalHelper", &offset))
1.39 + {
1.40 + g_pSM->LogError(myself, "Failed to find CalcIsAttackCriticalHelper offset");
1.41 + return false;
1.42 + }
1.43 +
1.44 + SH_MANUALHOOK_RECONFIGURE(CalcIsAttackCriticalHelper, offset, 0, 0);
1.45
1.46 -enum DetourResult
1.47 -{
1.48 - Result_Ignore,
1.49 - Result_NoCrit,
1.50 - Result_Crit,
1.51 -};
1.52 + if (!g_pGameConf->GetOffset("CalcIsAttackCriticalHelperNoCrits", &offset))
1.53 + {
1.54 + g_pSM->LogError(myself, "Failed to find CalcIsAttackCriticalHelperNoCrits offset");
1.55 + return false;
1.56 + }
1.57 +
1.58 + SH_MANUALHOOK_RECONFIGURE(CalcIsAttackCriticalHelperNoCrits, offset, 0, 0);
1.59 +
1.60 + m_hooksSetup = true;
1.61 + }
1.62
1.63 -int CheckBaseHandle(CBaseHandle &hndl)
1.64 -{
1.65 - if (!hndl.IsValid())
1.66 + for (size_t i = playerhelpers->GetMaxClients() + 1; i < MAX_EDICTS; ++i)
1.67 {
1.68 - return -1;
1.69 + CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(i);
1.70 + if (pEntity == nullptr)
1.71 + continue;
1.72 +
1.73 + IServerUnknown *pUnknown = (IServerUnknown *)pEntity;
1.74 + IServerNetworkable *pNetworkable = pUnknown->GetNetworkable();
1.75 + if (!pNetworkable)
1.76 + continue;
1.77 +
1.78 + if (!UTIL_ContainsDataTable(pNetworkable->GetServerClass()->m_pTable, TF_WEAPON_DATATABLE))
1.79 + continue;
1.80 +
1.81 + SH_ADD_MANUALHOOK(CalcIsAttackCriticalHelper, pEntity, SH_MEMBER(&g_CritManager, &CritManager::Hook_CalcIsAttackCriticalHelpers), false);
1.82 + SH_ADD_MANUALHOOK(CalcIsAttackCriticalHelperNoCrits, pEntity, SH_MEMBER(&g_CritManager, &CritManager::Hook_CalcIsAttackCriticalHelpers), false);
1.83 +
1.84 + m_entsHooked.Set(i);
1.85 }
1.86
1.87 - int index = hndl.GetEntryIndex();
1.88 + m_enabled = true;
1.89
1.90 - edict_t *pStoredEdict;
1.91 + return true;
1.92 +}
1.93
1.94 - pStoredEdict = engine->PEntityOfEntIndex(index);
1.95 +void CritManager::Disable()
1.96 +{
1.97 + int i = m_entsHooked.FindNextSetBit(playerhelpers->GetMaxClients() + 1);
1.98 + for (i; i != -1; i = m_entsHooked.FindNextSetBit(i))
1.99 + {
1.100 + CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(i);
1.101 + SH_REMOVE_MANUALHOOK(CalcIsAttackCriticalHelper, pEntity, SH_MEMBER(&g_CritManager, &CritManager::Hook_CalcIsAttackCriticalHelpers), false);
1.102 + SH_REMOVE_MANUALHOOK(CalcIsAttackCriticalHelperNoCrits, pEntity, SH_MEMBER(&g_CritManager, &CritManager::Hook_CalcIsAttackCriticalHelpers), false);
1.103
1.104 - if (pStoredEdict == NULL)
1.105 - {
1.106 - return -1;
1.107 + m_entsHooked.Set(i, false);
1.108 }
1.109
1.110 - IServerEntity *pSE = pStoredEdict->GetIServerEntity();
1.111 + m_enabled = false;
1.112 +}
1.113
1.114 - if (pSE == NULL)
1.115 - {
1.116 - return -1;
1.117 - }
1.118 +void CritManager::OnEntityCreated(CBaseEntity *pEntity, const char *classname)
1.119 +{
1.120 + if (!m_enabled)
1.121 + return;
1.122
1.123 - if (pSE->GetRefEHandle() != hndl)
1.124 - {
1.125 - return -1;
1.126 - }
1.127 + IServerUnknown *pUnknown = (IServerUnknown *)pEntity;
1.128 + IServerNetworkable *pNetworkable = pUnknown->GetNetworkable();
1.129 + if (!pNetworkable)
1.130 + return;
1.131
1.132 - return index;
1.133 + if (!UTIL_ContainsDataTable(pNetworkable->GetServerClass()->m_pTable, TF_WEAPON_DATATABLE))
1.134 + return;
1.135 +
1.136 + SH_ADD_MANUALHOOK(CalcIsAttackCriticalHelper, pEntity, SH_MEMBER(&g_CritManager, &CritManager::Hook_CalcIsAttackCriticalHelpers), false);
1.137 + SH_ADD_MANUALHOOK(CalcIsAttackCriticalHelperNoCrits, pEntity, SH_MEMBER(&g_CritManager, &CritManager::Hook_CalcIsAttackCriticalHelpers), false);
1.138 +
1.139 + m_entsHooked.Set(gamehelpers->EntityToBCompatRef(pEntity));
1.140 }
1.141
1.142 -DetourResult DetourCallback(CBaseEntity *pEnt, bool bMeleeNoCrits)
1.143 +void CritManager::OnEntityDestroyed(CBaseEntity *pEntity)
1.144 {
1.145 - edict_t *pEdict = gameents->BaseEntityToEdict((CBaseEntity *)pEnt);
1.146 + if (!m_enabled)
1.147 + return;
1.148 +
1.149 + int index = gamehelpers->EntityToBCompatRef(pEntity);
1.150 + if (index < 0 || index >= MAX_EDICTS)
1.151 + return;
1.152 +
1.153 + if (!m_entsHooked.IsBitSet(index))
1.154 + return;
1.155 +
1.156 + SH_REMOVE_MANUALHOOK(CalcIsAttackCriticalHelper, pEntity, SH_MEMBER(&g_CritManager, &CritManager::Hook_CalcIsAttackCriticalHelpers), false);
1.157 + SH_REMOVE_MANUALHOOK(CalcIsAttackCriticalHelperNoCrits, pEntity, SH_MEMBER(&g_CritManager, &CritManager::Hook_CalcIsAttackCriticalHelpers), false);
1.158
1.159 - if (!pEdict)
1.160 + m_entsHooked.Set(index, false);
1.161 +}
1.162 +
1.163 +bool CritManager::Hook_CalcIsAttackCriticalHelpers()
1.164 +{
1.165 + CBaseEntity *pWeapon = META_IFACEPTR(CBaseEntity);
1.166 +
1.167 + // If there's an invalid ent or invalid networkable here, we've got issues elsewhere.
1.168 +
1.169 + IServerNetworkable *pNetWeapon = ((IServerUnknown *)pWeapon)->GetNetworkable();
1.170 + ServerClass *pServerClass = pNetWeapon->GetServerClass();
1.171 + if (!pServerClass)
1.172 {
1.173 - g_pSM->LogMessage(myself, "Entity Error");
1.174 - return Result_Ignore;
1.175 + g_pSM->LogError(myself, "Invalid server class on weapon.");
1.176 + RETURN_META_VALUE(MRES_IGNORED, false);
1.177 }
1.178
1.179 sm_sendprop_info_t info;
1.180 -
1.181 - if (!gamehelpers->FindSendPropInfo(pEdict->GetNetworkable()->GetServerClass()->GetName(), "m_hOwnerEntity", &info))
1.182 + if (!gamehelpers->FindSendPropInfo(pServerClass->GetName(), "m_hOwnerEntity", &info))
1.183 {
1.184 - g_pSM->LogMessage(myself, "Offset Error");
1.185 - return Result_Ignore;
1.186 - }
1.187 -
1.188 - if (!g_critForward)
1.189 - {
1.190 - g_pSM->LogMessage(myself, "Invalid Forward");
1.191 - return Result_Ignore;
1.192 + g_pSM->LogError(myself, "Could not find m_hOwnerEntity on %s", pServerClass->GetName());
1.193 + RETURN_META_VALUE(MRES_IGNORED, false);
1.194 }
1.195
1.196 - int returnValue=0;
1.197 -
1.198 - CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pEnt + info.actual_offset);
1.199 - int index = CheckBaseHandle(hndl);
1.200 + int returnValue = 0;
1.201
1.202 - //Skip CTFWeaponBaseMelee::CalcIsAttackCriticalHelperNoCrits if m_iNextMeleeCrit is not 2
1.203 - if (bMeleeNoCrits)
1.204 + int ownerIndex = -1;
1.205 + CBaseHandle &hndl = *(CBaseHandle *) ((intptr_t)pWeapon + info.actual_offset);
1.206 + CBaseEntity *pHandleEntity = gamehelpers->ReferenceToEntity(hndl.GetEntryIndex());
1.207 +
1.208 + if (pHandleEntity != nullptr && hndl == reinterpret_cast<IHandleEntity *>(pHandleEntity)->GetRefEHandle())
1.209 {
1.210 - CBaseEntity *pPlayer = UTIL_GetCBaseEntity(index, true);
1.211 - if (pPlayer && *(uint32_t *)((intptr_t)pPlayer + nextMeleeCritOffset) != 2)
1.212 - return Result_Ignore;
1.213 + ownerIndex = hndl.GetEntryIndex();
1.214 }
1.215
1.216 - g_critForward->PushCell(index); //Client index
1.217 - g_critForward->PushCell(engine->IndexOfEdict(pEdict)); // Weapon index
1.218 - g_critForward->PushString(pEdict->GetClassName()); //Weapon classname
1.219 + g_critForward->PushCell(ownerIndex); //Client index
1.220 + g_critForward->PushCell(gamehelpers->EntityToBCompatRef(pWeapon)); // Weapon index
1.221 + g_critForward->PushString(gamehelpers->GetEntityClassname(pWeapon)); //Weapon classname
1.222 g_critForward->PushCellByRef(&returnValue); //return value
1.223
1.224 cell_t result = 0;
1.225
1.226 g_critForward->Execute(&result);
1.227
1.228 - if (result)
1.229 - {
1.230 - if (returnValue)
1.231 - {
1.232 - return Result_Crit;
1.233 - }
1.234 - else
1.235 - {
1.236 - return Result_NoCrit;
1.237 - }
1.238 - }
1.239 - else
1.240 - {
1.241 - return Result_Ignore;
1.242 - }
1.243 -}
1.244 -
1.245 -DETOUR_DECL_MEMBER0(CalcIsAttackCriticalHelperMelee, bool)
1.246 -{
1.247 - DetourResult result = DetourCallback((CBaseEntity *)this, false);
1.248 -
1.249 - if (result == Result_Ignore)
1.250 - {
1.251 - return DETOUR_MEMBER_CALL(CalcIsAttackCriticalHelperMelee)();
1.252 - }
1.253 - else if (result == Result_NoCrit)
1.254 - {
1.255 - return 0;
1.256 - }
1.257 - else
1.258 - {
1.259 - return 1;
1.260 - }
1.261 -}
1.262 -
1.263 -DETOUR_DECL_MEMBER0(CalcIsAttackCriticalHelper, bool)
1.264 -{
1.265 - DetourResult result = DetourCallback((CBaseEntity *)this, false);
1.266 -
1.267 - if (result == Result_Ignore)
1.268 - {
1.269 - return DETOUR_MEMBER_CALL(CalcIsAttackCriticalHelper)();
1.270 - }
1.271 - else if (result == Result_NoCrit)
1.272 - {
1.273 - return 0;
1.274 - }
1.275 - else
1.276 - {
1.277 - return 1;
1.278 - }
1.279 -}
1.280 -
1.281 -DETOUR_DECL_MEMBER0(CalcIsAttackCriticalHelperBow, bool)
1.282 -{
1.283 - DetourResult result = DetourCallback((CBaseEntity *)this, false);
1.284 -
1.285 - if (result == Result_Ignore)
1.286 - {
1.287 - return DETOUR_MEMBER_CALL(CalcIsAttackCriticalHelperBow)();
1.288 - }
1.289 - else if (result == Result_NoCrit)
1.290 - {
1.291 - return 0;
1.292 - }
1.293 - else
1.294 - {
1.295 - return 1;
1.296 - }
1.297 -}
1.298 -
1.299 -DETOUR_DECL_MEMBER0(CalcIsAttackCriticalHelperKnife, bool)
1.300 -{
1.301 - DetourResult result = DetourCallback((CBaseEntity *)this, false);
1.302 -
1.303 - if (result == Result_Ignore)
1.304 - {
1.305 - return DETOUR_MEMBER_CALL(CalcIsAttackCriticalHelperKnife)();
1.306 - }
1.307 - else if (result == Result_NoCrit)
1.308 - {
1.309 - return 0;
1.310 - }
1.311 - else
1.312 - {
1.313 - return 1;
1.314 - }
1.315 -}
1.316 -
1.317 -DETOUR_DECL_MEMBER0(CalcIsAttackCriticalHelperNoCrits, bool)
1.318 -{
1.319 - DetourResult result = DetourCallback((CBaseEntity *)this, false);
1.320 -
1.321 - if (result == Result_Ignore)
1.322 - {
1.323 - return DETOUR_MEMBER_CALL(CalcIsAttackCriticalHelperNoCrits)();
1.324 - }
1.325 - else if (result == Result_NoCrit)
1.326 - {
1.327 - return 0;
1.328 - }
1.329 - else
1.330 + if (result && returnValue)
1.331 {
1.332 - return 1;
1.333 - }
1.334 -}
1.335 -
1.336 -DETOUR_DECL_MEMBER0(CalcIsAttackCriticalHelperNoCritsMelee, bool)
1.337 -{
1.338 - DetourResult result = DetourCallback((CBaseEntity *)this, true);
1.339 -
1.340 - if (result == Result_Ignore)
1.341 - {
1.342 - return DETOUR_MEMBER_CALL(CalcIsAttackCriticalHelperNoCritsMelee)();
1.343 - }
1.344 - else if (result == Result_NoCrit)
1.345 - {
1.346 - return 0;
1.347 - }
1.348 - else
1.349 - {
1.350 - return 1;
1.351 - }
1.352 -}
1.353 -
1.354 -bool InitialiseCritDetours()
1.355 -{
1.356 - sm_sendprop_info_t prop;
1.357 -
1.358 - calcIsAttackCriticalDetour = DETOUR_CREATE_MEMBER(CalcIsAttackCriticalHelper, "CalcCritical");
1.359 - calcIsAttackCriticalMeleeDetour = DETOUR_CREATE_MEMBER(CalcIsAttackCriticalHelperMelee, "CalcCriticalMelee");
1.360 - calcIsAttackCriticalBowDetour = DETOUR_CREATE_MEMBER(CalcIsAttackCriticalHelperBow, "CalcCriticalBow");
1.361 - calcIsAttackCriticalKnifeDetour = DETOUR_CREATE_MEMBER(CalcIsAttackCriticalHelperKnife, "CalcCriticalKnife");
1.362 - calcIsAttackCriticalNoCritsDetour = DETOUR_CREATE_MEMBER(CalcIsAttackCriticalHelperNoCrits, "CalcCriticalNoCrits");
1.363 - calcIsAttackCriticalNoCritsMeleeDetour = DETOUR_CREATE_MEMBER(CalcIsAttackCriticalHelperNoCritsMelee, "CalcCriticalNoCritsMelee");
1.364 -
1.365 - bool HookCreated = false;
1.366 -
1.367 - if (calcIsAttackCriticalDetour != NULL)
1.368 - {
1.369 - calcIsAttackCriticalDetour->EnableDetour();
1.370 - HookCreated = true;
1.371 - }
1.372 -
1.373 - if (calcIsAttackCriticalMeleeDetour != NULL)
1.374 - {
1.375 - calcIsAttackCriticalMeleeDetour->EnableDetour();
1.376 - HookCreated = true;
1.377 - }
1.378 -
1.379 - if (calcIsAttackCriticalBowDetour != NULL)
1.380 - {
1.381 - calcIsAttackCriticalBowDetour->EnableDetour();
1.382 - HookCreated = true;
1.383 - }
1.384 -
1.385 - if (calcIsAttackCriticalKnifeDetour != NULL)
1.386 - {
1.387 - calcIsAttackCriticalKnifeDetour->EnableDetour();
1.388 - HookCreated = true;
1.389 - }
1.390 -
1.391 - if (calcIsAttackCriticalNoCritsDetour != NULL)
1.392 - {
1.393 - calcIsAttackCriticalNoCritsDetour->EnableDetour();
1.394 - HookCreated = true;
1.395 - }
1.396 -
1.397 - if (calcIsAttackCriticalNoCritsMeleeDetour != NULL)
1.398 - {
1.399 - calcIsAttackCriticalNoCritsMeleeDetour->EnableDetour();
1.400 - if (!gamehelpers->FindSendPropInfo("CTFPlayer", "m_iNextMeleeCrit", &prop))
1.401 - {
1.402 - g_pSM->LogError(myself, "Failed to find m_iNextMeleeCrit prop offset");
1.403 - return false;
1.404 - }
1.405 - nextMeleeCritOffset = prop.actual_offset;
1.406 - HookCreated = true;
1.407 - }
1.408 -
1.409 - if (HookCreated)
1.410 - {
1.411 - return true;
1.412 - }
1.413 -
1.414 - g_pSM->LogError(myself, "No critical hit forwards could be initialized - Disabled critical hit hooks");
1.415 -
1.416 - return false;
1.417 -}
1.418 -
1.419 -void RemoveCritDetours()
1.420 -{
1.421 - if (calcIsAttackCriticalDetour != NULL)
1.422 - {
1.423 - calcIsAttackCriticalDetour->Destroy();
1.424 - calcIsAttackCriticalDetour = NULL;
1.425 - }
1.426 -
1.427 - if (calcIsAttackCriticalMeleeDetour != NULL)
1.428 - {
1.429 - calcIsAttackCriticalMeleeDetour->Destroy();
1.430 - calcIsAttackCriticalMeleeDetour = NULL;
1.431 - }
1.432 -
1.433 - if (calcIsAttackCriticalBowDetour != NULL)
1.434 - {
1.435 - calcIsAttackCriticalBowDetour->Destroy();
1.436 - calcIsAttackCriticalBowDetour = NULL;
1.437 + RETURN_META_VALUE(MRES_SUPERCEDE, true);
1.438 }
1.439
1.440 - if (calcIsAttackCriticalKnifeDetour != NULL)
1.441 - {
1.442 - calcIsAttackCriticalKnifeDetour->Destroy();
1.443 - calcIsAttackCriticalKnifeDetour = NULL;
1.444 - }
1.445 -
1.446 - if (calcIsAttackCriticalNoCritsDetour != NULL)
1.447 - {
1.448 - calcIsAttackCriticalNoCritsDetour->Destroy();
1.449 - calcIsAttackCriticalNoCritsDetour = NULL;
1.450 - }
1.451 -
1.452 - if (calcIsAttackCriticalNoCritsMeleeDetour != NULL)
1.453 - {
1.454 - calcIsAttackCriticalNoCritsMeleeDetour->Destroy();
1.455 - calcIsAttackCriticalNoCritsMeleeDetour = NULL;
1.456 - }
1.457 + RETURN_META_VALUE(MRES_IGNORED, false);
1.458 }
2.1 --- a/extensions/tf2/criticals.h Wed Aug 28 13:46:34 2013 -0400
2.2 +++ b/extensions/tf2/criticals.h Thu Aug 29 09:27:35 2013 -0400
2.3 @@ -36,12 +36,38 @@
2.4 #include <jit/jit_helpers.h>
2.5 #include <jit/x86/x86_macros.h>
2.6 #include "CDetour/detours.h"
2.7 +#include "ISDKHooks.h"
2.8
2.9 -bool InitialiseCritDetours();
2.10 -void RemoveCritDetours();
2.11 +class CritManager : public ISMEntityListener
2.12 +{
2.13 +public:
2.14 + CritManager();
2.15 +
2.16 +public:
2.17 + bool TryEnable();
2.18 + void Disable();
2.19 +
2.20 + // ISMEntityListener
2.21 +public:
2.22 + virtual void OnEntityCreated(CBaseEntity *pEntity, const char *classname);
2.23 + virtual void OnEntityDestroyed(CBaseEntity *pEntity);
2.24 +
2.25 +private:
2.26 + void HookEntityIfWeapon(CBaseEntity *pEntity);
2.27 + void UnhookEntityIfHooked(CBaseEntity *pEntity);
2.28 +
2.29 +public:
2.30 + // CritHook
2.31 + bool Hook_CalcIsAttackCriticalHelpers();
2.32 +
2.33 +private:
2.34 + bool m_enabled;
2.35 + bool m_hooksSetup;
2.36 + CBitVec<MAX_EDICTS> m_entsHooked;
2.37 +};
2.38 +
2.39 +extern CritManager g_CritManager;
2.40
2.41 extern IForward *g_critForward;
2.42
2.43 -extern IServerGameEnts *gameents;
2.44 -
2.45 #endif //_INCLUDE_SOURCEMOD_CRITICALS_H_
3.1 --- a/extensions/tf2/extension.cpp Wed Aug 28 13:46:34 2013 -0400
3.2 +++ b/extensions/tf2/extension.cpp Thu Aug 29 09:27:35 2013 -0400
3.3 @@ -41,6 +41,7 @@
3.4 #include "gameplayrules.h"
3.5 #include "teleporter.h"
3.6 #include "CDetour/detours.h"
3.7 +#include "ISDKHooks.h"
3.8
3.9 /**
3.10 * @file extension.cpp
3.11 @@ -52,6 +53,7 @@
3.12 IGameConfig *g_pGameConf = NULL;
3.13
3.14 IBinTools *g_pBinTools = NULL;
3.15 +ISDKHooks *g_pSDKHooks = NULL;
3.16
3.17 SMEXT_LINK(&g_TF2Tools);
3.18
3.19 @@ -91,6 +93,7 @@
3.20 }
3.21
3.22 sharesys->AddDependency(myself, "bintools.ext", true, true);
3.23 + sharesys->AddDependency(myself, "sdkhooks.ext", true, true);
3.24
3.25 char conf_error[255] = "";
3.26 if (!gameconfs->LoadGameConfigFile("sm-tf2.games", &g_pGameConf, conf_error, sizeof(conf_error)))
3.27 @@ -151,8 +154,6 @@
3.28
3.29 GET_V_IFACE_CURRENT(GetEngineFactory, icvar, ICvar, CVAR_INTERFACE_VERSION);
3.30
3.31 - GET_V_IFACE_CURRENT(GetServerFactory, gameents, IServerGameEnts, INTERFACEVERSION_SERVERGAMEENTS);
3.32 -
3.33 GET_V_IFACE_CURRENT(GetEngineFactory, m_GameEventManager, IGameEventManager2, INTERFACEVERSION_GAMEEVENTSMANAGER2);
3.34 m_GameEventManager->AddListener(this, "teamplay_restart_round", true);
3.35
3.36 @@ -177,11 +178,22 @@
3.37 forwards->ReleaseForward(g_waitingPlayersStartForward);
3.38 forwards->ReleaseForward(g_waitingPlayersEndForward);
3.39 forwards->ReleaseForward(g_teleportForward);
3.40 +
3.41 + if (g_pSDKHooks != nullptr)
3.42 + {
3.43 + g_pSDKHooks->RemoveEntityListener(&g_CritManager);
3.44 + }
3.45 }
3.46
3.47 void TF2Tools::SDK_OnAllLoaded()
3.48 {
3.49 SM_GET_LATE_IFACE(BINTOOLS, g_pBinTools);
3.50 + SM_GET_LATE_IFACE(SDKHOOKS, g_pSDKHooks);
3.51 +
3.52 + if (g_pSDKHooks != nullptr)
3.53 + {
3.54 + g_pSDKHooks->AddEntityListener(&g_CritManager);
3.55 + }
3.56 }
3.57
3.58 bool TF2Tools::RegisterConCommandBase(ConCommandBase *pVar)
3.59 @@ -198,6 +210,7 @@
3.60 bool TF2Tools::QueryRunning(char *error, size_t maxlength)
3.61 {
3.62 SM_CHECK_IFACE(BINTOOLS, g_pBinTools);
3.63 + SM_GET_LATE_IFACE(SDKHOOKS, g_pSDKHooks);
3.64
3.65 return true;
3.66 }
3.67 @@ -209,6 +222,11 @@
3.68 return false;
3.69 }
3.70
3.71 + if (pInterface == g_pSDKHooks)
3.72 + {
3.73 + return false;
3.74 + }
3.75 +
3.76 return IExtensionInterface::QueryInterfaceDrop(pInterface);
3.77 }
3.78
3.79 @@ -321,7 +339,7 @@
3.80 {
3.81 if (!m_CritDetoursEnabled && g_critForward->GetFunctionCount())
3.82 {
3.83 - m_CritDetoursEnabled = InitialiseCritDetours();
3.84 + m_CritDetoursEnabled = g_CritManager.TryEnable();
3.85 }
3.86
3.87 if (!m_IsHolidayDetourEnabled && g_isHolidayForward->GetFunctionCount())
3.88 @@ -353,7 +371,7 @@
3.89 {
3.90 if (m_CritDetoursEnabled && !g_critForward->GetFunctionCount())
3.91 {
3.92 - RemoveCritDetours();
3.93 + g_CritManager.Disable();
3.94 m_CritDetoursEnabled = false;
3.95 }
3.96 if (m_IsHolidayDetourEnabled && !g_isHolidayForward->GetFunctionCount())
4.1 --- a/extensions/tf2/util.cpp Wed Aug 28 13:46:34 2013 -0400
4.2 +++ b/extensions/tf2/util.cpp Thu Aug 29 09:27:35 2013 -0400
4.3 @@ -88,6 +88,38 @@
4.4 return false;
4.5 }
4.6
4.7 +bool UTIL_ContainsDataTable(SendTable *pTable, const char *name)
4.8 +{
4.9 + const char *pname = pTable->GetName();
4.10 + int props = pTable->GetNumProps();
4.11 + SendProp *prop;
4.12 + SendTable *table;
4.13 +
4.14 + if (pname && strcmp(name, pname) == 0)
4.15 + return true;
4.16 +
4.17 + for (int i = 0; i < props; i++)
4.18 + {
4.19 + prop = pTable->GetProp(i);
4.20 +
4.21 + if ((table = prop->GetDataTable()) != NULL)
4.22 + {
4.23 + pname = table->GetName();
4.24 + if (pname && strcmp(name, pname) == 0)
4.25 + {
4.26 + return true;
4.27 + }
4.28 +
4.29 + if (UTIL_ContainsDataTable(table, name))
4.30 + {
4.31 + return true;
4.32 + }
4.33 + }
4.34 + }
4.35 +
4.36 + return false;
4.37 +}
4.38 +
4.39 ServerClass *UTIL_FindServerClass(const char *classname)
4.40 {
4.41 ServerClass *sc = gamedll->GetAllServerClasses();
5.1 --- a/extensions/tf2/util.h Wed Aug 28 13:46:34 2013 -0400
5.2 +++ b/extensions/tf2/util.h Thu Aug 29 09:27:35 2013 -0400
5.3 @@ -49,6 +49,8 @@
5.4 sm_sendprop_info_t *info,
5.5 unsigned int offset);
5.6
5.7 +bool UTIL_ContainsDataTable(SendTable *pTable, const char *name);
5.8 +
5.9 ServerClass *UTIL_FindServerClass(const char *classname);
5.10
5.11 CBaseEntity *UTIL_GetCBaseEntity(int num, bool onlyPlayers);
6.1 --- a/gamedata/sm-tf2.games.txt Wed Aug 28 13:46:34 2013 -0400
6.2 +++ b/gamedata/sm-tf2.games.txt Thu Aug 29 09:27:35 2013 -0400
6.3 @@ -36,48 +36,6 @@
6.4 "linux" "@_ZN15CTFPlayerShared8DisguiseEiiP9CTFPlayerb"
6.5 "mac" "@_ZN15CTFPlayerShared8DisguiseEiiP9CTFPlayerb"
6.6 }
6.7 - "CalcCritical"
6.8 - {
6.9 - "library" "server"
6.10 - "linux" "@_ZN13CTFWeaponBase26CalcIsAttackCriticalHelperEv"
6.11 - "mac" "@_ZN13CTFWeaponBase26CalcIsAttackCriticalHelperEv"
6.12 - "windows" "\x55\x8B\xEC\x83\xEC\x2A\x56\x57\x6A\x00\x68\x2A\x2A\x2A\x2A\x68\x2A\x2A\x2A\x2A\x6A\x00\x8B\xF1\xE8\x2A\x2A\x2A\x2A\x50\xE8\x2A\x2A\x2A\x2A\x8B\xF8\x83\xC4\x2A\x85\xFF\x74\x2A\x8B"
6.13 - }
6.14 - "CalcCriticalMelee"
6.15 - {
6.16 - "library" "server"
6.17 - "linux" "@_ZN18CTFWeaponBaseMelee26CalcIsAttackCriticalHelperEv"
6.18 - "mac" "@_ZN18CTFWeaponBaseMelee26CalcIsAttackCriticalHelperEv"
6.19 - "windows" "\x55\x8B\xEC\x83\xEC\x08\x53\x56\x8B\xF1\xE8\x2A\x2A\x2A\x2A\x8B\xD8\x85\xDB\x74\x10"
6.20 - }
6.21 - "CalcCriticalBow"
6.22 - {
6.23 - "library" "server"
6.24 - "linux" "@_ZN14CTFCompoundBow26CalcIsAttackCriticalHelperEv"
6.25 - "mac" "@_ZN14CTFCompoundBow26CalcIsAttackCriticalHelperEv"
6.26 - "windows" "\xE8\x2A\x2A\x2A\x2A\x85\xC0\x74\x2A\x8D\x88\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x84\xC0\x74\x2A\xB0"
6.27 - }
6.28 - "CalcCriticalKnife"
6.29 - {
6.30 - "library" "server"
6.31 - "linux" "@_ZN8CTFKnife26CalcIsAttackCriticalHelperEv"
6.32 - "mac" "@_ZN8CTFKnife26CalcIsAttackCriticalHelperEv"
6.33 - "windows" "\x8B\x81\x54\x07\x00\x00\x83\xF8\xFF\x74\x2A\x8B\x15\x2A\x2A\x2A\x2A\x8B\xC8\x81\xE1\xFF\x0F\x00\x00\x03\xC9\x8D\x4C\xCA\x04\xC1\xE8\x0C\x39\x41\x04\x75\x2A\x8B\x01"
6.34 - }
6.35 - "CalcCriticalNoCrits"
6.36 - {
6.37 - "library" "server"
6.38 - "linux" "@_ZN13CTFWeaponBase33CalcIsAttackCriticalHelperNoCritsEv"
6.39 - "mac" "@_ZN13CTFWeaponBase33CalcIsAttackCriticalHelperNoCritsEv"
6.40 - "windows" "\x56\x6A\x00\x68\x2A\x2A\x2A\x2A\x68\x2A\x2A\x2A\x2A\x6A\x00\xE8\x2A\x2A\x2A\x2A\x50\xE8\x2A\x2A\x2A\x2A\x8B\xF0\x83\xC4\x14\x85\xF6\x74\x2A"
6.41 - }
6.42 - "CalcCriticalNoCritsMelee"
6.43 - {
6.44 - "library" "server"
6.45 - "linux" "@_ZN18CTFWeaponBaseMelee33CalcIsAttackCriticalHelperNoCritsEv"
6.46 - "mac" "@_ZN18CTFWeaponBaseMelee33CalcIsAttackCriticalHelperNoCritsEv"
6.47 - "windows" "\x56\x57\x8B\xF9\xE8\x2A\x2A\x2A\x2A\x8B\xF0\x85\xF6\x74\x2A\x8B\x06\x8B\x90\x40\x01\x00\x00\x8B\xCE\xFF\xD2\x84\xC0\x75\x2A\x5F\x32\xC0\x5E\xC3\x83\xBE\x80\x1D\x00\x00\x02"
6.48 - }
6.49 "Regenerate"
6.50 {
6.51 "library" "server"
6.52 @@ -157,6 +115,18 @@
6.53 "linux" "325"
6.54 "mac" "325"
6.55 }
6.56 + "CalcIsAttackCriticalHelper"
6.57 + {
6.58 + "windows" "381"
6.59 + "linux" "388"
6.60 + "mac" "388"
6.61 + }
6.62 + "CalcIsAttackCriticalHelperNoCrits"
6.63 + {
6.64 + "windows" "382"
6.65 + "linux" "389"
6.66 + "mac" "389"
6.67 + }
6.68 }
6.69 }
6.70 }