diff options
author | Adam <Adam@anope.org> | 2011-07-14 02:31:12 -0400 |
---|---|---|
committer | Adam <Adam@anope.org> | 2011-07-14 02:31:12 -0400 |
commit | f858164deed48f2dcacd5ffc06a55398a54da7e8 (patch) | |
tree | 89c3cf36bd8e94942370135218d67d6d17ee222e /src | |
parent | 924f6849fee4598a1a3a7f1a98d96b79e5ffd3b4 (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.cpp | 150 | ||||
-rw-r--r-- | src/channels.cpp | 58 | ||||
-rw-r--r-- | src/chanserv.cpp | 14 | ||||
-rw-r--r-- | src/command.cpp | 64 | ||||
-rw-r--r-- | src/commands.cpp | 183 | ||||
-rw-r--r-- | src/config.cpp | 326 | ||||
-rw-r--r-- | src/init.cpp | 7 | ||||
-rw-r--r-- | src/language.cpp | 9 | ||||
-rw-r--r-- | src/logger.cpp | 36 | ||||
-rw-r--r-- | src/main.cpp | 4 | ||||
-rw-r--r-- | src/misc.cpp | 2 | ||||
-rw-r--r-- | src/modes.cpp | 23 | ||||
-rw-r--r-- | src/modulemanager.cpp | 11 | ||||
-rw-r--r-- | src/modules.cpp | 43 | ||||
-rw-r--r-- | src/operserv.cpp | 289 | ||||
-rw-r--r-- | src/protocol.cpp | 35 | ||||
-rw-r--r-- | src/regchannel.cpp | 20 | ||||
-rw-r--r-- | src/servers.cpp | 1 | ||||
-rw-r--r-- | src/users.cpp | 37 |
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 ¶m, 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 ¶m, 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 ¶m, 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> ¶ms) { - 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; } } |