Skip to content

Conversation

@A1mDev
Copy link
Contributor

@A1mDev A1mDev commented Nov 11, 2024

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;
}

Copy link
Member

@Kenzzer Kenzzer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent work, especially given the situation that surround Address. The less we mess with memory directly in plugin, the better !
I just have a few request changes, but otherwise I think this is a good addition to dhooks.

@A1mDev
Copy link
Contributor Author

A1mDev commented Dec 30, 2024

I think I've finished this PR, I just need to check

@A1mDev
Copy link
Contributor Author

A1mDev commented Dec 30, 2024

I tested it with this type address, everything works fine!

Copy link
Member

@Kenzzer Kenzzer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you so much for seeing this through, it looks great! I'm going to let this sit a for little while longer, so others may review it as well. Otherwise I think this is ready to be taken in, thanks again!

@A1mDev
Copy link
Contributor Author

A1mDev commented Oct 24, 2025

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.

@Kenzzer
Copy link
Member

Kenzzer commented Oct 24, 2025

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.

@A1mDev
Copy link
Contributor Author

A1mDev commented Oct 24, 2025

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.

@A1mDev
Copy link
Contributor Author

A1mDev commented Oct 24, 2025

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 &paramsVec = 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 &param = 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;
}

@A1mDev A1mDev marked this pull request as draft October 24, 2025 19:20
@A1mDev A1mDev marked this pull request as ready for review October 24, 2025 20:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants