2013-08-19 17:07:25 +02:00
|
|
|
#include "natives.h"
|
2016-08-30 22:40:24 +02:00
|
|
|
#include "util.h"
|
2016-12-12 06:02:10 +01:00
|
|
|
#include "dynhooks_sourcepawn.h"
|
2018-01-25 17:18:30 +01:00
|
|
|
#include "signatures.h"
|
2016-12-12 06:02:10 +01:00
|
|
|
|
|
|
|
// Must match same enum in sdktools.inc
|
|
|
|
enum SDKFuncConfSource
|
|
|
|
{
|
|
|
|
SDKConf_Virtual,
|
|
|
|
SDKConf_Signature,
|
|
|
|
SDKConf_Address
|
|
|
|
};
|
2013-08-19 17:07:25 +02:00
|
|
|
|
2013-08-23 20:29:01 +02:00
|
|
|
bool GetHandleIfValidOrError(HandleType_t type, void **object, IPluginContext *pContext, cell_t param)
|
|
|
|
{
|
|
|
|
if(param == BAD_HANDLE)
|
|
|
|
{
|
|
|
|
return pContext->ThrowNativeError("Invalid Handle %i", BAD_HANDLE) != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
HandleError err;
|
|
|
|
HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity());
|
|
|
|
|
2013-08-26 04:45:42 +02:00
|
|
|
if((err = handlesys->ReadHandle(param, type, &sec, object)) != HandleError_None)
|
2013-08-23 20:29:01 +02:00
|
|
|
{
|
|
|
|
return pContext->ThrowNativeError("Invalid Handle %x (error %d)", param, err) != 0;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2013-08-27 04:19:05 +02:00
|
|
|
|
2018-04-21 09:43:53 +02:00
|
|
|
IPluginFunction *GetCallback(IPluginContext *pContext, HookSetup * setup, const cell_t *params, cell_t callback_index)
|
2013-08-19 17:07:25 +02:00
|
|
|
{
|
2018-01-27 16:08:44 +01:00
|
|
|
IPluginFunction *ret = NULL;
|
|
|
|
|
|
|
|
if (params[0] >= callback_index)
|
2013-08-19 17:07:25 +02:00
|
|
|
{
|
2018-01-27 16:08:44 +01:00
|
|
|
ret = pContext->GetFunctionById(params[callback_index]);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!ret && setup->callback)
|
2013-08-19 17:07:25 +02:00
|
|
|
{
|
2018-01-27 16:08:44 +01:00
|
|
|
ret = setup->callback;
|
2013-08-19 17:07:25 +02:00
|
|
|
}
|
|
|
|
|
2018-01-27 16:08:44 +01:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2018-01-29 18:36:26 +01:00
|
|
|
//native Handle:DHookCreate(offset, HookType:hooktype, ReturnType:returntype, ThisPointerType:thistype, DHookCallback:callback = INVALID_FUNCTION); // Callback is now optional here.
|
2018-01-27 16:08:44 +01:00
|
|
|
cell_t Native_CreateHook(IPluginContext *pContext, const cell_t *params)
|
|
|
|
{
|
2016-08-30 16:56:56 +02:00
|
|
|
HookSetup *setup = new HookSetup((ReturnType)params[3], PASSFLAG_BYVAL, (HookType)params[2], (ThisPointerType)params[4], params[1], pContext->GetFunctionById(params[5]));
|
2013-08-19 17:07:25 +02:00
|
|
|
|
|
|
|
Handle_t hndl = handlesys->CreateHandle(g_HookSetupHandle, setup, pContext->GetIdentity(), myself->GetIdentity(), NULL);
|
|
|
|
|
|
|
|
if(!hndl)
|
|
|
|
{
|
|
|
|
delete setup;
|
|
|
|
return pContext->ThrowNativeError("Failed to create hook");
|
|
|
|
}
|
|
|
|
|
|
|
|
return hndl;
|
|
|
|
}
|
2016-12-12 06:02:10 +01:00
|
|
|
|
2018-01-25 17:18:30 +01:00
|
|
|
//native Handle:DHookCreateDetour(Address:funcaddr, CallingConvention:callConv, ReturnType:returntype, ThisPointerType:thistype);
|
2016-12-12 06:02:10 +01:00
|
|
|
cell_t Native_CreateDetour(IPluginContext *pContext, const cell_t *params)
|
|
|
|
{
|
|
|
|
HookSetup *setup = new HookSetup((ReturnType)params[3], PASSFLAG_BYVAL, (CallingConvention)params[2], (ThisPointerType)params[4], (void *)params[1]);
|
|
|
|
|
|
|
|
Handle_t hndl = handlesys->CreateHandle(g_HookSetupHandle, setup, pContext->GetIdentity(), myself->GetIdentity(), NULL);
|
|
|
|
|
|
|
|
if (!hndl)
|
|
|
|
{
|
|
|
|
delete setup;
|
|
|
|
return pContext->ThrowNativeError("Failed to create hook");
|
|
|
|
}
|
|
|
|
|
|
|
|
return hndl;
|
|
|
|
}
|
|
|
|
|
2018-04-21 09:43:53 +02:00
|
|
|
// native Handle:DHookCreateFromConf(Handle:gameconf, const String:function[]);
|
2018-01-25 17:18:30 +01:00
|
|
|
cell_t Native_DHookCreateFromConf(IPluginContext *pContext, const cell_t *params)
|
|
|
|
{
|
|
|
|
IGameConfig *conf;
|
|
|
|
HandleError err;
|
|
|
|
if ((conf = gameconfs->ReadHandle(params[1], pContext->GetIdentity(), &err)) == nullptr)
|
|
|
|
{
|
|
|
|
return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err);
|
|
|
|
}
|
|
|
|
|
|
|
|
char *function;
|
|
|
|
pContext->LocalToString(params[2], &function);
|
|
|
|
|
|
|
|
SignatureWrapper *sig = g_pSignatures->GetFunctionSignature(function);
|
|
|
|
if (!sig)
|
|
|
|
{
|
|
|
|
return pContext->ThrowNativeError("Function signature \"%s\" was not found.", function);
|
|
|
|
}
|
|
|
|
|
|
|
|
HookSetup *setup = nullptr;
|
|
|
|
// This is a virtual hook.
|
|
|
|
if (sig->offset.length() > 0)
|
|
|
|
{
|
|
|
|
int offset;
|
|
|
|
if (!conf->GetOffset(sig->offset.chars(), &offset))
|
|
|
|
{
|
|
|
|
return BAD_HANDLE;
|
|
|
|
}
|
|
|
|
|
2018-04-21 09:43:53 +02:00
|
|
|
setup = new HookSetup(sig->retType, PASSFLAG_BYVAL, sig->hookType, sig->thisType, offset, nullptr);
|
2018-01-25 17:18:30 +01:00
|
|
|
}
|
|
|
|
// This is a detour.
|
|
|
|
else
|
|
|
|
{
|
|
|
|
void *addr = nullptr;;
|
|
|
|
if (sig->signature.length() > 0)
|
|
|
|
{
|
|
|
|
if (!conf->GetMemSig(sig->signature.chars(), &addr) || !addr)
|
|
|
|
{
|
|
|
|
return BAD_HANDLE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!conf->GetAddress(sig->address.chars(), &addr) || !addr)
|
|
|
|
{
|
|
|
|
return BAD_HANDLE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setup = new HookSetup(sig->retType, PASSFLAG_BYVAL, sig->callConv, sig->thisType, addr);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Push all the arguments.
|
2018-04-21 11:50:07 +02:00
|
|
|
for (ArgumentInfo &arg : sig->args)
|
2018-01-25 17:18:30 +01:00
|
|
|
{
|
2018-04-21 11:50:07 +02:00
|
|
|
ParamInfo info = arg.info;
|
2018-01-25 17:18:30 +01:00
|
|
|
setup->params.push_back(info);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create the handle to hold this setup.
|
|
|
|
Handle_t hndl = handlesys->CreateHandle(g_HookSetupHandle, setup, pContext->GetIdentity(), myself->GetIdentity(), NULL);
|
|
|
|
if (!hndl)
|
|
|
|
{
|
|
|
|
delete setup;
|
|
|
|
return pContext->ThrowNativeError("Failed to create hook");
|
|
|
|
}
|
|
|
|
|
|
|
|
return hndl;
|
|
|
|
}
|
2016-12-12 06:02:10 +01:00
|
|
|
|
|
|
|
//native bool:DHookSetFromConf(Handle:setup, Handle:gameconf, SDKFuncConfSource:source, const String:name[]);
|
|
|
|
cell_t Native_SetFromConf(IPluginContext *pContext, const cell_t *params)
|
|
|
|
{
|
|
|
|
HookSetup *setup;
|
|
|
|
if (!GetHandleIfValidOrError(g_HookSetupHandle, (void **)&setup, pContext, params[1]))
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
IGameConfig *conf;
|
|
|
|
HandleError err;
|
|
|
|
if ((conf = gameconfs->ReadHandle(params[2], pContext->GetIdentity(), &err)) == nullptr)
|
|
|
|
{
|
|
|
|
return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[2], err);
|
|
|
|
}
|
|
|
|
|
|
|
|
char *key;
|
|
|
|
pContext->LocalToString(params[4], &key);
|
|
|
|
|
|
|
|
int offset = -1;
|
|
|
|
void *addr = nullptr;;
|
|
|
|
switch (params[3])
|
|
|
|
{
|
|
|
|
case SDKConf_Virtual:
|
|
|
|
if (!conf->GetOffset(key, &offset))
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDKConf_Signature:
|
|
|
|
if (!conf->GetMemSig(key, &addr) || !addr)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDKConf_Address:
|
|
|
|
if (!conf->GetAddress(key, &addr) || !addr)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return pContext->ThrowNativeError("Unknown SDKFuncConfSource: %d", params[3]);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Save the new info. This always invalidates the other option.
|
|
|
|
// Detour or vhook.
|
|
|
|
setup->funcAddr = addr;
|
|
|
|
setup->offset = offset;
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2018-01-23 03:15:03 +01:00
|
|
|
//native bool:DHookAddParam(Handle:setup, HookParamType:type, size=-1, DHookPassFlag:flag=DHookPass_ByVal, DHookRegister custom_register=DHookRegister_Default);
|
2013-08-19 17:07:25 +02:00
|
|
|
cell_t Native_AddParam(IPluginContext *pContext, const cell_t *params)
|
|
|
|
{
|
|
|
|
HookSetup *setup;
|
|
|
|
|
2013-08-23 20:29:01 +02:00
|
|
|
if(!GetHandleIfValidOrError(g_HookSetupHandle, (void **)&setup, pContext, params[1]))
|
2013-08-19 17:07:25 +02:00
|
|
|
{
|
2013-08-23 20:29:01 +02:00
|
|
|
return 0;
|
2013-08-19 17:07:25 +02:00
|
|
|
}
|
|
|
|
|
2013-08-23 20:29:01 +02:00
|
|
|
ParamInfo info;
|
2013-08-21 02:18:50 +02:00
|
|
|
|
|
|
|
info.type = (HookParamType)params[2];
|
|
|
|
|
2013-08-30 02:16:05 +02:00
|
|
|
if(params[0] >= 4)
|
|
|
|
{
|
2016-08-30 16:56:56 +02:00
|
|
|
info.flags = params[4];
|
2013-08-30 02:16:05 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-08-30 16:56:56 +02:00
|
|
|
info.flags = PASSFLAG_BYVAL;
|
2013-08-30 02:16:05 +02:00
|
|
|
}
|
|
|
|
|
2018-01-23 03:15:03 +01:00
|
|
|
if (params[0] >= 5)
|
|
|
|
{
|
|
|
|
PluginRegister custom_register = (PluginRegister)params[5];
|
|
|
|
info.custom_register = DynamicHooks_ConvertRegisterFrom(custom_register);
|
|
|
|
|
|
|
|
// Stay future proof.
|
|
|
|
if (info.custom_register == None && custom_register != DHookRegister_Default)
|
|
|
|
return pContext->ThrowNativeError("Unhandled DHookRegister %d", params[5]);
|
|
|
|
|
|
|
|
if (info.custom_register != None && info.type == HookParamType_Object)
|
|
|
|
return pContext->ThrowNativeError("Can't pass an object in a register.");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
info.custom_register = None;
|
|
|
|
}
|
|
|
|
|
2013-08-23 20:29:01 +02:00
|
|
|
if(params[0] >= 3 && params[3] != -1)
|
2013-08-19 17:07:25 +02:00
|
|
|
{
|
2013-08-21 02:18:50 +02:00
|
|
|
info.size = params[3];
|
2013-08-30 02:16:05 +02:00
|
|
|
}
|
|
|
|
else if(info.type == HookParamType_Object)
|
|
|
|
{
|
|
|
|
return pContext->ThrowNativeError("Object param being set with no size");
|
2013-08-19 17:07:25 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-08-21 02:18:50 +02:00
|
|
|
info.size = GetParamTypeSize(info.type);
|
2013-08-19 17:07:25 +02:00
|
|
|
}
|
2013-08-30 02:16:05 +02:00
|
|
|
|
2013-08-19 17:07:25 +02:00
|
|
|
info.pass_type = GetParamTypePassType(info.type);
|
2014-08-19 19:14:48 +02:00
|
|
|
setup->params.push_back(info);
|
2013-08-19 17:07:25 +02:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
2016-12-12 06:02:10 +01:00
|
|
|
|
|
|
|
|
|
|
|
// native bool:DHookEnableDetour(Handle:setup, bool:post, DHookCallback:callback);
|
|
|
|
cell_t Native_EnableDetour(IPluginContext *pContext, const cell_t *params)
|
|
|
|
{
|
|
|
|
HookSetup *setup;
|
|
|
|
|
|
|
|
if (!GetHandleIfValidOrError(g_HookSetupHandle, (void **)&setup, pContext, params[1]))
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (setup->funcAddr == nullptr)
|
|
|
|
{
|
|
|
|
return pContext->ThrowNativeError("Hook not setup for a detour.");
|
|
|
|
}
|
|
|
|
|
|
|
|
IPluginFunction *callback = pContext->GetFunctionById(params[3]);
|
|
|
|
if (!callback)
|
|
|
|
{
|
|
|
|
return pContext->ThrowNativeError("Failed to retrieve function by id");
|
|
|
|
}
|
|
|
|
|
|
|
|
bool post = params[2] != 0;
|
|
|
|
HookType_t hookType = post ? HOOKTYPE_POST : HOOKTYPE_PRE;
|
|
|
|
|
|
|
|
// Check if we already detoured that function.
|
|
|
|
CHookManager *pDetourManager = GetHookManager();
|
|
|
|
CHook* pDetour = pDetourManager->FindHook(setup->funcAddr);
|
|
|
|
|
|
|
|
// If there is no detour on this function yet, create it.
|
|
|
|
if (!pDetour)
|
|
|
|
{
|
|
|
|
ICallingConvention *pCallConv = ConstructCallingConvention(setup);
|
|
|
|
pDetour = pDetourManager->HookFunction(setup->funcAddr, pCallConv);
|
2018-01-23 03:15:03 +01:00
|
|
|
if (!UpdateRegisterArgumentSizes(pDetour, setup))
|
|
|
|
return pContext->ThrowNativeError("A custom register for a parameter isn't supported.");
|
2016-12-12 06:02:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Register our pre/post handler.
|
|
|
|
pDetour->AddCallback(hookType, (HookHandlerFn *)&HandleDetour);
|
|
|
|
|
|
|
|
// Add the plugin callback to the map.
|
|
|
|
return AddDetourPluginHook(hookType, pDetour, setup, callback);
|
|
|
|
}
|
|
|
|
|
|
|
|
// native bool:DHookDisableDetour(Handle:setup, bool:post, DHookCallback:callback);
|
|
|
|
cell_t Native_DisableDetour(IPluginContext *pContext, const cell_t *params)
|
|
|
|
{
|
|
|
|
HookSetup *setup;
|
|
|
|
|
|
|
|
if (!GetHandleIfValidOrError(g_HookSetupHandle, (void **)&setup, pContext, params[1]))
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (setup->funcAddr == nullptr)
|
|
|
|
{
|
|
|
|
return pContext->ThrowNativeError("Hook not setup for a detour.");
|
|
|
|
}
|
|
|
|
|
|
|
|
IPluginFunction *callback = pContext->GetFunctionById(params[3]);
|
|
|
|
if (!callback)
|
|
|
|
{
|
|
|
|
return pContext->ThrowNativeError("Failed to retrieve function by id");
|
|
|
|
}
|
|
|
|
|
|
|
|
bool post = params[2] != 0;
|
|
|
|
HookType_t hookType = post ? HOOKTYPE_POST : HOOKTYPE_PRE;
|
|
|
|
|
|
|
|
// Check if we already detoured that function.
|
|
|
|
CHookManager *pDetourManager = GetHookManager();
|
|
|
|
CHook* pDetour = pDetourManager->FindHook(setup->funcAddr);
|
|
|
|
|
|
|
|
if (!pDetour || !pDetour->IsCallbackRegistered(hookType, (HookHandlerFn *)&HandleDetour))
|
|
|
|
{
|
|
|
|
return pContext->ThrowNativeError("Function not detoured.");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove the callback from the hook.
|
|
|
|
return RemoveDetourPluginHook(hookType, pDetour, callback);
|
|
|
|
}
|
|
|
|
|
2018-01-29 18:36:26 +01:00
|
|
|
// native DHookEntity(Handle:setup, bool:post, entity, DHookRemovalCB:removalcb, DHookCallback:callback = INVALID_FUNCTION); // Both callbacks are optional
|
2013-08-19 17:07:25 +02:00
|
|
|
cell_t Native_HookEntity(IPluginContext *pContext, const cell_t *params)
|
|
|
|
{
|
|
|
|
HookSetup *setup;
|
|
|
|
|
2013-08-23 20:29:01 +02:00
|
|
|
if(!GetHandleIfValidOrError(g_HookSetupHandle, (void **)&setup, pContext, params[1]))
|
2013-08-19 17:07:25 +02:00
|
|
|
{
|
2013-08-23 20:29:01 +02:00
|
|
|
return 0;
|
2013-08-19 17:07:25 +02:00
|
|
|
}
|
2013-08-23 20:29:01 +02:00
|
|
|
|
2016-12-12 06:02:10 +01:00
|
|
|
if (setup->offset == -1)
|
|
|
|
{
|
|
|
|
return pContext->ThrowNativeError("Hook not setup for a virtual hook.");
|
|
|
|
}
|
|
|
|
|
2013-08-19 17:07:25 +02:00
|
|
|
if(setup->hookType != HookType_Entity)
|
|
|
|
{
|
|
|
|
return pContext->ThrowNativeError("Hook is not an entity hook");
|
|
|
|
}
|
|
|
|
bool post = params[2] != 0;
|
|
|
|
|
2016-08-27 16:20:38 +02:00
|
|
|
for(int i = g_pHooks.length() -1; i >= 0; i--)
|
2013-08-19 17:07:25 +02:00
|
|
|
{
|
2014-08-19 19:14:48 +02:00
|
|
|
DHooksManager *manager = g_pHooks.at(i);
|
|
|
|
if(manager->callback->hookType == HookType_Entity && manager->callback->entity == gamehelpers->ReferenceToBCompatRef(params[3]) && manager->callback->offset == setup->offset && manager->callback->post == post && manager->remove_callback == pContext->GetFunctionById(params[4]) && manager->callback->plugin_callback == setup->callback)
|
2013-08-19 17:07:25 +02:00
|
|
|
{
|
2013-08-20 04:33:44 +02:00
|
|
|
return manager->hookid;
|
2013-08-19 17:07:25 +02:00
|
|
|
}
|
|
|
|
}
|
2014-08-19 19:14:48 +02:00
|
|
|
CBaseEntity *pEnt = gamehelpers->ReferenceToEntity(params[3]);
|
2013-08-19 17:07:25 +02:00
|
|
|
|
|
|
|
if(!pEnt)
|
|
|
|
{
|
|
|
|
return pContext->ThrowNativeError("Invalid entity passed %i", params[2]);
|
|
|
|
}
|
|
|
|
|
2018-01-27 16:08:44 +01:00
|
|
|
IPluginFunction *cb = GetCallback(pContext, setup, params, 5);
|
|
|
|
|
|
|
|
if (!cb)
|
|
|
|
{
|
|
|
|
pContext->ThrowNativeError("Failed to hook entity %i, no callback provided", params[2]);
|
|
|
|
}
|
|
|
|
|
|
|
|
DHooksManager *manager = new DHooksManager(setup, pEnt, pContext->GetFunctionById(params[4]), cb, post);
|
2013-08-19 17:07:25 +02:00
|
|
|
|
|
|
|
if(!manager->hookid)
|
|
|
|
{
|
|
|
|
delete manager;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-08-27 16:20:38 +02:00
|
|
|
g_pHooks.append(manager);
|
2013-08-19 17:07:25 +02:00
|
|
|
|
|
|
|
return manager->hookid;
|
|
|
|
}
|
2018-01-29 18:36:26 +01:00
|
|
|
// native DHookGamerules(Handle:setup, bool:post, DHookRemovalCB:removalcb, DHookCallback:callback = INVALID_FUNCTION); // Both callbacks are optional
|
2013-08-22 04:18:52 +02:00
|
|
|
cell_t Native_HookGamerules(IPluginContext *pContext, const cell_t *params)
|
|
|
|
{
|
|
|
|
HookSetup *setup;
|
|
|
|
|
2013-08-23 20:29:01 +02:00
|
|
|
if(!GetHandleIfValidOrError(g_HookSetupHandle, (void **)&setup, pContext, params[1]))
|
2013-08-22 04:18:52 +02:00
|
|
|
{
|
2013-08-23 20:29:01 +02:00
|
|
|
return 0;
|
2013-08-22 04:18:52 +02:00
|
|
|
}
|
2013-08-23 20:29:01 +02:00
|
|
|
|
2016-12-12 06:02:10 +01:00
|
|
|
if (setup->offset == -1)
|
|
|
|
{
|
|
|
|
return pContext->ThrowNativeError("Hook not setup for a virtual hook.");
|
|
|
|
}
|
|
|
|
|
2013-08-22 04:18:52 +02:00
|
|
|
if(setup->hookType != HookType_GameRules)
|
|
|
|
{
|
|
|
|
return pContext->ThrowNativeError("Hook is not a gamerules hook");
|
|
|
|
}
|
|
|
|
|
|
|
|
bool post = params[2] != 0;
|
|
|
|
|
2016-08-27 16:20:38 +02:00
|
|
|
for(int i = g_pHooks.length() -1; i >= 0; i--)
|
2013-08-22 04:18:52 +02:00
|
|
|
{
|
2014-08-19 19:14:48 +02:00
|
|
|
DHooksManager *manager = g_pHooks.at(i);
|
2013-08-22 04:18:52 +02:00
|
|
|
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)
|
|
|
|
{
|
2014-08-19 19:14:48 +02:00
|
|
|
return pContext->ThrowNativeError("Could not get gamerules pointer");
|
2013-08-22 04:18:52 +02:00
|
|
|
}
|
|
|
|
|
2018-01-27 16:08:44 +01:00
|
|
|
IPluginFunction *cb = GetCallback(pContext, setup, params, 4);
|
|
|
|
|
|
|
|
if (!cb)
|
|
|
|
{
|
|
|
|
pContext->ThrowNativeError("Failed to hook gamerules, no callback provided");
|
|
|
|
}
|
|
|
|
|
|
|
|
DHooksManager *manager = new DHooksManager(setup, rules, pContext->GetFunctionById(params[3]), cb, post);
|
2013-08-22 04:18:52 +02:00
|
|
|
|
|
|
|
if(!manager->hookid)
|
|
|
|
{
|
|
|
|
delete manager;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-08-27 16:20:38 +02:00
|
|
|
g_pHooks.append(manager);
|
2013-08-22 04:18:52 +02:00
|
|
|
|
|
|
|
return manager->hookid;
|
|
|
|
}
|
2018-01-29 18:36:26 +01:00
|
|
|
// DHookRaw(Handle:setup, bool:post, Address:addr, DHookRemovalCB:removalcb, DHookCallback:callback = INVALID_FUNCTION); // Both callbacks are optional
|
2013-08-22 04:18:52 +02:00
|
|
|
cell_t Native_HookRaw(IPluginContext *pContext, const cell_t *params)
|
|
|
|
{
|
|
|
|
HookSetup *setup;
|
|
|
|
|
2013-08-23 20:29:01 +02:00
|
|
|
if(!GetHandleIfValidOrError(g_HookSetupHandle, (void **)&setup, pContext, params[1]))
|
2013-08-22 04:18:52 +02:00
|
|
|
{
|
2013-08-23 20:29:01 +02:00
|
|
|
return 0;
|
2013-08-22 04:18:52 +02:00
|
|
|
}
|
2013-08-23 20:29:01 +02:00
|
|
|
|
2016-12-12 06:02:10 +01:00
|
|
|
if (setup->offset == -1)
|
|
|
|
{
|
|
|
|
return pContext->ThrowNativeError("Hook not setup for a virtual hook.");
|
|
|
|
}
|
|
|
|
|
2013-08-22 04:18:52 +02:00
|
|
|
if(setup->hookType != HookType_Raw)
|
|
|
|
{
|
2014-08-19 19:14:48 +02:00
|
|
|
return pContext->ThrowNativeError("Hook is not a raw hook");
|
2013-08-22 04:18:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool post = params[2] != 0;
|
2015-11-13 22:26:05 +01:00
|
|
|
void *iface = (void *)(params[3]);
|
2013-08-22 04:18:52 +02:00
|
|
|
|
2016-08-27 16:20:38 +02:00
|
|
|
for(int i = g_pHooks.length() -1; i >= 0; i--)
|
2013-08-22 04:18:52 +02:00
|
|
|
{
|
2014-08-19 19:14:48 +02:00
|
|
|
DHooksManager *manager = g_pHooks.at(i);
|
2015-11-13 22:26:05 +01:00
|
|
|
if(manager->callback->hookType == HookType_Raw && manager->addr == (intptr_t)iface && manager->callback->offset == setup->offset && manager->callback->post == post && manager->remove_callback == pContext->GetFunctionById(params[4]) && manager->callback->plugin_callback == setup->callback)
|
2013-08-22 04:18:52 +02:00
|
|
|
{
|
|
|
|
return manager->hookid;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!iface)
|
|
|
|
{
|
|
|
|
return pContext->ThrowNativeError("Invalid address passed");
|
|
|
|
}
|
|
|
|
|
2018-01-27 16:08:44 +01:00
|
|
|
IPluginFunction *cb = GetCallback(pContext, setup, params, 5);
|
|
|
|
|
|
|
|
if (!cb)
|
|
|
|
{
|
|
|
|
pContext->ThrowNativeError("Failed to hook address, no callback provided");
|
|
|
|
}
|
|
|
|
|
|
|
|
DHooksManager *manager = new DHooksManager(setup, iface, pContext->GetFunctionById(params[4]), cb, post);
|
2013-08-22 04:18:52 +02:00
|
|
|
|
|
|
|
if(!manager->hookid)
|
|
|
|
{
|
|
|
|
delete manager;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-08-27 16:20:38 +02:00
|
|
|
g_pHooks.append(manager);
|
2013-08-22 04:18:52 +02:00
|
|
|
|
|
|
|
return manager->hookid;
|
|
|
|
}
|
|
|
|
// native bool:DHookRemoveHookID(hookid);
|
|
|
|
cell_t Native_RemoveHookID(IPluginContext *pContext, const cell_t *params)
|
|
|
|
{
|
2016-08-27 16:20:38 +02:00
|
|
|
for(int i = g_pHooks.length() -1; i >= 0; i--)
|
2013-08-22 04:18:52 +02:00
|
|
|
{
|
2014-08-19 19:14:48 +02:00
|
|
|
DHooksManager *manager = g_pHooks.at(i);
|
2013-08-22 04:18:52 +02:00
|
|
|
if(manager->hookid == params[1] && manager->callback->plugin_callback->GetParentRuntime()->GetDefaultContext() == pContext)
|
|
|
|
{
|
|
|
|
delete manager;
|
2016-08-27 16:20:38 +02:00
|
|
|
g_pHooks.remove(i);
|
2013-08-22 04:18:52 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
// native any:DHookGetParam(Handle:hParams, num);
|
2013-08-19 17:07:25 +02:00
|
|
|
cell_t Native_GetParam(IPluginContext *pContext, const cell_t *params)
|
|
|
|
{
|
|
|
|
HookParamsStruct *paramStruct;
|
2013-08-23 20:29:01 +02:00
|
|
|
|
|
|
|
if(!GetHandleIfValidOrError(g_HookParamsHandle, (void **)¶mStruct, pContext, params[1]))
|
2013-08-19 17:07:25 +02:00
|
|
|
{
|
2013-08-23 20:29:01 +02:00
|
|
|
return 0;
|
2013-08-19 17:07:25 +02:00
|
|
|
}
|
|
|
|
|
2014-08-19 19:14:48 +02:00
|
|
|
if(params[2] < 0 || params[2] > (int)paramStruct->dg->params.size())
|
2013-08-19 17:07:25 +02:00
|
|
|
{
|
2014-08-19 19:14:48 +02:00
|
|
|
return pContext->ThrowNativeError("Invalid param number %i max params is %i", params[2], paramStruct->dg->params.size());
|
2013-08-19 17:07:25 +02:00
|
|
|
}
|
|
|
|
if(params[2] == 0)
|
|
|
|
{
|
2014-08-19 19:14:48 +02:00
|
|
|
return paramStruct->dg->params.size();
|
2013-08-19 17:07:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int index = params[2] - 1;
|
|
|
|
|
2016-08-30 16:56:56 +02:00
|
|
|
size_t offset = GetParamOffset(paramStruct, index);
|
|
|
|
|
|
|
|
void *addr = (void **)((intptr_t)paramStruct->orgParams + offset);
|
|
|
|
|
|
|
|
if(*(void **)addr == NULL && (paramStruct->dg->params.at(index).type == HookParamType_CBaseEntity || paramStruct->dg->params.at(index).type == HookParamType_Edict))
|
2013-08-19 17:07:25 +02:00
|
|
|
{
|
|
|
|
return pContext->ThrowNativeError("Trying to get value for null pointer.");
|
|
|
|
}
|
|
|
|
|
2014-08-19 19:14:48 +02:00
|
|
|
switch(paramStruct->dg->params.at(index).type)
|
2013-08-19 17:07:25 +02:00
|
|
|
{
|
|
|
|
case HookParamType_Int:
|
2016-08-30 16:56:56 +02:00
|
|
|
return *(int *)addr;
|
2013-08-19 17:07:25 +02:00
|
|
|
case HookParamType_Bool:
|
2016-08-30 16:56:56 +02:00
|
|
|
return *(cell_t *)addr != 0;
|
2013-08-19 17:07:25 +02:00
|
|
|
case HookParamType_CBaseEntity:
|
2016-08-30 16:56:56 +02:00
|
|
|
return gamehelpers->EntityToBCompatRef(*(CBaseEntity **)addr);
|
2013-08-19 17:07:25 +02:00
|
|
|
case HookParamType_Edict:
|
2016-08-30 16:56:56 +02:00
|
|
|
return gamehelpers->IndexOfEdict(*(edict_t **)addr);
|
2013-08-19 17:07:25 +02:00
|
|
|
case HookParamType_Float:
|
2016-08-30 16:56:56 +02:00
|
|
|
return sp_ftoc(*(float *)addr);
|
2013-08-19 17:07:25 +02:00
|
|
|
default:
|
2014-08-19 19:14:48 +02:00
|
|
|
return pContext->ThrowNativeError("Invalid param type (%i) to get", paramStruct->dg->params.at(index).type);
|
2013-08-19 17:07:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
2013-08-22 04:18:52 +02:00
|
|
|
|
|
|
|
// native DHookSetParam(Handle:hParams, param, any:value)
|
|
|
|
cell_t Native_SetParam(IPluginContext *pContext, const cell_t *params)
|
|
|
|
{
|
|
|
|
HookParamsStruct *paramStruct;
|
2013-08-23 20:29:01 +02:00
|
|
|
|
|
|
|
if(!GetHandleIfValidOrError(g_HookParamsHandle, (void **)¶mStruct, pContext, params[1]))
|
2013-08-22 04:18:52 +02:00
|
|
|
{
|
2013-08-23 20:29:01 +02:00
|
|
|
return 0;
|
2013-08-22 04:18:52 +02:00
|
|
|
}
|
|
|
|
|
2014-08-19 19:14:48 +02:00
|
|
|
if(params[2] <= 0 || params[2] > (int)paramStruct->dg->params.size())
|
2013-08-22 04:18:52 +02:00
|
|
|
{
|
2014-08-19 19:14:48 +02:00
|
|
|
return pContext->ThrowNativeError("Invalid param number %i max params is %i", params[2], paramStruct->dg->params.size());
|
2013-08-22 04:18:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int index = params[2] - 1;
|
|
|
|
|
2016-08-30 16:56:56 +02:00
|
|
|
size_t offset = GetParamOffset(paramStruct, index);
|
|
|
|
void *addr = (void **)((intptr_t)paramStruct->newParams + offset);
|
|
|
|
|
2014-08-19 19:14:48 +02:00
|
|
|
switch(paramStruct->dg->params.at(index).type)
|
2013-08-22 04:18:52 +02:00
|
|
|
{
|
|
|
|
case HookParamType_Int:
|
2016-08-30 16:56:56 +02:00
|
|
|
*(int *)addr = params[3];
|
2013-08-22 04:18:52 +02:00
|
|
|
break;
|
|
|
|
case HookParamType_Bool:
|
2016-08-30 16:56:56 +02:00
|
|
|
*(bool *)addr = (params[3] ? true : false);
|
2013-08-22 04:18:52 +02:00
|
|
|
break;
|
|
|
|
case HookParamType_CBaseEntity:
|
|
|
|
{
|
2014-08-19 19:14:48 +02:00
|
|
|
CBaseEntity *pEnt = gamehelpers->ReferenceToEntity(params[2]);
|
2016-08-30 16:56:56 +02:00
|
|
|
|
2013-08-22 04:18:52 +02:00
|
|
|
if(!pEnt)
|
|
|
|
{
|
|
|
|
return pContext->ThrowNativeError("Invalid entity index passed for param value");
|
|
|
|
}
|
2016-08-30 16:56:56 +02:00
|
|
|
|
|
|
|
*(CBaseEntity **)addr = pEnt;
|
2013-08-22 04:18:52 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case HookParamType_Edict:
|
|
|
|
{
|
|
|
|
edict_t *pEdict = gamehelpers->EdictOfIndex(params[2]);
|
2016-08-30 16:56:56 +02:00
|
|
|
|
2013-08-22 04:18:52 +02:00
|
|
|
if(!pEdict || pEdict->IsFree())
|
|
|
|
{
|
|
|
|
pContext->ThrowNativeError("Invalid entity index passed for param value");
|
|
|
|
}
|
2016-08-30 16:56:56 +02:00
|
|
|
|
|
|
|
*(edict_t **)addr = pEdict;
|
2013-08-22 04:18:52 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case HookParamType_Float:
|
2016-08-30 16:56:56 +02:00
|
|
|
*(float *)addr = sp_ctof(params[3]);
|
2013-08-22 04:18:52 +02:00
|
|
|
break;
|
|
|
|
default:
|
2014-08-19 19:14:48 +02:00
|
|
|
return pContext->ThrowNativeError("Invalid param type (%i) to set", paramStruct->dg->params.at(index).type);
|
2013-08-22 04:18:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
paramStruct->isChanged[index] = true;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// native any:DHookGetReturn(Handle:hReturn);
|
2013-08-19 17:07:25 +02:00
|
|
|
cell_t Native_GetReturn(IPluginContext *pContext, const cell_t *params)
|
|
|
|
{
|
2013-08-20 04:33:44 +02:00
|
|
|
HookReturnStruct *returnStruct;
|
|
|
|
|
2013-08-23 20:29:01 +02:00
|
|
|
if(!GetHandleIfValidOrError(g_HookReturnHandle, (void **)&returnStruct, pContext, params[1]))
|
2013-08-20 04:33:44 +02:00
|
|
|
{
|
2013-08-23 20:29:01 +02:00
|
|
|
return 0;
|
2013-08-20 04:33:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
switch(returnStruct->type)
|
|
|
|
{
|
|
|
|
case ReturnType_Int:
|
|
|
|
return *(int *)returnStruct->orgResult;
|
|
|
|
case ReturnType_Bool:
|
2013-08-21 02:18:50 +02:00
|
|
|
return *(bool *)returnStruct->orgResult? 1 : 0;
|
2013-08-20 04:33:44 +02:00
|
|
|
case ReturnType_CBaseEntity:
|
2015-05-14 18:03:48 +02:00
|
|
|
return gamehelpers->EntityToBCompatRef((CBaseEntity *)returnStruct->orgResult);
|
2013-08-20 04:33:44 +02:00
|
|
|
case ReturnType_Edict:
|
2015-05-14 18:03:48 +02:00
|
|
|
return gamehelpers->IndexOfEdict((edict_t *)returnStruct->orgResult);
|
2013-08-20 04:33:44 +02:00
|
|
|
case ReturnType_Float:
|
|
|
|
return sp_ftoc(*(float *)returnStruct->orgResult);
|
|
|
|
default:
|
2013-08-21 04:21:29 +02:00
|
|
|
return pContext->ThrowNativeError("Invalid param type (%i) to get", returnStruct->type);
|
2013-08-20 04:33:44 +02:00
|
|
|
}
|
2013-08-19 17:07:25 +02:00
|
|
|
return 1;
|
|
|
|
}
|
2013-08-22 04:18:52 +02:00
|
|
|
// native DHookSetReturn(Handle:hReturn, any:value)
|
2013-08-19 17:07:25 +02:00
|
|
|
cell_t Native_SetReturn(IPluginContext *pContext, const cell_t *params)
|
|
|
|
{
|
2013-08-20 04:33:44 +02:00
|
|
|
HookReturnStruct *returnStruct;
|
|
|
|
|
2013-08-23 20:29:01 +02:00
|
|
|
if(!GetHandleIfValidOrError(g_HookReturnHandle, (void **)&returnStruct, pContext, params[1]))
|
2013-08-20 04:33:44 +02:00
|
|
|
{
|
2013-08-23 20:29:01 +02:00
|
|
|
return 0;
|
2013-08-20 04:33:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
switch(returnStruct->type)
|
|
|
|
{
|
|
|
|
case ReturnType_Int:
|
2013-08-21 04:21:29 +02:00
|
|
|
*(int *)returnStruct->newResult = params[2];
|
2013-08-20 04:33:44 +02:00
|
|
|
break;
|
|
|
|
case ReturnType_Bool:
|
2013-08-21 04:21:29 +02:00
|
|
|
*(bool *)returnStruct->newResult = params[2] != 0;
|
2013-08-20 04:33:44 +02:00
|
|
|
break;
|
|
|
|
case ReturnType_CBaseEntity:
|
2013-08-21 19:36:23 +02:00
|
|
|
{
|
2014-08-19 19:14:48 +02:00
|
|
|
CBaseEntity *pEnt = gamehelpers->ReferenceToEntity(params[2]);
|
2013-08-20 04:33:44 +02:00
|
|
|
if(!pEnt)
|
|
|
|
{
|
|
|
|
return pContext->ThrowNativeError("Invalid entity index passed for return value");
|
|
|
|
}
|
2015-05-14 18:03:48 +02:00
|
|
|
returnStruct->newResult = pEnt;
|
2013-08-20 04:33:44 +02:00
|
|
|
break;
|
2013-08-21 19:36:23 +02:00
|
|
|
}
|
2013-08-20 04:33:44 +02:00
|
|
|
case ReturnType_Edict:
|
2013-08-21 19:36:23 +02:00
|
|
|
{
|
|
|
|
edict_t *pEdict = gamehelpers->EdictOfIndex(params[2]);
|
2013-08-20 04:33:44 +02:00
|
|
|
if(!pEdict || pEdict->IsFree())
|
|
|
|
{
|
|
|
|
pContext->ThrowNativeError("Invalid entity index passed for return value");
|
|
|
|
}
|
2015-05-14 18:03:48 +02:00
|
|
|
returnStruct->newResult = pEdict;
|
2013-08-20 04:33:44 +02:00
|
|
|
break;
|
2013-08-21 19:36:23 +02:00
|
|
|
}
|
2013-08-20 04:33:44 +02:00
|
|
|
case ReturnType_Float:
|
2013-08-21 04:21:29 +02:00
|
|
|
*(float *)returnStruct->newResult = sp_ctof(params[2]);
|
2013-08-20 04:33:44 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return pContext->ThrowNativeError("Invalid param type (%i) to get",returnStruct->type);
|
|
|
|
}
|
|
|
|
returnStruct->isChanged = true;
|
2013-08-19 17:07:25 +02:00
|
|
|
return 1;
|
|
|
|
}
|
2013-08-23 20:29:01 +02:00
|
|
|
// native DHookGetParamVector(Handle:hParams, num, Float:vec[3])
|
|
|
|
cell_t Native_GetParamVector(IPluginContext *pContext, const cell_t *params)
|
|
|
|
{
|
|
|
|
HookParamsStruct *paramStruct;
|
2013-08-22 04:18:52 +02:00
|
|
|
|
2013-08-23 20:29:01 +02:00
|
|
|
if(!GetHandleIfValidOrError(g_HookParamsHandle, (void **)¶mStruct, pContext, params[1]))
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-08-19 19:14:48 +02:00
|
|
|
if(params[2] <= 0 || params[2] > (int)paramStruct->dg->params.size())
|
2013-08-23 20:29:01 +02:00
|
|
|
{
|
2014-08-19 19:14:48 +02:00
|
|
|
return pContext->ThrowNativeError("Invalid param number %i max params is %i", params[2], paramStruct->dg->params.size());
|
2013-08-23 20:29:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int index = params[2] - 1;
|
|
|
|
|
2016-08-30 16:56:56 +02:00
|
|
|
size_t offset = GetParamOffset(paramStruct, index);
|
|
|
|
void *addr = (void **)((intptr_t)paramStruct->orgParams + offset);
|
|
|
|
|
|
|
|
if (*(void **)addr == NULL)
|
|
|
|
{
|
|
|
|
return pContext->ThrowNativeError("Trying to get value for null pointer.");
|
|
|
|
}
|
|
|
|
|
2014-08-19 19:14:48 +02:00
|
|
|
switch(paramStruct->dg->params.at(index).type)
|
2013-08-23 20:29:01 +02:00
|
|
|
{
|
|
|
|
case HookParamType_VectorPtr:
|
|
|
|
{
|
|
|
|
cell_t *buffer;
|
|
|
|
pContext->LocalToPhysAddr(params[3], &buffer);
|
2016-08-30 16:56:56 +02:00
|
|
|
SDKVector *vec = *(SDKVector **)addr;
|
|
|
|
|
|
|
|
buffer[0] = sp_ftoc(vec->x);
|
|
|
|
buffer[1] = sp_ftoc(vec->y);
|
|
|
|
buffer[2] = sp_ftoc(vec->z);
|
2013-08-23 20:29:01 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return pContext->ThrowNativeError("Invalid param type to get. Param is not a vector.");
|
|
|
|
}
|
2019-08-03 18:26:53 +02:00
|
|
|
|
|
|
|
static void FreeChangedVector(void *pData)
|
|
|
|
{
|
|
|
|
delete (SDKVector *)pData;
|
|
|
|
}
|
|
|
|
|
2013-08-23 20:29:01 +02:00
|
|
|
// native DHookSetParamVector(Handle:hParams, num, Float:vec[3])
|
|
|
|
cell_t Native_SetParamVector(IPluginContext *pContext, const cell_t *params)
|
2013-08-19 17:07:25 +02:00
|
|
|
{
|
2013-08-23 20:29:01 +02:00
|
|
|
HookParamsStruct *paramStruct;
|
|
|
|
|
|
|
|
if(!GetHandleIfValidOrError(g_HookParamsHandle, (void **)¶mStruct, pContext, params[1]))
|
2013-08-19 17:07:25 +02:00
|
|
|
{
|
2013-08-23 20:29:01 +02:00
|
|
|
return 0;
|
2013-08-19 17:07:25 +02:00
|
|
|
}
|
|
|
|
|
2014-08-19 19:14:48 +02:00
|
|
|
if(params[2] <= 0 || params[2] > (int)paramStruct->dg->params.size())
|
2013-08-23 20:29:01 +02:00
|
|
|
{
|
2014-08-19 19:14:48 +02:00
|
|
|
return pContext->ThrowNativeError("Invalid param number %i max params is %i", params[2], paramStruct->dg->params.size());
|
2013-08-23 20:29:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int index = params[2] - 1;
|
|
|
|
|
2016-08-30 16:56:56 +02:00
|
|
|
size_t offset = GetParamOffset(paramStruct, index);
|
|
|
|
void *addr = (void **)((intptr_t)paramStruct->newParams + offset);
|
|
|
|
|
2014-08-19 19:14:48 +02:00
|
|
|
switch(paramStruct->dg->params.at(index).type)
|
2013-08-23 20:29:01 +02:00
|
|
|
{
|
|
|
|
case HookParamType_VectorPtr:
|
|
|
|
{
|
|
|
|
cell_t *buffer;
|
|
|
|
pContext->LocalToPhysAddr(params[3], &buffer);
|
|
|
|
|
2016-08-30 16:56:56 +02:00
|
|
|
*(SDKVector **)addr = new SDKVector(sp_ctof(buffer[0]), sp_ctof(buffer[1]), sp_ctof(buffer[2]));
|
2015-06-05 14:44:05 +02:00
|
|
|
paramStruct->isChanged[index] = true;
|
2019-08-03 18:26:53 +02:00
|
|
|
// Free it later (cheaply) after the function returned.
|
|
|
|
smutils->AddFrameAction(FreeChangedVector, *(SDKVector **)addr);
|
2013-08-23 20:29:01 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return pContext->ThrowNativeError("Invalid param type to set. Param is not a vector.");
|
|
|
|
}
|
|
|
|
|
|
|
|
// native DHookGetParamString(Handle:hParams, num, String:buffer[], size)
|
|
|
|
cell_t Native_GetParamString(IPluginContext *pContext, const cell_t *params)
|
|
|
|
{
|
2013-08-19 17:07:25 +02:00
|
|
|
HookParamsStruct *paramStruct;
|
2013-08-23 20:29:01 +02:00
|
|
|
|
|
|
|
if(!GetHandleIfValidOrError(g_HookParamsHandle, (void **)¶mStruct, pContext, params[1]))
|
2013-08-19 17:07:25 +02:00
|
|
|
{
|
2013-08-23 20:29:01 +02:00
|
|
|
return 0;
|
2013-08-19 17:07:25 +02:00
|
|
|
}
|
|
|
|
|
2014-08-19 19:14:48 +02:00
|
|
|
if(params[2] <= 0 || params[2] > (int)paramStruct->dg->params.size())
|
2013-08-19 17:07:25 +02:00
|
|
|
{
|
2014-08-19 19:14:48 +02:00
|
|
|
return pContext->ThrowNativeError("Invalid param number %i max params is %i", params[2], paramStruct->dg->params.size());
|
2013-08-19 17:07:25 +02:00
|
|
|
}
|
2016-08-30 16:56:56 +02:00
|
|
|
|
2013-08-19 17:07:25 +02:00
|
|
|
int index = params[2] - 1;
|
|
|
|
|
2016-08-30 16:56:56 +02:00
|
|
|
size_t offset = GetParamOffset(paramStruct, index);
|
|
|
|
void *addr = (void **)((intptr_t)paramStruct->orgParams + offset);
|
|
|
|
|
|
|
|
if(*(void **)addr == NULL)
|
2013-08-19 17:07:25 +02:00
|
|
|
{
|
|
|
|
return pContext->ThrowNativeError("Trying to get value for null pointer.");
|
|
|
|
}
|
|
|
|
|
2014-08-19 19:14:48 +02:00
|
|
|
if(paramStruct->dg->params.at(index).type == HookParamType_CharPtr)
|
2013-08-19 17:07:25 +02:00
|
|
|
{
|
2016-08-30 16:56:56 +02:00
|
|
|
pContext->StringToLocal(params[3], params[4], *(const char **)addr);
|
2013-08-19 17:07:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
2013-08-29 21:18:43 +02:00
|
|
|
|
2013-08-23 20:29:01 +02:00
|
|
|
// native DHookGetReturnString(Handle:hReturn, String:buffer[], size)
|
2013-08-22 22:14:32 +02:00
|
|
|
cell_t Native_GetReturnString(IPluginContext *pContext, const cell_t *params)
|
|
|
|
{
|
|
|
|
HookReturnStruct *returnStruct;
|
|
|
|
|
2013-08-23 20:29:01 +02:00
|
|
|
if(!GetHandleIfValidOrError(g_HookReturnHandle, (void **)&returnStruct, pContext, params[1]))
|
2013-08-22 22:14:32 +02:00
|
|
|
{
|
2013-08-23 20:29:01 +02:00
|
|
|
return 0;
|
2013-08-22 22:14:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
switch(returnStruct->type)
|
|
|
|
{
|
|
|
|
case ReturnType_String:
|
|
|
|
pContext->StringToLocal(params[2], params[3], (*(string_t *)returnStruct->orgResult == NULL_STRING) ? "" : STRING(*(string_t *)returnStruct->orgResult));
|
|
|
|
return 1;
|
|
|
|
case ReturnType_StringPtr:
|
2015-05-14 18:03:48 +02:00
|
|
|
pContext->StringToLocal(params[2], params[3], ((string_t *)returnStruct->orgResult == NULL) ? "" : ((string_t *)returnStruct->orgResult)->ToCStr());
|
2013-08-22 22:14:32 +02:00
|
|
|
return 1;
|
|
|
|
case ReturnType_CharPtr:
|
2015-05-14 18:03:48 +02:00
|
|
|
pContext->StringToLocal(params[2], params[3], ((char *)returnStruct->orgResult == NULL) ? "" : (const char *)returnStruct->orgResult);
|
2013-08-22 22:14:32 +02:00
|
|
|
return 1;
|
|
|
|
default:
|
|
|
|
return pContext->ThrowNativeError("Invalid param type to get. Param is not a string.");
|
|
|
|
}
|
|
|
|
}
|
2013-08-23 20:29:01 +02:00
|
|
|
|
2019-08-03 18:26:53 +02:00
|
|
|
static void FreeChangedCharPtr(void *pData)
|
|
|
|
{
|
|
|
|
delete[](char *)pData;
|
|
|
|
}
|
|
|
|
|
2013-08-23 20:29:01 +02:00
|
|
|
//native DHookSetReturnString(Handle:hReturn, String:value[])
|
2013-08-22 22:14:32 +02:00
|
|
|
cell_t Native_SetReturnString(IPluginContext *pContext, const cell_t *params)
|
|
|
|
{
|
|
|
|
HookReturnStruct *returnStruct;
|
|
|
|
|
2013-08-23 20:29:01 +02:00
|
|
|
if(!GetHandleIfValidOrError(g_HookReturnHandle, (void **)&returnStruct, pContext, params[1]))
|
2013-08-22 22:14:32 +02:00
|
|
|
{
|
2013-08-23 20:29:01 +02:00
|
|
|
return 0;
|
2013-08-22 22:14:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
char *value;
|
|
|
|
pContext->LocalToString(params[2], &value);
|
|
|
|
|
|
|
|
switch(returnStruct->type)
|
|
|
|
{
|
|
|
|
case ReturnType_CharPtr:
|
2016-08-30 16:56:56 +02:00
|
|
|
{
|
|
|
|
returnStruct->newResult = new char[strlen(value) + 1];
|
2015-05-14 18:03:48 +02:00
|
|
|
strcpy((char *)returnStruct->newResult, value);
|
2013-08-22 22:14:32 +02:00
|
|
|
returnStruct->isChanged = true;
|
2019-08-03 18:26:53 +02:00
|
|
|
// Free it later (cheaply) after the function returned.
|
|
|
|
smutils->AddFrameAction(FreeChangedCharPtr, returnStruct->newResult);
|
2013-08-22 22:14:32 +02:00
|
|
|
return 1;
|
2016-08-30 16:56:56 +02:00
|
|
|
}
|
2013-08-22 22:14:32 +02:00
|
|
|
default:
|
2015-05-14 18:03:48 +02:00
|
|
|
return pContext->ThrowNativeError("Invalid param type to get. Param is not a char pointer.");
|
2013-08-22 22:14:32 +02:00
|
|
|
}
|
|
|
|
}
|
2013-08-20 04:33:44 +02:00
|
|
|
|
|
|
|
//native DHookSetParamString(Handle:hParams, num, String:value[])
|
2013-08-19 17:07:25 +02:00
|
|
|
cell_t Native_SetParamString(IPluginContext *pContext, const cell_t *params)
|
|
|
|
{
|
2013-08-20 04:33:44 +02:00
|
|
|
HookParamsStruct *paramStruct;
|
2013-08-23 20:29:01 +02:00
|
|
|
|
|
|
|
if(!GetHandleIfValidOrError(g_HookParamsHandle, (void **)¶mStruct, pContext, params[1]))
|
2013-08-20 04:33:44 +02:00
|
|
|
{
|
2013-08-23 20:29:01 +02:00
|
|
|
return 0;
|
2013-08-20 04:33:44 +02:00
|
|
|
}
|
|
|
|
|
2014-08-19 19:14:48 +02:00
|
|
|
if(params[2] <= 0 || params[2] > (int)paramStruct->dg->params.size())
|
2013-08-20 04:33:44 +02:00
|
|
|
{
|
2014-08-19 19:14:48 +02:00
|
|
|
return pContext->ThrowNativeError("Invalid param number %i max params is %i", params[2], paramStruct->dg->params.size());
|
2013-08-20 04:33:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int index = params[2] - 1;
|
2016-08-30 16:56:56 +02:00
|
|
|
size_t offset = GetParamOffset(paramStruct, index);
|
|
|
|
void *addr = (void **)((intptr_t)paramStruct->newParams + offset);
|
2013-08-20 04:33:44 +02:00
|
|
|
|
|
|
|
char *value;
|
|
|
|
pContext->LocalToString(params[3], &value);
|
|
|
|
|
2014-08-19 19:14:48 +02:00
|
|
|
if(paramStruct->dg->params.at(index).type == HookParamType_CharPtr)
|
2013-08-20 04:33:44 +02:00
|
|
|
{
|
2016-08-30 22:40:24 +02:00
|
|
|
*(char **)addr = new char[strlen(value)+1];
|
2016-08-30 16:56:56 +02:00
|
|
|
strcpy(*(char **)addr, value);
|
2013-08-20 04:33:44 +02:00
|
|
|
paramStruct->isChanged[index] = true;
|
2019-08-03 18:26:53 +02:00
|
|
|
// Free it later (cheaply) after the function returned.
|
|
|
|
smutils->AddFrameAction(FreeChangedCharPtr, *(char **)addr);
|
2013-08-20 04:33:44 +02:00
|
|
|
}
|
2013-08-19 17:07:25 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-08-22 20:55:33 +02:00
|
|
|
//native DHookAddEntityListener(ListenType:type, ListenCB:callback);
|
|
|
|
cell_t Native_AddEntityListener(IPluginContext *pContext, const cell_t *params)
|
|
|
|
{
|
|
|
|
if(g_pEntityListener)
|
|
|
|
{
|
|
|
|
return g_pEntityListener->AddPluginEntityListener((ListenType)params[1], pContext->GetFunctionById(params[2]));;
|
|
|
|
}
|
|
|
|
return pContext->ThrowNativeError("Failed to get g_pEntityListener");
|
|
|
|
}
|
|
|
|
|
|
|
|
//native bool:DHookRemoveEntityListener(ListenType:type, ListenCB:callback);
|
|
|
|
cell_t Native_RemoveEntityListener(IPluginContext *pContext, const cell_t *params)
|
|
|
|
{
|
|
|
|
if(g_pEntityListener)
|
|
|
|
{
|
|
|
|
return g_pEntityListener->RemovePluginEntityListener((ListenType)params[1], pContext->GetFunctionById(params[2]));;
|
|
|
|
}
|
|
|
|
return pContext->ThrowNativeError("Failed to get g_pEntityListener");
|
|
|
|
}
|
|
|
|
|
2013-08-27 04:19:05 +02:00
|
|
|
//native any:DHookGetParamObjectPtrVar(Handle:hParams, num, offset, ObjectValueType:type);
|
|
|
|
cell_t Native_GetParamObjectPtrVar(IPluginContext *pContext, const cell_t *params)
|
|
|
|
{
|
|
|
|
HookParamsStruct *paramStruct;
|
|
|
|
|
|
|
|
if(!GetHandleIfValidOrError(g_HookParamsHandle, (void **)¶mStruct, pContext, params[1]))
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-08-19 19:14:48 +02:00
|
|
|
if(params[2] <= 0 || params[2] > (int)paramStruct->dg->params.size())
|
2013-08-27 04:19:05 +02:00
|
|
|
{
|
2014-08-19 19:14:48 +02:00
|
|
|
return pContext->ThrowNativeError("Invalid param number %i max params is %i", params[2], paramStruct->dg->params.size());
|
2013-08-27 04:19:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int index = params[2] - 1;
|
|
|
|
|
2014-08-19 19:14:48 +02:00
|
|
|
if(paramStruct->dg->params.at(index).type != HookParamType_ObjectPtr && paramStruct->dg->params.at(index).type != HookParamType_Object)
|
2013-08-27 04:19:05 +02:00
|
|
|
{
|
2014-08-19 19:14:48 +02:00
|
|
|
return pContext->ThrowNativeError("Invalid object value type %i", paramStruct->dg->params.at(index).type);
|
2013-08-27 04:19:05 +02:00
|
|
|
}
|
2016-08-30 16:56:56 +02:00
|
|
|
|
|
|
|
size_t offset = GetParamOffset(paramStruct, index);
|
|
|
|
void *addr = GetObjectAddr(paramStruct->dg->params.at(index).type, paramStruct->dg->params.at(index).flags, paramStruct->orgParams, offset);
|
2013-08-27 04:19:05 +02:00
|
|
|
|
|
|
|
switch((ObjectValueType)params[4])
|
|
|
|
{
|
|
|
|
case ObjectValueType_Int:
|
|
|
|
{
|
2016-08-30 16:56:56 +02:00
|
|
|
return *(int *)((intptr_t)addr + params[3]);
|
2013-08-27 04:19:05 +02:00
|
|
|
}
|
|
|
|
case ObjectValueType_Bool:
|
2016-08-30 16:56:56 +02:00
|
|
|
return (*(bool *)((intptr_t)addr + params[3])) ? 1 : 0;
|
2013-08-27 04:19:05 +02:00
|
|
|
case ObjectValueType_Ehandle:
|
2016-08-30 16:56:56 +02:00
|
|
|
case ObjectValueType_EhandlePtr:
|
2013-08-27 04:19:05 +02:00
|
|
|
{
|
2016-08-30 16:56:56 +02:00
|
|
|
edict_t *pEdict = gamehelpers->GetHandleEntity(*(CBaseHandle *)((intptr_t)addr +params[3]));
|
2014-08-19 19:14:48 +02:00
|
|
|
|
2014-08-19 23:37:04 +02:00
|
|
|
if(!pEdict)
|
2014-08-19 19:14:48 +02:00
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2014-08-19 23:37:04 +02:00
|
|
|
return gamehelpers->IndexOfEdict(pEdict);
|
2013-08-27 04:19:05 +02:00
|
|
|
}
|
|
|
|
case ObjectValueType_Float:
|
2016-08-30 16:56:56 +02:00
|
|
|
{
|
|
|
|
return sp_ftoc(*(float *)((intptr_t)addr + params[3]));
|
|
|
|
}
|
2013-08-27 04:19:05 +02:00
|
|
|
case ObjectValueType_CBaseEntityPtr:
|
2016-08-30 16:56:56 +02:00
|
|
|
return gamehelpers->EntityToBCompatRef(*(CBaseEntity **)((intptr_t)addr + params[3]));
|
2013-08-27 04:19:05 +02:00
|
|
|
case ObjectValueType_IntPtr:
|
|
|
|
{
|
2016-08-30 16:56:56 +02:00
|
|
|
int *ptr = *(int **)((intptr_t)addr + params[3]);
|
2013-08-27 04:19:05 +02:00
|
|
|
return *ptr;
|
|
|
|
}
|
|
|
|
case ObjectValueType_BoolPtr:
|
|
|
|
{
|
2016-08-30 16:56:56 +02:00
|
|
|
bool *ptr = *(bool **)((intptr_t)addr + params[3]);
|
2013-08-27 04:19:05 +02:00
|
|
|
return *ptr ? 1 : 0;
|
|
|
|
}
|
|
|
|
case ObjectValueType_FloatPtr:
|
|
|
|
{
|
2016-08-30 16:56:56 +02:00
|
|
|
float *ptr = *(float **)((intptr_t)addr + params[3]);
|
2013-08-27 04:19:05 +02:00
|
|
|
return sp_ftoc(*ptr);
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
return pContext->ThrowNativeError("Invalid Object value type");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//native DHookSetParamObjectPtrVar(Handle:hParams, num, offset, ObjectValueType:type, value)
|
|
|
|
cell_t Native_SetParamObjectPtrVar(IPluginContext *pContext, const cell_t *params)
|
|
|
|
{
|
|
|
|
HookParamsStruct *paramStruct;
|
|
|
|
|
|
|
|
if(!GetHandleIfValidOrError(g_HookParamsHandle, (void **)¶mStruct, pContext, params[1]))
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-08-19 19:14:48 +02:00
|
|
|
if(params[2] <= 0 || params[2] > (int)paramStruct->dg->params.size())
|
2013-08-27 04:19:05 +02:00
|
|
|
{
|
2014-08-19 19:14:48 +02:00
|
|
|
return pContext->ThrowNativeError("Invalid param number %i max params is %i", params[2], paramStruct->dg->params.size());
|
2013-08-27 04:19:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int index = params[2] - 1;
|
|
|
|
|
2016-08-30 16:56:56 +02:00
|
|
|
if(paramStruct->dg->params.at(index).type != HookParamType_ObjectPtr && paramStruct->dg->params.at(index).type != HookParamType_Object)
|
2013-08-27 04:19:05 +02:00
|
|
|
{
|
2014-08-19 19:14:48 +02:00
|
|
|
return pContext->ThrowNativeError("Invalid object value type %i", paramStruct->dg->params.at(index).type);
|
2013-08-27 04:19:05 +02:00
|
|
|
}
|
|
|
|
|
2016-08-30 16:56:56 +02:00
|
|
|
size_t offset = GetParamOffset(paramStruct, index);
|
|
|
|
void *addr = GetObjectAddr(paramStruct->dg->params.at(index).type, paramStruct->dg->params.at(index).flags, paramStruct->orgParams, offset);
|
2013-08-27 04:19:05 +02:00
|
|
|
|
|
|
|
switch((ObjectValueType)params[4])
|
|
|
|
{
|
|
|
|
case ObjectValueType_Int:
|
2016-08-30 16:56:56 +02:00
|
|
|
*(int *)((intptr_t)addr + params[3]) = params[5];
|
2013-08-27 04:19:05 +02:00
|
|
|
break;
|
|
|
|
case ObjectValueType_Bool:
|
2016-08-30 16:56:56 +02:00
|
|
|
*(bool *)((intptr_t)addr + params[3]) = params[5] != 0;
|
2013-08-27 04:19:05 +02:00
|
|
|
break;
|
|
|
|
case ObjectValueType_Ehandle:
|
2016-08-30 16:56:56 +02:00
|
|
|
case ObjectValueType_EhandlePtr:
|
2013-08-27 04:19:05 +02:00
|
|
|
{
|
2014-08-19 23:37:04 +02:00
|
|
|
edict_t *pEdict = gamehelpers->EdictOfIndex(params[5]);
|
2013-08-27 04:19:05 +02:00
|
|
|
|
2014-08-19 23:37:04 +02:00
|
|
|
if(!pEdict || pEdict->IsFree())
|
2013-08-27 04:19:05 +02:00
|
|
|
{
|
2014-08-19 23:37:04 +02:00
|
|
|
return pContext->ThrowNativeError("Invalid edict passed");
|
2013-08-27 04:19:05 +02:00
|
|
|
}
|
2016-08-30 16:56:56 +02:00
|
|
|
gamehelpers->SetHandleEntity(*(CBaseHandle *)((intptr_t)addr + params[3]), pEdict);
|
2013-08-27 04:19:05 +02:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ObjectValueType_Float:
|
2016-08-30 16:56:56 +02:00
|
|
|
*(float *)((intptr_t)addr + params[3]) = sp_ctof(params[5]);
|
2013-08-27 04:19:05 +02:00
|
|
|
break;
|
|
|
|
case ObjectValueType_CBaseEntityPtr:
|
|
|
|
{
|
2014-08-19 19:14:48 +02:00
|
|
|
CBaseEntity *pEnt = gamehelpers->ReferenceToEntity(params[5]);
|
2013-08-27 04:19:05 +02:00
|
|
|
|
|
|
|
if(!pEnt)
|
|
|
|
{
|
|
|
|
return pContext->ThrowNativeError("Invalid entity passed");
|
|
|
|
}
|
|
|
|
|
2016-08-30 16:56:56 +02:00
|
|
|
*(CBaseEntity **)((intptr_t)addr + params[3]) = pEnt;
|
2013-08-27 04:19:05 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ObjectValueType_IntPtr:
|
|
|
|
{
|
2016-08-30 16:56:56 +02:00
|
|
|
int *ptr = *(int **)((intptr_t)addr + params[3]);
|
2013-08-27 04:19:05 +02:00
|
|
|
*ptr = params[5];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ObjectValueType_BoolPtr:
|
|
|
|
{
|
2016-08-30 16:56:56 +02:00
|
|
|
bool *ptr = *(bool **)((intptr_t)addr + params[3]);
|
2013-08-27 04:19:05 +02:00
|
|
|
*ptr = params[5] != 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ObjectValueType_FloatPtr:
|
|
|
|
{
|
2016-08-30 16:56:56 +02:00
|
|
|
float *ptr = *(float **)((intptr_t)addr + params[3]);
|
2013-08-27 04:19:05 +02:00
|
|
|
*ptr = sp_ctof(params[5]);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
return pContext->ThrowNativeError("Invalid Object value type");
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
//native DHookGetParamObjectPtrVarVector(Handle:hParams, num, offset, ObjectValueType:type, Float:buffer[3]);
|
|
|
|
cell_t Native_GetParamObjectPtrVarVector(IPluginContext *pContext, const cell_t *params)
|
|
|
|
{
|
|
|
|
HookParamsStruct *paramStruct;
|
|
|
|
|
|
|
|
if(!GetHandleIfValidOrError(g_HookParamsHandle, (void **)¶mStruct, pContext, params[1]))
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-08-19 19:14:48 +02:00
|
|
|
if(params[2] <= 0 || params[2] > (int)paramStruct->dg->params.size())
|
2013-08-27 04:19:05 +02:00
|
|
|
{
|
2014-08-19 19:14:48 +02:00
|
|
|
return pContext->ThrowNativeError("Invalid param number %i max params is %i", params[2], paramStruct->dg->params.size());
|
2013-08-27 04:19:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int index = params[2] - 1;
|
|
|
|
|
2014-08-19 19:14:48 +02:00
|
|
|
if(paramStruct->dg->params.at(index).type != HookParamType_ObjectPtr && paramStruct->dg->params.at(index).type != HookParamType_Object)
|
2013-08-27 04:19:05 +02:00
|
|
|
{
|
2014-08-19 19:14:48 +02:00
|
|
|
return pContext->ThrowNativeError("Invalid object value type %i", paramStruct->dg->params.at(index).type);
|
2013-08-27 04:19:05 +02:00
|
|
|
}
|
|
|
|
|
2016-08-30 16:56:56 +02:00
|
|
|
size_t offset = GetParamOffset(paramStruct, index);
|
|
|
|
void *addr = GetObjectAddr(paramStruct->dg->params.at(index).type, paramStruct->dg->params.at(index).flags, paramStruct->orgParams, offset);
|
2013-08-27 04:19:05 +02:00
|
|
|
|
|
|
|
cell_t *buffer;
|
|
|
|
pContext->LocalToPhysAddr(params[5], &buffer);
|
|
|
|
|
2013-08-27 04:36:57 +02:00
|
|
|
if((ObjectValueType)params[4] == ObjectValueType_VectorPtr || (ObjectValueType)params[4] == ObjectValueType_Vector)
|
2013-08-27 04:19:05 +02:00
|
|
|
{
|
2016-06-26 19:00:27 +02:00
|
|
|
SDKVector *vec;
|
2013-08-27 04:36:57 +02:00
|
|
|
|
|
|
|
if((ObjectValueType)params[4] == ObjectValueType_VectorPtr)
|
2013-08-27 04:19:05 +02:00
|
|
|
{
|
2016-08-30 16:56:56 +02:00
|
|
|
vec = *(SDKVector **)((intptr_t)addr + params[3]);
|
2013-08-27 04:36:57 +02:00
|
|
|
if(vec == NULL)
|
|
|
|
{
|
|
|
|
return pContext->ThrowNativeError("Trying to get value for null pointer.");
|
|
|
|
}
|
2013-08-27 04:19:05 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-08-30 16:56:56 +02:00
|
|
|
vec = (SDKVector *)((intptr_t)addr + params[3]);
|
2013-08-27 04:19:05 +02:00
|
|
|
}
|
2013-08-27 04:36:57 +02:00
|
|
|
|
|
|
|
buffer[0] = sp_ftoc(vec->x);
|
|
|
|
buffer[1] = sp_ftoc(vec->y);
|
|
|
|
buffer[2] = sp_ftoc(vec->z);
|
2013-08-27 04:19:05 +02:00
|
|
|
return 1;
|
|
|
|
}
|
2013-08-27 04:36:57 +02:00
|
|
|
|
|
|
|
return pContext->ThrowNativeError("Invalid Object value type (not a type of vector)");
|
2013-08-27 04:19:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//native DHookSetParamObjectPtrVarVector(Handle:hParams, num, offset, ObjectValueType:type, Float:value[3]);
|
|
|
|
cell_t Native_SetParamObjectPtrVarVector(IPluginContext *pContext, const cell_t *params)
|
|
|
|
{
|
|
|
|
HookParamsStruct *paramStruct;
|
|
|
|
|
|
|
|
if(!GetHandleIfValidOrError(g_HookParamsHandle, (void **)¶mStruct, pContext, params[1]))
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-08-19 19:14:48 +02:00
|
|
|
if(params[2] <= 0 || params[2] > (int)paramStruct->dg->params.size())
|
2013-08-27 04:19:05 +02:00
|
|
|
{
|
2014-08-19 19:14:48 +02:00
|
|
|
return pContext->ThrowNativeError("Invalid param number %i max params is %i", params[2], paramStruct->dg->params.size());
|
2013-08-27 04:19:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int index = params[2] - 1;
|
|
|
|
|
2016-08-30 16:56:56 +02:00
|
|
|
if(paramStruct->dg->params.at(index).type != HookParamType_ObjectPtr && paramStruct->dg->params.at(index).type != HookParamType_Object)
|
2013-08-27 04:19:05 +02:00
|
|
|
{
|
2014-08-19 19:14:48 +02:00
|
|
|
return pContext->ThrowNativeError("Invalid object value type %i", paramStruct->dg->params.at(index).type);
|
2013-08-27 04:19:05 +02:00
|
|
|
}
|
|
|
|
|
2016-08-30 16:56:56 +02:00
|
|
|
size_t offset = GetParamOffset(paramStruct, index);
|
|
|
|
void *addr = GetObjectAddr(paramStruct->dg->params.at(index).type, paramStruct->dg->params.at(index).flags, paramStruct->orgParams, offset);
|
2013-08-27 04:19:05 +02:00
|
|
|
|
|
|
|
cell_t *buffer;
|
|
|
|
pContext->LocalToPhysAddr(params[5], &buffer);
|
|
|
|
|
2015-11-13 22:26:05 +01:00
|
|
|
if((ObjectValueType)params[4] == ObjectValueType_VectorPtr || (ObjectValueType)params[4] == ObjectValueType_Vector)
|
2013-08-27 04:19:05 +02:00
|
|
|
{
|
2016-06-26 19:00:27 +02:00
|
|
|
SDKVector *vec;
|
2013-08-27 04:36:57 +02:00
|
|
|
|
|
|
|
if((ObjectValueType)params[4] == ObjectValueType_VectorPtr)
|
2013-08-27 04:19:05 +02:00
|
|
|
{
|
2016-08-30 16:56:56 +02:00
|
|
|
vec = *(SDKVector **)((intptr_t)addr + params[3]);
|
2013-08-27 04:36:57 +02:00
|
|
|
if(vec == NULL)
|
|
|
|
{
|
|
|
|
return pContext->ThrowNativeError("Trying to set value for null pointer.");
|
|
|
|
}
|
2013-08-27 04:19:05 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-08-30 16:56:56 +02:00
|
|
|
vec = (SDKVector *)((intptr_t)addr + params[3]);
|
2013-08-27 04:19:05 +02:00
|
|
|
}
|
2013-08-27 04:36:57 +02:00
|
|
|
|
|
|
|
vec->x = sp_ctof(buffer[0]);
|
|
|
|
vec->y = sp_ctof(buffer[1]);
|
|
|
|
vec->z = sp_ctof(buffer[2]);
|
2013-08-27 04:19:05 +02:00
|
|
|
return 1;
|
|
|
|
}
|
2013-08-27 04:36:57 +02:00
|
|
|
return pContext->ThrowNativeError("Invalid Object value type (not a type of vector)");
|
2013-08-27 04:19:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//native DHookGetParamObjectPtrString(Handle:hParams, num, offset, ObjectValueType:type, String:buffer[], size)
|
|
|
|
cell_t Native_GetParamObjectPtrString(IPluginContext *pContext, const cell_t *params)
|
|
|
|
{
|
|
|
|
HookParamsStruct *paramStruct;
|
|
|
|
|
|
|
|
if(!GetHandleIfValidOrError(g_HookParamsHandle, (void **)¶mStruct, pContext, params[1]))
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-08-19 19:14:48 +02:00
|
|
|
if(params[2] <= 0 || params[2] > (int)paramStruct->dg->params.size())
|
2013-08-27 04:19:05 +02:00
|
|
|
{
|
2014-08-19 19:14:48 +02:00
|
|
|
return pContext->ThrowNativeError("Invalid param number %i max params is %i", params[2], paramStruct->dg->params.size());
|
2013-08-27 04:19:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int index = params[2] - 1;
|
|
|
|
|
2014-08-19 19:14:48 +02:00
|
|
|
if(paramStruct->dg->params.at(index).type != HookParamType_ObjectPtr && paramStruct->dg->params.at(index).type != HookParamType_Object)
|
2013-08-27 04:19:05 +02:00
|
|
|
{
|
2014-08-19 19:14:48 +02:00
|
|
|
return pContext->ThrowNativeError("Invalid object value type %i", paramStruct->dg->params.at(index).type);
|
2013-08-27 04:19:05 +02:00
|
|
|
}
|
|
|
|
|
2016-08-30 16:56:56 +02:00
|
|
|
size_t offset = GetParamOffset(paramStruct, index);
|
|
|
|
void *addr = GetObjectAddr(paramStruct->dg->params.at(index).type, paramStruct->dg->params.at(index).flags, paramStruct->orgParams, offset);
|
2013-08-27 04:19:05 +02:00
|
|
|
|
2013-08-27 04:36:57 +02:00
|
|
|
switch((ObjectValueType)params[4])
|
2013-08-27 04:19:05 +02:00
|
|
|
{
|
2013-08-27 04:36:57 +02:00
|
|
|
case ObjectValueType_CharPtr:
|
|
|
|
{
|
2016-08-30 16:56:56 +02:00
|
|
|
char *ptr = *(char **)((intptr_t)addr + params[3]);
|
2013-08-27 04:36:57 +02:00
|
|
|
pContext->StringToLocal(params[5], params[6], ptr == NULL ? "" : (const char *)ptr);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ObjectValueType_String:
|
|
|
|
{
|
2016-08-30 16:56:56 +02:00
|
|
|
string_t string = *(string_t *)((intptr_t)addr + params[3]);
|
2013-08-27 04:36:57 +02:00
|
|
|
pContext->StringToLocal(params[5], params[6], string == NULL_STRING ? "" : STRING(string));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
return pContext->ThrowNativeError("Invalid Object value type (not a type of string)");
|
2013-08-27 04:19:05 +02:00
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
2013-08-28 20:20:20 +02:00
|
|
|
|
|
|
|
// 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);
|
|
|
|
|
2015-05-14 18:03:48 +02:00
|
|
|
if(returnStruct->type == ReturnType_Vector)
|
|
|
|
{
|
2016-06-26 19:00:27 +02:00
|
|
|
buffer[0] = sp_ftoc((*(SDKVector *)returnStruct->orgResult).x);
|
|
|
|
buffer[1] = sp_ftoc((*(SDKVector *)returnStruct->orgResult).y);
|
|
|
|
buffer[2] = sp_ftoc((*(SDKVector *)returnStruct->orgResult).z);
|
2015-05-14 18:03:48 +02:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else if(returnStruct->type == ReturnType_VectorPtr)
|
2013-08-28 20:20:20 +02:00
|
|
|
{
|
2016-06-26 19:00:27 +02:00
|
|
|
buffer[0] = sp_ftoc(((SDKVector *)returnStruct->orgResult)->x);
|
|
|
|
buffer[1] = sp_ftoc(((SDKVector *)returnStruct->orgResult)->y);
|
|
|
|
buffer[2] = sp_ftoc(((SDKVector *)returnStruct->orgResult)->z);
|
2013-08-28 20:20:20 +02:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
2015-05-14 18:03:48 +02:00
|
|
|
if(returnStruct->type == ReturnType_Vector)
|
2013-08-28 20:20:20 +02:00
|
|
|
{
|
2016-06-26 19:00:27 +02:00
|
|
|
*(SDKVector *)returnStruct->newResult = SDKVector(sp_ctof(buffer[0]), sp_ctof(buffer[1]), sp_ctof(buffer[2]));
|
2016-08-01 22:35:27 +02:00
|
|
|
returnStruct->isChanged = true;
|
2013-08-28 20:20:20 +02:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
2015-05-14 18:03:48 +02:00
|
|
|
else if(returnStruct->type == ReturnType_VectorPtr)
|
|
|
|
{
|
2016-06-26 19:00:27 +02:00
|
|
|
returnStruct->newResult = new SDKVector(sp_ctof(buffer[0]), sp_ctof(buffer[1]), sp_ctof(buffer[2]));
|
2016-08-01 22:35:27 +02:00
|
|
|
returnStruct->isChanged = true;
|
2019-08-03 18:26:53 +02:00
|
|
|
// Free it later (cheaply) after the function returned.
|
|
|
|
smutils->AddFrameAction(FreeChangedVector, returnStruct->newResult);
|
2016-08-01 22:03:18 +02:00
|
|
|
|
|
|
|
return 1;
|
2015-05-14 18:03:48 +02:00
|
|
|
}
|
2013-08-28 20:20:20 +02:00
|
|
|
return pContext->ThrowNativeError("Return type is not a vector type");
|
|
|
|
}
|
|
|
|
|
2013-08-22 20:55:33 +02:00
|
|
|
//native bool:DHookIsNullParam(Handle:hParams, num);
|
|
|
|
cell_t Native_IsNullParam(IPluginContext *pContext, const cell_t *params)
|
|
|
|
{
|
|
|
|
HookParamsStruct *paramStruct;
|
|
|
|
|
2013-08-23 20:29:01 +02:00
|
|
|
if(!GetHandleIfValidOrError(g_HookParamsHandle, (void **)¶mStruct, pContext, params[1]))
|
2013-08-22 20:55:33 +02:00
|
|
|
{
|
2013-08-23 20:29:01 +02:00
|
|
|
return 0;
|
2013-08-22 20:55:33 +02:00
|
|
|
}
|
|
|
|
|
2014-08-19 19:14:48 +02:00
|
|
|
if(params[2] <= 0 || params[2] > (int)paramStruct->dg->params.size())
|
2013-08-22 20:55:33 +02:00
|
|
|
{
|
2014-08-19 19:14:48 +02:00
|
|
|
return pContext->ThrowNativeError("Invalid param number %i max params is %i", params[2], paramStruct->dg->params.size());
|
2013-08-22 20:55:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int index = params[2] - 1;
|
|
|
|
|
2014-08-19 19:14:48 +02:00
|
|
|
HookParamType type = paramStruct->dg->params.at(index).type;
|
2013-08-22 20:55:33 +02:00
|
|
|
|
|
|
|
//Check that the type is ptr
|
|
|
|
if(type == HookParamType_StringPtr || type == HookParamType_CharPtr || type == HookParamType_VectorPtr || type == HookParamType_CBaseEntity || type == HookParamType_ObjectPtr || type == HookParamType_Edict || type == HookParamType_Unknown)
|
|
|
|
return (paramStruct->orgParams[index] == NULL);
|
|
|
|
else
|
|
|
|
return pContext->ThrowNativeError("Param is not a pointer!");
|
|
|
|
}
|
|
|
|
|
2013-08-19 17:07:25 +02:00
|
|
|
sp_nativeinfo_t g_Natives[] =
|
|
|
|
{
|
|
|
|
{"DHookCreate", Native_CreateHook},
|
2016-12-12 06:02:10 +01:00
|
|
|
{"DHookCreateDetour", Native_CreateDetour},
|
2018-01-25 17:18:30 +01:00
|
|
|
{"DHookCreateFromConf", Native_DHookCreateFromConf},
|
|
|
|
{"DHookSetFromConf", Native_SetFromConf},
|
2013-08-19 17:07:25 +02:00
|
|
|
{"DHookAddParam", Native_AddParam},
|
2016-12-12 06:02:10 +01:00
|
|
|
{"DHookEnableDetour", Native_EnableDetour},
|
2018-01-25 17:18:30 +01:00
|
|
|
{"DHookDisableDetour", Native_DisableDetour},
|
2013-08-19 17:07:25 +02:00
|
|
|
{"DHookEntity", Native_HookEntity},
|
2013-08-22 04:18:52 +02:00
|
|
|
{"DHookGamerules", Native_HookGamerules},
|
2013-08-19 17:07:25 +02:00
|
|
|
{"DHookRaw", Native_HookRaw},
|
2013-08-22 04:18:52 +02:00
|
|
|
{"DHookRemoveHookID", Native_RemoveHookID},
|
2013-08-19 17:07:25 +02:00
|
|
|
{"DHookGetParam", Native_GetParam},
|
|
|
|
{"DHookGetReturn", Native_GetReturn},
|
|
|
|
{"DHookSetReturn", Native_SetReturn},
|
2013-08-22 04:18:52 +02:00
|
|
|
{"DHookSetParam", Native_SetParam},
|
2013-08-23 20:29:01 +02:00
|
|
|
{"DHookGetParamVector", Native_GetParamVector},
|
2013-08-28 20:20:20 +02:00
|
|
|
{"DHookGetReturnVector", Native_GetReturnVector},
|
|
|
|
{"DHookSetReturnVector", Native_SetReturnVector},
|
2013-08-23 20:29:01 +02:00
|
|
|
{"DHookSetParamVector", Native_SetParamVector},
|
2013-08-19 17:07:25 +02:00
|
|
|
{"DHookGetParamString", Native_GetParamString},
|
2013-08-22 22:14:32 +02:00
|
|
|
{"DHookGetReturnString", Native_GetReturnString},
|
|
|
|
{"DHookSetReturnString", Native_SetReturnString},
|
2013-08-19 17:07:25 +02:00
|
|
|
{"DHookSetParamString", Native_SetParamString},
|
2013-08-22 20:55:33 +02:00
|
|
|
{"DHookAddEntityListener", Native_AddEntityListener},
|
2013-08-19 17:07:25 +02:00
|
|
|
{"DHookRemoveEntityListener", Native_RemoveEntityListener},
|
2013-08-27 04:19:05 +02:00
|
|
|
{"DHookGetParamObjectPtrVar", Native_GetParamObjectPtrVar},
|
2013-08-19 17:07:25 +02:00
|
|
|
{"DHookSetParamObjectPtrVar", Native_SetParamObjectPtrVar},
|
|
|
|
{"DHookGetParamObjectPtrVarVector", Native_GetParamObjectPtrVarVector},
|
2013-08-27 04:19:05 +02:00
|
|
|
{"DHookSetParamObjectPtrVarVector", Native_SetParamObjectPtrVarVector},
|
|
|
|
{"DHookGetParamObjectPtrString", Native_GetParamObjectPtrString},
|
2013-08-22 20:55:33 +02:00
|
|
|
{"DHookIsNullParam", Native_IsNullParam},
|
2013-08-27 04:19:05 +02:00
|
|
|
{NULL, NULL}
|
2013-08-20 04:33:44 +02:00
|
|
|
};
|