2013-08-20 04:33:44 +02:00
|
|
|
#ifndef _INCLUDE_VFUNC_CALL_H_
|
|
|
|
#define _INCLUDE_VFUNC_CALL_H_
|
|
|
|
|
|
|
|
#include "vhook.h"
|
2013-08-28 20:20:20 +02:00
|
|
|
#include "extension.h"
|
2016-08-30 22:40:24 +02:00
|
|
|
#include "util.h"
|
2013-08-28 20:20:20 +02:00
|
|
|
|
|
|
|
#define PARAMINFO_SWITCH(passType) \
|
2016-08-30 16:58:04 +02:00
|
|
|
paramInfo[i].flags = dg->params.at(i).flags; \
|
2014-08-19 19:14:48 +02:00
|
|
|
paramInfo[i].size = dg->params.at(i).size; \
|
2013-08-28 20:20:20 +02:00
|
|
|
paramInfo[i].type = passType;
|
|
|
|
|
|
|
|
#define VSTK_PARAM_SWITCH(paramType) \
|
|
|
|
if(paramStruct->isChanged[i]) \
|
|
|
|
{ \
|
2016-08-30 16:58:04 +02:00
|
|
|
*(paramType *)vptr = *(paramType *)newAddr; \
|
2013-08-28 20:20:20 +02:00
|
|
|
} \
|
|
|
|
else \
|
|
|
|
{ \
|
2016-08-30 16:58:04 +02:00
|
|
|
*(paramType *)vptr = *(paramType *)orgAddr; \
|
2013-08-28 20:20:20 +02:00
|
|
|
} \
|
2014-08-19 19:14:48 +02:00
|
|
|
if(i + 1 != dg->params.size()) \
|
2013-08-28 20:20:20 +02:00
|
|
|
{ \
|
2014-08-19 19:14:48 +02:00
|
|
|
vptr += dg->params.at(i).size; \
|
2013-08-28 20:20:20 +02:00
|
|
|
} \
|
|
|
|
break;
|
2016-08-30 16:58:04 +02:00
|
|
|
|
|
|
|
#define VSTK_PARAM_SWITCH_OBJECT() \
|
|
|
|
memcpy(vptr, objAddr, dg->params.at(i).size); \
|
2014-08-19 19:14:48 +02:00
|
|
|
if(i + 1 != dg->params.size()) \
|
2013-08-28 20:20:20 +02:00
|
|
|
{ \
|
2014-08-19 19:14:48 +02:00
|
|
|
vptr += dg->params.at(i).size; \
|
2013-08-28 20:20:20 +02:00
|
|
|
} \
|
|
|
|
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;
|
|
|
|
|
2016-08-31 17:37:48 +02:00
|
|
|
size_t size = GetParamsSize(dg);
|
2013-08-28 20:20:20 +02:00
|
|
|
|
|
|
|
unsigned char *vstk = (unsigned char *)malloc(sizeof(void *) + size);
|
|
|
|
unsigned char *vptr = vstk;
|
|
|
|
|
|
|
|
*(void **)vptr = iface;
|
|
|
|
|
|
|
|
if(paramStruct)
|
|
|
|
{
|
|
|
|
vptr += sizeof(void *);
|
2014-08-19 19:14:48 +02:00
|
|
|
paramInfo = (SourceMod::PassInfo *)malloc(sizeof(SourceMod::PassInfo) * dg->params.size());
|
2016-08-30 16:58:04 +02:00
|
|
|
|
2014-08-19 19:14:48 +02:00
|
|
|
for(int i = 0; i < (int)dg->params.size(); i++)
|
2013-08-28 20:20:20 +02:00
|
|
|
{
|
2016-08-30 16:58:04 +02:00
|
|
|
size_t offset = GetParamOffset(paramStruct, i);
|
|
|
|
|
|
|
|
void *orgAddr = (void **)((intptr_t)paramStruct->orgParams + offset);
|
|
|
|
void *newAddr = (void **)((intptr_t)paramStruct->newParams + offset);
|
|
|
|
|
2014-08-19 19:14:48 +02:00
|
|
|
switch(dg->params.at(i).type)
|
2013-08-28 20:20:20 +02:00
|
|
|
{
|
|
|
|
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);
|
2016-08-30 16:58:04 +02:00
|
|
|
VSTK_PARAM_SWITCH(float);
|
2013-08-28 20:20:20 +02:00
|
|
|
case HookParamType_String:
|
|
|
|
PARAMINFO_SWITCH(PassType_Object);
|
2016-08-30 16:58:04 +02:00
|
|
|
VSTK_PARAM_SWITCH(string_t);
|
2013-08-28 20:20:20 +02:00
|
|
|
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);
|
2016-06-26 19:00:27 +02:00
|
|
|
VSTK_PARAM_SWITCH(SDKVector *);
|
2013-08-28 20:20:20 +02:00
|
|
|
case HookParamType_CBaseEntity:
|
|
|
|
PARAMINFO_SWITCH(PassType_Basic);
|
|
|
|
VSTK_PARAM_SWITCH(CBaseEntity *);
|
|
|
|
case HookParamType_Edict:
|
|
|
|
PARAMINFO_SWITCH(PassType_Basic);
|
|
|
|
VSTK_PARAM_SWITCH(edict_t *);
|
2016-08-30 16:58:04 +02:00
|
|
|
case HookParamType_Object:
|
|
|
|
{
|
|
|
|
void *objAddr = GetObjectAddr(HookParamType_Object, paramStruct->dg->params.at(i).flags, paramStruct->orgParams, offset);
|
|
|
|
PARAMINFO_SWITCH(PassType_Object);
|
|
|
|
VSTK_PARAM_SWITCH_OBJECT();
|
|
|
|
}
|
2013-08-28 20:20:20 +02:00
|
|
|
default:
|
|
|
|
PARAMINFO_SWITCH(PassType_Basic);
|
|
|
|
VSTK_PARAM_SWITCH(void *);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
T ret = 0;
|
2016-08-30 16:58:04 +02:00
|
|
|
|
2013-08-28 20:20:20 +02:00
|
|
|
if(dg->returnType == ReturnType_Void)
|
|
|
|
{
|
2014-08-19 19:14:48 +02:00
|
|
|
pCall = g_pBinTools->CreateVCall(dg->offset, 0, 0, NULL, paramInfo, dg->params.size());
|
2013-08-28 20:20:20 +02:00
|
|
|
pCall->Execute(vstk, NULL);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-08-19 19:14:48 +02:00
|
|
|
pCall = g_pBinTools->CreateVCall(dg->offset, 0, 0, &returnInfo, paramInfo, dg->params.size());
|
2013-08-28 20:20:20 +02:00
|
|
|
pCall->Execute(vstk, &ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
pCall->Destroy();
|
|
|
|
free(vstk);
|
|
|
|
|
|
|
|
if(paramInfo != NULL)
|
|
|
|
{
|
|
|
|
free(paramInfo);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2013-08-29 21:18:43 +02:00
|
|
|
template <>
|
2016-06-26 19:00:27 +02:00
|
|
|
SDKVector CallVFunction<SDKVector>(DHooksCallback *dg, HookParamsStruct *paramStruct, void *iface)
|
2013-08-29 21:18:43 +02:00
|
|
|
{
|
|
|
|
SourceMod::PassInfo *paramInfo = NULL;
|
|
|
|
SourceMod::PassInfo returnInfo;
|
|
|
|
|
|
|
|
if(dg->returnType != ReturnType_Void)
|
|
|
|
{
|
|
|
|
returnInfo.flags = dg->returnFlag;
|
2016-06-26 19:00:27 +02:00
|
|
|
returnInfo.size = sizeof(SDKVector);
|
2013-08-29 21:18:43 +02:00
|
|
|
returnInfo.type = PassType_Object;
|
|
|
|
}
|
|
|
|
|
|
|
|
ICallWrapper *pCall;
|
|
|
|
|
2016-08-31 17:37:48 +02:00
|
|
|
size_t size = GetParamsSize(dg);
|
2013-08-29 21:18:43 +02:00
|
|
|
|
|
|
|
unsigned char *vstk = (unsigned char *)malloc(sizeof(void *) + size);
|
|
|
|
unsigned char *vptr = vstk;
|
|
|
|
|
|
|
|
*(void **)vptr = iface;
|
|
|
|
|
|
|
|
if(paramStruct)
|
|
|
|
{
|
|
|
|
vptr += sizeof(void *);
|
2014-08-19 19:14:48 +02:00
|
|
|
paramInfo = (SourceMod::PassInfo *)malloc(sizeof(SourceMod::PassInfo) * dg->params.size());
|
|
|
|
for(int i = 0; i < (int)dg->params.size(); i++)
|
2013-08-29 21:18:43 +02:00
|
|
|
{
|
2016-08-30 16:58:04 +02:00
|
|
|
size_t offset = GetParamOffset(paramStruct, i);
|
|
|
|
|
|
|
|
void *orgAddr = *(void **)((intptr_t)paramStruct->orgParams + offset);
|
|
|
|
void *newAddr = *(void **)((intptr_t)paramStruct->newParams + offset);
|
|
|
|
|
|
|
|
switch (dg->params.at(i).type)
|
2013-08-29 21:18:43 +02:00
|
|
|
{
|
|
|
|
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);
|
2016-08-30 16:58:04 +02:00
|
|
|
VSTK_PARAM_SWITCH(float);
|
2013-08-29 21:18:43 +02:00
|
|
|
case HookParamType_String:
|
|
|
|
PARAMINFO_SWITCH(PassType_Object);
|
2016-08-30 16:58:04 +02:00
|
|
|
VSTK_PARAM_SWITCH(string_t);
|
2013-08-29 21:18:43 +02:00
|
|
|
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);
|
2016-06-26 19:00:27 +02:00
|
|
|
VSTK_PARAM_SWITCH(SDKVector *);
|
2013-08-29 21:18:43 +02:00
|
|
|
case HookParamType_CBaseEntity:
|
|
|
|
PARAMINFO_SWITCH(PassType_Basic);
|
|
|
|
VSTK_PARAM_SWITCH(CBaseEntity *);
|
|
|
|
case HookParamType_Edict:
|
|
|
|
PARAMINFO_SWITCH(PassType_Basic);
|
|
|
|
VSTK_PARAM_SWITCH(edict_t *);
|
2016-08-30 16:58:04 +02:00
|
|
|
case HookParamType_Object:
|
|
|
|
{
|
|
|
|
void *objAddr = GetObjectAddr(HookParamType_Object, paramStruct->dg->params.at(i).flags, paramStruct->orgParams, offset);
|
|
|
|
PARAMINFO_SWITCH(PassType_Object);
|
|
|
|
VSTK_PARAM_SWITCH_OBJECT();
|
|
|
|
}
|
2013-08-29 21:18:43 +02:00
|
|
|
default:
|
|
|
|
PARAMINFO_SWITCH(PassType_Basic);
|
|
|
|
VSTK_PARAM_SWITCH(void *);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-26 19:00:27 +02:00
|
|
|
SDKVector ret;
|
2013-09-01 17:11:38 +02:00
|
|
|
|
2014-08-19 19:14:48 +02:00
|
|
|
pCall = g_pBinTools->CreateVCall(dg->offset, 0, 0, &returnInfo, paramInfo, dg->params.size());
|
2013-09-01 17:11:38 +02:00
|
|
|
pCall->Execute(vstk, &ret);
|
|
|
|
|
|
|
|
pCall->Destroy();
|
|
|
|
free(vstk);
|
|
|
|
|
|
|
|
if(paramInfo != NULL)
|
2013-08-29 21:18:43 +02:00
|
|
|
{
|
2013-09-01 17:11:38 +02:00
|
|
|
free(paramInfo);
|
2013-08-29 21:18:43 +02:00
|
|
|
}
|
2013-09-01 17:11:38 +02:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2014-08-19 19:30:12 +02:00
|
|
|
#ifndef WIN32
|
2013-09-01 17:11:38 +02:00
|
|
|
template <>
|
|
|
|
string_t CallVFunction<string_t>(DHooksCallback *dg, HookParamsStruct *paramStruct, void *iface)
|
|
|
|
{
|
|
|
|
SourceMod::PassInfo *paramInfo = NULL;
|
|
|
|
SourceMod::PassInfo returnInfo;
|
|
|
|
|
|
|
|
if(dg->returnType != ReturnType_Void)
|
2013-08-29 21:18:43 +02:00
|
|
|
{
|
2013-09-01 17:11:38 +02:00
|
|
|
returnInfo.flags = dg->returnFlag;
|
|
|
|
returnInfo.size = sizeof(string_t);
|
|
|
|
returnInfo.type = PassType_Object;
|
2013-08-29 21:18:43 +02:00
|
|
|
}
|
|
|
|
|
2013-09-01 17:11:38 +02:00
|
|
|
ICallWrapper *pCall;
|
|
|
|
|
2016-08-31 17:37:48 +02:00
|
|
|
size_t size = GetParamsSize(dg);
|
2013-09-01 17:11:38 +02:00
|
|
|
|
|
|
|
unsigned char *vstk = (unsigned char *)malloc(sizeof(void *) + size);
|
|
|
|
unsigned char *vptr = vstk;
|
|
|
|
|
|
|
|
*(void **)vptr = iface;
|
|
|
|
|
|
|
|
if(paramStruct)
|
|
|
|
{
|
|
|
|
vptr += sizeof(void *);
|
2014-08-19 19:14:48 +02:00
|
|
|
paramInfo = (SourceMod::PassInfo *)malloc(sizeof(SourceMod::PassInfo) * dg->params.size());
|
|
|
|
for(int i = 0; i < dg->params.size(); i++)
|
2013-09-01 17:11:38 +02:00
|
|
|
{
|
2016-08-30 16:58:04 +02:00
|
|
|
size_t offset = GetParamOffset(paramStruct, i);
|
|
|
|
|
|
|
|
void *orgAddr = *(void **)((intptr_t)paramStruct->orgParams + offset);
|
|
|
|
void *newAddr = *(void **)((intptr_t)paramStruct->newParams + offset);
|
|
|
|
|
|
|
|
switch (dg->params.at(i).type)
|
2013-09-01 17:11:38 +02:00
|
|
|
{
|
|
|
|
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);
|
2016-08-30 16:58:04 +02:00
|
|
|
VSTK_PARAM_SWITCH(float);
|
2013-09-01 17:11:38 +02:00
|
|
|
case HookParamType_String:
|
|
|
|
PARAMINFO_SWITCH(PassType_Object);
|
2016-08-30 16:58:04 +02:00
|
|
|
VSTK_PARAM_SWITCH(string_t);
|
2013-09-01 17:11:38 +02:00
|
|
|
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);
|
2016-06-26 19:00:27 +02:00
|
|
|
VSTK_PARAM_SWITCH(SDKVector *);
|
2013-09-01 17:11:38 +02:00
|
|
|
case HookParamType_CBaseEntity:
|
|
|
|
PARAMINFO_SWITCH(PassType_Basic);
|
|
|
|
VSTK_PARAM_SWITCH(CBaseEntity *);
|
|
|
|
case HookParamType_Edict:
|
|
|
|
PARAMINFO_SWITCH(PassType_Basic);
|
|
|
|
VSTK_PARAM_SWITCH(edict_t *);
|
2016-08-30 16:58:04 +02:00
|
|
|
case HookParamType_Object:
|
|
|
|
{
|
|
|
|
void *objAddr = GetObjectAddr(HookParamType_Object, paramStruct->dg->params.at(i).flags, paramStruct->orgParams, offset);
|
|
|
|
PARAMINFO_SWITCH(PassType_Object);
|
|
|
|
VSTK_PARAM_SWITCH_OBJECT();
|
|
|
|
}
|
2013-09-01 17:11:38 +02:00
|
|
|
default:
|
|
|
|
PARAMINFO_SWITCH(PassType_Basic);
|
|
|
|
VSTK_PARAM_SWITCH(void *);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
string_t ret;
|
|
|
|
|
2014-08-19 19:14:48 +02:00
|
|
|
pCall = g_pBinTools->CreateVCall(dg->offset, 0, 0, &returnInfo, paramInfo, dg->params.size());
|
2013-09-01 17:11:38 +02:00
|
|
|
pCall->Execute(vstk, &ret);
|
|
|
|
|
2013-08-29 21:18:43 +02:00
|
|
|
pCall->Destroy();
|
|
|
|
free(vstk);
|
|
|
|
|
|
|
|
if(paramInfo != NULL)
|
|
|
|
{
|
|
|
|
free(paramInfo);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
#endif
|
2013-08-20 04:33:44 +02:00
|
|
|
#endif
|