summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2011-07-14 02:31:12 -0400
committerAdam <Adam@anope.org>2011-07-14 02:31:12 -0400
commitf858164deed48f2dcacd5ffc06a55398a54da7e8 (patch)
tree89c3cf36bd8e94942370135218d67d6d17ee222e /src
parent924f6849fee4598a1a3a7f1a98d96b79e5ffd3b4 (diff)
Rewrote how commands are handled within Anope.
This allows naming commands and having spaces within command names.
Diffstat (limited to 'src')
-rw-r--r--src/bots.cpp150
-rw-r--r--src/channels.cpp58
-rw-r--r--src/chanserv.cpp14
-rw-r--r--src/command.cpp64
-rw-r--r--src/commands.cpp183
-rw-r--r--src/config.cpp326
-rw-r--r--src/init.cpp7
-rw-r--r--src/language.cpp9
-rw-r--r--src/logger.cpp36
-rw-r--r--src/main.cpp4
-rw-r--r--src/misc.cpp2
-rw-r--r--src/modes.cpp23
-rw-r--r--src/modulemanager.cpp11
-rw-r--r--src/modules.cpp43
-rw-r--r--src/operserv.cpp289
-rw-r--r--src/protocol.cpp35
-rw-r--r--src/regchannel.cpp20
-rw-r--r--src/servers.cpp1
-rw-r--r--src/users.cpp37
19 files changed, 453 insertions, 859 deletions
diff --git a/src/bots.cpp b/src/bots.cpp
index f48a90228..13947c0bb 100644
--- a/src/bots.cpp
+++ b/src/bots.cpp
@@ -8,6 +8,7 @@
#include "services.h"
#include "modules.h"
#include "commands.h"
+#include "oper.h"
Anope::insensitive_map<BotInfo *> BotListByNick;
Anope::map<BotInfo *> BotListByUID;
@@ -35,30 +36,31 @@ BotInfo::BotInfo(const Anope::string &nnick, const Anope::string &nuser, const A
this->SetModeInternal(ModeManager::FindUserModeByName(UMODE_PROTECTED));
this->SetModeInternal(ModeManager::FindUserModeByName(UMODE_GOD));
- for (unsigned i = 0; i < Config->LogInfos.size(); ++i)
- {
- LogInfo *l = Config->LogInfos[i];
-
- if (ircd && !ircd->join2msg && !l->Inhabit)
- continue;
-
- for (std::list<Anope::string>::const_iterator sit = l->Targets.begin(), sit_end = l->Targets.end(); sit != sit_end; ++sit)
+ if (Config)
+ for (unsigned i = 0; i < Config->LogInfos.size(); ++i)
{
- const Anope::string &target = *sit;
+ LogInfo *l = Config->LogInfos[i];
+
+ if (ircd && !ircd->join2msg && !l->Inhabit)
+ continue;
- if (target[0] == '#')
+ for (std::list<Anope::string>::const_iterator sit = l->Targets.begin(), sit_end = l->Targets.end(); sit != sit_end; ++sit)
{
- Channel *c = findchan(target);
- if (!c)
- c = new Channel(target);
- c->SetFlag(CH_LOGCHAN);
- c->SetFlag(CH_PERSIST);
-
- if (!c->FindUser(this))
- this->Join(c, &Config->BotModeList);
+ const Anope::string &target = *sit;
+
+ if (target[0] == '#')
+ {
+ Channel *c = findchan(target);
+ if (!c)
+ c = new Channel(target);
+ c->SetFlag(CH_LOGCHAN);
+ c->SetFlag(CH_PERSIST);
+
+ if (!c->FindUser(this))
+ this->Join(c, &Config->BotModeList);
+ }
}
}
- }
}
BotInfo::~BotInfo()
@@ -79,20 +81,20 @@ BotInfo::~BotInfo()
ci->bi = NULL;
}
- for (CommandMap::const_iterator it = this->Commands.begin(), it_end = this->Commands.end(); it != it_end;)
- {
- Command *c = it->second;
- ++it;
-
- if (c->module)
- c->module->DelCommand(this, c);
- }
-
BotListByNick.erase(this->nick);
if (!this->uid.empty())
BotListByUID.erase(this->uid);
}
+void BotInfo::GenerateUID()
+{
+ if (!this->uid.empty())
+ throw CoreException("Bot already has a uid?");
+ this->uid = ts6_uid_retrieve();
+ BotListByUID[this->uid] = this;
+ UserListByUID[this->uid] = this;
+}
+
void BotInfo::SetNewNick(const Anope::string &newnick)
{
UserListByNick.erase(this->nick);
@@ -154,7 +156,7 @@ void BotInfo::UnAssign(User *u, ChannelInfo *ci)
void BotInfo::Join(Channel *c, ChannelStatus *status)
{
- if (Config->BSSmartJoin)
+ if (Config && ircdproto && Config->BSSmartJoin)
{
std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> bans = c->GetModeList(CMODE_BAN);
@@ -179,7 +181,8 @@ void BotInfo::Join(Channel *c, ChannelStatus *status)
}
c->JoinUser(this);
- ircdproto->SendJoin(this, c, status);
+ if (ircdproto)
+ ircdproto->SendJoin(this, c, status);
FOREACH_MOD(I_OnBotJoin, OnBotJoin(c, this));
}
@@ -198,6 +201,91 @@ void BotInfo::Part(Channel *c, const Anope::string &reason)
void BotInfo::OnMessage(User *u, const Anope::string &message)
{
- mod_run_cmd(this, u, NULL, message);
+ std::vector<Anope::string> params = BuildStringVector(message);
+
+ command_map::iterator it = this->commands.end();
+ unsigned count = 0;
+ for (unsigned max = params.size(); it == this->commands.end() && max > 0; --max)
+ {
+ Anope::string full_command;
+ for (unsigned i = 0; i < max; ++i)
+ full_command += " " + params[i];
+ full_command.erase(full_command.begin());
+
+ ++count;
+ it = this->commands.find(full_command);
+ }
+
+ if (it == this->commands.end())
+ {
+ u->SendMessage(this, _("Unknown command \002%s\002. \"%s%s HELP\" for help."), message.c_str(), Config->UseStrictPrivMsgString.c_str(), this->nick.c_str());
+ return;
+ }
+
+ service_reference<Command> c(it->second);
+ if (!c)
+ {
+ u->SendMessage(this, _("Unknown command \002%s\002. \"%s%s HELP\" for help."), message.c_str(), Config->UseStrictPrivMsgString.c_str(), this->nick.c_str());
+ Log(this) << "Command " << it->first << " exists on me, but its service " << it->second << " was not found!";
+ return;
+ }
+
+ // Command requires registered users only
+ if (!c->HasFlag(CFLAG_ALLOW_UNREGISTERED) && !u->IsIdentified())
+ {
+ u->SendMessage(this, NICK_IDENTIFY_REQUIRED);
+ Log(LOG_COMMAND, "denied", this) << "Access denied for unregistered user " << u->GetMask() << " with command " << c->name;
+ return;
+ }
+
+ for (unsigned i = 0, j = params.size() - (count - 1); i < j; ++i)
+ params.erase(params.begin());
+
+ while (c->MaxParams > 0 && params.size() > c->MaxParams)
+ {
+ params[c->MaxParams - 1] += " " + params[c->MaxParams];
+ params.erase(params.begin() + c->MaxParams);
+ }
+
+ CommandSource source;
+ source.u = u;
+ source.c = NULL;
+ source.owner = this;
+ source.service = this;
+ source.command = it->first;
+
+ EventReturn MOD_RESULT;
+ FOREACH_RESULT(I_OnPreCommand, OnPreCommand(source, c, params));
+ if (MOD_RESULT == EVENT_STOP)
+ {
+ source.DoReply();
+ return;
+ }
+
+
+ if (params.size() < c->MinParams)
+ {
+ c->OnSyntaxError(source, !params.empty() ? params[params.size() - 1] : "");
+ source.DoReply();
+ return;
+ }
+
+ // If the command requires a permission, and they aren't registered or don't have the required perm, DENIED
+ if (!c->permission.empty() && !u->HasCommand(c->permission))
+ {
+ u->SendMessage(this, ACCESS_DENIED);
+ Log(LOG_COMMAND, "denied", this) << "Access denied for user " << u->GetMask() << " with command " << c->name;
+ source.DoReply();
+ return;
+ }
+
+ dynamic_reference<User> user_reference(u);
+ c->Execute(source, params);
+ if (user_reference)
+ {
+ FOREACH_MOD(I_OnPostCommand, OnPostCommand(source, c, params));
+ if (user_reference)
+ source.DoReply();
+ }
}
diff --git a/src/channels.cpp b/src/channels.cpp
index d64a8b378..26ae18308 100644
--- a/src/channels.cpp
+++ b/src/channels.cpp
@@ -122,27 +122,6 @@ void Channel::JoinUser(User *user)
ircdproto->SendChannel(this);
this->Reset();
}
-
- if (!Config->s_BotServ.empty() && this->ci && this->ci->bi)
- {
- /**
- * We let the bot join even if it was an ignored user, as if we don't,
- * and the ignored user doesnt just leave, the bot will never
- * make it into the channel, leaving the channel botless even for
- * legit users - Rob
- **/
- if (this->users.size() >= Config->BSMinUsers && !this->FindUser(this->ci->bi))
- this->ci->bi->Join(this, &Config->BotModeList);
- /* Only display the greet if the main uplink we're connected
- * to has synced, or we'll get greet-floods when the net
- * recovers from a netsplit. -GD
- */
- if (this->FindUser(this->ci->bi) && this->ci->botflags.HasFlag(BS_GREET) && user->Account() && !user->Account()->greet.empty() && check_access(user, this->ci, CA_GREET) && user->server->IsSynced())
- {
- ircdproto->SendPrivmsg(this->ci->bi, this->name, "[%s] %s", user->Account()->display.c_str(), user->Account()->greet.c_str());
- this->ci->bi->lastmsg = Anope::CurTime;
- }
- }
}
/** Remove a user internally from the channel
@@ -154,6 +133,7 @@ void Channel::DeleteUser(User *user)
update_cs_lastseen(user, this->ci);
Log(user, this, "leaves");
+ FOREACH_MOD(I_OnLeaveChannel, OnLeaveChannel(user, this));
CUserList::iterator cit, cit_end = this->users.end();
for (cit = this->users.begin(); (*cit)->user != user && cit != cit_end; ++cit);
@@ -170,14 +150,13 @@ void Channel::DeleteUser(User *user)
UChannelList::iterator uit, uit_end = user->chans.end();
for (uit = user->chans.begin(); (*uit)->chan != this && uit != uit_end; ++uit);
if (uit == uit_end)
- {
Log(LOG_DEBUG) << "Channel::DeleteUser() tried to delete nonexistant channel " << this->name << " from " << user->nick << "'s channel list";
- return;
+ else
+ {
+ delete *uit;
+ user->chans.erase(uit);
}
- delete *uit;
- user->chans.erase(uit);
-
/* Channel is persistant, it shouldn't be deleted and the service bot should stay */
if (this->HasFlag(CH_PERSIST) || (this->ci && this->ci->HasFlag(CI_PERSIST)))
return;
@@ -192,12 +171,7 @@ void Channel::DeleteUser(User *user)
if (this->HasFlag(CH_INHABIT))
return;
- /* check for BSMinUsers and part the BotServ bot from the channel
- * Use <= because the bot is included in this->users.size()
- */
- if (!Config->s_BotServ.empty() && this->ci && this->ci->bi && this->users.size() <= Config->BSMinUsers && this->FindUser(this->ci->bi))
- this->ci->bi->Part(this->ci->c);
- else if (this->users.empty())
+ if (this->users.empty())
delete this;
}
@@ -298,10 +272,7 @@ void Channel::SetModeInternal(ChannelMode *cm, const Anope::string &param, bool
return;
}
- BotInfo *bi = NULL;
- if (!Config->s_BotServ.empty())
- bi = findbot(param);
- User *u = bi ? bi : finduser(param);
+ User *u = finduser(param);
if (!u)
{
@@ -411,9 +382,7 @@ void Channel::RemoveModeInternal(ChannelMode *cm, const Anope::string &param, bo
return;
}
- BotInfo *bi = NULL;
- if (!Config->s_BotServ.empty())
- bi = findbot(param);
+ BotInfo *bi = findbot(param);
User *u = bi ? bi : finduser(param);
if (!u)
@@ -467,16 +436,7 @@ void Channel::RemoveModeInternal(ChannelMode *cm, const Anope::string &param, bo
this->UnsetFlag(CH_PERSIST);
if (ci)
- {
ci->UnsetFlag(CI_PERSIST);
- if (!Config->s_BotServ.empty() && ci->bi && this->FindUser(ci->bi) && Config->BSMinUsers && this->users.size() <= Config->BSMinUsers)
- {
- bool empty = this->users.size() == 1;
- this->ci->bi->Part(this);
- if (empty)
- return;
- }
- }
if (this->users.empty())
{
@@ -780,7 +740,7 @@ void Channel::KickInternal(const Anope::string &source, const Anope::string &nic
{
User *sender = finduser(source);
BotInfo *bi = NULL;
- if (!Config->s_BotServ.empty() && this->ci)
+ if (this->ci && this->ci->bi)
bi = findbot(nick);
User *target = bi ? bi : finduser(nick);
if (!target)
diff --git a/src/chanserv.cpp b/src/chanserv.cpp
index 42d637c38..6a39340ae 100644
--- a/src/chanserv.cpp
+++ b/src/chanserv.cpp
@@ -13,7 +13,6 @@
#include "services.h"
#include "modules.h"
-#include "chanserv.h"
registered_channel_map RegisteredChannelList;
@@ -124,8 +123,7 @@ void check_modes(Channel *c)
/* Check for mode bouncing */
if (c->server_modecount >= 3 && c->chanserv_modecount >= 3)
{
- ircdproto->SendGlobops(NULL, "Warning: unable to set modes on channel %s. Are your servers' U:lines configured correctly?", c->name.c_str());
- Log() << "Bouncy modes on channel " << c->name;
+ Log() << "Warning: unable to set modes on channel " << c->name << ". Are your servers' U:lines configured correctly?";
c->bouncy_modes = 1;
return;
}
@@ -367,11 +365,12 @@ Anope::string get_xop_level(int level)
ChanServTimer::ChanServTimer(Channel *chan) : Timer(Config->CSInhabit), c(chan)
{
- if (!chanserv || !c)
+ BotInfo *bi = findbot(Config->ChanServ);
+ if (!bi || !c)
return;
c->SetFlag(CH_INHABIT);
if (!c->ci || !c->ci->bi)
- chanserv->Bot()->Join(c);
+ bi->Join(c);
else if (!c->FindUser(c->ci->bi))
c->ci->bi->Join(c);
}
@@ -385,8 +384,9 @@ void ChanServTimer::Tick(time_t)
if (!c->ci || !c->ci->bi)
{
- if (chanserv)
- chanserv->Bot()->Part(c);
+ BotInfo *bi = findbot(Config->ChanServ);
+ if (bi)
+ bi->Part(c);
}
else if (c->users.size() == 1 || c->users.size() < Config->BSMinUsers)
c->ci->bi->Part(c);
diff --git a/src/command.cpp b/src/command.cpp
index f13be6ee5..8803edf05 100644
--- a/src/command.cpp
+++ b/src/command.cpp
@@ -7,6 +7,7 @@
#include "services.h"
#include "modules.h"
+#include "commands.h"
void CommandSource::Reply(const char *message, ...)
{
@@ -42,29 +43,25 @@ void CommandSource::DoReply()
const Anope::string &message = *it;
// Send to the user if the reply is more than one line
- if (!this->fantasy || !this->ci || this->reply.size() > 1)
+ if (!this->c || !this->c->ci || this->reply.size() > 1)
u->SendMessage(this->service, message);
- else if (this->ci->botflags.HasFlag(BS_MSG_PRIVMSG))
- ircdproto->SendPrivmsg(this->service, this->ci->name, message.c_str());
- else if (this->ci->botflags.HasFlag(BS_MSG_NOTICE))
- ircdproto->SendNotice(this->service, this->ci->name, message.c_str());
- else if (this->ci->botflags.HasFlag(BS_MSG_NOTICEOPS))
- ircdproto->SendNoticeChanops(this->service, this->ci->c, message.c_str());
+ else if (this->c->ci->botflags.HasFlag(BS_MSG_PRIVMSG))
+ ircdproto->SendPrivmsg(this->service, this->c->name, message.c_str());
+ else if (this->c->ci->botflags.HasFlag(BS_MSG_NOTICE))
+ ircdproto->SendNotice(this->service, this->c->name, message.c_str());
+ else if (this->c->ci->botflags.HasFlag(BS_MSG_NOTICEOPS))
+ ircdproto->SendNoticeChanops(this->service, this->c, message.c_str());
else
u->SendMessage(this->service, message);
}
}
-Command::Command(const Anope::string &sname, size_t min_params, size_t max_params, const Anope::string &spermission) : Flags<CommandFlag>(CommandFlagStrings), MaxParams(max_params), MinParams(min_params), name(sname), permission(spermission)
+Command::Command(Module *owner, const Anope::string &sname, size_t min_params, size_t max_params, const Anope::string &spermission) : Service(owner, sname), Flags<CommandFlag>(CommandFlagStrings), MaxParams(max_params), MinParams(min_params), permission(spermission), module(owner)
{
- this->module = NULL;
- this->service = NULL;
}
Command::~Command()
{
- if (this->module)
- this->module->DelCommand(this->service, this);
}
void Command::SetDesc(const Anope::string &d)
@@ -72,37 +69,52 @@ void Command::SetDesc(const Anope::string &d)
this->desc = d;
}
-const Anope::string &Command::GetDesc() const
+void Command::ClearSyntax()
{
- return this->desc;
+ this->syntax.clear();
}
-void Command::OnServHelp(CommandSource &source)
+void Command::SetSyntax(const Anope::string &s)
{
- source.Reply(" %-14s %s", this->name.c_str(), translate(source.u, (this->GetDesc().c_str())));
+ this->syntax.push_back(s);
}
-bool Command::OnHelp(CommandSource &source, const Anope::string &subcommand) { return false; }
+void Command::SendSyntax(CommandSource &source)
+{
+ if (!this->syntax.empty())
+ {
+ source.Reply(_("Syntax: \002%s %s\002"), source.command.c_str(), this->syntax[0].c_str());
+ for (unsigned i = 1, j = this->syntax.size(); i < j; ++i)
+ source.Reply(" \002%s %s\002", source.command.c_str(), this->syntax[i].c_str());
+ }
+}
-void Command::OnSyntaxError(CommandSource &source, const Anope::string &subcommand) { }
+void Command::SendSyntax(CommandSource &source, const Anope::string &syntax)
+{
+ source.Reply(_("Syntax: \002%s %s\002"), source.command.c_str(), syntax.c_str());
+ source.Reply(MORE_INFO, Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str(), source.command.c_str());
+}
-void Command::SetPermission(const Anope::string &reststr)
+const Anope::string &Command::GetDesc() const
{
- this->permission = reststr;
+ return this->desc;
}
-bool Command::AddSubcommand(Module *creator, Command *c)
+void Command::OnServHelp(CommandSource &source)
{
- return false;
+ source.Reply(" %-14s %s", source.command.c_str(), translate(source.u, (this->GetDesc().c_str())));
}
-bool Command::DelSubcommand(Command *c)
+bool Command::OnHelp(CommandSource &source, const Anope::string &subcommand) { return false; }
+
+void Command::OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
- return false;
+ this->SendSyntax(source);
+ source.Reply(MORE_INFO, Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str(), source.command.c_str());
}
-Command *Command::FindSubcommand(const Anope::string &subcommand)
+void Command::SetPermission(const Anope::string &reststr)
{
- return NULL;
+ this->permission = reststr;
}
diff --git a/src/commands.cpp b/src/commands.cpp
deleted file mode 100644
index fea6e4376..000000000
--- a/src/commands.cpp
+++ /dev/null
@@ -1,183 +0,0 @@
-/* Routines for looking up commands in a *Serv command list.
- *
- * (C) 2003-2011 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- *
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
- */
-
-#include "services.h"
-#include "modules.h"
-#include "hashcomp.h"
-
-Command *FindCommand(BotInfo *bi, const Anope::string &name)
-{
- if (!bi || bi->Commands.empty() || name.empty())
- return NULL;
-
- CommandMap::iterator it = bi->Commands.find(name);
-
- if (it != bi->Commands.end())
- return it->second;
-
- return NULL;
-}
-
-void mod_run_cmd(BotInfo *bi, User *u, ChannelInfo *ci, const Anope::string &fullmessage)
-{
- if (!bi || !u)
- return;
-
- spacesepstream sep(fullmessage);
- Anope::string command, message;
-
- if (!sep.GetToken(command))
- return;
- message = sep.GetRemaining();
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(I_OnPreCommandRun, OnPreCommandRun(u, bi, command, message, ci));
- if (MOD_RESULT == EVENT_STOP)
- return;
-
- Command *c = FindCommand(bi, command);
-
- mod_run_cmd(bi, u, ci, c, command, message);
-}
-
-void mod_run_cmd(BotInfo *bi, User *u, ChannelInfo *ci, Command *c, const Anope::string &command, const Anope::string &message)
-{
- if (!bi || !u)
- return;
-
- if (!c)
- {
- u->SendMessage(bi, _("Unknown command \002%s\002. \"%s%s HELP\" for help."), command.c_str(), Config->UseStrictPrivMsgString.c_str(), bi->nick.c_str());
- return;
- }
-
- // Command requires registered users only
- if (!c->HasFlag(CFLAG_ALLOW_UNREGISTERED) && !u->IsIdentified())
- {
- u->SendMessage(bi, NICK_IDENTIFY_REQUIRED, Config->UseStrictPrivMsgString.c_str(), Config->s_NickServ.c_str());
- Log(LOG_COMMAND, "denied", bi) << "Access denied for unregistered user " << u->GetMask() << " with command " << command;
- return;
- }
-
- std::vector<Anope::string> params;
- Anope::string curparam, endparam;
- spacesepstream sep(message);
- while (sep.GetToken(curparam))
- {
- // - 1 because params[0] corresponds with a maxparam of 1.
- if (params.size() >= c->MaxParams - 1)
- endparam += curparam + " ";
- else
- params.push_back(curparam);
- }
-
- if (!endparam.empty())
- {
- // Remove trailing space
- endparam.erase(endparam.length() - 1);
-
- // Add it
- params.push_back(endparam);
- }
-
- bool fantasy = ci != NULL;
- if (params.size() > 0 && !c->HasFlag(CFLAG_STRIP_CHANNEL) && ircdproto->IsChannelValid(params[0]))
- ci = cs_findchan(params[0]);
-
- CommandSource source;
- source.u = u;
- source.ci = ci;
- source.owner = bi;
- source.service = fantasy && ci ? ci->bi : c->service;
- source.fantasy = fantasy;
-
- if (params.size() < c->MinParams)
- {
- c->OnSyntaxError(source, !params.empty() ? params[params.size() - 1] : "");
- source.DoReply();
- return;
- }
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(I_OnPreCommand, OnPreCommand(source, c, params));
- if (MOD_RESULT == EVENT_STOP)
- {
- source.DoReply();
- return;
- }
-
- // If the command requires a permission, and they aren't registered or don't have the required perm, DENIED
- if (!c->permission.empty() && !u->HasCommand(c->permission))
- {
- u->SendMessage(bi, ACCESS_DENIED);
- Log(LOG_COMMAND, "denied", bi) << "Access denied for user " << u->GetMask() << " with command " << command;
- source.DoReply();
- return;
- }
-
- dynamic_reference<User> user_reference(u);
- CommandReturn ret = c->Execute(source, params);
- if (ret != MOD_STOP && user_reference)
- {
- FOREACH_MOD(I_OnPostCommand, OnPostCommand(source, c, params));
- source.DoReply();
- }
-}
-
-/**
- * Prints the help message for a given command.
- * @param bi Client the command is on
- * @param u User
- * @param ci Optional channel the command was executed one (fantasy)
- * @param cmd Command
- */
-void mod_help_cmd(BotInfo *bi, User *u, ChannelInfo *ci, const Anope::string &cmd)
-{
- if (!bi || !u || cmd.empty())
- return;
-
- spacesepstream tokens(cmd);
- Anope::string token;
- tokens.GetToken(token);
-
- Command *c = FindCommand(bi, token);
- Anope::string subcommand = tokens.StreamEnd() ? "" : tokens.GetRemaining();
-
- CommandSource source;
- source.u = u;
- source.ci = ci;
- source.owner = bi;
- source.service = ci ? ci->bi : bi;
- source.fantasy = ci != NULL;
-
- if (!c || (Config->HidePrivilegedCommands && !c->permission.empty() && !u->HasCommand(c->permission)) || !c->OnHelp(source, subcommand))
- source.Reply( _("No help available for \002%s\002."), cmd.c_str());
- else
- {
- source.Reply(" ");
-
- /* Inform the user what permission is required to use the command */
- if (!c->permission.empty())
- source.Reply(_("Access to this command requires the permission \002%s\002 to be present in your opertype."), c->permission.c_str());
-
- /* User isn't identified and needs to be to use this command */
- if (!c->HasFlag(CFLAG_ALLOW_UNREGISTERED) && !u->IsIdentified())
- source.Reply( _("You need to be identified to use this command."));
- /* User doesn't have the proper permission to use this command */
- else if (!c->permission.empty() && !u->HasCommand(c->permission))
- source.Reply(_("You cannot use this command."));
- /* User can use this command */
- else
- source.Reply(_("You can use this command."));
- }
-
- source.DoReply();
-}
diff --git a/src/config.cpp b/src/config.cpp
index 7d3efcb91..0d9341424 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -11,18 +11,17 @@
#include "services.h"
#include "config.h"
+#include "module.h"
/*************************************************************************/
ConfigurationFile services_conf("services.conf", false); // Services configuration file name
ServerConfig *Config = NULL;
-static Anope::string Modules;
static Anope::string UlineServers;
static Anope::string OSNotifications;
static Anope::string BSDefaults;
static Anope::string CSDefaults;
-static Anope::string temp_nsuserhost;
static Anope::string NSDefaults;
/*************************************************************************/
@@ -31,21 +30,6 @@ ServerConfig::ServerConfig() : config_data(), NSDefFlags(NickCoreFlagStrings), C
{
this->Read();
- if (!temp_nsuserhost.empty())
- {
- size_t at = temp_nsuserhost.find('@');
- if (at == Anope::string::npos)
- {
- this->NSEnforcerUser = temp_nsuserhost;
- this->NSEnforcerHost = this->ServiceHost;
- }
- else
- {
- this->NSEnforcerUser = temp_nsuserhost.substr(0, at);
- this->NSEnforcerHost = temp_nsuserhost.substr(at + 1);
- }
- }
-
if (NSDefaults.empty())
{
this->NSDefFlags.SetFlag(NI_SECURE);
@@ -155,8 +139,6 @@ ServerConfig::ServerConfig() : config_data(), NSDefFlags(NickCoreFlagStrings), C
this->BSDefFlags.SetFlag(BS_GREET);
else if (option.equals_ci("fantasy"))
this->BSDefFlags.SetFlag(BS_FANTASY);
- else if (option.equals_ci("symbiosis"))
- this->BSDefFlags.SetFlag(BS_SYMBIOSIS);
}
}
@@ -196,23 +178,12 @@ ServerConfig::ServerConfig() : config_data(), NSDefFlags(NickCoreFlagStrings), C
this->Ulines.push_back(uline);
}
- /* Modules Autoload building... :P */
- this->ModulesAutoLoad = BuildStringList(Modules);
-
if (this->LimitSessions)
{
if (this->MaxSessionKill && !this->SessionAutoKillExpiry)
this->SessionAutoKillExpiry = 1800; /* 30 minutes */
}
- if (!this->s_BotServ.empty())
- {
- if (this->BSFantasyCharacter.empty())
- this->BSFantasyCharacter = "!";
- if (this->BSFantasyCharacter.length() > 1)
- Log() << "*** " << this->BSFantasyCharacter << " is more than 1 character long. Only the first character will be used. The others will be ignored.";
- }
-
/* Check the user keys */
if (this->UserKey1 == this->UserKey2 || this->UserKey1 == this->UserKey3 || this->UserKey3 == this->UserKey2)
Log() << "Every UserKey must be different. It's for YOUR safety! Remember that!";
@@ -421,7 +392,7 @@ bool ValidateBantype(ServerConfig *, const Anope::string &, const Anope::string
bool ValidateChanServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data)
{
- if (!config->s_ChanServ.empty())
+ if (!config->ChanServ.empty())
{
if ((value.equals_ci("decription") || value.equals_ci("autokickreason")) && data.GetValue().empty())
throw ConfigException("The value for <" + tag + ":" + value + "> cannot be empty when ChanServ is enabled!");
@@ -435,7 +406,7 @@ bool ValidateChanServ(ServerConfig *config, const Anope::string &tag, const Anop
bool ValidateMemoServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data)
{
- if (!config->s_MemoServ.empty())
+ if (!config->MemoServ.empty())
{
if (value.equals_ci("description"))
{
@@ -448,7 +419,7 @@ bool ValidateMemoServ(ServerConfig *config, const Anope::string &tag, const Anop
bool ValidateBotServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data)
{
- if (!config->s_BotServ.empty())
+ if (!config->BotServ.empty())
{
if (value.equals_ci("description"))
{
@@ -471,7 +442,7 @@ bool ValidateBotServ(ServerConfig *config, const Anope::string &tag, const Anope
bool ValidateHostServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data)
{
- if (!config->s_HostServ.empty())
+ if (!config->HostServ.empty())
{
if (value.equals_ci("description") && data.GetValue().empty())
throw ConfigException("The value for <" + tag + ":" + value + "> cannot be empty when HostServ is enabled!");
@@ -494,7 +465,7 @@ bool ValidateLimitSessions(ServerConfig *config, const Anope::string &tag, const
bool ValidateOperServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data)
{
- if (!config->s_OperServ.empty())
+ if (!config->OperServ.empty())
{
if (value.equals_ci("description") && data.GetValue().empty())
throw ConfigException("The value for <" + tag + ":" + value + "> cannot be empty when OperServ is enabled!");
@@ -508,7 +479,7 @@ bool ValidateOperServ(ServerConfig *config, const Anope::string &tag, const Anop
bool ValidateGlobal(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data)
{
- if (!config->s_Global.empty())
+ if (!config->Global.empty())
{
if (value.equals_ci("description") && data.GetValue().empty())
throw ConfigException("The value for <" + tag + ":" + value + "> cannot be empty when Global is enabled!");
@@ -571,7 +542,7 @@ bool InitUplinks(ServerConfig *config, const Anope::string &)
return true;
}
-bool DoUplink(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
+static bool DoUplink(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
{
// Validation variables
Anope::string host = values[0].GetValue(), password = values[3].GetValue();
@@ -592,7 +563,7 @@ bool DoUplink(ServerConfig *config, const Anope::string &, const Anope::string *
return true;
}
-bool DoneUplinks(ServerConfig *config, const Anope::string &)
+static bool DoneUplinks(ServerConfig *config, const Anope::string &)
{
if (config->Uplinks.empty())
throw ConfigException("You must define at least one uplink block!");
@@ -746,27 +717,31 @@ static bool DoneInclude(ServerConfig *config, const Anope::string &)
bool InitModules(ServerConfig *, const Anope::string &)
{
- Modules.clear();
return true;
}
-bool DoModule(ServerConfig *conf, const Anope::string &, const Anope::string *, ValueList &values, int *)
+static bool DoModule(ServerConfig *conf, const Anope::string &, const Anope::string *, ValueList &values, int *)
{
// First we validate that there was a name in the module block
Anope::string module = values[0].GetValue();
ValueItem vi(module);
if (!ValidateNotEmpty(conf, "module", "name", vi))
throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
- // If the string isn't empty, add a space before we add the module name
- if (!Modules.empty())
- Modules += " ";
- // Add the module name to the string
- Modules += values[0].GetValue();
+ conf->ModulesAutoLoad.push_back(module);
return true;
}
-bool DoneModules(ServerConfig *, const Anope::string &)
+static bool DoneModules(ServerConfig *config, const Anope::string &)
{
+ if (Config)
+ {
+ for (std::list<Anope::string>::iterator it = Config->ModulesAutoLoad.begin(); it != Config->ModulesAutoLoad.end(); ++it)
+ if (std::find(config->ModulesAutoLoad.begin(), config->ModulesAutoLoad.end(), *it) == config->ModulesAutoLoad.end())
+ ModuleManager::UnloadModule(ModuleManager::FindModule(*it), NULL);
+ for (std::list<Anope::string>::iterator it = config->ModulesAutoLoad.begin(); it != config->ModulesAutoLoad.end(); ++it)
+ if (std::find(Config->ModulesAutoLoad.begin(), Config->ModulesAutoLoad.end(), *it) == Config->ModulesAutoLoad.end())
+ ModuleManager::LoadModule(*it, NULL);
+ }
return true;
}
@@ -809,7 +784,7 @@ bool InitLogs(ServerConfig *config, const Anope::string &)
return true;
}
-bool DoLogs(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
+static bool DoLogs(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
{
//{"target", "source", "logage", "inhabit", "admin", "override", "commands", "servers", "channels", "users", "other", "rawio", "debug"},
Anope::string targets = values[0].GetValue();
@@ -846,7 +821,7 @@ bool DoLogs(ServerConfig *config, const Anope::string &, const Anope::string *,
return true;
}
-bool DoneLogs(ServerConfig *config, const Anope::string &)
+static bool DoneLogs(ServerConfig *config, const Anope::string &)
{
Log() << "Loaded " << config->LogInfos.size() << " log blocks";
@@ -873,7 +848,7 @@ bool DoneLogs(ServerConfig *config, const Anope::string &)
{
BotInfo *bi = it->second;
if (!c->FindUser(bi))
- bi->Join(c, &config->BotModeList);
+ bi->Join(c, NULL);
}
}
}
@@ -882,6 +857,106 @@ bool DoneLogs(ServerConfig *config, const Anope::string &)
return true;
}
+/*************************************************************************/
+
+static bool InitCommands(ServerConfig *config, const Anope::string &)
+{
+ for (botinfo_map::iterator it = BotListByNick.begin(), it_end = BotListByNick.end(); it != it_end; ++it)
+ it->second->commands.clear();
+ return true;
+}
+
+static bool DoCommands(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
+{
+ Anope::string service = values[0].GetValue();
+ Anope::string name = values[1].GetValue();
+ Anope::string command = values[2].GetValue();
+
+ ValueItem vi(service);
+ if (!ValidateNotEmpty(config, "command", "service", vi))
+ throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
+
+ vi = ValueItem(name);
+ if (!ValidateNotEmpty(config, "command", "name", vi))
+ throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
+
+ vi = ValueItem(command);
+ if (!ValidateNotEmpty(config, "command", "command", vi))
+ throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
+
+ BotInfo *bi = findbot(service);
+ if (bi == NULL)
+ throw ConfigException("Command " + name + " exists for nonexistant service " + service);
+
+ if (bi->commands.count(name))
+ throw ConfigException("Command name " + name + " already exists on " + bi->nick);
+
+ bi->commands[name] = command;
+ return true;
+}
+
+static bool DoneCommands(ServerConfig *config, const Anope::string &)
+{
+ return true;
+}
+
+/*************************************************************************/
+
+static std::set<Anope::string> services;
+static bool InitServices(ServerConfig *config, const Anope::string &)
+{
+ services.clear();
+ return true;
+}
+
+static bool DoServices(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
+{
+ Anope::string nick = values[0].GetValue();
+ Anope::string user = values[1].GetValue();
+ Anope::string host = values[2].GetValue();
+ Anope::string gecos = values[3].GetValue();
+
+ ValueItem vi(nick);
+ if (!ValidateNotEmpty(config, "service", "nick", vi))
+ throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
+
+ vi = ValueItem(user);
+ if (!ValidateNotEmpty(config, "service", "user", vi))
+ throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
+
+ vi = ValueItem(host);
+ if (!ValidateNotEmpty(config, "service", "host", vi))
+ throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
+
+ vi = ValueItem(gecos);
+ if (!ValidateNotEmpty(config, "service", "gecos", vi))
+ throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
+
+ services.insert(nick);
+ BotInfo *bi = findbot(nick);
+ if (bi != NULL)
+ return true;
+ bi = new BotInfo(nick, user, host, gecos);
+ bi->SetFlag(BI_CONF);
+ return true;
+}
+
+static bool DoneServices(ServerConfig *config, const Anope::string &)
+{
+ for (botinfo_map::iterator it = BotListByNick.begin(), it_end = BotListByNick.end(); it != it_end;)
+ {
+ BotInfo *bi = it->second;
+ ++it;
+
+ if (bi->HasFlag(BI_CONF) && services.count(bi->nick) == 0)
+ delete bi;
+ }
+ services.clear();
+ return true;
+}
+
+/*************************************************************************/
+
ConfigurationFile::ConfigurationFile(const Anope::string &n, bool e) : name(n), executable(e), fp(NULL)
{
}
@@ -1000,8 +1075,6 @@ ConfigItems::ConfigItems(ServerConfig *conf)
{"serverinfo", "description", "", new ValueContainerString(&conf->ServerDesc), DT_STRING | DT_NORELOAD, ValidateNotEmpty},
{"serverinfo", "localhost", "", new ValueContainerString(&conf->LocalHost), DT_HOSTNAME | DT_NORELOAD, NoValidation},
{"serverinfo", "id", "", new ValueContainerString(&conf->Numeric), DT_NOSPACES | DT_NORELOAD, NoValidation},
- {"serverinfo", "ident", "", new ValueContainerString(&conf->ServiceUser), DT_STRING | DT_NORELOAD, ValidateNotEmpty},
- {"serverinfo", "hostname", "", new ValueContainerString(&conf->ServiceHost), DT_STRING | DT_NORELOAD, ValidateNotEmpty},
{"serverinfo", "pid", "services.pid", new ValueContainerString(&conf->PIDFilename), DT_STRING | DT_NORELOAD, ValidateNotEmpty},
{"serverinfo", "motd", "services.motd", new ValueContainerString(&conf->MOTDFilename), DT_STRING, ValidateNotEmpty},
{"networkinfo", "networkname", "", new ValueContainerString(&conf->NetworkName), DT_STRING, ValidateNotEmpty},
@@ -1035,10 +1108,8 @@ ConfigItems::ConfigItems(ServerConfig *conf)
{"options", "botmodes", "", new ValueContainerString(&conf->BotModes), DT_STRING, NoValidation},
{"options", "retrywait", "60", new ValueContainerInt(&conf->RetryWait), DT_INTEGER, ValidateNotZero},
{"options", "hideprivilegedcommands", "no", new ValueContainerBool(&conf->HidePrivilegedCommands), DT_BOOLEAN, NoValidation},
- {"nickserv", "nick", "NickServ", new ValueContainerString(&conf->s_NickServ), DT_STRING | DT_NORELOAD, ValidateNotEmpty},
- {"nickserv", "description", "Nickname Registration Service", new ValueContainerString(&conf->desc_NickServ), DT_STRING | DT_NORELOAD, ValidateNotEmpty},
+ {"nickserv", "name", "NickServ", new ValueContainerString(&conf->NickServ), DT_STRING, NoValidation},
{"nickserv", "emailregistration", "no", new ValueContainerBool(&conf->NSEmailReg), DT_BOOLEAN, NoValidation},
- {"nickserv", "modules", "", new ValueContainerString(&conf->NickCoreModules), DT_STRING, NoValidation},
{"nickserv", "forceemail", "no", new ValueContainerBool(&conf->NSForceEmail), DT_BOOLEAN, ValidateEmailReg},
{"nickserv", "confirmemailchanges", "no", new ValueContainerBool(&conf->NSConfirmEmailChanges), DT_BOOLEAN, NoValidation},
{"nickserv", "defaults", "secure memosignon memoreceive", new ValueContainerString(&NSDefaults), DT_STRING, NoValidation},
@@ -1051,7 +1122,8 @@ ConfigItems::ConfigItems(ServerConfig *conf)
{"nickserv", "unconfirmedexpire", "0", new ValueContainerTime(&conf->NSUnconfirmedExpire), DT_TIME, ValidateEmailReg},
{"nickserv", "maxaliases", "0", new ValueContainerUInt(&conf->NSMaxAliases), DT_UINTEGER, NoValidation},
{"nickserv", "accessmax", "0", new ValueContainerUInt(&conf->NSAccessMax), DT_UINTEGER, ValidateNotZero},
- {"nickserv", "enforceruser", "", new ValueContainerString(&temp_nsuserhost), DT_STRING, ValidateNotEmpty},
+ {"nickserv", "enforceruser", "", new ValueContainerString(&conf->NSEnforcerUser), DT_STRING, ValidateNotEmpty},
+ {"nickserv", "enforcerhost", "", new ValueContainerString(&conf->NSEnforcerHost), DT_STRING, ValidateNotEmpty},
{"nickserv", "releasetimeout", "0", new ValueContainerTime(&conf->NSReleaseTimeout), DT_TIME, ValidateNotZero},
{"nickserv", "allowkillimmed", "no", new ValueContainerBool(&conf->NSAllowKillImmed), DT_BOOLEAN | DT_NORELOAD, NoValidation},
{"nickserv", "nogroupchange", "no", new ValueContainerBool(&conf->NSNoGroupChange), DT_BOOLEAN, NoValidation},
@@ -1071,9 +1143,7 @@ ConfigItems::ConfigItems(ServerConfig *conf)
{"mail", "dontquoteaddresses", "no", new ValueContainerBool(&conf->DontQuoteAddresses), DT_BOOLEAN, NoValidation},
{"dns", "nameserver", "127.0.0.1", new ValueContainerString(&conf->NameServer), DT_STRING, NoValidation},
{"dns", "timeout", "5", new ValueContainerTime(&conf->DNSTimeout), DT_TIME, NoValidation},
- {"chanserv", "nick", "", new ValueContainerString(&conf->s_ChanServ), DT_STRING | DT_NORELOAD, NoValidation},
- {"chanserv", "description", "Channel Registration Service", new ValueContainerString(&conf->desc_ChanServ), DT_STRING | DT_NORELOAD, ValidateChanServ},
- {"chanserv", "modules", "", new ValueContainerString(&conf->ChanCoreModules), DT_STRING, ValidateChanServ},
+ {"chanserv", "name", "ChanServ", new ValueContainerString(&conf->ChanServ), DT_STRING, NoValidation},
{"chanserv", "defaults", "keeptopic secure securefounder signkick", new ValueContainerString(&CSDefaults), DT_STRING, ValidateChanServ},
{"chanserv", "maxregistered", "0", new ValueContainerUInt(&conf->CSMaxReg), DT_UINTEGER, ValidateChanServ},
{"chanserv", "expire", "14d", new ValueContainerTime(&conf->CSExpire), DT_TIME, ValidateChanServ},
@@ -1087,16 +1157,13 @@ ConfigItems::ConfigItems(ServerConfig *conf)
{"chanserv", "listopersonly", "no", new ValueContainerBool(&conf->CSListOpersOnly), DT_BOOLEAN, ValidateChanServ},
{"chanserv", "listmax", "0", new ValueContainerUInt(&conf->CSListMax), DT_UINTEGER, ValidateChanServ},
{"chanserv", "opersonly", "no", new ValueContainerBool(&conf->CSOpersOnly), DT_BOOLEAN, ValidateChanServ},
- {"memoserv", "nick", "", new ValueContainerString(&conf->s_MemoServ), DT_STRING | DT_NORELOAD, NoValidation},
- {"memoserv", "description", "Memo Service", new ValueContainerString(&conf->desc_MemoServ), DT_STRING | DT_NORELOAD, ValidateMemoServ},
- {"memoserv", "modules", "", new ValueContainerString(&conf->MemoCoreModules), DT_STRING, NoValidation},
+ {"memoserv", "name", "MemoServ", new ValueContainerString(&conf->MemoServ), DT_STRING, NoValidation},
{"memoserv", "maxmemos", "0", new ValueContainerUInt(&conf->MSMaxMemos), DT_UINTEGER, NoValidation},
{"memoserv", "senddelay", "0", new ValueContainerTime(&conf->MSSendDelay), DT_TIME, NoValidation},
{"memoserv", "notifyall", "no", new ValueContainerBool(&conf->MSNotifyAll), DT_BOOLEAN, NoValidation},
{"memoserv", "memoreceipt", "0", new ValueContainerUInt(&conf->MSMemoReceipt), DT_UINTEGER, NoValidation},
- {"botserv", "nick", "", new ValueContainerString(&conf->s_BotServ), DT_STRING | DT_NORELOAD, NoValidation},
- {"botserv", "description", "Bot Service", new ValueContainerString(&conf->desc_BotServ), DT_STRING | DT_NORELOAD, ValidateBotServ},
- {"botserv", "modules", "", new ValueContainerString(&conf->BotCoreModules), DT_STRING, NoValidation},
+ {"hostserv", "name", "HostServ", new ValueContainerString(&conf->HostServ), DT_STRING, NoValidation},
+ {"botserv", "name", "BotServ", new ValueContainerString(&conf->BotServ), DT_STRING, NoValidation},
{"botserv", "defaults", "", new ValueContainerString(&BSDefaults), DT_STRING, NoValidation},
{"botserv", "minusers", "0", new ValueContainerUInt(&conf->BSMinUsers), DT_UINTEGER, ValidateBotServ},
{"botserv", "badwordsmax", "0", new ValueContainerUInt(&conf->BSBadWordsMax), DT_UINTEGER, ValidateBotServ},
@@ -1105,12 +1172,7 @@ ConfigItems::ConfigItems(ServerConfig *conf)
{"botserv", "gentlebadwordreason", "no", new ValueContainerBool(&conf->BSGentleBWReason), DT_BOOLEAN, NoValidation},
{"botserv", "casesensitive", "no", new ValueContainerBool(&conf->BSCaseSensitive), DT_BOOLEAN, NoValidation},
{"botserv", "fantasycharacter", "!", new ValueContainerString(&conf->BSFantasyCharacter), DT_STRING, NoValidation},
- {"hostserv", "nick", "", new ValueContainerString(&conf->s_HostServ), DT_STRING | DT_NORELOAD, NoValidation},
- {"hostserv", "description", "vHost Service", new ValueContainerString(&conf->desc_HostServ), DT_STRING | DT_NORELOAD, ValidateHostServ},
- {"hostserv", "modules", "", new ValueContainerString(&conf->HostCoreModules), DT_STRING, NoValidation},
- {"operserv", "nick", "", new ValueContainerString(&conf->s_OperServ), DT_STRING | DT_NORELOAD, NoValidation},
- {"operserv", "description", "Operator Service", new ValueContainerString(&conf->desc_OperServ), DT_STRING | DT_NORELOAD, ValidateOperServ},
- {"operserv", "modules", "", new ValueContainerString(&conf->OperCoreModules), DT_STRING, NoValidation},
+ {"operserv", "name", "OperServ", new ValueContainerString(&conf->OperServ), DT_STRING, NoValidation},
{"operserv", "superadmin", "no", new ValueContainerBool(&conf->SuperAdmin), DT_BOOLEAN, NoValidation},
{"operserv", "autokillexpiry", "0", new ValueContainerTime(&conf->AutokillExpiry), DT_TIME, ValidateOperServ},
{"operserv", "chankillexpiry", "0", new ValueContainerTime(&conf->ChankillExpiry), DT_TIME, ValidateOperServ},
@@ -1131,9 +1193,7 @@ ConfigItems::ConfigItems(ServerConfig *conf)
{"operserv", "sessionautokillexpiry", "0", new ValueContainerTime(&conf->SessionAutoKillExpiry), DT_TIME, NoValidation},
{"operserv", "addakiller", "no", new ValueContainerBool(&conf->AddAkiller), DT_BOOLEAN, NoValidation},
{"operserv", "opersonly", "no", new ValueContainerBool(&conf->OSOpersOnly), DT_BOOLEAN, NoValidation},
- {"global", "nick", "", new ValueContainerString(&conf->s_Global), DT_STRING | DT_NORELOAD, NoValidation},
- {"global", "description", "Global Noticer", new ValueContainerString(&conf->desc_Global), DT_STRING | DT_NORELOAD, ValidateGlobal},
- {"global", "modules", "", new ValueContainerString(&conf->GlobalCoreModules), DT_STRING, NoValidation},
+ {"global", "name", "Global", new ValueContainerString(&conf->Global), DT_STRING, NoValidation},
{"global", "globaloncycle", "no", new ValueContainerBool(&conf->GlobalOnCycle), DT_BOOLEAN, NoValidation},
{"global", "globaloncycledown", "", new ValueContainerString(&conf->GlobalOnCycleMessage), DT_STRING, ValidateGlobalOnCycle},
{"global", "globaloncycleup", "", new ValueContainerString(&conf->GlobalOnCycleUP), DT_STRING, ValidateGlobalOnCycle},
@@ -1161,11 +1221,6 @@ ConfigItems::ConfigItems(ServerConfig *conf)
{"", ""},
{DT_STRING},
InitModules, DoModule, DoneModules},
- {"log",
- {"target", "source", "logage", "inhabitlogchannel", "admin", "override", "commands", "servers", "channels", "users", "other", "rawio", "debug", ""},
- {"", "", "7", "yes", "", "", "", "", "", "", "no", "no", ""},
- {DT_STRING, DT_STRING, DT_INTEGER, DT_BOOLEAN, DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_BOOLEAN, DT_BOOLEAN},
- InitLogs, DoLogs, DoneLogs},
{"opertype",
{"name", "inherits", "commands", "privs", ""},
{"", "", "", "", ""},
@@ -1176,6 +1231,21 @@ ConfigItems::ConfigItems(ServerConfig *conf)
{"", "", "", "", ""},
{DT_STRING, DT_STRING, DT_STRING, DT_STRING},
InitOpers, DoOper, DoneOpers},
+ {"service",
+ {"nick", "user", "host", "gecos", ""},
+ {"", "", "", "", ""},
+ {DT_STRING, DT_STRING, DT_STRING, DT_STRING},
+ InitServices, DoServices, DoneServices},
+ {"log",
+ {"target", "source", "logage", "inhabitlogchannel", "admin", "override", "commands", "servers", "channels", "users", "other", "rawio", "debug", ""},
+ {"", "", "7", "yes", "", "", "", "", "", "", "no", "no", ""},
+ {DT_STRING, DT_STRING, DT_INTEGER, DT_BOOLEAN, DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_BOOLEAN, DT_BOOLEAN},
+ InitLogs, DoLogs, DoneLogs},
+ {"command",
+ {"service", "name", "command", ""},
+ {"", "", "", ""},
+ {DT_STRING, DT_STRING, DT_STRING},
+ InitCommands, DoCommands, DoneCommands},
{"",
{""},
{""},
@@ -1424,14 +1494,11 @@ void ServerConfig::LoadConf(ConfigurationFile &file)
if (in_quote)
{
if (ch == '"')
- {
in_quote = in_word = false;
- continue;
- }
- wordbuffer += ch;
- continue;
+ else
+ wordbuffer += ch;
}
- if (in_ml_comment)
+ else if (in_ml_comment)
{
if (ch == '*' && c + 1 < len && line[c + 1] == '/')
{
@@ -1440,8 +1507,8 @@ void ServerConfig::LoadConf(ConfigurationFile &file)
}
continue;
}
- if (ch == '#' || (ch == '/' && c + 1 < len && line[c + 1] == '/'))
- break; // Line comment, ignore the rest of the line (much like this one!)
+ else if (ch == '#' || (ch == '/' && c + 1 < len && line[c + 1] == '/'))
+ c = len - 1; // Line comment, ignore the rest of the line (much like this one!)
else if (ch == '/' && c + 1 < len && line[c + 1] == '*')
{
// Multiline (or less than one line) comment
@@ -1463,7 +1530,6 @@ void ServerConfig::LoadConf(ConfigurationFile &file)
throw ConfigException("Unexpected quoted string (prior unhandled words): " + file.GetName() + ":" + stringify(linenumber));
}
in_quote = in_word = true;
- continue;
}
else if (ch == '=')
{
@@ -1498,70 +1564,62 @@ void ServerConfig::LoadConf(ConfigurationFile &file)
in_word = false;
section = wordbuffer;
wordbuffer.clear();
+ continue;
+ }
+ else if (ch == ' ' || ch == '\r' || ch == '\t')
+ {
+ // Terminate word
+ in_word = false;
}
+ else if (!in_word && ch == ';')
+ ;
else if (ch == '}')
+ ;
+ else
{
- if (section.empty())
+ if (!in_word && !wordbuffer.empty())
{
file.Close();
- throw ConfigException("Stray '}': " + file.GetName() + ":" + stringify(linenumber));
+ throw ConfigException("Unexpected word: " + file.GetName() + ":" + stringify(linenumber));
}
- if (!wordbuffer.empty() || !itemname.empty())
+ wordbuffer += ch;
+ in_word = true;
+ }
+
+ if (ch == ';' || ch == '}' || c + 1 == len)
+ {
+ if (in_quote)
+ {
+ // Quotes can span multiple lines; all we need to do is go to the next line without clearing things
+ wordbuffer += "\n";
+ continue;
+ }
+ in_word = false;
+ if (!itemname.empty())
{
- // this will allow for the construct: section { key = value }
- // but will not allow for anything else, such as: section { key = value; key = value }
- if (!sectiondata.empty())
+ if (wordbuffer.empty())
{
file.Close();
- throw ConfigException("Unexpected end of section: " + file.GetName() + ":" + stringify(linenumber));
+ throw ConfigException("Item without value: " + file.GetName() + ":" + stringify(linenumber));
}
- // this is the same as the below section for testing if itemname is non-empty after the loop, but done inside it to allow the above construct
- Log(LOG_DEBUG) << "ln "<< linenumber << " EOL: s='" << section << "' '" << itemname << "' set to '" << wordbuffer << "'";
+ Log(LOG_DEBUG) << "ln " << linenumber << " EOL: s='" << section << "' '" << itemname << "' set to '" << wordbuffer << "'";
sectiondata.push_back(KeyVal(itemname, wordbuffer));
wordbuffer.clear();
itemname.clear();
}
- this->config_data.insert(std::pair<Anope::string, KeyValList>(section, sectiondata));
- section.clear();
- sectiondata.clear();
- }
- else if (ch == ';' || ch == '\r')
- continue; // Ignore
- else if (ch == ' ' || ch == '\t')
- {
- // Terminate word
- if (in_word)
- in_word = false;
- }
- else
- {
- if (!in_word && !wordbuffer.empty())
+
+ if (ch == '}')
{
- file.Close();
- throw ConfigException("Unexpected word: " + file.GetName() + ":" + stringify(linenumber));
+ if (section.empty())
+ {
+ file.Close();
+ throw ConfigException("Stray '}': " + file.GetName() + ":" + stringify(linenumber));
+ }
+ this->config_data.insert(std::pair<Anope::string, KeyValList>(section, sectiondata));
+ section.clear();
+ sectiondata.clear();
}
- wordbuffer += ch;
- in_word = true;
- }
- }
- if (in_quote)
- {
- // Quotes can span multiple lines; all we need to do is go to the next line without clearing things
- wordbuffer += "\n";
- continue;
- }
- in_word = false;
- if (!itemname.empty())
- {
- if (wordbuffer.empty())
- {
- file.Close();
- throw ConfigException("Item without value: " + file.GetName() + ":" + stringify(linenumber));
}
- Log(LOG_DEBUG) << "ln " << linenumber << " EOL: s='" << section << "' '" << itemname << "' set to '" << wordbuffer << "'";
- sectiondata.push_back(KeyVal(itemname, wordbuffer));
- wordbuffer.clear();
- itemname.clear();
}
}
if (in_ml_comment)
diff --git a/src/init.cpp b/src/init.cpp
index 73589b468..0f2f30a58 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -11,6 +11,7 @@
#include "services.h"
#include "modules.h"
+#include "oper.h"
Uplink *uplink_server;
@@ -401,6 +402,12 @@ void Init(int ac, char **av)
throw FatalException("You must load a protocol module!");
else if (ModuleManager::FindFirstOf(ENCRYPTION) == NULL)
throw FatalException("You must load at least one encryption module");
+
+ for (botinfo_map::iterator it = BotListByNick.begin(), it_end = BotListByNick.end(); it != it_end; ++it)
+ {
+ it->second->GenerateUID();
+ it->second->server = Me;
+ }
Log() << "Using IRCd protocol " << protocol->name;
diff --git a/src/language.cpp b/src/language.cpp
index 4e1b94e02..222008b8c 100644
--- a/src/language.cpp
+++ b/src/language.cpp
@@ -1,5 +1,6 @@
#include "services.h"
-#include <stack>
+#include "modules.h"
+#include "commands.h"
std::vector<Anope::string> languages;
std::vector<Anope::string> domains;
@@ -94,9 +95,3 @@ const char *anope_gettext(const char *lang, const char *string)
}
#endif
-void SyntaxError(CommandSource &source, const Anope::string &command, const Anope::string &message)
-{
- source.Reply(_("Syntax: \002%s\002"), message.c_str());
- source.Reply(_(_(MORE_INFO)), Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str(), command.c_str());
-}
-
diff --git a/src/logger.cpp b/src/logger.cpp
index 8a1be9ab2..1725e8670 100644
--- a/src/logger.cpp
+++ b/src/logger.cpp
@@ -11,9 +11,7 @@
#include "services.h"
#include "modules.h"
-#include "chanserv.h"
-#include "operserv.h"
-#include "global.h"
+#include "commands.h"
static Anope::string GetTimeStamp()
{
@@ -67,8 +65,8 @@ Anope::string LogFile::GetName() const
Log::Log(LogType type, const Anope::string &category, BotInfo *b) : bi(b), Type(type), Category(category)
{
- if (!bi && global)
- bi = global->Bot();
+ if (!bi)
+ bi = Config ? findbot(Config->Global) : NULL;
if (bi)
this->Sources.push_back(bi->nick);
}
@@ -81,8 +79,13 @@ Log::Log(LogType type, User *u, Command *c, ChannelInfo *ci) : Type(type)
if (type != LOG_COMMAND && type != LOG_OVERRIDE && type != LOG_ADMIN)
throw CoreException("This constructor does not support this log type");
- this->bi = c->service ? c->service : (global ? global->Bot() : NULL);
- this->Category = (c->service ? c->service->nick + "/" : "") + c->name;
+ size_t sl = c->name.find('/');
+ this->bi = NULL;
+ if (sl != Anope::string::npos)
+ this->bi = findbot(c->name.substr(0, sl));
+ if (this->bi == NULL)
+ this->bi = Config ? findbot(Config->Global) : NULL;
+ this->Category = c->name;
if (this->bi)
this->Sources.push_back(this->bi->nick);
this->Sources.push_back(u->nick);
@@ -96,7 +99,8 @@ Log::Log(LogType type, User *u, Command *c, ChannelInfo *ci) : Type(type)
buf << "OVERRIDE: ";
else
buf << "COMMAND: ";
- buf << u->GetMask() << " used " << c->name << " ";
+ Anope::string cname = sl != Anope::string::npos ? c->name.substr(sl + 1) : c->name;
+ buf << u->GetMask() << " used " << cname << " ";
if (ci)
buf << "on " << ci->name << " ";
}
@@ -106,7 +110,7 @@ Log::Log(User *u, Channel *c, const Anope::string &category) : Type(LOG_CHANNEL)
if (!c)
throw CoreException("Invalid pointers passed to Log::Log");
- this->bi = chanserv ? chanserv->Bot() : NULL;
+ this->bi = Config ? findbot(Config->ChanServ) : NULL;
this->Category = category;
if (this->bi)
this->Sources.push_back(this->bi->nick);
@@ -126,8 +130,7 @@ Log::Log(User *u, const Anope::string &category) : bi(NULL), Type(LOG_USER), Cat
if (!u)
throw CoreException("Invalid pointers passed to Log::Log");
- if (!this->bi && global)
- this->bi = global->Bot();
+ this->bi = Config ? findbot(Config->Global) : NULL;
if (this->bi)
this->Sources.push_back(this->bi->nick);
this->Sources.push_back(u->nick);
@@ -140,10 +143,9 @@ Log::Log(Server *s, const Anope::string &category) : bi(NULL), Type(LOG_SERVER),
if (!s)
throw CoreException("Invalid pointer passed to Log::Log");
- if (operserv)
- this->bi = operserv->Bot();
- if (!this->bi && global)
- this->bi = global->Bot();
+ this->bi = Config ? findbot(Config->OperServ) : NULL;
+ if (!this->bi)
+ this->bi = Config ? findbot(Config->Global) : NULL;
if (this->bi)
this->Sources.push_back(this->bi->nick);
this->Sources.push_back(s->GetName());
@@ -153,8 +155,8 @@ Log::Log(Server *s, const Anope::string &category) : bi(NULL), Type(LOG_SERVER),
Log::Log(BotInfo *b, const Anope::string &category) : bi(b), Type(LOG_NORMAL), Category(category)
{
- if (!b && global)
- this->bi = global->Bot();
+ if (!this->bi)
+ this->bi = Config ? findbot(Config->Global) : NULL;
if (this->bi)
this->Sources.push_back(bi->nick);
}
diff --git a/src/main.cpp b/src/main.cpp
index 4a02e532d..0c1db63ea 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -110,7 +110,7 @@ class UplinkSocket : public ConnectionSocket
~UplinkSocket()
{
- if (Me && Me->GetUplink() && Me->GetUplink()->IsSynced())
+ if (Me && !Me->GetLinks().empty() && Me->GetLinks()[0]->IsSynced())
{
FOREACH_MOD(I_OnServerDisconnect, OnServerDisconnect());
@@ -397,6 +397,8 @@ int main(int ac, char **av, char **envp)
quitmsg = "Terminating, reason unknown";
Log() << quitmsg;
+ delete UplinkSock;
+
ModuleManager::UnloadAll();
SocketEngine::Shutdown();
for (Module *m; (m = ModuleManager::FindFirstOf(PROTOCOL)) != NULL;)
diff --git a/src/misc.cpp b/src/misc.cpp
index 967e2f6ef..4c1d03af2 100644
--- a/src/misc.cpp
+++ b/src/misc.cpp
@@ -225,7 +225,7 @@ Anope::string duration(const time_t &t, NickCore *nc)
if (hours)
{
buffer += need_comma ? ", " : "";
- buffer += stringify(hours) + " " + (hours != 1 ? translate(nc, _("hounslaters")) : translate(nc, _("hour")));
+ buffer += stringify(hours) + " " + (hours != 1 ? translate(nc, _("hours")) : translate(nc, _("hour")));
need_comma = true;
}
if (minutes)
diff --git a/src/modes.cpp b/src/modes.cpp
index b91cc9b85..daada4322 100644
--- a/src/modes.cpp
+++ b/src/modes.cpp
@@ -279,29 +279,6 @@ bool ChannelModeRegistered::CanSet(User *u) const
return false;
}
-/** Add a ban to the channel
- * @param chan The channel
- * @param mask The ban
- */
-void ChannelModeBan::OnAdd(Channel *chan, const Anope::string &mask)
-{
- /* check for NULL values otherwise we will segfault */
- if (!chan || mask.empty())
- return;
-
- /* Check whether it matches a botserv bot */
- if (!Config->s_BotServ.empty() && Config->BSSmartJoin && chan->ci && chan->ci->bi && chan->FindUser(chan->ci->bi))
- {
- BotInfo *bi = chan->ci->bi;
-
- Entry ban(CMODE_BAN, mask);
- if (ban.Matches(bi))
- chan->RemoveMode(NULL, CMODE_BAN, mask);
- }
-
- Log(LOG_DEBUG) << "Added ban " << mask << " to channel " << chan->name;
-}
-
void StackerInfo::AddMode(Mode *mode, bool Set, const Anope::string &Param)
{
ChannelMode *cm = NULL;
diff --git a/src/modulemanager.cpp b/src/modulemanager.cpp
index 1c4e07eef..8f5e15146 100644
--- a/src/modulemanager.cpp
+++ b/src/modulemanager.cpp
@@ -523,3 +523,14 @@ Service *ModuleManager::GetService(const Anope::string &name)
return NULL;
}
+/** Get the existing service key names
+ * @return The keys
+ */
+std::vector<Anope::string> ModuleManager::GetServiceKeys()
+{
+ std::vector<Anope::string> keys;
+ for (std::map<Anope::string, Service *>::const_iterator it = ModuleManager::ServiceProviders.begin(), it_end = ModuleManager::ServiceProviders.end(); it != it_end; ++it)
+ keys.push_back(it->first);
+ return keys;
+}
+
diff --git a/src/modules.cpp b/src/modules.cpp
index c379a66dd..241054715 100644
--- a/src/modules.cpp
+++ b/src/modules.cpp
@@ -65,49 +65,6 @@ std::vector<Message *> Anope::FindMessage(const Anope::string &name)
return messages;
}
-/*******************************************************************************
- * Command Functions
- *******************************************************************************/
-
-int Module::AddCommand(BotInfo *bi, Command *c)
-{
- if (!bi || !c)
- return MOD_ERR_PARAMS;
-
- c->module = this;
- c->service = bi;
-
- std::pair<CommandMap::iterator, bool> it = bi->Commands.insert(std::make_pair(c->name, c));
-
- if (it.second != true)
- {
- Log() << "Error creating command " << c->name << ". Command already exists!";
- return MOD_ERR_EXISTS;
- }
-
- return MOD_ERR_OK;
-}
-
-/**
- * Delete a command from the service given.
- * @param cmdTable the cmdTable for the services to remove the command from
- * @param name the name of the command to delete from the service
- * @return returns MOD_ERR_OK on success
- */
-int Module::DelCommand(BotInfo *bi, Command *c)
-{
- if (!bi || !c)
- return MOD_ERR_PARAMS;
-
- if (!bi->Commands.erase(c->name))
- return MOD_ERR_NOEXIST;
-
- c->module = NULL;
- c->service = NULL;
-
- return MOD_ERR_OK;
-}
-
Service::Service(Module *o, const Anope::string &n) : owner(o), name(n)
{
}
diff --git a/src/operserv.cpp b/src/operserv.cpp
index 7426d4b20..9546b7ee1 100644
--- a/src/operserv.cpp
+++ b/src/operserv.cpp
@@ -11,9 +11,7 @@
#include "services.h"
#include "modules.h"
-#include "operserv.h"
-
-XLineManager *SGLine = NULL, *SZLine = NULL, *SQLine = NULL, *SNLine = NULL;
+#include "oper.h"
/* List of XLine managers we check users against in XLineManager::CheckAll */
std::list<XLineManager *> XLineManager::XLineManagers;
@@ -63,7 +61,7 @@ Anope::string XLine::GetHost() const
/** Constructor
*/
-XLineManager::XLineManager()
+XLineManager::XLineManager(Module *creator, const Anope::string &name, char t) : Service(creator, name), type(t)
{
}
@@ -75,6 +73,14 @@ XLineManager::~XLineManager()
this->Clear();
}
+/** The type of xline provided by this service
+ * @return The type
+ */
+const char &XLineManager::Type()
+{
+ return this->type;
+}
+
/** Register a XLineManager, places it in XLineManagers for use in XLineManager::CheckAll
* It is important XLineManagers are registered in the proper order. Eg, if you had one akilling
* clients and one handing them free olines, you would want the akilling one first. This way if a client
@@ -340,278 +346,3 @@ void XLineManager::OnExpire(XLine *x)
{
}
-XLine *SGLineManager::Add(const Anope::string &mask, const Anope::string &creator, time_t expires, const Anope::string &reason)
-{
- Anope::string realreason = reason;
- if (!creator.empty() && Config->AddAkiller)
- realreason = "[" + creator + "] " + reason;
-
- XLine *x = new XLine(mask, creator, expires, realreason);
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(I_OnAddAkill, OnAddAkill(x));
- if (MOD_RESULT == EVENT_STOP)
- {
- delete x;
- return NULL;
- }
-
- this->AddXLine(x);
-
- if (UplinkSock && Config->AkillOnAdd)
- this->Send(NULL, x);
-
- return x;
-}
-
-void SGLineManager::Del(XLine *x)
-{
- ircdproto->SendAkillDel(x);
-}
-
-void SGLineManager::OnMatch(User *u, XLine *x)
-{
- if (u)
- u->Kill(Config->s_OperServ, x->Reason);
- ircdproto->SendAkill(u, x);
-}
-
-void SGLineManager::OnExpire(XLine *x)
-{
- if (Config->WallAkillExpire && operserv)
- ircdproto->SendGlobops(operserv->Bot(), "AKILL on %s has expired", x->Mask.c_str());
-}
-
-void SGLineManager::Send(User *u, XLine *x)
-{
- ircdproto->SendAkill(u, x);
-}
-
-XLine *SNLineManager::Add(const Anope::string &mask, const Anope::string &creator, time_t expires, const Anope::string &reason)
-{
- XLine *x = new XLine(mask, creator, expires, reason);
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(I_OnAddXLine, OnAddXLine(x, X_SNLINE));
- if (MOD_RESULT == EVENT_STOP)
- {
- delete x;
- return NULL;
- }
-
- this->AddXLine(x);
-
- if (Config->KillonSNline && !ircd->sglineenforce)
- {
- Anope::string rreason = "G-Lined: " + reason;
-
- for (Anope::insensitive_map<User *>::const_iterator it = UserListByNick.begin(); it != UserListByNick.end();)
- {
- User *user = it->second;
- ++it;
-
- if (!user->HasMode(UMODE_OPER) && user->server != Me && Anope::Match(user->realname, x->Mask))
- user->Kill(Config->ServerName, rreason);
- }
- }
-
- return x;
-}
-
-void SNLineManager::Del(XLine *x)
-{
- ircdproto->SendSGLineDel(x);
-}
-
-void SNLineManager::OnMatch(User *u, XLine *x)
-{
- if (u)
- {
- Anope::string reason = "G-Lined: " + x->Reason;
- u->Kill(Config->s_OperServ, reason);
- }
- this->Send(u, x);
-}
-
-void SNLineManager::OnExpire(XLine *x)
-{
- if (Config->WallSNLineExpire && operserv)
- ircdproto->SendGlobops(operserv->Bot(), "SNLINE on \2%s\2 has expired", x->Mask.c_str());
-}
-
-void SNLineManager::Send(User *u, XLine *x)
-{
- ircdproto->SendSGLine(u, x);
-}
-
-XLine *SNLineManager::Check(User *u)
-{
- for (unsigned i = this->XLines.size(); i > 0; --i)
- {
- XLine *x = this->XLines[i - 1];
-
- if (x->Expires && x->Expires < Anope::CurTime)
- {
- this->OnExpire(x);
- this->Del(x);
- delete x;
- this->XLines.erase(XLines.begin() + i - 1);
- continue;
- }
-
- if (Anope::Match(u->realname, x->Mask))
- {
- this->OnMatch(u, x);
- return x;
- }
- }
-
- return NULL;
-}
-
-XLine *SQLineManager::Add(const Anope::string &mask, const Anope::string &creator, time_t expires, const Anope::string &reason)
-{
- XLine *x = new XLine(mask, creator, expires, reason);
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(I_OnAddXLine, OnAddXLine(x, X_SQLINE));
- if (MOD_RESULT == EVENT_STOP)
- {
- delete x;
- return NULL;
- }
-
- this->AddXLine(x);
-
- if (Config->KillonSQline)
- {
- Anope::string rreason = "Q-Lined: " + reason;
-
- if (mask[0] == '#')
- {
- for (channel_map::const_iterator cit = ChannelList.begin(), cit_end = ChannelList.end(); cit != cit_end; ++cit)
- {
- Channel *c = cit->second;
-
- if (!Anope::Match(c->name, mask))
- continue;
- for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; )
- {
- UserContainer *uc = *it;
- ++it;
-
- if (uc->user->HasMode(UMODE_OPER) || uc->user->server == Me)
- continue;
- c->Kick(NULL, uc->user, "%s", reason.c_str());
- }
- }
- }
- else
- {
- for (Anope::insensitive_map<User *>::const_iterator it = UserListByNick.begin(); it != UserListByNick.end();)
- {
- User *user = it->second;
- ++it;
-
- if (!user->HasMode(UMODE_OPER) && user->server != Me && Anope::Match(user->nick, x->Mask))
- user->Kill(Config->ServerName, rreason);
- }
- }
- }
-
- if (UplinkSock)
- this->Send(NULL, x);
-
- return x;
-}
-
-void SQLineManager::Del(XLine *x)
-{
- ircdproto->SendSQLineDel(x);
-}
-
-void SQLineManager::OnMatch(User *u, XLine *x)
-{
- if (u)
- {
- Anope::string reason = "Q-Lined: " + x->Reason;
- u->Kill(Config->s_OperServ, reason);
- }
-
- this->Send(u, x);
-}
-
-void SQLineManager::OnExpire(XLine *x)
-{
- if (Config->WallSQLineExpire && operserv)
- ircdproto->SendGlobops(operserv->Bot(), "SQLINE on \2%s\2 has expired", x->Mask.c_str());
-}
-
-void SQLineManager::Send(User *u, XLine *x)
-{
- ircdproto->SendSQLine(u, x);
-}
-
-bool SQLineManager::Check(Channel *c)
-{
- if (ircd->chansqline && SQLine)
- {
- for (std::vector<XLine *>::const_iterator it = SQLine->GetList().begin(), it_end = SQLine->GetList().end(); it != it_end; ++it)
- {
- XLine *x = *it;
-
- if (Anope::Match(c->name, x->Mask))
- return true;
- }
- }
-
- return false;
-}
-
-XLine *SZLineManager::Add(const Anope::string &mask, const Anope::string &creator, time_t expires, const Anope::string &reason)
-{
- XLine *x = new XLine(mask, creator, expires, reason);
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(I_OnAddXLine, OnAddXLine(x, X_SZLINE));
- if (MOD_RESULT == EVENT_STOP)
- {
- delete x;
- return NULL;
- }
-
- this->AddXLine(x);
-
- if (UplinkSock)
- this->Send(NULL, x);
-
- return x;
-}
-
-void SZLineManager::Del(XLine *x)
-{
- ircdproto->SendSZLineDel(x);
-}
-
-void SZLineManager::OnMatch(User *u, XLine *x)
-{
- if (u)
- {
- Anope::string reason = "Z-Lined: " + x->Reason;
- u->Kill(Config->s_OperServ, reason);
- }
-
- ircdproto->SendSZLine(u, x);
-}
-
-void SZLineManager::OnExpire(XLine *x)
-{
- if (Config->WallSZLineExpire && operserv)
- ircdproto->SendGlobops(operserv->Bot(), "SZLINE on \2%s\2 has expired", x->Mask.c_str());
-}
-
-void SZLineManager::Send(User *u, XLine *x)
-{
- ircdproto->SendSZLine(u, x);
-}
-
diff --git a/src/protocol.cpp b/src/protocol.cpp
index dc1c5960d..1c2ef4d7d 100644
--- a/src/protocol.cpp
+++ b/src/protocol.cpp
@@ -329,7 +329,7 @@ bool IRCdMessage::OnKill(const Anope::string &source, const std::vector<Anope::s
return true;
/* Recover if someone kills us. */
- if (!Config->s_BotServ.empty() && u->server == Me && (bi = dynamic_cast<BotInfo *>(u)))
+ if (u->server == Me && (bi = dynamic_cast<BotInfo *>(u)))
{
introduce_user(bi->nick);
bi->RejoinAll();
@@ -384,11 +384,10 @@ bool IRCdMessage::OnPrivmsg(const Anope::string &source, const std::vector<Anope
if (receiver[0] == '#')
{
- ChannelInfo *ci = cs_findchan(receiver);
- /* Some paranoia checks */
- if (ci && ci->c)
+ Channel *c = findchan(receiver);
+ if (c)
{
- FOREACH_MOD(I_OnPrivmsg, OnPrivmsg(u, ci, message));
+ FOREACH_MOD(I_OnPrivmsg, OnPrivmsg(u, c, message));
}
}
else
@@ -500,28 +499,22 @@ bool IRCdMessage::OnSQuit(const Anope::string &source, const std::vector<Anope::
bool IRCdMessage::OnWhois(const Anope::string &source, const std::vector<Anope::string> &params)
{
- const Anope::string &who = params[0];
-
- if (!source.empty() && !who.empty())
+ if (!source.empty() && !params.empty())
{
- User *u;
- BotInfo *bi = findbot(who);
- if (bi)
- {
- ircdproto->SendNumeric(Config->ServerName, 311, source, "%s %s %s * :%s", bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str(), bi->realname.c_str());
- ircdproto->SendNumeric(Config->ServerName, 307, source, "%s :is a registered nick", bi->nick.c_str());
- ircdproto->SendNumeric(Config->ServerName, 312, source, "%s %s :%s", bi->nick.c_str(), Config->ServerName.c_str(), Config->ServerDesc.c_str());
- ircdproto->SendNumeric(Config->ServerName, 317, source, "%s %ld %ld :seconds idle, signon time", bi->nick.c_str(), static_cast<long>(Anope::CurTime - bi->lastmsg), static_cast<long>(start_time));
- ircdproto->SendNumeric(Config->ServerName, 318, source, "%s :End of /WHOIS list.", who.c_str());
- }
- else if ((u = finduser(who)) && u->server == Me)
+ User *u = finduser(params[0]);
+ if (u && u->server == Me)
{
+ BotInfo *bi = findbot(u->nick);
ircdproto->SendNumeric(Config->ServerName, 311, source, "%s %s %s * :%s", u->nick.c_str(), u->GetIdent().c_str(), u->host.c_str(), u->realname.c_str());
+ if (bi)
+ ircdproto->SendNumeric(Config->ServerName, 307, source, "%s :is a registered nick", bi->nick.c_str());
ircdproto->SendNumeric(Config->ServerName, 312, source, "%s %s :%s", u->nick.c_str(), Config->ServerName.c_str(), Config->ServerDesc.c_str());
- ircdproto->SendNumeric(Config->ServerName, 318, source, "%s :End of /WHOIS list.", u->nick.c_str());
+ if (bi)
+ ircdproto->SendNumeric(Config->ServerName, 317, source, "%s %ld %ld :seconds idle, signon time", bi->nick.c_str(), static_cast<long>(Anope::CurTime - bi->lastmsg), static_cast<long>(start_time));
+ ircdproto->SendNumeric(Config->ServerName, 318, source, "%s :End of /WHOIS list.", params[0].c_str());
}
else
- ircdproto->SendNumeric(Config->ServerName, 401, source, "%s :No such user.", who.c_str());
+ ircdproto->SendNumeric(Config->ServerName, 401, source, "%s :No such user.", params[0].c_str());
}
return true;
diff --git a/src/regchannel.cpp b/src/regchannel.cpp
index cf2cb42df..131fdf29c 100644
--- a/src/regchannel.cpp
+++ b/src/regchannel.cpp
@@ -11,8 +11,6 @@
#include "services.h"
#include "modules.h"
-#include "chanserv.h"
-#include "nickserv.h"
ChanAccess::ChanAccess(const Anope::string &umask)
{
@@ -193,9 +191,14 @@ NickCore *ChannelInfo::GetFounder() const
*/
BotInfo *ChannelInfo::WhoSends()
{
- if (!this || !this->bi || !this->c || !this->botflags.HasFlag(BS_SYMBIOSIS) || !this->c->FindUser(this->bi))
- return chanserv ? chanserv->Bot() : (nickserv ? nickserv->Bot() : NULL);
- return this->bi;
+ if (this && this->bi)
+ return this->bi;
+ BotInfo *bi = findbot(Config->ChanServ);
+ if (bi)
+ return bi;
+ else if (!BotListByNick.empty())
+ return BotListByNick.begin()->second;
+ return NULL;
}
/** Add an entry to the channel access list
@@ -786,8 +789,11 @@ bool ChannelInfo::CheckKick(User *user)
return false;
bool set_modes = false, do_kick = false;
- if (ircd->chansqline && SQLineManager::Check(this->c))
- do_kick = true;
+
+ EventReturn MOD_RESULT;
+ FOREACH_MOD(I_OnCheckKick, OnCheckKick(user, this, do_kick));
+ if (MOD_RESULT == EVENT_ALLOW)
+ return false;
Anope::string mask, reason;
if (!user->HasMode(UMODE_OPER) && this->HasFlag(CI_SUSPENDED))
diff --git a/src/servers.cpp b/src/servers.cpp
index 19140c154..5aa44be82 100644
--- a/src/servers.cpp
+++ b/src/servers.cpp
@@ -11,6 +11,7 @@
#include "services.h"
#include "modules.h"
+#include "oper.h"
/* Anope */
Server *Me = NULL;
diff --git a/src/users.cpp b/src/users.cpp
index 5c993fcf0..343ef058a 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -11,7 +11,6 @@
#include "services.h"
#include "modules.h"
-#include "nickserv.h"
Anope::insensitive_map<User *> UserListByNick;
Anope::map<User *> UserListByUID;
@@ -309,6 +308,9 @@ void User::SendMessage(BotInfo *source, Anope::string msg)
*/
void User::Collide(NickAlias *na)
{
+ BotInfo *bi = findbot(Config->NickServ);
+ if (!bi)
+ return;
if (na)
na->SetFlag(NS_COLLIDED);
@@ -323,15 +325,15 @@ void User::Collide(NickAlias *na)
} while (finduser(guestnick) && i++ < 10);
if (i == 11)
- this->Kill(Config->s_NickServ, "Services nickname-enforcer kill");
+ this->Kill(Config->NickServ, "Services nickname-enforcer kill");
else
{
- this->SendMessage(nickserv->Bot(), _("Your nickname is now being changed to \002%s\002"), guestnick.c_str());
+ this->SendMessage(bi, _("Your nickname is now being changed to \002%s\002"), guestnick.c_str());
ircdproto->SendForceNickChange(this, guestnick, Anope::CurTime);
}
}
else
- this->Kill(Config->s_NickServ, "Services nickname-enforcer kill");
+ this->Kill(Config->NickServ, "Services nickname-enforcer kill");
}
/** Identify the user to the Nick
@@ -679,11 +681,6 @@ void User::SetModesInternal(const char *umodes, ...)
++opcnt;
else
--opcnt;
-
- break;
- case UMODE_REGISTERED:
- if (add && !this->IsIdentified() && nickserv)
- this->RemoveMode(nickserv->Bot(), UMODE_REGISTERED);
break;
case UMODE_CLOAK:
case UMODE_VHOST:
@@ -836,30 +833,10 @@ User *do_nick(const Anope::string &source, const Anope::string &nick, const Anop
old_na->OnCancel(user);
NickAlias *na = findnick(user->nick);
- /* If the new nick isnt registerd or its registerd and not yours */
- if (!na || na->nc != user->Account())
- {
- user->RemoveMode(nickserv->Bot(), UMODE_REGISTERED);
- ircdproto->SendUnregisteredNick(user);
-
- nickserv->Validate(user);
- }
- else
+ if (na && na->nc == user->Account())
{
na->last_seen = Anope::CurTime;
user->UpdateHost();
- if (na->nc->HasFlag(NI_UNCONFIRMED) == false)
- {
- user->SetMode(nickserv->Bot(), UMODE_REGISTERED);
- ircdproto->SetAutoIdentificationToken(user);
- }
- Log(nickserv->Bot()) << user->GetMask() << " automatically identified for group " << user->Account()->display;
- }
-
- if (ircd->sqline)
- {
- if (user->HasMode(UMODE_OPER) && SQLine->Check(user))
- return NULL;
}
}