Skip to content

Commit ef3a114

Browse files
committed
DHooks: Feature dtor hook cleanup
1 parent 6332514 commit ef3a114

4 files changed

Lines changed: 35 additions & 32 deletions

File tree

extensions/dhooks/src/handle.cpp

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ bool DynamicDetour::Disable(SourcePawn::IPluginFunction* callback, sp::HookMode
170170
return true;
171171
}
172172

173-
std::uint32_t DynamicHook::AddHook(SourcePawn::IPluginFunction* callback, SourcePawn::IPluginFunction* rm_callback, sp::HookMode mode, void* obj) {
173+
std::uint32_t DynamicHook::AddHook(SourcePawn::IPluginFunction* callback, SourcePawn::IPluginFunction* rm_callback, sp::HookMode mode, void* obj, bool dtor_cleanup) {
174174
if (!this->IsImmutable()) {
175175
return 0;
176176
}
@@ -189,31 +189,33 @@ std::uint32_t DynamicHook::AddHook(SourcePawn::IPluginFunction* callback, Source
189189
return 0;
190190
}
191191

192-
auto it = locals::class_dynamichooks.find((CGenericClass*)obj);
193-
if (it == locals::class_dynamichooks.end()) {
194-
auto insert = locals::class_dynamichooks.emplace((CGenericClass*)obj, std::vector<std::uint32_t>());
195-
if (insert.second == false) {
196-
return id;
197-
}
198-
it = insert.first;
199-
200-
if (locals::class_vtables.find(vtable) == locals::class_vtables.end()) {
201-
// Hook the virtual destructor, and perform hook cleaning actions under there
202-
KHook::SetupVirtualHook(
203-
vtable,
204-
DTOR_VTABLE_INDEX,
205-
nullptr,
206-
nullptr,
207-
KHook::ExtractMFP(&CGenericClass::KHook_Detour_PRE),
208-
nullptr,
209-
KHook::ExtractMFP(&CGenericClass::KHook_Make_Return),
210-
KHook::ExtractMFP(&CGenericClass::KHook_Make_CallOriginal),
211-
true
212-
);
213-
locals::class_vtables.insert(vtable);
192+
if (dtor_cleanup) {
193+
auto it = locals::class_dynamichooks.find((CGenericClass*)obj);
194+
if (it == locals::class_dynamichooks.end()) {
195+
auto insert = locals::class_dynamichooks.emplace((CGenericClass*)obj, std::vector<std::uint32_t>());
196+
if (insert.second == false) {
197+
return id;
198+
}
199+
it = insert.first;
200+
201+
if (locals::class_vtables.find(vtable) == locals::class_vtables.end()) {
202+
// Hook the virtual destructor, and perform hook cleaning actions under there
203+
KHook::SetupVirtualHook(
204+
vtable,
205+
DTOR_VTABLE_INDEX,
206+
nullptr,
207+
nullptr,
208+
KHook::ExtractMFP(&CGenericClass::KHook_Detour_PRE),
209+
nullptr,
210+
KHook::ExtractMFP(&CGenericClass::KHook_Make_Return),
211+
KHook::ExtractMFP(&CGenericClass::KHook_Make_CallOriginal),
212+
true
213+
);
214+
locals::class_vtables.insert(vtable);
215+
}
214216
}
217+
it->second.push_back(id);
215218
}
216-
it->second.push_back(id);
217219
return id;
218220
}
219221

extensions/dhooks/src/handle.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ class DynamicHook : public HookSetup {
111111
return _default_callback;
112112
}
113113

114-
std::uint32_t AddHook(SourcePawn::IPluginFunction* callback, SourcePawn::IPluginFunction* rm_callback, sp::HookMode, void* obj);
114+
std::uint32_t AddHook(SourcePawn::IPluginFunction* callback, SourcePawn::IPluginFunction* rm_callback, sp::HookMode, void* obj, bool dtor_cleanup);
115115
bool RemoveHook(std::uint32_t id);
116116
static cell_t FindByHookID(std::uint32_t id);
117117
protected:

extensions/dhooks/src/natives/dynamichook.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ cell_t DynamicHook_HookEntity(SourcePawn::IPluginContext* context, const cell_t*
8787
auto removal_callback = context->GetFunctionById(params[5]);
8888

8989
dynhook->SetImmutable();
90-
return dynhook->AddHook(callback, removal_callback, mode, entity);
90+
return dynhook->AddHook(callback, removal_callback, mode, entity, true);
9191
}
9292

9393
cell_t DynamicHook_DHookEntity(SourcePawn::IPluginContext* context, const cell_t* params) {
@@ -119,7 +119,7 @@ cell_t DynamicHook_DHookEntity(SourcePawn::IPluginContext* context, const cell_t
119119
}
120120

121121
dynhook->SetImmutable();
122-
return dynhook->AddHook(callback, removal_callback, (post) ? sp::HookMode::Hook_Post : sp::HookMode::Hook_Pre, entity);
122+
return dynhook->AddHook(callback, removal_callback, (post) ? sp::HookMode::Hook_Post : sp::HookMode::Hook_Pre, entity, true);
123123
}
124124

125125
cell_t DynamicHook_HookGamerules(SourcePawn::IPluginContext* context, const cell_t* params) {
@@ -155,7 +155,7 @@ cell_t DynamicHook_HookGamerules(SourcePawn::IPluginContext* context, const cell
155155
auto removal_callback = context->GetFunctionById(params[4]);
156156

157157
dynhook->SetImmutable();
158-
return dynhook->AddHook(callback, removal_callback, mode, gamerules);
158+
return dynhook->AddHook(callback, removal_callback, mode, gamerules, false);
159159
}
160160

161161
cell_t DynamicHook_DHookGamerules(SourcePawn::IPluginContext* context, const cell_t* params) {
@@ -191,7 +191,7 @@ cell_t DynamicHook_DHookGamerules(SourcePawn::IPluginContext* context, const cel
191191
}
192192

193193
dynhook->SetImmutable();
194-
return dynhook->AddHook(callback, removal_callback, (post) ? sp::HookMode::Hook_Post : sp::HookMode::Hook_Pre, gamerules);
194+
return dynhook->AddHook(callback, removal_callback, (post) ? sp::HookMode::Hook_Post : sp::HookMode::Hook_Pre, gamerules, false);
195195
}
196196

197197
cell_t DynamicHook_HookRaw(SourcePawn::IPluginContext* context, const cell_t* params) {
@@ -214,7 +214,7 @@ cell_t DynamicHook_HookRaw(SourcePawn::IPluginContext* context, const cell_t* pa
214214
}
215215

216216
dynhook->SetImmutable();
217-
return dynhook->AddHook(callback, nullptr, mode, addr);
217+
return dynhook->AddHook(callback, nullptr, mode, addr, (params[0] >= 5 && params[5] != 0));
218218
}
219219

220220
cell_t DynamicHook_DHookRaw(SourcePawn::IPluginContext* context, const cell_t* params) {
@@ -243,7 +243,7 @@ cell_t DynamicHook_DHookRaw(SourcePawn::IPluginContext* context, const cell_t* p
243243
}
244244

245245
dynhook->SetImmutable();
246-
return dynhook->AddHook(callback, removal_callback, (post) ? sp::HookMode::Hook_Post : sp::HookMode::Hook_Pre, addr);
246+
return dynhook->AddHook(callback, removal_callback, (post) ? sp::HookMode::Hook_Post : sp::HookMode::Hook_Pre, addr, false);
247247
}
248248

249249
cell_t DynamicHook_RemoveHook(SourcePawn::IPluginContext* context, const cell_t* params) {

plugins/include/dhooks.inc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -545,10 +545,11 @@ methodmap DynamicHook < DHookSetup
545545
// You can access the parameters and get/set the return value.
546546
// @param addr This pointer address.
547547
// @param callback Callback function.
548+
// @param dtorcleanup If object has a virtual dtor, pass true for automatic hook cleanup.
548549
//
549550
// @return A hookid on success, INVALID_HOOK_ID otherwise.
550551
// @error Invalid setup handle, invalid address, invalid hook type or invalid callback.
551-
public native int HookRaw(HookMode mode, Address addr, DHookCallback callback);
552+
public native int HookRaw(HookMode mode, Address addr, DHookCallback callback, bool dtorcleanup = false);
552553

553554
// Remove hook by hook id.
554555
//

0 commit comments

Comments
 (0)