More return struct fixes. Add Vector and Vector * return support. Change vfunc_call to use template. Update makefile
This commit is contained in:
parent
e07e2286cb
commit
c5b8d2fecb
2
Makefile
2
Makefile
@ -24,7 +24,7 @@ PROJECT = dhooks
|
|||||||
#Uncomment for Metamod: Source enabled extension
|
#Uncomment for Metamod: Source enabled extension
|
||||||
USEMETA = true
|
USEMETA = true
|
||||||
|
|
||||||
OBJECTS = sdk/smsdk_ext.cpp extension.cpp vhook.cpp $(SMSDK)/public/jit/x86/assembler-x86.cpp listeners.cpp natives.cpp vfunc_call.cpp
|
OBJECTS = sdk/smsdk_ext.cpp extension.cpp vhook.cpp $(SMSDK)/public/jit/x86/assembler-x86.cpp listeners.cpp natives.cpp
|
||||||
|
|
||||||
##############################################
|
##############################################
|
||||||
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
|
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
|
||||||
|
@ -886,7 +886,6 @@
|
|||||||
<ClCompile Include="..\extension.cpp" />
|
<ClCompile Include="..\extension.cpp" />
|
||||||
<ClCompile Include="..\listeners.cpp" />
|
<ClCompile Include="..\listeners.cpp" />
|
||||||
<ClCompile Include="..\natives.cpp" />
|
<ClCompile Include="..\natives.cpp" />
|
||||||
<ClCompile Include="..\vfunc_call.cpp" />
|
|
||||||
<ClCompile Include="..\vhook.cpp" />
|
<ClCompile Include="..\vhook.cpp" />
|
||||||
<ClCompile Include="..\sdk\smsdk_ext.cpp" />
|
<ClCompile Include="..\sdk\smsdk_ext.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\natives.cpp" />
|
<ClCompile Include="..\natives.cpp" />
|
||||||
<ClCompile Include="..\listeners.cpp" />
|
<ClCompile Include="..\listeners.cpp" />
|
||||||
<ClCompile Include="..\vfunc_call.cpp" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\extension.h">
|
<ClInclude Include="..\extension.h">
|
||||||
|
56
natives.cpp
56
natives.cpp
@ -947,6 +947,58 @@ cell_t Native_GetParamObjectPtrString(IPluginContext *pContext, const cell_t *pa
|
|||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DHookGetReturnVector(Handle:hReturn, Float:vec[3])
|
||||||
|
cell_t Native_GetReturnVector(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
HookReturnStruct *returnStruct;
|
||||||
|
|
||||||
|
if(!GetHandleIfValidOrError(g_HookReturnHandle, (void **)&returnStruct, pContext, params[1]))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t *buffer;
|
||||||
|
pContext->LocalToPhysAddr(params[2], &buffer);
|
||||||
|
|
||||||
|
if(returnStruct->type == ReturnType_Vector || returnStruct->type == ReturnType_VectorPtr)
|
||||||
|
{
|
||||||
|
buffer[0] = sp_ftoc((*(Vector **)returnStruct->orgResult)->x);
|
||||||
|
buffer[1] = sp_ftoc((*(Vector **)returnStruct->orgResult)->y);
|
||||||
|
buffer[2] = sp_ftoc((*(Vector **)returnStruct->orgResult)->z);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return pContext->ThrowNativeError("Return type is not a vector type");
|
||||||
|
}
|
||||||
|
|
||||||
|
//DHookSetReturnVector(Handle:hReturn, Float:vec[3])
|
||||||
|
cell_t Native_SetReturnVector(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
HookReturnStruct *returnStruct;
|
||||||
|
|
||||||
|
if(!GetHandleIfValidOrError(g_HookReturnHandle, (void **)&returnStruct, pContext, params[1]))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t *buffer;
|
||||||
|
pContext->LocalToPhysAddr(params[2], &buffer);
|
||||||
|
|
||||||
|
if(returnStruct->type == ReturnType_Vector || returnStruct->type == ReturnType_VectorPtr)
|
||||||
|
{
|
||||||
|
if(*(Vector **)returnStruct->newResult != NULL)
|
||||||
|
{
|
||||||
|
delete *(Vector **)returnStruct->newResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
*(Vector **)returnStruct->newResult = new Vector(sp_ctof(buffer[0]), sp_ctof(buffer[1]), sp_ctof(buffer[2]));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return pContext->ThrowNativeError("Return type is not a vector type");
|
||||||
|
}
|
||||||
|
|
||||||
//native bool:DHookIsNullParam(Handle:hParams, num);
|
//native bool:DHookIsNullParam(Handle:hParams, num);
|
||||||
cell_t Native_IsNullParam(IPluginContext *pContext, const cell_t *params)
|
cell_t Native_IsNullParam(IPluginContext *pContext, const cell_t *params)
|
||||||
{
|
{
|
||||||
@ -986,8 +1038,8 @@ sp_nativeinfo_t g_Natives[] =
|
|||||||
{"DHookSetReturn", Native_SetReturn},
|
{"DHookSetReturn", Native_SetReturn},
|
||||||
{"DHookSetParam", Native_SetParam},
|
{"DHookSetParam", Native_SetParam},
|
||||||
{"DHookGetParamVector", Native_GetParamVector},
|
{"DHookGetParamVector", Native_GetParamVector},
|
||||||
/*{"DHookGetReturnVector", Native_GetReturnVector},
|
{"DHookGetReturnVector", Native_GetReturnVector},
|
||||||
{"DHookSetReturnVector", Native_SetReturnVector},*/
|
{"DHookSetReturnVector", Native_SetReturnVector},
|
||||||
{"DHookSetParamVector", Native_SetParamVector},
|
{"DHookSetParamVector", Native_SetParamVector},
|
||||||
{"DHookGetParamString", Native_GetParamString},
|
{"DHookGetParamString", Native_GetParamString},
|
||||||
{"DHookGetReturnString", Native_GetReturnString},
|
{"DHookGetReturnString", Native_GetReturnString},
|
||||||
|
130
vfunc_call.h
130
vfunc_call.h
@ -2,6 +2,134 @@
|
|||||||
#define _INCLUDE_VFUNC_CALL_H_
|
#define _INCLUDE_VFUNC_CALL_H_
|
||||||
|
|
||||||
#include "vhook.h"
|
#include "vhook.h"
|
||||||
|
#include "extension.h"
|
||||||
|
|
||||||
|
#define PARAMINFO_SWITCH(passType) \
|
||||||
|
paramInfo[i].flags = dg->params.Element(i).flag; \
|
||||||
|
paramInfo[i].size = dg->params.Element(i).size; \
|
||||||
|
paramInfo[i].type = passType;
|
||||||
|
|
||||||
|
#define VSTK_PARAM_SWITCH(paramType) \
|
||||||
|
if(paramStruct->isChanged[i]) \
|
||||||
|
{ \
|
||||||
|
*(paramType *)vptr = (paramType)(paramStruct->newParams[i]); \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
*(paramType *)vptr = (paramType)(paramStruct->orgParams[i]); \
|
||||||
|
} \
|
||||||
|
if(i + 1 != dg->params.Count()) \
|
||||||
|
{ \
|
||||||
|
vptr += dg->params.Element(i).size; \
|
||||||
|
} \
|
||||||
|
break;
|
||||||
|
#define VSTK_PARAM_SWITCH_FLOAT() \
|
||||||
|
if(paramStruct->isChanged[i]) \
|
||||||
|
{ \
|
||||||
|
*(float *)vptr = *(float *)(paramStruct->newParams[i]); \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
*(float *)vptr = *(float *)(paramStruct->orgParams[i]); \
|
||||||
|
} \
|
||||||
|
if(i + 1 != dg->params.Count()) \
|
||||||
|
{ \
|
||||||
|
vptr += dg->params.Element(i).size; \
|
||||||
|
} \
|
||||||
|
break;
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
T CallVFunction(DHooksCallback *dg, HookParamsStruct *paramStruct, void *iface)
|
||||||
|
{
|
||||||
|
SourceMod::PassInfo *paramInfo = NULL;
|
||||||
|
SourceMod::PassInfo returnInfo;
|
||||||
|
|
||||||
|
if(dg->returnType != ReturnType_Void)
|
||||||
|
{
|
||||||
|
returnInfo.flags = dg->returnFlag;
|
||||||
|
returnInfo.size = sizeof(T);
|
||||||
|
if( dg->returnType != ReturnType_Vector)
|
||||||
|
{
|
||||||
|
returnInfo.type = PassType_Basic;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
returnInfo.type = PassType_Object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ICallWrapper *pCall;
|
||||||
|
|
||||||
|
size_t size = GetStackArgsSize(dg);
|
||||||
|
|
||||||
|
unsigned char *vstk = (unsigned char *)malloc(sizeof(void *) + size);
|
||||||
|
unsigned char *vptr = vstk;
|
||||||
|
|
||||||
|
*(void **)vptr = iface;
|
||||||
|
|
||||||
|
if(paramStruct)
|
||||||
|
{
|
||||||
|
vptr += sizeof(void *);
|
||||||
|
paramInfo = (SourceMod::PassInfo *)malloc(sizeof(SourceMod::PassInfo) * dg->params.Count());
|
||||||
|
for(int i = 0; i < dg->params.Count(); i++)
|
||||||
|
{
|
||||||
|
switch(dg->params.Element(i).type)
|
||||||
|
{
|
||||||
|
case HookParamType_Int:
|
||||||
|
PARAMINFO_SWITCH(PassType_Basic);
|
||||||
|
VSTK_PARAM_SWITCH(int);
|
||||||
|
case HookParamType_Bool:
|
||||||
|
PARAMINFO_SWITCH(PassType_Basic);
|
||||||
|
VSTK_PARAM_SWITCH(cell_t);
|
||||||
|
case HookParamType_Float:
|
||||||
|
PARAMINFO_SWITCH(PassType_Float);
|
||||||
|
VSTK_PARAM_SWITCH_FLOAT();
|
||||||
|
case HookParamType_String:
|
||||||
|
PARAMINFO_SWITCH(PassType_Object);
|
||||||
|
VSTK_PARAM_SWITCH(int);
|
||||||
|
case HookParamType_StringPtr:
|
||||||
|
PARAMINFO_SWITCH(PassType_Basic);
|
||||||
|
VSTK_PARAM_SWITCH(string_t *);
|
||||||
|
case HookParamType_CharPtr:
|
||||||
|
PARAMINFO_SWITCH(PassType_Basic);
|
||||||
|
VSTK_PARAM_SWITCH(char *);
|
||||||
|
case HookParamType_VectorPtr:
|
||||||
|
PARAMINFO_SWITCH(PassType_Basic);
|
||||||
|
VSTK_PARAM_SWITCH(Vector *);
|
||||||
|
case HookParamType_CBaseEntity:
|
||||||
|
PARAMINFO_SWITCH(PassType_Basic);
|
||||||
|
VSTK_PARAM_SWITCH(CBaseEntity *);
|
||||||
|
case HookParamType_Edict:
|
||||||
|
PARAMINFO_SWITCH(PassType_Basic);
|
||||||
|
VSTK_PARAM_SWITCH(edict_t *);
|
||||||
|
default:
|
||||||
|
PARAMINFO_SWITCH(PassType_Basic);
|
||||||
|
VSTK_PARAM_SWITCH(void *);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
T ret = 0;
|
||||||
|
if(dg->returnType == ReturnType_Void)
|
||||||
|
{
|
||||||
|
pCall = g_pBinTools->CreateVCall(dg->offset, 0, 0, NULL, paramInfo, dg->params.Count());
|
||||||
|
pCall->Execute(vstk, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pCall = g_pBinTools->CreateVCall(dg->offset, 0, 0, &returnInfo, paramInfo, dg->params.Count());
|
||||||
|
pCall->Execute(vstk, &ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
pCall->Destroy();
|
||||||
|
free(vstk);
|
||||||
|
|
||||||
|
if(paramInfo != NULL)
|
||||||
|
{
|
||||||
|
free(paramInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void *CallVFunction(DHooksCallback *dg, HookParamsStruct *paramStruct, void *iface);
|
|
||||||
#endif
|
#endif
|
||||||
|
195
vhook.cpp
195
vhook.cpp
@ -53,6 +53,10 @@ DHooksManager::DHooksManager(HookSetup *setup, void *iface, IPluginFunction *rem
|
|||||||
{
|
{
|
||||||
protoInfo.SetReturnType(sizeof(string_t), SourceHook::PassInfo::PassType_Object, setup->returnFlag, NULL, NULL, NULL, NULL);//We have to be 4 really... or else RIP
|
protoInfo.SetReturnType(sizeof(string_t), SourceHook::PassInfo::PassType_Object, setup->returnFlag, NULL, NULL, NULL, NULL);//We have to be 4 really... or else RIP
|
||||||
}
|
}
|
||||||
|
else if(this->callback->returnType == ReturnType_Vector)
|
||||||
|
{
|
||||||
|
protoInfo.SetReturnType(sizeof(Vector), SourceHook::PassInfo::PassType_Object, setup->returnFlag, NULL, NULL, NULL, NULL);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
protoInfo.SetReturnType(sizeof(void *), SourceHook::PassInfo::PassType_Basic, setup->returnFlag, NULL, NULL, NULL, NULL);
|
protoInfo.SetReturnType(sizeof(void *), SourceHook::PassInfo::PassType_Basic, setup->returnFlag, NULL, NULL, NULL, NULL);
|
||||||
@ -105,16 +109,29 @@ size_t GetStackArgsSize(DHooksCallback *dg)
|
|||||||
{
|
{
|
||||||
res += dg->params.Element(i).size;
|
res += dg->params.Element(i).size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(dg->returnType == ReturnType_Vector)//Account for result vector ptr.
|
||||||
|
{
|
||||||
|
res += sizeof(void *);
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
HookParamsStruct *GetParamStruct(DHooksCallback *dg, void **argStack, size_t argStackSize)
|
HookParamsStruct *GetParamStruct(DHooksCallback *dg, void **argStack, size_t argStackSize)
|
||||||
{
|
{
|
||||||
HookParamsStruct *params = new HookParamsStruct();
|
HookParamsStruct *params = new HookParamsStruct();
|
||||||
params->dg = dg;
|
params->dg = dg;
|
||||||
params->orgParams = (void **)malloc(argStackSize);
|
if(dg->returnType != ReturnType_Vector)
|
||||||
|
{
|
||||||
|
params->orgParams = (void **)malloc(argStackSize);
|
||||||
|
memcpy(params->orgParams, argStack, argStackSize);
|
||||||
|
}
|
||||||
|
else //Offset result ptr
|
||||||
|
{
|
||||||
|
params->orgParams = (void **)malloc(argStackSize-sizeof(void *));
|
||||||
|
memcpy(params->orgParams, argStack+sizeof(void *), argStackSize);
|
||||||
|
}
|
||||||
params->newParams = (void **)malloc(dg->params.Count() * sizeof(void *));
|
params->newParams = (void **)malloc(dg->params.Count() * sizeof(void *));
|
||||||
params->isChanged = (bool *)malloc(dg->params.Count() * sizeof(bool));
|
params->isChanged = (bool *)malloc(dg->params.Count() * sizeof(bool));
|
||||||
memcpy(params->orgParams, argStack, argStackSize);
|
|
||||||
for(int i = 0; i < dg->params.Count(); i++)
|
for(int i = 0; i < dg->params.Count(); i++)
|
||||||
{
|
{
|
||||||
params->newParams[i] = NULL;
|
params->newParams[i] = NULL;
|
||||||
@ -128,6 +145,7 @@ HookReturnStruct *GetReturnStruct(DHooksCallback *dg)
|
|||||||
res->isChanged = false;
|
res->isChanged = false;
|
||||||
res->type = dg->returnType;
|
res->type = dg->returnType;
|
||||||
res->newResult = malloc(sizeof(void *));
|
res->newResult = malloc(sizeof(void *));
|
||||||
|
*(void **)res->newResult = NULL;
|
||||||
res->orgResult = malloc(sizeof(void *));
|
res->orgResult = malloc(sizeof(void *));
|
||||||
|
|
||||||
if(g_SHPtr->GetOrigRet() && dg->post)
|
if(g_SHPtr->GetOrigRet() && dg->post)
|
||||||
@ -137,7 +155,6 @@ HookReturnStruct *GetReturnStruct(DHooksCallback *dg)
|
|||||||
case ReturnType_String:
|
case ReturnType_String:
|
||||||
*(string_t *)res->orgResult = META_RESULT_ORIG_RET(string_t);
|
*(string_t *)res->orgResult = META_RESULT_ORIG_RET(string_t);
|
||||||
break;
|
break;
|
||||||
//ReturnType_Vector,
|
|
||||||
case ReturnType_Int:
|
case ReturnType_Int:
|
||||||
*(int *)res->orgResult = META_RESULT_ORIG_RET(int);
|
*(int *)res->orgResult = META_RESULT_ORIG_RET(int);
|
||||||
break;
|
break;
|
||||||
@ -147,7 +164,14 @@ HookReturnStruct *GetReturnStruct(DHooksCallback *dg)
|
|||||||
case ReturnType_Float:
|
case ReturnType_Float:
|
||||||
*(float *)res->orgResult = META_RESULT_ORIG_RET(float);
|
*(float *)res->orgResult = META_RESULT_ORIG_RET(float);
|
||||||
break;
|
break;
|
||||||
|
case ReturnType_Vector:
|
||||||
|
{
|
||||||
|
Vector vec = META_RESULT_ORIG_RET(Vector);
|
||||||
|
*(Vector **)res->orgResult = new Vector(vec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
|
*(void **)res->orgResult = malloc(sizeof(void **));
|
||||||
*(void **)res->orgResult = META_RESULT_ORIG_RET(void *);
|
*(void **)res->orgResult = META_RESULT_ORIG_RET(void *);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -264,7 +288,7 @@ void *Callback(DHooksCallback *dg, void **argStack)
|
|||||||
g_SHPtr->DoRecall();
|
g_SHPtr->DoRecall();
|
||||||
g_SHPtr->SetRes(MRES_SUPERCEDE);
|
g_SHPtr->SetRes(MRES_SUPERCEDE);
|
||||||
mres = MRES_SUPERCEDE;
|
mres = MRES_SUPERCEDE;
|
||||||
ret = CallVFunction(dg, paramStruct, g_SHPtr->GetIfacePtr());
|
ret = CallVFunction<void *>(dg, paramStruct, g_SHPtr->GetIfacePtr());
|
||||||
break;
|
break;
|
||||||
case MRES_ChangedOverride:
|
case MRES_ChangedOverride:
|
||||||
if(dg->returnType != ReturnType_Void)
|
if(dg->returnType != ReturnType_Void)
|
||||||
@ -284,7 +308,7 @@ void *Callback(DHooksCallback *dg, void **argStack)
|
|||||||
g_SHPtr->DoRecall();
|
g_SHPtr->DoRecall();
|
||||||
g_SHPtr->SetRes(MRES_SUPERCEDE);
|
g_SHPtr->SetRes(MRES_SUPERCEDE);
|
||||||
mres = MRES_SUPERCEDE;
|
mres = MRES_SUPERCEDE;
|
||||||
CallVFunction(dg, paramStruct, g_SHPtr->GetIfacePtr());
|
CallVFunction<void *>(dg, paramStruct, g_SHPtr->GetIfacePtr());
|
||||||
break;
|
break;
|
||||||
case MRES_Override:
|
case MRES_Override:
|
||||||
if(dg->returnType != ReturnType_Void)
|
if(dg->returnType != ReturnType_Void)
|
||||||
@ -418,7 +442,7 @@ void *Callback_float(DHooksCallback *dg, void **argStack)
|
|||||||
g_SHPtr->DoRecall();
|
g_SHPtr->DoRecall();
|
||||||
g_SHPtr->SetRes(MRES_SUPERCEDE);
|
g_SHPtr->SetRes(MRES_SUPERCEDE);
|
||||||
mres = MRES_SUPERCEDE;
|
mres = MRES_SUPERCEDE;
|
||||||
ret = CallVFunction(dg, paramStruct, g_SHPtr->GetIfacePtr());
|
*(float *)ret = CallVFunction<float>(dg, paramStruct, g_SHPtr->GetIfacePtr());
|
||||||
break;
|
break;
|
||||||
case MRES_ChangedOverride:
|
case MRES_ChangedOverride:
|
||||||
if(dg->returnType != ReturnType_Void)
|
if(dg->returnType != ReturnType_Void)
|
||||||
@ -438,7 +462,7 @@ void *Callback_float(DHooksCallback *dg, void **argStack)
|
|||||||
g_SHPtr->DoRecall();
|
g_SHPtr->DoRecall();
|
||||||
g_SHPtr->SetRes(MRES_SUPERCEDE);
|
g_SHPtr->SetRes(MRES_SUPERCEDE);
|
||||||
mres = MRES_SUPERCEDE;
|
mres = MRES_SUPERCEDE;
|
||||||
CallVFunction(dg, paramStruct, g_SHPtr->GetIfacePtr());
|
CallVFunction<float>(dg, paramStruct, g_SHPtr->GetIfacePtr());
|
||||||
break;
|
break;
|
||||||
case MRES_Override:
|
case MRES_Override:
|
||||||
if(dg->returnType != ReturnType_Void)
|
if(dg->returnType != ReturnType_Void)
|
||||||
@ -497,3 +521,160 @@ void *Callback_float(DHooksCallback *dg, void **argStack)
|
|||||||
}
|
}
|
||||||
return *(float *)ret;
|
return *(float *)ret;
|
||||||
}
|
}
|
||||||
|
Vector *Callback_vector(DHooksCallback *dg, void **argStack, size_t *argsizep)
|
||||||
|
{
|
||||||
|
Vector *vec_result = (Vector *)argStack[0]; // Save the result
|
||||||
|
|
||||||
|
HookReturnStruct *returnStruct = NULL;
|
||||||
|
HookParamsStruct *paramStruct = NULL;
|
||||||
|
Handle_t rHndl;
|
||||||
|
Handle_t pHndl;
|
||||||
|
|
||||||
|
#ifndef __linux__
|
||||||
|
*argsizep = GetStackArgsSize(dg);
|
||||||
|
#else
|
||||||
|
size_t argsize = GetStackArgsSize(dg);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(dg->thisType == ThisPointer_CBaseEntity || dg->thisType == ThisPointer_Address)
|
||||||
|
{
|
||||||
|
dg->plugin_callback->PushCell(GetThisPtr(g_SHPtr->GetIfacePtr(), dg->thisType));
|
||||||
|
}
|
||||||
|
|
||||||
|
returnStruct = GetReturnStruct(dg);
|
||||||
|
rHndl = handlesys->CreateHandle(g_HookReturnHandle, returnStruct, dg->plugin_callback->GetParentRuntime()->GetDefaultContext()->GetIdentity(), myself->GetIdentity(), NULL);
|
||||||
|
|
||||||
|
if(!rHndl)
|
||||||
|
{
|
||||||
|
dg->plugin_callback->Cancel();
|
||||||
|
if(returnStruct)
|
||||||
|
{
|
||||||
|
delete returnStruct;
|
||||||
|
}
|
||||||
|
g_SHPtr->SetRes(MRES_IGNORED);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
dg->plugin_callback->PushCell(rHndl);
|
||||||
|
|
||||||
|
#ifndef __linux__
|
||||||
|
if(*argsizep > 0)
|
||||||
|
{
|
||||||
|
paramStruct = GetParamStruct(dg, argStack, *argsizep);
|
||||||
|
#else
|
||||||
|
if(argsize > 0)
|
||||||
|
{
|
||||||
|
paramStruct = GetParamStruct(dg, argStack, argsize);
|
||||||
|
#endif
|
||||||
|
pHndl = handlesys->CreateHandle(g_HookParamsHandle, paramStruct, dg->plugin_callback->GetParentRuntime()->GetDefaultContext()->GetIdentity(), myself->GetIdentity(), NULL);
|
||||||
|
if(!pHndl)
|
||||||
|
{
|
||||||
|
dg->plugin_callback->Cancel();
|
||||||
|
if(returnStruct)
|
||||||
|
{
|
||||||
|
delete returnStruct;
|
||||||
|
}
|
||||||
|
if(paramStruct)
|
||||||
|
{
|
||||||
|
delete paramStruct;
|
||||||
|
}
|
||||||
|
g_SHPtr->SetRes(MRES_IGNORED);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
dg->plugin_callback->PushCell(pHndl);
|
||||||
|
}
|
||||||
|
cell_t result = (cell_t)MRES_Ignored;
|
||||||
|
META_RES mres = MRES_IGNORED;
|
||||||
|
dg->plugin_callback->Execute(&result);
|
||||||
|
|
||||||
|
void *ret = g_SHPtr->GetOverrideRetPtr();
|
||||||
|
ret = vec_result;
|
||||||
|
switch((MRESReturn)result)
|
||||||
|
{
|
||||||
|
case MRES_Handled:
|
||||||
|
case MRES_ChangedHandled:
|
||||||
|
g_SHPtr->DoRecall();
|
||||||
|
g_SHPtr->SetRes(MRES_SUPERCEDE);
|
||||||
|
mres = MRES_SUPERCEDE;
|
||||||
|
*vec_result = CallVFunction<Vector>(dg, paramStruct, g_SHPtr->GetIfacePtr());
|
||||||
|
break;
|
||||||
|
case MRES_ChangedOverride:
|
||||||
|
if(dg->returnType != ReturnType_Void)
|
||||||
|
{
|
||||||
|
if(returnStruct->isChanged)
|
||||||
|
{
|
||||||
|
*vec_result = **(Vector **)returnStruct->newResult;
|
||||||
|
}
|
||||||
|
else //Throw an error if no override was set
|
||||||
|
{
|
||||||
|
g_SHPtr->SetRes(MRES_IGNORED);
|
||||||
|
mres = MRES_IGNORED;
|
||||||
|
dg->plugin_callback->GetParentRuntime()->GetDefaultContext()->ThrowNativeError("Tried to override return value without return value being set");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_SHPtr->DoRecall();
|
||||||
|
g_SHPtr->SetRes(MRES_SUPERCEDE);
|
||||||
|
mres = MRES_SUPERCEDE;
|
||||||
|
CallVFunction<Vector>(dg, paramStruct, g_SHPtr->GetIfacePtr());
|
||||||
|
break;
|
||||||
|
case MRES_Override:
|
||||||
|
if(dg->returnType != ReturnType_Void)
|
||||||
|
{
|
||||||
|
if(returnStruct->isChanged)
|
||||||
|
{
|
||||||
|
g_SHPtr->SetRes(MRES_OVERRIDE);
|
||||||
|
mres = MRES_OVERRIDE;
|
||||||
|
*vec_result = **(Vector **)returnStruct->newResult;
|
||||||
|
}
|
||||||
|
else //Throw an error if no override was set
|
||||||
|
{
|
||||||
|
g_SHPtr->SetRes(MRES_IGNORED);
|
||||||
|
mres = MRES_IGNORED;
|
||||||
|
dg->plugin_callback->GetParentRuntime()->GetDefaultContext()->ThrowNativeError("Tried to override return value without return value being set");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MRES_Supercede:
|
||||||
|
if(dg->returnType != ReturnType_Void)
|
||||||
|
{
|
||||||
|
if(returnStruct->isChanged)
|
||||||
|
{
|
||||||
|
g_SHPtr->SetRes(MRES_SUPERCEDE);
|
||||||
|
mres = MRES_SUPERCEDE;
|
||||||
|
*vec_result = **(Vector **)returnStruct->newResult;
|
||||||
|
}
|
||||||
|
else //Throw an error if no override was set
|
||||||
|
{
|
||||||
|
g_SHPtr->SetRes(MRES_IGNORED);
|
||||||
|
mres = MRES_IGNORED;
|
||||||
|
dg->plugin_callback->GetParentRuntime()->GetDefaultContext()->ThrowNativeError("Tried to override return value without return value being set");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_SHPtr->SetRes(MRES_IGNORED);
|
||||||
|
mres = MRES_IGNORED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
HandleSecurity sec(dg->plugin_callback->GetParentRuntime()->GetDefaultContext()->GetIdentity(), myself->GetIdentity());
|
||||||
|
|
||||||
|
if(returnStruct)
|
||||||
|
{
|
||||||
|
handlesys->FreeHandle(rHndl, &sec);
|
||||||
|
}
|
||||||
|
if(paramStruct)
|
||||||
|
{
|
||||||
|
handlesys->FreeHandle(pHndl, &sec);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dg->returnType == ReturnType_Void || mres <= MRES_HANDLED)
|
||||||
|
{
|
||||||
|
META_CONPRINT("Returning now\n");
|
||||||
|
vec_result->x = 0;
|
||||||
|
vec_result->y = 0;
|
||||||
|
vec_result->z = 0;
|
||||||
|
return vec_result;
|
||||||
|
}
|
||||||
|
return vec_result;
|
||||||
|
}
|
||||||
|
43
vhook.h
43
vhook.h
@ -91,7 +91,7 @@ class HookReturnStruct
|
|||||||
public:
|
public:
|
||||||
~HookReturnStruct()
|
~HookReturnStruct()
|
||||||
{
|
{
|
||||||
if(this->type != ReturnType_CharPtr && this->type != ReturnType_StringPtr)
|
if(this->type != ReturnType_CharPtr && this->type != ReturnType_StringPtr && this->type != ReturnType_Vector && this->type != ReturnType_VectorPtr)
|
||||||
{
|
{
|
||||||
free(this->newResult);
|
free(this->newResult);
|
||||||
}
|
}
|
||||||
@ -105,6 +105,18 @@ public:
|
|||||||
{
|
{
|
||||||
delete *(string_t **)this->newResult;
|
delete *(string_t **)this->newResult;
|
||||||
}
|
}
|
||||||
|
else if(this->type == ReturnType_Vector || this->type == ReturnType_VectorPtr)
|
||||||
|
{
|
||||||
|
delete *(Vector **)this->newResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(this->type == ReturnType_Vector || this->type == ReturnType_VectorPtr)
|
||||||
|
{
|
||||||
|
delete *(Vector **)this->orgResult;
|
||||||
|
}
|
||||||
|
else if(this->type != ReturnType_String && this->type != ReturnType_Int && this->type != ReturnType_Bool && this->type != ReturnType_Float)
|
||||||
|
{
|
||||||
|
free(*(void **)this->orgResult);
|
||||||
}
|
}
|
||||||
free(this->orgResult);
|
free(this->orgResult);
|
||||||
}
|
}
|
||||||
@ -149,6 +161,7 @@ public:
|
|||||||
#ifndef __linux__
|
#ifndef __linux__
|
||||||
void *Callback(DHooksCallback *dg, void **stack, size_t *argsizep);
|
void *Callback(DHooksCallback *dg, void **stack, size_t *argsizep);
|
||||||
float Callback_float(DHooksCallback *dg, void **stack, size_t *argsizep);
|
float Callback_float(DHooksCallback *dg, void **stack, size_t *argsizep);
|
||||||
|
Vector *Callback_vector(DHooksCallback *dg, void **stack, size_t *argsizep);
|
||||||
#else
|
#else
|
||||||
void *Callback(DHooksCallback *dg, void **stack);
|
void *Callback(DHooksCallback *dg, void **stack);
|
||||||
float Callback_float(DHooksCallback *dg, void **stack);
|
float Callback_float(DHooksCallback *dg, void **stack);
|
||||||
@ -181,23 +194,35 @@ static void *GenerateThunk(ReturnType type)
|
|||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
// HUGE THANKS TO BAILOPAN (dvander)!
|
||||||
static void *GenerateThunk(ReturnType type)
|
static void *GenerateThunk(ReturnType type)
|
||||||
{
|
{
|
||||||
MacroAssemblerX86 masm;
|
MacroAssemblerX86 masm;
|
||||||
|
static const size_t kStackNeeded = (3 + 1) * 4; // 3 args max, 1 locals max
|
||||||
|
static const size_t kReserve = ke::Align(kStackNeeded+8, 16)-8;
|
||||||
|
|
||||||
masm.push(ebp);
|
masm.push(ebp);
|
||||||
masm.movl(ebp, esp);
|
masm.movl(ebp, esp);
|
||||||
masm.subl(esp, 4);
|
masm.subl(esp, kReserve);
|
||||||
masm.push(esp);
|
masm.lea(eax, Operand(esp, 3 * 4)); // ptr to 2nd var after argument space
|
||||||
masm.lea(eax, Operand(ebp, 8));
|
masm.movl(Operand(esp, 2 * 4), eax); // set the ptr as the third argument
|
||||||
masm.push(eax);
|
masm.lea(eax, Operand(ebp, 8)); // grab the incoming caller argument vector
|
||||||
masm.push(ecx);
|
masm.movl(Operand(esp, 1 * 4), eax); // set that as the 2nd argument
|
||||||
|
masm.movl(Operand(esp, 0 * 4), ecx); // set |this| as the 1st argument
|
||||||
if(type == ReturnType_Float)
|
if(type == ReturnType_Float)
|
||||||
|
{
|
||||||
masm.call(ExternalAddress(Callback_float));
|
masm.call(ExternalAddress(Callback_float));
|
||||||
|
}
|
||||||
|
else if(type == ReturnType_Vector)
|
||||||
|
{
|
||||||
|
masm.call(ExternalAddress(Callback_vector));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
masm.call(ExternalAddress(Callback));
|
masm.call(ExternalAddress(Callback));
|
||||||
masm.addl(esp, 12);
|
}
|
||||||
masm.pop(ecx); // grab arg size
|
masm.movl(ecx, Operand(esp, 3*4));
|
||||||
|
masm.addl(esp, kReserve);
|
||||||
masm.pop(ebp); // restore ebp
|
masm.pop(ebp); // restore ebp
|
||||||
masm.pop(edx); // grab return address in edx
|
masm.pop(edx); // grab return address in edx
|
||||||
masm.addl(esp, ecx); // remove arguments
|
masm.addl(esp, ecx); // remove arguments
|
||||||
|
Loading…
Reference in New Issue
Block a user