Added return type modification / retrieval.

Added HAM_{IGNORED,HANDLED,OVERRIDE,SUPERCEDE} to include file.

Added the ability to disable and re-enable hooks.
This commit is contained in:
Steve Dudenhoeffer 2007-05-08 17:26:51 +00:00
parent 4e2493759e
commit f747acdc7c
11 changed files with 906 additions and 58 deletions

View File

@ -129,7 +129,7 @@ public:
}
//Added this for amxx inclusion
bool empty()
bool empty() const
{
if (!v)
return true;
@ -140,7 +140,7 @@ public:
return false;
}
size_t size()
size_t size() const
{
if (v)
return strlen(v);

View File

@ -0,0 +1,183 @@
#include "sdk/amxxmodule.h"
#include "CVector.h"
#include "CString.h"
#include "sh_stack.h"
#include "DataHandler.h"
#include "ham_const.h"
#include "ham_utils.h"
#include "NEW_Util.h"
CStack< Data * > ReturnStack;
CStack< Data * > OrigReturnStack;
CStack< CVector< Data * > * > ParamStack;
#define CHECK_STACK(__STACK__) \
if ( ( __STACK__ ).size() <= 0) \
{ \
MF_LogError(amx, AMX_ERR_NATIVE, "%s is empty!", #__STACK__); \
return 0; \
}
#define PARSE_RETURN() \
if (ret==-2) \
{ \
MF_LogError(amx, AMX_ERR_NATIVE, "Data pointer is NULL!"); \
} \
else if (ret==-1) \
{ \
MF_LogError(amx, AMX_ERR_NATIVE, "Wrong data type (data is of type %s)", returntypes[dat->GetType()]); \
} \
return ret
static const char *returntypes[] =
{
"void",
"integer",
"float",
"vector",
"string",
"cbase",
};
static cell AMX_NATIVE_CALL GetHamReturnInteger(AMX *amx, cell *params)
{
CHECK_STACK(ReturnStack);
Data *dat=ReturnStack.front();
int ret=dat->GetInt(MF_GetAmxAddr(amx, params[1]));
PARSE_RETURN();
}
static cell AMX_NATIVE_CALL GetOrigHamReturnInteger(AMX *amx, cell *params)
{
CHECK_STACK(OrigReturnStack);
Data *dat=OrigReturnStack.front();
int ret=dat->GetInt(MF_GetAmxAddr(amx, params[1]));
PARSE_RETURN();
}
static cell AMX_NATIVE_CALL GetHamReturnFloat(AMX *amx, cell *params)
{
CHECK_STACK(ReturnStack);
Data *dat=ReturnStack.front();
int ret=dat->GetFloat(MF_GetAmxAddr(amx, params[1]));
PARSE_RETURN();
}
static cell AMX_NATIVE_CALL GetOrigHamReturnFloat(AMX *amx, cell *params)
{
CHECK_STACK(OrigReturnStack);
Data *dat=OrigReturnStack.front();
int ret=dat->GetFloat(MF_GetAmxAddr(amx, params[1]));
PARSE_RETURN();
}
static cell AMX_NATIVE_CALL GetHamReturnVector(AMX *amx, cell *params)
{
CHECK_STACK(ReturnStack);
Data *dat=ReturnStack.front();
int ret=dat->GetVector(MF_GetAmxAddr(amx, params[1]));
PARSE_RETURN();
}
static cell AMX_NATIVE_CALL GetOrigHamReturnVector(AMX *amx, cell *params)
{
CHECK_STACK(OrigReturnStack);
Data *dat=OrigReturnStack.front();
int ret=dat->GetVector(MF_GetAmxAddr(amx, params[1]));
PARSE_RETURN();
}
static cell AMX_NATIVE_CALL GetHamReturnCbase(AMX *amx, cell *params)
{
CHECK_STACK(ReturnStack);
Data *dat=ReturnStack.front();
int ret=dat->GetCbase(MF_GetAmxAddr(amx, params[1]));
PARSE_RETURN();
}
static cell AMX_NATIVE_CALL GetOrigHamReturnCbase(AMX *amx, cell *params)
{
CHECK_STACK(OrigReturnStack);
Data *dat=OrigReturnStack.front();
int ret=dat->GetCbase(MF_GetAmxAddr(amx, params[1]));
PARSE_RETURN();
}
static cell AMX_NATIVE_CALL GetHamReturnString(AMX *amx, cell *params)
{
CHECK_STACK(ReturnStack);
Data *dat=ReturnStack.front();
int ret=dat->GetString(MF_GetAmxAddr(amx, params[1]), params[2]);
PARSE_RETURN();
}
static cell AMX_NATIVE_CALL GetOrigHamReturnString(AMX *amx, cell *params)
{
CHECK_STACK(OrigReturnStack);
Data *dat=OrigReturnStack.front();
int ret=dat->GetString(MF_GetAmxAddr(amx, params[1]), params[2]);
PARSE_RETURN();
}
static cell AMX_NATIVE_CALL SetHamReturnInteger(AMX *amx, cell *params)
{
CHECK_STACK(ReturnStack);
Data *dat=ReturnStack.front();
int ret=dat->SetInt(&params[1]);
PARSE_RETURN();
}
static cell AMX_NATIVE_CALL SetHamReturnFloat(AMX *amx, cell *params)
{
CHECK_STACK(ReturnStack);
Data *dat=ReturnStack.front();
int ret=dat->SetFloat(&params[1]);
PARSE_RETURN();
}
static cell AMX_NATIVE_CALL SetHamReturnVector(AMX *amx, cell *params)
{
CHECK_STACK(ReturnStack);
Data *dat=ReturnStack.front();
int ret=dat->SetVector(MF_GetAmxAddr(amx, params[1]));
PARSE_RETURN();
}
static cell AMX_NATIVE_CALL SetHamReturnCbase(AMX *amx, cell *params)
{
CHECK_STACK(ReturnStack);
Data *dat=ReturnStack.front();
int ret=dat->SetCbase(&params[1]);
PARSE_RETURN();
}
static cell AMX_NATIVE_CALL SetHamReturnString(AMX *amx, cell *params)
{
CHECK_STACK(ReturnStack);
Data *dat=ReturnStack.front();
int ret=dat->SetString(MF_GetAmxAddr(amx, params[1]));
PARSE_RETURN();
}
AMX_NATIVE_INFO ReturnNatives[] =
{
{ "GetHamReturnInteger", GetHamReturnInteger },
{ "GetHamReturnFloat", GetHamReturnFloat },
{ "GetHamReturnVector", GetHamReturnVector },
{ "GetHamReturnCbase", GetHamReturnCbase },
{ "GetHamReturnString", GetHamReturnString },
{ "GetOrigHamReturnInteger", GetOrigHamReturnInteger },
{ "GetOrigHamReturnFloat", GetOrigHamReturnFloat },
{ "GetOrigHamReturnVector", GetOrigHamReturnVector },
{ "GetOrigHamReturnCbase", GetOrigHamReturnCbase },
{ "GetOrigHamReturnString", GetOrigHamReturnString },
{ "SetHamReturnInteger", SetHamReturnInteger },
{ "SetHamReturnFloat", SetHamReturnFloat },
{ "SetHamReturnVector", SetHamReturnVector },
{ "SetHamReturnCbase", SetHamReturnCbase },
{ "SetHamReturnString", SetHamReturnString },
{ NULL, NULL },
};

View File

@ -0,0 +1,238 @@
#ifndef RETURNHANDLER_H
#define RETURNHANDLER_H
#include "ham_utils.h"
#include "CVector.h"
#include "CString.h"
#include "sh_stack.h"
enum
{
RET_VOID,
RET_INTEGER,
RET_FLOAT,
RET_VECTOR,
RET_STRING,
RET_CBASE
};
// Container for return and parameter data.
// Contains a void pointer, and a flag telling what it contains.
class Data
{
private:
void *m_data;
int m_type;
bool IsSet(void)
{
return (m_type != RET_VOID &&
m_data != NULL);
};
bool IsType(const int type)
{
return (m_type == type);
};
public:
Data() : m_data(NULL), m_type(RET_VOID)
{ /* nothing */ };
Data(int type, void *ptr) : m_data(ptr), m_type(type)
{ /* nothing */ };
~Data()
{ /* nothing */ };
int GetType()
{
return m_type;
};
// All Get/Set value natives return < 0 on failure.
// -1: Wrong type
// -2: Bad data pointer (void, etc).
int SetInt(cell *data)
{
if (!IsSet())
{
return -2;
}
if (!IsType(RET_INTEGER))
{
return -1;
}
*(reinterpret_cast<int *>(m_data))=*data;
return 0;
};
int SetFloat(cell *data)
{
if (!IsSet())
{
return -2;
}
if (!IsType(RET_FLOAT))
{
return -1;
}
*(reinterpret_cast<REAL *>(m_data))=amx_ctof2(*data);
return 0;
};
int SetVector(cell *data)
{
if (!IsSet())
{
return -2;
}
if (!IsType(RET_VECTOR))
{
return -1;
}
Vector *vec=reinterpret_cast<Vector *>(m_data);
vec->x=amx_ctof2(data[0]);
vec->y=amx_ctof2(data[1]);
vec->z=amx_ctof2(data[2]);
return 0;
};
int SetString(cell *data)
{
if (!IsSet())
{
return -2;
}
if (!IsType(RET_STRING))
{
return -1;
}
String *str=reinterpret_cast<String *>(m_data);
cell *i=data;
size_t len=0;
while (*i!=0)
{
i++;
len++;
};
char *temp=new char[len+1];
i=data;
char *j=temp;
while ((*j++=*i++)!=0)
{
/* nothing */
}
str->assign(temp);
delete[] temp;
return 0;
};
int SetCbase(cell *data)
{
if (!IsSet())
{
return -2;
}
if (!IsType(RET_CBASE))
{
return -1;
}
*(reinterpret_cast<void **>(m_data))=IndexToPrivate(*data);
return 0;
};
int GetInt(cell *data)
{
if (!IsSet())
{
return -2;
}
if (!IsType(RET_INTEGER))
{
return -1;
}
*data=*(reinterpret_cast<int *>(m_data));
return 0;
};
int GetFloat(cell *data)
{
if (!IsSet())
{
return -2;
}
if (!IsType(RET_FLOAT))
{
return -1;
}
*data=amx_ftoc2(*(reinterpret_cast<REAL *>(m_data)));
return 0;
};
int GetVector(cell *data)
{
if (!IsSet())
{
return -2;
}
if (!IsType(RET_VECTOR))
{
return -1;
}
Vector *vec=reinterpret_cast<Vector *>(m_data);
data[0]=amx_ftoc2(vec->x);
data[1]=amx_ftoc2(vec->y);
data[2]=amx_ftoc2(vec->z);
return 0;
};
int GetString(cell *data, int len)
{
if (!IsSet())
{
return -2;
}
if (!IsType(RET_STRING))
{
return -1;
}
const char *i=(reinterpret_cast<String *>(m_data)->c_str());
while (len-- &&
(*data++=*i++)!='\0')
{
/* nothing */
};
return 0;
};
int GetCbase(cell *data)
{
if (!IsSet())
{
return -2;
}
if (!IsType(RET_CBASE))
{
return -1;
}
*data=PrivateToIndex(m_data);
return 0;
}
};
extern CStack< Data * > ReturnStack;
extern CStack< Data * > OrigReturnStack;
extern CStack< CVector< Data * > * > ParamStack;
#endif

View File

@ -25,7 +25,7 @@ BIN_SUFFIX = amxx_i386.so
OBJECTS = sdk/amxxmodule.cpp amxx_api.cpp config_parser.cpp \
hook_callbacks.cpp hook_native.cpp srvcmd.cpp \
call_funcs.cpp hook_create.cpp
call_funcs.cpp hook_create.cpp DataHandler.cpp
LINK =

View File

@ -13,6 +13,7 @@ bool NEW_Initialized;
extern CVector<Hook*> hooks[HAM_LAST_ENTRY_DONT_USE_ME_LOL];
extern AMX_NATIVE_INFO RegisterNatives[];
extern AMX_NATIVE_INFO ReturnNatives[];
int ReadConfig(void);
@ -21,6 +22,7 @@ void OnAmxxAttach(void)
if (ReadConfig() > 0)
{
MF_AddNatives(RegisterNatives);
MF_AddNatives(ReturnNatives);
}
}

View File

@ -9,6 +9,8 @@
#include "CVector.h"
#include "CString.h"
#include "sh_stack.h"
#include "hook.h"
#include "forward.h"
@ -16,10 +18,21 @@
#include "ham_const.h"
#include "ham_utils.h"
#include "DataHandler.h"
extern bool gDoForwards;
#define PUSH_VOID() ReturnStack.push(new Data(RET_VOID, NULL)); OrigReturnStack.push(new Data(RET_VOID, NULL));
#define PUSH_INT() ReturnStack.push(new Data(RET_INTEGER, (void *)&ret)); OrigReturnStack.push(new Data(RET_INTEGER, (void *)&origret));
#define PUSH_FLOAT() ReturnStack.push(new Data(RET_FLOAT, (void *)&ret)); OrigReturnStack.push(new Data(RET_FLOAT, (void *)&origret));
#define PUSH_VECTOR() ReturnStack.push(new Data(RET_VECTOR, (void *)&ret)); OrigReturnStack.push(new Data(RET_VECTOR, (void *)&origret));
#define PUSH_CBASE() ReturnStack.push(new Data(RET_CBASE, (void *)&ret)); OrigReturnStack.push(new Data(RET_CBASE, (void *)&origret));
#define PUSH_STRING() ReturnStack.push(new Data(RET_STRING, (void *)&ret)); OrigReturnStack.push(new Data(RET_STRING, (void *)&origret));
#define POP() delete ReturnStack.front(); ReturnStack.pop(); delete OrigReturnStack.front(); OrigReturnStack.pop();
#define PRE_START() \
bool DoForwards=gDoForwards; \
gDoForwards=true; \
@ -65,8 +78,22 @@ extern bool gDoForwards;
}
#define CHECK_RETURN() \
if (thisresult < HAM_OVERRIDE) \
{ \
return origret; \
}
#define CHECK_RETURN_STR() \
if (thisresult < HAM_OVERRIDE) \
{ \
return origret.c_str(); \
}
void Hook_Void_Void(Hook *hook, void *pthis)
{
PUSH_VOID()
PRE_START()
PRE_END()
@ -78,29 +105,35 @@ void Hook_Void_Void(Hook *hook, void *pthis)
POST_START()
POST_END()
POP()
}
int Hook_Int_Void(Hook *hook, void *pthis)
{
int ireturn=0;
int ret=0;
int origret=0;
PUSH_INT()
PRE_START()
PRE_END()
#if defined _WIN32
ireturn=reinterpret_cast<int (__fastcall*)(void*,int)>(hook->func)(pthis,0);
origret=reinterpret_cast<int (__fastcall*)(void*,int)>(hook->func)(pthis,0);
#elif defined __linux__
ireturn=reinterpret_cast<int (*)(void*)>(hook->func)(pthis);
origret=reinterpret_cast<int (*)(void*)>(hook->func)(pthis);
#endif
POST_START()
POST_END()
return ireturn;
POP()
CHECK_RETURN()
return ret;
}
void Hook_Void_Entvar(Hook *hook, void *pthis, entvars_t *entvar)
{
PUSH_VOID()
int iOther=EntvarToIndex(entvar);
PRE_START()
@ -117,10 +150,13 @@ void Hook_Void_Entvar(Hook *hook, void *pthis, entvars_t *entvar)
, iOther
POST_END()
POP()
}
void Hook_Void_Cbase(Hook *hook, void *pthis, void *other)
{
PUSH_VOID()
int iOther=PrivateToIndex(other);
PRE_START()
@ -137,31 +173,36 @@ void Hook_Void_Cbase(Hook *hook, void *pthis, void *other)
, iOther
POST_END()
POP()
}
int Hook_Int_Float_Int(Hook *hook, void *pthis, float f1, int i1)
{
int ireturn=0;
int ret=0;
int origret=0;
PUSH_INT()
PRE_START()
, f1, i1
PRE_END()
#if defined _WIN32
ireturn=reinterpret_cast<int (__fastcall*)(void*, int, float, int)>(hook->func)(pthis, 0, f1, i1);
origret=reinterpret_cast<int (__fastcall*)(void*, int, float, int)>(hook->func)(pthis, 0, f1, i1);
#elif defined __linux__
ireturn=reinterpret_cast<int (*)(void*, float, int)>(hook->func)(pthis, f1, i1);
origret=reinterpret_cast<int (*)(void*, float, int)>(hook->func)(pthis, f1, i1);
#endif
POST_START()
, f1, i1
POST_END()
return ireturn;
POP();
CHECK_RETURN();
return ret;
}
void Hook_Void_Entvar_Int(Hook *hook, void *pthis, entvars_t *ev1, int i1)
{
PUSH_VOID()
int iOther=EntvarToIndex(ev1);
PRE_START()
@ -177,30 +218,38 @@ void Hook_Void_Entvar_Int(Hook *hook, void *pthis, entvars_t *ev1, int i1)
POST_START()
, iOther, i1
POST_END()
POP()
}
int Hook_Int_Cbase(Hook *hook, void *pthis, void *cb1)
{
int ret=0;
int origret=0;
PUSH_INT()
int iOther=PrivateToIndex(cb1);
int ireturn=0;
PRE_START()
, iOther
PRE_END()
#if defined _WIN32
ireturn=reinterpret_cast<int (__fastcall*)(void*, int, void *)>(hook->func)(pthis, 0, cb1);
origret=reinterpret_cast<int (__fastcall*)(void*, int, void *)>(hook->func)(pthis, 0, cb1);
#elif defined __linux__
ireturn=reinterpret_cast<int (*)(void*, void *)>(hook->func)(pthis, cb1);
origret=reinterpret_cast<int (*)(void*, void *)>(hook->func)(pthis, cb1);
#endif
POST_START()
, iOther
POST_END()
return ireturn;
POP()
CHECK_RETURN()
return ret;
}
void Hook_Void_Int_Int(Hook *hook, void *pthis, int i1, int i2)
{
PUSH_VOID()
PRE_START()
,i1, i2
PRE_END()
@ -213,51 +262,63 @@ void Hook_Void_Int_Int(Hook *hook, void *pthis, int i1, int i2)
POST_START()
,i1, i2
POST_END()
POP()
}
int Hook_Int_Int_Str_Int(Hook *hook, void *pthis, int i1, const char *sz1, int i2)
{
int ireturn=0;
int ret=0;
int origret=0;
PUSH_INT()
PRE_START()
,i1, sz1, i2
PRE_END()
#if defined _WIN32
ireturn=reinterpret_cast<int (__fastcall*)(void*, int, int, const char *, int)>(hook->func)(pthis, 0, i1, sz1, i2);
origret=reinterpret_cast<int (__fastcall*)(void*, int, int, const char *, int)>(hook->func)(pthis, 0, i1, sz1, i2);
#elif defined __linux__
ireturn=reinterpret_cast<int (*)(void*, int, const char *, int)>(hook->func)(pthis, i1, sz1, i2);
origret=reinterpret_cast<int (*)(void*, int, const char *, int)>(hook->func)(pthis, i1, sz1, i2);
#endif
POST_START()
,i1, sz1, i2
POST_END()
return ireturn;
POP()
CHECK_RETURN()
return ret;
}
int Hook_Int_Int(Hook *hook, void *pthis, int i1)
{
int ireturn=0;
int ret=0;
int origret=0;
PUSH_INT()
PRE_START()
,i1
PRE_END()
#if defined _WIN32
ireturn=reinterpret_cast<int (__fastcall*)(void*, int, int)>(hook->func)(pthis, 0, i1);
origret=reinterpret_cast<int (__fastcall*)(void*, int, int)>(hook->func)(pthis, 0, i1);
#elif defined __linux__
ireturn=reinterpret_cast<int (*)(void*, int)>(hook->func)(pthis, i1);
origret=reinterpret_cast<int (*)(void*, int)>(hook->func)(pthis, i1);
#endif
POST_START()
,i1
POST_END()
return ireturn;
POP()
CHECK_RETURN()
return ret;
}
int Hook_Int_Entvar(Hook *hook, void *pthis, entvars_t *ev1)
{
int ireturn=0;
int ret=0;
int origret=0;
PUSH_INT()
int iOther=EntvarToIndex(ev1);
PRE_START()
@ -265,16 +326,18 @@ int Hook_Int_Entvar(Hook *hook, void *pthis, entvars_t *ev1)
PRE_END()
#if defined _WIN32
ireturn=reinterpret_cast<int (__fastcall*)(void*, int, entvars_t *)>(hook->func)(pthis, 0, ev1);
origret=reinterpret_cast<int (__fastcall*)(void*, int, entvars_t *)>(hook->func)(pthis, 0, ev1);
#elif defined __linux__
ireturn=reinterpret_cast<int (*)(void*, entvars_t *)>(hook->func)(pthis, ev1);
origret=reinterpret_cast<int (*)(void*, entvars_t *)>(hook->func)(pthis, ev1);
#endif
POST_START()
, iOther
POST_END()
return ireturn;
POP()
CHECK_RETURN()
return ret;
}
@ -282,7 +345,9 @@ int Hook_Int_Entvar(Hook *hook, void *pthis, entvars_t *ev1)
// Takedamage
int Hook_Int_Entvar_Entvar_Float_Int(Hook *hook, void *pthis, entvars_t *inflictor, entvars_t *attacker, float damage, int damagebits)
{
int ireturn=0;
int ret=0;
int origret=0;
PUSH_INT()
int iInflictor=EntvarToIndex(inflictor);
int iAttacker=EntvarToIndex(attacker);
@ -293,20 +358,23 @@ int Hook_Int_Entvar_Entvar_Float_Int(Hook *hook, void *pthis, entvars_t *inflict
#if defined _WIN32
ireturn=reinterpret_cast<int (__fastcall*)(void*, int, entvars_t *, entvars_t *, float, int)>(hook->func)(pthis, 0, inflictor, attacker, damage, damagebits);
origret=reinterpret_cast<int (__fastcall*)(void*, int, entvars_t *, entvars_t *, float, int)>(hook->func)(pthis, 0, inflictor, attacker, damage, damagebits);
#elif defined __linux__
ireturn=reinterpret_cast<int (*)(void*, entvars_t *, entvars_t *, float, int)>(hook->func)(pthis, inflictor, attacker, damage, damagebits);
origret=reinterpret_cast<int (*)(void*, entvars_t *, entvars_t *, float, int)>(hook->func)(pthis, inflictor, attacker, damage, damagebits);
#endif
POST_START()
,iInflictor, iAttacker, damage, damagebits
POST_END()
return ireturn;
POP()
CHECK_RETURN()
return ret;
}
void Hook_Void_Int(Hook *hook, void *pthis, int i1)
{
PUSH_VOID()
PRE_START()
, i1
PRE_END()
@ -321,10 +389,12 @@ void Hook_Void_Int(Hook *hook, void *pthis, int i1)
,i1
POST_END()
POP()
}
void Hook_Void_Cbase_Cbase_Int_Float(Hook *hook, void *pthis, void *cb1, void *cb2, int i1, float f1)
{
PUSH_VOID()
int iCaller=PrivateToIndex(cb1);
int iActivator=PrivateToIndex(cb2);
@ -344,10 +414,12 @@ void Hook_Void_Cbase_Cbase_Int_Float(Hook *hook, void *pthis, void *cb1, void *c
,iCaller, iActivator, i1, f1
POST_END()
POP()
}
void Hook_Void_Entvar_Float_Vector_Trace_Int(Hook *hook, void *pthis, entvars_t *ev1, float f1, Vector v1, TraceResult *tr1, int i1)
{
PUSH_VOID()
int iev1=EntvarToIndex(ev1);
cell cvec[3];
cvec[0]=amx_ftoc2(v1.x);
@ -367,10 +439,13 @@ void Hook_Void_Entvar_Float_Vector_Trace_Int(Hook *hook, void *pthis, entvars_t
POST_START()
, iev1, f1, MF_PrepareCellArrayA(cvec, 3, false), tr1, i1
POST_END()
POP()
}
void Hook_Void_Float_Vector_TraceResult_Int(Hook *hook, void *pthis, float f1, Vector v1, TraceResult *tr1, int i1)
{
PUSH_VOID()
cell cvec[3];
cvec[0]=amx_ftoc2(v1.x);
cvec[1]=amx_ftoc2(v1.y);
@ -389,41 +464,50 @@ void Hook_Void_Float_Vector_TraceResult_Int(Hook *hook, void *pthis, float f1, V
POST_START()
, f1, MF_PrepareCellArrayA(cvec, 3, false), tr1, i1
POST_END()
POP()
}
const char *Hook_Str_Void(Hook *hook, void *pthis)
{
const char *ret=NULL;
String ret;
String origret;
PUSH_STRING()
PRE_START()
PRE_END()
#if defined _WIN32
ret=reinterpret_cast<const char *(__fastcall*)(void*, int)>(hook->func)(pthis, 0);
origret.assign(reinterpret_cast<const char *(__fastcall*)(void*, int)>(hook->func)(pthis, 0));
#elif defined __linux__
ret=reinterpret_cast<const char *(*)(void*)>(hook->func)(pthis);
origret.assign(reinterpret_cast<const char *(*)(void*)>(hook->func)(pthis));
#endif
POST_START()
POST_END()
return ret;
POP()
CHECK_RETURN_STR();
return ret.c_str();
}
void *Hook_Cbase_Void(Hook *hook, void *pthis)
{
void *ret=NULL;
void *origret=NULL;
PUSH_CBASE()
PRE_START()
PRE_END()
#if defined _WIN32
ret=reinterpret_cast<void *(__fastcall*)(void*, int)>(hook->func)(pthis, 0);
origret=reinterpret_cast<void *(__fastcall*)(void*, int)>(hook->func)(pthis, 0);
#elif defined __linux__
ret=reinterpret_cast<void *(*)(void*)>(hook->func)(pthis);
origret=reinterpret_cast<void *(*)(void*)>(hook->func)(pthis);
#endif
POST_START()
POST_END()
POP()
CHECK_RETURN()
return ret;
}
@ -432,21 +516,27 @@ void *Hook_Cbase_Void(Hook *hook, void *pthis)
Vector Hook_Vector_Void(Hook *hook, void *pthis)
{
Vector ret;
Vector origret;
PUSH_VECTOR()
memset(&ret, 0x0, sizeof(Vector));
memset(&origret, 0x0, sizeof(Vector));
PRE_START()
PRE_END()
#if defined _WIN32
ret=reinterpret_cast<Vector (__fastcall*)(void*, int)>(hook->func)(pthis, 0);
origret=reinterpret_cast<Vector (__fastcall*)(void*, int)>(hook->func)(pthis, 0);
#elif defined __linux__
ret=reinterpret_cast<Vector (*)(void*)>(hook->func)(pthis);
origret=reinterpret_cast<Vector (*)(void*)>(hook->func)(pthis);
#endif
POST_START()
POST_END()
POP()
CHECK_RETURN()
return ret;
}
@ -454,8 +544,12 @@ Vector Hook_Vector_Void(Hook *hook, void *pthis)
Vector Hook_Vector_pVector(Hook *hook, void *pthis, Vector *v1)
{
Vector ret;
Vector origret;
PUSH_VECTOR()
memset(&ret, 0x0, sizeof(Vector));
memset(&origret, 0x0, sizeof(Vector));
cell cv1[3];
cv1[0]=amx_ftoc2(v1->x);
@ -467,15 +561,17 @@ Vector Hook_Vector_pVector(Hook *hook, void *pthis, Vector *v1)
PRE_END()
#if defined _WIN32
ret=reinterpret_cast<Vector (__fastcall*)(void*, int, Vector *)>(hook->func)(pthis, 0, v1);
origret=reinterpret_cast<Vector (__fastcall*)(void*, int, Vector *)>(hook->func)(pthis, 0, v1);
#elif defined __linux__
ret=reinterpret_cast<Vector (*)(void*, Vector *)>(hook->func)(pthis, v1);
origret=reinterpret_cast<Vector (*)(void*, Vector *)>(hook->func)(pthis, v1);
#endif
POST_START()
, MF_PrepareCellArrayA(cv1, 3, false)
POST_END()
POP()
CHECK_RETURN()
return ret;
}
@ -483,6 +579,8 @@ Vector Hook_Vector_pVector(Hook *hook, void *pthis, Vector *v1)
int Hook_Int_pVector(Hook *hook, void *pthis, Vector *v1)
{
int ret=0;
int origret=0;
PUSH_INT()
cell cv1[3];
@ -495,21 +593,24 @@ int Hook_Int_pVector(Hook *hook, void *pthis, Vector *v1)
PRE_END()
#if defined _WIN32
ret=reinterpret_cast<int (__fastcall*)(void*, int, Vector *)>(hook->func)(pthis, 0, v1);
origret=reinterpret_cast<int (__fastcall*)(void*, int, Vector *)>(hook->func)(pthis, 0, v1);
#elif defined __linux__
ret=reinterpret_cast<int (*)(void*, Vector *)>(hook->func)(pthis, v1);
origret=reinterpret_cast<int (*)(void*, Vector *)>(hook->func)(pthis, v1);
#endif
POST_START()
, MF_PrepareCellArrayA(cv1, 3, false)
POST_END()
POP()
CHECK_RETURN()
return ret;
}
void Hook_Void_Entvar_Float_Float(Hook *hook, void *pthis, entvars_t *ev1, float f1, float f2)
{
PUSH_VOID()
cell cev1=EntvarToIndex(ev1);
PRE_START()
@ -526,11 +627,14 @@ void Hook_Void_Entvar_Float_Float(Hook *hook, void *pthis, entvars_t *ev1, float
, cev1, f1, f2
POST_END()
POP()
}
int Hook_Int_pFloat_pFloat(Hook *hook, void *pthis, float *f1, float *f2)
{
int ret=0;
int origret=0;
PUSH_INT()
cell cf1=amx_ftoc2(f1 == NULL ? 0.0 : *f1);
cell cf2=amx_ftoc2(f2 == NULL ? 0.0 : *f2);
@ -540,20 +644,23 @@ int Hook_Int_pFloat_pFloat(Hook *hook, void *pthis, float *f1, float *f2)
PRE_END()
#if defined _WIN32
ret=reinterpret_cast<int (__fastcall*)(void *, int, float *, float *)>(hook->func)(pthis, 0, f1, f2);
origret=reinterpret_cast<int (__fastcall*)(void *, int, float *, float *)>(hook->func)(pthis, 0, f1, f2);
#elif defined __linux__
ret=reinterpret_cast<int (*)(void *, float *, float *)>(hook->func)(pthis, f1, f2);
origret=reinterpret_cast<int (*)(void *, float *, float *)>(hook->func)(pthis, f1, f2);
#endif
POST_START()
, cf1, cf2
POST_END()
POP()
CHECK_RETURN()
return ret;
}
void Hook_Void_Entvar_Float(Hook *hook, void *pthis, entvars_t *ev1, float f1)
{
PUSH_VOID()
cell cev1=EntvarToIndex(ev1);
PRE_START()
@ -569,5 +676,6 @@ void Hook_Void_Entvar_Float(Hook *hook, void *pthis, entvars_t *ev1, float f1)
POST_START()
, cev1, f1
POST_END()
POP()
}

View File

@ -198,15 +198,16 @@ static cell AMX_NATIVE_CALL RegisterHam(AMX *amx, cell *params)
if ((*i)->tramp == vfunction)
{
// Yes, this function is hooked
Forward *pfwd=new Forward(fwd);
if (post)
{
(*i)->post.push_back(new Forward(fwd));
(*i)->post.push_back(pfwd);
}
else
{
(*i)->pre.push_back(new Forward(fwd));
(*i)->pre.push_back(pfwd);
}
return 1;
return reinterpret_cast<cell>(pfwd);
}
}
@ -214,16 +215,17 @@ static cell AMX_NATIVE_CALL RegisterHam(AMX *amx, cell *params)
Hook *hook=new Hook(vtable, hooklist[func].vtid, hooklist[func].targetfunc, hooklist[func].isvoid, hooklist[func].paramcount, classname);
hooks[func].push_back(hook);
Forward *pfwd=new Forward(fwd);
if (post)
{
hook->post.push_back(new Forward(fwd));
hook->post.push_back(pfwd);
}
else
{
hook->pre.push_back(new Forward(fwd));
hook->pre.push_back(pfwd);
}
return 1;
return reinterpret_cast<cell>(pfwd);
}
static cell AMX_NATIVE_CALL ExecuteHam(AMX *amx, cell *params)
{
@ -258,12 +260,40 @@ static cell AMX_NATIVE_CALL IsHamValid(AMX *amx, cell *params)
return 0;
}
static cell AMX_NATIVE_CALL DisableHamForward(AMX *amx, cell *params)
{
Forward *fwd=reinterpret_cast<Forward *>(params[1]);
if (fwd == 0)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid HamHook handle.");
return -1;
}
fwd->state=FSTATE_STOP;
return 0;
}
static cell AMX_NATIVE_CALL EnableHamForward(AMX *amx, cell *params)
{
Forward *fwd=reinterpret_cast<Forward *>(params[1]);
if (fwd == 0)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid HamHook handle.");
return -1;
}
fwd->state=FSTATE_OK;
return 0;
}
AMX_NATIVE_INFO RegisterNatives[] =
{
{ "RegisterHam", RegisterHam },
{ "ExecuteHam", ExecuteHam },
{ "ExecuteHamB", ExecuteHamB },
{ "IsHamValid", IsHamValid },
{ "DisableHamForward", DisableHamForward },
{ "EnableHamForward", EnableHamForward },
{ NULL, NULL }
};

View File

@ -455,6 +455,18 @@ enum Ham
};
/**
* Ham return types.
* -
* Return these from hooks to disable calling the target function.
* Numbers match up with fakemeta's FMRES_* for clarity. They are interchangable.
* 0 (or no return) is also interpretted as HAM_IGNORED.
*/
#define HAM_IGNORED 1 /**< Calls target function, returns normal value */
#define HAM_HANDLED 2 /**< Tells the module you did something, still calls target function and returns normal value */
#define HAM_OVERRIDE 3 /**< Still calls the target function, but returns whatever is set with SetHamReturn*() */
#define HAM_SUPERCEDE 4 /**< Block the target call, and use your return value (if applicable) (Set with SetHamReturn*()) */
/**
* Hooks the virtual table for the specified entity class.
* An example would be: RegisterHam(Ham_TakeDamage, "player_hurt", "player");
@ -464,8 +476,27 @@ enum Ham
* @param callback The forward to call.
* @param entity The entity classname to hook.
* @param post Whether or not to forward this in post.
* @return Returns a handle to the forward. Use EnableHamForward/DisableHamForward to toggle the forward on or off.
*/
native RegisterHam(Ham:function, const callback[], const entity[], post=0);
native HamHook:RegisterHam(Ham:function, const callback[], const entity[], post=0);
/**
* Stops a ham forward from triggering.
* Use the return value from RegisterHam as the parameter here!
*
* @param fwd The forward to stop.
*/
native DisableHamForward(HamHook:fwd);
/**
* Starts a ham forward back up.
* Use the return value from RegisterHam as the parameter here!
*
* @param fwd The forward to re-enable.
*/
native EnableHamForward(HamHook:fwd);
/**
* Executes the virtual function on the entity.
@ -487,6 +518,23 @@ native ExecuteHam(Ham:function, this, any:...);
native ExecuteHamB(Ham:function, this, any:...);
native GetHamReturnInteger(&output);
native GetHamReturnFloat(&Float:output);
native GetHamReturnVector(Float:output[3]);
native GetHamReturnCbase(&output);
native GetHamReturnString(output[], size);
native GetOrigHamReturnInteger(&output);
native GetOrigHamReturnFloat(&Float:output);
native GetOrigHamReturnVector(Float:output[3]);
native GetOrigHamReturnCbase(&output);
native GetOrigHamReturnString(output[], size);
native SetHamReturnInteger(output);
native SetHamReturnFloat(Float:output);
native SetHamReturnVector(const Float:output[3]);
native SetHamReturnCbase(output);
native SetHamReturnString(const output[]);
/**
* Returns whether or not the function for the specified Ham is valid.
* Things that would make it invalid would be bounds (an older module version

View File

@ -260,6 +260,26 @@
>
</File>
</Filter>
<Filter
Name="Data Handler"
>
<File
RelativePath="..\CString.h"
>
</File>
<File
RelativePath="..\DataHandler.cpp"
>
</File>
<File
RelativePath="..\DataHandler.h"
>
</File>
<File
RelativePath="..\sh_stack.h"
>
</File>
</Filter>
<File
RelativePath="..\amxx_api.cpp"
>

219
dlls/hamsandwich/sh_stack.h Normal file
View File

@ -0,0 +1,219 @@
/* ======== SourceMM ========
* Copyright (C) 2004-2005 Metamod:Source Development Team
* No warranties of any kind
*
* License: zlib/libpng
*
* Author(s): Pavol "PM OnoTo" Marko
* ============================
*/
#ifndef __SH_STACK_H__
#define __SH_STACK_H__
#define SH_STACK_DEFAULT_SIZE 4
//namespace SourceHook
//{/
// Vector
template <class T> class CStack
{
T *m_Elements;
size_t m_AllocatedSize;
size_t m_UsedSize;
public:
friend class iterator;
class iterator
{
CStack<T> *m_pParent;
size_t m_Index;
public:
iterator(CStack<T> *pParent, size_t id) : m_pParent(pParent), m_Index(id)
{
}
iterator(CStack<T> *pParent) : m_pParent(pParent), m_Index(0)
{
}
iterator() : m_pParent(NULL), m_Index(0)
{
}
T &operator *()
{
return m_pParent->m_Elements[m_Index];
}
const T &operator *() const
{
return m_pParent->m_Elements[m_Index];
}
T * operator->()
{
return m_pParent->m_Elements + m_Index;
}
const T * operator->() const
{
return m_pParent->m_Elements + m_Index;
}
iterator & operator++() // preincrement
{
++m_Index;
return (*this);
}
iterator operator++(int) // postincrement
{
iterator tmp = *this;
++m_Index;
return tmp;
}
iterator & operator--() // predecrement
{
--m_Index;
return (*this);
}
iterator operator--(int) // postdecrememnt
{
iterator tmp = *this;
--m_Index;
return tmp;
}
bool operator==(const iterator & right) const
{
return (m_pParent == right.m_pParent && m_Index == right.m_Index);
}
bool operator!=(const iterator & right) const
{
return !(*this == right);
}
};
CStack() : m_Elements(new T[SH_STACK_DEFAULT_SIZE]),
m_AllocatedSize(SH_STACK_DEFAULT_SIZE),
m_UsedSize(0)
{
}
CStack(size_t size) : m_Elements(new T[size]),
m_AllocatedSize(size),
m_UsedSize(0)
{
}
CStack(const CStack &other) : m_Elements(NULL),
m_AllocatedSize(0),
m_UsedSize(0)
{
reserve(other.m_AllocatedSize);
m_UsedSize = other.m_UsedSize;
for (size_t i = 0; i < m_UsedSize; ++i)
m_Elements[i] = other.m_Elements[i];
}
~CStack()
{
if (m_Elements)
delete [] m_Elements;
}
void operator=(const CStack &other)
{
if (m_AllocatedSize < other.m_AllocatedSize)
{
if (m_Elements)
delete [] m_Elements;
m_Elements = new T[other.m_AllocatedSize];
m_AllocatedSize = other.m_AllocatedSize;
}
m_UsedSize = other.m_UsedSize;
for (size_t i = 0; i < m_UsedSize; ++i)
m_Elements[i] = other.m_Elements[i];
}
bool push(const T &val)
{
if (m_UsedSize + 1 == m_AllocatedSize)
{
// zOHNOES! REALLOCATE!
m_AllocatedSize *= 2;
T *newElements = new T[m_AllocatedSize];
if (!newElements)
{
m_AllocatedSize /= 2;
return false;
}
if (m_Elements)
{
for (size_t i = 0; i < m_UsedSize; ++i)
newElements[i] = m_Elements[i];
delete [] m_Elements;
}
m_Elements = newElements;
}
m_Elements[m_UsedSize++] = val;
return true;
}
void pop()
{
--m_UsedSize;
}
T &front()
{
return m_Elements[m_UsedSize - 1];
}
const T &front() const
{
return m_Elements[m_UsedSize - 1];
}
iterator begin()
{
return iterator(this, 0);
}
iterator end()
{
return iterator(this, m_UsedSize);
}
size_t size()
{
return m_UsedSize;
}
size_t capacity()
{
return m_AllocatedSize;
}
bool empty()
{
return m_UsedSize == 0 ? true : false;
}
bool reserve(size_t size)
{
if (size > m_AllocatedSize)
{
T *newElements = new T[size];
if (!newElements)
return false;
if (m_Elements)
{
for (size_t i = 0; i < m_UsedSize; ++i)
newElements[i] = m_Elements[i];
delete [] m_Elements;
}
m_Elements = newElements;
m_AllocatedSize = size;
}
return true;
}
};
//}; //namespace SourceHook
#endif

