Skip to content

Commit 98831a8

Browse files
authored
Add the ability to work with the |this| parameter under dhooks callback (#2219)
1 parent 66d3f5e commit 98831a8

File tree

4 files changed

+74
-100
lines changed

4 files changed

+74
-100
lines changed

extensions/dhooks/dynhooks_sourcepawn.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,7 @@ CDynamicHooksSourcePawn::CDynamicHooksSourcePawn(HookSetup *setup, CHook *pDetou
532532
this->hookType = setup->hookType;
533533
this->m_pDetour = pDetour;
534534
this->callConv = setup->callConv;
535+
this->thisFuncCallConv = setup->callConv;
535536
}
536537

537538
HookReturnStruct *CDynamicHooksSourcePawn::GetReturnStruct()

extensions/dhooks/natives.cpp

Lines changed: 62 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ enum SDKFuncConfSource
4242
SDKConf_Address
4343
};
4444

45+
using ParamVector = SourceHook::CVector<ParamInfo>;
46+
4547
bool GetHandleIfValidOrError(HandleType_t type, void **object, IPluginContext *pContext, cell_t param)
4648
{
4749
if(param == BAD_HANDLE)
@@ -81,6 +83,56 @@ bool GetCallbackArgHandleIfValidOrError(HandleType_t type, HandleType_t otherTyp
8183
return true;
8284
}
8385

86+
bool GetObjectAddrOrThis(IPluginContext *pContext, const cell_t *params, void *&retAddr)
87+
{
88+
HookParamsStruct *paramStruct = NULL;
89+
retAddr = NULL;
90+
91+
if(!GetCallbackArgHandleIfValidOrError(g_HookParamsHandle, g_HookReturnHandle, (void **)&paramStruct, pContext, params[1]))
92+
{
93+
return false;
94+
}
95+
96+
if(params[2] != 0)
97+
{
98+
const ParamVector &paramsVec = paramStruct->dg->params;
99+
100+
if(params[2] < 0 || params[2] > static_cast<int>(paramsVec.size()))
101+
{
102+
return pContext->ThrowNativeError("Invalid param number %i max params is %i", params[2], paramsVec.size());
103+
}
104+
105+
int index = params[2] - 1;
106+
const ParamInfo &param = paramsVec.at(index);
107+
108+
if(param.type != HookParamType_ObjectPtr && param.type != HookParamType_Object)
109+
{
110+
return pContext->ThrowNativeError("Invalid object value type %i", param.type);
111+
}
112+
113+
size_t offset = GetParamOffset(paramStruct, index);
114+
retAddr = GetObjectAddr(param.type, param.flags, paramStruct->orgParams, offset);
115+
return true;
116+
}
117+
118+
const DHooksInfo* dgInfo = paramStruct->dg;
119+
120+
if(dgInfo->thisFuncCallConv != CallConv_THISCALL)
121+
{
122+
return pContext->ThrowNativeError("Parameter 'this' is only available in member functions");
123+
}
124+
125+
if(dgInfo->thisType != ThisPointer_Address
126+
&& dgInfo->thisType != ThisPointer_CBaseEntity
127+
&& dgInfo->hookType != HookType_GameRules)
128+
{
129+
return pContext->ThrowNativeError("Parameter 'this' is not specified as an address, it is not available");
130+
}
131+
132+
retAddr = g_SHPtr->GetIfacePtr();
133+
return true;
134+
}
135+
84136
IPluginFunction *GetCallback(IPluginContext *pContext, HookSetup * setup, const cell_t *params, cell_t callback_index)
85137
{
86138
IPluginFunction *ret = NULL;
@@ -1089,28 +1141,12 @@ cell_t Native_RemoveEntityListener(IPluginContext *pContext, const cell_t *param
10891141
//native any:DHookGetParamObjectPtrVar(Handle:hParams, num, offset, ObjectValueType:type);
10901142
cell_t Native_GetParamObjectPtrVar(IPluginContext *pContext, const cell_t *params)
10911143
{
1092-
HookParamsStruct *paramStruct;
1093-
1094-
if(!GetCallbackArgHandleIfValidOrError(g_HookParamsHandle, g_HookReturnHandle, (void **)&paramStruct, pContext, params[1]))
1144+
void *addr = NULL;
1145+
if(!GetObjectAddrOrThis(pContext, params, addr))
10951146
{
10961147
return 0;
10971148
}
10981149

1099-
if(params[2] <= 0 || params[2] > (int)paramStruct->dg->params.size())
1100-
{
1101-
return pContext->ThrowNativeError("Invalid param number %i max params is %i", params[2], paramStruct->dg->params.size());
1102-
}
1103-
1104-
int index = params[2] - 1;
1105-
1106-
if(paramStruct->dg->params.at(index).type != HookParamType_ObjectPtr && paramStruct->dg->params.at(index).type != HookParamType_Object)
1107-
{
1108-
return pContext->ThrowNativeError("Invalid object value type %i", paramStruct->dg->params.at(index).type);
1109-
}
1110-
1111-
size_t offset = GetParamOffset(paramStruct, index);
1112-
void *addr = GetObjectAddr(paramStruct->dg->params.at(index).type, paramStruct->dg->params.at(index).flags, paramStruct->orgParams, offset);
1113-
11141150
switch((ObjectValueType)params[4])
11151151
{
11161152
case ObjectValueType_Int:
@@ -1160,28 +1196,12 @@ cell_t Native_GetParamObjectPtrVar(IPluginContext *pContext, const cell_t *param
11601196
//native DHookSetParamObjectPtrVar(Handle:hParams, num, offset, ObjectValueType:type, value)
11611197
cell_t Native_SetParamObjectPtrVar(IPluginContext *pContext, const cell_t *params)
11621198
{
1163-
HookParamsStruct *paramStruct;
1164-
1165-
if(!GetCallbackArgHandleIfValidOrError(g_HookParamsHandle, g_HookReturnHandle, (void **)&paramStruct, pContext, params[1]))
1199+
void *addr = NULL;
1200+
if(!GetObjectAddrOrThis(pContext, params, addr))
11661201
{
11671202
return 0;
11681203
}
11691204

1170-
if(params[2] <= 0 || params[2] > (int)paramStruct->dg->params.size())
1171-
{
1172-
return pContext->ThrowNativeError("Invalid param number %i max params is %i", params[2], paramStruct->dg->params.size());
1173-
}
1174-
1175-
int index = params[2] - 1;
1176-
1177-
if(paramStruct->dg->params.at(index).type != HookParamType_ObjectPtr && paramStruct->dg->params.at(index).type != HookParamType_Object)
1178-
{
1179-
return pContext->ThrowNativeError("Invalid object value type %i", paramStruct->dg->params.at(index).type);
1180-
}
1181-
1182-
size_t offset = GetParamOffset(paramStruct, index);
1183-
void *addr = GetObjectAddr(paramStruct->dg->params.at(index).type, paramStruct->dg->params.at(index).flags, paramStruct->orgParams, offset);
1184-
11851205
switch((ObjectValueType)params[4])
11861206
{
11871207
case ObjectValueType_Int:
@@ -1245,28 +1265,12 @@ cell_t Native_SetParamObjectPtrVar(IPluginContext *pContext, const cell_t *param
12451265
//native DHookGetParamObjectPtrVarVector(Handle:hParams, num, offset, ObjectValueType:type, Float:buffer[3]);
12461266
cell_t Native_GetParamObjectPtrVarVector(IPluginContext *pContext, const cell_t *params)
12471267
{
1248-
HookParamsStruct *paramStruct;
1249-
1250-
if(!GetCallbackArgHandleIfValidOrError(g_HookParamsHandle, g_HookReturnHandle, (void **)&paramStruct, pContext, params[1]))
1268+
void *addr = NULL;
1269+
if(!GetObjectAddrOrThis(pContext, params, addr))
12511270
{
12521271
return 0;
12531272
}
12541273

1255-
if(params[2] <= 0 || params[2] > (int)paramStruct->dg->params.size())
1256-
{
1257-
return pContext->ThrowNativeError("Invalid param number %i max params is %i", params[2], paramStruct->dg->params.size());
1258-
}
1259-
1260-
int index = params[2] - 1;
1261-
1262-
if(paramStruct->dg->params.at(index).type != HookParamType_ObjectPtr && paramStruct->dg->params.at(index).type != HookParamType_Object)
1263-
{
1264-
return pContext->ThrowNativeError("Invalid object value type %i", paramStruct->dg->params.at(index).type);
1265-
}
1266-
1267-
size_t offset = GetParamOffset(paramStruct, index);
1268-
void *addr = GetObjectAddr(paramStruct->dg->params.at(index).type, paramStruct->dg->params.at(index).flags, paramStruct->orgParams, offset);
1269-
12701274
cell_t *buffer;
12711275
pContext->LocalToPhysAddr(params[5], &buffer);
12721276

@@ -1299,28 +1303,12 @@ cell_t Native_GetParamObjectPtrVarVector(IPluginContext *pContext, const cell_t
12991303
//native DHookSetParamObjectPtrVarVector(Handle:hParams, num, offset, ObjectValueType:type, Float:value[3]);
13001304
cell_t Native_SetParamObjectPtrVarVector(IPluginContext *pContext, const cell_t *params)
13011305
{
1302-
HookParamsStruct *paramStruct;
1303-
1304-
if(!GetCallbackArgHandleIfValidOrError(g_HookParamsHandle, g_HookReturnHandle, (void **)&paramStruct, pContext, params[1]))
1306+
void *addr = NULL;
1307+
if(!GetObjectAddrOrThis(pContext, params, addr))
13051308
{
13061309
return 0;
13071310
}
13081311

1309-
if(params[2] <= 0 || params[2] > (int)paramStruct->dg->params.size())
1310-
{
1311-
return pContext->ThrowNativeError("Invalid param number %i max params is %i", params[2], paramStruct->dg->params.size());
1312-
}
1313-
1314-
int index = params[2] - 1;
1315-
1316-
if(paramStruct->dg->params.at(index).type != HookParamType_ObjectPtr && paramStruct->dg->params.at(index).type != HookParamType_Object)
1317-
{
1318-
return pContext->ThrowNativeError("Invalid object value type %i", paramStruct->dg->params.at(index).type);
1319-
}
1320-
1321-
size_t offset = GetParamOffset(paramStruct, index);
1322-
void *addr = GetObjectAddr(paramStruct->dg->params.at(index).type, paramStruct->dg->params.at(index).flags, paramStruct->orgParams, offset);
1323-
13241312
cell_t *buffer;
13251313
pContext->LocalToPhysAddr(params[5], &buffer);
13261314

@@ -1352,28 +1340,12 @@ cell_t Native_SetParamObjectPtrVarVector(IPluginContext *pContext, const cell_t
13521340
//native DHookGetParamObjectPtrString(Handle:hParams, num, offset, ObjectValueType:type, String:buffer[], size)
13531341
cell_t Native_GetParamObjectPtrString(IPluginContext *pContext, const cell_t *params)
13541342
{
1355-
HookParamsStruct *paramStruct;
1356-
1357-
if(!GetCallbackArgHandleIfValidOrError(g_HookParamsHandle, g_HookReturnHandle, (void **)&paramStruct, pContext, params[1]))
1343+
void *addr = NULL;
1344+
if (!GetObjectAddrOrThis(pContext, params, addr))
13581345
{
13591346
return 0;
13601347
}
13611348

1362-
if(params[2] <= 0 || params[2] > (int)paramStruct->dg->params.size())
1363-
{
1364-
return pContext->ThrowNativeError("Invalid param number %i max params is %i", params[2], paramStruct->dg->params.size());
1365-
}
1366-
1367-
int index = params[2] - 1;
1368-
1369-
if(paramStruct->dg->params.at(index).type != HookParamType_ObjectPtr && paramStruct->dg->params.at(index).type != HookParamType_Object)
1370-
{
1371-
return pContext->ThrowNativeError("Invalid object value type %i", paramStruct->dg->params.at(index).type);
1372-
}
1373-
1374-
size_t offset = GetParamOffset(paramStruct, index);
1375-
void *addr = GetObjectAddr(paramStruct->dg->params.at(index).type, paramStruct->dg->params.at(index).flags, paramStruct->orgParams, offset);
1376-
13771349
switch((ObjectValueType)params[4])
13781350
{
13791351
case ObjectValueType_CharPtr:

extensions/dhooks/vhook.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ class DHooksInfo
162162
int entity;
163163
ThisPointerType thisType;
164164
HookType hookType;
165+
CallingConvention thisFuncCallConv;
165166
};
166167

167168
class DHooksCallback : public SourceHook::ISHDelegate, public DHooksInfo

plugins/include/dhooks.inc

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ methodmap DHookParam < Handle
310310

311311
// Gets an object's variable value.
312312
//
313-
// @param num Parameter number to get, starting at 1.
313+
// @param num Parameter number to get, 0 for param "this", other parameters start from 1
314314
// @param offset Byte offset within the object to the var to get.
315315
// @param type Type of var it is.
316316
//
@@ -320,7 +320,7 @@ methodmap DHookParam < Handle
320320

321321
// Gets an object's vector variable value.
322322
//
323-
// @param num Parameter number to get, starting at 1.
323+
// @param num Parameter number to get, 0 for param "this", other parameters start from 1.
324324
// @param offset Byte offset within the object to the var to get.
325325
// @param type Type of var it is.
326326
// @param vec Buffer to store the result vector.
@@ -330,7 +330,7 @@ methodmap DHookParam < Handle
330330

331331
// Gets an object's string variable value.
332332
//
333-
// @param num Parameter number to get, starting at 1.
333+
// @param num Parameter number to get, 0 for param "this", other parameters start from 1.
334334
// @param offset Byte offset within the object to the var to get.
335335
// @param type Type of var it is.
336336
// @param buffer Buffer to store the result string.
@@ -344,7 +344,7 @@ methodmap DHookParam < Handle
344344
// The changes are only applied when MRES_ChangedHandled or MRES_ChangedOverride
345345
// is returned in the callback.
346346
//
347-
// @param num Parameter number to set, starting at 1.
347+
// @param num Parameter number to set, 0 for param "this", other parameters start from 1.
348348
// @param offset Byte offset within the object to the var to set.
349349
// @param type Type of var it is.
350350
// @param value The value to set the var to.
@@ -357,7 +357,7 @@ methodmap DHookParam < Handle
357357
// The changes are only applied when MRES_ChangedHandled or MRES_ChangedOverride
358358
// is returned in the callback.
359359
//
360-
// @param num Parameter number to set, starting at 1.
360+
// @param num Parameter number to set, 0 for param "this", other parameters start from 1.
361361
// @param offset Byte offset within the object to the var to set.
362362
// @param type Type of var it is.
363363
// @param vec The value to set the vector var to.
@@ -928,7 +928,7 @@ native void DHookSetReturnString(Handle hReturn, char[] value);
928928
* Gets an objects variable value
929929
*
930930
* @param hParams Handle to params structure
931-
* @param num Param number to get.
931+
* @param num Param number to get, 0 for param "this".
932932
* @param offset Offset within the object to the var to get.
933933
* @param type Type of var it is
934934
*
@@ -941,7 +941,7 @@ native any DHookGetParamObjectPtrVar(Handle hParams, int num, int offset, Object
941941
* Sets an objects variable value
942942
*
943943
* @param hParams Handle to params structure
944-
* @param num Param number to set.
944+
* @param num Param number to set, 0 for param "this".
945945
* @param offset Offset within the object to the var to set.
946946
* @param type Type of var it is
947947
* @param value The value to set the var to.
@@ -954,7 +954,7 @@ native void DHookSetParamObjectPtrVar(Handle hParams, int num, int offset, Objec
954954
* Gets an objects vector variable value
955955
*
956956
* @param hParams Handle to params structure
957-
* @param num Param number to get.
957+
* @param num Param number to get, 0 for param "this".
958958
* @param offset Offset within the object to the var to get.
959959
* @param type Type of var it is
960960
* @param buffer Buffer to store the result vector
@@ -967,7 +967,7 @@ native void DHookGetParamObjectPtrVarVector(Handle hParams, int num, int offset,
967967
* Sets an objects vector variable value
968968
*
969969
* @param hParams Handle to params structure
970-
* @param num Param number to set.
970+
* @param num Param number to set, 0 for param "this".
971971
* @param offset Offset within the object to the var to set.
972972
* @param type Type of var it is
973973
* @param value The value to set the vector var to.
@@ -980,7 +980,7 @@ native void DHookSetParamObjectPtrVarVector(Handle hParams, int num, int offset,
980980
* Gets an objects string variable value
981981
*
982982
* @param hParams Handle to params structure
983-
* @param num Param number to get.
983+
* @param num Param number to get, 0 for param "this".
984984
* @param offset Offset within the object to the var to get.
985985
* @param type Type of var it is
986986
* @param buffer Buffer to store the result vector

0 commit comments

Comments
 (0)