diff options
-rw-r--r-- | include/modules.h | 9 | ||||
-rw-r--r-- | src/command_parse.cpp | 15 | ||||
-rw-r--r-- | src/modules.cpp | 1 |
3 files changed, 24 insertions, 1 deletions
diff --git a/include/modules.h b/include/modules.h index 1b1684810..5190860fe 100644 --- a/include/modules.h +++ b/include/modules.h @@ -231,7 +231,7 @@ enum Implementation I_OnPreChangeHost, I_OnPreTopicChange, I_OnConnectionFail, I_OnPostTopicChange, I_OnPostConnect, I_OnPostDeoper, I_OnPreChangeRealName, I_OnUserRegister, I_OnChannelPreDelete, I_OnChannelDelete, - I_OnPostOper, I_OnPostCommand, I_OnPostJoin, + I_OnPostOper, I_OnPostCommand, I_OnCommandBlocked, I_OnPostJoin, I_OnBuildNeighborList, I_OnGarbageCollect, I_OnSetConnectClass, I_OnUserMessage, I_OnPassCompare, I_OnNumeric, I_OnPreRehash, I_OnModuleRehash, I_OnChangeIdent, I_OnSetUserIP, @@ -739,6 +739,13 @@ class CoreExport Module : public classbase, public usecountbase */ virtual void OnPostCommand(Command* command, const CommandBase::Params& parameters, LocalUser* user, CmdResult result, bool loop); + /** Called when a command was blocked before it could be executed. + * @param command The command being executed. + * @param parameters The parameters for the command. + * @param user The user issuing the command. + */ + virtual void OnCommandBlocked(const std::string& command, const CommandBase::Params& parameters, LocalUser* user); + /** Called after a user object is initialised and added to the user list. * When this is called the user has not had their I/O hooks checked or had their initial * connect class assigned and may not yet have a serialiser. You probably want to use diff --git a/src/command_parse.cpp b/src/command_parse.cpp index 6b6ae0079..06281d2e7 100644 --- a/src/command_parse.cpp +++ b/src/command_parse.cpp @@ -190,7 +190,10 @@ void CommandParser::ProcessCommand(LocalUser* user, std::string& command, Comman ModResult MOD_RESULT; FIRST_MOD_RESULT(OnPreCommand, MOD_RESULT, (command, command_p, user, false)); if (MOD_RESULT == MOD_RES_DENY) + { + FOREACH_MOD(OnCommandBlocked, (command, command_p, user)); return; + } /* * This double lookup is in case a module (abbreviation) wishes to change a command. @@ -204,7 +207,9 @@ void CommandParser::ProcessCommand(LocalUser* user, std::string& command, Comman { if (user->registered == REG_ALL) user->WriteNumeric(ERR_UNKNOWNCOMMAND, command, "Unknown command"); + ServerInstance->stats.Unknown++; + FOREACH_MOD(OnCommandBlocked, (command, command_p, user)); return; } } @@ -244,7 +249,10 @@ void CommandParser::ProcessCommand(LocalUser* user, std::string& command, Comman ModResult MOD_RESULT; FIRST_MOD_RESULT(OnPreCommand, MOD_RESULT, (command, command_p, user, false)); if (MOD_RESULT == MOD_RES_DENY) + { + FOREACH_MOD(OnCommandBlocked, (command, command_p, user)); return; + } /* activity resets the ping pending timer */ user->nextping = ServerInstance->Time() + user->MyClass->GetPingTime(); @@ -255,6 +263,7 @@ void CommandParser::ProcessCommand(LocalUser* user, std::string& command, Comman { user->CommandFloodPenalty += failpenalty; user->WriteNumeric(ERR_NOPRIVILEGES, "Permission Denied - You do not have the required operator privileges"); + FOREACH_MOD(OnCommandBlocked, (command, command_p, user)); return; } @@ -263,6 +272,7 @@ void CommandParser::ProcessCommand(LocalUser* user, std::string& command, Comman user->CommandFloodPenalty += failpenalty; user->WriteNumeric(ERR_NOPRIVILEGES, InspIRCd::Format("Permission Denied - Oper type %s does not have access to command %s", user->oper->name.c_str(), command.c_str())); + FOREACH_MOD(OnCommandBlocked, (command, command_p, user)); return; } } @@ -276,6 +286,7 @@ void CommandParser::ProcessCommand(LocalUser* user, std::string& command, Comman user->WriteNumeric(ERR_NEEDMOREPARAMS, command, "Not enough parameters."); if ((ServerInstance->Config->SyntaxHints) && (user->registered == REG_ALL) && (handler->syntax.length())) user->WriteNumeric(RPL_SYNTAX, handler->name, handler->syntax); + FOREACH_MOD(OnCommandBlocked, (command, command_p, user)); return; } @@ -283,6 +294,7 @@ void CommandParser::ProcessCommand(LocalUser* user, std::string& command, Comman { user->CommandFloodPenalty += failpenalty; user->WriteNumeric(ERR_NOTREGISTERED, command, "You have not registered"); + FOREACH_MOD(OnCommandBlocked, (command, command_p, user)); } else { @@ -292,7 +304,10 @@ void CommandParser::ProcessCommand(LocalUser* user, std::string& command, Comman /* module calls too */ FIRST_MOD_RESULT(OnPreCommand, MOD_RESULT, (command, command_p, user, true)); if (MOD_RESULT == MOD_RES_DENY) + { + FOREACH_MOD(OnCommandBlocked, (command, command_p, user)); return; + } /* * WARNING: be careful, the user may be deleted soon diff --git a/src/modules.cpp b/src/modules.cpp index b8a29ca43..54d7fc543 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -104,6 +104,7 @@ void Module::OnUnloadModule(Module*) { DetachEvent(I_OnUnloadModule); } void Module::OnBackgroundTimer(time_t) { DetachEvent(I_OnBackgroundTimer); } ModResult Module::OnPreCommand(std::string&, CommandBase::Params&, LocalUser*, bool) { DetachEvent(I_OnPreCommand); return MOD_RES_PASSTHRU; } void Module::OnPostCommand(Command*, const CommandBase::Params&, LocalUser*, CmdResult, bool) { DetachEvent(I_OnPostCommand); } +void Module::OnCommandBlocked(const std::string&, const CommandBase::Params&, LocalUser*) { DetachEvent(I_OnCommandBlocked); } void Module::OnUserInit(LocalUser*) { DetachEvent(I_OnUserInit); } void Module::OnUserPostInit(LocalUser*) { DetachEvent(I_OnUserPostInit); } ModResult Module::OnCheckReady(LocalUser*) { DetachEvent(I_OnCheckReady); return MOD_RES_PASSTHRU; } |