View File

@ -74,8 +74,8 @@ void HamCommand(void)
}
else if (strcmp(cmd, "hooks")==0)
{
print_srvconsole("%-24s | %-32s | %10s | %10s\n", "Key", "Classname", "Pre", "Post");
print_srvconsole("-------------------------------------------------------------------------------------\n");
print_srvconsole("%-24s | %-27s | %10s | %10s\n", "Key", "Classname", "Pre", "Post");
print_srvconsole("--------------------------------------------------------------------------------\n");
unsigned int ForwardCount=0;
unsigned int HookCount=0;
int count = 0;
@ -90,14 +90,14 @@ void HamCommand(void)
HookCount++;
ForwardCount+=(*j)->pre.size() + (*j)->post.size();
print_srvconsole("%-24s | %-32s | %10d | %10d\n",hooklist[i].name, (*j)->ent, (*j)->pre.size(), (*j)->post.size());
print_srvconsole("%-24s | %-27s | %10d | %10d\n",hooklist[i].name, (*j)->ent, (*j)->pre.size(), (*j)->post.size());
if (count >= 5)
{
print_srvconsole("-------------------------------------------------------------------------------------\n");
print_srvconsole("--------------------------------------------------------------------------------\n");
}
}
}
print_srvconsole("\n%u active hooks, %u active forwards.\n\n", HookCount, ForwardCount);
print_srvconsole("\n%u hooks, %u forwards.\n\n", HookCount, ForwardCount);
return;
}