Skip to content

Commit

Permalink
Add support for relative gamedata offsets (#22)
Browse files Browse the repository at this point in the history
* Add support for relative gamedata offsets

* Remove debug log

* Formatting

* Alphabetically
  • Loading branch information
Mikusch authored Nov 24, 2022
1 parent 30d484c commit 457e757
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 79 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
27 changes: 15 additions & 12 deletions addons/sourcemod/gamedata/prophunt.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@
{
"tf"
{
"Keys"
{
"CTFWeaponBase_BaseOffset"
{
"linux" "m_flEffectBarRegenTime"
"windows" "m_flEffectBarRegenTime"
}
}
"Signatures"
{
"CTFPlayer::GetMaxHealthForBuffing"
Expand Down Expand Up @@ -74,11 +82,6 @@
"linux" "163"
"windows" "162"
}
"CBaseEntity::GetBaseEntity"
{
"linux" "6"
"windows" "5"
}
"CBaseEntity::Spawn"
{
"linux" "23"
Expand Down Expand Up @@ -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"
{
Expand Down
30 changes: 9 additions & 21 deletions addons/sourcemod/scripting/prophunt.sp
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@
#include <tf2attributes>
#include <tf2items>
#include <tf_econ_data>
#include <tf2utils>

#pragma semicolon 1
#pragma newdecls required

#define PLUGIN_VERSION "1.5.0"
#define PLUGIN_VERSION "1.6.0"

#define PLUGIN_TAG "[{orange}PropHunt{default}]"

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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"

Expand All @@ -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));

Expand All @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion addons/sourcemod/scripting/prophunt/console.sp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion addons/sourcemod/scripting/prophunt/convars.sp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ enum struct ConVarData

static StringMap g_ConVars;

void ConVars_Initialize()
void ConVars_Init()
{
g_ConVars = new StringMap();

Expand Down
6 changes: 3 additions & 3 deletions addons/sourcemod/scripting/prophunt/dhooks.sp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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))
Expand Down
2 changes: 1 addition & 1 deletion addons/sourcemod/scripting/prophunt/events.sp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ enum struct EventData

static ArrayList g_Events;

void Events_Initialize()
void Events_Init()
{
g_Events = new ArrayList(sizeof(EventData));

Expand Down
20 changes: 7 additions & 13 deletions addons/sourcemod/scripting/prophunt/helpers.sp
Original file line number Diff line number Diff line change
Expand Up @@ -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<Address>(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<Address>(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<float>(LoadFromAddress(view_as<Address>(GetWeaponData(weapon) + g_OffsetWeaponTimeFireDelay), NumberType_Int32));
}

int GetPlayerSharedOuter(Address playerShared)
{
Address outer = view_as<Address>(LoadFromAddress(playerShared + view_as<Address>(g_OffsetPlayerSharedOuter), NumberType_Int32));
return SDKCall_GetBaseEntity(outer);
return view_as<float>(LoadFromAddress(GetWeaponData(weapon) + GetOffset("WeaponData_t", "m_flTimeFireDelay"), NumberType_Int32));
}

bool GetConfigByModel(const char[] model, PropConfig config)
Expand Down
108 changes: 108 additions & 0 deletions addons/sourcemod/scripting/prophunt/offsets.sp
Original file line number Diff line number Diff line change
@@ -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 <https://www.gnu.org/licenses/>.
*/

#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);
}
}
}
25 changes: 1 addition & 24 deletions addons/sourcemod/scripting/prophunt/sdkcalls.sp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 457e757

Please sign in to comment.