Add more natives, Fix using deprecated functions, Add support for float returns, Fix more callback return stuff.

This commit is contained in:
Dr!fter 2013-08-21 22:18:52 -04:00
parent 07f7869d10
commit 6a47b6f1ef
8 changed files with 438 additions and 56 deletions

View File

@ -11,12 +11,12 @@ ISDKHooks *g_pSDKHooks;
ISDKTools *g_pSDKTools;
DHooksEntityListener *g_pEntityListener = NULL;
bool g_bAllowGamerules = true;
HandleType_t g_HookSetupHandle = 0;
HandleType_t g_HookParamsHandle = 0;
HandleType_t g_HookReturnHandle = 0;
SH_DECL_HOOK0_void(IServerGameDLL, LevelShutdown, SH_NOATTRIB, false);
bool DHooks::SDK_OnLoad(char *error, size_t maxlength, bool late)
{
HandleError err;
@ -47,6 +47,10 @@ bool DHooks::SDK_OnLoad(char *error, size_t maxlength, bool late)
plsys->AddPluginsListener(this);
sharesys->AddNatives(myself, g_Natives);
g_pEntityListener = new DHooksEntityListener();
SH_ADD_HOOK_MEMFUNC(IServerGameDLL, LevelShutdown, gamedll, g_pEntityListener, &DHooksEntityListener::LevelShutdown, false);
return true;
}
@ -69,18 +73,9 @@ void DHooks::OnHandleDestroy(HandleType_t type, void *object)
void DHooks::SDK_OnAllLoaded()
{
SM_GET_LATE_IFACE(SDKTOOLS, g_pSDKTools);
if(g_pSDKTools->GetInterfaceVersion() < 2)
{
//<psychonic> THIS ISN'T DA LIMBO STICK. LOW IS BAD
g_bAllowGamerules = false;
smutils->LogError(myself, "SDKTools interface is outdated. DHookGamerules native disabled.");
}
SM_GET_LATE_IFACE(BINTOOLS, g_pBinTools);
SM_GET_LATE_IFACE(SDKHOOKS, g_pSDKHooks);
g_pEntityListener = new DHooksEntityListener();
g_pSDKHooks->AddEntityListener(g_pEntityListener);
}
@ -91,6 +86,7 @@ void DHooks::SDK_OnUnload()
{
g_pEntityListener->CleanupListeners(NULL);
g_pSDKHooks->RemoveEntityListener(g_pEntityListener);
SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, LevelShutdown, gamedll, g_pEntityListener, &DHooksEntityListener::LevelShutdown, false);
delete g_pEntityListener;
}
plsys->RemovePluginsListener(this);

View File

