mirror of
https://github.com/znc/znc.git
synced 2026-05-07 13:54:47 +02:00
Add a generic command handling to CModule
With this, modules can use AddCommand() to register commands. CModule will dispatch all calls to OnModCommand() to the correct command handler. If a module calls AddHelpCommand(), it will also generate help output. Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
+100
-1
@@ -382,6 +382,68 @@ void CModule::ListSockets() {
|
|||||||
PutModule(Table);
|
PutModule(Table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CModule::AddCommand(const CModCommand& Command)
|
||||||
|
{
|
||||||
|
if (Command.GetFunction() == NULL)
|
||||||
|
return false;
|
||||||
|
if (Command.GetCommand().find(' ') != CString::npos)
|
||||||
|
return false;
|
||||||
|
if (FindCommand(Command.GetCommand()) != NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_mCommands[Command.GetCommand()] = Command;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CModule::AddCommand(const CString& sCmd, CModCommand::ModCmdFunc func, const CString& sArgs, const CString& sDesc)
|
||||||
|
{
|
||||||
|
CModCommand cmd(sCmd, func, sArgs, sDesc);
|
||||||
|
return AddCommand(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CModule::AddHelpCommand()
|
||||||
|
{
|
||||||
|
AddCommand("Help", &CModule::HandleHelpCommand, "", "Generate this output");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CModule::RemCommand(const CString& sCmd)
|
||||||
|
{
|
||||||
|
return m_mCommands.erase(sCmd) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CModCommand* CModule::FindCommand(const CString& sCmd) const
|
||||||
|
{
|
||||||
|
map<CString, CModCommand>::const_iterator it;
|
||||||
|
for (it = m_mCommands.begin(); it != m_mCommands.end(); ++it) {
|
||||||
|
if (!it->first.Equals(sCmd))
|
||||||
|
continue;
|
||||||
|
return &it->second;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CModule::HandleCommand(const CString& sLine) {
|
||||||
|
const CString& sCmd = sLine.Token(0);
|
||||||
|
const CModCommand* pCmd = FindCommand(sCmd);
|
||||||
|
|
||||||
|
if (pCmd) {
|
||||||
|
pCmd->Call(this, sLine);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CModule::HandleHelpCommand(const CString& sLine) {
|
||||||
|
CTable Table;
|
||||||
|
map<CString, CModCommand>::const_iterator it;
|
||||||
|
|
||||||
|
CModCommand::InitHelp(Table);
|
||||||
|
for (it = m_mCommands.begin(); it != m_mCommands.end(); ++it)
|
||||||
|
it->second.AddHelp(Table);
|
||||||
|
PutModule(Table);
|
||||||
|
}
|
||||||
|
|
||||||
CString CModule::GetModNick() const { return ((m_pUser) ? m_pUser->GetStatusPrefix() : "*") + m_sModName; }
|
CString CModule::GetModNick() const { return ((m_pUser) ? m_pUser->GetStatusPrefix() : "*") + m_sModName; }
|
||||||
|
|
||||||
// Webmods
|
// Webmods
|
||||||
@@ -416,7 +478,7 @@ void CModule::OnMode(const CNick& OpNick, CChan& Channel, char uMode, const CStr
|
|||||||
CModule::EModRet CModule::OnRaw(CString& sLine) { return CONTINUE; }
|
CModule::EModRet CModule::OnRaw(CString& sLine) { return CONTINUE; }
|
||||||
|
|
||||||
CModule::EModRet CModule::OnStatusCommand(CString& sCommand) { return CONTINUE; }
|
CModule::EModRet CModule::OnStatusCommand(CString& sCommand) { return CONTINUE; }
|
||||||
void CModule::OnModCommand(const CString& sCommand) {}
|
void CModule::OnModCommand(const CString& sCommand) { HandleCommand(sCommand); }
|
||||||
void CModule::OnModNotice(const CString& sMessage) {}
|
void CModule::OnModNotice(const CString& sMessage) {}
|
||||||
void CModule::OnModCTCP(const CString& sMessage) {}
|
void CModule::OnModCTCP(const CString& sMessage) {}
|
||||||
|
|
||||||
@@ -1089,3 +1151,40 @@ ModHandle CModules::OpenModule(const CString& sModule, const CString& sModPath,
|
|||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CModCommand::CModCommand()
|
||||||
|
: m_sCmd(), m_pFunc(NULL), m_sArgs(), m_sDesc()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CModCommand::CModCommand(const CString& sCmd, ModCmdFunc func, const CString& sArgs, const CString& sDesc)
|
||||||
|
: m_sCmd(sCmd), m_pFunc(func), m_sArgs(sArgs), m_sDesc(sDesc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CModCommand::CModCommand(const CModCommand& other)
|
||||||
|
: m_sCmd(other.m_sCmd), m_pFunc(other.m_pFunc), m_sArgs(other.m_sArgs), m_sDesc(other.m_sDesc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CModCommand& CModCommand::operator=(const CModCommand& other)
|
||||||
|
{
|
||||||
|
m_sCmd = other.m_sCmd;
|
||||||
|
m_pFunc = other.m_pFunc;
|
||||||
|
m_sArgs = other.m_sArgs;
|
||||||
|
m_sDesc = other.m_sDesc;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CModCommand::InitHelp(CTable& Table) {
|
||||||
|
Table.AddColumn("Command");
|
||||||
|
Table.AddColumn("Arguments");
|
||||||
|
Table.AddColumn("Description");
|
||||||
|
}
|
||||||
|
|
||||||
|
void CModCommand::AddHelp(CTable& Table) const {
|
||||||
|
Table.AddRow();
|
||||||
|
Table.SetCell("Command", GetCommand());
|
||||||
|
Table.SetCell("Arguments", GetArgs());
|
||||||
|
Table.SetCell("Description", GetDescription());
|
||||||
|
}
|
||||||
|
|||||||
@@ -200,6 +200,58 @@ protected:
|
|||||||
CString m_sDescription;
|
CString m_sDescription;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** A helper class for handling commands in modules. */
|
||||||
|
class CModCommand {
|
||||||
|
public:
|
||||||
|
/// Type for the callback function that handles the actual command.
|
||||||
|
typedef void (CModule::*ModCmdFunc)(const CString& sLine);
|
||||||
|
|
||||||
|
/// Default constructor, needed so that this can be saved in a std::map.
|
||||||
|
CModCommand();
|
||||||
|
|
||||||
|
/** Construct a new CModCommand.
|
||||||
|
* @param sCmd The name of the command.
|
||||||
|
* @param func The command's callback function.
|
||||||
|
* @param sArgs Help text describing the arguments to this command.
|
||||||
|
* @param sDesc Help text describing what this command does.
|
||||||
|
*/
|
||||||
|
CModCommand(const CString& sCmd, ModCmdFunc func, const CString& sArgs, const CString& sDesc);
|
||||||
|
|
||||||
|
/** Copy constructor, needed so that this can be saved in a std::map.
|
||||||
|
* @param other Object to copy from.
|
||||||
|
*/
|
||||||
|
CModCommand(const CModCommand& other);
|
||||||
|
|
||||||
|
/** Assignment operator, needed so that this can be saved in a std::map.
|
||||||
|
* @param other Object to copy from.
|
||||||
|
*/
|
||||||
|
CModCommand& operator=(const CModCommand& other);
|
||||||
|
|
||||||
|
/** Initialize a CTable so that it can be used with AddHelp().
|
||||||
|
* @param Table The instance of CTable to initialize.
|
||||||
|
*/
|
||||||
|
static void InitHelp(CTable& Table);
|
||||||
|
|
||||||
|
/** Add this command to the CTable instance.
|
||||||
|
* @param Table Instance of CTable to which this should be added.
|
||||||
|
* @warning The Table should be initialized via InitHelp().
|
||||||
|
*/
|
||||||
|
void AddHelp(CTable& Table) const;
|
||||||
|
|
||||||
|
const CString& GetCommand() const { return m_sCmd; }
|
||||||
|
ModCmdFunc GetFunction() const { return m_pFunc; }
|
||||||
|
const CString& GetArgs() const { return m_sArgs; }
|
||||||
|
const CString& GetDescription() const { return m_sDesc; }
|
||||||
|
|
||||||
|
void Call(CModule *pMod, const CString& sLine) const { (pMod->*m_pFunc)(sLine); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
CString m_sCmd;
|
||||||
|
ModCmdFunc m_pFunc;
|
||||||
|
CString m_sArgs;
|
||||||
|
CString m_sDesc;
|
||||||
|
};
|
||||||
|
|
||||||
/** The base class for your own ZNC modules.
|
/** The base class for your own ZNC modules.
|
||||||
*
|
*
|
||||||
* If you want to write a module for znc, you will have to implement a class
|
* If you want to write a module for znc, you will have to implement a class
|
||||||
@@ -758,6 +810,31 @@ public:
|
|||||||
virtual void ListSockets();
|
virtual void ListSockets();
|
||||||
// !Socket stuff
|
// !Socket stuff
|
||||||
|
|
||||||
|
// Command stuff
|
||||||
|
/// Register the "Help" command.
|
||||||
|
void AddHelpCommand();
|
||||||
|
/// @return True if the command was successfully added.
|
||||||
|
bool AddCommand(const CModCommand& Command);
|
||||||
|
/// @return True if the command was successfully added.
|
||||||
|
bool AddCommand(const CString& sCmd, CModCommand::ModCmdFunc func, const CString& sArgs = "", const CString& sDesc = "");
|
||||||
|
/// @return True if the command was successfully removed.
|
||||||
|
bool RemCommand(const CString& sCmd);
|
||||||
|
/// @return The CModCommand instance or NULL if none was found.
|
||||||
|
const CModCommand* FindCommand(const CString& sCmd) const;
|
||||||
|
/** This function tries to dispatch the given command via the correct
|
||||||
|
* instance of CModCommand. Before this can be called, commands have to
|
||||||
|
* be added via AddCommand(). If no "help" command is added, this
|
||||||
|
* function will call HandleHelpCommand.
|
||||||
|
* @param sLine The command line to handle.
|
||||||
|
* @return True if something was done, else false.
|
||||||
|
*/
|
||||||
|
bool HandleCommand(const CString& sLine);
|
||||||
|
/** Send a description of all registered commands via PutModule().
|
||||||
|
* @param sLine The help command that is being asked for.
|
||||||
|
*/
|
||||||
|
void HandleHelpCommand(const CString& sLine = "");
|
||||||
|
// !Command stuff
|
||||||
|
|
||||||
bool LoadRegistry();
|
bool LoadRegistry();
|
||||||
bool SaveRegistry() const;
|
bool SaveRegistry() const;
|
||||||
bool SetNV(const CString & sName, const CString & sValue, bool bWriteToDisk = true);
|
bool SetNV(const CString & sName, const CString & sValue, bool bWriteToDisk = true);
|
||||||
@@ -814,6 +891,7 @@ protected:
|
|||||||
private:
|
private:
|
||||||
MCString m_mssRegistry; //!< way to save name/value pairs. Note there is no encryption involved in this
|
MCString m_mssRegistry; //!< way to save name/value pairs. Note there is no encryption involved in this
|
||||||
VWebSubPages m_vSubPages;
|
VWebSubPages m_vSubPages;
|
||||||
|
map<CString, CModCommand> m_mCommands;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CModules : public vector<CModule*> {
|
class CModules : public vector<CModule*> {
|
||||||
|
|||||||
Reference in New Issue
Block a user