diff options
Diffstat (limited to 'modules')
120 files changed, 1561 insertions, 1226 deletions
diff --git a/modules/bs_autoassign.cpp b/modules/bs_autoassign.cpp index 134904925..3604fe69b 100644 --- a/modules/bs_autoassign.cpp +++ b/modules/bs_autoassign.cpp @@ -11,35 +11,28 @@ class BSAutoAssign : public Module { - Anope::string bot; - public: BSAutoAssign(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR) { - - Implementation i[] = { I_OnChanRegistered, I_OnReload }; + Implementation i[] = { I_OnChanRegistered }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } void OnChanRegistered(ChannelInfo *ci) anope_override { - if (this->bot.empty()) + const Anope::string &bot = Config->GetModule(this)->Get<const Anope::string &>("bot"); + if (bot.empty()) return; - BotInfo *bi = BotInfo::Find(this->bot); + BotInfo *bi = BotInfo::Find(bot); if (bi == NULL) { - Log(this) << "bs_autoassign is configured to assign bot " << this->bot << ", but it does not exist?"; + Log(this) << "bs_autoassign is configured to assign bot " << bot << ", but it does not exist?"; return; } bi->Assign(NULL, ci); } - - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override - { - this->bot = reader.ReadValue("bs_autoassign", "bot", "", 0); - } }; MODULE_INIT(BSAutoAssign) diff --git a/modules/commands/bs_badwords.cpp b/modules/commands/bs_badwords.cpp index 90fbb875d..31dee8f8e 100644 --- a/modules/commands/bs_badwords.cpp +++ b/modules/commands/bs_badwords.cpp @@ -9,11 +9,8 @@ * Based on the original code of Services by Andy Church. */ -/*************************************************************************/ - #include "module.h" - class BadwordsDelCallback : public NumberList { CommandSource &source; @@ -146,17 +143,20 @@ class CommandBSBadwords : public Command realword = word.substr(0, pos); } - if (ci->GetBadWordCount() >= Config->BSBadWordsMax) + unsigned badwordsmax = Config->GetModule(this->module)->Get<unsigned>("badwordsmax"); + if (ci->GetBadWordCount() >= badwordsmax) { - source.Reply(_("Sorry, you can only have %d bad words entries on a channel."), Config->BSBadWordsMax); + source.Reply(_("Sorry, you can only have %d bad words entries on a channel."), badwordsmax); return; } + bool casesensitive = Config->GetModule("botserv")->Get<bool>("casesensitive"); + for (unsigned i = 0, end = ci->GetBadWordCount(); i < end; ++i) { const BadWord *bw = ci->GetBadWord(i); - if (!bw->word.empty() && ((Config->BSCaseSensitive && realword.equals_cs(bw->word)) || (!Config->BSCaseSensitive && realword.equals_ci(bw->word)))) + if ((casesensitive && realword.equals_cs(bw->word)) || (!casesensitive && realword.equals_ci(bw->word))) { source.Reply(_("\002%s\002 already exists in %s bad words list."), bw->word.c_str(), ci->name.c_str()); return; @@ -168,8 +168,6 @@ class CommandBSBadwords : public Command ci->AddBadWord(realword, bwtype); source.Reply(_("\002%s\002 added to %s bad words list."), realword.c_str(), ci->name.c_str()); - - return; } void DoDelete(CommandSource &source, ChannelInfo *ci, const Anope::string &word) @@ -219,6 +217,7 @@ class CommandBSBadwords : public Command source.Reply(_("Bad words list is now empty.")); return; } + public: CommandBSBadwords(Module *creator) : Command(creator, "botserv/badwords", 2, 3) { @@ -289,7 +288,7 @@ class CommandBSBadwords : public Command "will be done if a user says a word that ends with\n" "\037word\037. If you don't specify anything, a kick will\n" "be issued every time \037word\037 is said by a user.\n" - " \n"), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), source.command.c_str()); + " \n"), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), source.command.c_str()); source.Reply(_("The \002DEL\002 command removes the given word from the\n" "bad words list. If a list of entry numbers is given, those\n" "entries are deleted. (See the example for LIST below.)\n" @@ -316,7 +315,6 @@ class BSBadwords : public Module BSBadwords(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandbsbadwords(this) { - } }; diff --git a/modules/commands/bs_bot.cpp b/modules/commands/bs_bot.cpp index f8ecb1a1d..16fd9f2f2 100644 --- a/modules/commands/bs_bot.cpp +++ b/modules/commands/bs_bot.cpp @@ -29,21 +29,23 @@ class CommandBSBot : public Command return; } - if (nick.length() > Config->NickLen) + Configuration::Block *networkinfo = Config->GetBlock("networkinfo"); + + if (nick.length() > networkinfo->Get<unsigned>("nicklen")) { - source.Reply(_("Bot nicks may only be %d characters long."), Config->NickLen); + source.Reply(_("Bot nicks may only be %d characters long."), networkinfo->Get<unsigned>("nicklen")); return; } - if (user.length() > Config->UserLen) + if (user.length() > networkinfo->Get<unsigned>("userlen")) { - source.Reply(_("Bot idents may only be %d characters long."), Config->UserLen); + source.Reply(_("Bot idents may only be %d characters long."), networkinfo->Get<unsigned>("userlen")); return; } - if (host.length() > Config->HostLen) + if (host.length() > networkinfo->Get<unsigned>("hostlen")) { - source.Reply(_("Bot hosts may only be %d characters long."), Config->HostLen); + source.Reply(_("Bot hosts may only be %d characters long."), networkinfo->Get<unsigned>("hostlen")); return; } @@ -112,21 +114,23 @@ class CommandBSBot : public Command return; } - if (nick.length() > Config->NickLen) + Configuration::Block *networkinfo = Config->GetBlock("networkinfo"); + + if (nick.length() > networkinfo->Get<unsigned>("nicklen")) { - source.Reply(_("Bot nicks may only be %d characters long."), Config->NickLen); + source.Reply(_("Bot nicks may only be %d characters long."), networkinfo->Get<unsigned>("nicklen")); return; } - if (!user.empty() && user.length() > Config->UserLen) + if (user.length() > networkinfo->Get<unsigned>("userlen")) { - source.Reply(_("Bot idents may only be %d characters long."), Config->UserLen); + source.Reply(_("Bot idents may only be %d characters long."), networkinfo->Get<unsigned>("userlen")); return; } - if (!host.empty() && host.length() > Config->HostLen) + if (host.length() > networkinfo->Get<unsigned>("hostlen")) { - source.Reply(_("Bot hosts may only be %d characters long."), Config->HostLen); + source.Reply(_("Bot hosts may only be %d characters long."), networkinfo->Get<unsigned>("hostlen")); return; } @@ -204,7 +208,15 @@ class CommandBSBot : public Command if (!user.empty()) { IRCD->SendClientIntroduction(bi); - bi->RejoinAll(); + unsigned minusers = Config->GetBlock("botserv")->Get<unsigned>("minusers"); + const std::set<ChannelInfo *> &channels = bi->GetChannels(); + for (std::set<ChannelInfo *>::const_iterator it = channels.begin(), it_end = channels.end(); it != it_end; ++it) + { + const ChannelInfo *ci = *it; + + if (ci->c && ci->c->users.size() >= minusers) + bi->Join(ci->c); + } } source.Reply(_("Bot \002%s\002 has been changed to %s!%s@%s (%s)."), oldnick.c_str(), bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str(), bi->realname.c_str()); diff --git a/modules/commands/bs_kick.cpp b/modules/commands/bs_kick.cpp index 86248ae80..5c1bdc6a8 100644 --- a/modules/commands/bs_kick.cpp +++ b/modules/commands/bs_kick.cpp @@ -13,6 +13,8 @@ #include "module.h" +static Module *me; + class CommandBSKick : public Command { public: @@ -54,7 +56,7 @@ class CommandBSKick : public Command "on a specific option.\n" " \n" "Note: access to this command is controlled by the\n" - "level SET."), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), this_name.c_str()); + "level SET."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), this_name.c_str()); return true; } @@ -199,7 +201,7 @@ class CommandBSKickBadwords : public CommandBSKickBase "more information.\n" "ttb is the number of times a user can be kicked\n" "before it get banned. Don't give ttb to disable\n" - "the ban system once activated."), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str()); + "the ban system once activated."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str()); return true; } }; @@ -406,8 +408,8 @@ class CommandBSKickFlood : public CommandBSKickBase catch (const ConvertException &) { } if (ci->floodsecs < 1) ci->floodsecs = 10; - if (ci->floodsecs > Config->BSKeepData) - ci->floodsecs = Config->BSKeepData; + if (ci->floodsecs > Config->GetModule(me)->Get<time_t>("keepdata")) + ci->floodsecs = Config->GetModule(me)->Get<time_t>("keepdata"); ci->ExtendMetadata("BS_KICK_FLOOD"); if (ci->ttb[TTB_FLOOD]) @@ -639,13 +641,14 @@ struct BanData : ExtensibleItem void purge() { + time_t keepdata = Config->GetModule(me)->Get<time_t>("keepdata"); for (data_type::iterator it = data_map.begin(), it_end = data_map.end(); it != it_end;) { const Anope::string &user = it->first; Data &bd = it->second; ++it; - if (Anope::CurTime - bd.last_use > Config->BSKeepData) + if (Anope::CurTime - bd.last_use > keepdata) data_map.erase(user); } } @@ -797,8 +800,10 @@ class BSKick : public Module purger(this) { + me = this; - ModuleManager::Attach(I_OnPrivmsg, this); + Implementation i[] = { I_OnPrivmsg }; + ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } ~BSKick() @@ -920,30 +925,31 @@ class BSKick : public Module /* Normalize the buffer */ Anope::string nbuf = Anope::NormalizeBuffer(realbuf); + bool casesensitive = Config->GetModule("botserv")->Get<bool>("casesensitive"); for (unsigned i = 0, end = ci->GetBadWordCount(); i < end; ++i) { const BadWord *bw = ci->GetBadWord(i); - if (bw->type == BW_ANY && ((Config->BSCaseSensitive && nbuf.find(bw->word) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(bw->word) != Anope::string::npos))) + if (bw->type == BW_ANY && ((casesensitive && nbuf.find(bw->word) != Anope::string::npos) || (!casesensitive && nbuf.find_ci(bw->word) != Anope::string::npos))) mustkick = true; else if (bw->type == BW_SINGLE) { size_t len = bw->word.length(); - if ((Config->BSCaseSensitive && bw->word.equals_cs(nbuf)) || (!Config->BSCaseSensitive && bw->word.equals_ci(nbuf))) + if ((casesensitive && bw->word.equals_cs(nbuf)) || (!casesensitive && bw->word.equals_ci(nbuf))) mustkick = true; - else if (nbuf.find(' ') == len && ((Config->BSCaseSensitive && bw->word.equals_cs(nbuf)) || (!Config->BSCaseSensitive && bw->word.equals_ci(nbuf)))) + else if (nbuf.find(' ') == len && ((casesensitive && bw->word.equals_cs(nbuf)) || (!casesensitive && bw->word.equals_ci(nbuf)))) mustkick = true; else { - if (nbuf.rfind(' ') == nbuf.length() - len - 1 && ((Config->BSCaseSensitive && nbuf.find(bw->word) == nbuf.length() - len) || (!Config->BSCaseSensitive && nbuf.find_ci(bw->word) == nbuf.length() - len))) + if (nbuf.rfind(' ') == nbuf.length() - len - 1 && ((casesensitive && nbuf.find(bw->word) == nbuf.length() - len) || (!casesensitive && nbuf.find_ci(bw->word) == nbuf.length() - len))) mustkick = true; else { Anope::string wordbuf = " " + bw->word + " "; - if ((Config->BSCaseSensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(wordbuf) != Anope::string::npos)) + if ((casesensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!casesensitive && nbuf.find_ci(wordbuf) != Anope::string::npos)) mustkick = true; } } @@ -952,13 +958,13 @@ class BSKick : public Module { size_t len = bw->word.length(); - if ((Config->BSCaseSensitive && nbuf.substr(0, len).equals_cs(bw->word)) || (!Config->BSCaseSensitive && nbuf.substr(0, len).equals_ci(bw->word))) + if ((casesensitive && nbuf.substr(0, len).equals_cs(bw->word)) || (!casesensitive && nbuf.substr(0, len).equals_ci(bw->word))) mustkick = true; else { Anope::string wordbuf = " " + bw->word; - if ((Config->BSCaseSensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(wordbuf) != Anope::string::npos)) + if ((casesensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!casesensitive && nbuf.find_ci(wordbuf) != Anope::string::npos)) mustkick = true; } } @@ -966,13 +972,13 @@ class BSKick : public Module { size_t len = bw->word.length(); - if ((Config->BSCaseSensitive && nbuf.substr(nbuf.length() - len).equals_cs(bw->word)) || (!Config->BSCaseSensitive && nbuf.substr(nbuf.length() - len).equals_ci(bw->word))) + if ((casesensitive && nbuf.substr(nbuf.length() - len).equals_cs(bw->word)) || (!casesensitive && nbuf.substr(nbuf.length() - len).equals_ci(bw->word))) mustkick = true; else { Anope::string wordbuf = bw->word + " "; - if ((Config->BSCaseSensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(wordbuf) != Anope::string::npos)) + if ((casesensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!casesensitive && nbuf.find_ci(wordbuf) != Anope::string::npos)) mustkick = true; } } @@ -980,7 +986,7 @@ class BSKick : public Module if (mustkick) { check_ban(ci, u, TTB_BADWORDS); - if (Config->BSGentleBWReason) + if (Config->GetModule(me)->Get<bool>("gentlebadwordreason")) bot_kick(ci, u, _("Watch your language!")); else bot_kick(ci, u, _("Don't use the word \"%s\" on this channel!"), bw->word.c_str()); diff --git a/modules/commands/bs_set.cpp b/modules/commands/bs_set.cpp index 6d764c665..20a53faf3 100644 --- a/modules/commands/bs_set.cpp +++ b/modules/commands/bs_set.cpp @@ -48,7 +48,7 @@ class CommandBSSet : public Command } } source.Reply(_("Type \002%s%s HELP %s \037option\037\002 for more information on a\n" - "particular option."), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), this_name.c_str()); + "particular option."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), this_name.c_str()); return true; } @@ -309,13 +309,13 @@ class CommandBSSetFantasy : public Command source.Reply(_(" \n" "Enables or disables \002fantasy\002 mode on a channel.\n" "When it is enabled, users will be able to use\n" - "%s commands on a channel when prefixed\n" + "fantasy commands on a channel when prefixed\n" "with one of the following fantasy characters: \002%s\002\n" " \n" "Note that users wanting to use fantaisist\n" "commands MUST have enough access for both\n" "the FANTASIA and the command they are executing."), - Config->ChanServ.c_str(), Config->BSFantasyCharacter.c_str()); + Config->GetModule("botserv")->Get<const char *>("fantasycharacter", "!")); return true; } }; @@ -495,7 +495,6 @@ class BSSet : public Module commandbsset(this), commandbssetbanexpire(this), commandbssetdontkickops(this), commandbssetdontkickvoices(this), commandbssetfantasy(this), commandbssetgreet(this), commandbssetnobot(this), commandbssetprivate(this) { - ModuleManager::Attach(I_OnBotBan, this); } diff --git a/modules/commands/cs_access.cpp b/modules/commands/cs_access.cpp index 90e17eeed..de434337b 100644 --- a/modules/commands/cs_access.cpp +++ b/modules/commands/cs_access.cpp @@ -158,9 +158,10 @@ class CommandCSAccess : public Command } } - if (ci->GetAccessCount() >= Config->CSAccessMax) + unsigned access_max = Config->GetModule("chanserv")->Get<unsigned>("accessmax", "1024"); + if (access_max && ci->GetAccessCount() >= access_max) { - source.Reply(_("Sorry, you can only have %d access entries on a channel."), Config->CSAccessMax); + source.Reply(_("Sorry, you can only have %d access entries on a channel."), access_max); return; } @@ -555,7 +556,7 @@ class CommandCSAccess : public Command source.Reply(" "); source.Reply(_("\002User access levels\002 can be seen by using the\n" "\002LEVELS\002 command; type \002%s%s HELP LEVELS\002 for\n" - "information."), source.service->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str()); + "information."), source.service->nick.c_str(), Config->StrictPrivmsg.c_str(), source.service->nick.c_str()); return true; } }; @@ -590,7 +591,7 @@ class CommandCSLevels : public Command { Privilege *p = PrivilegeManager::FindPrivilege(what); if (p == NULL) - source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS\002 for a list of valid settings."), what.c_str(), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str()); + source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS\002 for a list of valid settings."), what.c_str(), Config->StrictPrivmsg.c_str(), source.service->nick.c_str()); else { ci->SetLevel(p->name, level); @@ -628,7 +629,7 @@ class CommandCSLevels : public Command } } - source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS\002 for a list of valid settings."), what.c_str(), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str()); + source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS\002 for a list of valid settings."), what.c_str(), Config->StrictPrivmsg.c_str(), source.service->nick.c_str()); return; } @@ -792,19 +793,21 @@ class CSAccess : public Module ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override + void OnReload(Configuration::Conf *conf) anope_override { defaultLevels.clear(); - for (int i = 0; i < reader.Enumerate("privilege"); ++i) + for (int i = 0; i < conf->CountBlock("privilege"); ++i) { - const Anope::string &pname = reader.ReadValue("privilege", "name", "", i); + Configuration::Block *priv = conf->GetBlock("privilege", i); + + const Anope::string &pname = priv->Get<const Anope::string &>("name"); Privilege *p = PrivilegeManager::FindPrivilege(pname); if (p == NULL) continue; - const Anope::string &value = reader.ReadValue("privilege", "level", "", i); + const Anope::string &value = priv->Get<const Anope::string &>("level"); if (value.empty()) continue; else if (value.equals_ci("founder")) @@ -812,7 +815,7 @@ class CSAccess : public Module else if (value.equals_ci("disabled")) defaultLevels[p->name] = ACCESS_INVALID; else - defaultLevels[p->name] = reader.ReadInteger("privilege", "level", i, false); + defaultLevels[p->name] = priv->Get<int16_t>("level"); } } diff --git a/modules/commands/cs_akick.cpp b/modules/commands/cs_akick.cpp index b2b1c7579..bb1e6ecd6 100644 --- a/modules/commands/cs_akick.cpp +++ b/modules/commands/cs_akick.cpp @@ -23,8 +23,9 @@ class CommandCSAKick : public Command NickCore *nc = NULL; const AutoKick *akick; - if (reason.length() > Config->CSReasonMax) - reason = reason.substr(0, Config->CSReasonMax); + unsigned reasonmax = Config->GetModule("chanserv")->Get<unsigned>("reasonmax", "200"); + if (reason.length() > reasonmax) + reason = reason.substr(0, reasonmax); if (IRCD->IsExtbanValid(mask)) ; /* If this is an extban don't try to complete the mask */ @@ -148,9 +149,9 @@ class CommandCSAKick : public Command } } - if (ci->GetAkickCount() >= Config->CSAutokickMax) + if (ci->GetAkickCount() >= Config->GetModule(this->owner)->Get<unsigned>("autokickmax")) { - source.Reply(_("Sorry, you can only have %d autokick masks on a channel."), Config->CSAutokickMax); + source.Reply(_("Sorry, you can only have %d autokick masks on a channel."), Config->GetModule(this->owner)->Get<unsigned>("autokickmax")); return; } @@ -513,7 +514,6 @@ class CSAKick : public Module CSAKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcsakick(this) { - Implementation i[] = { I_OnCheckKick }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } @@ -544,7 +544,11 @@ class CSAKick : public Module autokick->last_used = Anope::CurTime; if (!autokick->nc && autokick->mask.find('#') == Anope::string::npos) mask = autokick->mask; - reason = autokick->reason.empty() ? Config->CSAutokickReason : autokick->reason; + reason = autokick->reason; + if (reason.empty()) + reason = Config->GetModule(this)->Get<const Anope::string &>("autokickreason"); + if (reason.empty()) + reason = "User has been banned from the channel"; return EVENT_STOP; } } diff --git a/modules/commands/cs_ban.cpp b/modules/commands/cs_ban.cpp index 7d441f14d..c3fffecd9 100644 --- a/modules/commands/cs_ban.cpp +++ b/modules/commands/cs_ban.cpp @@ -91,8 +91,9 @@ class CommandCSBan : public Command reason += " " + params[3]; } - if (reason.length() > Config->CSReasonMax) - reason = reason.substr(0, Config->CSReasonMax); + unsigned reasonmax = Config->GetModule("chanserv")->Get<unsigned>("reasonmax", "200"); + if (reason.length() > reasonmax) + reason = reason.substr(0, reasonmax); User *u = source.GetUser(); User *u2 = User::Find(target, true); diff --git a/modules/commands/cs_clone.cpp b/modules/commands/cs_clone.cpp index da8c82647..e4c1ac7f6 100644 --- a/modules/commands/cs_clone.cpp +++ b/modules/commands/cs_clone.cpp @@ -64,31 +64,25 @@ public: target_ci->name = target; (*RegisteredChannelList)[target_ci->name] = target_ci; target_ci->c = Channel::Find(target_ci->name); + + target_ci->bi = NULL; + if (ci->bi) + ci->bi->Assign(u, target_ci); + if (target_ci->c) { target_ci->c->ci = target_ci; target_ci->c->CheckModes(); - ChannelMode *cm; - if (u && u->FindChannel(target_ci->c) != NULL) - { - /* On most ircds you do not receive the admin/owner mode till its registered */ - if ((cm = ModeManager::FindChannelModeByName("OWNER"))) - target_ci->c->SetMode(NULL, cm, u->GetUID()); - else if ((cm = ModeManager::FindChannelModeByName("PROTECT"))) - target_ci->c->RemoveMode(NULL, cm, u->GetUID()); - } + target_ci->c->SetCorrectModes(u, true, true); /* Mark the channel as persistent */ if (target_ci->c->HasMode("PERM")) target_ci->ExtendMetadata("PERSIST"); /* Persist may be in def cflags, set it here */ - else if (target_ci->HasExt("PERSIST") && (cm = ModeManager::FindChannelModeByName("PERM"))) - target_ci->c->SetMode(NULL, cm); - - if (target_ci->bi && target_ci->c->FindUser(target_ci->bi) == NULL) - target_ci->bi->Join(target_ci->c, &ModeManager::DefaultBotModes); + else if (target_ci->HasExt("PERSIST")) + target_ci->c->SetMode(NULL, "PERM"); } if (target_ci->c && !target_ci->c->topic.empty()) diff --git a/modules/commands/cs_entrymsg.cpp b/modules/commands/cs_entrymsg.cpp index 961cf1895..da764d81c 100644 --- a/modules/commands/cs_entrymsg.cpp +++ b/modules/commands/cs_entrymsg.cpp @@ -39,8 +39,6 @@ struct EntryMsg : Serializable static Serializable* Unserialize(Serializable *obj, Serialize::Data &data); }; -static unsigned MaxEntries = 0; - struct EntryMessageList : Serialize::Checker<std::vector<EntryMsg *> >, ExtensibleItem { EntryMessageList() : Serialize::Checker<std::vector<EntryMsg *> >("EntryMsg") { } @@ -140,7 +138,7 @@ class CommandEntryMessage : public Command ci->Extend("cs_entrymsg", messages); } - if (MaxEntries && (*messages)->size() >= MaxEntries) + if ((*messages)->size() >= Config->GetModule(this->owner)->Get<unsigned>("maxentries")) source.Reply(_("The entry message list for \002%s\002 is full."), ci->name.c_str()); else { @@ -276,7 +274,7 @@ class CSEntryMessage : public Module CSEntryMessage(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), entrymsg_type("EntryMsg", EntryMsg::Unserialize), commandentrymsg(this) { - Implementation i[] = { I_OnReload, I_OnJoinChannel }; + Implementation i[] = { I_OnJoinChannel }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } @@ -291,11 +289,6 @@ class CSEntryMessage : public Module u->SendMessage(c->ci->WhoSends(), "[%s] %s", c->ci->name.c_str(), (*messages)->at(i)->message.c_str()); } } - - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override - { - MaxEntries = reader.ReadInteger("cs_entrymsg", "maxentries", "5", 0, true); - } }; MODULE_INIT(CSEntryMessage) diff --git a/modules/commands/cs_fantasy_stats.cpp b/modules/commands/cs_fantasy_stats.cpp index df24710a0..7709a38d3 100644 --- a/modules/commands/cs_fantasy_stats.cpp +++ b/modules/commands/cs_fantasy_stats.cpp @@ -77,11 +77,12 @@ class CSStats : public Module ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override + void OnReload(Configuration::Conf *conf) anope_override { - prefix = reader.ReadValue("chanstats", "prefix", "anope_", 0); - Anope::string engine = reader.ReadValue("chanstats", "engine", "", 0); - this->sql = ServiceReference<SQL::Provider>("SQL::Provider", engine); + prefix = conf->GetModule(this)->Get<const Anope::string &>("prefix"); + if (prefix.empty()) + prefix = "anope_"; + this->sql = ServiceReference<SQL::Provider>("SQL::Provider", conf->GetModule(this)->Get<const Anope::string &>("engine")); } SQL::Result RunQuery(const SQL::Query &query) diff --git a/modules/commands/cs_fantasy_top.cpp b/modules/commands/cs_fantasy_top.cpp index 9baceeda3..ef87cd87f 100644 --- a/modules/commands/cs_fantasy_top.cpp +++ b/modules/commands/cs_fantasy_top.cpp @@ -102,11 +102,12 @@ class CSTop : public Module ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override + void OnReload(Configuration::Conf *conf) anope_override { - prefix = reader.ReadValue("chanstats", "prefix", "anope_", 0); - Anope::string engine = reader.ReadValue("chanstats", "engine", "", 0); - this->sql = ServiceReference<SQL::Provider>("SQL::Provider", engine); + prefix = conf->GetModule(this)->Get<const Anope::string &>("prefix"); + if (prefix.empty()) + prefix = "anope_"; + this->sql = ServiceReference<SQL::Provider>("SQL::Provider", conf->GetModule(this)->Get<const Anope::string &>("engine")); } SQL::Result RunQuery(const SQL::Query &query) diff --git a/modules/commands/cs_flags.cpp b/modules/commands/cs_flags.cpp index cd1a14e83..8ed4cc8c6 100644 --- a/modules/commands/cs_flags.cpp +++ b/modules/commands/cs_flags.cpp @@ -13,6 +13,7 @@ #include "module.h" +static ServiceReference<ChanServService> chanserv("ChanServService", "ChanServ"); static std::map<Anope::string, char> defaultFlags; class FlagsChanAccess : public ChanAccess @@ -113,9 +114,10 @@ class CommandCSFlags : public Command } } - if (ci->GetAccessCount() >= Config->CSAccessMax) + unsigned access_max = Config->GetModule("chanserv")->Get<unsigned>("accessmax", "1024"); + if (access_max && ci->GetAccessCount() >= access_max) { - source.Reply(_("Sorry, you can only have %d access entries on a channel."), Config->CSAccessMax); + source.Reply(_("Sorry, you can only have %d access entries on a channel."), access_max); return; } @@ -396,19 +398,21 @@ class CSFlags : public Module ModuleManager::Attach(i, this, 1); } - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override + void OnReload(Configuration::Conf *conf) anope_override { defaultFlags.clear(); - for (int i = 0; i < reader.Enumerate("privilege"); ++i) + for (int i = 0; i < conf->CountBlock("privilege"); ++i) { - const Anope::string &pname = reader.ReadValue("privilege", "name", "", i); + Configuration::Block *priv = conf->GetBlock("privilege", i); + + const Anope::string &pname = priv->Get<const Anope::string &>("name"); Privilege *p = PrivilegeManager::FindPrivilege(pname); if (p == NULL) continue; - const Anope::string &value = reader.ReadValue("privilege", "flag", "", i); + const Anope::string &value = priv->Get<const Anope::string &>("flag"); if (value.empty()) continue; diff --git a/modules/commands/cs_info.cpp b/modules/commands/cs_info.cpp index a686541be..e26dc1970 100644 --- a/modules/commands/cs_info.cpp +++ b/modules/commands/cs_info.cpp @@ -13,6 +13,8 @@ #include "module.h" +static ServiceReference<ChanServService> chanserv("ChanServService", "ChanServ"); + class CommandCSInfo : public Command { void CheckOptStr(Anope::string &buf, const Anope::string &opt, const char *str, const ChannelInfo *ci, const NickCore *nc) @@ -102,8 +104,9 @@ class CommandCSInfo : public Command if (!ml.empty()) info["Mode lock"] = ml; - if (!ci->HasExt("NO_EXPIRE")) - info["Expires on"] = Anope::strftime(ci->last_used + Config->CSExpire); + time_t chanserv_expire = Config->GetModule("chanserv")->Get<time_t>("expire", "14d"); + if (!ci->HasExt("NO_EXPIRE") && chanserv_expire && !Anope::NoExpire) + info["Expires on"] = Anope::strftime(ci->last_used + chanserv_expire); } if (ci->HasExt("SUSPENDED")) { diff --git a/modules/commands/cs_kick.cpp b/modules/commands/cs_kick.cpp index d7251ec6b..f1a632af3 100644 --- a/modules/commands/cs_kick.cpp +++ b/modules/commands/cs_kick.cpp @@ -13,6 +13,8 @@ #include "module.h" +static ServiceReference<ChanServService> chanserv("ChanServService", "ChanServ"); + class CommandCSKick : public Command { public: @@ -45,8 +47,9 @@ class CommandCSKick : public Command return; } - if (reason.length() > Config->CSReasonMax) - reason = reason.substr(0, Config->CSReasonMax); + unsigned reasonmax = Config->GetModule("chanserv")->Get<unsigned>("reasonmax", "200"); + if (reason.length() > reasonmax) + reason = reason.substr(0, reasonmax); AccessGroup u_access = source.AccessFor(ci); diff --git a/modules/commands/cs_list.cpp b/modules/commands/cs_list.cpp index 72f3e35dc..5d0f16f60 100644 --- a/modules/commands/cs_list.cpp +++ b/modules/commands/cs_list.cpp @@ -68,6 +68,7 @@ class CommandCSList : public Command } Anope::string spattern = "#" + pattern; + unsigned listmax = Config->GetModule(this->owner)->Get<unsigned>("listmax"); source.Reply(_("List of entries matching \002%s\002:"), pattern.c_str()); @@ -91,7 +92,7 @@ class CommandCSList : public Command if (pattern.equals_ci(ci->name) || ci->name.equals_ci(spattern) || Anope::Match(ci->name, pattern, false, true) || Anope::Match(ci->name, spattern, false, true)) { - if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nchans <= Config->CSListMax) + if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nchans <= listmax) { bool isnoexpire = false; if (is_servadmin && (ci->HasExt("NO_EXPIRE"))) @@ -115,7 +116,7 @@ class CommandCSList : public Command for (unsigned i = 0; i < replies.size(); ++i) source.Reply(replies[i]); - source.Reply(_("End of list - %d/%d matches shown."), nchans > Config->CSListMax ? Config->CSListMax : nchans, nchans); + source.Reply(_("End of list - %d/%d matches shown."), nchans > listmax ? listmax : nchans, nchans); return; } @@ -150,11 +151,11 @@ class CommandCSList : public Command " \002LIST #51-100\002\n" " Lists all registered channels within the given range (51-100).")); - if (!Config->RegexEngine.empty()) + if (!Config->GetBlock("options")->Get<const Anope::string &>("regexengine").empty()) { source.Reply(" "); source.Reply(_("Regex matches are also supported using the %s engine.\n" - "Enclose your pattern in // if this is desired."), Config->RegexEngine.c_str()); + "Enclose your pattern in // if this is desired."), Config->GetBlock("options")->Get<const char *>("regexengine")); } return true; @@ -168,7 +169,6 @@ class CSList : public Module public: CSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcslist(this) { - } }; diff --git a/modules/commands/cs_mode.cpp b/modules/commands/cs_mode.cpp index f1d700cfa..38390251b 100644 --- a/modules/commands/cs_mode.cpp +++ b/modules/commands/cs_mode.cpp @@ -391,7 +391,7 @@ class CommandCSMode : public Command new_params.push_back("-*"); this->DoSet(source, ci, new_params); } - else if (param.equals_ci("BANS") || param.equals_ci("EXCEPTS") || param.equals_ci("INVITEOVERRIDES") || param.equals_ci("VOICES") || param.equals_ci("HALFOPS") || param.equals_ci("OPS")) + else if (param.equals_ci("BANS") || param.equals_ci("EXEMPTS") || param.equals_ci("INVITEOVERRIDES") || param.equals_ci("VOICES") || param.equals_ci("HALFOPS") || param.equals_ci("OPS")) { const Anope::string &mname = param.upper().substr(0, param.length() - 1); ChannelMode *cm = ModeManager::FindChannelModeByName(mname); diff --git a/modules/commands/cs_register.cpp b/modules/commands/cs_register.cpp index 5f31d823c..feeb605bc 100644 --- a/modules/commands/cs_register.cpp +++ b/modules/commands/cs_register.cpp @@ -26,6 +26,7 @@ class CommandCSRegister : public Command { const Anope::string &chan = params[0]; const Anope::string &chdesc = params.size() > 1 ? params[1] : ""; + unsigned maxregistered = Config->GetModule("chanserv")->Get<unsigned>("maxregistered"); User *u = source.GetUser(); NickCore *nc = source.nc; @@ -48,19 +49,14 @@ class CommandCSRegister : public Command source.Reply(_("Channel \002%s\002 is already registered!"), chan.c_str()); else if (c && !c->HasUserStatus(u, "OP")) source.Reply(_("You must be a channel operator to register the channel.")); - else if (Config->CSMaxReg && nc->channelcount >= Config->CSMaxReg && !source.HasPriv("chanserv/no-register-limit")) - source.Reply(nc->channelcount > Config->CSMaxReg ? CHAN_EXCEEDED_CHANNEL_LIMIT : CHAN_REACHED_CHANNEL_LIMIT, Config->CSMaxReg); + else if (maxregistered && nc->channelcount >= maxregistered && !source.HasPriv("chanserv/no-register-limit")) + source.Reply(nc->channelcount > maxregistered ? CHAN_EXCEEDED_CHANNEL_LIMIT : CHAN_REACHED_CHANNEL_LIMIT, maxregistered); else { ci = new ChannelInfo(chan); ci->SetFounder(nc); ci->desc = chdesc; - for (std::list<std::pair<Anope::string, Anope::string> >::const_iterator it = ModeManager::ModeLockOn.begin(), it_end = ModeManager::ModeLockOn.end(); it != it_end; ++it) - ci->SetMLock(ModeManager::FindChannelModeByName(it->first), true, it->second, source.GetNick()); - for (std::list<Anope::string>::const_iterator it = ModeManager::ModeLockOff.begin(), it_end = ModeManager::ModeLockOff.end(); it != it_end; ++it) - ci->SetMLock(ModeManager::FindChannelModeByName(*it), false, "", source.GetNick()); - if (c && !c->topic.empty()) { ci->last_topic = c->topic; @@ -113,9 +109,8 @@ class CommandCSRegister : public Command "other channel users.\n" " \n" "NOTICE: In order to register a channel, you must have\n" - "first registered your nickname. If you haven't,\n" - "\002%s%s HELP\002 for information on how to do so."), - source.service->nick.c_str(), source.service->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str()); + "first registered your nickname."), + source.service->nick.c_str(), source.service->nick.c_str(), Config->StrictPrivmsg.c_str(), source.service->nick.c_str()); return true; } }; diff --git a/modules/commands/cs_seen.cpp b/modules/commands/cs_seen.cpp index 2d45f9a15..610ad4475 100644 --- a/modules/commands/cs_seen.cpp +++ b/modules/commands/cs_seen.cpp @@ -82,9 +82,6 @@ struct SeenInfo : Serializable } }; -static time_t purgetime; -static time_t expiretimeout; - static SeenInfo *FindInfo(const Anope::string &nick) { database_map::iterator iter = database.find(nick); @@ -192,9 +189,9 @@ class CommandSeen : public Command { const Anope::string &target = params[0]; - if (target.length() > Config->NickLen) + if (target.length() > Config->GetBlock("networkinfo")->Get<unsigned>("nicklen")) { - source.Reply(_("Nick too long, max length is %u characters."), Config->NickLen); + source.Reply(_("Nick too long, max length is %u characters."), Config->GetBlock("networkinfo")->Get<unsigned>("nicklen")); return; } @@ -300,7 +297,9 @@ class DataBasePurger : public Timer void Tick(time_t) anope_override { - size_t previous_size = database.size(); + size_t previous_size = database.size(), purgetime = Config->GetModule(this->GetOwner())->Get<time_t>("purgetime"); + if (!purgetime) + purgetime = Anope::DoTime("30d"); for (database_map::iterator it = database.begin(), it_end = database.end(); it != it_end;) { database_map::iterator cur = it; @@ -333,14 +332,15 @@ class CSSeen : public Module I_OnUserQuit, I_OnJoinChannel, I_OnPartChannel, - I_OnUserKicked }; + I_OnPreUserKicked }; ModuleManager::Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation)); } - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override + void OnReload(Configuration::Conf *conf) anope_override { - purgetime = Anope::DoTime(reader.ReadValue("cs_seen", "purgetime", "30d", 0)); - expiretimeout = Anope::DoTime(reader.ReadValue("cs_seen", "expiretimeout", "1d", 0)); + time_t expiretimeout = conf->GetModule(this)->Get<time_t>("expiretimeout"); + if (!expiretimeout) + expiretimeout = Anope::DoTime("1d"); if (purger.GetSecs() != expiretimeout) purger.SetSecs(expiretimeout); @@ -373,9 +373,9 @@ class CSSeen : public Module UpdateUser(u, PART, u->nick, "", channel, msg); } - void OnUserKicked(Channel *c, User *target, MessageSource &source, const Anope::string &msg) anope_override + void OnPreUserKicked(MessageSource &source, ChanUserContainer *cu, const Anope::string &msg) anope_override { - UpdateUser(target, KICK, target->nick, source.GetSource(), c->name, msg); + UpdateUser(cu->user, KICK, cu->user->nick, source.GetSource(), cu->chan->name, msg); } private: diff --git a/modules/commands/cs_set.cpp b/modules/commands/cs_set.cpp index 99b3e3ec5..0de1a39ad 100644 --- a/modules/commands/cs_set.cpp +++ b/modules/commands/cs_set.cpp @@ -50,7 +50,7 @@ class CommandCSSet : public Command } } source.Reply(_("Type \002%s%s HELP %s \037option\037\002 for more information on a\n" - "particular option."), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), this_name.c_str()); + "particular option."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), this_name.c_str()); return true; } }; @@ -106,8 +106,8 @@ class CommandCSSetAutoOp : public Command source.Reply(" "); source.Reply(_("Enables or disables %s's autoop feature for a\n" "channel. When disabled, users who join the channel will\n" - "not automatically gain any status from %s."), Config->ChanServ.c_str(), - Config->ChanServ.c_str(), this->name.c_str()); + "not automatically gain any status from %s."), ChanServ->nick.c_str(), + ChanServ->nick.c_str(), this->name.c_str()); return true; } }; @@ -319,7 +319,8 @@ class CommandCSSetFounder : public Command } NickCore *nc = na->nc; - if (Config->CSMaxReg && nc->channelcount >= Config->CSMaxReg && !source.HasPriv("chanserv/no-register-limit")) + unsigned max_reg = Config->GetModule("chanserv")->Get<unsigned>("maxregistered"); + if (max_reg && nc->channelcount >= max_reg && !source.HasPriv("chanserv/no-register-limit")) { source.Reply(_("\002%s\002 has too many channels registered."), na->nick.c_str()); return; @@ -552,7 +553,7 @@ class CommandCSSetPersist : public Command /* No channel mode, no BotServ, but using ChanServ as the botserv bot * which was assigned when persist was set on */ - if (!cm && Config->BotServ.empty() && ci->bi) + if (!cm && !BotServ && ci->bi) { if (!ChanServ) { @@ -654,7 +655,7 @@ class CommandCSSetPrivate : public Command source.Reply(_("Enables or disables the \002private\002 option for a channel.\n" "When \002private\002 is set, a \002%s%s LIST\002 will not\n" "include the channel in any lists."), - Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str()); + Config->StrictPrivmsg.c_str(), source.service->nick.c_str()); return true; } }; @@ -1027,10 +1028,12 @@ class CommandCSSetSuccessor : public Command source.Reply(_("Changes the successor of a channel. If the founder's\n" "nickname expires or is dropped while the channel is still\n" "registered, the successor will become the new founder of the\n" - "channel. However, if the successor already has too many\n" + "channel. The new nickname must be a registered one.")); + unsigned max_reg = Config->GetModule("chanserv")->Get<unsigned>("maxregistered"); + if (max_reg) + source.Reply(_("However, if the successor already has too many\n" "channels registered (%d), the channel will be dropped\n" - "instead, just as if no successor had been set. The new\n" - "nickname must be a registered one."), Config->CSMaxReg); + "instead, just as if no successor had been set."), max_reg); return true; } }; @@ -1117,21 +1120,10 @@ class CSSet : public Module commandcssetsuccessor(this), commandcssetnoexpire(this) { - Implementation i[] = { I_OnReload, I_OnChanRegistered, I_OnCheckKick, I_OnDelChan }; + Implementation i[] = { I_OnCheckKick, I_OnDelChan }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override - { - CSDefChanstats = reader.ReadFlag("chanstats", "CSDefChanstats", "0", 0); - } - - void OnChanRegistered(ChannelInfo *ci) anope_override - { - if (CSDefChanstats) - ci->ExtendMetadata("STATS"); - } - EventReturn OnCheckKick(User *u, ChannelInfo *ci, Anope::string &mask, Anope::string &reason) anope_override { if (!ci->HasExt("RESTRICTED") || ci->c->MatchesList(u, "EXCEPT")) diff --git a/modules/commands/cs_set_misc.cpp b/modules/commands/cs_set_misc.cpp index e74587be1..325b652cd 100644 --- a/modules/commands/cs_set_misc.cpp +++ b/modules/commands/cs_set_misc.cpp @@ -142,17 +142,19 @@ class CSSetMisc : public Module ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override + void OnReload(Configuration::Conf *conf) anope_override { descriptions.clear(); - for (int i = 0; i < reader.Enumerate("command"); ++i) + for (int i = 0; i < conf->CountBlock("command"); ++i) { - if (reader.ReadValue("command", "command", "", i) != "chanserv/set/misc") + Configuration::Block *block = conf->GetBlock("command", i); + + if (block->Get<const Anope::string &>("command") != "chanserv/set/misc") continue; - Anope::string cname = reader.ReadValue("command", "name", "", i); - Anope::string desc = reader.ReadValue("command", "misc_description", "", i); + Anope::string cname = block->Get<const Anope::string &>("name"); + Anope::string desc = block->Get<const Anope::string &>("misc_description"); if (cname.empty() || desc.empty()) continue; diff --git a/modules/commands/cs_suspend.cpp b/modules/commands/cs_suspend.cpp index 4927737f6..a26cbacd5 100644 --- a/modules/commands/cs_suspend.cpp +++ b/modules/commands/cs_suspend.cpp @@ -27,8 +27,7 @@ class CommandCSSuspend : public Command const Anope::string &chan = params[0]; Anope::string expiry = params.size() > 1 ? params[1] : ""; Anope::string reason = params.size() > 2 ? params[2] : ""; - time_t expiry_secs = Config->CSSuspendExpire; - + time_t expiry_secs = Config->GetModule(this->owner)->Get<time_t>("expire"); if (!expiry.empty() && expiry[0] != '+') { @@ -39,12 +38,6 @@ class CommandCSSuspend : public Command else expiry_secs = Anope::DoTime(expiry); - if (Config->ForceForbidReason && reason.empty()) - { - this->OnSyntaxError(source, ""); - return; - } - if (Anope::ReadOnly) source.Reply(READ_ONLY_MODE); @@ -172,6 +165,8 @@ class CSSuspend : public Module ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } + // cs info output? + void OnPreChanExpire(ChannelInfo *ci, bool &expire) anope_override { if (!ci->HasExt("SUSPENDED")) diff --git a/modules/commands/cs_xop.cpp b/modules/commands/cs_xop.cpp index 8b6bc4bb7..5d0fe9f21 100644 --- a/modules/commands/cs_xop.cpp +++ b/modules/commands/cs_xop.cpp @@ -13,6 +13,7 @@ namespace { + ServiceReference<ChanServService> chanserv("ChanServService", "ChanServ"); std::vector<Anope::string> order; std::map<Anope::string, std::vector<Anope::string> > permissions; } @@ -161,9 +162,10 @@ class CommandCSXOP : public Command } } - if (ci->GetAccessCount() >= Config->CSAccessMax) + unsigned access_max = Config->GetModule("chanserv")->Get<unsigned>("accessmax", "1024"); + if (access_max && ci->GetAccessCount() >= access_max) { - source.Reply(_("Sorry, you can only have %d %s entries on a channel."), Config->CSAccessMax, source.command.c_str()); + source.Reply(_("Sorry, you can only have %d %s entries on a channel."), access_max, source.command.c_str()); return; } @@ -527,8 +529,8 @@ class CommandCSXOP : public Command "available. See \002%s%s HELP ACCESS\002 for information\n" "about the access list, and \002%s%s HELP FLAGS\002 for\n" "information about the flags based system."), - Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), - Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str()); + Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), + Config->StrictPrivmsg.c_str(), source.service->nick.c_str()); return true; } }; @@ -548,31 +550,32 @@ class CSXOP : public Module ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override + void OnReload(Configuration::Conf *conf) anope_override { order.clear(); permissions.clear(); - - for (int i = 0; i < reader.Enumerate("privilege"); ++i) + for (int i = 0; i < conf->CountBlock("privilege"); ++i) { - const Anope::string &pname = reader.ReadValue("privilege", "name", "", i); + Configuration::Block *block = conf->GetBlock("privilege", i); + const Anope::string &pname = block->Get<const Anope::string &>("name"); Privilege *p = PrivilegeManager::FindPrivilege(pname); if (p == NULL) continue; - const Anope::string &xop = reader.ReadValue("privilege", "xop", "", i); - if (xop.empty()) + const Anope::string &xop = block->Get<const Anope::string &>("xop"); + if (pname.empty() || xop.empty()) continue; permissions[xop].push_back(pname); } - for (int i = 0; i < reader.Enumerate("command"); ++i) + for (int i = 0; i < conf->CountBlock("command"); ++i) { - const Anope::string &cname = reader.ReadValue("command", "name", "", i), - &cserv = reader.ReadValue("command", "command", "", i); + Configuration::Block *block = conf->GetBlock("command", i); + const Anope::string &cname = block->Get<const Anope::string &>("name"), + &cserv = block->Get<const Anope::string &>("command"); if (cname.empty() || cserv != "chanserv/xop") continue; diff --git a/modules/commands/help.cpp b/modules/commands/help.cpp index a55af89ff..eaf45ebf4 100644 --- a/modules/commands/help.cpp +++ b/modules/commands/help.cpp @@ -46,6 +46,7 @@ class CommandHelp : public Command Anope::string source_command = source.command; const BotInfo *bi = source.service; const CommandInfo::map &map = source.c ? Config->Fantasy : bi->commands; + bool hide_privileged_commands = Config->GetBlock("options")->Get<bool>("hideprivilegedcommands"); if (params.empty() || params[0].equals_ci("ALL")) { @@ -73,8 +74,8 @@ class CommandHelp : public Command ServiceReference<Command> c("Command", info.name); if (!c) continue; - else if (!Config->HidePrivilegedCommands) - ; // Always show with HidePrivilegedCommands disabled + else if (!hide_privileged_commands) + ; // Always show with hide_privileged_commands disabled else if (!c->AllowUnregistered() && !source.GetAccount()) continue; else if (!info.permission.empty() && !source.HasCommand(info.permission)) @@ -146,8 +147,8 @@ class CommandHelp : public Command ServiceReference<Command> c("Command", info.name); if (!c) continue; - else if (!Config->HidePrivilegedCommands) - ; // Always show with HidePrivilegedCommands disabled + else if (!hide_privileged_commands) + ; // Always show with hide_privileged_commands disabled else if (!info.permission.empty() && !source.HasCommand(info.permission)) continue; diff --git a/modules/commands/hs_list.cpp b/modules/commands/hs_list.cpp index 94533e73d..6bf6d49a9 100644 --- a/modules/commands/hs_list.cpp +++ b/modules/commands/hs_list.cpp @@ -55,7 +55,7 @@ class CommandHSList : public Command } } - unsigned display_counter = 0; + unsigned display_counter = 0, listmax = Config->GetModule(this->owner)->Get<unsigned>("listmax"); ListFormatter list; list.AddColumn("Number").AddColumn("Nick").AddColumn("Vhost").AddColumn("Creator").AddColumn("Created"); @@ -68,7 +68,7 @@ class CommandHSList : public Command if (!key.empty() && key[0] != '#') { - if ((Anope::Match(na->nick, key) || Anope::Match(na->GetVhostHost(), key)) && display_counter < Config->NSListMax) + if ((Anope::Match(na->nick, key) || Anope::Match(na->GetVhostHost(), key)) && display_counter < listmax) { ++display_counter; @@ -90,7 +90,7 @@ class CommandHSList : public Command * List the host if its in the display range, and not more * than NSListMax records have been displayed... **/ - if (((counter >= from && counter <= to) || (!from && !to)) && display_counter < Config->NSListMax) + if (((counter >= from && counter <= to) || (!from && !to)) && display_counter < listmax) { ++display_counter; ListFormatter::ListEntry entry; @@ -141,9 +141,7 @@ class CommandHSList : public Command "entries beginning with \"Rob\"\n" "If a \037#X-Y\037 style is used, only entries between the range of \002X\002\n" "and \002Y\002 will be displayed, e.g. \002#1-3\002 will display the first 3\n" - "nick/vhost entries.\n" - "The list uses the value of NSListMax as a hard limit for the\n" - "number of items to display to a operator at any one time.")); + "nick/vhost entries.")); return true; } }; @@ -156,7 +154,6 @@ class HSList : public Module HSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandhslist(this) { - } }; diff --git a/modules/commands/hs_request.cpp b/modules/commands/hs_request.cpp index 1e8f2aa82..0c29705ef 100644 --- a/modules/commands/hs_request.cpp +++ b/modules/commands/hs_request.cpp @@ -18,12 +18,9 @@ #include "module.h" #include "memoserv.h" -static ServiceReference<MemoServService> MemoServService("MemoServService", "MemoServ"); +static ServiceReference<MemoServService> memoserv("MemoServService", "MemoServ"); -static bool HSRequestMemoUser = false; -static bool HSRequestMemoOper = false; - -void req_send_memos(CommandSource &source, const Anope::string &vIdent, const Anope::string &vHost); +static void req_send_memos(Module *me, CommandSource &source, const Anope::string &vIdent, const Anope::string &vHost); struct HostRequest : ExtensibleItem, Serializable { @@ -114,9 +111,9 @@ class CommandHSRequest : public Command if (!user.empty()) { - if (user.length() > Config->UserLen) + if (user.length() > Config->GetBlock("networkinfo")->Get<unsigned>("userlen")) { - source.Reply(HOST_SET_IDENTTOOLONG, Config->UserLen); + source.Reply(HOST_SET_IDENTTOOLONG, Config->GetBlock("networkinfo")->Get<unsigned>("userlen")); return; } else if (!IRCD->CanSetVIdent) @@ -132,9 +129,9 @@ class CommandHSRequest : public Command } } - if (host.length() > Config->HostLen) + if (host.length() > Config->GetBlock("networkinfo")->Get<unsigned>("hostlen")) { - source.Reply(HOST_SET_TOOLONG, Config->HostLen); + source.Reply(HOST_SET_TOOLONG, Config->GetBlock("networkinfo")->Get<unsigned>("hostlen")); return; } @@ -144,14 +141,14 @@ class CommandHSRequest : public Command return; } - if (HSRequestMemoOper && Config->MSSendDelay > 0 && u && u->lastmemosend + Config->MSSendDelay > Anope::CurTime) + time_t send_delay = Config->GetModule("memoserv")->Get<time_t>("senddelay"); + if (Config->GetModule(this->owner)->Get<bool>("memooper") && send_delay > 0 && u && u->lastmemosend + send_delay > Anope::CurTime) { - source.Reply(_("Please wait %d seconds before requesting a new vHost."), Config->MSSendDelay); + source.Reply(_("Please wait %d seconds before requesting a new vHost."), send_delay); u->lastmemosend = Anope::CurTime; return; } - HostRequest *req = new HostRequest; req->nick = source.GetNick(); req->ident = user; @@ -160,10 +157,8 @@ class CommandHSRequest : public Command na->Extend("hs_request", req); source.Reply(_("Your vHost has been requested.")); - req_send_memos(source, user, host); + req_send_memos(owner, source, user, host); Log(LOG_COMMAND, source, this) << "to request new vhost " << (!user.empty() ? user + "@" : "") << host; - - return; } bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override @@ -198,8 +193,8 @@ class CommandHSActivate : public Command na->SetVhost(req->ident, req->host, source.GetNick(), req->time); FOREACH_MOD(I_OnSetVhost, OnSetVhost(na)); - if (HSRequestMemoUser && MemoServService) - MemoServService->Send(Config->HostServ, na->nick, _("[auto memo] Your requested vHost has been approved."), true); + if (Config->GetModule(this->owner)->Get<bool>("memouser") && memoserv) + memoserv->Send(HostServ->nick, na->nick, _("[auto memo] Your requested vHost has been approved."), true); source.Reply(_("vHost for %s has been activated."), na->nick.c_str()); Log(LOG_COMMAND, source, this) << "for " << na->nick << " for vhost " << (!req->ident.empty() ? req->ident + "@" : "") << req->host; @@ -214,7 +209,7 @@ class CommandHSActivate : public Command this->SendSyntax(source); source.Reply(" "); source.Reply(_("Activate the requested vHost for the given nick.")); - if (HSRequestMemoUser) + if (Config->GetModule(this->owner)->Get<bool>("memouser")) source.Reply(_("A memo informing the user will also be sent.")); return true; @@ -242,7 +237,7 @@ class CommandHSReject : public Command { na->Shrink("hs_request"); - if (HSRequestMemoUser && MemoServService) + if (Config->GetModule(this->owner)->Get<bool>("memouser") && memoserv) { Anope::string message; if (!reason.empty()) @@ -250,7 +245,7 @@ class CommandHSReject : public Command else message = _("[auto memo] Your requested vHost has been rejected."); - MemoServService->Send(Config->HostServ, nick, message, true); + memoserv->Send(HostServ->nick, nick, message, true); } source.Reply(_("vHost for %s has been rejected."), nick.c_str()); @@ -267,7 +262,7 @@ class CommandHSReject : public Command this->SendSyntax(source); source.Reply(" "); source.Reply(_("Reject the requested vHost for the given nick.")); - if (HSRequestMemoUser) + if (Config->GetModule(this->owner)->Get<bool>("memouser")) source.Reply(_("A memo informing the user will also be sent.")); return true; @@ -280,7 +275,7 @@ class CommandHSWaiting : public Command { int counter = 1; int from = 0, to = 0; - unsigned display_counter = 0; + unsigned display_counter = 0, listmax = Config->GetModule(this->owner)->Get<unsigned>("listmax"); ListFormatter list; list.AddColumn("Number").AddColumn("Nick").AddColumn("Vhost").AddColumn("Created"); @@ -292,7 +287,7 @@ class CommandHSWaiting : public Command if (!hr) continue; - if (((counter >= from && counter <= to) || (!from && !to)) && display_counter < Config->NSListMax) + if (((counter >= from && counter <= to) || (!from && !to)) && display_counter < listmax) { ++display_counter; @@ -353,9 +348,6 @@ class HSRequest : public Module if (!IRCD || !IRCD->CanSetVHost) throw ModuleException("Your IRCd does not support vhosts"); - - Implementation i[] = { I_OnReload }; - ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } ~HSRequest() @@ -366,15 +358,9 @@ class HSRequest : public Module na->Shrink("hs_request"); } } - - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override - { - HSRequestMemoUser = reader.ReadFlag("hs_request", "memouser", "no", 0); - HSRequestMemoOper = reader.ReadFlag("hs_request", "memooper", "no", 0); - } }; -void req_send_memos(CommandSource &source, const Anope::string &vIdent, const Anope::string &vHost) +static void req_send_memos(Module *me, CommandSource &source, const Anope::string &vIdent, const Anope::string &vHost) { Anope::string host; std::list<std::pair<Anope::string, Anope::string> >::iterator it, it_end; @@ -384,7 +370,7 @@ void req_send_memos(CommandSource &source, const Anope::string &vIdent, const An else host = vHost; - if (HSRequestMemoOper == 1 && MemoServService) + if (Config->GetModule(me)->Get<bool>("memooper") && memoserv) for (unsigned i = 0; i < Config->Opers.size(); ++i) { Oper *o = Config->Opers[i]; @@ -395,7 +381,7 @@ void req_send_memos(CommandSource &source, const Anope::string &vIdent, const An Anope::string message = Anope::printf(_("[auto memo] vHost \002%s\002 has been requested by %s."), host.c_str(), source.GetNick().c_str()); - MemoServService->Send(Config->HostServ, na->nick, message, true); + memoserv->Send(HostServ->nick, na->nick, message, true); } } diff --git a/modules/commands/hs_set.cpp b/modules/commands/hs_set.cpp index 4adc86897..8e83ae8a8 100644 --- a/modules/commands/hs_set.cpp +++ b/modules/commands/hs_set.cpp @@ -67,9 +67,9 @@ class CommandHSSet : public Command } } - if (host.length() > Config->HostLen) + if (host.length() > Config->GetBlock("networkinfo")->Get<unsigned>("hostlen")) { - source.Reply(HOST_SET_TOOLONG, Config->HostLen); + source.Reply(HOST_SET_TOOLONG, Config->GetBlock("networkinfo")->Get<unsigned>("hostlen")); return; } @@ -168,9 +168,9 @@ class CommandHSSetAll : public Command } } - if (host.length() > Config->HostLen) + if (host.length() > Config->GetBlock("networkinfo")->Get<unsigned>("hostlen")) { - source.Reply(HOST_SET_TOOLONG, Config->HostLen); + source.Reply(HOST_SET_TOOLONG, Config->GetBlock("networkinfo")->Get<unsigned>("hostlen")); return; } diff --git a/modules/commands/ms_read.cpp b/modules/commands/ms_read.cpp index c98708724..0d269bd02 100644 --- a/modules/commands/ms_read.cpp +++ b/modules/commands/ms_read.cpp @@ -71,10 +71,13 @@ class MemoListCallback : public NumberList static void DoRead(CommandSource &source, MemoInfo *mi, const ChannelInfo *ci, unsigned index) { Memo *m = mi->GetMemo(index); + if (!m) + return; + if (ci) - source.Reply(_("Memo %d from %s (%s). To delete, type: \002%s%s DEL %s %d\002"), index + 1, m->sender.c_str(), Anope::strftime(m->time).c_str(), Config->UseStrictPrivMsgString.c_str(), Config->MemoServ.c_str(), ci->name.c_str(), index + 1); + source.Reply(_("Memo %d from %s (%s). To delete, type: \002%s%s DEL %s %d\002"), index + 1, m->sender.c_str(), Anope::strftime(m->time).c_str(), Config->StrictPrivmsg.c_str(), MemoServ->nick.c_str(), ci->name.c_str(), index + 1); else - source.Reply(_("Memo %d from %s (%s). To delete, type: \002%s%s DEL %d\002"), index + 1, m->sender.c_str(), Anope::strftime(m->time).c_str(), Config->UseStrictPrivMsgString.c_str(), Config->MemoServ.c_str(), index + 1); + source.Reply(_("Memo %d from %s (%s). To delete, type: \002%s%s DEL %d\002"), index + 1, m->sender.c_str(), Anope::strftime(m->time).c_str(), Config->StrictPrivmsg.c_str(), MemoServ->nick.c_str(), index + 1); source.Reply("%s", m->text.c_str()); m->unread = false; diff --git a/modules/commands/ms_rsend.cpp b/modules/commands/ms_rsend.cpp index bbfb50117..19a20a279 100644 --- a/modules/commands/ms_rsend.cpp +++ b/modules/commands/ms_rsend.cpp @@ -14,7 +14,10 @@ #include "module.h" #include "memoserv.h" -static ServiceReference<MemoServService> MemoServService("MemoServService", "MemoServ"); +namespace +{ + ServiceReference<MemoServService> memoserv("MemoServService", "MemoServ"); +} class CommandMSRSend : public Command { @@ -27,10 +30,9 @@ class CommandMSRSend : public Command void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (!MemoServService) + if (!memoserv) return; - const Anope::string &nick = params[0]; const Anope::string &text = params[1]; const NickAlias *na = NULL; @@ -42,20 +44,15 @@ class CommandMSRSend : public Command return; } - if (Config->MSMemoReceipt == 1 && !source.IsServicesOper()) + if (Config->GetModule(this->owner)->Get<bool>("operonly") && !source.IsServicesOper()) source.Reply(ACCESS_DENIED); - else if (Config->MSMemoReceipt > 2 || Config->MSMemoReceipt == 0) - { - Log(this->owner) << "MSMemoReceipt is misconfigured to " << Config->MSMemoReceipt; - source.Reply(_("Sorry, RSEND has been disabled on this network.")); - } else { - MemoServService::MemoResult result = MemoServService->Send(source.GetNick(), nick, text); + MemoServService::MemoResult result = memoserv->Send(source.GetNick(), nick, text); if (result == MemoServService::MEMO_INVALID_TARGET) source.Reply(_("\002%s\002 is not a registered unforbidden nick or channel."), nick.c_str()); else if (result == MemoServService::MEMO_TOO_FAST) - source.Reply(_("Please wait %d seconds before using the SEND command again."), Config->MSSendDelay); + source.Reply(_("Please wait %d seconds before using the %s command again."), Config->GetModule("memoserv")->Get<time_t>("senddelay"), source.command.c_str()); else if (result == MemoServService::MEMO_TARGET_FULL) source.Reply(_("Sorry, %s currently has too many memos and cannot receive more."), nick.c_str()); else @@ -71,8 +68,6 @@ class CommandMSRSend : public Command m->receipt = true; } } - - return; } bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override @@ -98,11 +93,8 @@ class MSRSend : public Module MSRSend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandmsrsend(this) { - - if (!MemoServService) + if (!memoserv) throw ModuleException("No MemoServ!"); - else if (!Config->MSMemoReceipt) - throw ModuleException("Invalid value for memoreceipt"); } }; diff --git a/modules/commands/ms_send.cpp b/modules/commands/ms_send.cpp index 15ca4a6ba..18a609893 100644 --- a/modules/commands/ms_send.cpp +++ b/modules/commands/ms_send.cpp @@ -39,11 +39,9 @@ class CommandMSSend : public Command else if (result == MemoServService::MEMO_INVALID_TARGET) source.Reply(_("\002%s\002 is not a registered unforbidden nick or channel."), nick.c_str()); else if (result == MemoServService::MEMO_TOO_FAST) - source.Reply(_("Please wait %d seconds before using the SEND command again."), Config->MSSendDelay); + source.Reply(_("Please wait %d seconds before using the %s command again."), Config->GetModule("memoserv")->Get<time_t>("senddelay"), source.command.c_str()); else if (result == MemoServService::MEMO_TARGET_FULL) source.Reply(_("Sorry, %s currently has too many memos and cannot receive more."), nick.c_str()); - - return; } bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override diff --git a/modules/commands/ms_set.cpp b/modules/commands/ms_set.cpp index b0a2fb8ba..dafb5a857 100644 --- a/modules/commands/ms_set.cpp +++ b/modules/commands/ms_set.cpp @@ -13,6 +13,11 @@ #include "module.h" +namespace +{ + ServiceReference<MemoServService> memoserv("MemoServService", "MemoServ"); +} + class CommandMSSet : public Command { private: @@ -25,19 +30,19 @@ class CommandMSSet : public Command { nc->ExtendMetadata("MEMO_SIGNON"); nc->ExtendMetadata("MEMO_RECEIVE"); - source.Reply(_("%s will now notify you of memos when you log on and when they are sent to you."), Config->MemoServ.c_str()); + source.Reply(_("%s will now notify you of memos when you log on and when they are sent to you."), MemoServ->nick.c_str()); } else if (param.equals_ci("LOGON")) { nc->ExtendMetadata("MEMO_SIGNON"); nc->Shrink("MEMO_RECEIVE"); - source.Reply(_("%s will now notify you of memos when you log on or unset /AWAY."), Config->MemoServ.c_str()); + source.Reply(_("%s will now notify you of memos when you log on or unset /AWAY."), MemoServ->nick.c_str()); } else if (param.equals_ci("NEW")) { nc->Shrink("MEMO_SIGNON"); nc->ExtendMetadata("MEMO_RECEIVE"); - source.Reply(_("%s will now notify you of memos when they are sent to you."), Config->MemoServ.c_str()); + source.Reply(_("%s will now notify you of memos when they are sent to you."), MemoServ->nick.c_str()); } else if (param.equals_ci("MAIL")) { @@ -59,7 +64,7 @@ class CommandMSSet : public Command nc->Shrink("MEMO_SIGNON"); nc->Shrink("MEMO_RECEIVE"); nc->Shrink("MEMO_MAIL"); - source.Reply(_("%s will not send you any notification of memos."), Config->MemoServ.c_str()); + source.Reply(_("%s will not send you any notification of memos."), MemoServ->nick.c_str()); } else this->OnSyntaxError(source, ""); @@ -158,6 +163,7 @@ class CommandMSSet : public Command source.Reply(_("You are not permitted to change your memo limit.")); return; } + int max_memos = Config->GetModule("memoserv")->Get<int>("maxmemos"); limit = -1; try { @@ -166,12 +172,12 @@ class CommandMSSet : public Command catch (const ConvertException &) { } /* The first character is a digit, but we could still go negative * from overflow... watch out! */ - if (limit < 0 || (Config->MSMaxMemos > 0 && static_cast<unsigned>(limit) > Config->MSMaxMemos)) + if (limit < 0 || (max_memos > 0 && limit > max_memos)) { if (!chan.empty()) - source.Reply(_("You cannot set the memo limit for %s higher than %d."), chan.c_str(), Config->MSMaxMemos); + source.Reply(_("You cannot set the memo limit for %s higher than %d."), chan.c_str(), max_memos); else - source.Reply(_("You cannot set your memo limit higher than %d."), Config->MSMaxMemos); + source.Reply(_("You cannot set your memo limit higher than %d."), max_memos); return; } } @@ -239,7 +245,7 @@ class CommandMSSet : public Command " receive\n" " \n" "Type \002%s%s HELP %s \037option\037\002 for more information\n" - "on a specific option."), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), source.command.c_str()); + "on a specific option."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), source.command.c_str()); } else if (subcommand.equals_ci("NOTIFY")) source.Reply(_("Syntax: \002NOTIFY {ON | LOGON | NEW | MAIL | NOMAIL | OFF}\002\n" @@ -260,6 +266,7 @@ class CommandMSSet : public Command "\002ON\002 is essentially \002LOGON\002 and \002NEW\002 combined.")); else if (subcommand.equals_ci("LIMIT")) { + int max_memos = Config->GetModule("memoserv")->Get<int>("maxmemos"); if (source.IsServicesOper()) source.Reply(_("Syntax: \002LIMIT [\037user\037 | \037channel\037] {\037limit\037 | NONE} [HARD]\002\n" " \n" @@ -278,14 +285,14 @@ class CommandMSSet : public Command "\002Admins\002. Other users may only enter a limit for themselves\n" "or a channel on which they have such privileges, may not\n" "remove their limit, may not set a limit above %d, and may\n" - "not set a hard limit."), Config->MSMaxMemos); + "not set a hard limit."), max_memos); else source.Reply(_("Syntax: \002LIMIT [\037channel\037] \037limit\037\002\n" " \n" "Sets the maximum number of memos you (or the given channel)\n" "are allowed to have. If you set this to 0, no one will be\n" "able to send any memos to you. However, you cannot set\n" - "this any higher than %d."), Config->MSMaxMemos); + "this any higher than %d."), max_memos); } else return false; diff --git a/modules/commands/ns_access.cpp b/modules/commands/ns_access.cpp index a026314e0..7de20b9b7 100644 --- a/modules/commands/ns_access.cpp +++ b/modules/commands/ns_access.cpp @@ -13,6 +13,8 @@ #include "module.h" +static ServiceReference<NickServService> nickserv("NickServService", "NickServ"); + class CommandNSAccess : public Command { private: @@ -24,9 +26,9 @@ class CommandNSAccess : public Command return; } - if (nc->access.size() >= Config->NSAccessMax) + if (nc->access.size() >= Config->GetModule(this->owner)->Get<unsigned>("accessmax")) { - source.Reply(_("Sorry, you can only have %d access entries for a nickname."), Config->NSAccessMax); + source.Reply(_("Sorry, you can only have %d access entries for a nickname."), Config->GetModule(this->owner)->Get<unsigned>("accessmax")); return; } @@ -119,7 +121,7 @@ class CommandNSAccess : public Command source.Reply(ACCESS_DENIED); return; } - else if (Config->NSSecureAdmins && source.GetAccount() != na->nc && na->nc->IsServicesOper() && !cmd.equals_ci("LIST")) + else if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && source.GetAccount() != na->nc && na->nc->IsServicesOper() && !cmd.equals_ci("LIST")) { source.Reply(_("You may view but not modify the access list of other Services Operators.")); return; @@ -133,7 +135,7 @@ class CommandNSAccess : public Command if (!mask.empty() && (mask.find('@') == Anope::string::npos || mask.find('!') != Anope::string::npos)) { source.Reply(BAD_USERHOST_MASK); - source.Reply(MORE_INFO, Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str(), this->name.c_str()); + source.Reply(MORE_INFO, Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), source.command.c_str()); } else if (nc->HasExt("SUSPENDED")) source.Reply(NICK_X_SUSPENDED, nc->display.c_str()); @@ -145,8 +147,6 @@ class CommandNSAccess : public Command return this->DoList(source, nc, mask); else this->OnSyntaxError(source, ""); - - return; } bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override @@ -171,7 +171,7 @@ class CommandNSAccess : public Command " Reverses the previous command.\n" " \n" " \002ACCESS LIST\002\n" - " Displays the current access list."), Config->NickServ.c_str(), Config->NickServ.c_str()); + " Displays the current access list."), source.service->nick.c_str(), source.service->nick.c_str()); return true; } }; @@ -184,7 +184,14 @@ class NSAccess : public Module NSAccess(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandnsaccess(this) { + Implementation i[] = { I_OnNickRegister }; + ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); + } + void OnNickRegister(User *u, NickAlias *na) anope_override + { + if (u && Config->GetModule(this)->Get<bool>("addaccessonreg")) + na->nc->AddAccess(u->Mask()); } }; diff --git a/modules/commands/ns_ajoin.cpp b/modules/commands/ns_ajoin.cpp index d427e9cf3..ba7e53912 100644 --- a/modules/commands/ns_ajoin.cpp +++ b/modules/commands/ns_ajoin.cpp @@ -133,7 +133,7 @@ class CommandNSAJoin : public Command if ((*channels)->at(i)->channel.equals_ci(chan)) break; - if (*source.nc == nc && (*channels)->size() >= Config->AJoinMax) + if (*source.nc == nc && (*channels)->size() >= Config->GetModule(this->owner)->Get<unsigned>("ajoinmax")) source.Reply(_("Your auto join list is full.")); else if (i != (*channels)->size()) source.Reply(_("%s is already on %s's auto join list."), chan.c_str(), nc->display.c_str()); diff --git a/modules/commands/ns_cert.cpp b/modules/commands/ns_cert.cpp index 1191aaa9b..71836481a 100644 --- a/modules/commands/ns_cert.cpp +++ b/modules/commands/ns_cert.cpp @@ -13,6 +13,8 @@ #include "module.h" +static unsigned accessmax; + class CommandNSCert : public Command { private: @@ -54,9 +56,9 @@ class CommandNSCert : public Command void DoAdd(CommandSource &source, NickCore *nc, const Anope::string &mask) { - if (nc->cert.size() >= Config->NSAccessMax) + if (nc->cert.size() >= Config->GetModule(this->owner)->Get<unsigned>("accessmax")) { - source.Reply(_("Sorry, you can only have %d certificate entries for a nickname."), Config->NSAccessMax); + source.Reply(_("Sorry, you can only have %d certificate entries for a nickname."), Config->GetModule(this->owner)->Get<unsigned>("accessmax")); return; } @@ -179,7 +181,7 @@ class CommandNSCert : public Command "If you connect to IRC and provide a client certificate with a\n" "matching fingerprint in the cert list, your nick will be\n" "automatically identified to %s.\n" - " \n"), Config->NickServ.c_str(), Config->NickServ.c_str()); + " \n"), NickServ ? NickServ->nick.c_str() : source.service->nick.c_str()); source.Reply(_("Examples:\n" " \n" " \002CERT ADD <fingerprint>\002\n" @@ -191,7 +193,7 @@ class CommandNSCert : public Command " Reverses the previous command.\n" " \n" " \002CERT LIST\002\n" - " Displays the current certificate list."), Config->NickServ.c_str()); + " Displays the current certificate list.")); return true; } }; diff --git a/modules/commands/ns_drop.cpp b/modules/commands/ns_drop.cpp index 047770f89..023d696f6 100644 --- a/modules/commands/ns_drop.cpp +++ b/modules/commands/ns_drop.cpp @@ -13,6 +13,8 @@ #include "module.h" +static ServiceReference<NickServService> nickserv("NickServService", "NickServ"); + class CommandNSDrop : public Command { public: @@ -43,7 +45,7 @@ class CommandNSDrop : public Command if (!is_mine && !source.HasPriv("nickserv/drop")) source.Reply(ACCESS_DENIED); - else if (Config->NSSecureAdmins && !is_mine && na->nc->IsServicesOper()) + else if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && !is_mine && na->nc->IsServicesOper()) source.Reply(_("You may not drop other Services Operators' nicknames.")); else { diff --git a/modules/commands/ns_getpass.cpp b/modules/commands/ns_getpass.cpp index aad6fb55b..a99181b3f 100644 --- a/modules/commands/ns_getpass.cpp +++ b/modules/commands/ns_getpass.cpp @@ -13,6 +13,8 @@ #include "module.h" +static ServiceReference<NickServService> nickserv("NickServService", "NickServ"); + class CommandNSGetPass : public Command { public: @@ -30,7 +32,7 @@ class CommandNSGetPass : public Command if (!(na = NickAlias::Find(nick))) source.Reply(NICK_X_NOT_REGISTERED, nick.c_str()); - else if (Config->NSSecureAdmins && na->nc->IsServicesOper()) + else if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && na->nc->IsServicesOper()) source.Reply(_("You may not get the password of other Services Operators.")); else { diff --git a/modules/commands/ns_group.cpp b/modules/commands/ns_group.cpp index 090b47fd4..cca6cd91c 100644 --- a/modules/commands/ns_group.cpp +++ b/modules/commands/ns_group.cpp @@ -13,6 +13,8 @@ #include "module.h" +static ServiceReference<NickServService> nickserv("NickServService", "NickServ"); + class NSGroupRequest : public IdentifyRequest { CommandSource source; @@ -46,7 +48,7 @@ class NSGroupRequest : public IdentifyRequest u->Login(target->nc); IRCD->SendLogin(u); - if (!Config->NoNicknameOwnership && na->nc == u->Account() && na->nc->HasExt("UNCONFIRMED") == false) + if (!Config->GetBlock("options")->Get<bool>("nonicknameownership") && na->nc == u->Account() && na->nc->HasExt("UNCONFIRMED") == false) u->SetMode(NickServ, "REGISTERED"); FOREACH_MOD(I_OnNickGroup, OnNickGroup(u, target)); @@ -102,7 +104,7 @@ class CommandNSGroup : public Command return; } - if (Config->RestrictOperNicks) + if (Config->GetBlock("nickserv")->Get<bool>("restrictopernicks")) for (unsigned i = 0; i < Config->Opers.size(); ++i) { Oper *o = Config->Opers[i]; @@ -115,10 +117,12 @@ class CommandNSGroup : public Command } NickAlias *target, *na = NickAlias::Find(u->nick); + const Anope::string &guestnick = Config->GetBlock("options")->Get<const Anope::string &>("guestnickprefix"); + time_t reg_delay = Config->GetModule("nickserv")->Get<time_t>("regdelay"); if (!(target = NickAlias::Find(nick))) source.Reply(NICK_X_NOT_REGISTERED, nick.c_str()); - else if (Anope::CurTime < u->lastnickreg + Config->NSRegDelay) - source.Reply(_("Please wait %d seconds before using the GROUP command again."), (Config->NSRegDelay + u->lastnickreg) - Anope::CurTime); + else if (Anope::CurTime < u->lastnickreg + reg_delay) + source.Reply(_("Please wait %d seconds before using the GROUP command again."), (reg_delay + u->lastnickreg) - Anope::CurTime); else if (target->nc->HasExt("SUSPENDED")) { Log(LOG_COMMAND, source, this) << "tried to use GROUP for SUSPENDED nick " << target->nick; @@ -127,14 +131,14 @@ class CommandNSGroup : public Command else if (na && *target->nc == *na->nc) source.Reply(_("You are already a member of the group of \002%s\002."), target->nick.c_str()); else if (na && na->nc != u->Account()) - source.Reply(NICK_IDENTIFY_REQUIRED, Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str()); - else if (na && Config->NSNoGroupChange) + source.Reply(NICK_IDENTIFY_REQUIRED, Config->StrictPrivmsg.c_str(), NickServ->nick.c_str()); + else if (na && Config->GetModule(this->owner)->Get<bool>("nogroupchange")) source.Reply(_("Your nick is already registered.")); - else if (Config->NSMaxAliases && (target->nc->aliases->size() >= Config->NSMaxAliases) && !target->nc->IsServicesOper()) - source.Reply(_("There are too many nicks in %s's group.")); - else if (u->nick.length() <= Config->NSGuestNickPrefix.length() + 7 && - u->nick.length() >= Config->NSGuestNickPrefix.length() + 1 && - !u->nick.find_ci(Config->NSGuestNickPrefix) && !u->nick.substr(Config->NSGuestNickPrefix.length()).find_first_not_of("1234567890")) + else if (target->nc->aliases->size() >= Config->GetModule(this->owner)->Get<unsigned>("maxaliases") && !target->nc->IsServicesOper()) + source.Reply(_("There are too many nicks in your group.")); + else if (u->nick.length() <= guestnick.length() + 7 && + u->nick.length() >= guestnick.length() + 1 && + !u->nick.find_ci(guestnick) && !u->nick.substr(guestnick.length()).find_first_not_of("1234567890")) { source.Reply(NICK_CANNOT_BE_REGISTERED, u->nick.c_str()); } @@ -289,7 +293,7 @@ class CommandNSGList : public Command } else if (na->nc != source.GetAccount() && !source.IsServicesOper()) { - source.Reply(ACCESS_DENIED, Config->NickServ.c_str()); + source.Reply(ACCESS_DENIED); return; } @@ -300,13 +304,14 @@ class CommandNSGList : public Command ListFormatter list; list.AddColumn("Nick").AddColumn("Expires"); + time_t nickserv_expire = Config->GetModule("nickserv")->Get<time_t>("expire"); for (unsigned i = 0; i < nc->aliases->size(); ++i) { const NickAlias *na2 = nc->aliases->at(i); ListFormatter::ListEntry entry; entry["Nick"] = na2->nick; - entry["Expires"] = (na2->HasExt("NO_EXPIRE") || !Config->NSExpire) ? "Does not expire" : ("expires in " + Anope::strftime(na2->last_seen + Config->NSExpire)); + entry["Expires"] = (na2->HasExt("NO_EXPIRE") || !nickserv_expire || Anope::NoExpire) ? "Does not expire" : ("expires in " + Anope::strftime(na2->last_seen + nickserv_expire)); list.AddEntry(entry); } @@ -351,8 +356,7 @@ class NSGroup : public Module NSGroup(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandnsgroup(this), commandnsungroup(this), commandnsglist(this) { - - if (Config->NoNicknameOwnership) + if (Config->GetBlock("options")->Get<bool>("nonicknameownership")) throw ModuleException(modname + " can not be used with options:nonicknameownership enabled"); } }; diff --git a/modules/commands/ns_info.cpp b/modules/commands/ns_info.cpp index 171937730..3e946a1f1 100644 --- a/modules/commands/ns_info.cpp +++ b/modules/commands/ns_info.cpp @@ -13,6 +13,8 @@ #include "module.h" +static ServiceReference<NickServService> nickserv("NickServService", "NickServ"); + class CommandNSInfo : public Command { private: @@ -126,13 +128,15 @@ class CommandNSInfo : public Command if (na->nc->HasExt("UNCONFIRMED") == false) { - if (na->HasExt("NO_EXPIRE") || !Config->NSExpire) - ; - else - info[_("Expires")] = Anope::strftime(na->last_seen + Config->NSExpire); + time_t nickserv_expire = Config->GetModule("nickserv")->Get<time_t>("expire"); + if (!na->HasExt("NO_EXPIRE") && nickserv_expire && !Anope::NoExpire) + info[_("Expires")] = Anope::strftime(na->last_seen + nickserv_expire); } else - info[_("Expires")] = Anope::strftime(na->time_registered + Config->NSUnconfirmedExpire); + { + time_t unconfirmed_expire = Config->GetModule("nickserv")->Get<time_t>("unconfirmedexpire", "1d"); + info[_("Expires")] = Anope::strftime(na->time_registered + unconfirmed_expire); + } } FOREACH_MOD(I_OnNickInfo, OnNickInfo(source, na, info, show_hidden)); diff --git a/modules/commands/ns_list.cpp b/modules/commands/ns_list.cpp index d1887f287..88d5929eb 100644 --- a/modules/commands/ns_list.cpp +++ b/modules/commands/ns_list.cpp @@ -31,6 +31,7 @@ class CommandNSList : public Command bool is_servadmin = source.HasCommand("nickserv/list"); int count = 0, from = 0, to = 0; bool suspended, nsnoexpire, unconfirmed; + unsigned listmax = Config->GetModule(this->owner)->Get<unsigned>("listmax"); suspended = nsnoexpire = unconfirmed = false; @@ -99,7 +100,7 @@ class CommandNSList : public Command Anope::string buf = Anope::printf("%s!%s", na->nick.c_str(), !na->last_usermask.empty() ? na->last_usermask.c_str() : "*@*"); if (na->nick.equals_ci(pattern) || Anope::Match(buf, pattern, false, true)) { - if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nnicks <= Config->NSListMax) + if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nnicks <= listmax) { bool isnoexpire = false; if (is_servadmin && na->HasExt("NO_EXPIRE")) @@ -129,7 +130,7 @@ class CommandNSList : public Command for (unsigned i = 0; i < replies.size(); ++i) source.Reply(replies[i]); - source.Reply(_("End of list - %d/%d matches shown."), nnicks > Config->NSListMax ? Config->NSListMax : nnicks, nnicks); + source.Reply(_("End of list - %d/%d matches shown."), nnicks > listmax ? listmax : nnicks, nnicks); return; } @@ -166,11 +167,12 @@ class CommandNSList : public Command " \002LIST #51-100\002\n" " Lists all registered nicks within the given range (51-100).")); - if (!Config->RegexEngine.empty()) + const Anope::string ®exengine = Config->GetBlock("options")->Get<const Anope::string &>("regexengine"); + if (!regexengine.empty()) { source.Reply(" "); source.Reply(_("Regex matches are also supported using the %s engine.\n" - "Enclose your pattern in // if this is desired."), Config->RegexEngine.c_str()); + "Enclose your pattern in // if this is desired."), regexengine.c_str()); } return true; @@ -185,7 +187,6 @@ class NSList : public Module NSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandnslist(this) { - } }; diff --git a/modules/commands/ns_recover.cpp b/modules/commands/ns_recover.cpp index 669d26da9..845c98915 100644 --- a/modules/commands/ns_recover.cpp +++ b/modules/commands/ns_recover.cpp @@ -13,6 +13,11 @@ #include "module.h" +namespace +{ + bool restoreonrecover; +} + struct NSRecoverExtensibleInfo : ExtensibleItem, std::map<Anope::string, ChannelStatus> { }; class NSRecoverRequest : public IdentifyRequest @@ -56,7 +61,7 @@ class NSRecoverRequest : public IdentifyRequest Log(LOG_COMMAND, source, cmd) << "and was automatically identified to " << u->Account()->display; } - if (Config->NSRestoreOnRecover) + if (restoreonrecover) { if (!u->chans.empty()) { @@ -205,7 +210,7 @@ class NSRecover : public Module commandnsrecover(this) { - if (Config->NoNicknameOwnership) + if (Config->GetBlock("options")->Get<bool>("nonicknameownership")) throw ModuleException(modname + " can not be used with options:nonicknameownership enabled"); Implementation i[] = { I_OnUserNickChange, I_OnJoinChannel, I_OnShutdown, I_OnRestart }; @@ -233,7 +238,7 @@ class NSRecover : public Module void OnUserNickChange(User *u, const Anope::string &oldnick) anope_override { - if (Config->NSRestoreOnRecover) + if (Config->GetModule(this)->Get<bool>("restoreonrecover")) { NSRecoverExtensibleInfo *ei = u->GetExt<NSRecoverExtensibleInfo *>("ns_recover_info"); @@ -255,7 +260,7 @@ class NSRecover : public Module void OnJoinChannel(User *u, Channel *c) anope_override { - if (Config->NSRestoreOnRecover) + if (Config->GetModule(this)->Get<bool>("restoreonrecover")) { NSRecoverExtensibleInfo *ei = u->GetExt<NSRecoverExtensibleInfo *>("ns_recover_info"); diff --git a/modules/commands/ns_register.cpp b/modules/commands/ns_register.cpp index 49e6a84d9..e0b8c77b5 100644 --- a/modules/commands/ns_register.cpp +++ b/modules/commands/ns_register.cpp @@ -13,6 +13,10 @@ #include "module.h" +namespace +{ + ServiceReference<NickServService> nickserv("NickServService", "NickServ"); +} static bool SendRegmail(User *u, const NickAlias *na, const BotInfo *bi); class CommandNSConfirm : public Command @@ -58,7 +62,7 @@ class CommandNSConfirm : public Command { IRCD->SendLogin(source.GetUser()); const NickAlias *na = NickAlias::Find(source.GetNick()); - if (!Config->NoNicknameOwnership && na != NULL && na->nc == source.GetAccount() && na->nc->HasExt("UNCONFIRMED") == false) + if (!Config->GetBlock("options")->Get<bool>("nonicknameownership") && na != NULL && na->nc == source.GetAccount() && na->nc->HasExt("UNCONFIRMED") == false) source.GetUser()->SetMode(NickServ, "REGISTERED"); } } @@ -101,7 +105,7 @@ class CommandNSRegister : public Command CommandNSRegister(Module *creator) : Command(creator, "nickserv/register", 1, 2) { this->SetDesc(_("Register a nickname")); - if (Config->NSForceEmail) + if (Config->GetModule("nickserv")->Get<bool>("forceemail", "yes")) this->SetSyntax(_("\037password\037 \037email\037")); else this->SetSyntax(_("\037password\037 \037[email]\037")); @@ -111,12 +115,12 @@ class CommandNSRegister : public Command void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { NickAlias *na; - size_t prefixlen = Config->NSGuestNickPrefix.length(); User *u = source.GetUser(); Anope::string u_nick = source.GetNick(); size_t nicklen = u_nick.length(); Anope::string pass = params[0]; Anope::string email = params.size() > 1 ? params[1] : ""; + const Anope::string &nsregister = Config->GetModule(this->owner)->Get<const Anope::string &>("registration"); if (Anope::ReadOnly) { @@ -124,15 +128,17 @@ class CommandNSRegister : public Command return; } - if (Config->NSRegistration.equals_ci("disable")) + if (nsregister.equals_ci("disable")) { source.Reply(_("Registration is currently disabled.")); return; } - if (u && !u->HasMode("OPER") && Config->NickRegDelay && Anope::CurTime - u->timestamp < Config->NickRegDelay) + time_t nickregdelay = Config->GetModule(this->owner)->Get<time_t>("nickregdelay"); + time_t reg_delay = Config->GetModule("nickserv")->Get<time_t>("regdelay"); + if (u && !u->HasMode("OPER") && nickregdelay && Anope::CurTime - u->timestamp < nickregdelay) { - source.Reply(_("You must have been using this nick for at least %d seconds to register."), Config->NickRegDelay); + source.Reply(_("You must have been using this nick for at least %d seconds to register."), nickregdelay); return; } @@ -141,7 +147,8 @@ class CommandNSRegister : public Command /* Guest nick can now have a series of between 1 and 7 digits. * --lara */ - if (nicklen <= prefixlen + 7 && nicklen >= prefixlen + 1 && !u_nick.find_ci(Config->NSGuestNickPrefix) && u_nick.substr(prefixlen).find_first_not_of("1234567890") == Anope::string::npos) + const Anope::string &guestnick = Config->GetBlock("options")->Get<const Anope::string &>("guestnickprefix"); + if (nicklen <= guestnick.length() + 7 && nicklen >= guestnick.length() + 1 && !u_nick.find_ci(guestnick) && u_nick.substr(guestnick.length()).find_first_not_of("1234567890") == Anope::string::npos) { source.Reply(NICK_CANNOT_BE_REGISTERED, u_nick.c_str()); return; @@ -153,7 +160,7 @@ class CommandNSRegister : public Command return; } - if (Config->RestrictOperNicks) + if (Config->GetBlock("nickserv")->Get<bool>("restrictopernicks")) for (unsigned i = 0; i < Config->Opers.size(); ++i) { Oper *o = Config->Opers[i]; @@ -165,15 +172,15 @@ class CommandNSRegister : public Command } } - if (Config->NSForceEmail && email.empty()) + if (Config->GetModule("nickserv")->Get<bool>("forceemail", "yes") && email.empty()) this->OnSyntaxError(source, ""); - else if (u && Anope::CurTime < u->lastnickreg + Config->NSRegDelay) - source.Reply(_("Please wait %d seconds before using the REGISTER command again."), (u->lastnickreg + Config->NSRegDelay) - Anope::CurTime); + else if (u && Anope::CurTime < u->lastnickreg + reg_delay) + source.Reply(_("Please wait %d seconds before using the REGISTER command again."), (u->lastnickreg + reg_delay) - Anope::CurTime); else if ((na = NickAlias::Find(u_nick))) source.Reply(NICK_ALREADY_REGISTERED, u_nick.c_str()); - else if (pass.equals_ci(u_nick) || (Config->StrictPasswords && pass.length() < 5)) + else if (pass.equals_ci(u_nick) || (Config->GetBlock("options")->Get<bool>("strictpasswords") && pass.length() < 5)) source.Reply(MORE_OBSCURE_PASSWORD); - else if (pass.length() > Config->PassLen) + else if (pass.length() > Config->GetBlock("options")->Get<unsigned>("passlen")) source.Reply(PASSWORD_TOO_LONG); else if (!email.empty() && !Mail::Validate(email)) source.Reply(MAIL_X_INVALID, email.c_str()); @@ -191,16 +198,13 @@ class CommandNSRegister : public Command na->last_realname = u->realname; u->Login(nc); - - if (Config->NSAddAccessOnReg) - nc->AddAccess(u->Mask()); } Log(LOG_COMMAND, source, this) << "to register " << na->nick << " (email: " << (!na->nc->email.empty() ? na->nc->email : "none") << ")"; - FOREACH_MOD(I_OnNickRegister, OnNickRegister(na)); + FOREACH_MOD(I_OnNickRegister, OnNickRegister(source.GetUser(), na)); - if (Config->NSAddAccessOnReg) + if (na->nc->GetAccessCount()) source.Reply(_("Nickname \002%s\002 registered under your user@host-mask: %s"), u_nick.c_str(), na->nc->GetAccess(0).c_str()); else source.Reply(_("Nickname \002%s\002 registered."), u_nick.c_str()); @@ -209,26 +213,27 @@ class CommandNSRegister : public Command if (Anope::Decrypt(na->nc->pass, tmp_pass) == 1) source.Reply(_("Your password is \002%s\002 - remember this for later use."), tmp_pass.c_str()); - if (Config->NSRegistration.equals_ci("admin")) + if (nsregister.equals_ci("admin")) { nc->ExtendMetadata("UNCONFIRMED"); source.Reply(_("All new accounts must be validated by an administrator. Please wait for your registration to be confirmed.")); } - else if (Config->NSRegistration.equals_ci("mail")) + else if (nsregister.equals_ci("mail")) { nc->ExtendMetadata("UNCONFIRMED"); if (SendRegmail(u, na, source.service)) { - source.Reply(_("A passcode has been sent to %s, please type \002%s%s CONFIRM <passcode>\002 to confirm your email address."), email.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str()); - source.Reply(_("If you do not confirm your email address within %s your account will expire."), Anope::Duration(Config->NSUnconfirmedExpire).c_str()); + time_t unconfirmed_expire = Config->GetModule("nickserv")->Get<time_t>("unconfirmedexpire", "1d"); + source.Reply(_("A passcode has been sent to %s, please type \002%s%s CONFIRM <passcode>\002 to confirm your email address."), email.c_str(), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str()); + source.Reply(_("If you do not confirm your email address within %s your account will expire."), Anope::Duration(unconfirmed_expire).c_str()); } } - else if (Config->NSRegistration.equals_ci("none")) + else if (nsregister.equals_ci("none")) { if (u) { IRCD->SendLogin(u); - if (!Config->NoNicknameOwnership && na->nc == u->Account() && na->nc->HasExt("UNCONFIRMED") == false) + if (!Config->GetBlock("options")->Get<bool>("nonicknameownership") && na->nc == u->Account() && na->nc->HasExt("UNCONFIRMED") == false) u->SetMode(NickServ, "REGISTERED"); } } @@ -259,9 +264,9 @@ class CommandNSRegister : public Command "passwords are vulnerable to trial-and-error searches, so\n" "you should choose a password at least 5 characters long.\n" "Finally, the space character cannot be used in passwords."), - Config->NickServ.c_str(), Config->NickServ.c_str()); + source.service->nick.c_str(), source.service->nick.c_str()); - if (!Config->NSForceEmail) + if (!Config->GetModule("nickserv")->Get<bool>("forceemail", "yes")) { source.Reply(" "); source.Reply(_("The \037email\037 parameter is optional and will set the email\n" @@ -289,7 +294,7 @@ class CommandNSResend : public Command void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (!Config->NSRegistration.equals_ci("mail")) + if (!Config->GetModule(this->owner)->Get<const Anope::string &>("registration").equals_ci("mail")) return; const NickAlias *na = NickAlias::Find(source.GetNick()); @@ -300,7 +305,7 @@ class CommandNSResend : public Command source.Reply(_("Your account is already confirmed.")); else { - if (Anope::CurTime < source.nc->lastmail + Config->NSResendDelay) + if (Anope::CurTime < source.nc->lastmail + Config->GetModule(this->owner)->Get<time_t>("resenddelay")) source.Reply(_("Cannot send mail now; please retry a little later.")); else if (SendRegmail(source.GetUser(), na, source.service)) { @@ -317,7 +322,7 @@ class CommandNSResend : public Command bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override { - if (!Config->NSRegistration.equals_ci("mail")) + if (!Config->GetModule(this->owner)->Get<const Anope::string &>("registration").equals_ci("mail")) return false; this->SendSyntax(source); @@ -329,7 +334,7 @@ class CommandNSResend : public Command void OnServHelp(CommandSource &source) anope_override { - if (Config->NSRegistration.equals_ci("mail")) + if (Config->GetModule(this->owner)->Get<const Anope::string &>("registration").equals_ci("mail")) Command::OnServHelp(source); } }; @@ -344,9 +349,8 @@ class NSRegister : public Module NSRegister(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandnsregister(this), commandnsconfirm(this), commandnsrsend(this) { - - if (Config->NSRegistration.equals_ci("disable")) - throw ModuleException("Module will not load with nickserv:registration disabled."); + if (Config->GetModule(this)->Get<const Anope::string &>("registration").equals_ci("disable")) + throw ModuleException("Module " + this->name + " will not load with registration disabled."); } }; @@ -373,15 +377,15 @@ static bool SendRegmail(User *u, const NickAlias *na, const BotInfo *bi) else codebuf = *code; - Anope::string subject = Language::Translate(na->nc, Config->MailRegistrationSubject.c_str()); - Anope::string message = Language::Translate(na->nc, Config->MailRegistrationMessage.c_str()); + Anope::string subject = Language::Translate(na->nc, Config->GetBlock("mail")->Get<const char *>("registration_subject")), + message = Language::Translate(na->nc, Config->GetBlock("mail")->Get<const char *>("registration_message")); subject = subject.replace_all_cs("%n", na->nick); - subject = subject.replace_all_cs("%N", Config->NetworkName); + subject = subject.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string &>("networkname")); subject = subject.replace_all_cs("%c", codebuf); message = message.replace_all_cs("%n", na->nick); - message = message.replace_all_cs("%N", Config->NetworkName); + message = message.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string &>("networkname")); message = message.replace_all_cs("%c", codebuf); return Mail::Send(u, nc, bi, subject, message); diff --git a/modules/commands/ns_resetpass.cpp b/modules/commands/ns_resetpass.cpp index 3ccb41ec1..f4516c5a6 100644 --- a/modules/commands/ns_resetpass.cpp +++ b/modules/commands/ns_resetpass.cpp @@ -29,7 +29,7 @@ class CommandNSResetPass : public Command { const NickAlias *na; - if (Config->RestrictMail && !source.HasCommand("nickserv/resetpass")) + if (Config->GetBlock("mail")->Get<bool>("restrict") && !source.HasCommand("nickserv/resetpass")) source.Reply(ACCESS_DENIED); else if (!(na = NickAlias::Find(params[0]))) source.Reply(NICK_X_NOT_REGISTERED, params[0].c_str()); @@ -69,8 +69,7 @@ class NSResetPass : public Module NSResetPass(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandnsresetpass(this) { - - if (!Config->UseMail) + if (!Config->GetBlock("mail")->Get<bool>("usemail")) throw ModuleException("Not using mail."); @@ -140,15 +139,15 @@ static bool SendResetEmail(User *u, const NickAlias *na, const BotInfo *bi) for (idx = 0; idx < 20; ++idx) passcode += chars[1 + static_cast<int>((static_cast<float>(max - min)) * static_cast<uint16_t>(rand()) / 65536.0) + min]; - Anope::string subject = Language::Translate(na->nc, Config->MailResetSubject.c_str()); - Anope::string message = Language::Translate(na->nc, Config->MailResetMessage.c_str()); + Anope::string subject = Language::Translate(na->nc, Config->GetBlock("mail")->Get<const char *>("reset_subject")), + message = Language::Translate(na->nc, Config->GetBlock("mail")->Get<const char *>("reset_message")); subject = subject.replace_all_cs("%n", na->nick); - subject = subject.replace_all_cs("%N", Config->NetworkName); + subject = subject.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string &>("networkname")); subject = subject.replace_all_cs("%c", passcode); message = message.replace_all_cs("%n", na->nick); - message = message.replace_all_cs("%N", Config->NetworkName); + message = message.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string &>("networkname")); message = message.replace_all_cs("%c", passcode); ResetInfo *ri = new ResetInfo; diff --git a/modules/commands/ns_set.cpp b/modules/commands/ns_set.cpp index 793b99fd1..fdc3aaac6 100644 --- a/modules/commands/ns_set.cpp +++ b/modules/commands/ns_set.cpp @@ -11,6 +11,8 @@ #include "module.h" +static ServiceReference<NickServService> nickserv("NickServService", "NickServ"); + class CommandNSSet : public Command { public: @@ -50,7 +52,7 @@ class CommandNSSet : public Command } source.Reply(_("Type \002%s%s HELP %s \037option\037\002 for more information\n" - "on a specific option."), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), this_name.c_str()); + "on a specific option."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), this_name.c_str()); return true; } @@ -96,7 +98,7 @@ class CommandNSSASet : public Command source.Reply(_("Type \002%s%s HELP %s \037option\037\002 for more information\n" "on a specific option. The options will be set on the given\n" - "\037nickname\037."), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str(), this_name.c_str()); + "\037nickname\037."), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str(), this_name.c_str()); return true; } }; @@ -115,12 +117,12 @@ class CommandNSSetPassword : public Command const Anope::string ¶m = params[1]; unsigned len = param.length(); - if (source.GetNick().equals_ci(param) || (Config->StrictPasswords && len < 5)) + if (source.GetNick().equals_ci(param) || (Config->GetBlock("options")->Get<bool>("strictpasswords") && len < 5)) { source.Reply(MORE_OBSCURE_PASSWORD); return; } - else if (len > Config->PassLen) + else if (len > Config->GetBlock("options")->Get<unsigned>("passlen")) { source.Reply(PASSWORD_TOO_LONG); return; @@ -167,17 +169,17 @@ class CommandNSSASetPassword : public Command size_t len = params[1].length(); - if (Config->NSSecureAdmins && source.nc != nc && nc->IsServicesOper()) + if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && source.nc != nc && nc->IsServicesOper()) { source.Reply(_("You may not change the password of other Services Operators.")); return; } - else if (nc->display.equals_ci(params[1]) || (Config->StrictPasswords && len < 5)) + else if (nc->display.equals_ci(params[1]) || (Config->GetBlock("options")->Get<bool>("strictpasswords") && len < 5)) { source.Reply(MORE_OBSCURE_PASSWORD); return; } - else if (len > Config->PassLen) + else if (len > Config->GetBlock("options")->Get<unsigned>("passlen")) { source.Reply(PASSWORD_TOO_LONG); return; @@ -378,7 +380,7 @@ class CommandNSSetDisplay : public Command { const NickAlias *user_na = NickAlias::Find(user), *na = NickAlias::Find(param); - if (Config->NoNicknameOwnership) + if (Config->GetBlock("options")->Get<bool>("nonicknameownership")) { source.Reply(_("This command may not be used on this network because nickname ownership is disabled.")); return; @@ -462,15 +464,15 @@ class CommandNSSetEmail : public Command u->Account()->Extend("ns_set_email_passcode", new ExtensibleItemClass<Anope::string>(code)); - Anope::string subject = Config->MailEmailchangeSubject; - Anope::string message = Config->MailEmailchangeMessage; + Anope::string subject = Config->GetBlock("mail")->Get<const char *>("emailchange_subject"), + message = Config->GetBlock("mail")->Get<const char *>("emailchange_message"); subject = subject.replace_all_cs("%e", u->Account()->email); - subject = subject.replace_all_cs("%N", Config->NetworkName); + subject = subject.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string &>("networkname")); subject = subject.replace_all_cs("%c", code); message = message.replace_all_cs("%e", u->Account()->email); - message = message.replace_all_cs("%N", Config->NetworkName); + message = message.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string &>("networkname")); message = message.replace_all_cs("%c", code); return Mail::Send(u, u->Account(), bi, subject, message); @@ -493,12 +495,12 @@ class CommandNSSetEmail : public Command } NickCore *nc = na->nc; - if (param.empty() && Config->NSForceEmail) + if (param.empty() && Config->GetModule("nickserv")->Get<bool>("forceemail", "yes")) { source.Reply(_("You cannot unset the e-mail on this network.")); return; } - else if (Config->NSSecureAdmins && source.nc != nc && nc->IsServicesOper()) + else if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && source.nc != nc && nc->IsServicesOper()) { source.Reply(_("You may not change the e-mail of other Services Operators.")); return; @@ -514,7 +516,7 @@ class CommandNSSetEmail : public Command if (MOD_RESULT == EVENT_STOP) return; - if (!param.empty() && Config->NSConfirmEmailChanges && !source.IsServicesOper()) + if (!param.empty() && Config->GetModule("nickserv")->Get<bool>("forceemail", "yes") && !source.IsServicesOper()) { source.nc->Extend("ns_set_email", new ExtensibleItemClass<Anope::string>(param)); Anope::string old = source.nc->email; @@ -722,13 +724,13 @@ class CommandNSSetHide : public Command { Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change hide " << param << " to " << arg << " for " << nc->display; nc->ExtendMetadata(flag); - source.Reply(onmsg.c_str(), nc->display.c_str(), Config->NickServ.c_str()); + source.Reply(onmsg.c_str(), nc->display.c_str(), NickServ->nick.c_str()); } else if (arg.equals_ci("OFF")) { Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change hide " << param << " to " << arg << " for " << nc->display; nc->Shrink(flag); - source.Reply(offmsg.c_str(), nc->display.c_str(), Config->NickServ.c_str()); + source.Reply(offmsg.c_str(), nc->display.c_str(), NickServ->nick.c_str()); } else this->OnSyntaxError(source, "HIDE"); @@ -751,7 +753,7 @@ class CommandNSSetHide : public Command "user@host mask (\002USERMASK\002), your services access status\n" "(\002STATUS\002) and last quit message (\002QUIT\002).\n" "The second parameter specifies whether the information should\n" - "be displayed (\002OFF\002) or hidden (\002ON\002)."), Config->NickServ.c_str()); + "be displayed (\002OFF\002) or hidden (\002ON\002)."), NickServ->nick.c_str()); return true; } }; @@ -780,7 +782,7 @@ class CommandNSSASetHide : public CommandNSSetHide "user@host mask (\002USERMASK\002), the services access status\n" "(\002STATUS\002) and last quit message (\002QUIT\002).\n" "The second parameter specifies whether the information should\n" - "be displayed (\002OFF\002) or hidden (\002ON\002)."), Config->NickServ.c_str()); + "be displayed (\002OFF\002) or hidden (\002ON\002)."), NickServ->nick.c_str()); return true; } }; @@ -796,7 +798,7 @@ class CommandNSSetKill : public Command void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m) { - if (Config->NoNicknameOwnership) + if (Config->GetBlock("options")->Get<bool>("nonicknameownership")) { source.Reply(_("This command may not be used on this network because nickname ownership is disabled.")); return; @@ -833,7 +835,7 @@ class CommandNSSetKill : public Command } else if (param.equals_ci("IMMED")) { - if (Config->NSAllowKillImmed) + if (Config->GetModule(this->owner)->Get<bool>("allowkillimmed")) { nc->ExtendMetadata("KILLPROTECT"); nc->ExtendMetadata("KILL_IMMED"); @@ -878,7 +880,7 @@ class CommandNSSetKill : public Command "\002IMMED\002, user's nick will be changed immediately \037without\037 being\n" "warned first or given a chance to change their nick; please\n" "do not use this option unless necessary. Also, your\n" - "network's administrators may have disabled this option."), Config->NickServ.c_str()); + "network's administrators may have disabled this option."), NickServ->nick.c_str()); return true; } }; @@ -912,7 +914,7 @@ class CommandNSSASetKill : public CommandNSSetKill "\002IMMED\002, the user's nick will be changed immediately \037without\037 being\n" "warned first or given a chance to change their nick; please\n" "do not use this option unless necessary. Also, your\n" - "network's administrators may have disabled this option."), Config->NickServ.c_str()); + "network's administrators may have disabled this option."), NickServ->nick.c_str()); return true; } }; @@ -956,8 +958,6 @@ class CommandNSSetLanguage : public Command nc->language = param != "en" ? param : ""; source.Reply(_("Language changed to \002English\002.")); - - return; } void Execute(CommandSource &source, const std::vector<Anope::string> ¶m) anope_override @@ -1040,7 +1040,7 @@ class CommandNSSetMessage : public Command } NickCore *nc = na->nc; - if (!Config->UsePrivmsg) + if (!Config->GetBlock("options")->Get<bool>("useprivmsg")) { source.Reply(_("You cannot %s on this network."), source.command.c_str()); return; @@ -1086,7 +1086,7 @@ class CommandNSSetMessage : public Command void OnServHelp(CommandSource &source) anope_override { - if (Config->UsePrivmsg) + if (!Config->GetBlock("options")->Get<bool>("useprivmsg")) Command::OnServHelp(source); } }; @@ -1121,7 +1121,7 @@ class CommandNSSetPrivate : public Command public: CommandNSSetPrivate(Module *creator, const Anope::string &sname = "nickserv/set/private", size_t min = 1) : Command(creator, sname, min, min + 1) { - this->SetDesc(Anope::printf(_("Prevent the nickname from appearing in a \002%s%s LIST\002"), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str())); + this->SetDesc(_("Prevent the nickname from appearing in the LIST command")); this->SetSyntax(_("{ON | OFF}")); } @@ -1172,7 +1172,7 @@ class CommandNSSetPrivate : public Command "nickname lists generated with %s's \002LIST\002 command.\n" "(However, anyone who knows your nickname can still get\n" "information on it using the \002INFO\002 command.)"), - Config->NickServ.c_str(), Config->NickServ.c_str()); + NickServ->nick.c_str(), NickServ->nick.c_str()); return true; } }; @@ -1200,7 +1200,7 @@ class CommandNSSASetPrivate : public CommandNSSetPrivate "nickname lists generated with %s's \002LIST\002 command.\n" "(However, anyone who knows the nickname can still get\n" "information on it using the \002INFO\002 command.)"), - Config->NickServ.c_str(), Config->NickServ.c_str()); + NickServ->nick.c_str(), NickServ->nick.c_str()); return true; } }; @@ -1260,7 +1260,7 @@ class CommandNSSetSecure : public Command "regardless of whether your address is on the access\n" "list. However, if you are on the access list, %s\n" "will not auto-kill you regardless of the setting of the\n" - "\002KILL\002 option."), Config->NickServ.c_str(), Config->NickServ.c_str()); + "\002KILL\002 option."), NickServ->nick.c_str(), NickServ->nick.c_str()); return true; } }; @@ -1289,7 +1289,7 @@ class CommandNSSASetSecure : public CommandNSSetSecure "regardless of whether your address is on the access\n" "list. However, if you are on the access list, %s\n" "will not auto-kill you regardless of the setting of the\n" - "\002KILL\002 option."), Config->NickServ.c_str(), Config->NickServ.c_str()); + "\002KILL\002 option."), NickServ->nick.c_str(), NickServ->nick.c_str()); return true; } }; @@ -1402,21 +1402,10 @@ class NSSet : public Module commandnssasetnoexpire(this) { - Implementation i[] = { I_OnReload, I_OnNickRegister, I_OnPreCommand }; + Implementation i[] = { I_OnPreCommand }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override - { - NSDefChanstats = reader.ReadFlag("chanstats", "NSDefChanstats", "0", 0); - } - - void OnNickRegister(NickAlias *na) anope_override - { - if (NSDefChanstats) - na->nc->ExtendMetadata("STATS"); - } - EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> ¶ms) anope_override { NickCore *uac = source.nc; diff --git a/modules/commands/ns_set_misc.cpp b/modules/commands/ns_set_misc.cpp index 5ee77a938..871a1191f 100644 --- a/modules/commands/ns_set_misc.cpp +++ b/modules/commands/ns_set_misc.cpp @@ -161,17 +161,21 @@ class NSSetMisc : public Module ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override + void OnReload(Configuration::Conf *conf) anope_override { descriptions.clear(); - for (int i = 0; i < reader.Enumerate("command"); ++i) + for (int i = 0; i < conf->CountBlock("command"); ++i) { - if (reader.ReadValue("command", "command", "", i) != "nickserv/set/misc" && reader.ReadValue("command", "command", "", i) != "nickserv/saset/misc") + Configuration::Block *block = conf->GetBlock("command", i); + + const Anope::string &cmd = block->Get<const Anope::string &>("command"); + + if (cmd != "nickserv/set/misc" && cmd != "nickserv/saset/misc") continue; - Anope::string cname = reader.ReadValue("command", "name", "", i); - Anope::string desc = reader.ReadValue("command", "misc_description", "", i); + Anope::string cname = block->Get<const Anope::string &>("name"); + Anope::string desc = block->Get<const Anope::string &>("misc_description"); if (cname.empty() || desc.empty()) continue; diff --git a/modules/commands/ns_suspend.cpp b/modules/commands/ns_suspend.cpp index dabd47a7e..e0bb6bf93 100644 --- a/modules/commands/ns_suspend.cpp +++ b/modules/commands/ns_suspend.cpp @@ -13,6 +13,8 @@ #include "module.h" +static ServiceReference<NickServService> nickserv("NickServService", "NickServ"); + class CommandNSSuspend : public Command { public: @@ -28,7 +30,7 @@ class CommandNSSuspend : public Command const Anope::string &nick = params[0]; Anope::string expiry = params[1]; Anope::string reason = params.size() > 2 ? params[2] : ""; - time_t expiry_secs = Config->NSSuspendExpire; + time_t expiry_secs = Config->GetModule(this->owner)->Get<time_t>("suspendexpire"); if (Anope::ReadOnly) { @@ -52,7 +54,7 @@ class CommandNSSuspend : public Command return; } - if (Config->NSSecureAdmins && na->nc->IsServicesOper()) + if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && na->nc->IsServicesOper()) { source.Reply(_("You may not suspend other Services Operators' nicknames.")); return; @@ -173,7 +175,6 @@ class NSSuspend : public Module NSSuspend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandnssuspend(this), commandnsunsuspend(this) { - Implementation i[] = { I_OnPreNickExpire }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } diff --git a/modules/commands/ns_update.cpp b/modules/commands/ns_update.cpp index 115d4f2b9..ee8a2c8cb 100644 --- a/modules/commands/ns_update.cpp +++ b/modules/commands/ns_update.cpp @@ -35,7 +35,7 @@ class CommandNSUpdate : public Command FOREACH_MOD(I_OnNickUpdate, OnNickUpdate(u)); - source.Reply(_("Status updated (memos, vhost, chmodes, flags)."), Config->NickServ.c_str()); + source.Reply(_("Status updated (memos, vhost, chmodes, flags).")); } bool OnHelp(CommandSource &source, const Anope::string &) anope_override diff --git a/modules/commands/os_akill.cpp b/modules/commands/os_akill.cpp index 47121c51f..c90dd096f 100644 --- a/modules/commands/os_akill.cpp +++ b/modules/commands/os_akill.cpp @@ -76,7 +76,7 @@ class CommandOSAKill : public Command sep.GetToken(mask); } - time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->AutokillExpiry; + time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->GetModule("operserv")->Get<time_t>("autokillexpiry", "30d"); /* If the expiry given does not contain a final letter, it's in days, * said the doc. Ah well. */ @@ -121,16 +121,18 @@ class CommandOSAKill : public Command if (mask[0] == '/' && mask[mask.length() - 1] == '/') { - if (Config->RegexEngine.empty()) + const Anope::string ®exengine = Config->GetBlock("options")->Get<const Anope::string &>("regexengine"); + + if (regexengine.empty()) { - source.Reply(_("Regex is enabled.")); + source.Reply(_("Regex is disabled.")); return; } - ServiceReference<RegexProvider> provider("Regex", Config->RegexEngine); + ServiceReference<RegexProvider> provider("Regex", regexengine); if (!provider) { - source.Reply(_("Unable to find regex engine %s."), Config->RegexEngine.c_str()); + source.Reply(_("Unable to find regex engine %s."), regexengine.c_str()); return; } @@ -158,8 +160,11 @@ class CommandOSAKill : public Command return; } + if (Config->GetModule("operserv")->Get<bool>("addakiller", "yes") && !source.GetNick().empty()) + reason = "[" + source.GetNick() + "] " + reason; + XLine *x = new XLine(mask, source.GetNick(), expires, reason); - if (Config->AkillIds) + if (Config->GetBlock("operserv")->Get<bool>("akilids")) x->id = XLineManager::GenerateUID(); unsigned int affected = 0; @@ -185,7 +190,7 @@ class CommandOSAKill : public Command } akills->AddXLine(x); - if (Config->AkillOnAdd) + if (Config->GetModule("operserv")->Get<bool>("akillonadd")) akills->Send(NULL, x); source.Reply(_("\002%s\002 added to the AKILL list."), mask.c_str()); @@ -414,11 +419,12 @@ class CommandOSAKill : public Command "be given, even if it is the same as the default. The\n" "current AKILL default expiry time can be found with the\n" "\002STATS AKILL\002 command.")); - if (!Config->RegexEngine.empty()) + const Anope::string ®exengine = Config->GetBlock("options")->Get<const Anope::string &>("regexengine"); + if (!regexengine.empty()) { source.Reply(" "); source.Reply(_("Regex matches are also supported using the %s engine.\n" - "Enclose your mask in // if this is desired."), Config->RegexEngine.c_str()); + "Enclose your mask in // if this is desired."), regexengine.c_str()); } source.Reply(_( " \n" diff --git a/modules/commands/os_chankill.cpp b/modules/commands/os_chankill.cpp index 8253742a6..713b5922f 100644 --- a/modules/commands/os_chankill.cpp +++ b/modules/commands/os_chankill.cpp @@ -30,7 +30,6 @@ class CommandOSChanKill : public Command return; Anope::string expiry, channel; - time_t expires; unsigned last_param = 1; Channel *c; @@ -42,7 +41,7 @@ class CommandOSChanKill : public Command last_param = 2; } - expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->ChankillExpiry; + time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->GetModule("operserv")->Get<time_t>("autokillexpiry", "30d"); if (!expiry.empty() && isdigit(expiry[expiry.length() - 1])) expires *= 86400; if (expires && expires < 60) @@ -65,7 +64,7 @@ class CommandOSChanKill : public Command if (!reason.empty()) { Anope::string realreason; - if (Config->AddAkiller) + if (Config->GetBlock("operserv")->Get<bool>("addakiller") && !source.GetNick().empty()) realreason = "[" + source.GetNick() + "] " + reason; else realreason = reason; diff --git a/modules/commands/os_config.cpp b/modules/commands/os_config.cpp index 0517f28d7..391d36157 100644 --- a/modules/commands/os_config.cpp +++ b/modules/commands/os_config.cpp @@ -15,22 +15,6 @@ class CommandOSConfig : public Command { - void ChangeHash(ConfigDataHash &hash, const Anope::string &block, const Anope::string &iname, const Anope::string &value) - { - ConfigDataHash::iterator it = hash.find(block); - - KeyValList &list = it->second; - for (unsigned i = 0; i < list.size(); ++i) - { - const Anope::string &item = list[i].first; - if (item == iname) - { - list[i] = std::make_pair(item, value); - break; - } - } - } - public: CommandOSConfig(Module *creator) : Command(creator, "operserv/config", 1, 4) { @@ -44,110 +28,17 @@ class CommandOSConfig : public Command if (what.equals_ci("MODIFY") && params.size() > 3) { - ConfigItems configitems(Config); - - for (unsigned i = 0; !configitems.Values[i].tag.empty(); ++i) + Configuration::Block *block = Config->GetBlock(params[1]); + if (!block) { - ConfigItems::Item *v = &configitems.Values[i]; - if (v->tag.equals_cs(params[1]) && v->value.equals_cs(params[2])) - { - try - { - ValueItem vi(params[3]); - if (!v->validation_function(Config, v->tag, v->value, vi)) - throw ConfigException("Parameter failed to validate."); - - int dt = v->datatype; - - if (dt & DT_NORELOAD) - throw ConfigException("This item can not be changed while Anope is running."); - bool allow_wild = dt & DT_ALLOW_WILD; - dt &= ~(DT_ALLOW_NEWLINE | DT_ALLOW_WILD); - - /* Yay for *massive* copypaste from reader.cpp */ - switch (dt) - { - case DT_NOSPACES: - { - ValueContainerString *vcs = anope_dynamic_static_cast<ValueContainerString *>(v->val); - Config->ValidateNoSpaces(vi.GetValue(), v->tag, v->value); - vcs->Set(vi.GetValue()); - break; - } - case DT_HOSTNAME: - { - ValueContainerString *vcs = anope_dynamic_static_cast<ValueContainerString *>(v->val); - Config->ValidateHostname(vi.GetValue(), v->tag, v->value); - vcs->Set(vi.GetValue()); - break; - } - case DT_IPADDRESS: - { - ValueContainerString *vcs = anope_dynamic_static_cast<ValueContainerString *>(v->val); - Config->ValidateIP(vi.GetValue(), v->tag, v->value, allow_wild); - vcs->Set(vi.GetValue()); - break; - } - case DT_STRING: - { - ValueContainerString *vcs = anope_dynamic_static_cast<ValueContainerString *>(v->val); - vcs->Set(vi.GetValue()); - break; - } - case DT_INTEGER: - { - int val = vi.GetInteger(); - ValueContainerInt *vci = anope_dynamic_static_cast<ValueContainerInt *>(v->val); - vci->Set(&val, sizeof(int)); - break; - } - case DT_UINTEGER: - { - unsigned val = vi.GetInteger(); - ValueContainerUInt *vci = anope_dynamic_static_cast<ValueContainerUInt *>(v->val); - vci->Set(&val, sizeof(unsigned)); - break; - } - case DT_LUINTEGER: - { - unsigned long val = vi.GetInteger(); - ValueContainerLUInt *vci = anope_dynamic_static_cast<ValueContainerLUInt *>(v->val); - vci->Set(&val, sizeof(unsigned long)); - break; - } - case DT_TIME: - { - time_t time = Anope::DoTime(vi.GetValue()); - ValueContainerTime *vci = anope_dynamic_static_cast<ValueContainerTime *>(v->val); - vci->Set(&time, sizeof(time_t)); - break; - } - case DT_BOOLEAN: - { - bool val = vi.GetBool(); - ValueContainerBool *vcb = anope_dynamic_static_cast<ValueContainerBool *>(v->val); - vcb->Set(&val, sizeof(bool)); - break; - } - default: - break; - } - } - catch (const ConfigException &ex) - { - source.Reply(_("Error changing configuration value: ") + ex.GetReason()); - return; - } - - ChangeHash(Config->config_data, params[1], params[2], params[3]); - - Log(LOG_ADMIN, source, this) << "to change the configuration value of " << params[1] << ":" << params[2] << " to " << params[3]; - source.Reply(_("Value of %s:%s changed to %s"), params[1].c_str(), params[2].c_str(), params[3].c_str()); - return; - } + source.Reply(_("There is no such configuration block %s."), params[1].c_str()); + return; } - source.Reply("There is no configuration value named %s:%s", params[1].c_str(), params[2].c_str()); + block->Set(params[2], params[3]); + + Log(LOG_ADMIN, source, this) << "to change the configuration value of " << params[1] << ":" << params[2] << " to " << params[3]; + source.Reply(_("Value of %s:%s changed to %s"), params[1].c_str(), params[2].c_str(), params[3].c_str()); } else if (what.equals_ci("VIEW")) { @@ -155,35 +46,30 @@ class CommandOSConfig : public Command const Anope::string show_blocks[] = { "botserv", "chanserv", "defcon", "global", "memoserv", "nickserv", "networkinfo", "operserv", "options", "" }; Log(LOG_ADMIN, source, this) << "VIEW"; - - for (ConfigDataHash::const_iterator it = Config->config_data.begin(), it_end = Config->config_data.end(); it != it_end; ++it) + + for (unsigned i = 0; !show_blocks[i].empty(); ++i) { - const Anope::string &bname = it->first; - const KeyValList &list = it->second; - - bool ok = false; - for (unsigned i = 0; !show_blocks[i].empty(); ++i) - if (bname == show_blocks[i]) - ok = true; - if (ok == false) + Configuration::Block *block = Config->GetBlock(show_blocks[i]); + const Configuration::Block::item_map *items = block->GetItems(); + + if (!items) continue; ListFormatter lflist; lflist.AddColumn("Name").AddColumn("Value"); - for (unsigned i = 0; i < list.size(); ++i) - { - const Anope::string &first = list[i].first, second = list[i].second; + for (Configuration::Block::item_map::const_iterator it = items->begin(), it_end = items->end(); it != it_end; ++it) + { ListFormatter::ListEntry entry; - entry["Name"] = first; - entry["Value"] = second; + entry["Name"] = it->first; + entry["Value"] = it->second; lflist.AddEntry(entry); } std::vector<Anope::string> replies; lflist.Process(replies); - source.Reply(_("%s settings:"), bname.c_str()); + source.Reply(_("%s settings:"), block->GetName().c_str()); for (unsigned i = 0; i < replies.size(); ++i) source.Reply(replies[i]); @@ -193,8 +79,6 @@ class CommandOSConfig : public Command } else this->OnSyntaxError(source, what); - - return; } bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override diff --git a/modules/commands/os_defcon.cpp b/modules/commands/os_defcon.cpp index dd45856fb..0fd3a1700 100644 --- a/modules/commands/os_defcon.cpp +++ b/modules/commands/os_defcon.cpp @@ -43,6 +43,10 @@ struct DefconConfig time_t akillexpire, timeout; bool globalondefcon; + unsigned max_session_kill; + time_t session_autokill_expiry; + Anope::string sle_reason, sle_detailsloc; + DefconConfig() { this->DefCon.resize(6); @@ -336,23 +340,32 @@ class OSDefcon : public Module ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override + void OnReload(Configuration::Conf *conf) anope_override { + Configuration::Block *block = conf->GetModule(this); DefconConfig dconfig; - dconfig.defaultlevel = reader.ReadInteger("defcon", "defaultlevel", 0, 0); - dconfig.defcons[4] = reader.ReadValue("defcon", "level4", 0); - dconfig.defcons[3] = reader.ReadValue("defcon", "level3", 0); - dconfig.defcons[2] = reader.ReadValue("defcon", "level2", 0); - dconfig.defcons[1] = reader.ReadValue("defcon", "level1", 0); - dconfig.sessionlimit = reader.ReadInteger("defcon", "sessionlimit", 0, 0); - dconfig.akillreason = reader.ReadValue("defcon", "akillreason", 0); - dconfig.akillexpire = Anope::DoTime(reader.ReadValue("defcon", "akillexpire", 0)); - dconfig.chanmodes = reader.ReadValue("defcon", "chanmodes", 0); - dconfig.timeout = Anope::DoTime(reader.ReadValue("defcon", "timeout", 0)); - dconfig.globalondefcon = reader.ReadFlag("defcon", "globalondefcon", 0); - dconfig.message = reader.ReadValue("defcon", "message", 0); - dconfig.offmessage = reader.ReadValue("defcon", "offmessage", 0); + dconfig.defaultlevel = block->Get<int>("defaultlevel"); + dconfig.defcons[4] = block->Get<const Anope::string &>("level4"); + dconfig.defcons[3] = block->Get<const Anope::string &>("level3"); + dconfig.defcons[2] = block->Get<const Anope::string &>("level2"); + dconfig.defcons[1] = block->Get<const Anope::string &>("level1"); + dconfig.sessionlimit = block->Get<int>("sessionlimit"); + dconfig.akillreason = block->Get<const Anope::string &>("akillreason"); + dconfig.akillexpire = block->Get<time_t>("akillexpire"); + dconfig.chanmodes = block->Get<const Anope::string &>("chanmodes"); + dconfig.timeout = block->Get<time_t>("timeout"); + dconfig.globalondefcon = block->Get<bool>("globalondefcon"); + dconfig.message = block->Get<const Anope::string &>("message"); + dconfig.offmessage = block->Get<const Anope::string &>("offmessage"); + + Module *session = ModuleManager::FindModule("os_session"); + block = conf->GetModule(session); + + dconfig.max_session_kill = block->Get<int>("maxsessionkill"); + dconfig.session_autokill_expiry = block->Get<time_t>("sessionautokillexpiry"); + dconfig.sle_reason = block->Get<const Anope::string &>("sessionlimitexceeded"); + dconfig.sle_detailsloc = block->Get<const Anope::string &>("sessionlimitdetailsloc"); if (dconfig.defaultlevel < 1 || dconfig.defaultlevel > 5) throw ConfigException("The value for <defcon:defaultlevel> must be between 1 and 5"); @@ -479,19 +492,18 @@ class OSDefcon : public Module if (DConfig.Check(DEFCON_AKILL_NEW_CLIENTS) && akills) { Log(OperServ, "operserv/defcon") << "DEFCON: adding akill for *@" << u->host; - XLine x("*@" + u->host, Config->OperServ, Anope::CurTime + DConfig.akillexpire, DConfig.akillreason, XLineManager::GenerateUID()); - x.by = Config->OperServ; + XLine x("*@" + u->host, OperServ ? OperServ->nick : "defcon", Anope::CurTime + DConfig.akillexpire, DConfig.akillreason, XLineManager::GenerateUID()); akills->Send(NULL, &x); } if (DConfig.Check(DEFCON_NO_NEW_CLIENTS) || DConfig.Check(DEFCON_AKILL_NEW_CLIENTS)) { - u->Kill(Config->OperServ, DConfig.akillreason); + u->Kill(OperServ ? OperServ->nick : "", DConfig.akillreason); return; } if (DConfig.Check(DEFCON_NO_NEW_CLIENTS) || DConfig.Check(DEFCON_AKILL_NEW_CLIENTS)) { - u->Kill(Config->OperServ, DConfig.akillreason); + u->Kill(OperServ ? OperServ->nick : "", DConfig.akillreason); return; } @@ -513,22 +525,24 @@ class OSDefcon : public Module { if (session && session->count > static_cast<unsigned>(DConfig.sessionlimit)) { - if (!Config->SessionLimitExceeded.empty()) - IRCD->SendMessage(OperServ, u->nick, Config->SessionLimitExceeded.c_str(), u->host.c_str()); - if (!Config->SessionLimitDetailsLoc.empty()) - IRCD->SendMessage(OperServ, u->nick, "%s", Config->SessionLimitDetailsLoc.c_str()); + if (!DConfig.sle_reason.empty()) + { + Anope::string message = DConfig.sle_reason.replace_all_cs("%IP%", u->ip); + u->SendMessage(OperServ, message); + } + if (!DConfig.sle_detailsloc.empty()) + u->SendMessage(OperServ, DConfig.sle_detailsloc); ++session->hits; - if (akills && Config->MaxSessionKill && session->hits >= Config->MaxSessionKill) + if (akills && DConfig.max_session_kill && session->hits >= DConfig.max_session_kill) { - XLine x("*@" + u->host, Config->OperServ, Anope::CurTime + Config->SessionAutoKillExpiry, "Defcon session limit exceeded", XLineManager::GenerateUID()); + XLine x("*@" + u->host, OperServ ? OperServ->nick : "", Anope::CurTime + DConfig.session_autokill_expiry, "Defcon session limit exceeded", XLineManager::GenerateUID()); akills->Send(NULL, &x); Log(OperServ, "akill/defcon") << "[DEFCON] Added a temporary AKILL for \002*@" << u->host << "\002 due to excessive connections"; } else { - u->Kill(Config->OperServ, "Defcon session limit exceeded"); - u = NULL; /* No guarentee u still exists */ + u->Kill(OperServ ? OperServ->nick : "", "Defcon session limit exceeded"); } } } diff --git a/modules/commands/os_dns.cpp b/modules/commands/os_dns.cpp index 346ff4727..9d1a12eb6 100644 --- a/modules/commands/os_dns.cpp +++ b/modules/commands/os_dns.cpp @@ -686,15 +686,15 @@ class ModuleDNS : public Module delete dns_servers->at(i - 1); } - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override - { - - this->ttl = Anope::DoTime(reader.ReadValue("os_dns", "ttl", 0)); - this->user_drop_mark = reader.ReadInteger("os_dns", "user_drop_mark", 0, false); - this->user_drop_time = Anope::DoTime(reader.ReadValue("os_dns", "user_drop_time", 0, false)); - this->user_drop_readd_time = Anope::DoTime(reader.ReadValue("os_dns", "user_drop_readd_time", 0, false)); - this->remove_split_servers = reader.ReadFlag("os_dns", "remove_split_servers", 0); - this->readd_connected_servers = reader.ReadFlag("os_dns", "readd_connected_servers", 0); + void OnReload(Configuration::Conf *conf) anope_override + { + Configuration::Block *block = conf->GetModule(this); + this->ttl = block->Get<time_t>("ttl"); + this->user_drop_mark = block->Get<int>("user_drop_mark"); + this->user_drop_time = block->Get<time_t>("user_drop_time"); + this->user_drop_readd_time = block->Get<time_t>("user_drop_readd_time"); + this->remove_split_servers = block->Get<bool>("remove_split_servers"); + this->readd_connected_servers = block->Get<bool>("readd_connected_servers"); } void OnNewServer(Server *s) anope_override diff --git a/modules/commands/os_forbid.cpp b/modules/commands/os_forbid.cpp index 2144aa591..1d99d47b4 100644 --- a/modules/commands/os_forbid.cpp +++ b/modules/commands/os_forbid.cpp @@ -14,6 +14,8 @@ #include "module.h" #include "os_forbid.h" +static ServiceReference<NickServService> nickserv("NickServService", "NickServ"); + class MyForbidService : public ForbidService { Serialize::Checker<std::vector<ForbidData *>[FT_SIZE - 1]> forbid_data; @@ -121,12 +123,6 @@ class CommandOSForbid : public Command time_t expiryt = 0; - if (Config->ForceForbidReason && reason.empty()) - { - this->OnSyntaxError(source, ""); - return; - } - if (!expiry.empty()) { expiryt = Anope::DoTime(expiry); @@ -135,7 +131,7 @@ class CommandOSForbid : public Command } NickAlias *target = NickAlias::Find(entry); - if (target != NULL && Config->NSSecureAdmins && target->nc->IsServicesOper()) + if (target != NULL && Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && target->nc->IsServicesOper()) { source.Reply(ACCESS_DENIED); return; @@ -234,11 +230,12 @@ class CommandOSForbid : public Command source.Reply(_("Forbid allows you to forbid usage of certain nicknames, channels,\n" "and email addresses. Wildcards are accepted for all entries.")); - if (!Config->RegexEngine.empty()) + const Anope::string ®exengine = Config->GetBlock("options")->Get<const Anope::string &>("regexengine"); + if (!regexengine.empty()) { source.Reply(" "); source.Reply(_("Regex matches are also supported using the %s engine.\n" - "Enclose your pattern in // if this is desired."), Config->RegexEngine.c_str()); + "Enclose your pattern in // if this is desired."), regexengine.c_str()); } return true; @@ -295,21 +292,19 @@ class OSForbid : public Module ForbidData *d = this->forbidService.FindForbid(c->name, FT_CHAN); if (d != NULL) { - if (IRCD->CanSQLineChannel) + ServiceReference<ChanServService> chanserv("ChanServService", "ChanServ"); + if (!chanserv) + ; + else if (IRCD->CanSQLineChannel) { - XLine x(c->name, OperServ->nick, Anope::CurTime + Config->CSInhabit, d->reason); + time_t inhabit = Config->GetModule("chanserv")->Get<time_t>("inhabit", "15s"); + XLine x(c->name, OperServ->nick, Anope::CurTime + inhabit, d->reason); IRCD->SendSQLine(NULL, &x); } - else if (!c->HasExt("INHABIT")) + else { - /* Join ChanServ and set a timer for this channel to part ChanServ later */ - c->Hold(); - - /* Set +si to prevent rejoin */ - c->SetMode(NULL, "NOEXTERNAL"); - c->SetMode(NULL, "TOPIC"); - c->SetMode(NULL, "SECRET"); - c->SetMode(NULL, "INVITE"); + if (chanserv) + chanserv->Hold(c); } if (d->reason.empty()) diff --git a/modules/commands/os_ignore.cpp b/modules/commands/os_ignore.cpp index 1b7ae61c5..073101066 100644 --- a/modules/commands/os_ignore.cpp +++ b/modules/commands/os_ignore.cpp @@ -299,11 +299,12 @@ class CommandOSIgnore : public Command " \n" "Ignores will not be enforced on IRC Operators.")); - if (!Config->RegexEngine.empty()) + const Anope::string ®exengine = Config->GetBlock("options")->Get<const Anope::string &>("regexengine"); + if (!regexengine.empty()) { source.Reply(" "); source.Reply(_("Regex matches are also supported using the %s engine.\n" - "Enclose your pattern in // if this is desired."), Config->RegexEngine.c_str()); + "Enclose your pattern in // if this is desired."), regexengine.c_str()); } return true; diff --git a/modules/commands/os_kill.cpp b/modules/commands/os_kill.cpp index d3eeedda5..99a65ae4b 100644 --- a/modules/commands/os_kill.cpp +++ b/modules/commands/os_kill.cpp @@ -36,10 +36,10 @@ class CommandOSKill : public Command { if (reason.empty()) reason = "No reason specified"; - if (Config->AddAkiller) + if (Config->GetBlock("operserv")->Get<bool>("addakiller")) reason = "(" + source.GetNick() + ") " + reason; Log(LOG_ADMIN, source, this) << "on " << u2->nick << " for " << reason; - u2->Kill(Config->OperServ, reason); + u2->Kill(source.service->nick, reason); } } diff --git a/modules/commands/os_list.cpp b/modules/commands/os_list.cpp index e8092cb4d..6692f52fd 100644 --- a/modules/commands/os_list.cpp +++ b/modules/commands/os_list.cpp @@ -103,11 +103,12 @@ class CommandOSChanList : public Command "specified, lists only channels matching \002pattern\002 that have the +s or\n" "+p mode.")); - if (!Config->RegexEngine.empty()) + const Anope::string ®exengine = Config->GetBlock("options")->Get<const Anope::string &>("regexengine"); + if (!regexengine.empty()) { source.Reply(" "); source.Reply(_("Regex matches are also supported using the %s engine.\n" - "Enclose your pattern in // if this is desired."), Config->RegexEngine.c_str()); + "Enclose your pattern in // if this is desired."), regexengine.c_str()); } return true; @@ -208,11 +209,12 @@ class CommandOSUserList : public Command "that are on the given channel. If INVISIBLE is specified, only users\n" "with the +i flag will be listed.")); - if (!Config->RegexEngine.empty()) + const Anope::string ®exengine = Config->GetBlock("options")->Get<const Anope::string &>("regexengine"); + if (!regexengine.empty()) { source.Reply(" "); source.Reply(_("Regex matches are also supported using the %s engine.\n" - "Enclose your pattern in // if this is desired."), Config->RegexEngine.c_str()); + "Enclose your pattern in // if this is desired."), regexengine.c_str()); } return true; diff --git a/modules/commands/os_login.cpp b/modules/commands/os_login.cpp index 36d772aa2..30172a0f3 100644 --- a/modules/commands/os_login.cpp +++ b/modules/commands/os_login.cpp @@ -19,7 +19,6 @@ class CommandOSLogin : public Command public: CommandOSLogin(Module *creator) : Command(creator, "operserv/login", 1, 1) { - this->SetDesc(Anope::printf(_("Login to %s"), Config->OperServ.c_str())); this->SetSyntax(_("\037password\037")); this->RequireUser(true); } @@ -60,6 +59,11 @@ class CommandOSLogin : public Command "configured without a password."), source.service->nick.c_str()); return true; } + + const Anope::string GetDesc(CommandSource &source) const anope_override + { + return Anope::printf(_("Login to %s"), source.service->nick.c_str()); + } }; class CommandOSLogout : public Command @@ -67,7 +71,6 @@ class CommandOSLogout : public Command public: CommandOSLogout(Module *creator) : Command(creator, "operserv/logout", 0, 0) { - this->SetDesc(Anope::printf(_("Logout from %s"), Config->OperServ.c_str())); this->RequireUser(true); } @@ -98,6 +101,11 @@ class CommandOSLogout : public Command "with a password."), source.service->nick.c_str()); return true; } + + const Anope::string GetDesc(CommandSource &source) const anope_override + { + return Anope::printf(_("Logout from %s"), source.service->nick.c_str()); + } }; class OSLogin : public Module diff --git a/modules/commands/os_logsearch.cpp b/modules/commands/os_logsearch.cpp index c033c6bb5..5bc11a6c9 100644 --- a/modules/commands/os_logsearch.cpp +++ b/modules/commands/os_logsearch.cpp @@ -11,8 +11,6 @@ #include "module.h" -static Anope::string logfile_name; - class CommandOSLogSearch : public Command { static inline Anope::string CreateLogName(const Anope::string &file, time_t t = Anope::CurTime) @@ -91,6 +89,7 @@ class CommandOSLogSearch : public Command Log(LOG_ADMIN, source, this) << "for " << search_string; + const Anope::string &logfile_name = Config->GetModule(this->owner)->Get<const Anope::string &>("logname"); std::list<Anope::string> matches; for (int d = days - 1; d >= 0; --d) { @@ -151,13 +150,6 @@ class OSLogSearch : public Module OSLogSearch(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandoslogsearch(this) { - Implementation i[] = { I_OnReload }; - ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - } - - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override - { - logfile_name = reader.ReadValue("logsearch", "name", "services.log", 0); } }; diff --git a/modules/commands/os_news.cpp b/modules/commands/os_news.cpp index f72273104..7292b6471 100644 --- a/modules/commands/os_news.cpp +++ b/modules/commands/os_news.cpp @@ -271,10 +271,8 @@ class CommandOSLogonNews : public NewsBase "user connects to the network, these messages will be sent\n" "to them. (However, no more than \002%d\002 messages will be\n" "sent in order to avoid flooding the user. If there are\n" - "more news messages, only the most recent will be sent.)\n" - "NewsCount can be configured in services.conf.\n" - " \n" - "LOGONNEWS may only be used by Services Operators."), Config->NewsCount); + "more news messages, only the most recent will be sent."), + Config->GetModule(this->owner)->Get<unsigned>("newscount", "3")); return true; } }; @@ -300,10 +298,8 @@ class CommandOSOperNews : public NewsBase "user opers up (with the /OPER command), these messages will\n" "be sent to them. (However, no more than \002%d\002 messages will\n" "be sent in order to avoid flooding the user. If there are\n" - "more news messages, only the most recent will be sent.)\n" - "NewsCount can be configured in services.conf.\n" - " \n" - "OPERNEWS may only be used by Services Operators."), Config->NewsCount); + "more news messages, only the most recent will be sent."), + Config->GetModule(this->owner)->Get<unsigned>("newscount", "3")); return true; } }; @@ -327,9 +323,7 @@ class CommandOSRandomNews : public NewsBase source.Reply(" "); source.Reply(_("Edits or displays the list of random news messages. When a\n" "user connects to the network, one (and only one) of the\n" - "random news will be randomly chosen and sent to them.\n" - " \n" - "RANDOMNEWS may only be used by Services Operators.")); + "random news will be randomly chosen and sent to them.\n")); return true; } }; @@ -358,7 +352,7 @@ class OSNews : public Module msg = _("[\002Random News\002 - %s] %s"); static unsigned cur_rand_news = 0; - unsigned displayed = 0; + unsigned displayed = 0, news_count = Config->GetModule(this)->Get<unsigned>("newscount", "3"); for (unsigned i = 0, end = newsList.size(); i < end; ++i) { if (Type == NEWS_RANDOM && i != cur_rand_news) @@ -380,7 +374,7 @@ class OSNews : public Module ++cur_rand_news; break; } - else if (displayed >= Config->NewsCount) + else if (displayed >= news_count) break; } @@ -393,7 +387,6 @@ class OSNews : public Module OSNews(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), newsitem_type("NewsItem", NewsItem::Unserialize), newsservice(this), commandoslogonnews(this), commandosopernews(this), commandosrandomnews(this) { - Implementation i[] = { I_OnUserModeSet, I_OnUserConnect }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } diff --git a/modules/commands/os_noop.cpp b/modules/commands/os_noop.cpp index 1d619dbb6..204b0e6e8 100644 --- a/modules/commands/os_noop.cpp +++ b/modules/commands/os_noop.cpp @@ -49,7 +49,7 @@ class CommandOSNOOP : public Command User *u2 = it->second; if (u2->server == s && u2->HasMode("OPER")) - u2->Kill(Config->OperServ, reason); + u2->Kill(source.service->nick, reason); } } else if (cmd.equals_ci("REVOKE")) @@ -95,7 +95,7 @@ class OSNOOP : public Module if (setter) { Anope::string reason = "NOOP command used by " + *setter; - u->Kill(Config->OperServ, reason); + u->Kill(OperServ ? OperServ->nick : "", reason); } } } diff --git a/modules/commands/os_reload.cpp b/modules/commands/os_reload.cpp index 00e649ed7..ed04fbea3 100644 --- a/modules/commands/os_reload.cpp +++ b/modules/commands/os_reload.cpp @@ -25,10 +25,10 @@ class CommandOSReload : public Command { try { - ServerConfig *new_config = new ServerConfig(); + Configuration::Conf *new_config = new Configuration::Conf(); delete Config; Config = new_config; - source.Reply(_("Services' configuration file has been reloaded.")); + source.Reply(_("Services' configuration has been reloaded.")); } catch (const ConfigException &ex) { diff --git a/modules/commands/os_session.cpp b/modules/commands/os_session.cpp index 67d1b79a3..74f6c2f7e 100644 --- a/modules/commands/os_session.cpp +++ b/modules/commands/os_session.cpp @@ -14,6 +14,29 @@ #include "module.h" #include "os_session.h" +namespace +{ + /* The default session limit */ + unsigned session_limit; + /* How many times to kill before adding an AKILL */ + unsigned max_session_kill; + /* How long session akills should last */ + time_t session_autokill_expiry; + /* Reason to use for session kills */ + Anope::string sle_reason; + /* Optional second reason */ + Anope::string sle_detailsloc; + + /* Max limit that can be used for exceptions */ + unsigned max_exception_limit; + /* How long before exceptions expire by default */ + time_t exception_expiry; + + /* Number of bits to use when comparing session IPs */ + unsigned ipv4_cidr; + unsigned ipv6_cidr; +} + class MySessionService : public SessionService { SessionMap Sessions; @@ -68,7 +91,7 @@ class MySessionService : public SessionService Session *FindSession(const Anope::string &ip) anope_override { - cidr c(ip, ip.find(':') != Anope::string::npos ? Config->SessionIPv6CIDR : Config->SessionIPv4CIDR); + cidr c(ip, ip.find(':') != Anope::string::npos ? ipv6_cidr : ipv4_cidr); SessionMap::iterator it = this->Sessions.find(c); if (it != this->Sessions.end()) return it->second; @@ -77,13 +100,13 @@ class MySessionService : public SessionService SessionMap::iterator FindSessionIterator(const Anope::string &ip) { - cidr c(ip, ip.find(':') != Anope::string::npos ? Config->SessionIPv6CIDR : Config->SessionIPv4CIDR); + cidr c(ip, ip.find(':') != Anope::string::npos ? ipv6_cidr : ipv4_cidr); return this->Sessions.find(c); } Session* &FindOrCreateSession(const Anope::string &ip) { - cidr c(ip, ip.find(':') != Anope::string::npos ? Config->SessionIPv6CIDR : Config->SessionIPv4CIDR); + cidr c(ip, ip.find(':') != Anope::string::npos ? ipv6_cidr : ipv4_cidr); return this->Sessions[c]; } @@ -96,7 +119,7 @@ class MySessionService : public SessionService class ExpireTimer : public Timer { public: - ExpireTimer() : Timer(Config->ExpireTimeout, Anope::CurTime, true) { } + ExpireTimer() : Timer(Config->GetBlock("options")->Get<time_t>("expiretimeout"), Anope::CurTime, true) { } void Tick(time_t) anope_override { @@ -218,10 +241,16 @@ class CommandOSSession : public Command else { Exception *exception = session_service->FindException(param); - source.Reply(_("The host \002%s\002 currently has \002%d\002 sessions with a limit of \002%d\002."), session->addr.mask().c_str(), session->count, exception && exception->limit > Config->DefSessionLimit ? exception->limit : Config->DefSessionLimit); + unsigned limit = session_limit; + if (exception) + { + if (!exception->limit) + limit = 0; + else if (exception->limit > limit) + limit = exception->limit; + } + source.Reply(_("The host \002%s\002 currently has \002%d\002 sessions with a limit of \002%d\002."), session->addr.mask().c_str(), session->count, limit); } - - return; } public: CommandOSSession(Module *creator) : Command(creator, "operserv/session", 2, 2) @@ -235,20 +264,14 @@ class CommandOSSession : public Command { const Anope::string &cmd = params[0]; - if (!Config->LimitSessions) - { + if (!session_limit) source.Reply(_("Session limiting is disabled.")); - return; - } - - if (cmd.equals_ci("LIST")) + else if (cmd.equals_ci("LIST")) return this->DoList(source, params); else if (cmd.equals_ci("VIEW")) return this->DoView(source, params); else this->OnSyntaxError(source, ""); - - return; } bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override @@ -303,7 +326,7 @@ class CommandOSException : public Command return; } - time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->ExceptionExpiry; + time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : exception_expiry; if (expires < 0) { source.Reply(BAD_EXPIRY_TIME); @@ -319,9 +342,9 @@ class CommandOSException : public Command } catch (const ConvertException &) { } - if (limit > Config->MaxSessionLimit) + if (limit > max_exception_limit) { - source.Reply(_("Invalid session limit. It must be a valid integer greater than or equal to zero and less than \002%d\002."), Config->MaxSessionLimit); + source.Reply(_("Invalid session limit. It must be a valid integer greater than or equal to zero and less than \002%d\002."), max_exception_limit); return; } else @@ -548,13 +571,9 @@ class CommandOSException : public Command { const Anope::string &cmd = params[0]; - if (!Config->LimitSessions) - { + if (!session_limit) source.Reply(_("Session limiting is disabled.")); - return; - } - - if (cmd.equals_ci("ADD")) + else if (cmd.equals_ci("ADD")) return this->DoAdd(source, params); else if (cmd.equals_ci("DEL")) return this->DoDel(source, params); @@ -566,8 +585,6 @@ class CommandOSException : public Command return this->DoView(source, params); else this->OnSyntaxError(source, ""); - - return; } bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override @@ -579,10 +596,9 @@ class CommandOSException : public Command "such as shell servers, to carry more than the default number\n" "of clients at a time. Once a host reaches its session limit,\n" "all clients attempting to connect from that host will be\n" - "killed. Before the user is killed, they are notified, via a\n" - "/NOTICE from %s, of a source of help regarding session\n" - "limiting. The content of this notice is a config setting.\n"), - Config->OperServ.c_str()); + "killed. Before the user is killed, they are notified, of a\n" + "source of help regarding session limiting. The content of\n" + "this notice is a config setting.\n")); source.Reply(" "); source.Reply(_("\002EXCEPTION ADD\002 adds the given host mask to the exception list.\n" "Note that \002nick!user@host\002 and \002user@host\002 masks are invalid!\n" @@ -624,14 +640,34 @@ class OSSession : public Module { this->SetPermanent(true); - Implementation i[] = { I_OnUserConnect, I_OnPreUserLogoff }; + Implementation i[] = { I_OnReload, I_OnUserConnect, I_OnPreUserLogoff }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); ModuleManager::SetPriority(this, PRIORITY_FIRST); } + void OnReload(Configuration::Conf *conf) anope_override + { + Configuration::Block *block = Config->GetModule(this); + + session_limit = block->Get<int>("defaultsessionlimit"); + max_session_kill = block->Get<int>("maxsessionkill"); + session_autokill_expiry = block->Get<time_t>("sessionautokillexpiry"); + sle_reason = block->Get<const Anope::string &>("sessionlimitexceeded"); + sle_detailsloc = block->Get<const Anope::string &>("sessionlimitdetailsloc"); + + max_exception_limit = block->Get<int>("maxsessionlimit"); + exception_expiry = block->Get<time_t>("exceptionexpiry"); + + ipv4_cidr = block->Get<unsigned>("session_ipv4_cidr", "32"); + ipv6_cidr = block->Get<unsigned>("session_ipv6_cidr", "128"); + + if (ipv4_cidr > 32 || ipv6_cidr > 128) + throw ConfigException(this->name + ": session CIDR value out of range"); + } + void OnUserConnect(User *u, bool &exempt) anope_override { - if (u->Quitting() || !Config->LimitSessions || exempt || !u->server || u->server->IsULined()) + if (u->Quitting() || !session_limit || exempt || !u->server || u->server->IsULined()) return; try @@ -641,7 +677,7 @@ class OSSession : public Module if (session) { bool kill = false; - if (Config->DefSessionLimit && session->count >= Config->DefSessionLimit) + if (session->count >= session_limit) { kill = true; Exception *exception = this->ss.FindException(u); @@ -658,7 +694,7 @@ class OSSession : public Module * * Now, we create the user struture before calling this to fix some user tracking issues, * so we must increment this here no matter what because it will either be - * decremented in do_kill or in do_quit - Adam + * decremented when the user is killed or quits - Adam */ ++session->count; @@ -666,30 +702,33 @@ class OSSession : public Module { if (OperServ) { - if (!Config->SessionLimitExceeded.empty()) - u->SendMessage(OperServ, Config->SessionLimitExceeded.c_str(), u->ip.c_str()); - if (!Config->SessionLimitDetailsLoc.empty()) - u->SendMessage(OperServ, "%s", Config->SessionLimitDetailsLoc.c_str()); + if (!sle_reason.empty()) + { + Anope::string message = sle_reason.replace_all_cs("%IP%", u->ip); + u->SendMessage(OperServ, message); + } + if (!sle_detailsloc.empty()) + u->SendMessage(OperServ, sle_detailsloc); } ++session->hits; - if (Config->MaxSessionKill && session->hits >= Config->MaxSessionKill && akills) + if (max_session_kill && session->hits >= max_session_kill && akills) { const Anope::string &akillmask = "*@" + u->ip; - XLine *x = new XLine(akillmask, Config->OperServ, Anope::CurTime + Config->SessionAutoKillExpiry, "Session limit exceeded", XLineManager::GenerateUID()); + XLine *x = new XLine(akillmask, OperServ ? OperServ->nick : "", Anope::CurTime + session_autokill_expiry, "Session limit exceeded", XLineManager::GenerateUID()); akills->AddXLine(x); akills->Send(NULL, x); Log(OperServ, "akill/session") << "Added a temporary AKILL for \002" << akillmask << "\002 due to excessive connections"; } else { - u->Kill(Config->OperServ, "Session limit exceeded"); + u->Kill(OperServ ? OperServ->nick : "", "Session limit exceeded"); } } } else { - session = new Session(u->ip, u->ip.find(':') != Anope::string::npos ? Config->SessionIPv6CIDR : Config->SessionIPv4CIDR); + session = new Session(u->ip, u->ip.find(':') != Anope::string::npos ? ipv6_cidr : ipv4_cidr); } } catch (const SocketException &) { } @@ -697,7 +736,7 @@ class OSSession : public Module void OnPreUserLogoff(User *u) anope_override { - if (!Config->LimitSessions || !u->server || u->server->IsULined()) + if (!session_limit || !u->server || u->server->IsULined()) return; SessionService::SessionMap::iterator sit; diff --git a/modules/commands/os_set.cpp b/modules/commands/os_set.cpp index 6d701dd11..6fc05ab60 100644 --- a/modules/commands/os_set.cpp +++ b/modules/commands/os_set.cpp @@ -78,22 +78,23 @@ class CommandOSSet : public Command * * Rob **/ - if (!Config->SuperAdmin) - source.Reply(_("SuperAdmin can not be set because it is not enabled in the configuration.")); + bool super_admin = Config->GetModule(this->owner)->Get<bool>("superadmin"); + if (!super_admin) + source.Reply(_("Super admin can not be set because it is not enabled in the configuration.")); else if (setting.equals_ci("ON")) { source.GetUser()->super_admin = true; - source.Reply(_("You are now a SuperAdmin.")); + source.Reply(_("You are now a super admin.")); Log(LOG_ADMIN, source, this) << "SUPERADMIN ON"; } else if (setting.equals_ci("OFF")) { source.GetUser()->super_admin = false; - source.Reply(_("You are no longer a SuperAdmin.")); + source.Reply(_("You are no longer a super admin.")); Log(LOG_ADMIN, source, this) << "SUPERADMIN OFF"; } else - source.Reply(_("Setting for SuperAdmin must be \002ON\002 or \002OFF\002.")); + source.Reply(_("Setting for super admin must be \002ON\002 or \002OFF\002.")); return; } @@ -202,12 +203,12 @@ class CommandOSSet : public Command " READONLY Set read-only or read-write mode\n" " DEBUG Activate or deactivate debug mode\n" " NOEXPIRE Activate or deactivate no expire mode\n" - " SUPERADMIN Activate or deactivate SuperAdmin mode\n" + " SUPERADMIN Activate or deactivate super admin mode\n" " LIST List the options")); } else if (subcommand.equals_ci("LIST")) source.Reply(_("Syntax: \002LIST\n" - "Display the various %s settings"), Config->OperServ.c_str()); + "Display the various %s settings"), source.service->nick.c_str()); else if (subcommand.equals_ci("READONLY")) source.Reply(_("Syntax: \002READONLY {ON | OFF}\002\n" " \n" @@ -249,7 +250,6 @@ class OSSet : public Module OSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandosset(this) { - } }; diff --git a/modules/commands/os_stats.cpp b/modules/commands/os_stats.cpp index 7aa8740c7..04bd6e60d 100644 --- a/modules/commands/os_stats.cpp +++ b/modules/commands/os_stats.cpp @@ -62,7 +62,7 @@ class CommandOSStats : public Command { /* AKILLs */ source.Reply(_("Current number of AKILLs: \002%d\002"), akills->GetCount()); - timeout = Config->AutokillExpiry + 59; + timeout = Config->GetModule("operserv")->Get<time_t>("autokillexpiry", "30d") + 59; if (timeout >= 172800) source.Reply(_("Default AKILL expiry time: \002%d days\002"), timeout / 86400); else if (timeout >= 86400) @@ -82,7 +82,7 @@ class CommandOSStats : public Command { /* SNLINEs */ source.Reply(_("Current number of SNLINEs: \002%d\002"), snlines->GetCount()); - timeout = Config->SNLineExpiry + 59; + timeout = Config->GetModule("operserv")->Get<time_t>("snlineexpiry", "30d") + 59; if (timeout >= 172800) source.Reply(_("Default SNLINE expiry time: \002%d days\002"), timeout / 86400); else if (timeout >= 86400) @@ -102,7 +102,7 @@ class CommandOSStats : public Command { /* SQLINEs */ source.Reply(_("Current number of SQLINEs: \002%d\002"), sqlines->GetCount()); - timeout = Config->SQLineExpiry + 59; + timeout = Config->GetModule("operserv")->Get<time_t>("sglineexpiry", "30d") + 59; if (timeout >= 172800) source.Reply(_("Default SQLINE expiry time: \002%d days\002"), timeout / 86400); else if (timeout >= 86400) @@ -118,7 +118,6 @@ class CommandOSStats : public Command else source.Reply(_("Default SQLINE expiry time: \002No expiration\002")); } - return; } void DoStatsReset(CommandSource &source) diff --git a/modules/commands/os_svs.cpp b/modules/commands/os_svs.cpp index 13b29e84c..9fb1d63c3 100644 --- a/modules/commands/os_svs.cpp +++ b/modules/commands/os_svs.cpp @@ -34,11 +34,12 @@ class CommandOSSVSNick : public Command return; } - /* Truncate long nicknames to Config->NickLen characters */ - if (newnick.length() > Config->NickLen) + /* Truncate long nicknames to nicklen characters */ + unsigned nicklen = Config->GetBlock("networkinfo")->Get<unsigned>("nicklen"); + if (newnick.length() > nicklen) { - source.Reply(_("Nick \002%s\002 was truncated to %d characters."), newnick.c_str(), Config->NickLen, newnick.c_str()); - newnick = params[1].substr(0, Config->NickLen); + source.Reply(_("Nick \002%s\002 was truncated to %d characters."), newnick.c_str(), nicklen, newnick.c_str()); + newnick = params[1].substr(0, nicklen); } /* Check for valid characters */ diff --git a/modules/commands/os_sxline.cpp b/modules/commands/os_sxline.cpp index 1cf921467..efe81955d 100644 --- a/modules/commands/os_sxline.cpp +++ b/modules/commands/os_sxline.cpp @@ -258,7 +258,6 @@ class CommandOSSNLine : public CommandOSSXLineBase unsigned last_param = 2; Anope::string param, expiry; - time_t expires; param = params.size() > 1 ? params[1] : ""; if (!param.empty() && param[0] == '+') @@ -268,7 +267,7 @@ class CommandOSSNLine : public CommandOSSXLineBase last_param = 3; } - expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->SNLineExpiry; + time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->GetModule("operserv")->Get<time_t>("snlineexpiry", "30d"); /* If the expiry given does not contain a final letter, it's in days, * said the doc. Ah well. */ @@ -312,16 +311,18 @@ class CommandOSSNLine : public CommandOSSXLineBase if (mask[0] == '/' && mask[mask.length() - 1] == '/') { - if (Config->RegexEngine.empty()) + const Anope::string ®exengine = Config->GetBlock("options")->Get<const Anope::string &>("regexengine"); + + if (regexengine.empty()) { - source.Reply(_("Regex is enabled.")); + source.Reply(_("Regex is disabled.")); return; } - ServiceReference<RegexProvider> provider("Regex", Config->RegexEngine); + ServiceReference<RegexProvider> provider("Regex", regexengine); if (!provider) { - source.Reply(_("Unable to find regex engine %s."), Config->RegexEngine.c_str()); + source.Reply(_("Unable to find regex engine %s."), regexengine.c_str()); return; } @@ -352,8 +353,11 @@ class CommandOSSNLine : public CommandOSSXLineBase if (mask[masklen - 1] == ' ') mask.erase(masklen - 1); + if (Config->GetModule("operserv")->Get<bool>("addakiller", "yes") && !source.GetNick().empty()) + reason = "[" + source.GetNick() + "] " + reason; + XLine *x = new XLine(mask, source.GetNick(), expires, reason); - if (Config->AkillIds) + if (Config->GetBlock("operserv")->Get<bool>("akilids")) x->id = XLineManager::GenerateUID(); unsigned int affected = 0; @@ -380,7 +384,7 @@ class CommandOSSNLine : public CommandOSSXLineBase this->xlm()->AddXLine(x); - if (Config->KillonSNline) + if (Config->GetModule("operserv")->Get<bool>("killonsnline", "yes")) { this->xlm()->Send(source.GetUser(), x); @@ -391,7 +395,7 @@ class CommandOSSNLine : public CommandOSSXLineBase User *user = it->second; if (!user->HasMode("OPER") && user->server != Me && Anope::Match(user->realname, x->mask, false, true)) - user->Kill(Config->ServerName, rreason); + user->Kill(Me->GetName(), rreason); } } @@ -434,11 +438,12 @@ class CommandOSSNLine : public CommandOSSXLineBase "\002STATS AKILL\002 command.\n" "Note: because the realname mask may contain spaces, the\n" "separator between it and the reason is a colon.")); - if (!Config->RegexEngine.empty()) + const Anope::string ®exengine = Config->GetBlock("options")->Get<const Anope::string &>("regexengine"); + if (!regexengine.empty()) { source.Reply(" "); source.Reply(_("Regex matches are also supported using the %s engine.\n" - "Enclose your mask in // if this is desired."), Config->RegexEngine.c_str()); + "Enclose your mask in // if this is desired."), regexengine.c_str()); } source.Reply(_(" \n" "The \002SNLINE DEL\002 command removes the given mask from the\n" @@ -480,7 +485,6 @@ class CommandOSSQLine : public CommandOSSXLineBase unsigned last_param = 2; Anope::string expiry, mask; - time_t expires; mask = params.size() > 1 ? params[1] : ""; if (!mask.empty() && mask[0] == '+') @@ -490,7 +494,7 @@ class CommandOSSQLine : public CommandOSSXLineBase last_param = 3; } - expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->SQLineExpiry; + time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->GetModule("operserv")->Get<time_t>("sqlineexpiry", "30d"); /* If the expiry given does not contain a final letter, it's in days, * said the doc. Ah well. */ @@ -523,16 +527,18 @@ class CommandOSSQLine : public CommandOSSXLineBase if (mask[0] == '/' && mask[mask.length() - 1] == '/') { - if (Config->RegexEngine.empty()) + const Anope::string ®exengine = Config->GetBlock("options")->Get<const Anope::string &>("regexengine"); + + if (regexengine.empty()) { - source.Reply(_("Regex is enabled.")); + source.Reply(_("Regex is disabled.")); return; } - ServiceReference<RegexProvider> provider("Regex", Config->RegexEngine); + ServiceReference<RegexProvider> provider("Regex", regexengine); if (!provider) { - source.Reply(_("Unable to find regex engine %s."), Config->RegexEngine.c_str()); + source.Reply(_("Unable to find regex engine %s."), regexengine.c_str()); return; } @@ -556,8 +562,11 @@ class CommandOSSQLine : public CommandOSSXLineBase return; } + if (Config->GetModule("operserv")->Get<bool>("addakiller", "yes") && !source.GetNick().empty()) + reason = "[" + source.GetNick() + "] " + reason; + XLine *x = new XLine(mask, source.GetNick(), expires, reason); - if (Config->AkillIds) + if (Config->GetBlock("operserv")->Get<bool>("akilids")) x->id = XLineManager::GenerateUID(); unsigned int affected = 0; @@ -583,7 +592,8 @@ class CommandOSSQLine : public CommandOSSXLineBase } this->xlm()->AddXLine(x); - if (Config->KillonSQline) + + if (Config->GetModule("operserv")->Get<bool>("killonsqline", "yes")) { Anope::string rreason = "Q-Lined: " + reason; @@ -617,7 +627,7 @@ class CommandOSSQLine : public CommandOSSXLineBase User *user = it->second; if (!user->HasMode("OPER") && user->server != Me && Anope::Match(user->nick, x->mask, false, true)) - user->Kill(Config->ServerName, rreason); + user->Kill(Me->GetName(), rreason); } } @@ -664,11 +674,12 @@ class CommandOSSQLine : public CommandOSSXLineBase "must be given, even if it is the same as the default. The\n" "current SQLINE default expiry time can be found with the\n" "\002STATS AKILL\002 command.")); - if (!Config->RegexEngine.empty()) + const Anope::string ®exengine = Config->GetBlock("options")->Get<const Anope::string &>("regexengine"); + if (!regexengine.empty()) { source.Reply(" "); source.Reply(_("Regex matches are also supported using the %s engine.\n" - "Enclose your mask in // if this is desired."), Config->RegexEngine.c_str()); + "Enclose your mask in // if this is desired."), regexengine.c_str()); } source.Reply(_(" \n" "The \002SQLINE DEL\002 command removes the given mask from the\n" diff --git a/modules/database/db_flatfile.cpp b/modules/database/db_flatfile.cpp index dcf4a5aa4..8cede5394 100644 --- a/modules/database/db_flatfile.cpp +++ b/modules/database/db_flatfile.cpp @@ -102,12 +102,10 @@ class LoadData : public Serialize::Data class DBFlatFile : public Module, public Pipe { - Anope::string database_file; /* Day the last backup was on */ int last_day; /* Backup file names */ std::map<Anope::string, std::list<Anope::string> > backups; - bool use_fork; bool loaded; void BackupDatabase() @@ -121,7 +119,7 @@ class DBFlatFile : public Module, public Pipe const std::vector<Anope::string> &type_order = Serialize::Type::GetTypeOrder(); std::set<Anope::string> dbs; - dbs.insert(database_file); + dbs.insert(Config->GetModule(this)->Get<const Anope::string &>("database")); for (unsigned i = 0; i < type_order.size(); ++i) { @@ -146,7 +144,7 @@ class DBFlatFile : public Module, public Pipe { Log(this) << "Unable to back up database " << *it << "!"; - if (!Config->NoBackupOkay) + if (!Config->GetModule(this)->Get<bool>("nobackupok")) Anope::Quitting = true; continue; @@ -154,7 +152,8 @@ class DBFlatFile : public Module, public Pipe backups[*it].push_back(newname); - if (Config->KeepBackups > 0 && backups[*it].size() > static_cast<unsigned>(Config->KeepBackups)) + unsigned keepbackups = Config->GetModule(this)->Get<unsigned>("keepbackups"); + if (keepbackups > 0 && backups[*it].size() > keepbackups) { unlink(backups[*it].front().c_str()); backups[*it].pop_front(); @@ -164,10 +163,10 @@ class DBFlatFile : public Module, public Pipe } public: - DBFlatFile(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE | VENDOR), last_day(0), use_fork(false), loaded(false) + DBFlatFile(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE | VENDOR), last_day(0), loaded(false) { - Implementation i[] = { I_OnReload, I_OnLoadDatabase, I_OnSaveDatabase, I_OnSerializeTypeCreate }; + Implementation i[] = { I_OnLoadDatabase, I_OnSaveDatabase, I_OnSerializeTypeCreate }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } @@ -187,22 +186,16 @@ class DBFlatFile : public Module, public Pipe Log(this) << "Error saving databases: " << buf; - if (!Config->NoBackupOkay) + if (!Config->GetModule(this)->Get<bool>("nobackupok")) Anope::Quitting = true; } - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override - { - database_file = reader.ReadValue("db_flatfile", "database", "anope.db", 0); - use_fork = reader.ReadFlag("db_flatfile", "fork", "no", 0); - } - EventReturn OnLoadDatabase() anope_override { const std::vector<Anope::string> &type_order = Serialize::Type::GetTypeOrder(); std::set<Anope::string> tried_dbs; - const Anope::string &db_name = Anope::DataDir + "/" + database_file; + const Anope::string &db_name = Anope::DataDir + "/" + Config->GetModule(this)->Get<const Anope::string &>("database"); std::fstream fd(db_name.c_str(), std::ios_base::in); if (!fd.is_open()) @@ -253,7 +246,7 @@ class DBFlatFile : public Module, public Pipe int i = -1; #ifndef _WIN32 - if (use_fork) + if (Config->GetModule(this)->Get<bool>("fork")) { i = fork(); if (i > 0) @@ -279,7 +272,7 @@ class DBFlatFile : public Module, public Pipe if (s_type->GetOwner()) db_name = Anope::DataDir + "/module_" + s_type->GetOwner()->name + ".db"; else - db_name = Anope::DataDir + "/" + database_file; + db_name = Anope::DataDir + "/" + Config->GetModule(this)->Get<const Anope::string &>("database"); if (Anope::IsFile(db_name)) rename(db_name.c_str(), (db_name + ".tmp").c_str()); @@ -311,7 +304,7 @@ class DBFlatFile : public Module, public Pipe for (std::map<Module *, std::fstream *>::iterator it = databases.begin(), it_end = databases.end(); it != it_end; ++it) { std::fstream *f = it->second; - const Anope::string &db_name = Anope::DataDir + "/" + (it->first ? (it->first->name + ".db") : database_file); + const Anope::string &db_name = Anope::DataDir + "/" + (it->first ? (it->first->name + ".db") : Config->GetModule(this)->Get<const Anope::string &>("database")); if (!f->is_open() || !f->good()) { @@ -356,7 +349,7 @@ class DBFlatFile : public Module, public Pipe if (stype->GetOwner()) db_name = Anope::DataDir + "/module_" + stype->GetOwner()->name + ".db"; else - db_name = Anope::DataDir + "/" + database_file; + db_name = Anope::DataDir + "/" + Config->GetModule(this)->Get<const Anope::string &>("database"); std::fstream fd(db_name.c_str(), std::ios_base::in); if (!fd.is_open()) diff --git a/modules/database/db_old.cpp b/modules/database/db_old.cpp index 6eba8a2a9..52d61bfad 100644 --- a/modules/database/db_old.cpp +++ b/modules/database/db_old.cpp @@ -1098,8 +1098,7 @@ class DBOld : public Module Implementation i[] = { I_OnLoadDatabase, I_OnUplinkSync }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - ConfigReader conf; - hashm = conf.ReadValue("db_old", "hash", "", 0); + hashm = Config->GetModule(this)->Get<const Anope::string &>("hash"); if (hashm != "md5" && hashm != "oldmd5" && hashm != "sha1" && hashm != "plain" && hashm != "sha256") throw ModuleException("Invalid hash method"); diff --git a/modules/database/db_plain.cpp b/modules/database/db_plain.cpp index 11274c593..76a2aa455 100644 --- a/modules/database/db_plain.cpp +++ b/modules/database/db_plain.cpp @@ -136,7 +136,7 @@ EventReturn OnDatabaseReadMetadata(ChannelInfo *ci, const Anope::string &key, co try { if (key.equals_ci("BANTYPE")) - ci->bantype = params[0].is_pos_number_only() ? convertTo<int16_t>(params[0]) : Config->CSDefBantype; + ci->bantype = params[0].is_pos_number_only() ? convertTo<int16_t>(params[0]) : 2; else if (key.equals_ci("MEMOMAX")) ci->memos.memomax = params[0].is_pos_number_only() ? convertTo<int16_t>(params[0]) : -1; else if (key.equals_ci("FOUNDER")) @@ -618,7 +618,7 @@ class DBPlain : public Module { Log() << "Unable to back up database!"; - if (!Config->NoBackupOkay) + if (!Config->GetModule(this)->Get<bool>("nobackupok")) Anope::Quitting = true; return; @@ -626,7 +626,7 @@ class DBPlain : public Module Backups.push_back(newname); - unsigned KeepBackups = Config->KeepBackups; + unsigned KeepBackups = Config->GetModule(this)->Get<unsigned>("keepbackups"); if (KeepBackups && Backups.size() > KeepBackups) { unlink(Backups.front().c_str()); @@ -635,10 +635,12 @@ class DBPlain : public Module } } - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override + void OnReload(Configuration::Conf *conf) anope_override { - DatabaseFile = Anope::DataDir + "/" + reader.ReadValue("db_plain", "database", "anope.db", 0); - BackupFile = Anope::DataDir + "/backups/" + reader.ReadValue("db_plain", "database", "anope.db", 0); + DatabaseFile = Anope::DataDir + "/" + conf->GetModule(this)->Get<const Anope::string &>("database"); + if (DatabaseFile.empty()) + DatabaseFile = "anope.db"; + BackupFile = Anope::DataDir + "/backups/" + DatabaseFile; } EventReturn OnLoadDatabase() anope_override diff --git a/modules/database/db_sql.cpp b/modules/database/db_sql.cpp index 894037026..400619159 100644 --- a/modules/database/db_sql.cpp +++ b/modules/database/db_sql.cpp @@ -146,12 +146,12 @@ class DBSQL : public Module, public Pipe this->imported = true; } - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override + void OnReload(Configuration::Conf *conf) anope_override { - Anope::string engine = reader.ReadValue("db_sql", "engine", "", 0); - this->sql = ServiceReference<Provider>("SQL::Provider", engine); - this->prefix = reader.ReadValue("db_sql", "prefix", "anope_db_", 0); - this->import = reader.ReadFlag("db_sql", "import", "false", 0); + Configuration::Block *block = conf->GetModule(this); + this->sql = ServiceReference<Provider>("SQL::Provider", block->Get<const Anope::string &>("engine")); + this->prefix = block->Get<const Anope::string &>("prefix", "anope_db_"); + this->import = block->Get<bool>("import"); } void OnShutdown() anope_override diff --git a/modules/database/db_sql_live.cpp b/modules/database/db_sql_live.cpp index 239c543c2..a7116892d 100644 --- a/modules/database/db_sql_live.cpp +++ b/modules/database/db_sql_live.cpp @@ -7,7 +7,6 @@ using namespace SQL; class DBMySQL : public Module, public Pipe { private: - Anope::string engine; Anope::string prefix; ServiceReference<Provider> SQL; time_t lastwarn; @@ -29,7 +28,7 @@ class DBMySQL : public Module, public Pipe } else { - if (Anope::CurTime - Config->UpdateTimeout > lastwarn) + if (Anope::CurTime - Config->GetBlock("options")->Get<time_t>("updatetimeout") > lastwarn) { Log() << "Unable to locate SQL reference, going to readonly..."; Anope::ReadOnly = this->ro = true; @@ -130,11 +129,11 @@ class DBMySQL : public Module, public Pipe init = false; } - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override + void OnReload(Configuration::Conf *conf) anope_override { - this->engine = reader.ReadValue("db_sql", "engine", "", 0); - this->SQL = ServiceReference<Provider>("SQL::Provider", this->engine); - this->prefix = reader.ReadValue("db_sql", "prefix", "anope_db_", 0); + Configuration::Block *block = conf->GetModule(this); + this->SQL = ServiceReference<Provider>("SQL::Provider", block->Get<const Anope::string &>("engine")); + this->prefix = block->Get<const Anope::string &>("prefix", "anope_db_"); } void OnSerializableConstruct(Serializable *obj) anope_override diff --git a/modules/extra/m_chanstats.cpp b/modules/extra/m_chanstats.cpp index caa20aacb..f5e20646b 100644 --- a/modules/extra/m_chanstats.cpp +++ b/modules/extra/m_chanstats.cpp @@ -1,5 +1,5 @@ #include "module.h" -#include "../extra/sql.h" +#include "sql.h" class MySQLInterface : public SQL::Interface { @@ -338,7 +338,7 @@ class MChanstats : public Module { Implementation i[] = { I_OnPrivmsg, - I_OnUserKicked, + I_OnPreUserKicked, I_OnChannelModeSet, I_OnChannelModeUnset, I_OnTopicUpdated, @@ -349,14 +349,15 @@ class MChanstats : public Module ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override + void OnReload(Configuration::Conf *conf) anope_override { - prefix = reader.ReadValue("chanstats", "prefix", "anope_", 0); - SmileysHappy = reader.ReadValue("chanstats", "SmileysHappy", ":) :-) ;) :D :-D", 0); - SmileysSad = reader.ReadValue("chanstats", "SmileysSad", ":( :-( ;( ;-(", 0); - SmileysOther = reader.ReadValue("chanstats", "SmileysOther", ":/", 0); + Configuration::Block *block = conf->GetModule(this); + prefix = block->Get<const Anope::string &>("prefix", "anope_"); + SmileysHappy = block->Get<const Anope::string &>("SmileysHappy"); + SmileysSad = block->Get<const Anope::string &>("SmileysSad"); + SmileysOther = block->Get<const Anope::string &>("SmileysOther"); - Anope::string engine = reader.ReadValue("chanstats", "engine", "", 0); + Anope::string engine = block->Get<const Anope::string &>("engine"); this->sql = ServiceReference<SQL::Provider>("SQL::Provider", engine); if (sql) this->CheckTables(); @@ -399,24 +400,24 @@ class MChanstats : public Module this->RunQuery(query); } public: - void OnUserKicked(Channel *c, User *target, MessageSource &source, const Anope::string &kickmsg) anope_override + void OnPreUserKicked(MessageSource &source, ChanUserContainer *cu, const Anope::string &kickmsg) anope_override { - if (!c->ci || !c->ci->HasExt("STATS")) + if (!cu->chan->ci || !cu->chan->ci->HasExt("STATS")) return; query = "CALL " + prefix + "chanstats_proc_update(@channel@, @nick@, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0);"; - query.SetValue("channel", c->name); - query.SetValue("nick", GetDisplay(target)); + query.SetValue("channel", cu->chan->name); + query.SetValue("nick", GetDisplay(cu->user)); this->RunQuery(query); query = "CALL " + prefix + "chanstats_proc_update(@channel@, @nick@, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0);"; - query.SetValue("channel", c->name); + query.SetValue("channel", cu->chan->name); query.SetValue("nick", GetDisplay(source.GetUser())); this->RunQuery(query); } void OnPrivmsg(User *u, Channel *c, Anope::string &msg) anope_override { - if (!c->ci || !c->ci->HasExt("STATS") || (msg[0] == Config->BSFantasyCharacter[0])) + if (!c->ci || !c->ci->HasExt("STATS")) return; size_t letters = msg.length(); diff --git a/modules/extra/m_httpd.cpp b/modules/extra/m_httpd.cpp index 5e643d942..87d1ad6a1 100644 --- a/modules/extra/m_httpd.cpp +++ b/modules/extra/m_httpd.cpp @@ -352,21 +352,24 @@ class HTTPD : public Module this->providers.clear(); } - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override + void OnReload(Configuration::Conf *conf) anope_override { std::set<Anope::string> existing; - for (int i = 0, num = reader.Enumerate("httpd"); i < num; ++i) + for (int i = 0; i < conf->CountBlock("httpd"); ++i) { - Anope::string hname = reader.ReadValue("httpd", "name", "httpd/main", i); + Configuration::Block *block = conf->GetBlock("httpd", i); + + + const Anope::string &hname = block->Get<const Anope::string &>("name", "httpd/main"); existing.insert(hname); - Anope::string ip = reader.ReadValue("httpd", "ip", "", i); - int port = reader.ReadInteger("httpd", "port", "8080", i, true); - int timeout = reader.ReadInteger("httpd", "timeout", "30", i, true); - bool ssl = reader.ReadFlag("httpd", "ssl", "no", i); - Anope::string ext_ip = reader.ReadValue("httpd", "extforward_ip", "", i); - Anope::string ext_header = reader.ReadValue("httpd", "extforward_header", "", i); + Anope::string ip = block->Get<const Anope::string &>("ip"); + int port = block->Get<int>("port", "8080"); + int timeout = block->Get<int>("timeout", "30"); + bool ssl = block->Get<bool>("ssl", "no"); + Anope::string ext_ip = block->Get<const Anope::string &>("extforward_ip"); + Anope::string ext_header = block->Get<const Anope::string &>("extforward_header"); if (ip.empty()) { diff --git a/modules/extra/m_ldap.cpp b/modules/extra/m_ldap.cpp index 3200d3e38..a6066c008 100644 --- a/modules/extra/m_ldap.cpp +++ b/modules/extra/m_ldap.cpp @@ -1,7 +1,7 @@ /* RequiredLibraries: ldap,lber */ #include "module.h" -#include "ldap.h" +#include "ldapapi.h" #include <ldap.h> static Pipe *me; @@ -423,7 +423,7 @@ class ModuleLDAP : public Module, public Pipe LDAPServices.clear(); } - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override + void OnReload(Configuration::Conf *conf) anope_override { int i, num; @@ -433,13 +433,9 @@ class ModuleLDAP : public Module, public Pipe LDAPService *s = it->second; ++it; - for (i = 0, num = reader.Enumerate("ldap"); i < num; ++i) - { - if (reader.ReadValue("ldap", "name", "main", i) == cname) - { + for (i = 0; i < Config->CountBlock("ldap"); ++i) + if (Config->GetBlock("ldap", i)->Get<const Anope::string &>("name", "ldap/main") == cname) break; - } - } if (i == num) { @@ -451,16 +447,16 @@ class ModuleLDAP : public Module, public Pipe } } - for (i = 0, num = reader.Enumerate("ldap"); i < num; ++i) + for (i = 0; i < Config->CountBlock("ldap"); ++i) { - Anope::string connname = reader.ReadValue("ldap", "name", "main", i); + const Anope::string &connname = Config->GetBlock("ldap", i)->Get<const Anope::string &>("name", "ldap/main"); if (this->LDAPServices.find(connname) == this->LDAPServices.end()) { - Anope::string server = reader.ReadValue("ldap", "server", "127.0.0.1", i); - int port = reader.ReadInteger("ldap", "port", "389", i, true); - Anope::string admin_binddn = reader.ReadValue("ldap", "admin_binddn", "", i); - Anope::string admin_password = reader.ReadValue("ldap", "admin_password", "", i); + const Anope::string &server = Config->GetBlock("ldap", i)->Get<const Anope::string &>("server", "127.0.0.1"); + int port = Config->GetBlock("ldap", i)->Get<int>("port", "389"); + const Anope::string &admin_binddn = Config->GetBlock("ldap", i)->Get<const Anope::string &>("admin_binddn"); + const Anope::string &admin_password = Config->GetBlock("ldap", i)->Get<const Anope::string &>("admin_password"); try { diff --git a/modules/extra/m_ldap_authentication.cpp b/modules/extra/m_ldap_authentication.cpp index f39bb43e8..a8ece73ff 100644 --- a/modules/extra/m_ldap_authentication.cpp +++ b/modules/extra/m_ldap_authentication.cpp @@ -1,6 +1,6 @@ #include "module.h" #include "nickserv.h" -#include "ldap.h" +#include "ldapapi.h" static Module *me; @@ -104,14 +104,9 @@ class IdentifyInterface : public LDAPInterface if (na == NULL) { na = new NickAlias(ii->req->GetAccount(), new NickCore(ii->req->GetAccount())); - if (ii->user) - { - if (Config->NSAddAccessOnReg) - na->nc->AddAccess(ii->user->Mask()); - - if (NickServ) - ii->user->SendMessage(NickServ, _("Your account \002%s\002 has been successfully created."), na->nick.c_str()); - } + FOREACH_MOD(I_OnNickRegister, OnNickRegister(ii->user, na)); + if (ii->user && NickServ) + ii->user->SendMessage(NickServ, _("Your account \002%s\002 has been successfully created."), na->nick.c_str()); } // encrypt and store the password in the nickcore Anope::Encrypt(ii->req->GetPassword(), na->nc->pass); @@ -226,21 +221,22 @@ class NSIdentifyLDAP : public Module ModuleManager::SetPriority(this, PRIORITY_FIRST); } - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override + void OnReload(Configuration::Conf *conf) anope_override { + Configuration::Block *config = Config->GetModule(this); - basedn = reader.ReadValue("m_ldap_authentication", "basedn", "", 0); - search_filter = reader.ReadValue("m_ldap_authentication", "search_filter", "", 0); - object_class = reader.ReadValue("m_ldap_authentication", "object_class", "", 0); - username_attribute = reader.ReadValue("m_ldap_authentication", "username_attribute", "", 0); - this->password_attribute = reader.ReadValue("m_ldap_authentication", "password_attribute", "", 0); - email_attribute = reader.ReadValue("m_ldap_authentication", "email_attribute", "", 0); - this->disable_register_reason = reader.ReadValue("m_ldap_authentication", "disable_register_reason", "", 0); - this->disable_email_reason = reader.ReadValue("m_ldap_authentication", "disable_email_reason", "", 0); + basedn = conf->Get<const Anope::string &>("basedn"); + search_filter = conf->Get<const Anope::string &>("search_filter"); + object_class = conf->Get<const Anope::string &>("object_class"); + username_attribute = conf->Get<const Anope::string &>("username_attribute"); + this->password_attribute = conf->Get<const Anope::string &>("password_attribute"); + email_attribute = conf->Get<const Anope::string &>("email_attribute"); + this->disable_register_reason = conf->Get<const Anope::string &>("disable_register_reason"); + this->disable_email_reason = conf->Get<const Anope::string &>("disable_email_reason"); if (!email_attribute.empty()) /* Don't complain to users about how they need to update their email, we will do it for them */ - Config->NSForceEmail = false; + Config->GetBlock("nickserv")->Set("forceemail", "false"); } EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> ¶ms) anope_override @@ -297,7 +293,7 @@ class NSIdentifyLDAP : public Module } } - void OnNickRegister(NickAlias *na) anope_override + void OnNickRegister(User *, NickAlias *na) anope_override { if (!this->disable_register_reason.empty() || !this->ldap) return; diff --git a/modules/extra/m_ldap_oper.cpp b/modules/extra/m_ldap_oper.cpp index afe3fde48..4324a7bc0 100644 --- a/modules/extra/m_ldap_oper.cpp +++ b/modules/extra/m_ldap_oper.cpp @@ -1,5 +1,5 @@ #include "module.h" -#include "ldap.h" +#include "ldapapi.h" static std::set<Oper *> my_opers; static Anope::string opertype_attribute; @@ -93,13 +93,15 @@ class LDAPOper : public Module ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override + void OnReload(Configuration::Conf *conf) anope_override { - this->binddn = reader.ReadValue("m_ldap_oper", "binddn", "", 0); - this->password = reader.ReadValue("m_ldap_oper", "password", "", 0); - this->basedn = reader.ReadValue("m_ldap_oper", "basedn", "", 0); - this->filter = reader.ReadValue("m_ldap_oper", "filter", "", 0); - opertype_attribute = reader.ReadValue("m_ldap_oper", "opertype_attribute", "", 0); + Configuration::Block *config = Config->GetModule(this); + + this->binddn = config->Get<const Anope::string &>("binddn"); + this->password = config->Get<const Anope::string &>("password"); + this->basedn = config->Get<const Anope::string &>("basedn"); + this->filter = config->Get<const Anope::string &>("filter"); + opertype_attribute = config->Get<const Anope::string &>("opertype_attribute"); for (std::set<Oper *>::iterator it = my_opers.begin(), it_end = my_opers.end(); it != it_end; ++it) delete *it; diff --git a/modules/extra/m_mysql.cpp b/modules/extra/m_mysql.cpp index c41ba37a8..372cb6982 100644 --- a/modules/extra/m_mysql.cpp +++ b/modules/extra/m_mysql.cpp @@ -188,8 +188,9 @@ class ModuleSQL : public Module, public Pipe delete DThread; } - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override + void OnReload(Configuration::Conf *conf) anope_override { + Configuration::Block *config = Config->GetModule(this); int i, num; for (std::map<Anope::string, MySQLService *>::iterator it = this->MySQLServices.begin(); it != this->MySQLServices.end();) @@ -198,13 +199,9 @@ class ModuleSQL : public Module, public Pipe MySQLService *s = it->second; ++it; - for (i = 0, num = reader.Enumerate("mysql"); i < num; ++i) - { - if (reader.ReadValue("mysql", "name", "main", i) == cname) - { + for (i = 0; i < Config->CountBlock("mysql"); ++i) + if (Config->GetBlock("mysql", i)->Get<const Anope::string &>("name", "main") == cname) break; - } - } if (i == num) { @@ -215,17 +212,18 @@ class ModuleSQL : public Module, public Pipe } } - for (i = 0, num = reader.Enumerate("mysql"); i < num; ++i) + for (i = 0; i < Config->CountBlock("mysql"); ++i) { - Anope::string connname = reader.ReadValue("mysql", "name", "mysql/main", i); + Configuration::Block *block = Config->GetBlock("mysql", i); + const Anope::string &connname = block->Get<const Anope::string &>("name", "mysql/main"); if (this->MySQLServices.find(connname) == this->MySQLServices.end()) { - Anope::string database = reader.ReadValue("mysql", "database", "anope", i); - Anope::string server = reader.ReadValue("mysql", "server", "127.0.0.1", i); - Anope::string user = reader.ReadValue("mysql", "username", "anope", i); - Anope::string password = reader.ReadValue("mysql", "password", "", i); - int port = reader.ReadInteger("mysql", "port", "3306", i, true); + const Anope::string &database = block->Get<const Anope::string &>("database", "anope"); + const Anope::string &server = block->Get<const Anope::string &>("server", "127.0.0.1"); + const Anope::string &user = block->Get<const Anope::string &>("username", "anope"); + const Anope::string &password = block->Get<const Anope::string &>("password"); + int port = block->Get<int>("port", "3306"); try { diff --git a/modules/extra/m_proxyscan.cpp b/modules/extra/m_proxyscan.cpp index 9dd3f8884..c77f0f9cd 100644 --- a/modules/extra/m_proxyscan.cpp +++ b/modules/extra/m_proxyscan.cpp @@ -86,7 +86,7 @@ class ProxyConnect : public ConnectionSocket reason = reason.replace_all_cs("%p", stringify(this->conaddr.port())); Log(OperServ) << "PROXYSCAN: Open " << this->GetType() << " proxy found on " << this->conaddr.addr() << ":" << this->conaddr.port() << " (" << reason << ")"; - XLine *x = new XLine("*@" + this->conaddr.addr(), Config->OperServ, Anope::CurTime + this->proxy.duration, reason, XLineManager::GenerateUID()); + XLine *x = new XLine("*@" + this->conaddr.addr(), OperServ ? OperServ->nick : "", Anope::CurTime + this->proxy.duration, reason, XLineManager::GenerateUID()); if (add_to_akill && akills) { akills->AddXLine(x); @@ -253,34 +253,36 @@ class ModuleProxyScan : public Module delete this->listener; } - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override + void OnReload(Configuration::Conf *conf) anope_override { - Anope::string s_target_ip = reader.ReadValue("m_proxyscan", "target_ip", "", 0); + Configuration::Block *config = Config->GetModule(this); + + Anope::string s_target_ip = config->Get<const Anope::string &>("target_ip"); if (s_target_ip.empty()) - throw ConfigException("m_proxyscan:target_ip may not be empty"); + throw ConfigException(this->name + " target_ip may not be empty"); - int s_target_port = reader.ReadInteger("m_proxyscan", "target_port", "-1", 0, true); + int s_target_port = config->Get<int>("target_port", "-1"); if (s_target_port <= 0) - throw ConfigException("m_proxyscan:target_port may not be empty and must be a positive number"); + throw ConfigException(this->name + " target_port may not be empty and must be a positive number"); - Anope::string s_listen_ip = reader.ReadValue("m_proxyscan", "listen_ip", "", 0); + Anope::string s_listen_ip = config->Get<const Anope::string &>("listen_ip"); if (s_listen_ip.empty()) - throw ConfigException("m_proxyscan:listen_ip may not be empty"); + throw ConfigException(this->name + " listen_ip may not be empty"); - int s_listen_port = reader.ReadInteger("m_proxyscan", "listen_port", "-1", 0, true); + int s_listen_port = config->Get<int>("listen_port", "-1"); if (s_listen_port <= 0) - throw ConfigException("m_proxyscan:listen_port may not be empty and must be a positive number"); + throw ConfigException(this->name + " listen_port may not be empty and must be a positive number"); target_ip = s_target_ip; target_port = s_target_port; this->listen_ip = s_listen_ip; this->listen_port = s_listen_port; - this->con_notice = reader.ReadValue("m_proxyscan", "connect_notice", "", 0); - this->con_source = reader.ReadValue("m_proxyscan", "connect_source", "", 0); - add_to_akill = reader.ReadFlag("m_proxyscan", "add_to_akill", "true", 0); - this->connectionTimeout.SetSecs(reader.ReadInteger("m_proxyscan", "timeout", "5", 0, true)); + this->con_notice = config->Get<const Anope::string &>("connect_notice"); + this->con_source = config->Get<const Anope::string &>("connect_source"); + add_to_akill = config->Get<bool>("add_to_akill", "true"); + this->connectionTimeout.SetSecs(config->Get<time_t>("timeout", "5s")); - ProxyCheckString = Config->NetworkName + " proxy check"; + ProxyCheckString = Config->GetBlock("networkinfo")->Get<const Anope::string &>("networkname") + " proxy check"; delete this->listener; this->listener = NULL; try @@ -293,12 +295,13 @@ class ModuleProxyScan : public Module } this->proxyscans.clear(); - for (int i = 0; i < reader.Enumerate("proxyscan"); ++i) + for (int i = 0; i < conf->CountBlock("proxyscan"); ++i) { + Configuration::Block *block = conf->GetBlock("proxyscan", i); ProxyCheck p; Anope::string token; - commasepstream sep(reader.ReadValue("proxyscan", "type", "", i)); + commasepstream sep(block->Get<const Anope::string &>("type")); while (sep.GetToken(token)) { if (!token.equals_ci("HTTP") && !token.equals_ci("SOCKS5")) @@ -308,7 +311,7 @@ class ModuleProxyScan : public Module if (p.types.empty()) continue; - commasepstream sep2(reader.ReadValue("proxyscan", "port", "", i)); + commasepstream sep2(block->Get<const Anope::string &>("port")); while (sep2.GetToken(token)) { try @@ -321,8 +324,8 @@ class ModuleProxyScan : public Module if (p.ports.empty()) continue; - p.duration = Anope::DoTime(reader.ReadValue("proxyscan", "time", "4h", i)); - p.reason = reader.ReadValue("proxyscan", "reason", "", i); + p.duration = block->Get<time_t>("time", "4h"); + p.reason = block->Get<const Anope::string &>("reason"); if (p.reason.empty()) continue; diff --git a/modules/extra/m_sql_authentication.cpp b/modules/extra/m_sql_authentication.cpp index 027b0bbcc..98fd4c2e9 100644 --- a/modules/extra/m_sql_authentication.cpp +++ b/modules/extra/m_sql_authentication.cpp @@ -2,6 +2,7 @@ #include "sql.h" static Module *me; +static ServiceReference<NickServService> nickserv("NickServService", "NickServ"); class SQLAuthenticationResult : public SQL::Interface { @@ -41,14 +42,9 @@ class SQLAuthenticationResult : public SQL::Interface if (na == NULL) { na = new NickAlias(req->GetAccount(), new NickCore(req->GetAccount())); - if (user) - { - if (Config->NSAddAccessOnReg) - na->nc->AddAccess(user->Mask()); - - if (NickServ) - user->SendMessage(NickServ, _("Your account \002%s\002 has been successfully created."), na->nick.c_str()); - } + FOREACH_MOD(I_OnNickRegister, OnNickRegister(user, na)); + if (user && nickserv) + user->SendMessage(NickServ, _("Your account \002%s\002 has been successfully created."), na->nick.c_str()); } if (!email.empty() && email != na->nc->email) @@ -80,18 +76,18 @@ class ModuleSQLAuthentication : public Module public: ModuleSQLAuthentication(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR) { - me = this; Implementation i[] = { I_OnReload, I_OnPreCommand, I_OnCheckAuthentication }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override + void OnReload(Configuration::Conf *conf) anope_override { - this->engine = reader.ReadValue("m_sql_authentication", "engine", "", 0); - this->query = reader.ReadValue("m_sql_authentication", "query", "", 0); - this->disable_reason = reader.ReadValue("m_sql_authentication", "disable_reason", "", 0); + Configuration::Block *config = conf->GetModule(this); + this->engine = config->Get<const Anope::string &>("engine"); + this->query = config->Get<const Anope::string &>("query"); + this->disable_reason = config->Get<const Anope::string &>("disable_reason"); this->SQL = ServiceReference<SQL::Provider>("SQL::Provider", this->engine); } diff --git a/modules/extra/m_sql_oper.cpp b/modules/extra/m_sql_oper.cpp index 4f982e1d8..480bcf5a0 100644 --- a/modules/extra/m_sql_oper.cpp +++ b/modules/extra/m_sql_oper.cpp @@ -101,10 +101,12 @@ class ModuleSQLOper : public Module ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override + void OnReload(Configuration::Conf *conf) anope_override { - this->engine = reader.ReadValue("m_sql_oper", "engine", "", 0); - this->query = reader.ReadValue("m_sql_oper", "query", "", 0); + Configuration::Block *config = conf->GetModule(this); + + this->engine = config->Get<const Anope::string &>("engine"); + this->query = config->Get<const Anope::string &>("query"); this->SQL = ServiceReference<SQL::Provider>("SQL::Provider", this->engine); } diff --git a/modules/extra/m_sqlite.cpp b/modules/extra/m_sqlite.cpp index 9626741a0..b0f947985 100644 --- a/modules/extra/m_sqlite.cpp +++ b/modules/extra/m_sqlite.cpp @@ -77,18 +77,19 @@ class ModuleSQLite : public Module SQLiteServices.clear(); } - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override + void OnReload(Configuration::Conf *conf) anope_override { - int i, num; + Configuration::Block *config = conf->GetModule(this); for (std::map<Anope::string, SQLiteService *>::iterator it = this->SQLiteServices.begin(); it != this->SQLiteServices.end();) { const Anope::string &cname = it->first; SQLiteService *s = it->second; + int i, num; ++it; - for (i = 0, num = reader.Enumerate("sqlite"); i < num; ++i) - if (reader.ReadValue("sqlite", "name", "sqlite/main", i) == cname) + for (i = 0, num = config->CountBlock("sqlite"); i < num; ++i) + if (config->GetBlock("sqlite", i)->Get<const Anope::string &>("name", "sqlite/main") == cname) break; if (i == num) @@ -100,13 +101,14 @@ class ModuleSQLite : public Module } } - for (i = 0, num = reader.Enumerate("sqlite"); i < num; ++i) + for (int i = 0; i < config->CountBlock("sqlite"); ++i) { - Anope::string connname = reader.ReadValue("sqlite", "name", "sqlite/main", i); + Configuration::Block *block = config->GetBlock("sqlite", i); + Anope::string connname = block->Get<const Anope::string &>("name", "sqlite/main"); if (this->SQLiteServices.find(connname) == this->SQLiteServices.end()) { - Anope::string database = Anope::DataDir + "/" + reader.ReadValue("sqlite", "database", "anope", i); + Anope::string database = Anope::DataDir + "/" + block->Get<const Anope::string &>("database", "anope"); try { diff --git a/modules/extra/m_ssl.cpp b/modules/extra/m_ssl.cpp index 95de6694a..3219830e7 100644 --- a/modules/extra/m_ssl.cpp +++ b/modules/extra/m_ssl.cpp @@ -136,10 +136,12 @@ class SSLModule : public Module SSL_CTX_free(server_ctx); } - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override + void OnReload(Configuration::Conf *conf) anope_override { - this->certfile = reader.ReadValue("ssl", "cert", "data/anope.crt", 0); - this->keyfile = reader.ReadValue("ssl", "key", "data/anope.key", 0); + Configuration::Block *config = conf->GetModule(this); + + this->certfile = config->Get<const Anope::string &>("cert", "data/anope.crt"); + this->keyfile = config->Get<const Anope::string &>("key", "data/anope.key"); if (Anope::IsFile(this->certfile.c_str())) { @@ -182,9 +184,9 @@ class SSLModule : public Module void OnPreServerConnect() anope_override { - ConfigReader reader; + Configuration::Block *config = Config->GetBlock("uplink", Anope::CurrentUplink); - if (reader.ReadFlag("uplink", "ssl", "no", Anope::CurrentUplink)) + if (config->Get<bool>("ssl")) { this->service.Init(UplinkSock); } diff --git a/modules/extra/m_xmlrpc_main.cpp b/modules/extra/m_xmlrpc_main.cpp index 0ba748f0b..8016d620e 100644 --- a/modules/extra/m_xmlrpc_main.cpp +++ b/modules/extra/m_xmlrpc_main.cpp @@ -239,14 +239,15 @@ class MyXMLRPCEvent : public XMLRPCEvent void DoOperType(XMLRPCServiceInterface *iface, HTTPClient *client, XMLRPCRequest &request) { - for (std::list<OperType *>::const_iterator it = Config->MyOperTypes.begin(), it_end = Config->MyOperTypes.end(); it != it_end; ++it) + for (unsigned i = 0; i < Config->MyOperTypes.size(); ++i) { + OperType *ot = Config->MyOperTypes[i]; Anope::string perms; - for (std::list<Anope::string>::const_iterator it2 = (*it)->GetPrivs().begin(), it2_end = (*it)->GetPrivs().end(); it2 != it2_end; ++it2) + for (std::list<Anope::string>::const_iterator it2 = ot->GetPrivs().begin(), it2_end = ot->GetPrivs().end(); it2 != it2_end; ++it2) perms += " " + *it2; - for (std::list<Anope::string>::const_iterator it2 = (*it)->GetCommands().begin(), it2_end = (*it)->GetCommands().end(); it2 != it2_end; ++it2) + for (std::list<Anope::string>::const_iterator it2 = ot->GetCommands().begin(), it2_end = ot->GetCommands().end(); it2 != it2_end; ++it2) perms += " " + *it2; - request.reply((*it)->GetName(), perms); + request.reply(ot->GetName(), perms); } } }; diff --git a/modules/extra/webcpanel/pages/chanserv/access.cpp b/modules/extra/webcpanel/pages/chanserv/access.cpp index 33250035e..0df2ecfc1 100644 --- a/modules/extra/webcpanel/pages/chanserv/access.cpp +++ b/modules/extra/webcpanel/pages/chanserv/access.cpp @@ -44,7 +44,7 @@ bool WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::s params.push_back("DEL"); params.push_back(message.get_data["mask"]); - WebPanel::RunCommand(na->nc->display, na->nc, Config->ChanServ, "chanserv/access", params, replacements); + WebPanel::RunCommand(na->nc->display, na->nc, ::ChanServ->nick, "chanserv/access", params, replacements); } else if (message.post_data["mask"].empty() == false && message.post_data["access"].empty() == false && message.post_data["provider"].empty() == false) { @@ -75,8 +75,10 @@ bool WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::s } } - if (ci->GetAccessCount() >= Config->CSAccessMax) - replacements["MESSAGES"] = "Sorry, you can only have " + stringify(Config->CSAccessMax) + " access entries on a channel."; + + unsigned access_max = Config->GetModule("chanserv")->Get<unsigned>("accessmax", "1024"); + if (access_max && ci->GetAccessCount() >= access_max) + replacements["MESSAGES"] = "Sorry, you can only have " + stringify(access_max) + " access entries on a channel."; else if (!denied) { ChanAccess *new_acc = a->Create(); diff --git a/modules/extra/webcpanel/pages/chanserv/akick.cpp b/modules/extra/webcpanel/pages/chanserv/akick.cpp index 95fb8fb30..06aede8e7 100644 --- a/modules/extra/webcpanel/pages/chanserv/akick.cpp +++ b/modules/extra/webcpanel/pages/chanserv/akick.cpp @@ -40,7 +40,7 @@ bool WebCPanel::ChanServ::Akick::OnRequest(HTTPProvider *server, const Anope::st params.push_back("DEL"); params.push_back(message.get_data["mask"]); - WebPanel::RunCommand(na->nc->display, na->nc, Config->ChanServ, "chanserv/akick", params, replacements); + WebPanel::RunCommand(na->nc->display, na->nc, ::ChanServ->nick, "chanserv/akick", params, replacements); } else if (message.post_data["mask"].empty() == false) { @@ -51,7 +51,7 @@ bool WebCPanel::ChanServ::Akick::OnRequest(HTTPProvider *server, const Anope::st if (message.post_data["reason"].empty() == false) params.push_back(message.get_data["reason"]); - WebPanel::RunCommand(na->nc->display, na->nc, Config->ChanServ, "chanserv/akick", params, replacements); + WebPanel::RunCommand(na->nc->display, na->nc, ::ChanServ->nick, "chanserv/akick", params, replacements); } replacements["ESCAPED_CHANNEL"] = HTTPUtils::URLEncode(chname); diff --git a/modules/extra/webcpanel/pages/chanserv/drop.cpp b/modules/extra/webcpanel/pages/chanserv/drop.cpp index 5462aa131..f18700651 100644 --- a/modules/extra/webcpanel/pages/chanserv/drop.cpp +++ b/modules/extra/webcpanel/pages/chanserv/drop.cpp @@ -21,7 +21,7 @@ bool WebCPanel::ChanServ::Drop::OnRequest(HTTPProvider *server, const Anope::str std::vector<Anope::string> params; params.push_back(HTTPUtils::URLDecode(message.post_data["channel"])); - WebPanel::RunCommand(na->nc->display, na->nc, Config->ChanServ, "chanserv/drop", params, replacements); + WebPanel::RunCommand(na->nc->display, na->nc, ::ChanServ->nick, "chanserv/drop", params, replacements); } else replacements["MESSAGES"] = "Invalid Confirmation"; } diff --git a/modules/extra/webcpanel/pages/confirm.cpp b/modules/extra/webcpanel/pages/confirm.cpp index 1f5d61cc1..ab86ee5c9 100644 --- a/modules/extra/webcpanel/pages/confirm.cpp +++ b/modules/extra/webcpanel/pages/confirm.cpp @@ -21,7 +21,7 @@ bool WebCPanel::Confirm::OnRequest(HTTPProvider *server, const Anope::string &pa if (!email.empty()) params.push_back(email); - WebPanel::RunCommand(user, NULL, Config->NickServ, "nickserv/register", params, replacements); + WebPanel::RunCommand(user, NULL, ::NickServ->nick, "nickserv/register", params, replacements); } TemplateFileServer page("confirm.html"); diff --git a/modules/extra/webcpanel/pages/hostserv/request.cpp b/modules/extra/webcpanel/pages/hostserv/request.cpp index 6335b1a56..30a396a9b 100644 --- a/modules/extra/webcpanel/pages/hostserv/request.cpp +++ b/modules/extra/webcpanel/pages/hostserv/request.cpp @@ -18,7 +18,7 @@ bool WebCPanel::HostServ::Request::OnRequest(HTTPProvider *server, const Anope:: std::vector<Anope::string> params; params.push_back(HTTPUtils::URLDecode(message.post_data["req"])); - WebPanel::RunCommand(na->nc->display, na->nc, Config->HostServ, "hostserv/request", params, replacements, "CMDR"); + WebPanel::RunCommand(na->nc->display, na->nc, ::HostServ->nick, "hostserv/request", params, replacements, "CMDR"); } if (na->HasVhost()) diff --git a/modules/extra/webcpanel/pages/memoserv/memos.cpp b/modules/extra/webcpanel/pages/memoserv/memos.cpp index 671820ced..9324bea56 100644 --- a/modules/extra/webcpanel/pages/memoserv/memos.cpp +++ b/modules/extra/webcpanel/pages/memoserv/memos.cpp @@ -57,7 +57,7 @@ bool WebCPanel::MemoServ::Memos::OnRequest(HTTPProvider *server, const Anope::st params.push_back(HTTPUtils::URLDecode(message.post_data["receiver"])); params.push_back(HTTPUtils::URLDecode(message.post_data["message"])); - WebPanel::RunCommand(na->nc->display, na->nc, Config->MemoServ, "memoserv/send", params, replacements, "CMDR"); + WebPanel::RunCommand(na->nc->display, na->nc, ::MemoServ->nick, "memoserv/send", params, replacements, "CMDR"); } if (message.get_data.count("del") > 0 && message.get_data.count("number") > 0) { @@ -66,7 +66,7 @@ bool WebCPanel::MemoServ::Memos::OnRequest(HTTPProvider *server, const Anope::st params.push_back(chname); params.push_back(message.get_data["number"]); - WebPanel::RunCommand(na->nc->display, na->nc, Config->MemoServ, "memoserv/del", params, replacements, "CMDR"); + WebPanel::RunCommand(na->nc->display, na->nc, ::MemoServ->nick, "memoserv/del", params, replacements, "CMDR"); } if (message.get_data.count("read") > 0 && message.get_data.count("number") > 0) { diff --git a/modules/extra/webcpanel/pages/nickserv/access.cpp b/modules/extra/webcpanel/pages/nickserv/access.cpp index de0e544f7..41dc0f429 100644 --- a/modules/extra/webcpanel/pages/nickserv/access.cpp +++ b/modules/extra/webcpanel/pages/nickserv/access.cpp @@ -19,7 +19,7 @@ bool WebCPanel::NickServ::Access::OnRequest(HTTPProvider *server, const Anope::s params.push_back("ADD"); params.push_back(message.post_data["access"]); - WebPanel::RunCommand(na->nc->display, na->nc, Config->NickServ, "nickserv/access", params, replacements); + WebPanel::RunCommand(na->nc->display, na->nc, ::NickServ->nick, "nickserv/access", params, replacements); } else if (message.get_data.count("del") > 0 && message.get_data.count("mask") > 0) { @@ -27,7 +27,7 @@ bool WebCPanel::NickServ::Access::OnRequest(HTTPProvider *server, const Anope::s params.push_back("DEL"); params.push_back(message.get_data["mask"]); - WebPanel::RunCommand(na->nc->display, na->nc, Config->NickServ, "nickserv/access", params, replacements); + WebPanel::RunCommand(na->nc->display, na->nc, ::NickServ->nick, "nickserv/access", params, replacements); } for (unsigned i = 0; i < na->nc->access.size(); ++i) diff --git a/modules/extra/webcpanel/pages/nickserv/cert.cpp b/modules/extra/webcpanel/pages/nickserv/cert.cpp index fc13e2ce5..44849a302 100644 --- a/modules/extra/webcpanel/pages/nickserv/cert.cpp +++ b/modules/extra/webcpanel/pages/nickserv/cert.cpp @@ -19,7 +19,7 @@ bool WebCPanel::NickServ::Cert::OnRequest(HTTPProvider *server, const Anope::str params.push_back("ADD"); params.push_back(message.post_data["certfp"]); - WebPanel::RunCommand(na->nc->display, na->nc, Config->NickServ, "nickserv/cert", params, replacements); + WebPanel::RunCommand(na->nc->display, na->nc, ::NickServ->nick, "nickserv/cert", params, replacements); } else if (message.get_data.count("del") > 0 && message.get_data.count("mask") > 0) { @@ -27,7 +27,7 @@ bool WebCPanel::NickServ::Cert::OnRequest(HTTPProvider *server, const Anope::str params.push_back("DEL"); params.push_back(message.get_data["mask"]); - WebPanel::RunCommand(na->nc->display, na->nc, Config->NickServ, "nickserv/cert", params, replacements); + WebPanel::RunCommand(na->nc->display, na->nc, ::NickServ->nick, "nickserv/cert", params, replacements); } for (unsigned i = 0; i < na->nc->cert.size(); ++i) diff --git a/modules/extra/webcpanel/pages/operserv/akill.cpp b/modules/extra/webcpanel/pages/operserv/akill.cpp index 87b8f94fb..ae9824bce 100644 --- a/modules/extra/webcpanel/pages/operserv/akill.cpp +++ b/modules/extra/webcpanel/pages/operserv/akill.cpp @@ -34,7 +34,7 @@ bool WebCPanel::OperServ::Akill::OnRequest(HTTPProvider *server, const Anope::st cmdstr << " " << HTTPUtils::URLDecode(message.post_data["mask"]); cmdstr << " " << HTTPUtils::URLDecode(message.post_data["reason"]); params.push_back(cmdstr.str()); - WebPanel::RunCommand(na->nc->display, na->nc, Config->OperServ, "operserv/akill", params, replacements); + WebPanel::RunCommand(na->nc->display, na->nc, ::OperServ->nick, "operserv/akill", params, replacements); } if (message.get_data["del"] == "1" && message.get_data.count("number") > 0) @@ -42,7 +42,7 @@ bool WebCPanel::OperServ::Akill::OnRequest(HTTPProvider *server, const Anope::st std::vector<Anope::string> params; params.push_back("DEL"); params.push_back(HTTPUtils::URLDecode(message.get_data["number"])); - WebPanel::RunCommand(na->nc->display, na->nc, Config->OperServ, "operserv/akill", params, replacements); + WebPanel::RunCommand(na->nc->display, na->nc, ::OperServ->nick, "operserv/akill", params, replacements); } for (unsigned i = 0, end = akills->GetCount(); i < end; ++i) diff --git a/modules/extra/webcpanel/pages/register.cpp b/modules/extra/webcpanel/pages/register.cpp index 409069348..730db612d 100644 --- a/modules/extra/webcpanel/pages/register.cpp +++ b/modules/extra/webcpanel/pages/register.cpp @@ -13,7 +13,7 @@ bool WebCPanel::Register::OnRequest(HTTPProvider *server, const Anope::string &p replacements["TITLE"] = page_title; - if (!Config->NSForceEmail) + if (!Config->GetModule("nickserv")->Get<bool>("forceemail", "yes")) replacements["EMAIL_TYPE"] = "hidden"; TemplateFileServer page("register.html"); diff --git a/modules/extra/webcpanel/webcpanel.cpp b/modules/extra/webcpanel/webcpanel.cpp index e2a026559..ca0b2f93d 100644 --- a/modules/extra/webcpanel/webcpanel.cpp +++ b/modules/extra/webcpanel/webcpanel.cpp @@ -45,19 +45,19 @@ class ModuleWebCPanel : public Module panel(this, "webcpanel"), style_css("style.css", "/static/style.css", "text/css"), logo_png("logo.png", "/static/logo.png", "image/png"), favicon_ico("favicon.ico", "/favicon.ico", "image/x-icon"), index("/"), logout("/logout"), _register("/register"), confirm("/confirm"), - nickserv_info(Config->NickServ, "/nickserv/info"), nickserv_cert(Config->NickServ, "/nickserv/cert"), nickserv_access(Config->NickServ, "/nickserv/access"), nickserv_alist(Config->NickServ, "/nickserv/alist"), - chanserv_info(Config->ChanServ, "/chanserv/info"), chanserv_set(Config->ChanServ, "/chanserv/set"), chanserv_access(Config->ChanServ, "/chanserv/access"), chanserv_akick(Config->ChanServ, "/chanserv/akick"), - chanserv_drop(Config->ChanServ, "/chanserv/drop"), memoserv_memos(Config->MemoServ, "/memoserv/memos"), hostserv_request(Config->HostServ, "/hostserv/request"), operserv_akill(Config->OperServ, "/operserv/akill") + nickserv_info("NickServ", "/nickserv/info"), nickserv_cert("NickServ", "/nickserv/cert"), nickserv_access("NickServ", "/nickserv/access"), nickserv_alist("NickServ", "/nickserv/alist"), + chanserv_info("ChanServ", "/chanserv/info"), chanserv_set("ChanServ", "/chanserv/set"), chanserv_access("ChanServ", "/chanserv/access"), chanserv_akick("ChanServ", "/chanserv/akick"), + chanserv_drop("ChanServ", "/chanserv/drop"), memoserv_memos("MemoServ", "/memoserv/memos"), hostserv_request("HostServ", "/hostserv/request"), operserv_akill("OperServ", "/operserv/akill") { me = this; - ConfigReader reader; - provider_name = reader.ReadValue("webcpanel", "server", "httpd/main", 0); - template_name = reader.ReadValue("webcpanel", "template", "template", 0); + Configuration::Block *block = Config->GetModule(this); + provider_name = block->Get<const Anope::string &>("server", "httpd/main"); + template_name = block->Get<const Anope::string &>("template", "default"); template_base = Anope::DataDir + "/modules/webcpanel/templates/" + template_name; - page_title = reader.ReadValue("webcpanel", "title", "Anope IRC Services", 0); - use_ssl = reader.ReadFlag("webcpanel", "ssl", "no", 0); // This is dumb, is there a better way to do this? + page_title = block->Get<const Anope::string &>("title", "Anope IRC Services"); + use_ssl = block->Get<bool>("ssl", "no"); // This is dumb, is there a better way to do this? ServiceReference<HTTPProvider> provider("HTTPProvider", provider_name); if (!provider) @@ -72,10 +72,10 @@ class ModuleWebCPanel : public Module provider->RegisterPage(&this->_register); provider->RegisterPage(&this->confirm); - if (Config->NickServ.empty() == false) + if (NickServ) { Section s; - s.name = Config->NickServ; + s.name = NickServ->nick; SubSection ss; ss.name = "Information"; @@ -103,10 +103,11 @@ class ModuleWebCPanel : public Module panel.sections.push_back(s); } - if (Config->ChanServ.empty() == false) + + if (ChanServ) { Section s; - s.name = Config->ChanServ; + s.name = ChanServ->nick; SubSection ss; ss.name = "Channels"; @@ -137,10 +138,10 @@ class ModuleWebCPanel : public Module panel.sections.push_back(s); } - if (Config->MemoServ.empty() == false) + if (MemoServ) { Section s; - s.name = Config->MemoServ; + s.name = MemoServ->nick; SubSection ss; ss.name = "Memos"; @@ -151,10 +152,10 @@ class ModuleWebCPanel : public Module panel.sections.push_back(s); } - if (Config->HostServ.empty() == false) + if (HostServ) { Section s; - s.name = Config->HostServ; + s.name = HostServ->nick; SubSection ss; ss.name = "vHost Request"; @@ -165,10 +166,10 @@ class ModuleWebCPanel : public Module panel.sections.push_back(s); } - if (Config->OperServ.empty() == false) + if (OperServ) { Section s; - s.name = Config->OperServ; + s.name = OperServ->nick; SubSection ss; ss.name = "Akill"; diff --git a/modules/ldap.h b/modules/ldapapi.h index 65be27687..65be27687 100644 --- a/modules/ldap.h +++ b/modules/ldapapi.h diff --git a/modules/m_dns.cpp b/modules/m_dns.cpp index e8f3bd758..af16e3be3 100644 --- a/modules/m_dns.cpp +++ b/modules/m_dns.cpp @@ -940,16 +940,17 @@ class ModuleDNS : public Module ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override + void OnReload(Configuration::Conf *conf) anope_override { - - nameserver = reader.ReadValue("dns", "nameserver", "127.0.0.1", 0); - timeout = Anope::DoTime(reader.ReadValue("dns", "timeout", "5", 0)); - ip = reader.ReadValue("dns", "ip", "0.0.0.0", 0); - port = reader.ReadInteger("dns", "port", "53", 0, false); - admin = reader.ReadValue("dns", "admin", "admin@example.com", 0); - nameservers = reader.ReadValue("dns", "nameservers", "ns1.example.com", 0); - refresh = reader.ReadInteger("dns", "refresh", "3600", 0, false); + Configuration::Block *block = conf->GetModule(this); + + nameserver = block->Get<const Anope::string &>("nameserver", "127.0.0.1"); + timeout = block->Get<time_t>("timeout", "5"); + ip = block->Get<const Anope::string &>("ip", "0.0.0.0"); + port = block->Get<int>("port", "53"); + admin = block->Get<const Anope::string &>("admin", "admin@example.com"); + nameservers = block->Get<const Anope::string &>("nameservers", "ns1.example.com"); + refresh = block->Get<int>("refresh", "3600"); if (Anope::IsFile(nameserver)) { diff --git a/modules/m_dnsbl.cpp b/modules/m_dnsbl.cpp index bf7c02fa0..5b46410d0 100644 --- a/modules/m_dnsbl.cpp +++ b/modules/m_dnsbl.cpp @@ -63,10 +63,10 @@ class DNSBLResolver : public Request reason = reason.replace_all_cs("%h", user->host); reason = reason.replace_all_cs("%i", user->ip); reason = reason.replace_all_cs("%r", record_reason); - reason = reason.replace_all_cs("%N", Config->NetworkName); + reason = reason.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string &>("networkname")); Log(OperServ) << "DNSBL: " << user->GetMask() << " (" << user->ip << ") appears in " << this->blacklist.name; - XLine *x = new XLine("*@" + user->ip, Config->OperServ, Anope::CurTime + this->blacklist.bantime, reason, XLineManager::GenerateUID()); + XLine *x = new XLine("*@" + user->ip, OperServ ? OperServ->nick : "m_dnsbl", Anope::CurTime + this->blacklist.bantime, reason, XLineManager::GenerateUID()); if (this->add_to_akill && akills) { akills->AddXLine(x); @@ -95,27 +95,27 @@ class ModuleDNSBL : public Module ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override + void OnReload(Configuration::Conf *conf) anope_override { - this->check_on_connect = reader.ReadFlag("m_dnsbl", "check_on_connect", "no", 0); - this->check_on_netburst = reader.ReadFlag("m_dnsbl", "check_on_netburst", "no", 0); - this->add_to_akill = reader.ReadFlag("m_dnsbl", "add_to_akill", "yes", 0); + Configuration::Block *block = conf->GetModule(this); + this->check_on_connect = block->Get<bool>("check_on_connect"); + this->check_on_netburst = block->Get<bool>("check_on_netburst"); + this->add_to_akill = block->Get<bool>("add_to_akill", "yes"); this->blacklists.clear(); - for (int i = 0, num = reader.Enumerate("blacklist"); i < num; ++i) + for (int i = 0, num = conf->CountBlock("blacklist"); i < num; ++i) { - Anope::string bname = reader.ReadValue("blacklist", "name", "", i); + Configuration::Block *bl = conf->GetBlock("blacklist", i); + + Anope::string bname = bl->Get<const Anope::string &>("name"); if (bname.empty()) continue; - Anope::string sbantime = reader.ReadValue("blacklist", "time", "4h", i); - time_t bantime = Anope::DoTime(sbantime); - if (bantime < 0) - bantime = 9000; - Anope::string reason = reader.ReadValue("blacklist", "reason", "", i); + time_t bantime = bl->Get<time_t>("time", "4h"); + Anope::string reason = bl->Get<const Anope::string &>("reason"); std::map<int, Anope::string> replies; for (int j = 0; j < 256; ++j) { - Anope::string k = reader.ReadValue("blacklist", stringify(j), "", i); + Anope::string k = bl->Get<const Anope::string &>(stringify(j)); if (!k.empty()) replies[j] = k; } diff --git a/modules/m_helpchan.cpp b/modules/m_helpchan.cpp index d39b5afd9..4768fec71 100644 --- a/modules/m_helpchan.cpp +++ b/modules/m_helpchan.cpp @@ -9,18 +9,16 @@ class HelpChannel : public Module { - Anope::string HelpChan; - public: HelpChannel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR) { - Implementation i[] = { I_OnChannelModeSet, I_OnReload }; + Implementation i[] = { I_OnChannelModeSet }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, const Anope::string &mname, const Anope::string ¶m) anope_override { - if (mname == "OP" && c && c->ci && c->name.equals_ci(this->HelpChan)) + if (mname == "OP" && c && c->ci && c->name.equals_ci(Config->GetModule(this)->Get<const Anope::string &>("helpchannel"))) { User *u = User::Find(param); @@ -30,11 +28,6 @@ class HelpChannel : public Module return EVENT_CONTINUE; } - - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override - { - this->HelpChan = reader.ReadValue("m_helpchan", "helpchannel", "", 0); - } }; MODULE_INIT(HelpChannel) diff --git a/modules/m_rewrite.cpp b/modules/m_rewrite.cpp index fb7fe46ed..dfa8a9162 100644 --- a/modules/m_rewrite.cpp +++ b/modules/m_rewrite.cpp @@ -159,22 +159,23 @@ class ModuleRewrite : public Module ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override + void OnReload(Configuration::Conf *conf) anope_override { - Rewrite::rewrites.clear(); - for (int i = 0; i < reader.Enumerate("command"); ++i) + for (int i = 0; i < conf->CountBlock("command"); ++i) { - if (!reader.ReadFlag("command", "rewrite", "no", i)) + Configuration::Block *block = conf->GetBlock("command", i); + + if (!block->Get<bool>("rewrite")) continue; Rewrite rw; - rw.client = reader.ReadValue("command", "service", "", i); - rw.source_message = reader.ReadValue("command", "rewrite_source", "", i), - rw.target_message = reader.ReadValue("command", "rewrite_target", "", i); - rw.desc = reader.ReadValue("command", "rewrite_description", "", i); + rw.client = block->Get<const Anope::string &>("service"); + rw.source_message = block->Get<const Anope::string &>("rewrite_source"); + rw.target_message = block->Get<const Anope::string &>("rewrite_target"); + rw.desc = block->Get<const Anope::string &>("rewrite_description"); if (rw.client.empty() || rw.source_message.empty() || rw.target_message.empty()) continue; diff --git a/modules/ns_maxemail.cpp b/modules/ns_maxemail.cpp index 530ca5fe4..fc678e8a5 100644 --- a/modules/ns_maxemail.cpp +++ b/modules/ns_maxemail.cpp @@ -14,20 +14,20 @@ class NSMaxEmail : public Module { - int NSEmailMax; - bool CheckLimitReached(CommandSource &source, const Anope::string &email) { - if (this->NSEmailMax < 1 || email.empty()) + int NSEmailMax = Config->GetModule(this)->Get<int>("maxemails"); + + if (NSEmailMax < 1 || email.empty()) return false; - if (this->CountEmail(email, source.nc) < this->NSEmailMax) + if (this->CountEmail(email, source.nc) < NSEmailMax) return false; - if (this->NSEmailMax == 1) + if (NSEmailMax == 1) source.Reply(_("The given email address has reached its usage limit of 1 user.")); else - source.Reply(_("The given email address has reached its usage limit of %d users."), this->NSEmailMax); + source.Reply(_("The given email address has reached its usage limit of %d users."), NSEmailMax); return true; } @@ -53,14 +53,6 @@ class NSMaxEmail : public Module public: NSMaxEmail(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR) { - - Implementation i[] = { I_OnReload, I_OnPreCommand }; - ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - } - - void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override - { - this->NSEmailMax = reader.ReadInteger("ns_maxemail", "maxemails", "0", 0, false); } EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> ¶ms) anope_override diff --git a/modules/protocol/bahamut.cpp b/modules/protocol/bahamut.cpp index 458602d3b..6aa097433 100644 --- a/modules/protocol/bahamut.cpp +++ b/modules/protocol/bahamut.cpp @@ -79,9 +79,9 @@ class BahamutIRCdProto : public IRCDProto } /* SVSHOLD - set */ - void SendSVSHold(const Anope::string &nick) anope_override + void SendSVSHold(const Anope::string &nick, time_t time) anope_override { - UplinkSocket::Message(Me) << "SVSHOLD " << nick << " " << Config->NSReleaseTimeout << " :Being held for registered user"; + UplinkSocket::Message(Me) << "SVSHOLD " << nick << " " << time << " :Being held for registered user"; } /* SVSHOLD - release */ @@ -265,7 +265,7 @@ class BahamutIRCdProto : public IRCDProto void SendConnect() anope_override { - UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink]->password << " :TS"; + UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink].password << " :TS"; UplinkSocket::Message() << "CAPAB SSJOIN NOQUIT BURST UNCONNECT NICKIP TSMODE TS3"; SendServer(Me); /* diff --git a/modules/protocol/charybdis.cpp b/modules/protocol/charybdis.cpp index 374111f44..1fb017fef 100644 --- a/modules/protocol/charybdis.cpp +++ b/modules/protocol/charybdis.cpp @@ -11,6 +11,7 @@ #include "module.h" +static bool sasl = true; static Anope::string UplinkSID; static ServiceReference<IRCDProto> ratbox("IRCDProto", "ratbox"); @@ -64,7 +65,7 @@ class CharybdisProto : public IRCDProto void SendConnect() anope_override { - UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink]->password << " TS 6 :" << Me->GetSID(); + UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink].password << " TS 6 :" << Me->GetSID(); /* * Received: CAPAB :BAN CHW CLUSTER ENCAP EOPMOD EUID EX IE KLN * KNOCK MLOCK QS RSFNC SAVE SERVICES TB UNKLN @@ -128,12 +129,12 @@ class CharybdisProto : public IRCDProto << " " << newnick << " " << when << " " << u->timestamp; } - void SendSVSHold(const Anope::string &nick) + void SendSVSHold(const Anope::string &nick, time_t delay) anope_override { - UplinkSocket::Message(Me) << "ENCAP * NICKDELAY " << Config->NSReleaseTimeout << " " << nick; + UplinkSocket::Message(Me) << "ENCAP * NICKDELAY " << delay << " " << nick; } - void SendSVSHoldDel(const Anope::string &nick) + void SendSVSHoldDel(const Anope::string &nick) anope_override { UplinkSocket::Message(Me) << "ENCAP * NICKDELAY 0 " << nick; } @@ -183,7 +184,7 @@ struct IRCDMessageEncap : IRCDMessage * * Charybdis only accepts messages from SASL agents; these must have umode +S */ - if (params[1] == "SASL" && Config->NSSASL && params.size() == 6) + if (params[1] == "SASL" && sasl && params.size() == 6) { class CharybdisSASLIdentifyRequest : public IdentifyRequest { @@ -298,7 +299,7 @@ struct IRCDMessageServer : IRCDMessage if (params[1] != "1") return; new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], 1, params[2], UplinkSID); - IRCD->SendPing(Config->ServerName, params[0]); + IRCD->SendPing(Me->GetName(), params[0]); } }; @@ -350,6 +351,8 @@ class ProtoCharybdis : public Module IRCDMessagePass message_pass; IRCDMessageServer message_server; + bool use_server_side_mlock; + void AddModes() { /* Add user modes */ @@ -403,7 +406,7 @@ class ProtoCharybdis : public Module { - Implementation i[] = { I_OnChannelCreate, I_OnMLock, I_OnUnMLock }; + Implementation i[] = { I_OnReload, I_OnChannelCreate, I_OnMLock, I_OnUnMLock }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); if (ModuleManager::LoadModule("ratbox", User::Find(creator)) != MOD_ERR_OK) @@ -422,9 +425,15 @@ class ProtoCharybdis : public Module ModuleManager::UnloadModule(m_ratbox, NULL); } + void OnReload(Configuration::Conf *conf) anope_override + { + use_server_side_mlock = conf->GetModule(this)->Get<bool>("use_server_side_mlock"); + sasl = conf->GetModule(this)->Get<bool>("sasl"); + } + void OnChannelCreate(Channel *c) anope_override { - if (c->ci && Config->UseServerSideMLock && Servers::Capab.count("MLOCK") > 0) + if (use_server_side_mlock && c->ci && Servers::Capab.count("MLOCK") > 0) { Anope::string modes = c->ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", ""); UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(c->creation_time) << " " << c->ci->name << " " << modes; @@ -434,7 +443,7 @@ class ProtoCharybdis : public Module EventReturn OnMLock(ChannelInfo *ci, ModeLock *lock) anope_override { ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name); - if (cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0 && Config->UseServerSideMLock) + if (use_server_side_mlock && cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0) { Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "") + cm->mchar; UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes; @@ -446,7 +455,7 @@ class ProtoCharybdis : public Module EventReturn OnUnMLock(ChannelInfo *ci, ModeLock *lock) anope_override { ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name); - if (cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0 && Config->UseServerSideMLock) + if (use_server_side_mlock && cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0) { Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "").replace_all_cs(cm->mchar, ""); UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes; diff --git a/modules/protocol/hybrid.cpp b/modules/protocol/hybrid.cpp index a00158bf8..1a50b89a6 100644 --- a/modules/protocol/hybrid.cpp +++ b/modules/protocol/hybrid.cpp @@ -160,7 +160,7 @@ class HybridProto : public IRCDProto void SendConnect() anope_override { - UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink]->password << " TS 6 :" << Me->GetSID(); + UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink].password << " TS 6 :" << Me->GetSID(); /* * As of October 13, 2012, ircd-hybrid-8 does support the following capabilities @@ -249,9 +249,9 @@ class HybridProto : public IRCDProto UplinkSocket::Message(Me) << "SVSNICK " << u->nick << " " << newnick << " " << when; } - void SendSVSHold(const Anope::string &nick) anope_override + void SendSVSHold(const Anope::string &nick, time_t t) anope_override { - XLine x(nick, OperServ->nick, Anope::CurTime + Config->NSReleaseTimeout, "Being held for registered user"); + XLine x(nick, OperServ->nick, Anope::CurTime + t, "Being held for registered user"); this->SendSQLine(NULL, &x); } @@ -357,7 +357,7 @@ struct IRCDMessageServer : IRCDMessage new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], 1, params[2], UplinkSID); - IRCD->SendPing(Config->ServerName, params[0]); + IRCD->SendPing(Me->GetName(), params[0]); } }; @@ -372,7 +372,7 @@ struct IRCDMessageSID : IRCDMessage unsigned int hops = params[1].is_pos_number_only() ? convertTo<unsigned>(params[1]) : 0; new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], hops, params[3], params[2]); - IRCD->SendPing(Config->ServerName, params[0]); + IRCD->SendPing(Me->GetName(), params[0]); } }; @@ -608,12 +608,8 @@ public: ModuleManager::Attach(I_OnUserNickChange, this); - if (Config->Numeric.empty()) - { - Anope::string numeric = Servers::TS6_SID_Retrieve(); - Me->SetSID(numeric); - Config->Numeric = numeric; - } + if (Me->GetSID() == Me->GetName()) + Me->SetSID(Servers::TS6_SID_Retrieve()); for (botinfo_map::iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it) it->second->GenerateUID(); diff --git a/modules/protocol/inspircd11.cpp b/modules/protocol/inspircd11.cpp index eeb1e17e1..12a22e724 100644 --- a/modules/protocol/inspircd11.cpp +++ b/modules/protocol/inspircd11.cpp @@ -239,7 +239,7 @@ class InspIRCdProto : public IRCDProto void SendConnect() anope_override { - current_pass = Config->Uplinks[Anope::CurrentUplink]->password; + current_pass = Config->Uplinks[Anope::CurrentUplink].password; SendServer(Me); UplinkSocket::Message() << "BURST"; Module *enc = ModuleManager::FindFirstOf(ENCRYPTION); @@ -247,9 +247,9 @@ class InspIRCdProto : public IRCDProto } /* SVSHOLD - set */ - void SendSVSHold(const Anope::string &nick) anope_override + void SendSVSHold(const Anope::string &nick, time_t t) anope_override { - UplinkSocket::Message(OperServ) << "SVSHOLD " << nick << " " << Config->NSReleaseTimeout << "s :Being held for registered user"; + UplinkSocket::Message(OperServ) << "SVSHOLD " << nick << " " << t << "s :Being held for registered user"; } /* SVSHOLD - release */ @@ -790,7 +790,7 @@ struct IRCDMessageRSQuit : IRCDMessage Server *s; /* Horrible workaround to an insp bug (#) in how RSQUITs are sent - mark */ - if (params.size() > 1 && Config->ServerName.equals_cs(params[0])) + if (params.size() > 1 && params[0] == Me->GetName()) s = Server::Find(params[1]); else s = Server::Find(params[0]); diff --git a/modules/protocol/inspircd12.cpp b/modules/protocol/inspircd12.cpp index 80f21c3da..c3fa04b85 100644 --- a/modules/protocol/inspircd12.cpp +++ b/modules/protocol/inspircd12.cpp @@ -211,7 +211,7 @@ class InspIRCd12Proto : public IRCDProto /* SERVER services-dev.chatspike.net password 0 :Description here */ void SendServer(const Server *server) anope_override { - UplinkSocket::Message() << "SERVER " << server->GetName() << " " << Config->Uplinks[Anope::CurrentUplink]->password << " " << server->GetHops() << " " << server->GetSID() << " :" << server->GetDescription(); + UplinkSocket::Message() << "SERVER " << server->GetName() << " " << Config->Uplinks[Anope::CurrentUplink].password << " " << server->GetHops() << " " << server->GetSID() << " :" << server->GetDescription(); } /* JOIN */ @@ -270,13 +270,13 @@ class InspIRCd12Proto : public IRCDProto SendServer(Me); UplinkSocket::Message(Me) << "BURST"; Module *enc = ModuleManager::FindFirstOf(ENCRYPTION); - UplinkSocket::Message(Me) << "VERSION :Anope-" << Anope::Version() << " " << Config->ServerName << " :" << IRCD->GetProtocolName() << " - (" << (enc ? enc->name : "none") << ") -- " << Anope::VersionBuildString(); + UplinkSocket::Message(Me) << "VERSION :Anope-" << Anope::Version() << " " << Me->GetName() << " :" << IRCD->GetProtocolName() << " - (" << (enc ? enc->name : "none") << ") -- " << Anope::VersionBuildString(); } /* SVSHOLD - set */ - void SendSVSHold(const Anope::string &nick) anope_override + void SendSVSHold(const Anope::string &nick, time_t t) anope_override { - UplinkSocket::Message(NickServ) << "SVSHOLD " << nick << " " << Config->NSReleaseTimeout << " :Being held for registered user"; + UplinkSocket::Message(NickServ) << "SVSHOLD " << nick << " " << t << " :Being held for registered user"; } /* SVSHOLD - release */ @@ -929,7 +929,7 @@ struct IRCDMessageMetadata : IRCDMessage u->Login(nc); const NickAlias *user_na = NickAlias::Find(u->nick); - if (!Config->NoNicknameOwnership && user_na && user_na->nc == nc && user_na->nc->HasExt("UNCONFIRMED") == false) + if (!Config->GetBlock("options")->Get<bool>("nonicknameownership") && user_na && user_na->nc == nc && user_na->nc->HasExt("UNCONFIRMED") == false) u->SetMode(NickServ, "REGISTERED"); /* Sometimes a user connects, we send them the usual "this nickname is registered" mess (if @@ -1221,12 +1221,8 @@ class ProtoInspIRCd : public Module Servers::Capab.insert("NOQUIT"); - if (Config->Numeric.empty()) - { - Anope::string numeric = Servers::TS6_SID_Retrieve(); - Me->SetSID(numeric); - Config->Numeric = numeric; - } + if (Me->GetSID() == Me->GetName()) + Me->SetSID(Servers::TS6_SID_Retrieve()); for (botinfo_map::iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it) it->second->GenerateUID(); diff --git a/modules/protocol/inspircd20.cpp b/modules/protocol/inspircd20.cpp index 7b21c2b08..3884862d9 100644 --- a/modules/protocol/inspircd20.cpp +++ b/modules/protocol/inspircd20.cpp @@ -13,6 +13,7 @@ #include "module.h" +static bool sasl = true; static unsigned int spanningtree_proto_ver = 0; static ServiceReference<IRCDProto> insp12("IRCDProto", "inspircd12"); @@ -58,7 +59,7 @@ class InspIRCd20Proto : public IRCDProto void SendSQLineDel(const XLine *x) anope_override { insp12->SendSQLineDel(x); } void SendSQLine(User *u, const XLine *x) anope_override { insp12->SendSQLine(u, x); } void SendVhost(User *u, const Anope::string &vident, const Anope::string &vhost) anope_override { insp12->SendVhost(u, vident, vhost); } - void SendSVSHold(const Anope::string &nick) anope_override { insp12->SendSVSHold(nick); } + void SendSVSHold(const Anope::string &nick, time_t t) anope_override { insp12->SendSVSHold(nick, t); } void SendSVSHoldDel(const Anope::string &nick) anope_override { insp12->SendSVSHoldDel(nick); } void SendSZLineDel(const XLine *x) anope_override { insp12->SendSZLineDel(x); } void SendSZLine(User *u, const XLine *x) anope_override { insp12->SendSZLine(u, x); } @@ -367,8 +368,9 @@ struct IRCDMessageCapab : Message::Capab else if (module.find("m_rline.so") == 0) { Servers::Capab.insert("RLINE"); - if (!Config->RegexEngine.empty() && module.length() > 11 && Config->RegexEngine != module.substr(11)) - Log() << "Warning: InspIRCd is using regex engine " << module.substr(11) << ", but we have " << Config->RegexEngine << ". This may cause inconsistencies."; + const Anope::string ®exengine = Config->GetBlock("options")->Get<const Anope::string &>("regexengine"); + if (!regexengine.empty() && module.length() > 11 && regexengine != module.substr(11)) + Log() << "Warning: InspIRCd is using regex engine " << module.substr(11) << ", but we have " << regexengine << ". This may cause inconsistencies."; } else if (module.equals_cs("m_topiclock.so")) Servers::Capab.insert("TOPICLOCK"); @@ -502,8 +504,6 @@ struct IRCDMessageCapab : Message::Capab Log() << "CHGHOST missing, Usage disabled until module is loaded."; if (!Servers::Capab.count("CHGIDENT")) Log() << "CHGIDENT missing, Usage disabled until module is loaded."; - if (!Servers::Capab.count("TOPICLOCK") && Config->UseServerSideTopicLock) - Log() << "m_topiclock missing, server side topic locking disabled until module is loaded."; chmodes.clear(); umodes.clear(); @@ -549,7 +549,7 @@ struct IRCDMessageEncap : IRCDMessage u->SetRealname(params[3]); UplinkSocket::Message(u) << "FNAME " << params[3]; } - else if (Config->NSSASL && params[1] == "SASL" && params.size() == 6) + else if (sasl && params[1] == "SASL" && params.size() == 6) { class InspIRCDSASLIdentifyRequest : public IdentifyRequest { @@ -656,6 +656,8 @@ class ProtoInspIRCd : public Module IRCDMessageEncap message_encap; IRCDMessageFIdent message_fident; + bool use_server_side_topiclock, use_server_side_mlock; + void SendChannelMetadata(Channel *c, const Anope::string &metadataname, const Anope::string &value) { UplinkSocket::Message(Me) << "METADATA " << c->name << " " << metadataname << " :" << value; @@ -695,7 +697,7 @@ class ProtoInspIRCd : public Module throw ModuleException("No protocol interface for insp12"); ModuleManager::DetachAll(m_insp12); - Implementation i[] = { I_OnUserNickChange, I_OnChannelCreate, I_OnChanRegistered, I_OnDelChan, I_OnMLock, I_OnUnMLock, I_OnSetChannelOption }; + Implementation i[] = { I_OnReload, I_OnUserNickChange, I_OnChannelCreate, I_OnChanRegistered, I_OnDelChan, I_OnMLock, I_OnUnMLock, I_OnSetChannelOption }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } @@ -704,6 +706,13 @@ class ProtoInspIRCd : public Module ModuleManager::UnloadModule(m_insp12, NULL); } + void OnReload(Configuration::Conf *conf) anope_override + { + use_server_side_topiclock = conf->GetModule(this)->Get<bool>("use_server_side_topiclock"); + use_server_side_mlock = conf->GetModule(this)->Get<bool>("use_server_side_mlock"); + sasl = conf->GetModule(this)->Get<bool>("sasl"); + } + void OnUserNickChange(User *u, const Anope::string &) anope_override { u->RemoveModeInternal(ModeManager::FindUserModeByName("REGISTERED")); @@ -711,19 +720,18 @@ class ProtoInspIRCd : public Module void OnChannelCreate(Channel *c) anope_override { - if (c->ci && (Config->UseServerSideMLock || Config->UseServerSideTopicLock)) - this->OnChanRegistered(c->ci); + this->OnChanRegistered(c->ci); } void OnChanRegistered(ChannelInfo *ci) anope_override { - if (Config->UseServerSideMLock && ci->c) + if (use_server_side_mlock && ci->c) { Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", ""); SendChannelMetadata(ci->c, "mlock", modes); } - if (Config->UseServerSideTopicLock && Servers::Capab.count("TOPICLOCK") && ci->c) + if (use_server_side_topiclock && Servers::Capab.count("TOPICLOCK") && ci->c) { Anope::string on = ci->HasExt("TOPICLOCK") ? "1" : ""; SendChannelMetadata(ci->c, "topiclock", on); @@ -732,17 +740,17 @@ class ProtoInspIRCd : public Module void OnDelChan(ChannelInfo *ci) anope_override { - if (Config->UseServerSideMLock && ci->c) + if (use_server_side_mlock && ci->c) SendChannelMetadata(ci->c, "mlock", ""); - if (Config->UseServerSideTopicLock && Servers::Capab.count("TOPICLOCK") && ci->c) + if (use_server_side_topiclock && Servers::Capab.count("TOPICLOCK") && ci->c) SendChannelMetadata(ci->c, "topiclock", ""); } EventReturn OnMLock(ChannelInfo *ci, ModeLock *lock) anope_override { ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name); - if (cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Config->UseServerSideMLock) + if (use_server_side_mlock && cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM)) { Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "") + cm->mchar; SendChannelMetadata(ci->c, "mlock", modes); @@ -754,7 +762,7 @@ class ProtoInspIRCd : public Module EventReturn OnUnMLock(ChannelInfo *ci, ModeLock *lock) anope_override { ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name); - if (cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Config->UseServerSideMLock) + if (use_server_side_mlock && cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM)) { Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "").replace_all_cs(cm->mchar, ""); SendChannelMetadata(ci->c, "mlock", modes); @@ -767,7 +775,6 @@ class ProtoInspIRCd : public Module { if (cmd->name == "chanserv/topic" && ci->c) { - if (setting == "topiclock on") SendChannelMetadata(ci->c, "topiclock", "1"); else if (setting == "topiclock off") diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp index c749a2d7d..3d1a727e7 100644 --- a/modules/protocol/ngircd.cpp +++ b/modules/protocol/ngircd.cpp @@ -53,7 +53,7 @@ class ngIRCdProto : public IRCDProto void SendConnect() anope_override { - UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink]->password << " 0210-IRC+ Anope|" << Anope::VersionShort() << ":CLHMSo P"; + UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink].password << " 0210-IRC+ Anope|" << Anope::VersionShort() << ":CLHMSo P"; /* Make myself known to myself in the serverlist */ SendServer(Me); /* finish the enhanced server handshake and register the connection */ @@ -184,11 +184,10 @@ struct IRCDMessage005 : IRCDMessage } else if (parameter == "NICKLEN") { - unsigned newlen = convertTo<unsigned>(data); - if (Config->NickLen != newlen) + unsigned newlen = convertTo<unsigned>(data), len = Config->GetBlock("networkinfo")->Get<unsigned>("nicklen"); + if (len != newlen) { - Log() << "NickLen changed from " << Config->NickLen << " to " << newlen; - Config->NickLen = newlen; + Log() << "Warning: NICKLEN is " << newlen << " but networkinfo:nicklen is " << len; } } } @@ -540,7 +539,7 @@ struct IRCDMessageServer : IRCDMessage * when receiving a new server and then finish sync once we * get a pong back from that server. */ - IRCD->SendPing(Config->ServerName, params[0]); + IRCD->SendPing(Me->GetName(), params[0]); } }; diff --git a/modules/protocol/plexus.cpp b/modules/protocol/plexus.cpp index b256afc36..484f6a4bc 100644 --- a/modules/protocol/plexus.cpp +++ b/modules/protocol/plexus.cpp @@ -45,7 +45,7 @@ class PlexusProto : public IRCDProto void SendAkill(User *u, XLine *x) anope_override { hybrid->SendAkill(u, x); } void SendServer(const Server *server) anope_override { hybrid->SendServer(server); } void SendChannel(Channel *c) anope_override { hybrid->SendChannel(c); } - void SendSVSHold(const Anope::string &nick) anope_override { hybrid->SendSVSHold(nick); } + void SendSVSHold(const Anope::string &nick, time_t t) anope_override { hybrid->SendSVSHold(nick, t); } void SendSVSHoldDel(const Anope::string &nick) anope_override { hybrid->SendSVSHoldDel(nick); } void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override @@ -90,7 +90,7 @@ class PlexusProto : public IRCDProto void SendConnect() anope_override { - UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink]->password << " TS 6 :" << Me->GetSID(); + UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink].password << " TS 6 :" << Me->GetSID(); /* CAPAB * QS - Can handle quit storm removal * EX - Can do channel +e exemptions @@ -186,7 +186,7 @@ struct IRCDMessageEncap : IRCDMessage if (u && nc) { u->Login(nc); - if (!Config->NoNicknameOwnership && user_na && user_na->nc == nc && user_na->nc->HasExt("UNCONFIRMED") == false) + if (!Config->GetBlock("options")->Get<bool>("nonicknameownership") && user_na && user_na->nc == nc && user_na->nc->HasExt("UNCONFIRMED") == false) u->SetMode(NickServ, "REGISTERED"); } } diff --git a/modules/protocol/ratbox.cpp b/modules/protocol/ratbox.cpp index 2d01605bb..2b971b23f 100644 --- a/modules/protocol/ratbox.cpp +++ b/modules/protocol/ratbox.cpp @@ -45,7 +45,7 @@ class RatboxProto : public IRCDProto void SendConnect() anope_override { - UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink]->password << " TS 6 :" << Me->GetSID(); + UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink].password << " TS 6 :" << Me->GetSID(); /* QS - Can handle quit storm removal EX - Can do channel +e exemptions @@ -107,7 +107,7 @@ struct IRCDMessageEncap : IRCDMessage u->Login(nc); const NickAlias *user_na = NickAlias::Find(u->nick); - if (!Config->NoNicknameOwnership && user_na && user_na->nc == nc && user_na->nc->HasExt("UNCONFIRMED") == false) + if (!Config->GetBlock("options")->Get<bool>("nonicknameownership") && user_na && user_na->nc == nc && user_na->nc->HasExt("UNCONFIRMED") == false) u->SetMode(NickServ, "REGISTERED"); } } @@ -134,7 +134,7 @@ struct IRCDMessageServer : IRCDMessage if (params[1] != "1") return; new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], 1, params[2], UplinkSID); - IRCD->SendPing(Config->ServerName, params[0]); + IRCD->SendPing(Me->GetName(), params[0]); } }; @@ -217,6 +217,7 @@ class ProtoRatbox : public Module /* user modes */ ModeManager::RemoveUserMode(ModeManager::FindUserModeByName("HIDEOPER")); ModeManager::RemoveUserMode(ModeManager::FindUserModeByName("REGPRIV")); + ModeManager::AddUserMode(new UserMode("PROTECTED", 'S')); /* v/h/o/a/q */ ModeManager::RemoveChannelMode(ModeManager::FindChannelModeByName("HALFOP")); diff --git a/modules/protocol/unreal.cpp b/modules/protocol/unreal.cpp index 7a7847972..4186ee5d0 100644 --- a/modules/protocol/unreal.cpp +++ b/modules/protocol/unreal.cpp @@ -13,6 +13,8 @@ #include "module.h" +static bool sasl = true; + class UnrealIRCdProto : public IRCDProto { public: @@ -53,7 +55,7 @@ class UnrealIRCdProto : public IRCDProto } catch (const SocketException &) { } - UplinkSocket::Message() << "TKL - G " << x->GetUser() << " " << x->GetHost() << " " << Config->OperServ; + UplinkSocket::Message() << "TKL - G " << x->GetUser() << " " << x->GetHost() << " " << x->by; } void SendTopic(BotInfo *whosets, Channel *c) anope_override @@ -143,8 +145,8 @@ class UnrealIRCdProto : public IRCDProto /* Unreal 3.2 actually sends some info about itself in the descript area */ void SendServer(const Server *server) anope_override { - if (!Config->Numeric.empty()) - UplinkSocket::Message() << "SERVER " << server->GetName() << " " << server->GetHops() << " :U0-*-" << Config->Numeric << " " << server->GetDescription(); + if (!server->GetSID().empty() && server == Me) + UplinkSocket::Message() << "SERVER " << server->GetName() << " " << server->GetHops() << " :U0-*-" << server->GetSID() << " " << server->GetDescription(); else UplinkSocket::Message() << "SERVER " << server->GetName() << " " << server->GetHops() << " :" << server->GetDescription(); } @@ -225,24 +227,24 @@ class UnrealIRCdProto : public IRCDProto VL = Version Info NS = Config->Numeric Server */ - if (!Config->Numeric.empty()) - UplinkSocket::Message() << "PROTOCTL NICKv2 VHP UMODE2 NICKIP SJOIN SJOIN2 SJ3 NOQUIT TKLEXT ESVID MLOCK VL"; - else - UplinkSocket::Message() << "PROTOCTL NICKv2 VHP UMODE2 NICKIP SJOIN SJOIN2 SJ3 NOQUIT TKLEXT ESVID MLOCK"; - UplinkSocket::Message() << "PASS :" << Config->Uplinks[Anope::CurrentUplink]->password; + Anope::string protoctl = "NICKv2 VHP UMODE2 NICKIP SJOIN SJOIN2 SJ3 NOQUIT TKLEXT ESVID MLOCK VL"; + if (!Me->GetSID().empty()) + protoctl += " VL"; + UplinkSocket::Message() << "PROTOCTL " << protoctl; + UplinkSocket::Message() << "PASS :" << Config->Uplinks[Anope::CurrentUplink].password; SendServer(Me); } /* SVSHOLD - set */ - void SendSVSHold(const Anope::string &nick) anope_override + void SendSVSHold(const Anope::string &nick, time_t t) anope_override { - UplinkSocket::Message() << "TKL + Q H " << nick << " " << Config->ServerName << " " << Anope::CurTime + Config->NSReleaseTimeout << " " << Anope::CurTime << " :Being held for registered user"; + UplinkSocket::Message() << "TKL + Q H " << nick << " " << Me->GetName() << " " << Anope::CurTime + t << " " << Anope::CurTime << " :Being held for registered user"; } /* SVSHOLD - release */ void SendSVSHoldDel(const Anope::string &nick) anope_override { - UplinkSocket::Message() << "TKL - Q * " << nick << " " << Config->ServerName; + UplinkSocket::Message() << "TKL - Q * " << nick << " " << Me->GetName(); } /* UNSGLINE */ @@ -257,7 +259,7 @@ class UnrealIRCdProto : public IRCDProto /* UNSZLINE */ void SendSZLineDel(const XLine *x) anope_override { - UplinkSocket::Message() << "TKL - Z * " << x->GetHost() << " " << Config->OperServ; + UplinkSocket::Message() << "TKL - Z * " << x->GetHost() << " " << x->by; } /* SZLINE */ @@ -892,7 +894,7 @@ struct IRCDMessageSASL : IRCDMessage void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override { size_t p = params[1].find('!'); - if (!Config->NSSASL || p == Anope::string::npos) + if (!sasl || p == Anope::string::npos) return; if (params[2] == "S") @@ -996,7 +998,7 @@ struct IRCDMessageServer : IRCDMessage else new Server(source.GetServer(), params[0], hops, params[2]); - IRCD->SendPing(Config->ServerName, params[0]); + IRCD->SendPing(Me->GetName(), params[0]); } }; @@ -1158,6 +1160,8 @@ class ProtoUnreal : public Module IRCDMessageTopic message_topic; IRCDMessageUmode2 message_umode2; + bool use_server_side_mlock; + void AddModes() { ModeManager::AddChannelMode(new ChannelModeStatus("VOICE", 'v', '+', 0)); @@ -1212,11 +1216,17 @@ class ProtoUnreal : public Module this->AddModes(); - Implementation i[] = { I_OnUserNickChange, I_OnChannelCreate, I_OnChanRegistered, I_OnDelChan, I_OnMLock, I_OnUnMLock }; + Implementation i[] = { I_OnReload, I_OnUserNickChange, I_OnChannelCreate, I_OnChanRegistered, I_OnDelChan, I_OnMLock, I_OnUnMLock }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); ModuleManager::SetPriority(this, PRIORITY_FIRST); } + void OnReload(Configuration::Conf *conf) anope_override + { + use_server_side_mlock = conf->GetModule(this)->Get<bool>("use_server_side_mlock"); + sasl = conf->GetModule(this)->Get<bool>("sasl"); + } + void OnUserNickChange(User *u, const Anope::string &) anope_override { u->RemoveModeInternal(ModeManager::FindUserModeByName("REGISTERED")); @@ -1226,7 +1236,7 @@ class ProtoUnreal : public Module void OnChannelCreate(Channel *c) anope_override { - if (Config->UseServerSideMLock && Servers::Capab.count("MLOCK") > 0 && c->ci) + if (use_server_side_mlock && Servers::Capab.count("MLOCK") > 0 && c->ci) { Anope::string modes = c->ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", ""); UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(c->creation_time) << " " << c->ci->name << " " << modes; @@ -1235,7 +1245,7 @@ class ProtoUnreal : public Module void OnChanRegistered(ChannelInfo *ci) anope_override { - if (!ci->c || !Config->UseServerSideMLock) + if (!ci->c || !use_server_side_mlock || !Servers::Capab.count("MLOCK")) return; Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", ""); UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes; @@ -1243,7 +1253,7 @@ class ProtoUnreal : public Module void OnDelChan(ChannelInfo *ci) anope_override { - if (!ci->c || !Config->UseServerSideMLock) + if (!ci->c || !use_server_side_mlock || !Servers::Capab.count("MLOCK")) return; UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " :"; } @@ -1251,7 +1261,7 @@ class ProtoUnreal : public Module EventReturn OnMLock(ChannelInfo *ci, ModeLock *lock) anope_override { ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name); - if (cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0 && Config->UseServerSideMLock) + if (use_server_side_mlock && cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0) { Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "") + cm->mchar; UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes; @@ -1263,7 +1273,7 @@ class ProtoUnreal : public Module EventReturn OnUnMLock(ChannelInfo *ci, ModeLock *lock) anope_override { ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name); - if (cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0 && Config->UseServerSideMLock) + if (use_server_side_mlock && cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0) { Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "").replace_all_cs(cm->mchar, ""); UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes; diff --git a/modules/pseudoclients/botserv.cpp b/modules/pseudoclients/botserv.cpp index 29c1b1143..c33a8eeb5 100644 --- a/modules/pseudoclients/botserv.cpp +++ b/modules/pseudoclients/botserv.cpp @@ -18,13 +18,8 @@ class BotServCore : public Module public: BotServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR) { - - BotServ = BotInfo::Find(Config->BotServ); - if (!BotServ) - throw ModuleException("No bot named " + Config->BotServ); - - Implementation i[] = { I_OnBotDelete, I_OnPrivmsg, I_OnJoinChannel, I_OnLeaveChannel, - I_OnPreHelp, I_OnPostHelp, I_OnChannelModeSet }; + Implementation i[] = { I_OnReload, I_OnSetCorrectModes, I_OnBotAssign, I_OnBotDelete, I_OnPrivmsg, I_OnJoinChannel, I_OnLeaveChannel, + I_OnPreHelp, I_OnPostHelp, I_OnChannelModeSet, I_OnCreateChan, I_OnUserKicked }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } @@ -33,6 +28,40 @@ class BotServCore : public Module BotServ = NULL; } + void OnReload(Configuration::Conf *conf) anope_override + { + const Anope::string &bsnick = conf->GetModule(this)->Get<const Anope::string &>("client"); + + if (bsnick.empty()) + throw ConfigException(this->name + ": <client> must be defined"); + + BotInfo *bi = BotInfo::Find(bsnick, true); + if (!bi) + throw ConfigException(this->name + ": no bot named " + bsnick); + + BotServ = bi; + } + + void OnSetCorrectModes(User *user, Channel *chan, AccessGroup &access, bool give_modes) anope_override + { + /* Do not allow removing bot modes on our service bots */ + if (chan->ci && chan->ci->bi == user) + { + const Anope::string &botmodes = Config->GetModule(this)->Get<const Anope::string &>("botmodes"); + for (unsigned i = 0; i < botmodes.length(); ++i) + chan->SetMode(chan->ci->bi, ModeManager::FindChannelModeByChar(botmodes[i]), chan->ci->bi->GetUID()); + } + } + + void OnBotAssign(User *sender, ChannelInfo *ci, BotInfo *bi) anope_override + { + if (Me->IsSynced() && ci->c && ci->c->users.size() >= Config->GetModule(this)->Get<unsigned>("minusers")) + { + ChannelStatus status(Config->GetModule(this)->Get<const Anope::string &>("botmodes")); + bi->Join(ci->c, &status); + } + } + void OnBotDelete(BotInfo *bi) anope_override { if (bi == BotServ) @@ -70,9 +99,7 @@ class BotServCore : public Module if (!realbuf.find(c->ci->bi->nick)) params.erase(params.begin()); - else if (Config->BSFantasyCharacter.empty()) - ; - else if (!realbuf.find_first_of(Config->BSFantasyCharacter)) + else if (!realbuf.find_first_of(Config->GetModule(this)->Get<const Anope::string &>("fantasycharacter", "!"))) params[0].erase(params[0].begin()); else return; @@ -158,6 +185,42 @@ class BotServCore : public Module void OnJoinChannel(User *user, Channel *c) anope_override { + if (!Config || !IRCD) + return; + + BotInfo *bi = user->server == Me ? dynamic_cast<BotInfo *>(user) : NULL; + if (bi && Config->GetModule(this)->Get<bool>("smartjoin")) + { + std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> bans = c->GetModeList("BAN"); + + /* We check for bans */ + for (; bans.first != bans.second; ++bans.first) + { + Entry ban("BAN", bans.first->second); + if (ban.Matches(user)) + c->RemoveMode(NULL, "BAN", ban.GetMask()); + } + + Anope::string Limit; + unsigned limit = 0; + try + { + if (c->GetParam("LIMIT", Limit)) + limit = convertTo<unsigned>(Limit); + } + catch (const ConvertException &) { } + + /* Should we be invited? */ + if (c->HasMode("INVITE") || (limit && c->users.size() >= limit)) + { + ChannelMode *cm = ModeManager::FindChannelModeByName("OP"); + char symbol = cm ? anope_dynamic_static_cast<ChannelModeStatus *>(cm)->symbol : 0; + IRCD->SendNotice(bi, (symbol ? Anope::string(symbol) : "") + c->name, "%s invited %s into the channel.", user->nick.c_str(), user->nick.c_str()); + } + + ModeManager::ProcessModes(); + } + if (user->server != Me && c->ci && c->ci->bi) { /** @@ -166,8 +229,11 @@ class BotServCore : public Module * make it into the channel, leaving the channel botless even for * legit users - Rob **/ - if (c->users.size() >= Config->BSMinUsers && !c->FindUser(c->ci->bi)) - c->ci->bi->Join(c, &ModeManager::DefaultBotModes); + if (c->users.size() >= Config->GetModule(this)->Get<unsigned>("minusers") && !c->FindUser(c->ci->bi)) + { + ChannelStatus status(Config->GetModule(this)->Get<const Anope::string &>("botmodes")); + c->ci->bi->Join(c, &status); + } /* 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 @@ -197,7 +263,7 @@ class BotServCore : public Module return; /* This is called prior to removing the user from the channnel, so c->users.size() - 1 should be safe */ - if (c->ci && c->ci->bi && u != *c->ci->bi && c->users.size() - 1 <= Config->BSMinUsers && c->FindUser(c->ci->bi)) + if (c->ci && c->ci->bi && u != *c->ci->bi && c->users.size() - 1 <= Config->GetModule(this)->Get<unsigned>("minusers") && c->FindUser(c->ci->bi)) c->ci->bi->Part(c->ci->c); } @@ -209,17 +275,18 @@ class BotServCore : public Module if (source.c) { source.Reply(_("\002%s\002 allows you to execute \"fantasy\" commands in the channel.\n" - "Fantasy commands are tied to existing commands, usually on \002%s\002,\n" - "and provide a more convenient way to execute commands. Commands that\n" + "Fantasy commands are commands that can be executed from messaging a\n" + "channel, and provide a more convenient way to execute commands. Commands that\n" "require a channel as a parameter will automatically have that parameter\n" - "given.\n"), source.service->nick.c_str(), Config->ChanServ.c_str()); - if (!Config->BSFantasyCharacter.empty()) + "given.\n"), source.service->nick.c_str()); + const Anope::string &fantasycharacters = Config->GetModule(this)->Get<const Anope::string &>("fantasycharacter", "!"); + if (!fantasycharacters.empty()) source.Reply(_(" \n" - "Fantasy commands may be prefixed with one of the following characters: %s\n"), Config->BSFantasyCharacter.c_str()); + "Fantasy commands may be prefixed with one of the following characters: %s\n"), fantasycharacters.c_str()); source.Reply(_(" \n" "Available commands are:")); } - else if (source.service->nick == Config->BotServ) + else if (*source.service == BotServ) { source.Reply(_("\002%s\002 allows you to have a bot on your own channel.\n" "It has been created for users that can't host or\n" @@ -228,8 +295,8 @@ class BotServCore : public Module "below; to use them, type \002%s%s \037command\037\002. For\n" "more information on a specific command, type\n" "\002%s%s %s \037command\037\002.\n "), - Config->BotServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->BotServ.c_str(), - Config->UseStrictPrivMsgString.c_str(), Config->BotServ.c_str(), source.command.c_str()); + BotServ->nick.c_str(), Config->StrictPrivmsg.c_str(), BotServ->nick.c_str(), + Config->StrictPrivmsg.c_str(), BotServ->nick.c_str(), source.command.c_str()); } return EVENT_CONTINUE; @@ -237,21 +304,22 @@ class BotServCore : public Module void OnPostHelp(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (!params.empty() || source.c || source.service->nick != Config->BotServ) + if (!params.empty() || source.c || source.service != BotServ) return; source.Reply(_(" \n" "Bot will join a channel whenever there is at least\n" - "\002%d\002 user(s) on it."), Config->BSMinUsers); - if (!Config->BSFantasyCharacter.empty()) - source.Reply(_("Additionally, all %s commands can be used if fantasy\n" - "is enabled by prefixing the command name with one of\n" - "the following characters: %s"), Config->ChanServ.c_str(), Config->BSFantasyCharacter.c_str()); + "\002%d\002 user(s) on it."), Config->GetModule(this)->Get<unsigned>("minusers")); + const Anope::string &fantasycharacters = Config->GetModule(this)->Get<const Anope::string &>("fantasycharacter", "!"); + if (!fantasycharacters.empty()) + source.Reply(_("Additionally, if fantasy is enabled fantasy commands\n" + "can be executed by prefixing the command name with\n" + "one of the following characters: %s"), fantasycharacters.c_str()); } EventReturn OnChannelModeSet(Channel *c, MessageSource &, const Anope::string &mname, const Anope::string ¶m) anope_override { - if (Config->BSSmartJoin && mname == "BAN" && c->ci && c->ci->bi && c->FindUser(c->ci->bi)) + if (Config->GetModule(this)->Get<bool>("smartjoin") && mname == "BAN" && c->ci && c->ci->bi && c->FindUser(c->ci->bi)) { BotInfo *bi = c->ci->bi; @@ -262,6 +330,26 @@ class BotServCore : public Module return EVENT_CONTINUE; } + + void OnCreateChan(ChannelInfo *ci) anope_override + { + /* Set default bot flags */ + spacesepstream sep(Config->GetModule(this)->Get<const Anope::string &>("defaults", "greet fantasy")); + for (Anope::string token; sep.GetToken(token);) + this->ExtendMetadata("BS_" + token); + } + + void OnPreUserKicked(MessageSource &source, ChanUserContainer *cu, const Anope::string &kickmsg) anope_override + { + } + + void OnUserKicked(MessageSource &source, User *target, const Anope::string &channel, ChannelStatus &status, const Anope::string &kickmsg) anope_override + { + BotInfo *bi = BotInfo::Find(target->nick); + if (bi) + /* Bots get rejoined */ + bi->Join(channel, &status); + } }; MODULE_INIT(BotServCore) diff --git a/modules/pseudoclients/chanserv.cpp b/modules/pseudoclients/chanserv.cpp index 2c5cffcea..e34cd56e8 100644 --- a/modules/pseudoclients/chanserv.cpp +++ b/modules/pseudoclients/chanserv.cpp @@ -16,11 +16,13 @@ class ExpireCallback : public Timer { public: - ExpireCallback(Module *o) : Timer(o, Config->ExpireTimeout, Anope::CurTime, true) { } + ExpireCallback(Module *o) : Timer(o, Config->GetBlock("options")->Get<time_t>("expiretimeout"), Anope::CurTime, true) { } void Tick(time_t) anope_override { - if (!Config->CSExpire || Anope::NoExpire || Anope::ReadOnly) + time_t chanserv_expire = Config->GetModule("chanserv")->Get<time_t>("expire", "14d"); + + if (!chanserv_expire || Anope::NoExpire || Anope::ReadOnly) return; for (registered_channel_map::const_iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; ) @@ -30,7 +32,7 @@ class ExpireCallback : public Timer bool expire = false; - if (Anope::CurTime - ci->last_used >= Config->CSExpire) + if (Anope::CurTime - ci->last_used >= chanserv_expire) { if (ci->c) { @@ -62,19 +64,81 @@ class ExpireCallback : public Timer } }; +class MyChanServService : public ChanServService +{ + public: + MyChanServService(Module *m) : ChanServService(m) { } + + void Hold(Channel *c) anope_override + { + /** A timer used to keep the BotServ bot/ChanServ in the channel + * after kicking the last user in a channel + */ + class ChanServTimer : public Timer + { + Reference<Channel> c; + + public: + /** Constructor + * @param chan The channel + */ + ChanServTimer(Module *m, Channel *chan) : Timer(m, Config->GetModule(this->GetOwner())->Get<time_t>("inhabit", "15s")), c(chan) + { + if (!ChanServ || !c) + return; + c->Extend("INHABIT"); + if (!c->ci || !c->ci->bi) + ChanServ->Join(c); + else if (!c->FindUser(c->ci->bi)) + c->ci->bi->Join(c); + + /* Set +ntsi to prevent rejoin */ + c->SetMode(NULL, "NOEXTERNAL"); + c->SetMode(NULL, "TOPIC"); + c->SetMode(NULL, "SECRET"); + c->SetMode(NULL, "INVITE"); + } + + /** Called when the delay is up + * @param The current time + */ + void Tick(time_t) anope_override + { + if (!c) + return; + + c->Shrink("INHABIT"); + + if (!c->ci || !c->ci->bi) + { + if (ChanServ) + ChanServ->Part(c); + } + else + c->ci->bi->Part(c); + } + }; + + if (c->HasExt("INHABIT")) + return; + + new ChanServTimer(this->owner, c); + } +}; + class ChanServCore : public Module { + MyChanServService chanserv; ExpireCallback expires; + std::vector<Anope::string> defaults; public: - ChanServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR), expires(this) + ChanServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR), + chanserv(this), expires(this) { - - ChanServ = BotInfo::Find(Config->ChanServ); - if (!ChanServ) - throw ModuleException("No bot named " + Config->ChanServ); - - Implementation i[] = { I_OnBotDelete, I_OnBotPrivmsg, I_OnDelCore, I_OnPreHelp, I_OnPostHelp, I_OnCheckModes }; + Implementation i[] = { I_OnReload, I_OnBotDelete, I_OnBotPrivmsg, I_OnDelCore, + I_OnPreHelp, I_OnPostHelp, I_OnCheckModes, I_OnCreateChan, I_OnCanSet, + I_OnChannelSync, I_OnBotKick }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } @@ -83,6 +147,31 @@ class ChanServCore : public Module ChanServ = NULL; } + void OnReload(Configuration::Conf *conf) anope_override + { + const Anope::string &channick = conf->GetModule(this)->Get<const Anope::string &>("client"); + + if (channick.empty()) + throw ConfigException(this->name + ": <client> must be defined"); + + BotInfo *bi = BotInfo::Find(channick, true); + if (!bi) + throw ConfigException(this->name + ": no bot named " + channick); + + ChanServ = bi; + + spacesepstream(conf->GetModule(this)->Get<const Anope::string &>("defaults", "greet fantasy")).GetTokens(defaults); + if (defaults.empty()) + { + defaults.push_back("KEEPTOPIC"); + defaults.push_back("SECURE"); + defaults.push_back("SECUREFOUNDER"); + defaults.push_back("SIGNKICK"); + } + else if (defaults[0].equals_ci("none")) + defaults.erase(defaults.begin()); + } + void OnBotDelete(BotInfo *bi) anope_override { if (bi == ChanServ) @@ -91,7 +180,7 @@ class ChanServCore : public Module EventReturn OnBotPrivmsg(User *u, BotInfo *bi, Anope::string &message) anope_override { - if (Config->CSOpersOnly && bi == ChanServ && !u->HasMode("OPER")) + if (bi == ChanServ && Config->GetModule(this)->Get<bool>("operonly") && !u->HasMode("OPER")) { u->SendMessage(bi, ACCESS_DENIED); return EVENT_STOP; @@ -104,6 +193,7 @@ class ChanServCore : public Module { std::deque<ChannelInfo *> chans; nc->GetChannelReferences(chans); + int max_reg = Config->GetModule(this)->Get<int>("maxregistered"); for (unsigned i = 0; i < chans.size(); ++i) { @@ -112,7 +202,7 @@ class ChanServCore : public Module if (ci->GetFounder() == nc) { NickCore *newowner = NULL; - if (ci->GetSuccessor() && ci->GetSuccessor() != nc && (ci->GetSuccessor()->IsServicesOper() || !Config->CSMaxReg || ci->GetSuccessor()->channelcount < Config->CSMaxReg)) + if (ci->GetSuccessor() && ci->GetSuccessor() != nc && (ci->GetSuccessor()->IsServicesOper() || !max_reg || ci->GetSuccessor()->channelcount < max_reg)) newowner = ci->GetSuccessor(); else { @@ -122,7 +212,7 @@ class ChanServCore : public Module const ChanAccess *ca = ci->GetAccess(j); const NickCore *anc = NickCore::Find(ca->mask); - if (!anc || (!anc->IsServicesOper() && Config->CSMaxReg && anc->channelcount >= Config->CSMaxReg) || (anc == nc)) + if (!anc || (!anc->IsServicesOper() && max_reg && anc->channelcount >= max_reg) || (anc == nc)) continue; if (!highest || *ca > *highest) highest = ca; @@ -175,7 +265,7 @@ class ChanServCore : public Module EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (!params.empty() || source.c || source.service->nick != Config->ChanServ) + if (!params.empty() || source.c || source.service != ChanServ) return EVENT_CONTINUE; source.Reply(_("\002%s\002 allows you to register and control various\n" "aspects of channels. %s can often prevent\n" @@ -184,19 +274,20 @@ class ChanServCore : public Module "commands are listed below; to use them, type\n" "\002%s%s \037command\037\002. For more information on a\n" "specific command, type \002%s%s HELP \037command\037\002.\n "), - Config->ChanServ.c_str(), Config->ChanServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->ChanServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->ChanServ.c_str(), Config->ChanServ.c_str(), source.command.c_str()); + ChanServ->nick.c_str(), ChanServ->nick.c_str(), Config->StrictPrivmsg.c_str(), ChanServ->nick.c_str(), Config->StrictPrivmsg.c_str(), ChanServ->nick.c_str(), ChanServ->nick.c_str(), source.command.c_str()); return EVENT_CONTINUE; } void OnPostHelp(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (!params.empty() || source.c || source.service->nick != Config->ChanServ) + if (!params.empty() || source.c || source.service != ChanServ) return; - if (Config->CSExpire >= 86400) + time_t expire = Config->GetModule(this)->Get<time_t>("expire", "14d"); + if (expire >= 86400) source.Reply(_(" \n" "Note that any channel which is not used for %d days\n" "(i.e. which no user on the channel's access list enters\n" - "for that period of time) will be automatically dropped."), Config->CSExpire / 86400); + "for that period of time) will be automatically dropped."), expire / 86400); if (source.IsServicesOper()) source.Reply(_(" \n" "Services Operators can also, depending on their access drop\n" @@ -206,12 +297,84 @@ class ChanServCore : public Module EventReturn OnCheckModes(Channel *c) anope_override { - if (!Config->CSRequire.empty()) + const Anope::string &require = Config->GetModule(this)->Get<const Anope::string &>("require", "r"); + if (!require.empty()) { if (c->ci) - c->SetModes(NULL, false, "+%s", Config->CSRequire.c_str()); + c->SetModes(NULL, false, "+%s", require.c_str()); else - c->SetModes(NULL, false, "-%s", Config->CSRequire.c_str()); + c->SetModes(NULL, false, "-%s", require.c_str()); + } + + return EVENT_CONTINUE; + } + + void OnCreateChan(ChannelInfo *ci) anope_override + { + ci->bantype = Config->GetModule(this)->Get<int>("defbantype", "2"); + + /* Set default chan flags */ + for (unsigned i = 0; i < defaults.size(); ++i) + this->ExtendMetadata(defaults[i]); + + { + Anope::string modes; + spacesepstream sep(Config->GetModule(this)->Get<const Anope::string &>("mlock", "+nrt")); + if (sep.GetToken(modes)) + { + bool add = true; + for (unsigned i = 0; i < modes.length(); ++i) + { + if (modes[i] == '+') + add = true; + else if (modes[i] == '-') + add = false; + else + { + ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]); + Anope::string param; + if (cm && (cm->type == MODE_REGULAR || sep.GetToken(param))) + ci->SetMLock(cm, add, param); + } + } + } + } + } + + EventReturn OnCanSet(User *u, const ChannelMode *cm) anope_override + { + if (Config->GetModule(this)->Get<const Anope::string &>("nomlock").find(cm->mchar) != Anope::string::npos + || Config->GetModule(this)->Get<const Anope::string &>("require", "r").find(cm->mchar) || Anope::string::npos) + return EVENT_STOP; + return EVENT_CONTINUE; + } + + void OnChannelSync(Channel *c) anope_override + { + if (!c->HasMode("PERM") && (c->users.empty() || (c->users.size() == 1 && c->ci && c->ci->bi && *c->ci->bi == c->users.begin()->second->user))) + { + chanserv.Hold(c); + } + if (c->ci) + { + c->CheckModes(); + + if (Me && Me->IsSynced()) + c->ci->RestoreTopic(); + } + } + + EventReturn OnBotKick(BotInfo *bi, Channel *c, User *u, const Anope::string &reason) + { + /* If the channel isn't syncing and doesn't have any users, join ChanServ + * Note that the user AND POSSIBLY the botserv bot exist here + * ChanServ always enforces channels like this to keep people from deleting bots etc + * that are holding channels. + */ + if (c->ci && c->users.size() == (c->ci->bi && c->FindUser(c->ci->bi) ? 2 : 1) && !c->HasExt("INHABIT") && !c->HasExt("SYNCING")) + { + /* Join ChanServ and set a timer for this channel to part ChanServ later */ + chanserv.Hold(c); } return EVENT_CONTINUE; diff --git a/modules/pseudoclients/chanserv.h b/modules/pseudoclients/chanserv.h new file mode 100644 index 000000000..e1c3849fd --- /dev/null +++ b/modules/pseudoclients/chanserv.h @@ -0,0 +1,18 @@ +#ifndef CHANSERV_H +#define CHANSERV_H + +class ChanServService : public Service +{ + public: + ChanServService(Module *m) : Service(m, "ChanServService", "ChanServ") + { + } + + /* Have ChanServ hold the channel, that is, join and set +nsti and wait + * for a few minutes so no one can join or rejoin. + */ + virtual void Hold(Channel *c) = 0; +}; + +#endif // CHANSERV_H + diff --git a/modules/pseudoclients/global.cpp b/modules/pseudoclients/global.cpp index 02b199afa..837200e5d 100644 --- a/modules/pseudoclients/global.cpp +++ b/modules/pseudoclients/global.cpp @@ -34,29 +34,24 @@ class MyGlobalService : public GlobalService Anope::string rmessage; - if (!source.empty() && !Config->AnonymousGlobal) + if (!source.empty() && !Config->GetModule("global")->Get<bool>("anonymousglobal")) rmessage = "[" + source + "] " + message; else rmessage = message; - this->ServerGlobal(sender, Me->GetLinks().front(), rmessage); + this->ServerGlobal(sender, Servers::GetUplink(), rmessage); } }; class GlobalCore : public Module { - MyGlobalService myglobalservice; + MyGlobalService global; public: GlobalCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR), - myglobalservice(this) + global(this) { - - Global = BotInfo::Find(Config->Global); - if (!Global) - throw ModuleException("No bot named " + Config->Global); - - Implementation i[] = { I_OnBotDelete, I_OnRestart, I_OnShutdown, I_OnNewServer, I_OnPreHelp }; + Implementation i[] = { I_OnReload, I_OnBotDelete, I_OnRestart, I_OnShutdown, I_OnNewServer, I_OnPreHelp }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } @@ -65,6 +60,20 @@ class GlobalCore : public Module Global = NULL; } + void OnReload(Configuration::Conf *conf) anope_override + { + const Anope::string &glnick = conf->GetModule(this)->Get<const Anope::string &>("client"); + + if (glnick.empty()) + throw ConfigException(this->name + ": <client> must be defined"); + + BotInfo *bi = BotInfo::Find(glnick, true); + if (!bi) + throw ConfigException(this->name + ": no bot named " + glnick); + + Global = bi; + } + void OnBotDelete(BotInfo *bi) anope_override { if (bi == Global) @@ -73,27 +82,30 @@ class GlobalCore : public Module void OnRestart() anope_override { - if (Config->GlobalOnCycle) - this->myglobalservice.SendGlobal(Global, "", Config->GlobalOnCycleMessage); + const Anope::string &gl = Config->GetModule(this)->Get<const Anope::string &>("globaloncycledown"); + if (!gl.empty()) + this->global.SendGlobal(Global, "", gl); } void OnShutdown() anope_override { - if (Config->GlobalOnCycle) - this->myglobalservice.SendGlobal(Global, "", Config->GlobalOnCycleMessage); + const Anope::string &gl = Config->GetModule(this)->Get<const Anope::string &>("globaloncycledown"); + if (!gl.empty()) + this->global.SendGlobal(Global, "", gl); } void OnNewServer(Server *s) anope_override { - if (Config->GlobalOnCycle && !Config->GlobalOnCycleUP.empty()) - s->Notice(Global, Config->GlobalOnCycleUP); + const Anope::string &gl = Config->GetModule(this)->Get<const Anope::string &>("globaloncycleup"); + if (!gl.empty() && !Me->IsSynced()) + s->Notice(Global, gl); } EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (!params.empty() || source.c || source.service->nick != Config->Global) + if (!params.empty() || source.c || source.service != Global) return EVENT_CONTINUE; - source.Reply(_("%s commands:"), Config->Global.c_str()); + source.Reply(_("%s commands:"), Global->nick.c_str()); return EVENT_CONTINUE; } }; diff --git a/modules/pseudoclients/global.h b/modules/pseudoclients/global.h index fccd96558..52afc4a23 100644 --- a/modules/pseudoclients/global.h +++ b/modules/pseudoclients/global.h @@ -4,7 +4,9 @@ class GlobalService : public Service { public: - GlobalService(Module *m) : Service(m, "GlobalService", "Global") { } + GlobalService(Module *m) : Service(m, "GlobalService", "Global") + { + } /** Send out a global message to all users * @param sender Our client which should send the global diff --git a/modules/pseudoclients/hostserv.cpp b/modules/pseudoclients/hostserv.cpp index d8cd74d69..acca6f7ff 100644 --- a/modules/pseudoclients/hostserv.cpp +++ b/modules/pseudoclients/hostserv.cpp @@ -22,11 +22,7 @@ class HostServCore : public Module if (!IRCD || !IRCD->CanSetVHost) throw ModuleException("Your IRCd does not support vhosts"); - HostServ = BotInfo::Find(Config->HostServ); - if (!HostServ) - throw ModuleException("No bot named " + Config->HostServ); - - Implementation i[] = { I_OnBotDelete, I_OnNickIdentify, I_OnNickUpdate, I_OnPreHelp }; + Implementation i[] = { I_OnReload, I_OnBotDelete, I_OnNickIdentify, I_OnNickUpdate, I_OnPreHelp }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } @@ -35,6 +31,20 @@ class HostServCore : public Module HostServ = NULL; } + void OnReload(Configuration::Conf *conf) anope_override + { + const Anope::string &hsnick = conf->GetModule(this)->Get<const Anope::string &>("client"); + + if (hsnick.empty()) + throw ConfigException(this->name + ": <client> must be defined"); + + BotInfo *bi = BotInfo::Find(hsnick, true); + if (!bi) + throw ConfigException(this->name + ": no bot named " + hsnick); + + HostServ = bi; + } + void OnBotDelete(BotInfo *bi) anope_override { if (bi == HostServ) @@ -76,9 +86,9 @@ class HostServCore : public Module EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (!params.empty() || source.c || source.service->nick != Config->HostServ) + if (!params.empty() || source.c || source.service != HostServ) return EVENT_CONTINUE; - source.Reply(_("%s commands:"), Config->HostServ.c_str()); + source.Reply(_("%s commands:"), HostServ->nick.c_str()); return EVENT_CONTINUE; } }; diff --git a/modules/pseudoclients/memoserv.cpp b/modules/pseudoclients/memoserv.cpp index 5eca5cd4e..46ad82194 100644 --- a/modules/pseudoclients/memoserv.cpp +++ b/modules/pseudoclients/memoserv.cpp @@ -16,20 +16,20 @@ static bool SendMemoMail(NickCore *nc, MemoInfo *mi, Memo *m) { - Anope::string subject = Language::Translate(nc, Config->MailMemoSubject.c_str()); - Anope::string message = Language::Translate(nc, Config->MailMemoMessage.c_str()); + Anope::string subject = Language::Translate(nc, Config->GetBlock("mail")->Get<const char *>("memo_subject")), + message = Language::Translate(Config->GetBlock("mail")->Get<const char *>("memo_message")); subject = subject.replace_all_cs("%n", nc->display); subject = subject.replace_all_cs("%s", m->sender); subject = subject.replace_all_cs("%d", stringify(mi->GetIndex(m) + 1)); subject = subject.replace_all_cs("%t", m->text); - subject = subject.replace_all_cs("%N", Config->NetworkName); + subject = subject.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string &>("networkname")); message = message.replace_all_cs("%n", nc->display); message = message.replace_all_cs("%s", m->sender); message = message.replace_all_cs("%d", stringify(mi->GetIndex(m) + 1)); message = message.replace_all_cs("%t", m->text); - message = message.replace_all_cs("%N", Config->NetworkName); + message = message.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string &>("networkname")); return Mail::Send(nc, subject, message); } @@ -50,7 +50,8 @@ class MyMemoServService : public MemoServService User *sender = User::Find(source); if (sender != NULL && !sender->HasPriv("memoserv/no-limit") && !force) { - if (Config->MSSendDelay > 0 && sender->lastmemosend + Config->MSSendDelay > Anope::CurTime) + time_t send_delay = Config->GetModule("memoserv")->Get<time_t>("senddelay"); + if (send_delay > 0 && sender->lastmemosend + send_delay > Anope::CurTime) return MEMO_TOO_FAST; else if (!mi->memomax) return MEMO_TARGET_FULL; @@ -86,7 +87,7 @@ class MyMemoServService : public MemoServService if (ci->AccessFor(cu->user).HasPriv("MEMO")) { if (cu->user->Account() && cu->user->Account()->HasExt("MEMO_RECEIVE")) - cu->user->SendMessage(MemoServ, MEMO_NEW_X_MEMO_ARRIVED, ci->name.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->MemoServ.c_str(), ci->name.c_str(), mi->memos->size()); + cu->user->SendMessage(MemoServ, MEMO_NEW_X_MEMO_ARRIVED, ci->name.c_str(), Config->StrictPrivmsg.c_str(), MemoServ->nick.c_str(), ci->name.c_str(), mi->memos->size()); } } } @@ -102,7 +103,7 @@ class MyMemoServService : public MemoServService const NickAlias *na = nc->aliases->at(i); User *user = User::Find(na->nick); if (user && user->IsIdentified()) - user->SendMessage(MemoServ, MEMO_NEW_MEMO_ARRIVED, source.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->MemoServ.c_str(), mi->memos->size()); + user->SendMessage(MemoServ, MEMO_NEW_MEMO_ARRIVED, source.c_str(), Config->StrictPrivmsg.c_str(), MemoServ->nick.c_str(), mi->memos->size()); } } @@ -138,17 +139,12 @@ class MyMemoServService : public MemoServService class MemoServCore : public Module { - MyMemoServService mymemoserv; + MyMemoServService memoserv; public: MemoServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR), - mymemoserv(this) + memoserv(this) { - - MemoServ = BotInfo::Find(Config->MemoServ); - if (!MemoServ) - throw ModuleException("No bot named " + Config->MemoServ); - - Implementation i[] = { I_OnBotDelete, I_OnNickIdentify, I_OnJoinChannel, I_OnUserAway, I_OnNickUpdate, I_OnPreHelp, I_OnPostHelp }; + Implementation i[] = { I_OnNickCoreCreate, I_OnCreateChan, I_OnReload, I_OnBotDelete, I_OnNickIdentify, I_OnJoinChannel, I_OnUserAway, I_OnNickUpdate, I_OnPreHelp, I_OnPostHelp }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } @@ -157,6 +153,30 @@ class MemoServCore : public Module MemoServ = NULL; } + void OnReload(Configuration::Conf *conf) anope_override + { + const Anope::string &msnick = conf->GetModule(this)->Get<const Anope::string &>("client"); + + if (msnick.empty()) + throw ConfigException(this->name + ": <client> must be defined"); + + BotInfo *bi = BotInfo::Find(msnick, true); + if (!bi) + throw ConfigException(this->name + ": no bot named " + msnick); + + MemoServ = bi; + } + + void OnNickCoreCreate(NickCore *nc) anope_override + { + nc->memos.memomax = Config->GetModule(this)->Get<int>("maxmemos"); + } + + void OnCreateChan(ChannelInfo *ci) anope_override + { + ci->memos.memomax = Config->GetModule(this)->Get<int>("maxmemos"); + } + void OnBotDelete(BotInfo *bi) anope_override { if (bi == MemoServ) @@ -165,7 +185,7 @@ class MemoServCore : public Module void OnNickIdentify(User *u) anope_override { - this->mymemoserv.Check(u); + this->memoserv.Check(u); } void OnJoinChannel(User *u, Channel *c) anope_override @@ -182,37 +202,37 @@ class MemoServCore : public Module void OnUserAway(User *u, const Anope::string &message) anope_override { if (message.empty()) - this->mymemoserv.Check(u); + this->memoserv.Check(u); } void OnNickUpdate(User *u) anope_override { - this->mymemoserv.Check(u); + this->memoserv.Check(u); } EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (!params.empty() || source.c || source.service->nick != Config->MemoServ) + if (!params.empty() || source.c || source.service != MemoServ) return EVENT_CONTINUE; source.Reply(_("\002%s\002 is a utility allowing IRC users to send short\n" "messages to other IRC users, whether they are online at\n" "the time or not, or to channels(*). Both the sender's\n" "nickname and the target nickname or channel must be\n" "registered in order to send a memo.\n" - "%s's commands include:"), Config->MemoServ.c_str(), Config->MemoServ.c_str()); + "%s's commands include:"), MemoServ->nick.c_str(), MemoServ->nick.c_str()); return EVENT_CONTINUE; } void OnPostHelp(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (!params.empty() || source.c || source.service->nick != Config->MemoServ) + if (!params.empty() || source.c || source.service != MemoServ) return; source.Reply(_(" \n" "Type \002%s%s HELP \037command\037\002 for help on any of the\n" "above commands.\n" "(*) By default, any user with at least level 10 access on a\n" " channel can read that channel's memos. This can be\n" - " changed with the %s \002LEVELS\002 command."), Config->UseStrictPrivMsgString.c_str(), Config->MemoServ.c_str(), Config->ChanServ.c_str()); + " changed with the %s \002LEVELS\002 command."), Config->StrictPrivmsg.c_str(), MemoServ->nick.c_str(), ChanServ->nick.c_str()); } }; diff --git a/modules/pseudoclients/memoserv.h b/modules/pseudoclients/memoserv.h index 71ca064de..d35d3f8a0 100644 --- a/modules/pseudoclients/memoserv.h +++ b/modules/pseudoclients/memoserv.h @@ -12,7 +12,9 @@ class MemoServService : public Service MEMO_TARGET_FULL }; - MemoServService(Module *m) : Service(m, "MemoServService", "MemoServ") { } + MemoServService(Module *m) : Service(m, "MemoServService", "MemoServ") + { + } /** Sends a memo. * @param source The source of the memo, can be anythin. diff --git a/modules/pseudoclients/nickserv.cpp b/modules/pseudoclients/nickserv.cpp index cde1fbbf7..3f4250fb6 100644 --- a/modules/pseudoclients/nickserv.cpp +++ b/modules/pseudoclients/nickserv.cpp @@ -18,6 +18,7 @@ class NickServCollide; typedef std::map<Anope::string, NickServCollide *> nickservcollides_map; +static ServiceReference<NickServService> nickserv("NickServService", "NickServ"); static nickservcollides_map NickServCollides; /** Timer for colliding nicks to force people off of nicknames @@ -98,15 +99,15 @@ class MyNickServService : public NickServService return; } - if (Config->NoNicknameOwnership) + if (Config->GetBlock("options")->Get<bool>("nonicknameownership")) return; if (u->IsRecognized(false) || !na->nc->HasExt("KILL_IMMED")) { if (na->nc->HasExt("SECURE")) - u->SendMessage(NickServ, NICK_IS_SECURE, Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str()); + u->SendMessage(NickServ, NICK_IS_SECURE, Config->StrictPrivmsg.c_str(), NickServ->nick.c_str()); else - u->SendMessage(NickServ, NICK_IS_REGISTERED, Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str()); + u->SendMessage(NickServ, NICK_IS_REGISTERED, Config->StrictPrivmsg.c_str(), NickServ->nick.c_str()); } if (na->nc->HasExt("KILLPROTECT") && !u->IsRecognized(false)) @@ -118,13 +119,15 @@ class MyNickServService : public NickServService } else if (na->nc->HasExt("KILL_QUICK")) { - u->SendMessage(NickServ, _("If you do not change within %s, I will change your nick."), Anope::Duration(Config->NSKillQuick, u->Account()).c_str()); - new NickServCollide(u, Config->NSKillQuick); + time_t killquick = Config->GetModule("nickserv")->Get<time_t>("killquick", "60s"); + u->SendMessage(NickServ, _("If you do not change within %s, I will change your nick."), Anope::Duration(killquick, u->Account()).c_str()); + new NickServCollide(u, killquick); } else { - u->SendMessage(NickServ, _("If you do not change within %s, I will change your nick."), Anope::Duration(Config->NSKill, u->Account()).c_str()); - new NickServCollide(u, Config->NSKill); + time_t kill = Config->GetModule("nickserv")->Get<time_t>("kill", "20s"); + u->SendMessage(NickServ, _("If you do not change within %s, I will change your nick."), Anope::Duration(kill, u->Account()).c_str()); + new NickServCollide(u, kill); } } @@ -134,7 +137,7 @@ class MyNickServService : public NickServService { const NickAlias *u_na = NickAlias::Find(user->nick); user->Login(na->nc); - if (u_na && *u_na->nc == *na->nc && !Config->NoNicknameOwnership && na->nc->HasExt("UNCONFIRMED") == false) + if (u_na && *u_na->nc == *na->nc && !Config->GetBlock("options")->Get<bool>("nonicknameownership") && na->nc->HasExt("UNCONFIRMED") == false) user->SetMode(NickServ, "REGISTERED"); } }; @@ -142,13 +145,16 @@ class MyNickServService : public NickServService class ExpireCallback : public Timer { public: - ExpireCallback(Module *o) : Timer(o, Config->ExpireTimeout, Anope::CurTime, true) { } + ExpireCallback(Module *o) : Timer(o, Config->GetBlock("options")->Get<time_t>("expiretimeout"), Anope::CurTime, true) { } void Tick(time_t) anope_override { if (Anope::NoExpire || Anope::ReadOnly) return; + time_t unconfirmed_expire = Config->GetModule(this->GetOwner())->Get<time_t>("unconfirmedexpire", "1d"); + time_t nickserv_expire = Config->GetModule(this->GetOwner())->Get<time_t>("expire"); + for (nickalias_map::const_iterator it = NickAliasList->begin(), it_end = NickAliasList->end(); it != it_end; ) { NickAlias *na = it->second; @@ -161,9 +167,9 @@ class ExpireCallback : public Timer bool expire = false; if (na->nc->HasExt("UNCONFIRMED")) - if (Config->NSUnconfirmedExpire && Anope::CurTime - na->time_registered >= Config->NSUnconfirmedExpire) + if (unconfirmed_expire && Anope::CurTime - na->time_registered >= unconfirmed_expire) expire = true; - if (Config->NSExpire && Anope::CurTime - na->last_seen >= Config->NSExpire) + if (nickserv_expire && Anope::CurTime - na->last_seen >= nickserv_expire) expire = true; if (na->HasExt("NO_EXPIRE")) expire = false; @@ -185,19 +191,16 @@ class ExpireCallback : public Timer class NickServCore : public Module { - MyNickServService mynickserv; + MyNickServService nickserv; ExpireCallback expires; + std::vector<Anope::string> defaults; public: - NickServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR), mynickserv(this), expires(this) + NickServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR), nickserv(this), expires(this) { - - NickServ = BotInfo::Find(Config->NickServ); - if (!NickServ) - throw ModuleException("No bot named " + Config->NickServ); - - Implementation i[] = { I_OnBotDelete, I_OnDelNick, I_OnDelCore, I_OnChangeCoreDisplay, I_OnNickIdentify, I_OnNickGroup, - I_OnNickUpdate, I_OnUserConnect, I_OnPostUserLogoff, I_OnServerSync, I_OnUserNickChange, I_OnPreHelp, I_OnPostHelp }; + Implementation i[] = { I_OnReload, I_OnBotDelete, I_OnDelNick, I_OnDelCore, I_OnChangeCoreDisplay, I_OnNickIdentify, I_OnNickGroup, + I_OnNickUpdate, I_OnUserConnect, I_OnPostUserLogoff, I_OnServerSync, I_OnUserNickChange, I_OnPreHelp, I_OnPostHelp, + I_OnNickCoreCreate, I_OnUserQuit }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } @@ -206,6 +209,28 @@ class NickServCore : public Module NickServ = NULL; } + void OnReload(Configuration::Conf *conf) anope_override + { + const Anope::string &nsnick = conf->GetModule(this)->Get<const Anope::string &>("client"); + + if (nsnick.empty()) + throw ConfigException(this->name + ": <client> must be defined"); + + BotInfo *bi = BotInfo::Find(nsnick, true); + if (!bi) + throw ConfigException(this->name + ": no bot named " + nsnick); + + NickServ = bi; + + spacesepstream(conf->GetModule(this)->Get<const Anope::string &>("defaults", "secure memo_signon memo_receive")).GetTokens(defaults); + if (defaults.empty()) + { + defaults.push_back("SECURE"); + defaults.push_back("MEMO_SIGNON"); + defaults.push_back("MEMO_RECEIVE"); + } + } + void OnBotDelete(BotInfo *bi) anope_override { if (bi == NickServ) @@ -246,14 +271,16 @@ class NickServCore : public Module void OnNickIdentify(User *u) anope_override { - if (!Config->NoNicknameOwnership) + Configuration::Block *block = Config->GetModule(this); + + if (!Config->GetBlock("options")->Get<bool>("nonicknameownership")) { const NickAlias *this_na = NickAlias::Find(u->nick); if (this_na && this_na->nc == u->Account() && u->Account()->HasExt("UNCONFIRMED") == false) u->SetMode(NickServ, "REGISTERED"); } - if (Config->NSModeOnID) + if (block->Get<bool>("modeonid", "yes")) for (User::ChanUserList::iterator it = u->chans.begin(), it_end = u->chans.end(); it != it_end; ++it) { ChanUserContainer *cc = it->second; @@ -262,17 +289,18 @@ class NickServCore : public Module c->SetCorrectModes(u, true, true); } - if (!Config->NSModesOnID.empty()) - u->SetModes(NickServ, "%s", Config->NSModesOnID.c_str()); + const Anope::string &modesonid = block->Get<const Anope::string &>("modesonid"); + if (!modesonid.empty()) + u->SetModes(NickServ, "%s", modesonid.c_str()); - if (Config->NSForceEmail && u->Account()->email.empty()) + if (block->Get<bool>("forceemail") && u->Account()->email.empty()) { u->SendMessage(NickServ, _("You must now supply an e-mail for your nick.\n" "This e-mail will allow you to retrieve your password in\n" "case you forget it.")); u->SendMessage(NickServ, _("Type \002%s%s SET EMAIL \037e-mail\037\002 in order to set your e-mail.\n" "Your privacy is respected; this e-mail won't be given to\n" - "any third-party person."), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str()); + "any third-party person."), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str()); } if (u->Account()->HasExt("UNCONFIRMED")) @@ -280,8 +308,9 @@ class NickServCore : public Module u->SendMessage(NickServ, _("Your email address is not confirmed. To confirm it, follow the instructions that were emailed to you when you registered.")); const NickAlias *this_na = NickAlias::Find(u->Account()->display); time_t time_registered = Anope::CurTime - this_na->time_registered; - if (Config->NSUnconfirmedExpire > time_registered) - u->SendMessage(NickServ, _("Your account will expire, if not confirmed, in %s"), Anope::Duration(Config->NSUnconfirmedExpire - time_registered).c_str()); + time_t unconfirmed_expire = Config->GetModule(this)->Get<time_t>("unconfirmedexpire", "1d"); + if (unconfirmed_expire > time_registered) + u->SendMessage(NickServ, _("Your account will expire, if not confirmed, in %s"), Anope::Duration(unconfirmed_expire - time_registered).c_str()); } } @@ -308,10 +337,11 @@ class NickServCore : public Module return; const NickAlias *na = NickAlias::Find(u->nick); - if (!Config->NoNicknameOwnership && !Config->NSUnregisteredNotice.empty() && !na) - u->SendMessage(NickServ, Config->NSUnregisteredNotice); + const Anope::string &unregistered_notice = Config->GetModule(this)->Get<const Anope::string &>("unregistered_notice"); + if (!Config->GetBlock("options")->Get<bool>("nonicknameownership") && !unregistered_notice.empty() && !na) + u->SendMessage(NickServ, unregistered_notice); else if (na) - this->mynickserv.Validate(u); + this->nickserv.Validate(u); } void OnPostUserLogoff(User *u) anope_override @@ -327,7 +357,7 @@ class NickServCore : public Module { User *u = it->second; if (u->server == s && !u->IsIdentified()) - this->mynickserv.Validate(u); + this->nickserv.Validate(u); } } @@ -340,13 +370,13 @@ class NickServCore : public Module /* Remove +r, but keep an account associated with the user */ u->RemoveMode(NickServ, "REGISTERED"); - this->mynickserv.Validate(u); + this->nickserv.Validate(u); } else { /* Reset +r and re-send account (even though it really should be set at this point) */ IRCD->SendLogin(u); - if (!Config->NoNicknameOwnership && na->nc == u->Account() && na->nc->HasExt("UNCONFIRMED") == false) + if (!Config->GetBlock("options")->Get<bool>("nonicknameownership") && na->nc == u->Account() && na->nc->HasExt("UNCONFIRMED") == false) u->SetMode(NickServ, "REGISTERED"); Log(NickServ) << u->GetMask() << " automatically identified for group " << u->Account()->display; } @@ -363,45 +393,67 @@ class NickServCore : public Module EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (!params.empty() || source.c || source.service->nick != Config->NickServ) + if (!params.empty() || source.c || source.service != NickServ) return EVENT_CONTINUE; - if (!Config->NoNicknameOwnership) + if (!Config->GetBlock("options")->Get<bool>("nonicknameownership")) source.Reply(_("\002%s\002 allows you to register a nickname and\n" "prevent others from using it. The following\n" "commands allow for registration and maintenance of\n" "nicknames; to use them, type \002%s%s \037command\037\002.\n" "For more information on a specific command, type\n" - "\002%s%s %s \037command\037\002.\n "), Config->NickServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str(), source.command.c_str()); + "\002%s%s %s \037command\037\002.\n "), NickServ->nick.c_str(), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str(), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str(), source.command.c_str()); else source.Reply(_("\002%s\002 allows you to register an account.\n" "The following commands allow for registration and maintenance of\n" "accounts; to use them, type \002%s%s \037command\037\002.\n" "For more information on a specific command, type\n" - "\002%s%s %s \037command\037\002.\n "), Config->NickServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str(), source.command.c_str()); + "\002%s%s %s \037command\037\002.\n "), NickServ->nick.c_str(), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str(), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str(), source.command.c_str()); return EVENT_CONTINUE; } void OnPostHelp(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (!params.empty() || source.c || source.service->nick != Config->NickServ) + if (!params.empty() || source.c || source.service != NickServ) return; if (source.IsServicesOper()) source.Reply(_(" \n" "Services Operators can also drop any nickname without needing\n" "to identify for the nick, and may view the access list for\n" "any nickname.")); - if (Config->NSExpire >= 86400) + time_t nickserv_expire = Config->GetModule(this)->Get<time_t>("expire"); + if (nickserv_expire >= 86400) source.Reply(_(" \n" "Accounts that are not used anymore are subject to \n" "the automatic expiration, i.e. they will be deleted\n" - "after %d days if not used."), Config->NSExpire / 86400); + "after %d days if not used."), nickserv_expire / 86400); source.Reply(_(" \n" "\002NOTICE:\002 This service is intended to provide a way for\n" "IRC users to ensure their identity is not compromised.\n" "It is \002NOT\002 intended to facilitate \"stealing\" of\n" "nicknames or other malicious actions. Abuse of %s\n" "will result in, at minimum, loss of the abused\n" - "nickname(s)."), Config->NickServ.c_str()); + "nickname(s)."), NickServ->nick.c_str()); + } + + void OnNickCoreCreate(NickCore *nc) + { + /* Set default flags */ + for (unsigned i = 0; i < defaults.size(); ++i) + this->ExtendMetadata(defaults[i].upper()); + } + + void OnUserQuit(User *u, const Anope::string &msg) + { + if (u->server && !u->server->GetQuitReason().empty() && Config->GetModule(this)->Get<bool>("hidenetsplitquit")) + return; + + /* Update last quit and last seen for the user */ + NickAlias *na = NickAlias::Find(u->nick); + if (na && !na->nc->HasExt("SUSPENDED") && (u->IsRecognized() || u->IsIdentified(true))) + { + na->last_seen = Anope::CurTime; + na->last_quit = msg; + } } }; diff --git a/modules/pseudoclients/nickserv.h b/modules/pseudoclients/nickserv.h index 63923de2b..b20d6ebd1 100644 --- a/modules/pseudoclients/nickserv.h +++ b/modules/pseudoclients/nickserv.h @@ -4,7 +4,9 @@ class NickServService : public Service { public: - NickServService(Module *m) : Service(m, "NickServService", "NickServ") { } + NickServService(Module *m) : Service(m, "NickServService", "NickServ") + { + } virtual void Validate(User *u) = 0; virtual void Login(User *u, NickAlias *na) = 0; diff --git a/modules/pseudoclients/operserv.cpp b/modules/pseudoclients/operserv.cpp index ab67ceb47..a3a384cea 100644 --- a/modules/pseudoclients/operserv.cpp +++ b/modules/pseudoclients/operserv.cpp @@ -161,12 +161,7 @@ class OperServCore : public Module OperServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR), sglines(this), sqlines(this), snlines(this) { - - OperServ = BotInfo::Find(Config->OperServ); - if (!OperServ) - throw ModuleException("No bot named " + Config->OperServ); - - Implementation i[] = { I_OnBotDelete, I_OnBotPrivmsg, I_OnServerQuit, I_OnUserModeSet, I_OnUserModeUnset, I_OnUserConnect, I_OnUserNickChange, I_OnPreHelp }; + Implementation i[] = { I_OnReload, I_OnBotDelete, I_OnBotPrivmsg, I_OnServerQuit, I_OnUserModeSet, I_OnUserModeUnset, I_OnUserConnect, I_OnUserNickChange, I_OnPreHelp }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); /* Yes, these are in this order for a reason. Most violent->least violent. */ @@ -188,6 +183,20 @@ class OperServCore : public Module XLineManager::UnregisterXLineManager(&snlines); } + void OnReload(Configuration::Conf *conf) anope_override + { + const Anope::string &osnick = conf->GetModule(this)->Get<const Anope::string &>("client"); + + if (osnick.empty()) + throw ConfigException(this->name + ": <client> must be defined"); + + BotInfo *bi = BotInfo::Find(osnick, true); + if (!bi) + throw ConfigException(this->name + ": no bot named " + osnick); + + OperServ = bi; + } + void OnBotDelete(BotInfo *bi) anope_override { if (bi == OperServ) @@ -196,10 +205,10 @@ class OperServCore : public Module EventReturn OnBotPrivmsg(User *u, BotInfo *bi, Anope::string &message) anope_override { - if (Config->OSOpersOnly && !u->HasMode("OPER") && bi->nick == Config->OperServ) + if (bi == OperServ && !u->HasMode("OPER") && Config->GetModule(this)->Get<bool>("opersonly")) { u->SendMessage(bi, ACCESS_DENIED); - Log(OperServ, "bados") << "Denied access to " << Config->OperServ << " from " << u->GetMask() << " (non-oper)"; + Log(OperServ, "bados") << "Denied access to " << bi->nick << " from " << u->GetMask() << " (non-oper)"; return EVENT_STOP; } @@ -243,9 +252,9 @@ class OperServCore : public Module EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (!params.empty() || source.c || source.service->nick != Config->OperServ) + if (!params.empty() || source.c || source.service != OperServ) return EVENT_CONTINUE; - source.Reply(_("%s commands:"), Config->OperServ.c_str()); + source.Reply(_("%s commands:"), OperServ->nick.c_str()); return EVENT_CONTINUE; } }; |