Well, as people will need to hook ConCommand (due to autobuy) I thought I would share my version of hooking ConCommand, which make the coding a hook almost the same as a regular ConCommand...
Example to hook 'say'...
Code:
extern ICvar *g_pCVar;
PLUGIN_CON_COMMAND_F( say, "Display player message", FCVAR_GAMEDLL )
{
... your code ...
if( ... do not call original function ... )
return PLUGIN_STOP;
return PLUGIN_CONTINUE;
}
NOTE! If you create multiple hooks they will be called in the order declared. Between different server plugins I don't know as I haven't tested it.
NOTE2! I have only tested this on linux... please let me know if it works on windows...
/X
PS! The name of the class should probably be something else than plugin but that's what I started with...
The header file...
Code:
//-----------------------------------------------------------------------------
// Purpose: Support command hook, requires g_pCVar to be allocated.
// NOTE! Default ICvar allocation is 'g_pCVar'.
// To use a different pointer name define "ENGINEVAR" before
// including this header file.
//-----------------------------------------------------------------------------
#ifndef ENGINECVAR
#define ENGINECVAR (g_pCVar)
#endif
extern ICvar *ENGINECVAR;
#define PLUGIN_CON_COMMAND( name, description ) \
static PLUGIN_RESULT name(); \
static PluginConCommand name##_command( #name, name, description ); \
static PLUGIN_RESULT name()
#define PLUGIN_CON_COMMAND_F( name, description, flags ) \
static PLUGIN_RESULT name(); \
static PluginConCommand name##_command( #name, name, description, flags ); \
static PLUGIN_RESULT name()
// Called when a ConCommand needs to execute
// (return with PLUGIN_CONTINUE to call original function)
typedef PLUGIN_RESULT (*FnPluginCommandCallback)( void );
// Special ConCommand to hook commands
class PluginConCommand : public ConCommand
{
friend class ConCommandBaseMgr;
friend class CCvar;
public:
PluginConCommand( void ) : ConCommand() { Create(); }
PluginConCommand( char const *pName, FnPluginCommandCallback fnCallback,
char const *pHelpString = 0, int flags = 0,
FnCommandCompletionCallback completionFunc = 0 )
: ConCommand( pName, NULL, pHelpString, flags, completionFunc )
{ Create( pName, fnCallback ); }
// Invoke the original function
virtual void Dispatch( void )
{
if( m_fnPluginCommandCallback && (*m_fnPluginCommandCallback)() != PLUGIN_CONTINUE )
return;
if ( m_pConCommandOriginal && m_pConCommandOriginal->IsCommand() )
m_pConCommandOriginal->Dispatch();
}
protected:
virtual void Create( const char *pName = NULL, FnPluginCommandCallback fnCallback = NULL )
{
m_fnPluginCommandCallback = fnCallback;
m_pConCommandOriginal = NULL;
}
// Override Init
virtual void Init( void )
{
if( ! m_pConCommandOriginal )
{
const char *name = GetName();
if( name && name[0] )
{
// Search the engine command list
ConCommandBase const *cmd = NULL;
if( ENGINECVAR )
cmd = ENGINECVAR->GetCommands();
for ( ; cmd && stricmp( name, cmd->GetName() ); cmd = cmd->GetNext() )
{}
if( cmd && cmd != this && cmd->IsCommand() )
{
m_pConCommandOriginal = (ConCommand*) cmd;
Msg( "[%s] Plugin created hook on command \"%s\"\n",
VNAME, cmd->GetName() );
}
}
}
ConCommand::Init();
}
protected:
// This will hold the new callback pointer
FnPluginCommandCallback m_fnPluginCommandCallback;
// This will hold a pointer to the original command
ConCommand *m_pConCommandOriginal;
};