From 457e757f027dc48eb432e940bbc877a0943efd35 Mon Sep 17 00:00:00 2001 From: Mikusch Date: Thu, 24 Nov 2022 11:53:01 +0100 Subject: [PATCH] Add support for relative gamedata offsets (#22) * Add support for relative gamedata offsets * Remove debug log * Formatting * Alphabetically --- README.md | 6 +- addons/sourcemod/gamedata/prophunt.txt | 27 +++-- addons/sourcemod/scripting/prophunt.sp | 30 ++--- .../sourcemod/scripting/prophunt/console.sp | 2 +- .../sourcemod/scripting/prophunt/convars.sp | 2 +- addons/sourcemod/scripting/prophunt/dhooks.sp | 6 +- addons/sourcemod/scripting/prophunt/events.sp | 2 +- .../sourcemod/scripting/prophunt/helpers.sp | 20 ++-- .../sourcemod/scripting/prophunt/offsets.sp | 108 ++++++++++++++++++ .../sourcemod/scripting/prophunt/sdkcalls.sp | 25 +--- 10 files changed, 149 insertions(+), 79 deletions(-) create mode 100644 addons/sourcemod/scripting/prophunt/offsets.sp diff --git a/README.md b/README.md index 7c1af68..99d8b79 100644 --- a/README.md +++ b/README.md @@ -23,12 +23,12 @@ AlliedModders forum thread: https://forums.alliedmods.net/showthread.php?p=27712 ## Requirements -* SourceMod 1.10+ +* SourceMod 1.11+ * [StaticProps](https://github.com/sigsegv-mvm/StaticProps) * [TF2Items](https://github.com/asherkin/TF2Items) * [TF2 Econ Data](https://github.com/nosoop/SM-TFEconData) -* [TF2Attributes](https://github.com/nosoop/tf2attributes) -* [DHooks 2 with Detour Support](https://github.com/peace-maker/DHooks2/tree/dynhooks) (included in SM 1.11) +* [TF2Attributes](https://github.com/FlaminSarge/tf2attributes) +* [TF2 Utils](https://github.com/nosoop/SM-TFUtils) * [More Colors](https://github.com/DoctorMcKay/sourcemod-plugins/blob/master/scripting/include/morecolors.inc) (compile only) ## Special Thanks diff --git a/addons/sourcemod/gamedata/prophunt.txt b/addons/sourcemod/gamedata/prophunt.txt index dbdc9ad..02a0e86 100644 --- a/addons/sourcemod/gamedata/prophunt.txt +++ b/addons/sourcemod/gamedata/prophunt.txt @@ -19,6 +19,14 @@ { "tf" { + "Keys" + { + "CTFWeaponBase_BaseOffset" + { + "linux" "m_flEffectBarRegenTime" + "windows" "m_flEffectBarRegenTime" + } + } "Signatures" { "CTFPlayer::GetMaxHealthForBuffing" @@ -74,11 +82,6 @@ "linux" "163" "windows" "162" } - "CBaseEntity::GetBaseEntity" - { - "linux" "6" - "windows" "5" - } "CBaseEntity::Spawn" { "linux" "23" @@ -136,18 +139,18 @@ } "CTFWeaponBase::m_iWeaponMode" { - "linux" "1704" - "windows" "1700" + "linux" "4" + "windows" "4" } "CTFWeaponBase::m_pWeaponInfo" { - "linux" "1716" - "windows" "1712" + "linux" "16" + "windows" "16" } - "CTFPlayerShared::m_pOuter" + "sizeof(WeaponData_t)" { - "linux" "400" - "windows" "400" + "linux" "58" + "windows" "58" } "WeaponData_t::m_nDamage" { diff --git a/addons/sourcemod/scripting/prophunt.sp b/addons/sourcemod/scripting/prophunt.sp index 17d1d8a..8b0e793 100644 --- a/addons/sourcemod/scripting/prophunt.sp +++ b/addons/sourcemod/scripting/prophunt.sp @@ -26,11 +26,12 @@ #include #include #include +#include #pragma semicolon 1 #pragma newdecls required -#define PLUGIN_VERSION "1.5.0" +#define PLUGIN_VERSION "1.6.0" #define PLUGIN_TAG "[{orange}PropHunt{default}]" @@ -117,14 +118,6 @@ Handle g_ControlPointBonusTimer; // Forwards GlobalForward g_ForwardOnPlayerDisguised; -// Offsets -int g_OffsetWeaponMode; -int g_OffsetWeaponInfo; -int g_OffsetPlayerSharedOuter; -int g_OffsetWeaponDamage; -int g_OffsetWeaponBulletsPerShot; -int g_OffsetWeaponTimeFireDelay; - // ConVars ConVar ph_enable; ConVar ph_prop_min_size; @@ -159,6 +152,7 @@ ConVar ph_gravity_modifier; #include "prophunt/dhooks.sp" #include "prophunt/events.sp" #include "prophunt/helpers.sp" +#include "prophunt/offsets.sp" #include "prophunt/sdkcalls.sp" #include "prophunt/sdkhooks.sp" @@ -176,9 +170,9 @@ public void OnPluginStart() LoadTranslations("common.phrases"); LoadTranslations("prophunt.phrases"); - Console_Initialize(); - ConVars_Initialize(); - Events_Initialize(); + Console_Init(); + ConVars_Init(); + Events_Init(); g_PropConfigs = new ArrayList(sizeof(PropConfig)); @@ -189,15 +183,9 @@ public void OnPluginStart() GameData gamedata = new GameData("prophunt"); if (gamedata) { - DHooks_Initialize(gamedata); - SDKCalls_Initialize(gamedata); - - g_OffsetWeaponMode = gamedata.GetOffset("CTFWeaponBase::m_iWeaponMode"); - g_OffsetWeaponInfo = gamedata.GetOffset("CTFWeaponBase::m_pWeaponInfo"); - g_OffsetPlayerSharedOuter = gamedata.GetOffset("CTFPlayerShared::m_pOuter"); - g_OffsetWeaponDamage = gamedata.GetOffset("WeaponData_t::m_nDamage"); - g_OffsetWeaponBulletsPerShot = gamedata.GetOffset("WeaponData_t::m_nBulletsPerShot"); - g_OffsetWeaponTimeFireDelay = gamedata.GetOffset("WeaponData_t::m_flTimeFireDelay"); + DHooks_Init(gamedata); + Offsets_Init(gamedata); + SDKCalls_Init(gamedata); delete gamedata; } diff --git a/addons/sourcemod/scripting/prophunt/console.sp b/addons/sourcemod/scripting/prophunt/console.sp index fdac72c..ba2d385 100644 --- a/addons/sourcemod/scripting/prophunt/console.sp +++ b/addons/sourcemod/scripting/prophunt/console.sp @@ -18,7 +18,7 @@ #pragma semicolon 1 #pragma newdecls required -void Console_Initialize() +void Console_Init() { RegAdminCmd("sm_getmodel", ConCmd_GetModel, ADMFLAG_CHEATS); RegAdminCmd("sm_setmodel", ConCmd_SetModel, ADMFLAG_CHEATS); diff --git a/addons/sourcemod/scripting/prophunt/convars.sp b/addons/sourcemod/scripting/prophunt/convars.sp index 92b490b..5bcef38 100644 --- a/addons/sourcemod/scripting/prophunt/convars.sp +++ b/addons/sourcemod/scripting/prophunt/convars.sp @@ -30,7 +30,7 @@ enum struct ConVarData static StringMap g_ConVars; -void ConVars_Initialize() +void ConVars_Init() { g_ConVars = new StringMap(); diff --git a/addons/sourcemod/scripting/prophunt/dhooks.sp b/addons/sourcemod/scripting/prophunt/dhooks.sp index 7dbd467..6146e20 100644 --- a/addons/sourcemod/scripting/prophunt/dhooks.sp +++ b/addons/sourcemod/scripting/prophunt/dhooks.sp @@ -37,7 +37,7 @@ static DynamicHook g_DHookHasKnockback; static int g_OldGameType; -void DHooks_Initialize(GameData gamedata) +void DHooks_Init(GameData gamedata) { g_DynamicDetours = new ArrayList(sizeof(DetourData)); g_DynamicHookIds = new ArrayList(); @@ -299,9 +299,9 @@ static MRESReturn DHookCallback_HookTarget_Post(int projectile, DHookParam param return MRES_Ignored; } -static MRESReturn DHookCallback_Heal_Pre(Address playerShared, DHookParam params) +static MRESReturn DHookCallback_Heal_Pre(Address pShared, DHookParam params) { - int player = GetPlayerSharedOuter(playerShared); + int player = TF2Util_GetPlayerFromSharedAddress(pShared); // Reduce healing from continuous sources (except control point bonus) if (!TF2_IsPlayerInCondition(player, TFCond_HalloweenQuickHeal)) diff --git a/addons/sourcemod/scripting/prophunt/events.sp b/addons/sourcemod/scripting/prophunt/events.sp index b05f093..6604567 100644 --- a/addons/sourcemod/scripting/prophunt/events.sp +++ b/addons/sourcemod/scripting/prophunt/events.sp @@ -29,7 +29,7 @@ enum struct EventData static ArrayList g_Events; -void Events_Initialize() +void Events_Init() { g_Events = new ArrayList(sizeof(EventData)); diff --git a/addons/sourcemod/scripting/prophunt/helpers.sp b/addons/sourcemod/scripting/prophunt/helpers.sp index 15b7470..f2a4772 100644 --- a/addons/sourcemod/scripting/prophunt/helpers.sp +++ b/addons/sourcemod/scripting/prophunt/helpers.sp @@ -138,35 +138,29 @@ bool IsWeaponBaseMelee(int entity) return HasEntProp(entity, Prop_Data, "CTFWeaponBaseMeleeSmack"); } -int GetWeaponData(int weapon) +any GetWeaponData(int weapon) { - int weaponMode = GetEntData(weapon, g_OffsetWeaponMode); - int weaponInfo = GetEntData(weapon, g_OffsetWeaponInfo); - return weaponInfo + (WEAPONDATA_SIZE * weaponMode); + int weaponMode = GetEntData(weapon, GetOffset("CTFWeaponBase", "m_iWeaponMode")); + int weaponInfo = GetEntData(weapon, GetOffset("CTFWeaponBase", "m_pWeaponInfo")); + return weaponInfo + (GetOffset(NULL_STRING, "sizeof(WeaponData_t)") * weaponMode); } int GetWeaponDamage(int weapon) { // m_pWeaponInfo->GetWeaponData( m_iWeaponMode ).m_nDamage - return LoadFromAddress(view_as
(GetWeaponData(weapon) + g_OffsetWeaponDamage), NumberType_Int32); + return LoadFromAddress(GetWeaponData(weapon) + GetOffset("WeaponData_t", "m_nDamage"), NumberType_Int32); } int GetWeaponBulletsPerShot(int weapon) { // m_pWeaponInfo->GetWeaponData( m_iWeaponMode ).m_nBulletsPerShot - return LoadFromAddress(view_as
(GetWeaponData(weapon) + g_OffsetWeaponBulletsPerShot), NumberType_Int32); + return LoadFromAddress(GetWeaponData(weapon) + GetOffset("WeaponData_t", "m_nBulletsPerShot"), NumberType_Int32); } float GetWeaponTimeFireDelay(int weapon) { // m_pWeaponInfo->GetWeaponData( m_iWeaponMode ).m_flTimeFireDelay - return view_as(LoadFromAddress(view_as
(GetWeaponData(weapon) + g_OffsetWeaponTimeFireDelay), NumberType_Int32)); -} - -int GetPlayerSharedOuter(Address playerShared) -{ - Address outer = view_as
(LoadFromAddress(playerShared + view_as
(g_OffsetPlayerSharedOuter), NumberType_Int32)); - return SDKCall_GetBaseEntity(outer); + return view_as(LoadFromAddress(GetWeaponData(weapon) + GetOffset("WeaponData_t", "m_flTimeFireDelay"), NumberType_Int32)); } bool GetConfigByModel(const char[] model, PropConfig config) diff --git a/addons/sourcemod/scripting/prophunt/offsets.sp b/addons/sourcemod/scripting/prophunt/offsets.sp new file mode 100644 index 0000000..a6069c6 --- /dev/null +++ b/addons/sourcemod/scripting/prophunt/offsets.sp @@ -0,0 +1,108 @@ +/** + * Copyright (C) 2021 Mikusch + * + * 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 3 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, see . + */ + +#pragma semicolon 1 +#pragma newdecls required + +static StringMap g_offsets; + +void Offsets_Init(GameData gamedata) +{ + g_offsets = new StringMap(); + + SetOffset(gamedata, "CTFWeaponBase", "m_iWeaponMode"); + SetOffset(gamedata, "CTFWeaponBase", "m_pWeaponInfo"); + + SetOffset(gamedata, NULL_STRING, "sizeof(WeaponData_t)"); + SetOffset(gamedata, "WeaponData_t", "m_nDamage"); + SetOffset(gamedata, "WeaponData_t", "m_nBulletsPerShot"); + SetOffset(gamedata, "WeaponData_t", "m_flTimeFireDelay"); +} + +any GetOffset(const char[] cls, const char[] prop) +{ + int offset; + + if (IsNullString(cls)) + { + if (!g_offsets.GetValue(prop, offset)) + { + ThrowError("Offset '%s' not present in map", prop); + } + } + else + { + char key[64]; + Format(key, sizeof(key), "%s::%s", cls, prop); + + if (!g_offsets.GetValue(key, offset)) + { + ThrowError("Offset '%s' not present in map", key); + } + } + + return offset; +} + +static void SetOffset(GameData gamedata, const char[] cls, const char[] prop) +{ + if (IsNullString(cls)) + { + // Simple gamedata key lookup + int offset = gamedata.GetOffset(prop); + if (offset == -1) + { + ThrowError("Offset '%s' could not be found", prop); + } + + g_offsets.SetValue(prop, offset); + } + else + { + char key[64], base_key[64], base_prop[64]; + Format(key, sizeof(key), "%s::%s", cls, prop); + Format(base_key, sizeof(base_key), "%s_BaseOffset", cls); + + // Get the actual offset, calculated using a base offset if present + if (gamedata.GetKeyValue(base_key, base_prop, sizeof(base_prop))) + { + int base_offset = FindSendPropInfo(cls, base_prop); + if (base_offset == -1) + { + // If we found nothing, search on CBaseEntity instead + base_offset = FindSendPropInfo("CBaseEntity", base_prop); + if (base_offset == -1) + { + ThrowError("Base offset '%s::%s' could not be found", cls, base_prop); + } + } + + int offset = base_offset + gamedata.GetOffset(key); + g_offsets.SetValue(key, offset); + } + else + { + int offset = gamedata.GetOffset(key); + if (offset == -1) + { + ThrowError("Offset '%s' could not be found", key); + } + + g_offsets.SetValue(key, offset); + } + } +} diff --git a/addons/sourcemod/scripting/prophunt/sdkcalls.sp b/addons/sourcemod/scripting/prophunt/sdkcalls.sp index bce6322..2457cea 100644 --- a/addons/sourcemod/scripting/prophunt/sdkcalls.sp +++ b/addons/sourcemod/scripting/prophunt/sdkcalls.sp @@ -22,20 +22,18 @@ static Handle g_SDKCallCastSelfHeal; static Handle g_SDKCallFindCriterionIndex; static Handle g_SDKCallRemoveCriteria; static Handle g_SDKCallSetSwitchTeams; -static Handle g_SDKCallGetBaseEntity; static Handle g_SDKCallGetDamageType; static Handle g_SDKCallInitClass; static Handle g_SDKCallGetProjectileDamage; static Handle g_SDKCallGetMeleeDamage; static Handle g_SDKCallJarGetDamage; -void SDKCalls_Initialize(GameData gamedata) +void SDKCalls_Init(GameData gamedata) { g_SDKCallCastSelfHeal = PrepSDKCall_CastSelfHeal(gamedata); g_SDKCallFindCriterionIndex = PrepSDKCall_FindCriterionIndex(gamedata); g_SDKCallRemoveCriteria = PrepSDKCall_RemoveCriteria(gamedata); g_SDKCallSetSwitchTeams = PrepSDKCall_SetSwitchTeams(gamedata); - g_SDKCallGetBaseEntity = PrepSDKCall_GetBaseEntity(gamedata); g_SDKCallGetDamageType = PrepSDKCall_GetDamageType(gamedata); g_SDKCallInitClass = PrepSDKCall_InitClass(gamedata); g_SDKCallGetProjectileDamage = PrepSDKCall_GetProjectileDamage(gamedata); @@ -97,19 +95,6 @@ static Handle PrepSDKCall_SetSwitchTeams(GameData gamedata) return call; } -static Handle PrepSDKCall_GetBaseEntity(GameData gamedata) -{ - StartPrepSDKCall(SDKCall_Raw); - PrepSDKCall_SetFromConf(gamedata, SDKConf_Virtual, "CBaseEntity::GetBaseEntity"); - PrepSDKCall_SetReturnInfo(SDKType_CBaseEntity, SDKPass_Pointer); - - Handle call = EndPrepSDKCall(); - if (!call) - LogMessage("Failed to create SDKCall: CBaseEntity::GetBaseEntity"); - - return call; -} - static Handle PrepSDKCall_GetDamageType(GameData gamedata) { StartPrepSDKCall(SDKCall_Entity); @@ -205,14 +190,6 @@ void SDKCall_SetSwitchTeams(bool shouldSwitch) SDKCall(g_SDKCallSetSwitchTeams, shouldSwitch); } -int SDKCall_GetBaseEntity(Address address) -{ - if (g_SDKCallGetBaseEntity) - return SDKCall(g_SDKCallGetBaseEntity, address); - else - return -1; -} - int SDKCall_GetDamageType(int entity) { if (g_SDKCallGetDamageType)