mirror of
https://github.com/alliedmodders/sourcemod.git
synced 2025-12-07 02:18:35 +00:00
Finish DHookParam implem
This commit is contained in:
parent
ec23b35725
commit
c3f798d065
@ -23,7 +23,8 @@ void JIT_Recall(AsmJit& jit, bool save_general_register[MAX_GENERAL_REGISTERS],
|
|||||||
|
|
||||||
Capsule::Capsule(void* address, sp::CallingConvention conv, const std::vector<Variable>& params, const ReturnVariable& ret) :
|
Capsule::Capsule(void* address, sp::CallingConvention conv, const std::vector<Variable>& params, const ReturnVariable& ret) :
|
||||||
_parameters(params),
|
_parameters(params),
|
||||||
_return(ret) {
|
_return(ret),
|
||||||
|
_call_conv(conv) {
|
||||||
if (!abi::Proccess(conv, _parameters, _return, _stack_size)) {
|
if (!abi::Proccess(conv, _parameters, _return, _stack_size)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -81,6 +81,7 @@ public:
|
|||||||
|
|
||||||
const std::vector<Variable>& GetParameters() const { return _parameters; };
|
const std::vector<Variable>& GetParameters() const { return _parameters; };
|
||||||
const ReturnVariable& GetReturn() const { return _return; };
|
const ReturnVariable& GetReturn() const { return _return; };
|
||||||
|
const sp::CallingConvention GetCallConv() const { return _call_conv; };
|
||||||
protected:
|
protected:
|
||||||
//void JIT_SaveRegisters(AsmJit& jit);
|
//void JIT_SaveRegisters(AsmJit& jit);
|
||||||
void JIT_RestoreRegisters(AsmJit& jit);
|
void JIT_RestoreRegisters(AsmJit& jit);
|
||||||
@ -118,6 +119,9 @@ protected:
|
|||||||
|
|
||||||
std::unordered_set<HookCallback*> _pre_hooks;
|
std::unordered_set<HookCallback*> _pre_hooks;
|
||||||
std::unordered_set<HookCallback*> _post_hooks;
|
std::unordered_set<HookCallback*> _post_hooks;
|
||||||
|
|
||||||
|
// Only for dhook natives
|
||||||
|
sp::CallingConvention _call_conv;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename RETURN>
|
template<typename RETURN>
|
||||||
|
|||||||
@ -83,6 +83,20 @@ inline ParamReturn* Get(SourcePawn::IPluginContext* context, const cell_t param)
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline cell_t GetParam(SourcePawn::IPluginContext* context, ParamReturn* obj, const cell_t param) {
|
||||||
|
int index = param - 1;
|
||||||
|
if (obj->GetCapsule()->GetCallConv() == sp::CallConv_THISCALL) {
|
||||||
|
// Skip the |this| ptr parameter
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param <= 0 || index >= obj->GetCapsule()->GetParameters().size()) {
|
||||||
|
context->ThrowNativeError("Invalid param number %i max params is %i", param, obj->GetCapsule()->GetParameters().size() - ((obj->GetCapsule()->GetCallConv() == sp::CallConv_THISCALL) ? 1 : 0));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
cell_t DHookReturn_GetReturn(SourcePawn::IPluginContext* context, const cell_t* params) {
|
cell_t DHookReturn_GetReturn(SourcePawn::IPluginContext* context, const cell_t* params) {
|
||||||
auto obj = Get(context, params[1]);
|
auto obj = Get(context, params[1]);
|
||||||
if (obj == nullptr) {
|
if (obj == nullptr) {
|
||||||
@ -178,7 +192,7 @@ cell_t DHookReturn_GetReturnVector(SourcePawn::IPluginContext* context, const ce
|
|||||||
static void FreeChangedVector(void* data) {
|
static void FreeChangedVector(void* data) {
|
||||||
delete (sdk::Vector*)data;
|
delete (sdk::Vector*)data;
|
||||||
}
|
}
|
||||||
cell_t Native_SetReturnVector(SourcePawn::IPluginContext* context, const cell_t* params) {
|
cell_t DHookReturn_SetReturnVector(SourcePawn::IPluginContext* context, const cell_t* params) {
|
||||||
auto obj = Get(context, params[1]);
|
auto obj = Get(context, params[1]);
|
||||||
if (obj == nullptr) {
|
if (obj == nullptr) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -202,6 +216,532 @@ cell_t Native_SetReturnVector(SourcePawn::IPluginContext* context, const cell_t*
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cell_t DHookReturn_GetReturnString(SourcePawn::IPluginContext* context, const cell_t* params) {
|
||||||
|
auto obj = Get(context, params[1]);
|
||||||
|
if (obj == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& ret = obj->GetCapsule()->GetReturn();
|
||||||
|
switch (ret.dhook_type) {
|
||||||
|
case sp::ReturnType_String:
|
||||||
|
context->StringToLocal(params[2], params[3], obj->GetReturn<sdk::string_t>()->ToCStr());
|
||||||
|
return 1;
|
||||||
|
case sp::ReturnType_StringPtr:
|
||||||
|
context->StringToLocal(params[2], params[3], (obj->GetReturn<sdk::string_t*>() != nullptr) ? (*obj->GetReturn<sdk::string_t*>())->ToCStr() : "");
|
||||||
|
return 1;
|
||||||
|
case sp::ReturnType_CharPtr:
|
||||||
|
context->StringToLocal(params[2], params[3], (*(obj->GetReturn<const char*>()) == nullptr) ? "" : *(obj->GetReturn<const char*>()));
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
return context->ThrowNativeError("Invalid param type to get. Param is not a string.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FreeChangedCharPtr(void* data) {
|
||||||
|
delete[] (const char*)data;
|
||||||
|
}
|
||||||
|
cell_t DHookReturn_SetReturnString(SourcePawn::IPluginContext* context, const cell_t* params) {
|
||||||
|
auto obj = Get(context, params[1]);
|
||||||
|
if (obj == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& ret = obj->GetCapsule()->GetReturn();
|
||||||
|
|
||||||
|
char *value;
|
||||||
|
context->LocalToString(params[2], &value);
|
||||||
|
|
||||||
|
switch (ret.dhook_type) {
|
||||||
|
case sp::ReturnType_CharPtr: {
|
||||||
|
auto new_str = new char[strlen(value) + 1];
|
||||||
|
strcpy(new_str, value);
|
||||||
|
*(obj->GetReturn<const char*>()) = new_str;
|
||||||
|
// Free it later (cheaply) after the function returned.
|
||||||
|
globals::sourcemod->AddFrameAction(FreeChangedCharPtr, new_str);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return context->ThrowNativeError("Invalid param type to get. Param is not a char pointer.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t DHookParam_GetParam(SourcePawn::IPluginContext* context, const cell_t* params) {
|
||||||
|
auto obj = Get(context, params[1]);
|
||||||
|
if (obj == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params[2] == 0) {
|
||||||
|
return obj->GetCapsule()->GetParameters().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = GetParam(context, obj, params[2]);
|
||||||
|
if (index == -1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& var = obj->GetCapsule()->GetParameters()[index];
|
||||||
|
if (sp::HookParamTypeIsPtr(var.dhook_type) && *obj->Get<void*>(index) == nullptr) {
|
||||||
|
return context->ThrowNativeError("Trying to get value for null pointer.");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(var.dhook_type) {
|
||||||
|
case sp::HookParamType_Int:
|
||||||
|
return *obj->Get<int>(index);
|
||||||
|
case sp::HookParamType_Bool:
|
||||||
|
return (*obj->Get<bool>(index)) ? 1 : 0;
|
||||||
|
case sp::HookParamType_CBaseEntity:
|
||||||
|
return globals::gamehelpers->EntityToBCompatRef(*obj->Get<CBaseEntity*>(index));
|
||||||
|
case sp::HookParamType_Edict:
|
||||||
|
return globals::gamehelpers->IndexOfEdict(*obj->Get<edict_t*>(index));
|
||||||
|
case sp::HookParamType_Float:
|
||||||
|
return sp_ftoc(*obj->Get<float>(index));
|
||||||
|
default:
|
||||||
|
return context->ThrowNativeError("Invalid param type (%i) to get", var.dhook_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t DHookParam_SetParam(SourcePawn::IPluginContext* context, const cell_t* params) {
|
||||||
|
auto obj = Get(context, params[1]);
|
||||||
|
if (obj == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = GetParam(context, obj, params[2]);
|
||||||
|
if (index == -1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& var = obj->GetCapsule()->GetParameters()[index];
|
||||||
|
switch (var.dhook_type) {
|
||||||
|
case sp::HookParamType_Int:
|
||||||
|
*obj->Get<int>(index) = params[3];
|
||||||
|
break;
|
||||||
|
case sp::HookParamType_Bool:
|
||||||
|
*obj->Get<bool>(index) = (params[3] ? true : false);
|
||||||
|
break;
|
||||||
|
case sp::HookParamType_CBaseEntity: {
|
||||||
|
CBaseEntity* entity = globals::gamehelpers->ReferenceToEntity(params[3]);
|
||||||
|
|
||||||
|
if (params[3] != -1 && entity == nullptr) {
|
||||||
|
return context->ThrowNativeError("Invalid entity reference passed for param value");
|
||||||
|
}
|
||||||
|
|
||||||
|
*obj->Get<CBaseEntity*>(index) = entity;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case sp::HookParamType_Edict: {
|
||||||
|
sdk::edict_t* edict = reinterpret_cast<sdk::edict_t*>(globals::gamehelpers->EdictOfIndex(params[3]));
|
||||||
|
|
||||||
|
if (params[3] != -1 && (edict == nullptr || edict->IsFree())) {
|
||||||
|
return context->ThrowNativeError("Invalid edict index passed for param value");
|
||||||
|
}
|
||||||
|
|
||||||
|
*obj->Get<sdk::edict_t*>(index) = edict;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case sp::HookParamType_Float:
|
||||||
|
*obj->Get<float>(index) = sp_ctof(params[3]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return context->ThrowNativeError("Invalid param type (%i) to set", var.dhook_type);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t DHookParam_GetParamVector(SourcePawn::IPluginContext* context, const cell_t* params) {
|
||||||
|
auto obj = Get(context, params[1]);
|
||||||
|
if (obj == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = GetParam(context, obj, params[2]);
|
||||||
|
if (index == -1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& var = obj->GetCapsule()->GetParameters()[index];
|
||||||
|
if (var.dhook_type == sp::HookParamType_VectorPtr) {
|
||||||
|
cell_t* buffer;
|
||||||
|
context->LocalToPhysAddr(params[3], &buffer);
|
||||||
|
|
||||||
|
auto vec = *obj->Get<sdk::Vector*>(index);
|
||||||
|
if (vec == nullptr) {
|
||||||
|
return context->ThrowNativeError("Trying to get value for null pointer.");
|
||||||
|
}
|
||||||
|
buffer[0] = sp_ftoc(vec->x);
|
||||||
|
buffer[1] = sp_ftoc(vec->y);
|
||||||
|
buffer[2] = sp_ftoc(vec->z);
|
||||||
|
} else {
|
||||||
|
return context->ThrowNativeError("Invalid param type to get. Param is not a vector.");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t DHookParam_SetParamVector(SourcePawn::IPluginContext* context, const cell_t* params) {
|
||||||
|
auto obj = Get(context, params[1]);
|
||||||
|
if (obj == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = GetParam(context, obj, params[2]);
|
||||||
|
if (index == -1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& var = obj->GetCapsule()->GetParameters()[index];
|
||||||
|
if (var.dhook_type == sp::HookParamType_VectorPtr) {
|
||||||
|
cell_t* buffer;
|
||||||
|
context->LocalToPhysAddr(params[3], &buffer);
|
||||||
|
|
||||||
|
auto vec = *obj->Get<sdk::Vector*>(index);
|
||||||
|
if (vec == nullptr) {
|
||||||
|
vec = new sdk::Vector;
|
||||||
|
globals::sourcemod->AddFrameAction(FreeChangedVector, vec);
|
||||||
|
*obj->Get<sdk::Vector*>(index) = vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec->x = sp_ctof(buffer[0]);
|
||||||
|
vec->y = sp_ctof(buffer[1]);
|
||||||
|
vec->z = sp_ctof(buffer[2]);
|
||||||
|
} else {
|
||||||
|
return context->ThrowNativeError("Invalid param type to set. Param is not a vector.");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t DHookParam_GetParamString(SourcePawn::IPluginContext* context, const cell_t* params) {
|
||||||
|
auto obj = Get(context, params[1]);
|
||||||
|
if (obj == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = GetParam(context, obj, params[2]);
|
||||||
|
if (index == -1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& var = obj->GetCapsule()->GetParameters()[index];
|
||||||
|
if (sp::HookParamTypeIsPtr(var.dhook_type) && *obj->Get<void*>(index) == nullptr) {
|
||||||
|
return context->ThrowNativeError("Trying to get value for null pointer.");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (var.dhook_type) {
|
||||||
|
case sp::HookParamType_CharPtr: {
|
||||||
|
auto str = *obj->Get<const char*>(index);
|
||||||
|
context->StringToLocal(params[3], params[4], str);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case sp::HookParamType_String: {
|
||||||
|
auto str = *obj->Get<sdk::string_t>(index);
|
||||||
|
context->StringToLocal(params[3], params[4], str.ToCStr());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case sp::HookParamType_StringPtr: {
|
||||||
|
auto str = *obj->Get<sdk::string_t*>(index);
|
||||||
|
context->StringToLocal(params[3], params[4], str->ToCStr());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return context->ThrowNativeError("Invalid param type to get. Param is not a string.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t DHookParam_SetParamString(SourcePawn::IPluginContext* context, const cell_t* params) {
|
||||||
|
auto obj = Get(context, params[1]);
|
||||||
|
if (obj == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = GetParam(context, obj, params[2]);
|
||||||
|
if (index == -1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* value;
|
||||||
|
context->LocalToString(params[3], &value);
|
||||||
|
|
||||||
|
const auto& var = obj->GetCapsule()->GetParameters()[index];
|
||||||
|
if (var.dhook_type == sp::HookParamType_CharPtr) {
|
||||||
|
auto str = new char[strlen(value) + 1];
|
||||||
|
strcpy(str, value);
|
||||||
|
*obj->Get<const char*>(index) = str;
|
||||||
|
// Free it later (cheaply) after the function returned.
|
||||||
|
globals::sourcemod->AddFrameAction(FreeChangedCharPtr, str);
|
||||||
|
} else if (var.dhook_type == sp::HookParamType_String || var.dhook_type == sp::HookParamType_StringPtr) {
|
||||||
|
return context->ThrowNativeError("DHooks currently lacks support for setting string_t. Pull requests are welcome!");
|
||||||
|
} else {
|
||||||
|
return context->ThrowNativeError("Invalid param type to set. Param is not a string.");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t Native_GetParamObjectPtrVar(SourcePawn::IPluginContext* context, const cell_t* params) {
|
||||||
|
auto obj = Get(context, params[1]);
|
||||||
|
if (obj == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = GetParam(context, obj, params[2]);
|
||||||
|
if (index == -1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& var = obj->GetCapsule()->GetParameters()[index];
|
||||||
|
if (var.dhook_type != sp::HookParamType_ObjectPtr && var.dhook_type != sp::HookParamType_Object) {
|
||||||
|
return context->ThrowNativeError("Invalid object value type %i", var.dhook_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint8_t* object = obj->Get<std::uint8_t>(index);
|
||||||
|
if (var.dhook_type == sp::HookParamType_ObjectPtr) {
|
||||||
|
object = *(std::uint8_t**)object;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch((sp::ObjectValueType)params[4]) {
|
||||||
|
case sp::ObjectValueType_Int:
|
||||||
|
return *(int *)(object + params[3]);
|
||||||
|
case sp::ObjectValueType_Bool:
|
||||||
|
return (*(bool *)(object + params[3])) ? 1 : 0;
|
||||||
|
case sp::ObjectValueType_Ehandle: {
|
||||||
|
auto edict = reinterpret_cast<sdk::edict_t*>(globals::gamehelpers->GetHandleEntity(*(CBaseHandle *)(object + params[3])));
|
||||||
|
if (edict == nullptr || edict->IsFree()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return globals::gamehelpers->IndexOfEdict(reinterpret_cast<edict_t*>(edict));
|
||||||
|
}
|
||||||
|
case sp::ObjectValueType_EhandlePtr: {
|
||||||
|
auto edict = reinterpret_cast<sdk::edict_t*>(globals::gamehelpers->GetHandleEntity(**(CBaseHandle **)(object + params[3])));
|
||||||
|
if (edict == nullptr || edict->IsFree()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return globals::gamehelpers->IndexOfEdict(reinterpret_cast<edict_t*>(edict));
|
||||||
|
}
|
||||||
|
case sp::ObjectValueType_Float:
|
||||||
|
return sp_ftoc(*(float *)(object + params[3]));
|
||||||
|
// This is technically incorrect and doesn't follow the "convention" that CBaseEntity is always a pointer for plugins
|
||||||
|
// Therefore this should be a pointer of pointer (i.e a triple pointer when offseted to it). But it isn't....
|
||||||
|
case sp::ObjectValueType_CBaseEntityPtr:
|
||||||
|
return globals::gamehelpers->EntityToBCompatRef(*(CBaseEntity **)(object + params[3]));
|
||||||
|
case sp::ObjectValueType_IntPtr:
|
||||||
|
return **(int **)(object + params[3]);
|
||||||
|
case sp::ObjectValueType_BoolPtr:
|
||||||
|
return (**(bool **)(object + params[3])) ? 1 : 0;
|
||||||
|
case sp::ObjectValueType_FloatPtr:
|
||||||
|
return sp_ftoc(**(float **)(object + params[3]));
|
||||||
|
default:
|
||||||
|
return context->ThrowNativeError("Invalid Object value type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t DHookParam_SetParamObjectPtrVar(SourcePawn::IPluginContext* context, const cell_t* params) {
|
||||||
|
auto obj = Get(context, params[1]);
|
||||||
|
if (obj == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = GetParam(context, obj, params[2]);
|
||||||
|
if (index == -1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& var = obj->GetCapsule()->GetParameters()[index];
|
||||||
|
if (var.dhook_type != sp::HookParamType_ObjectPtr && var.dhook_type != sp::HookParamType_Object) {
|
||||||
|
return context->ThrowNativeError("Invalid object value type %i", var.dhook_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint8_t* object = obj->Get<std::uint8_t>(index);
|
||||||
|
if (var.dhook_type == sp::HookParamType_ObjectPtr) {
|
||||||
|
object = *(std::uint8_t**)object;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch((sp::ObjectValueType)params[4]) {
|
||||||
|
case sp::ObjectValueType_Int:
|
||||||
|
*(int *)(object + params[3]) = params[5];
|
||||||
|
break;
|
||||||
|
case sp::ObjectValueType_Bool:
|
||||||
|
*(bool *)(object + params[3]) = params[5] != 0;
|
||||||
|
break;
|
||||||
|
case sp::ObjectValueType_Ehandle:
|
||||||
|
globals::gamehelpers->SetHandleEntity(*(CBaseHandle *)(object + params[3]), globals::gamehelpers->EdictOfIndex(params[5]));
|
||||||
|
break;
|
||||||
|
case sp::ObjectValueType_EhandlePtr:
|
||||||
|
globals::gamehelpers->SetHandleEntity(**(CBaseHandle **)(object + params[3]), globals::gamehelpers->EdictOfIndex(params[5]));
|
||||||
|
break;
|
||||||
|
case sp::ObjectValueType_Float:
|
||||||
|
*(float *)(object + params[3]) = sp_ctof(params[5]);
|
||||||
|
break;
|
||||||
|
// This is technically incorrect and doesn't follow the "convention" that CBaseEntity is always a pointer for plugins
|
||||||
|
// Therefore this should be a pointer of pointer (i.e a triple pointer when offseted to it). But it isn't....
|
||||||
|
case sp::ObjectValueType_CBaseEntityPtr: {
|
||||||
|
CBaseEntity* entity = globals::gamehelpers->ReferenceToEntity(params[5]);
|
||||||
|
|
||||||
|
if (params[5] != -1 && entity == nullptr) {
|
||||||
|
return context->ThrowNativeError("Invalid entity passed");
|
||||||
|
}
|
||||||
|
|
||||||
|
*(CBaseEntity **)(object + params[3]) = entity;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case sp::ObjectValueType_IntPtr:
|
||||||
|
**(int **)(object + params[3]) = params[5];
|
||||||
|
break;
|
||||||
|
case sp::ObjectValueType_BoolPtr:
|
||||||
|
**(int **)(object + params[3]) = params[5] != 0;
|
||||||
|
break;
|
||||||
|
case sp::ObjectValueType_FloatPtr:
|
||||||
|
**(float **)(object + params[3]) = sp_ctof(params[5]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return context->ThrowNativeError("Invalid Object value type");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t DHookParam_GetParamObjectPtrVarVector(SourcePawn::IPluginContext* context, const cell_t* params) {
|
||||||
|
auto obj = Get(context, params[1]);
|
||||||
|
if (obj == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = GetParam(context, obj, params[2]);
|
||||||
|
if (index == -1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& var = obj->GetCapsule()->GetParameters()[index];
|
||||||
|
if (var.dhook_type != sp::HookParamType_ObjectPtr && var.dhook_type != sp::HookParamType_Object) {
|
||||||
|
return context->ThrowNativeError("Invalid object value type %i", var.dhook_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint8_t* object = obj->Get<std::uint8_t>(index);
|
||||||
|
if (var.dhook_type == sp::HookParamType_ObjectPtr) {
|
||||||
|
object = *(std::uint8_t**)object;
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t *buffer;
|
||||||
|
context->LocalToPhysAddr(params[5], &buffer);
|
||||||
|
|
||||||
|
if ((sp::ObjectValueType)params[4] == sp::ObjectValueType_VectorPtr || (sp::ObjectValueType)params[4] == sp::ObjectValueType_Vector) {
|
||||||
|
sdk::Vector* vec = (sdk::Vector*)(object + params[3]);
|
||||||
|
|
||||||
|
if ((sp::ObjectValueType)params[4] == sp::ObjectValueType_VectorPtr) {
|
||||||
|
vec = *(sdk::Vector**)vec;
|
||||||
|
if (vec == nullptr) {
|
||||||
|
return context->ThrowNativeError("Trying to get value for null pointer.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[0] = sp_ftoc(vec->x);
|
||||||
|
buffer[1] = sp_ftoc(vec->y);
|
||||||
|
buffer[2] = sp_ftoc(vec->z);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return context->ThrowNativeError("Invalid Object value type (not a type of vector)");
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t DHookParam_SetParamObjectPtrVarVector(SourcePawn::IPluginContext* context, const cell_t* params) {
|
||||||
|
auto obj = Get(context, params[1]);
|
||||||
|
if (obj == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = GetParam(context, obj, params[2]);
|
||||||
|
if (index == -1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& var = obj->GetCapsule()->GetParameters()[index];
|
||||||
|
if (var.dhook_type != sp::HookParamType_ObjectPtr && var.dhook_type != sp::HookParamType_Object) {
|
||||||
|
return context->ThrowNativeError("Invalid object value type %i", var.dhook_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint8_t* object = obj->Get<std::uint8_t>(index);
|
||||||
|
if (var.dhook_type == sp::HookParamType_ObjectPtr) {
|
||||||
|
object = *(std::uint8_t**)object;
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t *buffer;
|
||||||
|
context->LocalToPhysAddr(params[5], &buffer);
|
||||||
|
|
||||||
|
if((sp::ObjectValueType)params[4] == sp::ObjectValueType_VectorPtr || (sp::ObjectValueType)params[4] == sp::ObjectValueType_Vector) {
|
||||||
|
sdk::Vector* vec = (sdk::Vector*)(object + params[3]);
|
||||||
|
|
||||||
|
if ((sp::ObjectValueType)params[4] == sp::ObjectValueType_VectorPtr) {
|
||||||
|
vec = *(sdk::Vector**)vec;
|
||||||
|
if (vec == nullptr) {
|
||||||
|
return context->ThrowNativeError("Trying to set value for null pointer.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vec->x = sp_ctof(buffer[0]);
|
||||||
|
vec->y = sp_ctof(buffer[1]);
|
||||||
|
vec->z = sp_ctof(buffer[2]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return context->ThrowNativeError("Invalid Object value type (not a type of vector)");
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t DHookParam_GetParamObjectPtrString(SourcePawn::IPluginContext* context, const cell_t* params) {
|
||||||
|
auto obj = Get(context, params[1]);
|
||||||
|
if (obj == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = GetParam(context, obj, params[2]);
|
||||||
|
if (index == -1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& var = obj->GetCapsule()->GetParameters()[index];
|
||||||
|
if (var.dhook_type != sp::HookParamType_ObjectPtr && var.dhook_type != sp::HookParamType_Object) {
|
||||||
|
return context->ThrowNativeError("Invalid object value type %i", var.dhook_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint8_t* object = obj->Get<std::uint8_t>(index);
|
||||||
|
if (var.dhook_type == sp::HookParamType_ObjectPtr) {
|
||||||
|
object = *(std::uint8_t**)object;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
switch((sp::ObjectValueType)params[4]) {
|
||||||
|
case sp::ObjectValueType_CharPtr: {
|
||||||
|
char *ptr = *(char **)(object + params[3]);
|
||||||
|
context->StringToLocal(params[5], params[6], ptr == NULL ? "" : (const char *)ptr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case sp::ObjectValueType_String: {
|
||||||
|
auto str = *(sdk::string_t *)(object + params[3]);
|
||||||
|
context->StringToLocal(params[5], params[6], str.ToCStr());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return context->ThrowNativeError("Invalid Object value type (not a type of string)");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t DHookParam_IsNullParam(SourcePawn::IPluginContext* context, const cell_t* params) {
|
||||||
|
auto obj = Get(context, params[1]);
|
||||||
|
if (obj == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = GetParam(context, obj, params[2]);
|
||||||
|
if (index == -1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& var = obj->GetCapsule()->GetParameters()[index];
|
||||||
|
if (sp::HookParamTypeIsPtr(var.dhook_type)) {
|
||||||
|
return (*obj->Get<void*>(index) != nullptr) ? 1 : 0;
|
||||||
|
}
|
||||||
|
return context->ThrowNativeError("Param is not a pointer!");
|
||||||
|
}
|
||||||
|
|
||||||
/*void foo() {
|
/*void foo() {
|
||||||
{
|
{
|
||||||
{"DHookGetParam", DHookParam_GetParam},
|
{"DHookGetParam", DHookParam_GetParam},
|
||||||
@ -217,16 +757,16 @@ cell_t Native_SetReturnVector(SourcePawn::IPluginContext* context, const cell_t*
|
|||||||
{"DHookGetParamObjectPtrString", DHookParam_GetParamObjectPtrString},
|
{"DHookGetParamObjectPtrString", DHookParam_GetParamObjectPtrString},
|
||||||
{"DHookIsNullParam", DHookParam_IsNullParam}
|
{"DHookIsNullParam", DHookParam_IsNullParam}
|
||||||
{"DHookParam.Get", DHookParam_GetParam},
|
{"DHookParam.Get", DHookParam_GetParam},
|
||||||
{"DHookParam.GetVector", DHookParam_GetParamVector},
|
|
||||||
{"DHookParam.GetString", DHookParam_GetParamString},
|
|
||||||
{"DHookParam.Set", DHookParam_SetParam},
|
{"DHookParam.Set", DHookParam_SetParam},
|
||||||
|
{"DHookParam.GetVector", DHookParam_GetParamVector},
|
||||||
{"DHookParam.SetVector", DHookParam_SetParamVector},
|
{"DHookParam.SetVector", DHookParam_SetParamVector},
|
||||||
|
{"DHookParam.GetString", DHookParam_GetParamString},
|
||||||
{"DHookParam.SetString", DHookParam_SetParamString},
|
{"DHookParam.SetString", DHookParam_SetParamString},
|
||||||
{"DHookParam.GetObjectVar", DHookParam_GetParamObjectPtrVar},
|
{"DHookParam.GetObjectVar", DHookParam_GetParamObjectPtrVar},
|
||||||
{"DHookParam.GetObjectVarVector", DHookParam_GetParamObjectPtrVarVector},
|
|
||||||
{"DHookParam.GetObjectVarString", DHookParam_GetParamObjectPtrString},
|
|
||||||
{"DHookParam.SetObjectVar", DHookParam_SetParamObjectPtrVar},
|
{"DHookParam.SetObjectVar", DHookParam_SetParamObjectPtrVar},
|
||||||
|
{"DHookParam.GetObjectVarVector", DHookParam_GetParamObjectPtrVarVector},
|
||||||
{"DHookParam.SetObjectVarVector", DHookParam_SetParamObjectPtrVarVector},
|
{"DHookParam.SetObjectVarVector", DHookParam_SetParamObjectPtrVarVector},
|
||||||
|
{"DHookParam.GetObjectVarString", DHookParam_GetParamObjectPtrString},
|
||||||
{"DHookParam.IsNull", DHookParam_IsNullParam},
|
{"DHookParam.IsNull", DHookParam_IsNullParam},
|
||||||
|
|
||||||
{"DHookGetReturn", DHookReturn_GetReturn},
|
{"DHookGetReturn", DHookReturn_GetReturn},
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
namespace sdk {
|
namespace sdk {
|
||||||
|
|
||||||
class CBaseEntity;
|
class CBaseEntity;
|
||||||
@ -32,6 +34,7 @@ public:
|
|||||||
float z;
|
float z;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static constexpr std::uintptr_t NULL_STRING = 0;
|
||||||
struct string_t
|
struct string_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@ -33,6 +33,10 @@ enum HookParamType
|
|||||||
HookParamType_Object
|
HookParamType_Object
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline bool HookParamTypeIsPtr(HookParamType type) {
|
||||||
|
return (type == HookParamType_StringPtr || type == HookParamType_CharPtr || type == HookParamType_VectorPtr || type == HookParamType_CBaseEntity || type == HookParamType_ObjectPtr || type == HookParamType_Edict);
|
||||||
|
}
|
||||||
|
|
||||||
enum ReturnType
|
enum ReturnType
|
||||||
{
|
{
|
||||||
ReturnType_Unknown,
|
ReturnType_Unknown,
|
||||||
@ -98,4 +102,21 @@ enum DHookRegister
|
|||||||
DHookRegister_ST0
|
DHookRegister_ST0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ObjectValueType
|
||||||
|
{
|
||||||
|
ObjectValueType_Int = 0,
|
||||||
|
ObjectValueType_Bool,
|
||||||
|
ObjectValueType_Ehandle,
|
||||||
|
ObjectValueType_Float,
|
||||||
|
ObjectValueType_CBaseEntityPtr,
|
||||||
|
ObjectValueType_IntPtr,
|
||||||
|
ObjectValueType_BoolPtr,
|
||||||
|
ObjectValueType_EhandlePtr,
|
||||||
|
ObjectValueType_FloatPtr,
|
||||||
|
ObjectValueType_Vector,
|
||||||
|
ObjectValueType_VectorPtr,
|
||||||
|
ObjectValueType_CharPtr,
|
||||||
|
ObjectValueType_String
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user