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 //Added this for amxx inclusion
bool empty() bool empty() const
{ {
if (!v) if (!v)
return true; return true;
@ -140,7 +140,7 @@ public:
return false; return false;
} }
size_t size() size_t size() const
{ {
if (v) if (v)
return strlen(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 \ OBJECTS = sdk/amxxmodule.cpp amxx_api.cpp config_parser.cpp \
hook_callbacks.cpp hook_native.cpp srvcmd.cpp \ hook_callbacks.cpp hook_native.cpp srvcmd.cpp \
call_funcs.cpp hook_create.cpp call_funcs.cpp hook_create.cpp DataHandler.cpp
LINK = LINK =

View File

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

View File

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

View File

@ -198,15 +198,16 @@ static cell AMX_NATIVE_CALL RegisterHam(AMX *amx, cell *params)
if ((*i)->tramp == vfunction) if ((*i)->tramp == vfunction)
{ {
// Yes, this function is hooked // Yes, this function is hooked
Forward *pfwd=new Forward(fwd);
if (post) if (post)
{ {
(*i)->post.push_back(new Forward(fwd)); (*i)->post.push_back(pfwd);
} }
else 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); Hook *hook=new Hook(vtable, hooklist[func].vtid, hooklist[func].targetfunc, hooklist[func].isvoid, hooklist[func].paramcount, classname);
hooks[func].push_back(hook); hooks[func].push_back(hook);
Forward *pfwd=new Forward(fwd);
if (post) if (post)
{ {
hook->post.push_back(new Forward(fwd)); hook->post.push_back(pfwd);
} }
else 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) 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; 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[] = AMX_NATIVE_INFO RegisterNatives[] =
{ {
{ "RegisterHam", RegisterHam }, { "RegisterHam", RegisterHam },
{ "ExecuteHam", ExecuteHam }, { "ExecuteHam", ExecuteHam },
{ "ExecuteHamB", ExecuteHamB }, { "ExecuteHamB", ExecuteHamB },
{ "IsHamValid", IsHamValid }, { "IsHamValid", IsHamValid },
{ "DisableHamForward", DisableHamForward },
{ "EnableHamForward", EnableHamForward },
{ NULL, NULL } { 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. * Hooks the virtual table for the specified entity class.
* An example would be: RegisterHam(Ham_TakeDamage, "player_hurt", "player"); * An example would be: RegisterHam(Ham_TakeDamage, "player_hurt", "player");
@ -464,8 +476,27 @@ enum Ham
* @param callback The forward to call. * @param callback The forward to call.
* @param entity The entity classname to hook. * @param entity The entity classname to hook.
* @param post Whether or not to forward this in post. * @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. * Executes the virtual function on the entity.
@ -487,6 +518,23 @@ native ExecuteHam(Ham:function, this, any:...);
native ExecuteHamB(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. * 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 * Things that would make it invalid would be bounds (an older module version

View File

@ -260,6 +260,26 @@
> >
</File> </File>
</Filter> </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 <File
RelativePath="..\amxx_api.cpp" 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) else if (strcmp(cmd, "hooks")==0)
{ {
print_srvconsole("%-24s | %-32s | %10s | %10s\n", "Key", "Classname", "Pre", "Post"); print_srvconsole("%-24s | %-27s | %10s | %10s\n", "Key", "Classname", "Pre", "Post");
print_srvconsole("-------------------------------------------------------------------------------------\n"); print_srvconsole("--------------------------------------------------------------------------------\n");
unsigned int ForwardCount=0; unsigned int ForwardCount=0;
unsigned int HookCount=0; unsigned int HookCount=0;
int count = 0; int count = 0;
@ -90,14 +90,14 @@ void HamCommand(void)
HookCount++; HookCount++;
ForwardCount+=(*j)->pre.size() + (*j)->post.size(); 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) 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; return;
} }