diff options
Diffstat (limited to 'src/command.cpp')
-rw-r--r-- | src/command.cpp | 190 |
1 files changed, 131 insertions, 59 deletions
diff --git a/src/command.cpp b/src/command.cpp index f314eaf93..7d5b9e46c 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -1,9 +1,21 @@ /* + * Anope IRC Services * - * (C) 2008-2011 Robin Burchell <w00t@inspircd.org> - * (C) 2008-2017 Anope Team <team@anope.org> + * Copyright (C) 2008-2011 Robin Burchell <w00t@inspircd.org> + * Copyright (C) 2008-2017 Anope Team <team@anope.org> * - * Please read COPYING and README for further details. + * This file is part of Anope. Anope is free software; you can + * redistribute it and/or modify it under the terms of the GNU + * General Public License as published by the Free Software + * Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see see <http://www.gnu.org/licenses/>. */ #include "services.h" @@ -11,14 +23,20 @@ #include "users.h" #include "language.h" #include "config.h" -#include "bots.h" #include "opertype.h" -#include "access.h" -#include "regchannel.h" #include "channels.h" - -CommandSource::CommandSource(const Anope::string &n, User *user, NickCore *core, CommandReply *r, BotInfo *bi) : nick(n), u(user), nc(core), reply(r), - c(NULL), service(bi) +#include "event.h" +#include "bots.h" +#include "protocol.h" +#include "modules/botserv.h" +#include "modules/chanserv.h" + +CommandSource::CommandSource(const Anope::string &n, User *user, NickServ::Account *core, CommandReply *r, ServiceBot *bi) + : nick(n) + , u(user) + , nc(core) + , reply(r) + , service(bi) { } @@ -32,25 +50,63 @@ User *CommandSource::GetUser() return this->u; } -NickCore *CommandSource::GetAccount() +NickServ::Account *CommandSource::GetAccount() { return this->nc; } -AccessGroup CommandSource::AccessFor(ChannelInfo *ci) +Anope::string CommandSource::GetSource() +{ + if (u) + if (nc) + return this->u->GetMask() + " (" + this->nc->GetDisplay() + ")"; + else + return this->u->GetMask(); + else if (nc) + return nc->GetDisplay(); + else + return this->nick; +} + +const Anope::string &CommandSource::GetCommand() const +{ + return this->command.cname; +} + +void CommandSource::SetCommand(const Anope::string &command) +{ + this->command.cname = command; +} + +const Anope::string &CommandSource::GetPermission() const +{ + return this->command.permission; +} + +const CommandInfo &CommandSource::GetCommandInfo() const +{ + return this->command; +} + +void CommandSource::SetCommandInfo(const CommandInfo &ci) +{ + this->command = ci; +} + +ChanServ::AccessGroup CommandSource::AccessFor(ChanServ::Channel *ci) { if (this->u) return ci->AccessFor(this->u); else if (this->nc) return ci->AccessFor(this->nc); else - return AccessGroup(); + return ChanServ::AccessGroup(); } -bool CommandSource::IsFounder(ChannelInfo *ci) +bool CommandSource::IsFounder(ChanServ::Channel *ci) { if (this->u) - return ::IsFounder(this->u, ci); + return ci->IsFounder(this->u); else if (this->nc) return *this->nc == ci->GetFounder(); return false; @@ -60,8 +116,10 @@ bool CommandSource::HasCommand(const Anope::string &cmd) { if (this->u) return this->u->HasCommand(cmd); - else if (this->nc && this->nc->o) - return this->nc->o->ot->HasCommand(cmd); + + if (this->nc && this->nc->GetOper()) + return this->nc->GetOper()->HasCommand(cmd); + return false; } @@ -69,8 +127,10 @@ bool CommandSource::HasPriv(const Anope::string &cmd) { if (this->u) return this->u->HasPriv(cmd); - else if (this->nc && this->nc->o) - return this->nc->o->ot->HasPriv(cmd); + + if (this->nc && this->nc->GetOper()) + return this->nc->GetOper()->HasPriv(cmd); + return false; } @@ -79,7 +139,7 @@ bool CommandSource::IsServicesOper() if (this->u) return this->u->IsServicesOper(); else if (this->nc) - return this->nc->IsServicesOper(); + return this->nc->GetOper() != nullptr; return false; } @@ -88,23 +148,31 @@ bool CommandSource::IsOper() if (this->u) return this->u->HasMode("OPER"); else if (this->nc) - return this->nc->IsServicesOper(); + return this->nc->GetOper() != nullptr; return false; } -void CommandSource::Reply(const char *message, ...) +bool CommandSource::HasOverridePriv(const Anope::string &priv) { - va_list args; - char buf[4096]; // Messages can be really big. + if (!HasPriv(priv)) + return false; - const char *translated_message = Language::Translate(this->nc, message); + override = true; + return true; +} - va_start(args, message); - vsnprintf(buf, sizeof(buf), translated_message, args); +bool CommandSource::HasOverrideCommand(const Anope::string &priv) +{ + if (!HasCommand(priv)) + return false; - this->Reply(Anope::string(buf)); + override = true; + return true; +} - va_end(args); +bool CommandSource::IsOverride() const +{ + return override; } void CommandSource::Reply(const Anope::string &message) @@ -114,15 +182,14 @@ void CommandSource::Reply(const Anope::string &message) sepstream sep(translated_message, '\n', true); Anope::string tok; while (sep.GetToken(tok)) - this->reply->SendMessage(this->service, tok); + this->reply->SendMessage(*this->service, tok); } -Command::Command(Module *o, const Anope::string &sname, size_t minparams, size_t maxparams) : Service(o, "Command", sname), max_params(maxparams), min_params(minparams), module(o) -{ - allow_unregistered = require_user = false; -} - -Command::~Command() +Command::Command(Module *o, const Anope::string &sname, size_t minparams, size_t maxparams) : Service(o, NAME, sname) + , max_params(maxparams) + , min_params(minparams) + , module(o) + , logger(this) { } @@ -146,13 +213,13 @@ void Command::SendSyntax(CommandSource &source) Anope::string s = Language::Translate(source.GetAccount(), _("Syntax")); if (!this->syntax.empty()) { - source.Reply("%s: \002%s %s\002", s.c_str(), source.command.c_str(), Language::Translate(source.GetAccount(), this->syntax[0].c_str())); + source.Reply("{0}: \002{1} {2}\002", s, source.GetCommand(), Language::Translate(source.GetAccount(), this->syntax[0].c_str())); Anope::string spaces(s.length(), ' '); for (unsigned i = 1, j = this->syntax.size(); i < j; ++i) - source.Reply("%s \002%s %s\002", spaces.c_str(), source.command.c_str(), Language::Translate(source.GetAccount(), this->syntax[i].c_str())); + source.Reply("{0} \002{1} {2}\002", spaces, source.GetCommand(), Language::Translate(source.GetAccount(), this->syntax[i].c_str())); } else - source.Reply("%s: \002%s\002", s.c_str(), source.command.c_str()); + source.Reply("{0}: \002{1}\002", s, source.GetCommand()); } bool Command::AllowUnregistered() const @@ -182,7 +249,7 @@ const Anope::string Command::GetDesc(CommandSource &) const void Command::OnServHelp(CommandSource &source) { - source.Reply(" %-14s %s", source.command.c_str(), Language::Translate(source.nc, this->GetDesc(source).c_str())); + source.Reply(Anope::printf(" %-14s %s", source.GetCommand().c_str(), Language::Translate(source.nc, this->GetDesc(source).c_str()))); } bool Command::OnHelp(CommandSource &source, const Anope::string &subcommand) { return false; } @@ -192,7 +259,7 @@ void Command::OnSyntaxError(CommandSource &source, const Anope::string &subcomma this->SendSyntax(source); bool has_help = source.service->commands.find("HELP") != source.service->commands.end(); if (has_help) - source.Reply(MORE_INFO, Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), source.command.c_str()); + source.Reply(_("\002{0}{1} HELP {2}\002 for more information."), Config->StrictPrivmsg, source.service->nick, source.GetCommand()); } void Command::Run(CommandSource &source, const Anope::string &message) @@ -217,21 +284,21 @@ void Command::Run(CommandSource &source, const Anope::string &message) if (it == source.service->commands.end()) { if (has_help) - source.Reply(_("Unknown command \002%s\002. \"%s%s HELP\" for help."), message.c_str(), Config->StrictPrivmsg.c_str(), source.service->nick.c_str()); + source.Reply(_("Unknown command \002{0}\002. \"{1}{2} HELP\" for help."), message, Config->StrictPrivmsg, source.service->nick); else - source.Reply(_("Unknown command \002%s\002."), message.c_str()); + source.Reply(_("Unknown command \002{0}\002."), message); return; } const CommandInfo &info = it->second; - ServiceReference<Command> c("Command", info.name); + ServiceReference<Command> c(info.name); if (!c) { if (has_help) - source.Reply(_("Unknown command \002%s\002. \"%s%s HELP\" for help."), message.c_str(), Config->StrictPrivmsg.c_str(), source.service->nick.c_str()); + source.Reply(_("Unknown command \002{0}\002. \"{1}{2} HELP\" for help."), message, Config->StrictPrivmsg, source.service->nick); else - source.Reply(_("Unknown command \002%s\002."), message.c_str()); - Log(source.service) << "Command " << it->first << " exists on me, but its service " << info.name << " was not found!"; + source.Reply(_("Unknown command \002{0}\002."), message); + source.service->logger.Log("Command {0} exists on me, but its service {1} was not found!", it->first, info.name); return; } @@ -255,17 +322,15 @@ void Command::Run(CommandSource &source, const Anope::string &cmdname, const Com // Command requires registered users only if (!this->AllowUnregistered() && !source.nc) { - source.Reply(NICK_IDENTIFY_REQUIRED); + source.Reply(_("Password authentication required for that command.")); if (source.GetUser()) - Log(LOG_NORMAL, "access_denied_unreg", source.service) << "Access denied for unregistered user " << source.GetUser()->GetMask() << " with command " << cmdname; + Anope::Logger.User(source.service).Category("access_denied_unreg").Log(_("Access denied for unregistered user {0} with command {1}"), source.GetUser()->GetMask(), cmdname); return; } - source.command = cmdname; - source.permission = info.permission; + source.SetCommandInfo(info); - EventReturn MOD_RESULT; - FOREACH_RESULT(OnPreCommand, MOD_RESULT, (source, this, params)); + EventReturn MOD_RESULT = EventManager::Get()->Dispatch(&Event::PreCommand::OnPreCommand, source, this, params); if (MOD_RESULT == EVENT_STOP) return; @@ -278,23 +343,30 @@ void Command::Run(CommandSource &source, const Anope::string &cmdname, const Com // If the command requires a permission, and they aren't registered or don't have the required perm, DENIED if (!info.permission.empty() && !source.HasCommand(info.permission)) { - source.Reply(ACCESS_DENIED); + if (!source.IsOper()) + source.Reply(_("Access denied. You are not a Services Operator.")); + else + source.Reply(_("Access denied. You do not have access to command \002{0}\002."), info.permission); if (source.GetUser()) - Log(LOG_NORMAL, "access_denied", source.service) << "Access denied for user " << source.GetUser()->GetMask() << " with command " << cmdname; + Anope::Logger.User(source.service).Category("access_denied").Log(_("Access denied for user {0} with command {1}"), source.GetUser()->GetMask(), cmdname); return; } this->Execute(source, params); - FOREACH_MOD(OnPostCommand, (source, this, params)); + EventManager::Get()->Dispatch(&Event::PostCommand::OnPostCommand, source, this, params); } -bool Command::FindCommandFromService(const Anope::string &command_service, BotInfo* &bot, Anope::string &name) +bool Command::FindCommandFromService(const Anope::string &command_service, ServiceBot* &bot, Anope::string &name) { bot = NULL; - for (botinfo_map::iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it) + for (std::pair<Anope::string, User *> p : UserListByNick) { - BotInfo *bi = it->second; + User *u = p.second; + if (u->type != UserType::BOT) + continue; + + ServiceBot *bi = anope_dynamic_static_cast<ServiceBot *>(u); for (CommandInfo::map::const_iterator cit = bi->commands.begin(), cit_end = bi->commands.end(); cit != cit_end; ++cit) { @@ -309,7 +381,7 @@ bool Command::FindCommandFromService(const Anope::string &command_service, BotIn return true; } } - + return false; } |