@ -51,9 +51,9 @@
class DHooks : public SDKExtension, public ISMEntityListener, public IPluginsListener, public IHandleTypeDispatch
{
public:
void OnHandleDestroy(HandleType_t type, void *object);
virtual void OnHandleDestroy(HandleType_t type, void *object);
public: //IPluginsListener
void OnPluginUnloaded(IPlugin *plugin);
virtual void OnPluginUnloaded(IPlugin *plugin);
public:
/**
* @brief This is called after the initial loading sequence has been processed.

View File

@ -5,11 +5,24 @@ using namespace SourceHook;
CUtlVector<EntityListener> g_EntityListeners;
void DHooksEntityListener::LevelShutdown()
{
for(int i = g_pHooks.Count() -1; i >= 0; i--)
{
DHooksManager *manager = g_pHooks.Element(i);
if(manager->callback->hookType == HookType_GameRules)
{
delete manager;
g_pHooks.Remove(i);
}
}
}
void DHooksEntityListener::CleanupListeners(IPluginContext *pContext)
{
for(int i = g_EntityListeners.Count() -1; i >= 0; i--)
{
if(pContext == NULL || pContext == g_EntityListeners.Element(i).callback->GetParentContext())
if(pContext == NULL || pContext == g_EntityListeners.Element(i).callback->GetParentRuntime()->GetDefaultContext())
{
g_EntityListeners.Remove(i);
}

View File

@ -7,9 +7,10 @@
class DHooksEntityListener : public ISMEntityListener
{
public:
void OnEntityCreated(CBaseEntity *pEntity, const char *classname);
void OnEntityDestroyed(CBaseEntity *pEntity);
virtual void OnEntityCreated(CBaseEntity *pEntity, const char *classname);
virtual void OnEntityDestroyed(CBaseEntity *pEntity);
void CleanupListeners(IPluginContext *func);
virtual void LevelShutdown();
};
enum ListenType

View File

@ -36,7 +36,7 @@ cell_t Native_CreateHook(IPluginContext *pContext, const cell_t *params)
return hndl;
}
//native bool:DHookAddParam(Handle:setup, HookParamType:type);
//native bool:DHookAddParam(Handle:setup, HookParamType:type); OLD
//native bool:DHookAddParam(Handle:setup, HookParamType:type, size=-1, flag=-1);
cell_t Native_AddParam(IPluginContext *pContext, const cell_t *params)
{
@ -121,8 +121,124 @@ cell_t Native_HookEntity(IPluginContext *pContext, const cell_t *params)
return manager->hookid;
}
/*cell_t Native_HookGamerules(IPluginContext *pContext, const cell_t *params);
cell_t Native_RemoveHookID(IPluginContext *pContext, const cell_t *params);*/
// native DHookGamerules(Handle:setup, bool:post, DHookRemovalCB:removalcb);
cell_t Native_HookGamerules(IPluginContext *pContext, const cell_t *params)
{
if(params[1] == BAD_HANDLE)
{
return pContext->ThrowNativeError("Invalid Handle %i", BAD_HANDLE);
}
HandleError err;
HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity());
HookSetup *setup;
if((err = handlesys->ReadHandle(params[1], g_HookSetupHandle, &sec, (void **)&setup)) != HandleError_None)
{
return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err);
}
if(setup->hookType != HookType_GameRules)
{
return pContext->ThrowNativeError("Hook is not a gamerules hook");
}
bool post = params[2] != 0;
for(int i = g_pHooks.Count() -1; i >= 0; i--)
{
DHooksManager *manager = g_pHooks.Element(i);
if(manager->callback->hookType == HookType_GameRules && manager->callback->offset == setup->offset && manager->callback->post == post && manager->remove_callback == pContext->GetFunctionById(params[3]) && manager->callback->plugin_callback == setup->callback)
{
return manager->hookid;
}
}
void *rules = g_pSDKTools->GetGameRules();
if(!rules)
{
return pContext->ThrowNativeError("Could not get game rules pointer");
}
DHooksManager *manager = new DHooksManager(setup, rules, pContext->GetFunctionById(params[3]), post);
if(!manager->hookid)
{
delete manager;
return 0;
}
g_pHooks.AddToTail(manager);
return manager->hookid;
}
// DHookRaw(Handle:setup, bool:post, Address:addr, DHookRemovalCB:removalcb);
cell_t Native_HookRaw(IPluginContext *pContext, const cell_t *params)
{
if(params[1] == BAD_HANDLE)
{
return pContext->ThrowNativeError("Invalid Handle %i", BAD_HANDLE);
}
HandleError err;
HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity());
HookSetup *setup;
if((err = handlesys->ReadHandle(params[1], g_HookSetupHandle, &sec, (void **)&setup)) != HandleError_None)
{
return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err);
}
if(setup->hookType != HookType_Raw)
{
return pContext->ThrowNativeError("Hook is not a gamerules hook");
}
bool post = params[2] != 0;
for(int i = g_pHooks.Count() -1; i >= 0; i--)
{
DHooksManager *manager = g_pHooks.Element(i);
if(manager->callback->hookType == HookType_Raw && manager->callback->offset == setup->offset && manager->callback->post == post && manager->remove_callback == pContext->GetFunctionById(params[3]) && manager->callback->plugin_callback == setup->callback)
{
return manager->hookid;
}
}
void *iface = (void *)(params[3]);
if(!iface)
{
return pContext->ThrowNativeError("Invalid address passed");
}
DHooksManager *manager = new DHooksManager(setup, iface, pContext->GetFunctionById(params[3]), post);
if(!manager->hookid)
{
delete manager;
return 0;
}
g_pHooks.AddToTail(manager);
return manager->hookid;
}
// native bool:DHookRemoveHookID(hookid);
cell_t Native_RemoveHookID(IPluginContext *pContext, const cell_t *params)
{
for(int i = g_pHooks.Count() -1; i >= 0; i--)
{
DHooksManager *manager = g_pHooks.Element(i);
if(manager->hookid == params[1] && manager->callback->plugin_callback->GetParentRuntime()->GetDefaultContext() == pContext)
{
delete manager;
g_pHooks.Remove(i);
return 1;
}
}
return 0;
}
// native any:DHookGetParam(Handle:hParams, num);
cell_t Native_GetParam(IPluginContext *pContext, const cell_t *params)
{
if(params[1] == BAD_HANDLE)
@ -172,6 +288,71 @@ cell_t Native_GetParam(IPluginContext *pContext, const cell_t *params)
return 1;
}
// native DHookSetParam(Handle:hParams, param, any:value)
cell_t Native_SetParam(IPluginContext *pContext, const cell_t *params)
{
if(params[1] == BAD_HANDLE)
{
return pContext->ThrowNativeError("Invalid Handle %i", BAD_HANDLE);
}
HandleError err;
HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity());
HookParamsStruct *paramStruct;
if((err = handlesys->ReadHandle(params[1], g_HookParamsHandle, &sec, (void **)&paramStruct)) != HandleError_None)
{
return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err);
}
if(params[2] <= 0 || params[2] > paramStruct->dg->params.Count())
{
return pContext->ThrowNativeError("Invalid param number %i max params is %i", params[2], paramStruct->dg->params.Count());
}
int index = params[2] - 1;
switch(paramStruct->dg->params.Element(index).type)
{
case HookParamType_Int:
paramStruct->newParams[index] = (void *)params[3];
break;
case HookParamType_Bool:
paramStruct->newParams[index] = (void *)(params[3] ? 1 : 0);
break;
case HookParamType_CBaseEntity:
{
CBaseEntity *pEnt = UTIL_GetCBaseEntity(params[2]);
if(!pEnt)
{
return pContext->ThrowNativeError("Invalid entity index passed for param value");
}
paramStruct->newParams[index] = pEnt;
break;
}
case HookParamType_Edict:
{
edict_t *pEdict = gamehelpers->EdictOfIndex(params[2]);
if(!pEdict || pEdict->IsFree())
{
pContext->ThrowNativeError("Invalid entity index passed for param value");
}
paramStruct->newParams[index] = pEdict;
break;
}
case HookParamType_Float:
paramStruct->newParams[index] = new float;
*(float *)paramStruct->newParams[index] = sp_ctof(params[3]);
break;
default:
return pContext->ThrowNativeError("Invalid param type (%i) to set", paramStruct->dg->params.Element(index).type);
}
paramStruct->isChanged[index] = true;
return 1;
}
// native any:DHookGetReturn(Handle:hReturn);
cell_t Native_GetReturn(IPluginContext *pContext, const cell_t *params)
{
if(params[1] == BAD_HANDLE)
@ -205,6 +386,7 @@ cell_t Native_GetReturn(IPluginContext *pContext, const cell_t *params)
}
return 1;
}
// native DHookSetReturn(Handle:hReturn, any:value)
cell_t Native_SetReturn(IPluginContext *pContext, const cell_t *params)
{
if(params[1] == BAD_HANDLE)
@ -258,11 +440,12 @@ cell_t Native_SetReturn(IPluginContext *pContext, const cell_t *params)
returnStruct->isChanged = true;
return 1;
}
/*cell_t Native_SetParam(IPluginContext *pContext, const cell_t *params);
cell_t Native_GetParamVector(IPluginContext *pContext, const cell_t *params);
/*cell_t Native_GetParamVector(IPluginContext *pContext, const cell_t *params);
cell_t Native_GetReturnVector(IPluginContext *pContext, const cell_t *params);
cell_t Native_SetReturnVector(IPluginContext *pContext, const cell_t *params);
cell_t Native_SetParamVector(IPluginContext *pContext, const cell_t *params);*/
// native DHookGetParamString(Handle:hParams, num, String:buffer[], size)
cell_t Native_GetParamString(IPluginContext *pContext, const cell_t *params)
{
if(params[1] == BAD_HANDLE)
@ -327,7 +510,7 @@ cell_t Native_SetParamString(IPluginContext *pContext, const cell_t *params)
if(paramStruct->dg->params.Element(index).type == HookParamType_CharPtr)
{
if(paramStruct->newParams[index] != NULL)
if((char *)paramStruct->newParams[index] != NULL && paramStruct->isChanged[index])
delete (char *)paramStruct->newParams[index];
paramStruct->newParams[index] = new char[strlen(value)+1];
@ -342,14 +525,14 @@ sp_nativeinfo_t g_Natives[] =
{"DHookCreate", Native_CreateHook},
{"DHookAddParam", Native_AddParam},
{"DHookEntity", Native_HookEntity},
/*{"DHookGamerules", Native_HookGamerules},
{"DHookGamerules", Native_HookGamerules},
{"DHookRaw", Native_HookRaw},
{"DHookRemoveHookID", Native_RemoveHookID},*/
{"DHookRemoveHookID", Native_RemoveHookID},
{"DHookGetParam", Native_GetParam},
{"DHookGetReturn", Native_GetReturn},
{"DHookSetReturn", Native_SetReturn},
/*{"DHookSetParam", Native_SetParam},
{"DHookGetParamVector", Native_GetParamVector},
{"DHookSetParam", Native_SetParam},
/*{"DHookGetParamVector", Native_GetParamVector},
{"DHookGetReturnVector", Native_GetReturnVector},
{"DHookSetReturnVector", Native_SetReturnVector},
{"DHookSetParamVector", Native_SetParamVector},*/

View File

@ -3,8 +3,7 @@
#include "extension.h"
#include "vhook.h"
extern bool g_bAllowGamerules;
extern ISDKTools *g_pSDKTools;
extern HandleType_t g_HookSetupHandle;
extern HandleType_t g_HookParamsHandle;
extern HandleType_t g_HookReturnHandle;

229
vhook.cpp
View File

@ -19,6 +19,7 @@ DHooksManager::DHooksManager(HookSetup *setup, void *iface, IPluginFunction *rem
this->callback->post = post;
this->callback->hookType = setup->hookType;
this->callback->params = setup->params;
this->addr = 0;
if(this->callback->hookType == HookType_Entity)
{
@ -26,6 +27,10 @@ DHooksManager::DHooksManager(HookSetup *setup, void *iface, IPluginFunction *rem
}
else
{
if(this->callback->hookType == HookType_Raw)
{
this->addr = (intptr_t)iface;
}
this->callback->entity = -1;
}
@ -40,10 +45,14 @@ DHooksManager::DHooksManager(HookSetup *setup, void *iface, IPluginFunction *rem
{
protoInfo.SetReturnType(0, SourceHook::PassInfo::PassType_Unknown, 0, NULL, NULL, NULL, NULL);
}
else
else if(this->callback->returnType != ReturnType_Float)
{
protoInfo.SetReturnType(sizeof(void *), SourceHook::PassInfo::PassType_Basic, setup->returnFlag, NULL, NULL, NULL, NULL);
}
else
{
protoInfo.SetReturnType(sizeof(void *), SourceHook::PassInfo::PassType_Float, setup->returnFlag, NULL, NULL, NULL, NULL);
}
HookManagerPubFunc hook = g_pHookManager->MakeHookMan(protoInfo, 0, this->callback->offset);
this->hookid = g_SHPtr->AddHook(g_PLID,ISourceHook::Hook_Normal, iface, 0, hook, this->callback, this->callback->post);
@ -55,7 +64,7 @@ void CleanupHooks(IPluginContext *pContext)
{
DHooksManager *manager = g_pHooks.Element(i);
if(pContext == NULL || pContext == manager->callback->plugin_callback->GetParentContext())
if(pContext == NULL || pContext == manager->callback->plugin_callback->GetParentRuntime()->GetDefaultContext())
{
delete manager;
g_pHooks.Remove(i);
@ -96,18 +105,18 @@ size_t GetStackArgsSize(DHooksCallback *dg)
}
HookParamsStruct *GetParamStruct(DHooksCallback *dg, void **argStack, size_t argStackSize)
{
HookParamsStruct *res = new HookParamsStruct();
res->dg = dg;
res->orgParams = (void **)malloc(argStackSize);
res->newParams = (void **)malloc(argStackSize);
res->isChanged = (bool *)malloc(dg->params.Count() * sizeof(bool));
memcpy(res->orgParams, argStack, argStackSize);
HookParamsStruct *params = new HookParamsStruct();
params->dg = dg;
params->orgParams = (void **)malloc(argStackSize);
params->newParams = (void **)malloc(dg->params.Count() * sizeof(void *));
params->isChanged = (bool *)malloc(dg->params.Count() * sizeof(bool));
memcpy(params->orgParams, argStack, argStackSize);
for(int i = 0; i < dg->params.Count(); i++)
{
res->newParams[i] = NULL;
res->isChanged[i] = false;
params->newParams[i] = NULL;
params->isChanged[i] = false;
}
return res;
return params;
}
HookReturnStruct *GetReturnStruct(DHooksCallback *dg, const void *result)
{
@ -138,7 +147,22 @@ HookReturnStruct *GetReturnStruct(DHooksCallback *dg, const void *result)
}
else
{
res->orgResult = NULL;
switch(dg->returnType)
{
//ReturnType_String,
//ReturnType_Vector,
case ReturnType_Int:
*(int *)res->orgResult = 0;
case ReturnType_Bool:
*(bool *)res->orgResult = false;
break;
case ReturnType_Float:
*(float *)res->orgResult = 0.0;
break;
default:
*(void **)res->orgResult = NULL;
break;
}
}
return res;
@ -186,7 +210,7 @@ void *Callback(DHooksCallback *dg, void **argStack)
delete returnStruct;
}
g_SHPtr->SetRes(MRES_IGNORED);
return 0;
return NULL;
}
dg->plugin_callback->PushCell(rHndl);
}
@ -213,11 +237,13 @@ void *Callback(DHooksCallback *dg, void **argStack)
delete paramStruct;
}
g_SHPtr->SetRes(MRES_IGNORED);
return 0;
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();
@ -227,6 +253,7 @@ void *Callback(DHooksCallback *dg, void **argStack)
case MRES_ChangedHandled:
g_SHPtr->DoRecall();
g_SHPtr->SetRes(MRES_SUPERCEDE);
mres = MRES_SUPERCEDE;
ret = CallVFunction(dg, paramStruct, g_SHPtr->GetIfacePtr());
break;
case MRES_ChangedOverride:
@ -239,13 +266,14 @@ void *Callback(DHooksCallback *dg, void **argStack)
else //Throw an error if no override was set
{
g_SHPtr->SetRes(MRES_IGNORED);
IPlugin *plugin = plsys->FindPluginByContext(dg->plugin_callback->GetParentContext()->GetContext());
smutils->LogError(myself, "Plugin %s tried to override a return without a return being set", plugin->GetFilename());
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(dg, paramStruct, g_SHPtr->GetIfacePtr());
break;
case MRES_Override:
@ -254,13 +282,14 @@ void *Callback(DHooksCallback *dg, void **argStack)
if(returnStruct->isChanged)
{
g_SHPtr->SetRes(MRES_OVERRIDE);
mres = MRES_OVERRIDE;
ret = *(void **)returnStruct->newResult;
}
else //Throw an error if no override was set
{
g_SHPtr->SetRes(MRES_IGNORED);
IPlugin *plugin = plsys->FindPluginByContext(dg->plugin_callback->GetParentContext()->GetContext());
smutils->LogError(myself, "Plugin %s tried to override a return without a return being set", plugin->GetFilename());
mres = MRES_IGNORED;
dg->plugin_callback->GetParentRuntime()->GetDefaultContext()->ThrowNativeError("Tried to override return value without return value being set");
}
}
break;
@ -270,22 +299,24 @@ void *Callback(DHooksCallback *dg, void **argStack)
if(returnStruct->isChanged)
{
g_SHPtr->SetRes(MRES_SUPERCEDE);
mres = MRES_SUPERCEDE;
ret = *(void **)returnStruct->newResult;
}
else //Throw an error if no override was set
{
g_SHPtr->SetRes(MRES_IGNORED);
IPlugin *plugin = plsys->FindPluginByContext(dg->plugin_callback->GetParentContext()->GetContext());
smutils->LogError(myself, "Plugin %s tried to override a return without a return being set", plugin->GetFilename());
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->GetParentContext()->GetIdentity(), myself->GetIdentity());
HandleSecurity sec(dg->plugin_callback->GetParentRuntime()->GetDefaultContext()->GetIdentity(), myself->GetIdentity());
if(returnStruct)
{
@ -296,9 +327,163 @@ void *Callback(DHooksCallback *dg, void **argStack)
handlesys->FreeHandle(pHndl, &sec);
}
if(dg->returnType == ReturnType_Void || g_SHPtr->GetStatus() <= MRES_HANDLED)
if(dg->returnType == ReturnType_Void || mres <= MRES_HANDLED)
{
return NULL;
}
return ret;
}
#ifndef __linux__
float Callback_float(DHooksCallback *dg, void **argStack, size_t *argsizep)
#else
void *Callback_float(DHooksCallback *dg, void **argStack)
#endif
{
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, g_SHPtr->GetOrigRet());
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();
switch((MRESReturn)result)
{
case MRES_Handled:
case MRES_ChangedHandled:
g_SHPtr->DoRecall();
g_SHPtr->SetRes(MRES_SUPERCEDE);
mres = MRES_SUPERCEDE;
ret = CallVFunction(dg, paramStruct, g_SHPtr->GetIfacePtr());
break;
case MRES_ChangedOverride:
if(dg->returnType != ReturnType_Void)
{
if(returnStruct->isChanged)
{
*(float *)ret = *(float *)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(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;
*(float *)ret = *(float *)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;
*(float *)ret = *(float *)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)
{
return NULL;
}
return *(float *)ret;
}

17
vhook.h
View File

@ -117,7 +117,7 @@ public:
#ifndef __linux__
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);
#else
void *Callback(DHooksCallback *dg, void **stack);
float Callback_float(DHooksCallback *dg, void **stack);
@ -137,9 +137,9 @@ static void *GenerateThunk(ReturnType type)
masm.lea(eax, Operand(ebp, 12));
masm.push(eax);
masm.push(Operand(ebp, 8));
/*if(type == ReturnType_Float)
if(type == ReturnType_Float)
masm.call(ExternalAddress((void *)Callback_float));
else*/
else
masm.call(ExternalAddress((void *)Callback));
masm.addl(esp, 8);
masm.pop(ebp);
@ -161,9 +161,9 @@ static void *GenerateThunk(ReturnType type)
masm.lea(eax, Operand(ebp, 8));
masm.push(eax);
masm.push(ecx);
//if(type == ReturnType_Float)
// masm.call(ExternalAddress(Callback_float));
//else
if(type == ReturnType_Float)
masm.call(ExternalAddress(Callback_float));
else
masm.call(ExternalAddress(Callback));
masm.addl(esp, 12);
masm.pop(ecx); // grab arg size
@ -226,6 +226,10 @@ public:
{
delete (char *)this->newParams[i];
}
else if(dg->params.Element(i).type == HookParamType_Float)
{
delete (float *)this->newParams[i];
}
}
free(this->newParams);
}
@ -277,6 +281,7 @@ public:
}
}
public:
intptr_t addr;
int hookid;
DHooksCallback *callback;
IPluginFunction *remove_callback;