summaryrefslogtreecommitdiff
path: root/src/command.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/command.cpp')
-rw-r--r--src/command.cpp190
1 files changed, 131 insertions, 59 deletions
diff --git a/src/command.cpp b/src/command.cpp
index 35a99eb80..02decd1b7 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-2016 Anope Team <team@anope.org>
+ * Copyright (C) 2008-2011 Robin Burchell <w00t@inspircd.org>
+ * Copyright (C) 2008-2016 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;
}