This extension is not just ANOTHER hooks extension But rather allows sourcemod plugins to create their own hooks. It has a very limited (currently) param and return type support.
Return types supported
ReturnType_Unknown //Very risky to use. But can be attempted to be used if type is not
ReturnType_String, //Note this is a string_t
ReturnType_StringPtr, //Note this is a string_t *
Param types supported
HookParamType_Unknown //Same as return it is very risky to use but can be attempted to be used if the param type isnt supported.
HookParamType_String, //Note this is a string_t
HookParamType_StringPtr, //Note this is a string_t *
HookParamType_CharPtr //char *
HookParamType_VectorPtr //Vector *
HookParamType_CBaseEntity //CBaseEntity *
HookParamType_ObjectPtr //Objects like CTakeDamageInfo *
HookParamType_Edict //edict_t *
Note that you cannot set or get a unknown param/return's value.
If you feel that a common param type is missing let me know and ill try to add support for it. This currently also allows for a total 10 params for a function. If you need to hook a function with more params also let me know and ill add support for more
So, some examples! (This example plugin is inside the zip and is only for cs:s and l4d2)
//Dont add removal callback for this one
DHookEntity(hTakeDamage, false, client);
public EntityCreated(entity, const String:classname)
PrintToServer("Entity %i has been created it is %s", entity, classname);
PrintToServer("Entity %i has been deleted", entity);
//int CCSPlayer::OnTakeDamage(CTakeDamageInfo const&)
public MRESReturn:OnTakeDamage(this, Handle:hReturn, Handle:hParams)
PrintToServer("DHooksHacks = Victim %i, Attacker %i, Inflictor %i, Damage %f", this, DHookGetParamObjectPtrVar(hParams, 1, 40, ObjectValueType_Ehandle), DHookGetParamObjectPtrVar(hParams, 1, 36, ObjectValueType_Ehandle), DHookGetParamObjectPtrVar(hParams, 1, 48, ObjectValueType_Float));
if(this <= MaxClients && this > 0 && !IsFakeClient(this))
DHookSetParamObjectPtrVar(hParams, 1, 48, ObjectValueType_Float, 0.0);
PrintToChat(this, "Pimping your hp");
// void CBaseEntity::SetModel(char const*)
public MRESReturn:SetModel(this, Handle:hParams)
//Change all bot skins to phoenix one
DHookSetParamString(hParams, 1, "models/player/t_phoenix.mdl");
public MRESReturn:GetMaxPlayerSpeedPost(this, Handle:hReturn)
//Change return max speed for non bots.
// bool CGameRules::CanHaveAmmo(CBaseCombatCharacter *, int)
public MRESReturn:CanHaveAmmoPost(Handle:hReturn, Handle:hParams)
PrintToServer("Can has ammo? %s %i", DHookGetReturn(hReturn)?"true":"false", DHookGetParam(hParams, 2));
// string_t CBaseEntity::GetModelName(void)
public MRESReturn:GetModelName(this, Handle:hReturn)
DHookGetReturnString(hReturn, returnval, sizeof(returnval));
PrintToServer("It is a bot, Model should be: models/player/t_phoenix.mdl It is %s", returnval);
// Vector CBasePlayer::GetPlayerMaxs()
PrintToServer("Get maxes %.1f, %.1f, %.1f", vec, vec, vec);
// bool CBaseCombatCharacter::Weapon_CanUse(CBaseCombatWeapon *)
public MRESReturn:CanUsePost(this, Handle:hReturn, Handle:hParams)
//Deny bots everything
// int CBaseCombatCharacter::BloodColor(void)
public MRESReturn:BloodColorPost(this, Handle:hReturn)
//Change the bots blood color to goldish yellow
PrintToServer("Removed hook %i", hookid);
As a basic note, if the return type is void there won’t be a return handle pushed to the callback. If there is no params no param handle will be pushed. If this pointer is set to ignore this won’t be pushed.
Here is a quick example written for TF2 to stop round ending. (Not tested just wrote it )
new Handle:temp = LoadGameConfigFile("tf2-roundend.games");
if(temp == INVALID_HANDLE)
SetFailState("Why you no has gamedata?");
Note: Gamerule hooks are removed OnMapEnd so you must hook them again in OnMapStart. Entity hooks are removed when the entity is removed.
Thats all there is to it!
Since this is a dev preview crashes can happen. I mostly tested in CS: S Windows. If you experience a crash please post the function, game, OS, and code. This extension can replace most of SDKHooks hooks but not all... yet
Added Raw hook (allows passing class pointer)
Fixed certain hooks unhooking randomly.
Added support for more params (new max is 10)
Added ability to add entity listeners (To hook OnEntityCreated and OnEntityDestroyed)
Changed from pre-alpha to alpha
Fixed various memory leaks.
Fixed requiring latest gamehelpers i face
Added support for Object pointer params (CTakeDamage in OnTakeDamage for example)
Removed the need for a removal callback when hooking (Its not mandatory now).
Fixed a crash when a hook was removed that had no removal callback.
Fixed a crash on newer engines.
Fixed a crash with strings
Fixed a crash on new engines
Added support for CS:GO
Added support for edict_t
Added support for getting the address of |this|
Removed asserts from OnEntityCreated
Made engine specific builds so that it works with tf2 again.
Hopefully fixed crashes in CS:GO in OnEntityCreated
Fixed a bug using Edict params.
Requires SM 1.5 and MM:S 1.9+
Fixed crashing when accessing NULL pointers
Added native to check if a param is NULL before accessing it (DHookIsNullParam)
Fixed a memory leak when unhooking entities.
Removed the need for gamedata by switching to SDKHooks entity listeners.
Current builds supported are CS:S, CS:GO, OBV, L4D/2. Other builds can be supported per request.
Note: You can delete the old dhooks files without the engine extensions (dhooks.ext.dll and dhooks.ext.so).
P.S Don't laugh at my code But feel free to point out ways to improve it.
asherkin - Explaining how SourceHook changes params along with other tidbits of info.
psychonic - For SDKHooks code to look at and answering way too many questions.
Updated the extension to add support for raw pointer address's. There is an example using CDirector for left4dead2 in the test plugin. Also fixed hooks randomly getting unhooked if they weren't entity hooks.
Updated again. Full changelog is in the original post. I removed the "pre-alpha" tag and made it an alpha. Ive been getting more time to test different hooks and seems to be working good so that is the reason
<KyleS> Drifter, Are you aware of any leaks in DHooks? D:
* ViolentCrimes has quit (Read error: Connection reset by peer)
<KyleS> Drifter, http://pastie.org/private/vxdnhepkmhi7wowytmydcg - If the client is kicked, if the plugin or ext is unloaded, the memory still isn't freed. I'm not sure where it's occuring. I could fire up Valgrind though if you can't reproduce it.
<KyleS> Hit about 2.5gb in 12h lol D: