showdax
10-14-2005, 21:44
First thing's first. I've written a ConCommand hook class similar to PM's say hook. It's generic though, and you specify the ConCommand you want to hook in the constructor, and pass your dispatch function to the constructor as a function pointer.
This is what the class definition looks like:typedef void (*DispatchFunction)(ConCommand *command, int client);
class ConCommandHook: public ConCommand
{
friend class CServerPluginAdmin;
const char *name;
ConCommand *command;
DispatchFunction CustomDispatch;
bool isHooked;
static int clientIndex;
public:
ConCommandHook(const char *name, const char *description, DispatchFunction customDispatch):
ConCommand(name, NULL, description, FCVAR_GAMEDLL), command(NULL)
{
this->isHooked = false;
this->name = name;
this->CustomDispatch = customDispatch;
this->Init();
}
void Init();
void Dispatch();
bool IsHooked();
};
Here's how I'm instantiating the objects:bool CServerPluginAdmin::Load(PluginId id, ISmmAPI *ismm, factories *list, char *error, size_t maxlen, bool late)
{
// ...
g_SayHook = new ConCommandHook("say", "Display player message (admin_mm)", (DispatchFunction) g_SayHookDispatch);
g_SayTeamHook = new ConCommandHook("say_team", "Display player message to team (admin_mm)", (DispatchFunction) g_SayHookDispatch);
// ...
}
And on Unload it calls delete on the objects. When the plugin is unloaded, it segfaults with this:Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1218535296 (LWP 9555)]
0x002a9920 in ConCommandBase::GetNext (this=0x39) at convar.cpp:261
261 return m_pNext;
Current language: auto; currently c++
(gdb) bt
#0 0x002a9920 in ConCommandBase::GetNext (this=0x39) at convar.cpp:261
#1 0x002aac3e in SMConVarAccessor::Unregister (this=0x2bf04c, pCommand=0xafc900) at concommands.cpp:78
#2 0x002b4380 in SourceMM::CPluginManager::UnregAllConCmds (this=0x2c1270, pl=0x98f98e8) at CPlugin.cpp:501
#3 0x002b3abc in SourceMM::CPluginManager::_Unload (this=0x2c1270, pl=0x98f98e8, force=false, error=0xbfff8330 "", maxlen=254) at CPlugin.cpp:304
#4 0x002b33c7 in SourceMM::CPluginManager::Unload (this=0x2c1270, id=1, force=false, error=0xbfff8330 "", maxlen=254) at CPlugin.cpp:142
Do any of you know what's going on there? If I remove the assignment and deletions, unloading works just fine, so it's definitely that that's causing and nothing else.
Edit: Actually, maybe it'd be better to hook ConCommand::Dispatch() for each convcommand I want. It's virtual after all.
This is what the class definition looks like:typedef void (*DispatchFunction)(ConCommand *command, int client);
class ConCommandHook: public ConCommand
{
friend class CServerPluginAdmin;
const char *name;
ConCommand *command;
DispatchFunction CustomDispatch;
bool isHooked;
static int clientIndex;
public:
ConCommandHook(const char *name, const char *description, DispatchFunction customDispatch):
ConCommand(name, NULL, description, FCVAR_GAMEDLL), command(NULL)
{
this->isHooked = false;
this->name = name;
this->CustomDispatch = customDispatch;
this->Init();
}
void Init();
void Dispatch();
bool IsHooked();
};
Here's how I'm instantiating the objects:bool CServerPluginAdmin::Load(PluginId id, ISmmAPI *ismm, factories *list, char *error, size_t maxlen, bool late)
{
// ...
g_SayHook = new ConCommandHook("say", "Display player message (admin_mm)", (DispatchFunction) g_SayHookDispatch);
g_SayTeamHook = new ConCommandHook("say_team", "Display player message to team (admin_mm)", (DispatchFunction) g_SayHookDispatch);
// ...
}
And on Unload it calls delete on the objects. When the plugin is unloaded, it segfaults with this:Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1218535296 (LWP 9555)]
0x002a9920 in ConCommandBase::GetNext (this=0x39) at convar.cpp:261
261 return m_pNext;
Current language: auto; currently c++
(gdb) bt
#0 0x002a9920 in ConCommandBase::GetNext (this=0x39) at convar.cpp:261
#1 0x002aac3e in SMConVarAccessor::Unregister (this=0x2bf04c, pCommand=0xafc900) at concommands.cpp:78
#2 0x002b4380 in SourceMM::CPluginManager::UnregAllConCmds (this=0x2c1270, pl=0x98f98e8) at CPlugin.cpp:501
#3 0x002b3abc in SourceMM::CPluginManager::_Unload (this=0x2c1270, pl=0x98f98e8, force=false, error=0xbfff8330 "", maxlen=254) at CPlugin.cpp:304
#4 0x002b33c7 in SourceMM::CPluginManager::Unload (this=0x2c1270, id=1, force=false, error=0xbfff8330 "", maxlen=254) at CPlugin.cpp:142
Do any of you know what's going on there? If I remove the assignment and deletions, unloading works just fine, so it's definitely that that's causing and nothing else.
Edit: Actually, maybe it'd be better to hook ConCommand::Dispatch() for each convcommand I want. It's virtual after all.