forked from Drifter321/DHooks2
-
Notifications
You must be signed in to change notification settings - Fork 11
/
extension.cpp
165 lines (145 loc) · 4.64 KB
/
extension.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#include "extension.h"
#include "listeners.h"
#include "dynhooks_sourcepawn.h"
#include "signatures.h"
DHooks g_DHooksIface; /**< Global singleton for extension's main interface */
SMEXT_LINK(&g_DHooksIface);
IBinTools *g_pBinTools;
ISDKHooks *g_pSDKHooks;
ISDKTools *g_pSDKTools;
DHooksEntityListener *g_pEntityListener = NULL;
HandleType_t g_HookSetupHandle = 0;
HandleType_t g_HookParamsHandle = 0;
HandleType_t g_HookReturnHandle = 0;
std::thread::id g_MainThreadId;
bool DHooks::SDK_OnLoad(char *error, size_t maxlength, bool late)
{
HandleError err;
g_HookSetupHandle = handlesys->CreateType("HookSetup", this, 0, NULL, NULL, myself->GetIdentity(), &err);
if(g_HookSetupHandle == 0)
{
snprintf(error, maxlength, "Could not create hook setup handle type (err: %d)", err);
return false;
}
g_HookParamsHandle = handlesys->CreateType("HookParams", this, 0, NULL, NULL, myself->GetIdentity(), &err);
if(g_HookParamsHandle == 0)
{
snprintf(error, maxlength, "Could not create hook params handle type (err: %d)", err);
return false;
}
g_HookReturnHandle = handlesys->CreateType("HookReturn", this, 0, NULL, NULL, myself->GetIdentity(), &err);
if(g_HookReturnHandle == 0)
{
snprintf(error, maxlength, "Could not create hook return handle type (err: %d)", err);
return false;
}
if (!g_pPreDetours.init())
{
snprintf(error, maxlength, "Could not initialize pre hook detours hashmap.");
return false;
}
if (!g_pPostDetours.init())
{
snprintf(error, maxlength, "Could not initialize post hook detours hashmap.");
return false;
}
sharesys->AddDependency(myself, "bintools.ext", true, true);
sharesys->AddDependency(myself, "sdktools.ext", true, true);
sharesys->AddDependency(myself, "sdkhooks.ext", true, true);
sharesys->RegisterLibrary(myself, "dhooks");
plsys->AddPluginsListener(this);
sharesys->AddNatives(myself, g_Natives);
g_pEntityListener = new DHooksEntityListener();
g_pSignatures = new SignatureGameConfig();
g_MainThreadId = std::this_thread::get_id();
return true;
}
void DHooks::OnHandleDestroy(HandleType_t type, void *object)
{
if(type == g_HookSetupHandle)
{
delete (HookSetup *)object;
}
else if(type == g_HookParamsHandle)
{
delete (HookParamsStruct *)object;
}
else if(type == g_HookReturnHandle)
{
delete (HookReturnStruct *)object;
}
}
void DHooks::SDK_OnAllLoaded()
{
SM_GET_LATE_IFACE(SDKTOOLS, g_pSDKTools);
SM_GET_LATE_IFACE(BINTOOLS, g_pBinTools);
SM_GET_LATE_IFACE(SDKHOOKS, g_pSDKHooks);
g_pSDKHooks->AddEntityListener(g_pEntityListener);
gameconfs->AddUserConfigHook("Functions", g_pSignatures);
}
void DHooks::SDK_OnUnload()
{
CleanupHooks();
CleanupDetours();
if(g_pEntityListener)
{
g_pEntityListener->CleanupListeners();
g_pEntityListener->CleanupRemoveList();
g_pSDKHooks->RemoveEntityListener(g_pEntityListener);
delete g_pEntityListener;
}
plsys->RemovePluginsListener(this);
handlesys->RemoveType(g_HookSetupHandle, myself->GetIdentity());
handlesys->RemoveType(g_HookParamsHandle, myself->GetIdentity());
handlesys->RemoveType(g_HookReturnHandle, myself->GetIdentity());
gameconfs->RemoveUserConfigHook("Functions", g_pSignatures);
}
bool DHooks::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late)
{
if(!SetupHookManager(ismm))
{
snprintf(error, maxlength, "Failed to get IHookManagerAutoGen iface");
return false;
}
return true;
}
void DHooks::OnPluginUnloaded(IPlugin *plugin)
{
CleanupHooks(plugin->GetBaseContext());
RemoveAllCallbacksForContext(plugin->GetBaseContext());
if(g_pEntityListener)
{
g_pEntityListener->CleanupListeners(plugin->GetBaseContext());
}
}
// The next 3 functions handle cleanup if our interfaces are going to be unloaded
bool DHooks::QueryRunning(char *error, size_t maxlength)
{
SM_CHECK_IFACE(SDKTOOLS, g_pSDKTools);
SM_CHECK_IFACE(BINTOOLS, g_pBinTools);
SM_CHECK_IFACE(SDKHOOKS, g_pSDKHooks);
return true;
}
void DHooks::NotifyInterfaceDrop(SMInterface *pInterface)
{
if(strcmp(pInterface->GetInterfaceName(), SMINTERFACE_SDKHOOKS_NAME) == 0)
{
if(g_pEntityListener)
{
// If this fails, remove this line and just delete the ent listener instead
g_pSDKHooks->RemoveEntityListener(g_pEntityListener);
g_pEntityListener->CleanupListeners();
delete g_pEntityListener;
g_pEntityListener = NULL;
}
g_pSDKHooks = NULL;
}
else if(strcmp(pInterface->GetInterfaceName(), SMINTERFACE_BINTOOLS_NAME) == 0)
{
g_pBinTools = NULL;
}
else if(strcmp(pInterface->GetInterfaceName(), SMINTERFACE_SDKTOOLS_NAME) == 0)
{
g_pSDKTools = NULL;
}
}