[Dhooks] Add the ability to work with the this parameter, which is an object
Sometimes we have to work with this parameter which is a class but dhooks doesn't have this feature, this PR solves this problem. This code has been tested on both post and pre hooks. Below is an example code for working with the new functionality.
/*class CBaseEntity : public IServerEntity
{
...
protected:
EHANDLE m_pParent; // for movement hierarchy
...
};*/
MRESReturn Handler_CBaseEntity__OnTakeDamage(Address pThis, Handle hReturn, Handle hParams)
{
// If EHANDLE type or entity returns entity index.
// Index num 0, for working with this parameter
int iParent = DHookGetParamObjectPtrVar(hParams, 0, 384, ObjectValueType_Ehandle);
if (iParent < 1 || !IsValidEntity(iParent)) {
return MRES_Ignored;
}
char sEntityName[64];
GetEntityClassname(iParent, sEntityName, sizeof(sEntityName));
PrintToChatAll("[Handler_CBaseEntity__OnTakeDamage] iParent: %s (%d)", sEntityName, iParent);
return MRES_Ignored;
}
I think I've finished this PR, I just need to check
I tested it with this type address, everything works fine!
Hey, following up on this PR — I just wanted to know if it’s still being considered. I can rebase or adjust it if that helps move it forward.
Still very much considered. I was going to merge this, but I'm currently rewriting dhooks from scratch (see k/sourcehook_alternative branch). Merging this now would be weird, given original dhooks might explode soon.
Should the rewrite fail, I'll totally merge this. Should it succeed, I'll instead port the features of that PR over.
I understand that you're focused on rewriting SourceHook, and merging it right now might be impractical, but I'm afraid it will take a long time, with source hook-related changes and testing. People won't see this change anytime soon, which is a shame. Still, this PR has been pending for quite some time, and the changes don’t look too invasive — in addition, they don’t break anything. In the old version, using index 0 for a parameter would cause a plugin error. In the new version, people will be able to use index 0 for the 'this' parameter. It would be great to have this functionality available already — ideally in SM 1.12/1.13. Requiring people to rely on the unstable branch just to get these features isn’t ideal, and having to write simple logic as a separate SourceMod extension feels unnecessary.
I refactored the code, moving similar blocks into a separate function in the old code, and added my own. As a result, the code I added looks like this. I've moved it here in a comment for easier understanding:
bool GetObjectAddrOrThis(IPluginContext *pContext, const cell_t *params, void *&retAddr)
{
// Some dhooks code
if(params[2] != 0)
{
// Dhooks code start
const auto ¶msVec = paramStruct->dg->params;
if(params[2] < 0 || params[2] > static_cast<int>(paramsVec.size()))
{
return pContext->ThrowNativeError("Invalid param number %i max params is %i", params[2], paramsVec.size());
}
int index = params[2] - 1;
const auto ¶m = paramsVec.at(index);
if(param.type != HookParamType_ObjectPtr && param.type != HookParamType_Object)
{
return pContext->ThrowNativeError("Invalid object value type %i", param.type);
}
size_t offset = GetParamOffset(paramStruct, index);
retAddr = GetObjectAddr(param.type, param.flags, paramStruct->orgParams, offset);
return true;
// Dhooks code end
}
// New code
const auto &dgInfo = paramStruct->dg;
if(dgInfo->thisFuncCallConv != CallConv_THISCALL)
{
return pContext->ThrowNativeError("Parameter 'this' is only available in member functions, specify the calling convention type 'thiscall'");
}
if(dgInfo->thisType != ThisPointer_Address
&& dgInfo->thisType != ThisPointer_CBaseEntity
&& !(dgInfo->thisType == ThisPointer_Ignore && dgInfo->hookType == HookType_GameRules))
{
return pContext->ThrowNativeError("Parameter 'this' is not specified as an address, it is not available");
}
retAddr = g_SHPtr->GetIfacePtr();
return true;
}
It would be great to have this functionality available already — ideally in SM 1.12/1.13. Requiring people to rely on the unstable branch just to get these features isn’t ideal, and having to write simple logic as a separate SourceMod extension feels unnecessary.
I'm okay with merging this into 1.13 as I'll be rewriting it later anyways, however no backport for 1.12. (But feel free to convince the maintainers)
It would be great to have this functionality available already — ideally in SM 1.12/1.13. Requiring people to rely on the unstable branch just to get these features isn’t ideal, and having to write simple logic as a separate SourceMod extension feels unnecessary.
I'm okay with merging this into 1.13 as I'll be rewriting it later anyways, however no backport for 1.12. (But feel free to convince the maintainers)
The current implementation of SourceMod 1.12 with DHooks has limitations when working with the this pointer. Some plugins may crash or exhibit undefined behavior if used incorrectly. Additionally, certain types, such as EHANDLE, cannot be accessed correctly from within a plugin. This extension addresses these limitations, improving stability and usability while reducing memory-related issues.
I often had to choose between writing a C++ extension or a plugin because the current API was limited, making simple fixes cumbersome.
Until now, users were forced to write their own custom solutions for different types, such as the FollowTarget_Detour plugin for working with EHANDLE.
I believe users should not need to rely on the unstable branch to access these improvements.
The changes are minimal and do not break the existing plugin API.
Furthermore, this PR has been open for a long time, and it would be beneficial for these improvements to be integrated and available.
Since major changes are planned for the 1.13 branch, which will require extensive testing, it might make sense to make an exception for this PR and merge it into the 1.12 branch so that users can safely benefit from the improved functionality.
So what about this commit?