Thanks Cold.
What I have now is: Declare the hooks
Code:
SH_DECL_HOOK1_void(CBasePlayer, Touch, SH_NOATTRIB, 0, CBaseEntity *);
SH_DECL_HOOK5(IServerGameClients, ClientConnect, SH_NOATTRIB, 0, bool, edict_t *, char const *, char const *, char *, int);
SH_DECL_HOOK1_void(IServerGameClients, ClientDisconnect, SH_NOATTRIB, 0, edict_t *);
Hook connect and disconnect
Code:
bool TouchCatcher::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late)
{
...
SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, m_ServerClients, &g_TouchCatcher, &TouchCatcher::ClientDisconnect, true);
SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientConnect, m_ServerClients, &g_TouchCatcher, &TouchCatcher::ClientConnect, true);
...
}
Then hook and unhook Touch on connect and disconnect
Code:
void TouchCatcher::Touch_handler(CBaseEntity *pOther) {
RETURN_META(MRES_IGNORED);
}
bool TouchCatcher::ClientConnect(edict_t *pEntity, char const *pszName, char const *pszAddress, char *reject, int maxrejectlen)
{
CBaseEntity *pBaseEntity = pEntity->GetUnknown()->GetBaseEntity();
CBasePlayer *pPlayer = dynamic_cast<CBasePlayer *>(pBaseEntity);
SH_ADD_HOOK_MEMFUNC(CBasePlayer, Touch, pPlayer, &g_TouchCatcher, &TouchCatcher::Touch_handler, false);
RETURN_META_VALUE(MRES_IGNORED, true);
}
void TouchCatcher::ClientDisconnect(edict_t *pEntity)
{
CBaseEntity *pBaseEntity = pEntity->GetUnknown()->GetBaseEntity();
CBasePlayer *pPlayer = dynamic_cast<CBasePlayer *>(pBaseEntity);
SH_REMOVE_HOOK_MEMFUNC(CBasePlayer, Touch, pPlayer, &g_TouchCatcher, &TouchCatcher::Touch_handler, false);
RETURN_META(MRES_IGNORED);
}
This actually causes a pure virtual function call runtime error, but I'm assuming this is due to the incorrect header Duke pointed out so I'll convert to manual hooking. Is this the right way to go about it in principle though?