diff --git a/extensions/dhooks/dynhooks_sourcepawn.cpp b/extensions/dhooks/dynhooks_sourcepawn.cpp index 927f3d66c8..6ad744d163 100644 --- a/extensions/dhooks/dynhooks_sourcepawn.cpp +++ b/extensions/dhooks/dynhooks_sourcepawn.cpp @@ -532,6 +532,7 @@ CDynamicHooksSourcePawn::CDynamicHooksSourcePawn(HookSetup *setup, CHook *pDetou this->hookType = setup->hookType; this->m_pDetour = pDetour; this->callConv = setup->callConv; + this->thisFuncCallConv = setup->callConv; } HookReturnStruct *CDynamicHooksSourcePawn::GetReturnStruct() diff --git a/extensions/dhooks/natives.cpp b/extensions/dhooks/natives.cpp index f228fcf306..20237fa0e6 100644 --- a/extensions/dhooks/natives.cpp +++ b/extensions/dhooks/natives.cpp @@ -1096,20 +1096,39 @@ cell_t Native_GetParamObjectPtrVar(IPluginContext *pContext, const cell_t *param return 0; } - if(params[2] <= 0 || params[2] > (int)paramStruct->dg->params.size()) + void *addr = NULL; + + if(params[2] != 0) { - return pContext->ThrowNativeError("Invalid param number %i max params is %i", params[2], paramStruct->dg->params.size()); - } + if(params[2] < 0 || params[2] > (int)paramStruct->dg->params.size()) + { + return pContext->ThrowNativeError("Invalid param number %i max params is %i", params[2], paramStruct->dg->params.size()); + } - int index = params[2] - 1; + int index = params[2] - 1; - if(paramStruct->dg->params.at(index).type != HookParamType_ObjectPtr && paramStruct->dg->params.at(index).type != HookParamType_Object) - { - return pContext->ThrowNativeError("Invalid object value type %i", paramStruct->dg->params.at(index).type); + if(paramStruct->dg->params.at(index).type != HookParamType_ObjectPtr && paramStruct->dg->params.at(index).type != HookParamType_Object) + { + return pContext->ThrowNativeError("Invalid object value type %i", paramStruct->dg->params.at(index).type); + } + + size_t offset = GetParamOffset(paramStruct, index); + addr = GetObjectAddr(paramStruct->dg->params.at(index).type, paramStruct->dg->params.at(index).flags, paramStruct->orgParams, offset); } + else + { + if(paramStruct->dg->thisFuncCallConv != CallConv_THISCALL) + { + return pContext->ThrowNativeError("Parameter 'this' is only available in member functions, specify the calling convention type 'thiscall'"); + } + + if(paramStruct->dg->thisType != ThisPointer_Address && paramStruct->dg->thisType != ThisPointer_CBaseEntity && !(paramStruct->dg->thisType == ThisPointer_Ignore && paramStruct->dg->hookType == HookType_GameRules)) + { + return pContext->ThrowNativeError("Parameter 'this' is not specified as an address, it is not available"); + } - size_t offset = GetParamOffset(paramStruct, index); - void *addr = GetObjectAddr(paramStruct->dg->params.at(index).type, paramStruct->dg->params.at(index).flags, paramStruct->orgParams, offset); + addr = g_SHPtr->GetIfacePtr(); + } switch((ObjectValueType)params[4]) { @@ -1167,20 +1186,39 @@ cell_t Native_SetParamObjectPtrVar(IPluginContext *pContext, const cell_t *param return 0; } - if(params[2] <= 0 || params[2] > (int)paramStruct->dg->params.size()) + void *addr = NULL; + + if(params[2] != 0) { - return pContext->ThrowNativeError("Invalid param number %i max params is %i", params[2], paramStruct->dg->params.size()); - } + if(params[2] < 0 || params[2] > (int)paramStruct->dg->params.size()) + { + return pContext->ThrowNativeError("Invalid param number %i max params is %i", params[2], paramStruct->dg->params.size()); + } - int index = params[2] - 1; + int index = params[2] - 1; - if(paramStruct->dg->params.at(index).type != HookParamType_ObjectPtr && paramStruct->dg->params.at(index).type != HookParamType_Object) + if(paramStruct->dg->params.at(index).type != HookParamType_ObjectPtr && paramStruct->dg->params.at(index).type != HookParamType_Object) + { + return pContext->ThrowNativeError("Invalid object value type %i", paramStruct->dg->params.at(index).type); + } + + size_t offset = GetParamOffset(paramStruct, index); + addr = GetObjectAddr(paramStruct->dg->params.at(index).type, paramStruct->dg->params.at(index).flags, paramStruct->orgParams, offset); + } + else { - return pContext->ThrowNativeError("Invalid object value type %i", paramStruct->dg->params.at(index).type); + if(paramStruct->dg->thisFuncCallConv != CallConv_THISCALL) + { + return pContext->ThrowNativeError("Parameter 'this' is only available in member functions, specify the calling convention type 'thiscall'"); + } + + if(paramStruct->dg->thisType != ThisPointer_Address && paramStruct->dg->thisType != ThisPointer_CBaseEntity && !(paramStruct->dg->thisType == ThisPointer_Ignore && paramStruct->dg->hookType == HookType_GameRules)) + { + return pContext->ThrowNativeError("Parameter 'this' is not specified as an address, it is not available"); + } + + addr = g_SHPtr->GetIfacePtr(); } - - size_t offset = GetParamOffset(paramStruct, index); - void *addr = GetObjectAddr(paramStruct->dg->params.at(index).type, paramStruct->dg->params.at(index).flags, paramStruct->orgParams, offset); switch((ObjectValueType)params[4]) { @@ -1252,20 +1290,39 @@ cell_t Native_GetParamObjectPtrVarVector(IPluginContext *pContext, const cell_t return 0; } - if(params[2] <= 0 || params[2] > (int)paramStruct->dg->params.size()) + void *addr = NULL; + + if(params[2] != 0) { - return pContext->ThrowNativeError("Invalid param number %i max params is %i", params[2], paramStruct->dg->params.size()); - } + if(params[2] < 0 || params[2] > (int)paramStruct->dg->params.size()) + { + return pContext->ThrowNativeError("Invalid param number %i max params is %i", params[2], paramStruct->dg->params.size()); + } - int index = params[2] - 1; + int index = params[2] - 1; - if(paramStruct->dg->params.at(index).type != HookParamType_ObjectPtr && paramStruct->dg->params.at(index).type != HookParamType_Object) - { - return pContext->ThrowNativeError("Invalid object value type %i", paramStruct->dg->params.at(index).type); + if(paramStruct->dg->params.at(index).type != HookParamType_ObjectPtr && paramStruct->dg->params.at(index).type != HookParamType_Object) + { + return pContext->ThrowNativeError("Invalid object value type %i", paramStruct->dg->params.at(index).type); + } + + size_t offset = GetParamOffset(paramStruct, index); + addr = GetObjectAddr(paramStruct->dg->params.at(index).type, paramStruct->dg->params.at(index).flags, paramStruct->orgParams, offset); } + else + { + if(paramStruct->dg->thisFuncCallConv != CallConv_THISCALL) + { + return pContext->ThrowNativeError("Parameter 'this' is only available in member functions, specify the calling convention type 'thiscall'"); + } - size_t offset = GetParamOffset(paramStruct, index); - void *addr = GetObjectAddr(paramStruct->dg->params.at(index).type, paramStruct->dg->params.at(index).flags, paramStruct->orgParams, offset); + if(paramStruct->dg->thisType != ThisPointer_Address && paramStruct->dg->thisType != ThisPointer_CBaseEntity && !(paramStruct->dg->thisType == ThisPointer_Ignore && paramStruct->dg->hookType == HookType_GameRules)) + { + return pContext->ThrowNativeError("Parameter 'this' is not specified as an address, it is not available"); + } + + addr = g_SHPtr->GetIfacePtr(); + } cell_t *buffer; pContext->LocalToPhysAddr(params[5], &buffer); @@ -1305,21 +1362,40 @@ cell_t Native_SetParamObjectPtrVarVector(IPluginContext *pContext, const cell_t { return 0; } + + void *addr = NULL; - if(params[2] <= 0 || params[2] > (int)paramStruct->dg->params.size()) + if(params[2] != 0) { - return pContext->ThrowNativeError("Invalid param number %i max params is %i", params[2], paramStruct->dg->params.size()); - } + if(params[2] < 0 || params[2] > (int)paramStruct->dg->params.size()) + { + return pContext->ThrowNativeError("Invalid param number %i max params is %i", params[2], paramStruct->dg->params.size()); + } - int index = params[2] - 1; + int index = params[2] - 1; - if(paramStruct->dg->params.at(index).type != HookParamType_ObjectPtr && paramStruct->dg->params.at(index).type != HookParamType_Object) - { - return pContext->ThrowNativeError("Invalid object value type %i", paramStruct->dg->params.at(index).type); + if(paramStruct->dg->params.at(index).type != HookParamType_ObjectPtr && paramStruct->dg->params.at(index).type != HookParamType_Object) + { + return pContext->ThrowNativeError("Invalid object value type %i", paramStruct->dg->params.at(index).type); + } + + size_t offset = GetParamOffset(paramStruct, index); + addr = GetObjectAddr(paramStruct->dg->params.at(index).type, paramStruct->dg->params.at(index).flags, paramStruct->orgParams, offset); } + else + { + if(paramStruct->dg->thisFuncCallConv != CallConv_THISCALL) + { + return pContext->ThrowNativeError("Parameter 'this' is only available in member functions, specify the calling convention type 'thiscall'"); + } - size_t offset = GetParamOffset(paramStruct, index); - void *addr = GetObjectAddr(paramStruct->dg->params.at(index).type, paramStruct->dg->params.at(index).flags, paramStruct->orgParams, offset); + if(paramStruct->dg->thisType != ThisPointer_Address && paramStruct->dg->thisType != ThisPointer_CBaseEntity && !(paramStruct->dg->thisType == ThisPointer_Ignore && paramStruct->dg->hookType == HookType_GameRules)) + { + return pContext->ThrowNativeError("Parameter 'this' is not specified as an address, it is not available"); + } + + addr = g_SHPtr->GetIfacePtr(); + } cell_t *buffer; pContext->LocalToPhysAddr(params[5], &buffer); @@ -1359,20 +1435,39 @@ cell_t Native_GetParamObjectPtrString(IPluginContext *pContext, const cell_t *pa return 0; } - if(params[2] <= 0 || params[2] > (int)paramStruct->dg->params.size()) + void *addr = NULL; + + if(params[2] != 0) { - return pContext->ThrowNativeError("Invalid param number %i max params is %i", params[2], paramStruct->dg->params.size()); - } + if(params[2] <= 0 || params[2] > (int)paramStruct->dg->params.size()) + { + return pContext->ThrowNativeError("Invalid param number %i max params is %i", params[2], paramStruct->dg->params.size()); + } - int index = params[2] - 1; + int index = params[2] - 1; - if(paramStruct->dg->params.at(index).type != HookParamType_ObjectPtr && paramStruct->dg->params.at(index).type != HookParamType_Object) - { - return pContext->ThrowNativeError("Invalid object value type %i", paramStruct->dg->params.at(index).type); + if(paramStruct->dg->params.at(index).type != HookParamType_ObjectPtr && paramStruct->dg->params.at(index).type != HookParamType_Object) + { + return pContext->ThrowNativeError("Invalid object value type %i", paramStruct->dg->params.at(index).type); + } + + size_t offset = GetParamOffset(paramStruct, index); + addr = GetObjectAddr(paramStruct->dg->params.at(index).type, paramStruct->dg->params.at(index).flags, paramStruct->orgParams, offset); } + else + { + if(paramStruct->dg->thisFuncCallConv != CallConv_THISCALL) + { + return pContext->ThrowNativeError("Parameter 'this' is only available in member functions, specify the calling convention type 'thiscall'"); + } - size_t offset = GetParamOffset(paramStruct, index); - void *addr = GetObjectAddr(paramStruct->dg->params.at(index).type, paramStruct->dg->params.at(index).flags, paramStruct->orgParams, offset); + if(paramStruct->dg->thisType != ThisPointer_Address && paramStruct->dg->thisType != ThisPointer_CBaseEntity && !(paramStruct->dg->thisType == ThisPointer_Ignore && paramStruct->dg->hookType == HookType_GameRules)) + { + return pContext->ThrowNativeError("Parameter 'this' is not specified as an address, it is not available"); + } + + addr = g_SHPtr->GetIfacePtr(); + } switch((ObjectValueType)params[4]) { diff --git a/extensions/dhooks/vhook.h b/extensions/dhooks/vhook.h index b58f9c4ff1..92dd279e80 100644 --- a/extensions/dhooks/vhook.h +++ b/extensions/dhooks/vhook.h @@ -162,6 +162,7 @@ class DHooksInfo int entity; ThisPointerType thisType; HookType hookType; + CallingConvention thisFuncCallConv; }; class DHooksCallback : public SourceHook::ISHDelegate, public DHooksInfo diff --git a/plugins/include/dhooks.inc b/plugins/include/dhooks.inc index 99f17e7e8f..fa36aa0102 100644 --- a/plugins/include/dhooks.inc +++ b/plugins/include/dhooks.inc @@ -310,7 +310,7 @@ methodmap DHookParam < Handle // Gets an object's variable value. // - // @param num Parameter number to get, starting at 1. + // @param num Parameter number to get, 0 for param "this", other parameters start from 1 // @param offset Byte offset within the object to the var to get. // @param type Type of var it is. // @@ -320,7 +320,7 @@ methodmap DHookParam < Handle // Gets an object's vector variable value. // - // @param num Parameter number to get, starting at 1. + // @param num Parameter number to get, 0 for param "this", other parameters start from 1. // @param offset Byte offset within the object to the var to get. // @param type Type of var it is. // @param vec Buffer to store the result vector. @@ -330,7 +330,7 @@ methodmap DHookParam < Handle // Gets an object's string variable value. // - // @param num Parameter number to get, starting at 1. + // @param num Parameter number to get, 0 for param "this", other parameters start from 1. // @param offset Byte offset within the object to the var to get. // @param type Type of var it is. // @param buffer Buffer to store the result string. @@ -344,7 +344,7 @@ methodmap DHookParam < Handle // The changes are only applied when MRES_ChangedHandled or MRES_ChangedOverride // is returned in the callback. // - // @param num Parameter number to set, starting at 1. + // @param num Parameter number to set, 0 for param "this", other parameters start from 1. // @param offset Byte offset within the object to the var to set. // @param type Type of var it is. // @param value The value to set the var to. @@ -357,7 +357,7 @@ methodmap DHookParam < Handle // The changes are only applied when MRES_ChangedHandled or MRES_ChangedOverride // is returned in the callback. // - // @param num Parameter number to set, starting at 1. + // @param num Parameter number to set, 0 for param "this", other parameters start from 1. // @param offset Byte offset within the object to the var to set. // @param type Type of var it is. // @param vec The value to set the vector var to. @@ -928,7 +928,7 @@ native void DHookSetReturnString(Handle hReturn, char[] value); * Gets an objects variable value * * @param hParams Handle to params structure - * @param num Param number to get. + * @param num Param number to get, 0 for param "this". * @param offset Offset within the object to the var to get. * @param type Type of var it is * @@ -941,7 +941,7 @@ native any DHookGetParamObjectPtrVar(Handle hParams, int num, int offset, Object * Sets an objects variable value * * @param hParams Handle to params structure - * @param num Param number to set. + * @param num Param number to set, 0 for param "this". * @param offset Offset within the object to the var to set. * @param type Type of var it is * @param value The value to set the var to. @@ -954,7 +954,7 @@ native void DHookSetParamObjectPtrVar(Handle hParams, int num, int offset, Objec * Gets an objects vector variable value * * @param hParams Handle to params structure - * @param num Param number to get. + * @param num Param number to get, 0 for param "this". * @param offset Offset within the object to the var to get. * @param type Type of var it is * @param buffer Buffer to store the result vector @@ -967,7 +967,7 @@ native void DHookGetParamObjectPtrVarVector(Handle hParams, int num, int offset, * Sets an objects vector variable value * * @param hParams Handle to params structure - * @param num Param number to set. + * @param num Param number to set, 0 for param "this". * @param offset Offset within the object to the var to set. * @param type Type of var it is * @param value The value to set the vector var to. @@ -980,7 +980,7 @@ native void DHookSetParamObjectPtrVarVector(Handle hParams, int num, int offset, * Gets an objects string variable value * * @param hParams Handle to params structure - * @param num Param number to get. + * @param num Param number to get, 0 for param "this". * @param offset Offset within the object to the var to get. * @param type Type of var it is * @param buffer Buffer to store the result vector