diff options
Diffstat (limited to 'modules')
65 files changed, 642 insertions, 318 deletions
diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index 1ae397cc3..9078f2654 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -36,7 +36,7 @@ macro(build_modules SRC) add_library(${SO} MODULE ${MODULE_SRC}) # Windows requires this because it's weird if(WIN32) - set(WIN32_NO_LIBS "/nodefaultlib:\"libcmt.lib\"") + set(WIN32_NO_LIBS "/nodefaultlib:\"libcmt.lib\" /OPT:NOREF") else(WIN32) set(WIN32_NO_LIBS) endif(WIN32) diff --git a/modules/bs_autoassign.cpp b/modules/bs_autoassign.cpp index e9a6e062b..170d32d38 100644 --- a/modules/bs_autoassign.cpp +++ b/modules/bs_autoassign.cpp @@ -24,7 +24,7 @@ class BSAutoAssign : public Module if (bot.empty()) return; - BotInfo *bi = BotInfo::Find(bot); + BotInfo *bi = BotInfo::Find(bot, true); if (bi == NULL) { Log(this) << "bs_autoassign is configured to assign bot " << bot << ", but it does not exist?"; diff --git a/modules/commands/bs_bot.cpp b/modules/commands/bs_bot.cpp index 2413e6b6d..f4beba6e6 100644 --- a/modules/commands/bs_bot.cpp +++ b/modules/commands/bs_bot.cpp @@ -202,7 +202,10 @@ class CommandBSBot : public Command } if (!user.empty()) + { IRCD->SendQuit(bi, "Quit: Be right back"); + bi->introduced = false; + } else IRCD->SendNickChange(bi, nick); @@ -217,18 +220,7 @@ class CommandBSBot : public Command bi->realname = real; if (!user.empty()) - { - IRCD->SendClientIntroduction(bi); - unsigned minusers = Config->GetBlock("botserv")->Get<unsigned>("minusers"); - const std::set<ChanServ::Channel *> &channels = bi->GetChannels(); - for (std::set<ChanServ::Channel *>::const_iterator it = channels.begin(), it_end = channels.end(); it != it_end; ++it) - { - const ChanServ::Channel *ci = *it; - - if (ci->c && ci->c->users.size() >= minusers) - bi->Join(ci->c); - } - } + bi->OnKill(); source.Reply(_("Bot \002{0}\002 has been changed to \002{1}!{2}@{3}\002 (\002{4}\002)."), oldnick, bi->nick, bi->GetIdent(), bi->host, bi->realname); Log(LOG_ADMIN, source, this) << "CHANGE " << oldnick << " to " << bi->GetMask() << " " << bi->realname; diff --git a/modules/commands/bs_kick.cpp b/modules/commands/bs_kick.cpp index c0ea685c5..b263b3988 100644 --- a/modules/commands/bs_kick.cpp +++ b/modules/commands/bs_kick.cpp @@ -322,7 +322,7 @@ class CommandBSKickBolds : public CommandBSKickBase public: CommandBSKickBolds(Module *creator) : CommandBSKickBase(creator, "botserv/kick/bolds", 2, 3) { - this->SetDesc(_("Configures badwords kicker")); + this->SetDesc(_("Configures bolds kicker")); this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]")); } diff --git a/modules/commands/cs_access.cpp b/modules/commands/cs_access.cpp index c9dfe08cb..a1153cac6 100644 --- a/modules/commands/cs_access.cpp +++ b/modules/commands/cs_access.cpp @@ -185,12 +185,12 @@ class CommandCSAccess : public Command for (unsigned i = ci->GetAccessCount(); i > 0; --i) { const ChanServ::ChanAccess *access = ci->GetAccess(i - 1); - if (mask.equals_ci(access->mask)) + if (mask.equals_ci(access->Mask())) { /* Don't allow lowering from a level >= u_level */ if ((!highest || *access >= *highest) && !u_access.founder && !source.HasPriv("chanserv/access/modify")) { - source.Reply(_("Access denied. You do not have enough privileges on \002{0}\002 to lower the access of \002{1}\002."), ci->name, access->mask); + source.Reply(_("Access denied. You do not have enough privileges on \002{0}\002 to lower the access of \002{1}\002."), ci->name, access->Mask()); return; } delete ci->EraseAccess(i - 1); @@ -209,8 +209,7 @@ class CommandCSAccess : public Command if (!provider) return; AccessChanAccess *access = anope_dynamic_static_cast<AccessChanAccess *>(provider->Create()); - access->ci = ci; - access->mask = mask; + access->SetMask(mask, ci); access->creator = source.GetNick(); access->level = level; access->last_seen = 0; @@ -221,9 +220,9 @@ class CommandCSAccess : public Command Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to add " << mask << " with level " << level; if (p != NULL) - source.Reply(_("\002{0}\002 added to the access list of \002{1}\002 with privilege \002{2}\002 (level \002{3}\002)."), access->mask, ci->name, p->name, level); + source.Reply(_("\002{0}\002 added to the access list of \002{1}\002 with privilege \002{2}\002 (level \002{3}\002)."), access->Mask(), ci->name, p->name, level); else - source.Reply(_("\002{0}\002 added to the access list of \002{1}\002 at level \002{2}\002."), access->mask, ci->name, level); + source.Reply(_("\002{0}\002 added to the access list of \002{1}\002 at level \002{2}\002."), access->Mask(), ci->name, level); } void DoDel(CommandSource &source, ChanServ::Channel *ci, const std::vector<Anope::string> ¶ms) @@ -294,7 +293,7 @@ class CommandCSAccess : public Command ChanServ::AccessGroup ag = source.AccessFor(ci); const ChanServ::ChanAccess *u_highest = ag.Highest(); - if ((!u_highest || *u_highest <= *access) && !ag.founder && !this->override && !access->mask.equals_ci(source.nc->display)) + if ((!u_highest || *u_highest <= *access) && !ag.founder && !this->override && access->GetAccount() != source.nc) { denied = true; return; @@ -302,9 +301,9 @@ class CommandCSAccess : public Command ++deleted; if (!Nicks.empty()) - Nicks += ", " + access->mask; + Nicks += ", " + access->Mask(); else - Nicks = access->mask; + Nicks = access->Mask(); ci->EraseAccess(Number - 1); @@ -323,15 +322,15 @@ class CommandCSAccess : public Command for (unsigned i = ci->GetAccessCount(); i > 0; --i) { ChanServ::ChanAccess *access = ci->GetAccess(i - 1); - if (mask.equals_ci(access->mask)) + if (mask.equals_ci(access->Mask())) { - if (!access->mask.equals_ci(source.nc->display) && !u_access.founder && (!highest || *highest <= *access) && !source.HasPriv("chanserv/access/modify")) - source.Reply(_("Access denied. You do not have enough privileges on \002{0}\002 to remove the access of \002{1}\002."), ci->name, access->mask); + if (access->GetAccount() != source.nc && !u_access.founder && (!highest || *highest <= *access) && !source.HasPriv("chanserv/access/modify")) + source.Reply(_("Access denied. You do not have enough privileges on \002{0}\002 to remove the access of \002{1}\002."), ci->name, access->Mask()); else { - source.Reply(_("\002{0}\002 deleted from the access list of \002{1}\002."), access->mask, ci->name); - bool override = !u_access.founder && !u_access.HasPriv("ACCESS_CHANGE") && !access->mask.equals_ci(source.nc->display); - Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << access->mask; + source.Reply(_("\002{0}\002 deleted from the access list of \002{1}\002."), access->Mask(), ci->name); + bool override = !u_access.founder && !u_access.HasPriv("ACCESS_CHANGE") && !access->Mask().equals_ci(source.nc->display); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << access->Mask(); ci->EraseAccess(i - 1); Event::OnAccessDel(&Event::AccessDel::OnAccessDel, ci, source, access); @@ -393,7 +392,7 @@ class CommandCSAccess : public Command ListFormatter::ListEntry entry; entry["Number"] = stringify(number); entry["Level"] = access->AccessSerialize(); - entry["Mask"] = access->mask; + entry["Mask"] = access->Mask(); entry["By"] = access->creator; entry["Last seen"] = timebuf; this->list.AddEntry(entry); @@ -408,7 +407,7 @@ class CommandCSAccess : public Command { const ChanServ::ChanAccess *access = ci->GetAccess(i); - if (!nick.empty() && !Anope::Match(access->mask, nick)) + if (!nick.empty() && !Anope::Match(access->Mask(), nick)) continue; Anope::string timebuf; @@ -430,7 +429,7 @@ class CommandCSAccess : public Command ListFormatter::ListEntry entry; entry["Number"] = stringify(i + 1); entry["Level"] = access->AccessSerialize(); - entry["Mask"] = access->mask; + entry["Mask"] = access->Mask(); entry["By"] = access->creator; entry["Last seen"] = timebuf; list.AddEntry(entry); diff --git a/modules/commands/cs_ban.cpp b/modules/commands/cs_ban.cpp index 3571ccdf3..e8674600d 100644 --- a/modules/commands/cs_ban.cpp +++ b/modules/commands/cs_ban.cpp @@ -19,15 +19,16 @@ class TempBan : public Timer private: Anope::string channel; Anope::string mask; + Anope::string mode; public: - TempBan(time_t seconds, Channel *c, const Anope::string &banmask) : Timer(me, seconds), channel(c->name), mask(banmask) { } + TempBan(time_t seconds, Channel *c, const Anope::string &banmask, const Anope::string &mod) : Timer(me, seconds), channel(c->name), mask(banmask), mode(mod) { } void Tick(time_t ctime) override { Channel *c = Channel::Find(this->channel); if (c) - c->RemoveMode(NULL, "BAN", this->mask); + c->RemoveMode(NULL, mode, this->mask); } }; @@ -43,6 +44,8 @@ class CommandCSBan : public Command void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override { const Anope::string &chan = params[0]; + Configuration::Block *block = Config->GetCommand(source); + const Anope::string &mode = block->Get<Anope::string>("mode", "BAN"); ChanServ::Channel *ci = ChanServ::Find(chan); if (ci == NULL) @@ -58,9 +61,9 @@ class CommandCSBan : public Command return; } - if (IRCD->GetMaxListFor(c) && c->HasMode("BAN") >= IRCD->GetMaxListFor(c)) + if (IRCD->GetMaxListFor(c) && c->HasMode(mode) >= IRCD->GetMaxListFor(c)) { - source.Reply(_("The ban list for %s is full."), c->name.c_str()); + source.Reply(_("The %s list for %s is full."), mode.lower().c_str(), c->name.c_str()); return; } @@ -141,12 +144,12 @@ class CommandCSBan : public Command bool override = !u_access.HasPriv("BAN") || (u != u2 && ci->HasExt("PEACE") && u2_access >= u_access); Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "for " << mask; - if (!c->HasMode("BAN", mask)) + if (!c->HasMode(mode, mask)) { - c->SetMode(NULL, "BAN", mask); + c->SetMode(NULL, mode, mask); if (ban_time) { - new TempBan(ban_time, c, mask); + new TempBan(ban_time, c, mask, mode); source.Reply(_("Ban on \002{0}\002 expires in \002{1}\002."), mask, Anope::Duration(ban_time, source.GetAccount())); } } @@ -155,10 +158,13 @@ class CommandCSBan : public Command if (!c->FindUser(u2)) return; - if (ci->HasExt("SIGNKICK") || (ci->HasExt("SIGNKICK_LEVEL") && !source.AccessFor(ci).HasPriv("SIGNKICK"))) - c->Kick(ci->WhoSends(), u2, "%s (%s)", reason.c_str(), source.GetNick().c_str()); - else - c->Kick(ci->WhoSends(), u2, "%s", reason.c_str()); + if (block->Get<bool>("kick", "yes")) + { + if (ci->HasExt("SIGNKICK") || (ci->HasExt("SIGNKICK_LEVEL") && !source.AccessFor(ci).HasPriv("SIGNKICK"))) + c->Kick(ci->WhoSends(), u2, "%s (%s)", reason.c_str(), source.GetNick().c_str()); + else + c->Kick(ci->WhoSends(), u2, "%s", reason.c_str()); + } } else { @@ -166,12 +172,12 @@ class CommandCSBan : public Command bool override = !founder && !u_access.HasPriv("BAN"); Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "for " << target; - if (!c->HasMode("BAN", target)) + if (!c->HasMode(mode, target)) { - c->SetMode(NULL, "BAN", target); + c->SetMode(NULL, mode, target); if (ban_time) { - new TempBan(ban_time, c, target); + new TempBan(ban_time, c, target, mode); source.Reply(_("Ban on \002{0}\002 expires in \002{1}\002."), target, Anope::Duration(ban_time, source.GetAccount())); } } @@ -197,11 +203,14 @@ class CommandCSBan : public Command else if (uc->user->IsProtected()) continue; - ++kicked; - if (ci->HasExt("SIGNKICK") || (ci->HasExt("SIGNKICK_LEVEL") && !u_access.HasPriv("SIGNKICK"))) - c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s) (%s)", reason.c_str(), target.c_str(), source.GetNick().c_str()); - else - c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s)", reason.c_str(), target.c_str()); + if (block->Get<bool>("kick", "yes")) + { + ++kicked; + if (ci->HasExt("SIGNKICK") || (ci->HasExt("SIGNKICK_LEVEL") && !u_access.HasPriv("SIGNKICK"))) + c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s) (%s)", reason.c_str(), target.c_str(), source.GetNick().c_str()); + else + c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s)", reason.c_str(), target.c_str()); + } } } diff --git a/modules/commands/cs_clone.cpp b/modules/commands/cs_clone.cpp index a32320131..25ed88c96 100644 --- a/modules/commands/cs_clone.cpp +++ b/modules/commands/cs_clone.cpp @@ -113,7 +113,7 @@ public: unsigned count = 0; for (unsigned i = 0; i < target_ci->GetAccessCount(); ++i) - masks.insert(target_ci->GetAccess(i)->mask); + masks.insert(target_ci->GetAccess(i)->Mask()); for (unsigned i = 0; i < ci->GetAccessCount(); ++i) { @@ -123,13 +123,12 @@ public: if (access_max && target_ci->GetDeepAccessCount() >= access_max) break; - if (masks.count(taccess->mask)) + if (masks.count(taccess->Mask())) continue; - masks.insert(taccess->mask); + masks.insert(taccess->Mask()); ChanServ::ChanAccess *newaccess = provider->Create(); - newaccess->ci = target_ci; - newaccess->mask = taccess->mask; + newaccess->SetMask(taccess->Mask(), target_ci); newaccess->creator = taccess->creator; newaccess->last_seen = taccess->last_seen; newaccess->created = taccess->created; diff --git a/modules/commands/cs_flags.cpp b/modules/commands/cs_flags.cpp index c7953f0c9..7e17a1b47 100644 --- a/modules/commands/cs_flags.cpp +++ b/modules/commands/cs_flags.cpp @@ -142,7 +142,7 @@ class CommandCSFlags : public Command for (current_idx = ci->GetAccessCount(); current_idx > 0; --current_idx) { ChanServ::ChanAccess *access = ci->GetAccess(current_idx - 1); - if (mask.equals_ci(access->mask)) + if (mask.equals_ci(access->Mask())) { // Flags allows removing others that have the same access as you, // but no other access system does. @@ -154,7 +154,7 @@ class CommandCSFlags : public Command override = true; else { - source.Reply(_("Access denied. You do not have enough privileges on \002{0}\002 to modify the access of \002{1}\002."), ci->name, access->mask); + source.Reply(_("Access denied. You do not have enough privileges on \002{0}\002 to modify the access of \002{1}\002."), ci->name, access->Mask()); return; } } @@ -260,8 +260,7 @@ class CommandCSFlags : public Command if (!provider) return; FlagsChanAccess *access = anope_dynamic_static_cast<FlagsChanAccess *>(provider->Create()); - access->ci = ci; - access->mask = mask; + access->SetMask(mask, ci); access->creator = source.GetNick(); access->last_seen = current ? current->last_seen : 0; access->created = Anope::CurTime; @@ -278,12 +277,12 @@ class CommandCSFlags : public Command if (p != NULL) { if (add) - source.Reply(_("Privilege \002{0}\002 added to \002{1}\002 on \002{2}\002, new flags are +\002{3}\002"), p->name, access->mask, ci->name, access->AccessSerialize()); + source.Reply(_("Privilege \002{0}\002 added to \002{1}\002 on \002{2}\002, new flags are +\002{3}\002"), p->name, access->Mask(), ci->name, access->AccessSerialize()); else - source.Reply(_("Privilege \002{0}\002 removed from \002{1}\002 on \002{2}\002, new flags are +\002{3}\002"), p->name, access->mask, ci->name, access->AccessSerialize()); + source.Reply(_("Privilege \002{0}\002 removed from \002{1}\002 on \002{2}\002, new flags are +\002{3}\002"), p->name, access->Mask(), ci->name, access->AccessSerialize()); } else - source.Reply(_("Flags for \002{0}\002 on \002{1}\002 set to +\002{2}\002"), access->mask, ci->name, access->AccessSerialize()); + source.Reply(_("Flags for \002{0}\002 on \002{1}\002 set to +\002{2}\002"), access->Mask(), ci->name, access->AccessSerialize()); } void DoList(CommandSource &source, ChanServ::Channel *ci, const std::vector<Anope::string> ¶ms) @@ -317,14 +316,14 @@ class CommandCSFlags : public Command if (pass == false) continue; } - else if (!Anope::Match(access->mask, arg)) + else if (!Anope::Match(access->Mask(), arg)) continue; } ListFormatter::ListEntry entry; ++count; entry["Number"] = stringify(i + 1); - entry["Mask"] = access->mask; + entry["Mask"] = access->Mask(); entry["Flags"] = flags; entry["Creator"] = access->creator; entry["Created"] = Anope::strftime(access->created, source.nc, true); diff --git a/modules/commands/cs_list.cpp b/modules/commands/cs_list.cpp index c8901fa03..ba3c95aa3 100644 --- a/modules/commands/cs_list.cpp +++ b/modules/commands/cs_list.cpp @@ -12,6 +12,7 @@ #include "module.h" #include "modules/cs_info.h" #include "modules/cs_set.h" +#include "modules/cs_mode.h" class CommandCSList : public Command { @@ -89,6 +90,11 @@ class CommandCSList : public Command continue; if (ci->c && ci->c->HasMode("SECRET")) continue; + + ModeLocks *ml = ci->GetExt<ModeLocks>("modelocks"); + const ModeLock *secret = ml ? ml->GetMLock("SECRET") : NULL; + if (secret && secret->set) + continue; } if (suspended && !ci->HasExt("CS_SUSPENDED")) @@ -97,7 +103,7 @@ class CommandCSList : public Command if (channoexpire && !ci->HasExt("CS_NO_EXPIRE")) continue; - 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 (pattern.equals_ci(ci->name) || ci->name.equals_ci(spattern) || Anope::Match(ci->name, pattern, false, true) || Anope::Match(ci->name, spattern, false, true) || Anope::Match(ci->desc, pattern, false, true) || Anope::Match(ci->last_topic, pattern, false, true)) { if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nchans <= listmax) { diff --git a/modules/commands/cs_mode.cpp b/modules/commands/cs_mode.cpp index 696d0214f..d197102c7 100644 --- a/modules/commands/cs_mode.cpp +++ b/modules/commands/cs_mode.cpp @@ -491,8 +491,7 @@ class CommandCSMode : public Command for (unsigned j = 0; j < ModeManager::GetChannelModes().size(); ++j) { ChannelMode *cm = ModeManager::GetChannelModes()[j]; - if (!cm) - continue; + if (!u || cm->CanSet(u) || can_override) { if (cm->type == MODE_REGULAR || (!adding && cm->type == MODE_PARAM)) @@ -861,7 +860,7 @@ class CommandCSModes : public Command class CSMode : public Module , public EventHook<Event::CheckModes> - , public EventHook<Event::CreateChan> + , public EventHook<Event::ChanRegistered> , public EventHook<Event::ChanInfo> { CommandCSMode commandcsmode; @@ -874,7 +873,7 @@ class CSMode : public Module public: CSMode(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR) , EventHook<Event::CheckModes>("OnCheckModes") - , EventHook<Event::CreateChan>("OnCreateChan") + , EventHook<Event::ChanRegistered>("OnChanRegistered") , EventHook<Event::ChanInfo>("OnChanInfo") , commandcsmode(this) , commandcsmodes(this) @@ -958,7 +957,7 @@ class CSMode : public Module } } - void OnCreateChan(ChanServ::Channel *ci) override + void OnChanRegistered(ChanServ::Channel *ci) override { ModeLocks *ml = modelocks.Require(ci); Anope::string mlock; diff --git a/modules/commands/cs_seen.cpp b/modules/commands/cs_seen.cpp index 8ae9814a1..8bec55967 100644 --- a/modules/commands/cs_seen.cpp +++ b/modules/commands/cs_seen.cpp @@ -239,7 +239,7 @@ class CommandSeen : public Command { ChanServ::ChanAccess *a = ag[i]; - if (*a->nc == na->nc && a->last_seen > last) + if (a->GetAccount() == na->nc && a->last_seen > last) last = a->last_seen; } diff --git a/modules/commands/cs_set_misc.cpp b/modules/commands/cs_set_misc.cpp index b057b1398..4b1a07e4a 100644 --- a/modules/commands/cs_set_misc.cpp +++ b/modules/commands/cs_set_misc.cpp @@ -15,7 +15,7 @@ static Module *me; -static std::map<Anope::string, Anope::string> descriptions; +static Anope::map<Anope::string> descriptions; struct CSMiscData; static Anope::map<ExtensibleItem<CSMiscData> *> items; diff --git a/modules/commands/cs_status.cpp b/modules/commands/cs_status.cpp index e559f7749..aa8eb701d 100644 --- a/modules/commands/cs_status.cpp +++ b/modules/commands/cs_status.cpp @@ -68,7 +68,7 @@ public: { ChanServ::ChanAccess *acc = ag[i]; - source.Reply(_("\002{0}\002 matches access entry \002{1}\002, which has privilege \002{2}\002."), nick, acc->mask, acc->AccessSerialize()); + source.Reply(_("\002{0}\002 matches access entry \002{1}\002, which has privilege \002{2}\002."), nick, acc->Mask(), acc->AccessSerialize()); } } diff --git a/modules/commands/cs_suspend.cpp b/modules/commands/cs_suspend.cpp index b97760bd9..d389783b0 100644 --- a/modules/commands/cs_suspend.cpp +++ b/modules/commands/cs_suspend.cpp @@ -201,6 +201,20 @@ class CSSuspend : public Module Serialize::Type suspend_type; EventHandlers<Event::ChanSuspend> onchansuspend; EventHandlers<Event::ChanUnsuspend> onchanunsuspend; + std::vector<Anope::string> show; + + struct trim + { + Anope::string operator()(Anope::string s) const + { + return s.trim(); + } + }; + + bool Show(CommandSource &source, const Anope::string &what) const + { + return source.IsOper() || std::find(show.begin(), show.end(), what) != show.end(); + } public: CSSuspend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR) @@ -220,18 +234,19 @@ class CSSuspend : public Module void OnChanInfo(CommandSource &source, ChanServ::Channel *ci, InfoFormatter &info, bool show_hidden) override { CSSuspendInfo *si = suspend.Get(ci); - if (si) - { + if (!si) + return; + + if (show_hidden || Show(source, "suspended")) info[_("Suspended")] = _("This channel is \002suspended\002."); - if (!si->by.empty()) - info[_("Suspended by")] = si->by; - if (!si->reason.empty()) - info[_("Suspend reason")] = si->reason; - if (si->when) - info[_("Suspended on")] = Anope::strftime(si->when, source.GetAccount(), true); - if (si->expires) - info[_("Suspension expires")] = Anope::strftime(si->expires, source.GetAccount(), true); - } + if (!si->by.empty() && (show_hidden || Show(source, "by"))) + info[_("Suspended by")] = si->by; + if (!si->reason.empty() && (show_hidden || Show(source, "reason"))) + info[_("Suspend reason")] = si->reason; + if (si->when && (show_hidden || Show(source, "on"))) + info[_("Suspended on")] = Anope::strftime(si->when, source.GetAccount(), true); + if (si->expires && (show_hidden || Show(source, "expires"))) + info[_("Suspension expires")] = Anope::strftime(si->expires, source.GetAccount(), true); } void OnPreChanExpire(ChanServ::Channel *ci, bool &expire) override diff --git a/modules/commands/cs_unban.cpp b/modules/commands/cs_unban.cpp index cf06b82f9..8937b8142 100644 --- a/modules/commands/cs_unban.cpp +++ b/modules/commands/cs_unban.cpp @@ -22,6 +22,13 @@ class CommandCSUnban : public Command void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override { + ChannelMode *cm = ModeManager::FindChannelModeByName("BAN"); + if (!cm) + return; + + std::vector<ChannelMode *> modes = cm->listeners; + modes.push_back(cm); + if (params.empty()) { if (!source.GetUser()) @@ -38,8 +45,9 @@ class CommandCSUnban : public Command if (!ci->c || !source.AccessFor(ci).HasPriv("UNBAN")) continue; - if (ci->c->Unban(source.GetUser(), true)) - ++count; + for (unsigned j = 0; j < modes.size(); ++j) + if (ci->c->Unban(source.GetUser(), modes[j]->name, true)) + ++count; } Log(LOG_COMMAND, source, this, NULL) << "on all channels"; @@ -82,7 +90,8 @@ class CommandCSUnban : public Command bool override = !source.AccessFor(ci).HasPriv("UNBAN") && source.HasPriv("chanserv/kick"); Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to unban " << u2->nick; - ci->c->Unban(u2, source.GetUser() == u2); + for (unsigned i = 0; i < modes.size(); ++i) + ci->c->Unban(u2, modes[i]->name, source.GetUser() == u2); if (u2 == source.GetUser()) source.Reply(_("You have been unbanned from \002{0}\002."), ci->c->name); else diff --git a/modules/commands/cs_updown.cpp b/modules/commands/cs_updown.cpp index 7468331aa..0e487ff6c 100644 --- a/modules/commands/cs_updown.cpp +++ b/modules/commands/cs_updown.cpp @@ -81,8 +81,8 @@ class CommandCSUp : public Command } User *u = User::Find(nick, true); - Channel *c = ci->c; User *srcu = source.GetUser(); + Channel *c = ci->c; bool override = false; if (u == NULL) @@ -90,9 +90,13 @@ class CommandCSUp : public Command source.Reply(_("User \002{0}\002 isn't currently online."), nick); return; } - if (srcu && !srcu->FindChannel(c)) { + source.Reply(_("You must be in \002%s\002 to use this command."), c->name.c_str()); + return; + } + else if (!u->FindChannel(c)) + { source.Reply(_("You must be on channel \002{0}\002 to use this command."), c->name); return; } @@ -182,6 +186,7 @@ class CommandCSDown : public Command User *u = User::Find(nick, true); Channel *c = ci->c; + User *srcu = source.GetUser(); bool override = false; @@ -196,8 +201,12 @@ class CommandCSDown : public Command source.Reply(_("You must be on channel \002{0}\002 to use this command."), c->name); return; } - - if (!u->FindChannel(c)) + if (srcu && !srcu->FindChannel(c)) + { + source.Reply(_("You must be in \002%s\002 to use this command."), c->name.c_str()); + return; + } + else if (!u->FindChannel(c)) { source.Reply(_("\002%s\002 is not on channel %s."), u->nick, c->name); return; diff --git a/modules/commands/cs_xop.cpp b/modules/commands/cs_xop.cpp index 53730cb57..c3b43cd3e 100644 --- a/modules/commands/cs_xop.cpp +++ b/modules/commands/cs_xop.cpp @@ -182,11 +182,11 @@ class CommandCSXOP : public Command { const ChanServ::ChanAccess *a = ci->GetAccess(i); - if (a->mask.equals_ci(mask)) + if (a->Mask().equals_ci(mask)) { if ((!highest || *a >= *highest) && !access.founder && !source.HasPriv("chanserv/access/modify")) { - source.Reply(_("Access denied. You do not have enough privileges on \002{0}\002 to lower the access of \002{1}\002."), ci->name, a->mask); + source.Reply(_("Access denied. You do not have enough privileges on \002{0}\002 to lower the access of \002{1}\002."), ci->name, a->Mask()); return; } @@ -206,8 +206,7 @@ class CommandCSXOP : public Command if (!provider) return; XOPChanAccess *acc = anope_dynamic_static_cast<XOPChanAccess *>(provider->Create()); - acc->ci = ci; - acc->mask = mask; + acc->SetMask(mask, ci); acc->creator = source.GetNick(); acc->type = source.command.upper(); acc->last_seen = 0; @@ -217,7 +216,7 @@ class CommandCSXOP : public Command Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to add " << mask; Event::OnAccessAdd(&Event::AccessAdd::OnAccessAdd, ci, source, acc); - source.Reply(_("\002%s\002 added to %s %s list."), acc->mask.c_str(), ci->name.c_str(), source.command.c_str()); + source.Reply(_("\002%s\002 added to %s %s list."), acc->Mask(), ci->name.c_str(), source.command.c_str()); } void DoDel(CommandSource &source, ChanServ::Channel *ci, const std::vector<Anope::string> ¶ms) @@ -320,9 +319,9 @@ class CommandCSXOP : public Command ++deleted; if (!nicks.empty()) - nicks += ", " + caccess->mask; + nicks += ", " + caccess->Mask(); else - nicks = caccess->mask; + nicks = caccess->Mask(); ci->EraseAccess(number - 1); Event::OnAccessDel(&Event::AccessDel::OnAccessDel, ci, source, caccess); @@ -341,11 +340,11 @@ class CommandCSXOP : public Command if (a->provider->name != "access/xop" || source.command.upper() != a->AccessSerialize()) continue; - if (a->mask.equals_ci(mask)) + if (a->Mask().equals_ci(mask)) { - Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << a->mask; + Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << a->Mask(); - source.Reply(_("\002%s\002 deleted from %s %s list."), a->mask.c_str(), ci->name.c_str(), source.command.c_str()); + source.Reply(_("\002%s\002 deleted from %s %s list."), a->Mask().c_str(), ci->name.c_str(), source.command.c_str()); ci->EraseAccess(i); Event::OnAccessDel(&Event::AccessDel::OnAccessDel, ci, source, a); @@ -405,7 +404,7 @@ class CommandCSXOP : public Command ListFormatter::ListEntry entry; entry["Number"] = stringify(Number); - entry["Mask"] = a->mask; + entry["Mask"] = a->Mask(); this->list.AddEntry(entry); } } nl_list(list, ci, nick, source); @@ -419,12 +418,12 @@ class CommandCSXOP : public Command if (a->provider->name != "access/xop" || source.command.upper() != a->AccessSerialize()) continue; - else if (!nick.empty() && !Anope::Match(a->mask, nick)) + else if (!nick.empty() && !Anope::Match(a->Mask(), nick)) continue; ListFormatter::ListEntry entry; entry["Number"] = stringify(i + 1); - entry["Mask"] = a->mask; + entry["Mask"] = a->Mask(); list.AddEntry(entry); } } diff --git a/modules/commands/ns_access.cpp b/modules/commands/ns_access.cpp index 95a93fea1..443686bca 100644 --- a/modules/commands/ns_access.cpp +++ b/modules/commands/ns_access.cpp @@ -186,7 +186,7 @@ class NSAccess : public Module { } - void OnNickRegister(User *u, NickServ::Nick *na) override + void OnNickRegister(User *u, NickServ::Nick *na, const Anope::string &) override { if (u && Config->GetModule(this)->Get<bool>("addaccessonreg")) na->nc->AddAccess(u->Mask()); diff --git a/modules/commands/ns_group.cpp b/modules/commands/ns_group.cpp index 62620f7c4..7a67337f9 100644 --- a/modules/commands/ns_group.cpp +++ b/modules/commands/ns_group.cpp @@ -138,12 +138,14 @@ class CommandNSGroup : public Command Log(LOG_COMMAND, source, this) << "and tried to group to suspended nick " << target->nick; source.Reply(_("\002{0}\002 is suspended."), target->nick); } + else if (na && Config->GetModule(this->owner)->Get<bool>("nogroupchange")) + source.Reply(_("Your nick is already registered.")); else if (na && *target->nc == *na->nc) source.Reply(_("You are already a member of the group of \002{0}\002."), target->nick); else if (na && na->nc != u->Account()) source.Reply(_("\002{0}\002 is already registered."), na->nick); else if (na && Config->GetModule(this->owner)->Get<bool>("nogroupchange")) - source.Reply(_("Your nick is already registered.")); + source.Reply(_("You are already registered.")); else if (maxaliases && target->nc->aliases->size() >= maxaliases && !target->nc->IsServicesOper()) source.Reply(_("There are too many nicknames in your group.")); else if (u->nick.length() <= guestnick.length() + 7 && @@ -155,7 +157,7 @@ class CommandNSGroup : public Command else { bool ok = false; - if (!na && u->Account()) + if (!na && u->Account() == target->nc) ok = true; NSCertList *cl = target->nc->GetExt<NSCertList>("certificates"); @@ -290,7 +292,7 @@ class CommandNSGList : public Command Anope::string expires; if (na2->HasExt("NS_NO_EXPIRE")) - expires = "Does not expire"; + expires = _("Does not expire"); else if (!nickserv_expire || Anope::NoExpire) ; else if (na2->nc->HasExt("UNCONFIRMED") && unconfirmed_expire) diff --git a/modules/commands/ns_info.cpp b/modules/commands/ns_info.cpp index a5bf571fc..bbec0fef0 100644 --- a/modules/commands/ns_info.cpp +++ b/modules/commands/ns_info.cpp @@ -66,9 +66,13 @@ class CommandNSInfo : public Command if (nick_online) { + bool shown = false; if (show_hidden && !na->last_realhost.empty()) + { info[_("Online from")] = na->last_realhost; - if (show_hidden || !na->nc->HasExt("HIDE_MASK")) + shown = true; + } + if ((show_hidden || !na->nc->HasExt("HIDE_MASK")) && (!shown || na->last_usermask != na->last_realhost)) info[_("Online from")] = na->last_usermask; else source.Reply(_("\002{0}\002 is currently online."), na->nick); diff --git a/modules/commands/ns_register.cpp b/modules/commands/ns_register.cpp index 1aa0595d4..c54ea3764 100644 --- a/modules/commands/ns_register.cpp +++ b/modules/commands/ns_register.cpp @@ -191,7 +191,7 @@ class CommandNSRegister : public Command Log(LOG_COMMAND, source, this) << "to register " << na->nick << " (email: " << (!na->nc->email.empty() ? na->nc->email : "none") << ")"; if (NickServ::Event::OnNickRegister) - NickServ::Event::OnNickRegister(&NickServ::Event::NickRegister::OnNickRegister, source.GetUser(), na); + NickServ::Event::OnNickRegister(&NickServ::Event::NickRegister::OnNickRegister, source.GetUser(), na, pass); if (na->nc->GetAccessCount()) source.Reply(_("\002{0}\002 has been registered under your hostmask: \002{1}\002"), u_nick, na->nc->GetAccess(0)); diff --git a/modules/commands/ns_set.cpp b/modules/commands/ns_set.cpp index 58311f0af..cec5e10b0 100644 --- a/modules/commands/ns_set.cpp +++ b/modules/commands/ns_set.cpp @@ -334,7 +334,7 @@ class CommandNSSetDisplay : public Command return; } - const NickServ::Nick *user_na = NickServ::FindNick(user), *na = NickServ::FindNick(param); + NickServ::Nick *user_na = NickServ::FindNick(user), *na = NickServ::FindNick(param); if (Config->GetModule("nickserv")->Get<bool>("nonicknameownership")) { @@ -362,6 +362,8 @@ class CommandNSSetDisplay : public Command Log(user_na->nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change the display of " << user_na->nc->display << " to " << na->nick; user_na->nc->SetDisplay(na); + if (source.GetUser()) + IRCD->SendLogin(source.GetUser(), na); source.Reply(_("The new display is now \002{0}\002."), user_na->nc->display); } @@ -762,7 +764,7 @@ class CommandNSSetLanguage : public Command if (MOD_RESULT == EVENT_STOP) return; - if (param != "en") + if (param != "en_US") for (unsigned j = 0; j < Language::Languages.size(); ++j) { if (Language::Languages[j] == param) @@ -789,7 +791,7 @@ class CommandNSSetLanguage : public Command { source.Reply(_("Changes the language services will use when sending messages to you (for example, when responding to a command you send). \037language\037 should be chosen from the following list of supported languages:")); - source.Reply(" en (English)"); + source.Reply(" en_US (English)"); for (unsigned j = 0; j < Language::Languages.size(); ++j) { const Anope::string &langname = Language::Translate(Language::Languages[j].c_str(), _("English")); diff --git a/modules/commands/ns_set_misc.cpp b/modules/commands/ns_set_misc.cpp index fc450b601..eb8ee63be 100644 --- a/modules/commands/ns_set_misc.cpp +++ b/modules/commands/ns_set_misc.cpp @@ -16,7 +16,7 @@ static Module *me; -static std::map<Anope::string, Anope::string> descriptions; +static Anope::map<Anope::string> descriptions; struct NSMiscData; static Anope::map<ExtensibleItem<NSMiscData> *> items; diff --git a/modules/commands/ns_suspend.cpp b/modules/commands/ns_suspend.cpp index 1dfc48995..8c29afecc 100644 --- a/modules/commands/ns_suspend.cpp +++ b/modules/commands/ns_suspend.cpp @@ -210,6 +210,20 @@ class NSSuspend : public Module Serialize::Type suspend_type; EventHandlers<Event::NickSuspend> onnicksuspend; EventHandlers<Event::NickUnsuspended> onnickunsuspend; + std::vector<Anope::string> show; + + struct trim + { + Anope::string operator()(Anope::string s) const + { + return s.trim(); + } + }; + + bool Show(CommandSource &source, const Anope::string &what) const + { + return source.IsOper() || std::find(show.begin(), show.end(), what) != show.end(); + } public: NSSuspend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR) @@ -225,21 +239,29 @@ class NSSuspend : public Module { } + void OnReload(Configuration::Conf *conf) override + { + Anope::string s = conf->GetModule(this)->Get<Anope::string>("show"); + commasepstream(s).GetTokens(show); + std::transform(show.begin(), show.end(), show.begin(), trim()); + } + void OnNickInfo(CommandSource &source, NickServ::Nick *na, InfoFormatter &info, bool show_hidden) override { NSSuspendInfo *s = suspend.Get(na->nc); - if (s) - { + if (!s) + return; + + if (show_hidden || Show(source, "suspended")) info[_("Suspended")] = _("This nickname is \002suspended\002."); - if (!s->by.empty()) - info[_("Suspended by")] = s->by; - if (!s->reason.empty()) - info[_("Suspend reason")] = s->reason; - if (s->when) - info[_("Suspended on")] = Anope::strftime(s->when, source.GetAccount(), true); - if (s->expires) - info[_("Suspension expires")] = Anope::strftime(s->expires, source.GetAccount(), true); - } + if (!s->by.empty() && (show_hidden || Show(source, "by"))) + info[_("Suspended by")] = s->by; + if (!s->reason.empty() && (show_hidden || Show(source, "reason"))) + info[_("Suspend reason")] = s->reason; + if (s->when && (show_hidden || Show(source, "on"))) + info[_("Suspended on")] = Anope::strftime(s->when, source.GetAccount(), true); + if (s->expires && (show_hidden || Show(source, "expires"))) + info[_("Suspension expires")] = Anope::strftime(s->expires, source.GetAccount(), true); } void OnPreNickExpire(NickServ::Nick *na, bool &expire) override diff --git a/modules/commands/os_akill.cpp b/modules/commands/os_akill.cpp index 0b8bd35fc..d5b9b6e70 100644 --- a/modules/commands/os_akill.cpp +++ b/modules/commands/os_akill.cpp @@ -151,6 +151,11 @@ class CommandOSAKill : public Command source.Reply(_("\002{0}\002 coverage is too wide; Please use a more specific mask."), mask); return; } + else if (mask.find('@') == Anope::string::npos) + { + source.Reply(_("Mask must be in the form \037user\037@\037host\037.")); + return; + } if (Config->GetModule("operserv")->Get<bool>("addakiller", "yes") && !source.GetNick().empty()) reason = "[" + source.GetNick() + "] " + reason; diff --git a/modules/commands/os_defcon.cpp b/modules/commands/os_defcon.cpp index a5608037d..20b687b4f 100644 --- a/modules/commands/os_defcon.cpp +++ b/modules/commands/os_defcon.cpp @@ -524,7 +524,7 @@ class OSDefcon : public Module if (DConfig.sessionlimit <= 0 || !session_service) return; - Session *session = session_service->FindSession(u->ip); + Session *session = session_service->FindSession(u->ip.addr()); Exception *exception = session_service->FindException(u); if (DConfig.Check(DEFCON_REDUCE_SESSION) && !exception) @@ -533,7 +533,7 @@ class OSDefcon : public Module { if (!DConfig.sle_reason.empty()) { - Anope::string message = DConfig.sle_reason.replace_all_cs("%IP%", u->ip); + Anope::string message = DConfig.sle_reason.replace_all_cs("%IP%", u->ip.addr()); u->SendMessage(OperServ, message); } if (!DConfig.sle_detailsloc.empty()) diff --git a/modules/commands/os_dns.cpp b/modules/commands/os_dns.cpp index d9dabcc66..340d66bbd 100644 --- a/modules/commands/os_dns.cpp +++ b/modules/commands/os_dns.cpp @@ -661,7 +661,7 @@ class CommandOSDNS : public Command } public: - CommandOSDNS(Module *creator) : Command(creator, "operserv/dns", 0, 3) + CommandOSDNS(Module *creator) : Command(creator, "operserv/dns", 0, 4) { this->SetDesc(_("Manage DNS zones for this network")); this->SetSyntax(_("ADDZONE \037zone.name\037")); diff --git a/modules/commands/os_jupe.cpp b/modules/commands/os_jupe.cpp index 38766faa3..e2dd30b3a 100644 --- a/modules/commands/os_jupe.cpp +++ b/modules/commands/os_jupe.cpp @@ -36,7 +36,7 @@ class CommandOSJupe : public Command { Anope::string rbuf = "Juped by " + source.GetNick() + (!reason.empty() ? ": " + reason : ""); /* Generate the new sid before quitting the old server, so they can't collide */ - Anope::string sid = Servers::TS6_SID_Retrieve(); + Anope::string sid = IRCD->SID_Retrieve(); if (server) { IRCD->SendSquit(server, rbuf); diff --git a/modules/commands/os_list.cpp b/modules/commands/os_list.cpp index 1ad4b3238..ea88b12ff 100644 --- a/modules/commands/os_list.cpp +++ b/modules/commands/os_list.cpp @@ -174,7 +174,7 @@ class CommandOSUserList : public Command if (!pattern.empty()) { - Anope::string mask = u2->nick + "!" + u2->GetIdent() + "@" + u2->GetDisplayedHost(), mask2 = u2->nick + "!" + u2->GetIdent() + "@" + u2->host, mask3 = u2->nick + "!" + u2->GetIdent() + "@" + (!u2->ip.empty() ? u2->ip : u2->host); + Anope::string mask = u2->nick + "!" + u2->GetIdent() + "@" + u2->GetDisplayedHost(), mask2 = u2->nick + "!" + u2->GetIdent() + "@" + u2->host, mask3 = u2->nick + "!" + u2->GetIdent() + "@" + u2->ip.addr(); if (!Anope::Match(mask, pattern) && !Anope::Match(mask2, pattern) && !Anope::Match(mask3, pattern)) continue; if (!modes.empty()) diff --git a/modules/commands/os_session.cpp b/modules/commands/os_session.cpp index 30af3ccbf..48f9fa033 100644 --- a/modules/commands/os_session.cpp +++ b/modules/commands/os_session.cpp @@ -66,10 +66,10 @@ class MySessionService : public SessionService for (std::vector<Exception *>::const_iterator it = this->Exceptions->begin(), it_end = this->Exceptions->end(); it != it_end; ++it) { Exception *e = *it; - if (Anope::Match(u->host, e->mask) || Anope::Match(u->ip, e->mask)) + if (Anope::Match(u->host, e->mask) || Anope::Match(u->ip.addr(), e->mask)) return e; - - if (cidr(e->mask).match(sockaddrs(u->ip))) + + if (cidr(e->mask).match(u->ip)) return e; } return NULL; @@ -111,9 +111,9 @@ class MySessionService : public SessionService return NULL; } - SessionMap::iterator FindSessionIterator(const Anope::string &ip) + SessionMap::iterator FindSessionIterator(const sockaddrs &ip) { - cidr c(ip, ip.find(':') != Anope::string::npos ? ipv6_cidr : ipv4_cidr); + cidr c(ip, ip.ipv6() ? ipv6_cidr : ipv4_cidr); if (!c.valid()) return this->Sessions.end(); return this->Sessions.find(c); @@ -655,7 +655,7 @@ class OSSession : public Module if (u->Quitting() || !session_limit || exempt || !u->server || u->server->IsULined()) return; - cidr u_ip(u->ip, u->ip.find(':') != Anope::string::npos ? ipv6_cidr : ipv4_cidr); + cidr u_ip(u->ip, u->ip.ipv6() ? ipv6_cidr : ipv4_cidr); if (!u_ip.valid()) return; @@ -685,7 +685,7 @@ class OSSession : public Module { if (!sle_reason.empty()) { - Anope::string message = sle_reason.replace_all_cs("%IP%", u->ip); + Anope::string message = sle_reason.replace_all_cs("%IP%", u->ip.addr()); u->SendMessage(OperServ, message); } if (!sle_detailsloc.empty()) @@ -709,7 +709,7 @@ class OSSession : public Module } else { - session = new Session(u->ip, u->ip.find(':') != Anope::string::npos ? ipv6_cidr : ipv4_cidr); + session = new Session(u->ip, u->ip.ipv6() ? ipv6_cidr : ipv4_cidr); } } diff --git a/modules/commands/os_stats.cpp b/modules/commands/os_stats.cpp index 1251226c3..a4a2a858a 100644 --- a/modules/commands/os_stats.cpp +++ b/modules/commands/os_stats.cpp @@ -14,7 +14,12 @@ struct Stats : Serializable { - Stats() : Serializable("Stats") { } + static Stats *me; + + Stats() : Serializable("Stats") + { + me = this; + } void Serialize(Serialize::Data &data) const override { @@ -26,10 +31,12 @@ struct Stats : Serializable { data["maxusercnt"] >> MaxUserCount; data["maxusertime"] >> MaxUserTime; - return NULL; + return me; } }; +Stats *Stats::me; + /** * Count servers connected to server s * @param s The server to start counting from @@ -237,6 +244,7 @@ class CommandOSStats : public Command }; class OSStats : public Module + , public EventHook<Event::UserConnect> { CommandOSStats commandosstats; Serialize::Type stats_type; @@ -244,11 +252,18 @@ class OSStats : public Module public: OSStats(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR) + , EventHook<Event::UserConnect>("OnUserConnect") , commandosstats(this) , stats_type("Stats", Stats::Unserialize) { } + + void OnUserConnect(User *u, bool &exempt) override + { + if (UserListByNick.size() == MaxUserCount && Anope::CurTime == MaxUserTime) + stats_saver.QueueUpdate(); + } }; MODULE_INIT(OSStats) diff --git a/modules/commands/os_svs.cpp b/modules/commands/os_svs.cpp index fb6808df3..35c3136a8 100644 --- a/modules/commands/os_svs.cpp +++ b/modules/commands/os_svs.cpp @@ -112,10 +112,10 @@ class CommandOSSVSJoin : public Command class CommandOSSVSPart : public Command { public: - CommandOSSVSPart(Module *creator) : Command(creator, "operserv/svspart", 2, 2) + CommandOSSVSPart(Module *creator) : Command(creator, "operserv/svspart", 2, 3) { this->SetDesc(_("Forcefully part a user from a channel")); - this->SetSyntax(_("\037user\037 \037channel\037")); + this->SetSyntax(_("\037nick\037 \037channel\037 [\037reason\037]")); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override @@ -128,6 +128,7 @@ class CommandOSSVSPart : public Command User *target = User::Find(params[0], true); Channel *c = Channel::Find(params[1]); + const Anope::string &reason = params.size() > 2 ? params[2] : ""; if (target == NULL) source.Reply(_("\002{0}\002 isn't currently online."), params[0]); else if (source.GetUser() != target && (target->IsProtected() || target->server == Me)) @@ -138,8 +139,11 @@ class CommandOSSVSPart : public Command source.Reply(_("\002{0}\002 is not in \002{1}\002."), target->nick, c->name); else { - IRCD->SendSVSPart(*source.service, target, params[1], ""); - Log(LOG_ADMIN, source, this) << "to force " << target->nick << " to part " << c->name; + IRCD->SendSVSPart(*source.service, target, params[1], reason); + if (!reason.empty()) + Log(LOG_ADMIN, source, this) << "to force " << target->nick << " to part " << c->name << " with reason " << reason; + else + Log(LOG_ADMIN, source, this) << "to force " << target->nick << " to part " << c->name; source.Reply(_("\002{0}\002 has been parted from \002{1}\002."), target->nick, c->name); } } diff --git a/modules/database/db_flatfile.cpp b/modules/database/db_flatfile.cpp index 266b79379..a2226a0ef 100644 --- a/modules/database/db_flatfile.cpp +++ b/modules/database/db_flatfile.cpp @@ -128,7 +128,7 @@ class DBFlatFile : public Module, public Pipe const std::vector<Anope::string> &type_order = Serialize::Type::GetTypeOrder(); std::set<Anope::string> dbs; - dbs.insert(Config->GetModule(this)->Get<const Anope::string>("database")); + dbs.insert(Config->GetModule(this)->Get<const Anope::string>("database", "anope.db")); for (unsigned i = 0; i < type_order.size(); ++i) { @@ -151,10 +151,14 @@ class DBFlatFile : public Module, public Pipe Log(LOG_DEBUG) << "db_flatfile: Attempting to rename " << *it << " to " << newname; if (rename(oldname.c_str(), newname.c_str())) { - Log(this) << "Unable to back up database " << *it << "!"; + Anope::string err = Anope::LastError(); + Log(this) << "Unable to back up database " << *it << " (" << err << ")!"; if (!Config->GetModule(this)->Get<bool>("nobackupok")) + { Anope::Quitting = true; + Anope::QuitReason = "Unable to back up database " + *it + " (" + err + ")"; + } continue; } @@ -350,7 +354,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") : Config->GetModule(this)->Get<const Anope::string>("database")); + const Anope::string &db_name = Anope::DataDir + "/" + (it->first ? (it->first->name + ".db") : Config->GetModule(this)->Get<const Anope::string>("database", "anope.db")); if (!f->is_open() || !f->good()) { diff --git a/modules/database/db_old.cpp b/modules/database/db_old.cpp index c541104d9..587a8f227 100644 --- a/modules/database/db_old.cpp +++ b/modules/database/db_old.cpp @@ -732,7 +732,7 @@ static void LoadBots() READ(read_int32(&created, f)); READ(read_int16(&chancount, f)); - BotInfo *bi = BotInfo::Find(nick); + BotInfo *bi = BotInfo::Find(nick, true); if (!bi) bi = new BotInfo(nick, user, host, real); bi->created = created; @@ -914,7 +914,7 @@ static void LoadChannels() Anope::string mask; READ(read_string(mask, f)); if (access) - access->mask = mask; + access->SetMask(mask, ci); READ(read_int32(&tmp32, f)); if (access) @@ -1002,7 +1002,7 @@ static void LoadChannels() } READ(read_string(buffer, f)); - ci->bi = BotInfo::Find(buffer); + ci->bi = BotInfo::Find(buffer, true); READ(read_int32(&tmp32, f)); if (tmp32 & OLD_BS_DONTKICKOPS) diff --git a/modules/extra/m_ldap.cpp b/modules/extra/m_ldap.cpp index efbef59f8..6c8da7688 100644 --- a/modules/extra/m_ldap.cpp +++ b/modules/extra/m_ldap.cpp @@ -1,4 +1,5 @@ /* RequiredLibraries: ldap,lber */ +/* RequiredWindowsLibraries: libldap,liblber */ #include "module.h" #include "modules/ldap.h" @@ -514,7 +515,7 @@ class ModuleLDAP : public Module, public Pipe ss->Start(); this->LDAPServices.insert(std::make_pair(connname, ss)); - Log(LOG_NORMAL, "ldap") << "LDAP: Successfully connected to server " << connname << " (" << server << ")"; + Log(LOG_NORMAL, "ldap") << "LDAP: Successfully initialized server " << connname << " (" << server << ")"; } catch (const LDAPException &ex) { diff --git a/modules/extra/m_ldap_authentication.cpp b/modules/extra/m_ldap_authentication.cpp index 9f2550e69..1b8b36fb4 100644 --- a/modules/extra/m_ldap_authentication.cpp +++ b/modules/extra/m_ldap_authentication.cpp @@ -105,7 +105,7 @@ class IdentifyInterface : public LDAPInterface { na = new NickServ::Nick(ii->req->GetAccount(), new NickServ::Account(ii->req->GetAccount())); na->last_realname = ii->user ? ii->user->realname : ii->req->GetAccount(); - NickServ::Event::OnNickRegister(&NickServ::Event::NickRegister::OnNickRegister, ii->user, na); + NickServ::Event::OnNickRegister(&NickServ::Event::NickRegister::OnNickRegister, ii->user, na, ii->req->GetPassword());; BotInfo *NickServ = Config->GetClient("NickServ"); if (ii->user && NickServ) ii->user->SendMessage(NickServ, _("Your account \002%s\002 has been successfully created."), na->nick.c_str()); @@ -311,7 +311,11 @@ class NSIdentifyLDAP : public Module } } +<<<<<<< HEAD void OnNickRegister(User *, NickServ::Nick *na) override +======= + void OnNickRegister(User *, NickAlias *na, const Anope::string &pass) anope_override +>>>>>>> 2.0 { if (!this->disable_register_reason.empty() || !this->ldap) return; @@ -337,7 +341,7 @@ class NSIdentifyLDAP : public Module } attributes[3].name = this->password_attribute; - attributes[3].values.push_back(na->nc->pass); + attributes[3].values.push_back(pass); Anope::string new_dn = username_attribute + "=" + na->nick + "," + basedn; this->ldap->Add(&this->orinterface, new_dn, attributes); diff --git a/modules/extra/m_mysql.cpp b/modules/extra/m_mysql.cpp index 02d015ed8..c00788e82 100644 --- a/modules/extra/m_mysql.cpp +++ b/modules/extra/m_mysql.cpp @@ -1,9 +1,14 @@ /* RequiredLibraries: mysqlclient */ +/* RequiredWindowsLibraries: libmysql */ #include "module.h" #include "modules/sql.h" #define NO_CLIENT_LONG_LONG -#include <mysql/mysql.h> +#ifdef WIN32 +# include <mysql.h> +#else +# include <mysql/mysql.h> +#endif using namespace SQL; diff --git a/modules/extra/m_sasl_dh-aes.cpp b/modules/extra/m_sasl_dh-aes.cpp index f3294bfc1..18c0f0e66 100644 --- a/modules/extra/m_sasl_dh-aes.cpp +++ b/modules/extra/m_sasl_dh-aes.cpp @@ -1,4 +1,5 @@ /* RequiredLibraries: ssl,crypto */ +/* RequiredWindowsLibraries: ssleay32,libeay32 */ #include "module.h" #include "modules/sasl.h" diff --git a/modules/extra/m_sasl_dh-blowfish.cpp b/modules/extra/m_sasl_dh-blowfish.cpp index b32e8855e..bd0fb97db 100644 --- a/modules/extra/m_sasl_dh-blowfish.cpp +++ b/modules/extra/m_sasl_dh-blowfish.cpp @@ -1,4 +1,5 @@ /* RequiredLibraries: ssl,crypto */ +/* RequiredWindowsLibraries: ssleay32,libeay32 */ #include "module.h" #include "modules/sasl.h" diff --git a/modules/extra/m_sql_authentication.cpp b/modules/extra/m_sql_authentication.cpp index 74e2554fa..cca8b9af1 100644 --- a/modules/extra/m_sql_authentication.cpp +++ b/modules/extra/m_sql_authentication.cpp @@ -43,7 +43,7 @@ class SQLAuthenticationResult : public SQL::Interface if (na == NULL) { na = new NickServ::Nick(req->GetAccount(), new NickServ::Account(req->GetAccount())); - NickServ::Event::OnNickRegister(&NickServ::Event::NickRegister::OnNickRegister, user, na); + NickServ::Event::OnNickRegister(&NickServ::Event::NickRegister::OnNickRegister, user, na, ""); if (user && NickServ) user->SendMessage(NickServ, _("Your account \002%s\002 has been successfully created."), na->nick.c_str()); } @@ -127,7 +127,7 @@ class ModuleSQLAuthentication : public Module if (u) { q.SetValue("n", u->nick); - q.SetValue("i", u->ip); + q.SetValue("i", u->ip.addr()); } else { diff --git a/modules/extra/m_sql_oper.cpp b/modules/extra/m_sql_oper.cpp index 8337252ba..3e056c1d7 100644 --- a/modules/extra/m_sql_oper.cpp +++ b/modules/extra/m_sql_oper.cpp @@ -137,7 +137,7 @@ class ModuleSQLOper : public Module SQL::Query q(this->query); q.SetValue("a", u->Account()->display); - q.SetValue("i", u->ip); + q.SetValue("i", u->ip.addr()); this->SQL->Run(new SQLOperResult(this, u), q); diff --git a/modules/extra/m_sqlite.cpp b/modules/extra/m_sqlite.cpp index 32d335b1b..f07f6dbc2 100644 --- a/modules/extra/m_sqlite.cpp +++ b/modules/extra/m_sqlite.cpp @@ -1,4 +1,5 @@ /* RequiredLibraries: sqlite3 */ +/* RequiredWindowsLibraries: sqlite3 */ #include "module.h" #include "modules/sql.h" diff --git a/modules/extra/m_ssl_gnutls.cpp b/modules/extra/m_ssl_gnutls.cpp index 492536c5c..9be87d95c 100644 --- a/modules/extra/m_ssl_gnutls.cpp +++ b/modules/extra/m_ssl_gnutls.cpp @@ -7,6 +7,7 @@ */ /* RequiredLibraries: gnutls */ +/* RequiredWindowsLibraries: libgnutls-28 */ #include "module.h" #include "modules/ssl.h" diff --git a/modules/extra/m_ssl_openssl.cpp b/modules/extra/m_ssl_openssl.cpp index 7687b599e..23e2596ce 100644 --- a/modules/extra/m_ssl_openssl.cpp +++ b/modules/extra/m_ssl_openssl.cpp @@ -1,4 +1,5 @@ /* RequiredLibraries: ssl,crypto */ +/* RequiredWindowsLibraries: ssleay32,libeay32 */ #include "module.h" #include "modules/ssl.h" diff --git a/modules/extra/stats/irc2sql/irc2sql.cpp b/modules/extra/stats/irc2sql/irc2sql.cpp index 56284c6f1..8c0aa83ab 100644 --- a/modules/extra/stats/irc2sql/irc2sql.cpp +++ b/modules/extra/stats/irc2sql/irc2sql.cpp @@ -95,7 +95,7 @@ void IRC2SQL::OnUserConnect(User *u, bool &exempt) query.SetValue("vhost", u->vhost); query.SetValue("chost", u->chost); query.SetValue("realname", u->realname); - query.SetValue("ip", u->ip); + query.SetValue("ip", u->ip.addr()); query.SetValue("ident", u->GetIdent()); query.SetValue("vident", u->GetVIdent()); query.SetValue("secure", u->HasMode("SSL") || u->HasExt("ssl") ? "Y" : "N"); diff --git a/modules/extra/stats/m_chanstats.cpp b/modules/extra/stats/m_chanstats.cpp index d472fd55d..6238b749c 100644 --- a/modules/extra/stats/m_chanstats.cpp +++ b/modules/extra/stats/m_chanstats.cpp @@ -638,7 +638,7 @@ class MChanstats : public Module ci->Extend<bool>("CS_STATS"); } - void OnNickRegister(User *user, NickServ::Nick *na) + void OnNickRegister(User *user, NickAlias *na, const Anope::string &) { if (NSDefChanstats) na->nc->Extend<bool>("NS_STATS"); diff --git a/modules/m_dnsbl.cpp b/modules/m_dnsbl.cpp index c5dd94f21..d695fa8cd 100644 --- a/modules/m_dnsbl.cpp +++ b/modules/m_dnsbl.cpp @@ -54,18 +54,18 @@ class DNSBLResolver : public Request record_reason = this->blacklist.replies[result]; } - Anope::string reason = this->blacklist.reason; + Anope::string reason = this->blacklist.reason, addr = user->ip.addr(); reason = reason.replace_all_cs("%n", user->nick); reason = reason.replace_all_cs("%u", user->GetIdent()); reason = reason.replace_all_cs("%g", user->realname); reason = reason.replace_all_cs("%h", user->host); - reason = reason.replace_all_cs("%i", user->ip); + reason = reason.replace_all_cs("%i", addr); reason = reason.replace_all_cs("%r", record_reason); reason = reason.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname")); BotInfo *OperServ = Config->GetClient("OperServ"); - Log(creator, "dnsbl", OperServ) << user->GetMask() << " (" << user->ip << ") appears in " << this->blacklist.name; - XLine *x = new XLine("*@" + user->ip, OperServ ? OperServ->nick : "m_dnsbl", Anope::CurTime + this->blacklist.bantime, reason, XLineManager::GenerateUID()); + Log(creator, "dnsbl", OperServ) << user->GetMask() << " (" << addr << ") appears in " << this->blacklist.name; + XLine *x = new XLine("*@" + addr, OperServ ? OperServ->nick : "m_dnsbl", Anope::CurTime + this->blacklist.bantime, reason, XLineManager::GenerateUID()); if (this->add_to_akill && akills) { akills->AddXLine(x); @@ -132,22 +132,21 @@ class ModuleDNSBL : public Module return; /* At this time we only support IPv4 */ - sockaddrs user_ip; - user_ip.pton(AF_INET, user->ip); - if (!user_ip.valid()) + if (!user->ip.valid() || user->ip.sa.sa_family != AF_INET) /* User doesn't have a valid IPv4 IP (ipv6/spoof/etc) */ return; - const unsigned long &ip = user_ip.sa4.sin_addr.s_addr; + const unsigned long &ip = user->ip.sa4.sin_addr.s_addr; unsigned long reverse_ip = (ip << 24) | ((ip & 0xFF00) << 8) | ((ip & 0xFF0000) >> 8) | (ip >> 24); - user_ip.sa4.sin_addr.s_addr = reverse_ip; + sockaddrs reverse = user->ip; + reverse.sa4.sin_addr.s_addr = reverse_ip; for (unsigned i = 0; i < this->blacklists.size(); ++i) { const Blacklist &b = this->blacklists[i]; - Anope::string dnsbl_host = user_ip.addr() + "." + b.name; + Anope::string dnsbl_host = reverse.addr() + "." + b.name; DNSBLResolver *res = NULL; try { diff --git a/modules/m_proxyscan.cpp b/modules/m_proxyscan.cpp index c67bb620f..fbf4055b6 100644 --- a/modules/m_proxyscan.cpp +++ b/modules/m_proxyscan.cpp @@ -207,12 +207,13 @@ class ModuleProxyScan : public Module void Tick(time_t) override { - for (std::set<ProxyConnect *>::iterator it = ProxyConnect::proxies.begin(), it_end = ProxyConnect::proxies.end(); it != it_end; ++it) + for (std::set<ProxyConnect *>::iterator it = ProxyConnect::proxies.begin(), it_end = ProxyConnect::proxies.end(); it != it_end;) { ProxyConnect *p = *it; + ++it; if (p->created + this->GetSecs() < Anope::CurTime) - p->flags[SF_DEAD] = true; + delete p; } } } connectionTimeout; @@ -335,15 +336,13 @@ class ModuleProxyScan : public Module return; /* At this time we only support IPv4 */ - sockaddrs user_ip; - user_ip.pton(AF_INET, user->ip); - if (!user_ip.valid()) + if (!user->ip.valid() || user->ip.sa.sa_family != AF_INET) /* User doesn't have a valid IPv4 IP (ipv6/spoof/etc) */ return; if (!this->con_notice.empty() && !this->con_source.empty()) { - BotInfo *bi = BotInfo::Find(this->con_source); + BotInfo *bi = BotInfo::Find(this->con_source, true); if (bi) user->SendMessage(bi, this->con_notice); } @@ -365,7 +364,7 @@ class ModuleProxyScan : public Module con = new SOCKS5ProxyConnect(p, p.ports[k]); else continue; - con->Connect(user->ip, p.ports[k]); + con->Connect(user->ip.addr(), p.ports[k]); } catch (const SocketException &ex) { diff --git a/modules/m_rewrite.cpp b/modules/m_rewrite.cpp index adf702b9d..d812448b0 100644 --- a/modules/m_rewrite.cpp +++ b/modules/m_rewrite.cpp @@ -115,7 +115,7 @@ class RewriteCommand : public Command { Anope::string new_message = r->Process(source, full_params); Log(LOG_DEBUG) << "m_rewrite: Rewrote '" << source.command << (!params.empty() ? " " + params[0] : "") << "' to '" << new_message << "' using '" << r->source_message << "'"; - source.service = BotInfo::Find(r->client); + source.service = BotInfo::Find(r->client, true); if (!source.service) return; Command::Run(source, new_message); diff --git a/modules/m_xmlrpc_main.cpp b/modules/m_xmlrpc_main.cpp index 224b25a60..9ee11b7a3 100644 --- a/modules/m_xmlrpc_main.cpp +++ b/modules/m_xmlrpc_main.cpp @@ -74,7 +74,7 @@ class MyXMLRPCEvent : public XMLRPCEvent request.reply("error", "Invalid parameters"); else { - BotInfo *bi = BotInfo::Find(service); + BotInfo *bi = BotInfo::Find(service, true); if (!bi) request.reply("error", "Invalid service"); else @@ -212,8 +212,7 @@ class MyXMLRPCEvent : public XMLRPCEvent request.reply("vhost", iface->Sanitize(u->vhost)); if (!u->chost.empty()) request.reply("chost", iface->Sanitize(u->chost)); - if (!u->ip.empty()) - request.reply("ip", u->ip); + request.reply("ip", u->ip.addr()); request.reply("timestamp", stringify(u->timestamp)); request.reply("signon", stringify(u->signon)); if (u->Account()) diff --git a/modules/protocol/bahamut.cpp b/modules/protocol/bahamut.cpp index a67f4dc0d..5649dbbbe 100644 --- a/modules/protocol/bahamut.cpp +++ b/modules/protocol/bahamut.cpp @@ -16,7 +16,7 @@ class ChannelModeFlood : public ChannelModeParam public: ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam("FLOOD", modeChar, minusNoArg) { } - bool IsValid(const Anope::string &value) const override + bool IsValid(Anope::string &value) const override { try { @@ -175,7 +175,7 @@ class BahamutIRCdProto : public IRCDProto if (uc != NULL) uc->status.Clear(); - BotInfo *setter = BotInfo::Find(user->nick); + BotInfo *setter = BotInfo::Find(user->GetUID()); for (size_t i = 0; i < cs.Modes().length(); ++i) c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false); diff --git a/modules/protocol/hybrid.cpp b/modules/protocol/hybrid.cpp index 116f56a84..eb774d541 100644 --- a/modules/protocol/hybrid.cpp +++ b/modules/protocol/hybrid.cpp @@ -1,7 +1,7 @@ /* ircd-hybrid-8 protocol module * * (C) 2003-2014 Anope Team - * (C) 2012-2013 by the Hybrid Development Team + * (C) 2012-2014 ircd-hybrid development team * * Please read COPYING and README for further details. * @@ -40,10 +40,11 @@ class HybridProto : public IRCDProto { DefaultPseudoclientModes = "+oi"; CanSVSNick = true; + CanSVSHold = true; + CanSVSJoin = true; CanSNLine = true; CanSQLine = true; CanSZLine = true; - CanSVSHold = true; CanCertFP = true; CanSetVHost = true; RequiresID = true; @@ -174,9 +175,9 @@ class HybridProto : public IRCDProto void SendServer(const Server *server) override { if (server == Me) - UplinkSocket::Message() << "SERVER " << server->GetName() << " " << server->GetHops() << " :" << server->GetDescription(); + UplinkSocket::Message() << "SERVER " << server->GetName() << " " << server->GetHops() + 1 << " :" << server->GetDescription(); else - UplinkSocket::Message(Me) << "SID " << server->GetName() << " " << server->GetHops() << " " << server->GetSID() << " :" << server->GetDescription(); + UplinkSocket::Message(Me) << "SID " << server->GetName() << " " << server->GetHops() + 1 << " " << server->GetSID() << " :" << server->GetDescription(); } void SendConnect() override @@ -254,6 +255,19 @@ class HybridProto : public IRCDProto UplinkSocket::Message(Me) << "SVSNICK " << u->nick << " " << newnick << " " << when; } + void SendSVSJoin(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &) override + { + UplinkSocket::Message(source) << "SVSJOIN " << u->GetUID() << " " << chan; + } + + void SendSVSPart(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string ¶m) override + { + if (!param.empty()) + UplinkSocket::Message(source) << "SVSPART " << u->GetUID() << " " << chan << " :" << param; + else + UplinkSocket::Message(source) << "SVSPART " << u->GetUID() << " " << chan; + } + void SendSVSHold(const Anope::string &nick, time_t t) override { XLine x(nick, Me->GetName(), Anope::CurTime + t, "Being held for registered user"); @@ -611,7 +625,7 @@ class ProtoHybrid : public Module ModeManager::AddUserMode(new UserModeOperOnly("CALLERID", 'g')); ModeManager::AddUserMode(new UserMode("INVIS", 'i')); ModeManager::AddUserMode(new UserModeOperOnly("LOCOPS", 'l')); - ModeManager::AddUserMode(new UserMode("OPER", 'o')); + ModeManager::AddUserMode(new UserModeOperOnly("OPER", 'o')); ModeManager::AddUserMode(new UserModeNoone("REGISTERED", 'r')); ModeManager::AddUserMode(new UserModeOperOnly("SNOMASK", 's')); ModeManager::AddUserMode(new UserMode("WALLOPS", 'w')); diff --git a/modules/protocol/inspircd20.cpp b/modules/protocol/inspircd20.cpp index 1981b3cc5..b25d4d5cb 100644 --- a/modules/protocol/inspircd20.cpp +++ b/modules/protocol/inspircd20.cpp @@ -434,25 +434,61 @@ class InspIRCd20Proto : public IRCDProto } }; -class InspIRCdExtBan : public ChannelModeList +class InspIRCdExtBan : public ChannelModeVirtual<ChannelModeList> { + char ext; + public: - InspIRCdExtBan(const Anope::string &mname, char modeChar) : ChannelModeList(mname, modeChar) { } + InspIRCdExtBan(const Anope::string &mname, const Anope::string &basename, char extban) : ChannelModeVirtual<ChannelModeList>(mname, basename) + , ext(extban) + { + } + + ChannelMode *Wrap(Anope::string ¶m) override + { + param = Anope::string(ext) + ":" + param; + return ChannelModeVirtual<ChannelModeList>::Wrap(param); + } - bool Matches(User *u, const Entry *e) override + ChannelMode *Unwrap(ChannelMode *cm, Anope::string ¶m) override { - const Anope::string &mask = e->GetMask(); + if (cm->type != MODE_LIST || param.length() < 3 || param[0] != ext || param[1] != ':') + return cm; - if (mask.find("m:") == 0 || mask.find("N:") == 0) + param = param.substr(2); + return this; + } +}; + +namespace InspIRCdExtban +{ + class EntryMatcher : public InspIRCdExtBan + { + public: + EntryMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : InspIRCdExtBan(mname, mbase, c) { + } + + bool Matches(User *u, const Entry *e) override + { + const Anope::string &mask = e->GetMask(); Anope::string real_mask = mask.substr(3); - Entry en(this->name, real_mask); - if (en.Matches(u)) - return true; + return Entry(this->name, real_mask).Matches(u); + } + }; + + class ChannelMatcher : public InspIRCdExtBan + { + public: + ChannelMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : InspIRCdExtBan(mname, mbase, c) + { } - else if (mask.find("j:") == 0) + + bool Matches(User *u, const Entry *e) override { + const Anope::string &mask = e->GetMask(); + Anope::string channel = mask.substr(3); ChannelMode *cm = NULL; @@ -473,46 +509,94 @@ class InspIRCdExtBan : public ChannelModeList if (cm == NULL || uc->status.HasMode(cm->mchar)) return true; } - } - else if (mask.find("R:") == 0) - { - Anope::string real_mask = mask.substr(2); - if (u->IsIdentified() && real_mask.equals_ci(u->Account()->display)) - return true; + return false; } - else if (mask.find("r:") == 0) - { - Anope::string real_mask = mask.substr(2); + }; - if (Anope::Match(u->realname, real_mask)) - return true; - } - else if (mask.find("s:") == 0) + class AccountMatcher : public InspIRCdExtBan + { + public: + AccountMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : InspIRCdExtBan(mname, mbase, c) + { + } + + bool Matches(User *u, const Entry *e) override { + const Anope::string &mask = e->GetMask(); Anope::string real_mask = mask.substr(2); - if (Anope::Match(u->server->GetName(), real_mask)) - return true; + return u->IsIdentified() && real_mask.equals_ci(u->Account()->display); } - else if (mask.find("z:") == 0) + }; + + class RealnameMatcher : public InspIRCdExtBan + { + public: + RealnameMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : InspIRCdExtBan(mname, mbase, c) + { + } + + bool Matches(User *u, const Entry *e) override + { + const Anope::string &mask = e->GetMask(); + Anope::string real_mask = mask.substr(2); + return Anope::Match(u->realname, real_mask); + } + }; + + class ServerMatcher : public InspIRCdExtBan + { + public: + ServerMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : InspIRCdExtBan(mname, mbase, c) + { + } + + bool Matches(User *u, const Entry *e) override + { + const Anope::string &mask = e->GetMask(); + Anope::string real_mask = mask.substr(2); + return Anope::Match(u->server->GetName(), real_mask); + } + }; + + class FinerprintMatcher : public InspIRCdExtBan + { + public: + FinerprintMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : InspIRCdExtBan(mname, mbase, c) + { + } + + bool Matches(User *u, const Entry *e) override + { + const Anope::string &mask = e->GetMask(); + Anope::string real_mask = mask.substr(2); + return !u->fingerprint.empty() && Anope::Match(u->fingerprint, real_mask); + } + }; + + class UnidentifiedMatcher : public InspIRCdExtBan + { + public: + UnidentifiedMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : InspIRCdExtBan(mname, mbase, c) { - Anope::string real_mask = mask.substr(2); - - if (!u->fingerprint.empty() && Anope::Match(u->fingerprint, real_mask)) - return true; } - return false; - } -}; + bool Matches(User *u, const Entry *e) override + { + const Anope::string &mask = e->GetMask(); + Anope::string real_mask = mask.substr(2); + return !u->Account() && Entry("BAN", real_mask).Matches(u); + } + }; +} class ColonDelimitedParamMode : public ChannelModeParam { public: ColonDelimitedParamMode(const Anope::string &modename, char modeChar) : ChannelModeParam(modename, modeChar, true) { } - bool IsValid(const Anope::string &value) const override + bool IsValid(Anope::string &value) const override { return IsValid(value, false); } @@ -561,7 +645,7 @@ class SimpleNumberParamMode : public ChannelModeParam public: SimpleNumberParamMode(const Anope::string &modename, char modeChar) : ChannelModeParam(modename, modeChar, true) { } - bool IsValid(const Anope::string &value) const override + bool IsValid(Anope::string &value) const override { if (value.empty()) return false; // empty param is never valid @@ -586,11 +670,12 @@ class ChannelModeFlood : public ColonDelimitedParamMode public: ChannelModeFlood(char modeChar) : ColonDelimitedParamMode("FLOOD", modeChar) { } - bool IsValid(const Anope::string &value) const override + bool IsValid(Anope::string &value) const override { // The parameter of this mode is a bit different, it may begin with a '*', // ignore it if that's the case - return ((!value.empty()) && (ColonDelimitedParamMode::IsValid(value[0] == '*' ? value.substr(1) : value))); + Anope::string v = value[0] == '*' ? value.substr(1) : value; + return ((!value.empty()) && (ColonDelimitedParamMode::IsValid(v))); } }; @@ -599,7 +684,7 @@ class ChannelModeHistory : public ColonDelimitedParamMode public: ChannelModeHistory(char modeChar) : ColonDelimitedParamMode("HISTORY", modeChar) { } - bool IsValid(const Anope::string &value) const override + bool IsValid(Anope::string &value) const override { return (ColonDelimitedParamMode::IsValid(value, true)); } @@ -610,7 +695,7 @@ class ChannelModeRedirect : public ChannelModeParam public: ChannelModeRedirect(char modeChar) : ChannelModeParam("REDIRECT", modeChar, true) { } - bool IsValid(const Anope::string &value) const override + bool IsValid(Anope::string &value) const override { // The parameter of this mode is a channel, and channel names start with '#' return ((!value.empty()) && (value[0] == '#')); @@ -661,17 +746,26 @@ struct IRCDMessageCapab : Message::Capab if (modename.equals_cs("admin")) cm = new ChannelModeStatus("PROTECT", modechar.length() > 1 ? modechar[1] : modechar[0], modechar.length() > 1 ? modechar[0] : 0, 3); else if (modename.equals_cs("allowinvite")) + { cm = new ChannelMode("ALLINVITE", modechar[0]); + ModeManager::AddChannelMode(new InspIRCdExtban::EntryMatcher("INVITEBAN", "BAN", 'A')); + } else if (modename.equals_cs("auditorium")) cm = new ChannelMode("AUDITORIUM", modechar[0]); else if (modename.equals_cs("ban")) - cm = new InspIRCdExtBan("BAN", modechar[0]); + cm = new ChannelModeList("BAN", modechar[0]); else if (modename.equals_cs("banexception")) - cm = new InspIRCdExtBan("EXCEPT", 'e'); + cm = new ChannelModeList("EXCEPT", modechar[0]); else if (modename.equals_cs("blockcaps")) + { cm = new ChannelMode("BLOCKCAPS", modechar[0]); + ModeManager::AddChannelMode(new InspIRCdExtban::EntryMatcher("BLOCKCAPSBAN", "BAN", 'B')); + } else if (modename.equals_cs("blockcolor")) + { cm = new ChannelMode("BLOCKCOLOR", modechar[0]); + ModeManager::AddChannelMode(new InspIRCdExtban::EntryMatcher("BLOCKCOLORBAN", "BAN", 'c')); + } else if (modename.equals_cs("c_registered")) cm = new ChannelModeNoone("REGISTERED", modechar[0]); else if (modename.equals_cs("censor")) @@ -691,7 +785,7 @@ struct IRCDMessageCapab : Message::Capab else if (modename.equals_cs("history")) cm = new ChannelModeHistory(modechar[0]); else if (modename.equals_cs("invex")) - cm = new InspIRCdExtBan("INVITEOVERRIDE", 'I'); + cm = new ChannelModeList("INVITEOVERRIDE", modechar[0]); else if (modename.equals_cs("inviteonly")) cm = new ChannelMode("INVITE", modechar[0]); else if (modename.equals_cs("joinflood")) @@ -707,17 +801,29 @@ struct IRCDMessageCapab : Message::Capab else if (modename.equals_cs("nickflood")) cm = new ColonDelimitedParamMode("NICKFLOOD", modechar[0]); else if (modename.equals_cs("noctcp")) + { cm = new ChannelMode("NOCTCP", modechar[0]); + ModeManager::AddChannelMode(new InspIRCdExtban::EntryMatcher("NOCTCPBAN", "BAN", 'C')); + } else if (modename.equals_cs("noextmsg")) cm = new ChannelMode("NOEXTERNAL", modechar[0]); else if (modename.equals_cs("nokick")) + { cm = new ChannelMode("NOKICK", modechar[0]); + ModeManager::AddChannelMode(new InspIRCdExtban::EntryMatcher("NOKICKBAN", "BAN", 'Q')); + } else if (modename.equals_cs("noknock")) cm = new ChannelMode("NOKNOCK", modechar[0]); else if (modename.equals_cs("nonick")) + { cm = new ChannelMode("NONICK", modechar[0]); + ModeManager::AddChannelMode(new InspIRCdExtban::EntryMatcher("NONICKBAN", "BAN", 'N')); + } else if (modename.equals_cs("nonotice")) + { cm = new ChannelMode("NONOTICE", modechar[0]); + ModeManager::AddChannelMode(new InspIRCdExtban::EntryMatcher("NONOTICEBAN", "BAN", 'T')); + } else if (modename.equals_cs("op")) cm = new ChannelModeStatus("OP", modechar.length() > 1 ? modechar[1] : modechar[0], modechar.length() > 1 ? modechar[0] : 0, 2); else if (modename.equals_cs("operonly")) @@ -735,9 +841,15 @@ struct IRCDMessageCapab : Message::Capab else if (modename.equals_cs("secret")) cm = new ChannelMode("SECRET", modechar[0]); else if (modename.equals_cs("sslonly")) + { cm = new ChannelMode("SSL", modechar[0]); + ModeManager::AddChannelMode(new InspIRCdExtban::FinerprintMatcher("SSLBAN", "BAN", 'z')); + } else if (modename.equals_cs("stripcolor")) + { cm = new ChannelMode("STRIPCOLOR", modechar[0]); + ModeManager::AddChannelMode(new InspIRCdExtban::EntryMatcher("STRIPCOLORBAN", "BAN", 'S')); + } else if (modename.equals_cs("topiclock")) cm = new ChannelMode("TOPIC", modechar[0]); else if (modename.equals_cs("voice")) @@ -838,11 +950,25 @@ struct IRCDMessageCapab : Message::Capab while (ssep.GetToken(module)) { if (module.equals_cs("m_services_account.so")) + { Servers::Capab.insert("SERVICES"); + ModeManager::AddChannelMode(new InspIRCdExtban::AccountMatcher("ACCOUNTBAN", "BAN", 'R')); + ModeManager::AddChannelMode(new InspIRCdExtban::UnidentifiedMatcher("UNREGISTEREDBAN", "BAN", 'U')); + } else if (module.equals_cs("m_chghost.so")) Servers::Capab.insert("CHGHOST"); else if (module.equals_cs("m_chgident.so")) Servers::Capab.insert("CHGIDENT"); + else if (module == "m_channelban.so") + ModeManager::AddChannelMode(new InspIRCdExtban::ChannelMatcher("CHANNELBAN", "BAN", 'j')); + else if (module == "m_gecosban.so") + ModeManager::AddChannelMode(new InspIRCdExtban::RealnameMatcher("REALNAMEBAN", "BAN", 'r')); + else if (module == "m_nopartmessage.so") + ModeManager::AddChannelMode(new InspIRCdExtban::EntryMatcher("PARTMESSAGEBAN", "BAN", 'p')); + else if (module == "m_serverban.so") + ModeManager::AddChannelMode(new InspIRCdExtban::ServerMatcher("SERVERBAN", "BAN", 's')); + else if (module == "m_muteban.so") + ModeManager::AddChannelMode(new InspIRCdExtban::EntryMatcher("QUIET", "BAN", 'm')); } } else if (params[0].equals_cs("CAPABILITIES") && params.size() > 1) @@ -934,6 +1060,8 @@ struct IRCDMessageCapab : Message::Capab ModeManager::RebuildStatusModes(); } + else if (capab == "GLOBOPS=1") + Servers::Capab.insert("GLOBOPS"); } } else if (params[0].equals_cs("END")) @@ -1431,6 +1559,7 @@ class ProtoInspIRCd20 : public Module , public EventHook<Event::DelChan> , public EventHook<Event::MLockEvents> , public EventHook<Event::SetChannelOption> + , public EventHook<Event::ChannelModeUnset> { InspIRCd20Proto ircd_proto; ExtensibleItem<bool> ssl; @@ -1486,6 +1615,7 @@ class ProtoInspIRCd20 : public Module , EventHook<Event::DelChan>("OnDelChan") , EventHook<Event::MLockEvents>("MLock") , EventHook<Event::SetChannelOption>("OnSetChannelOption") + , EventHook<Event::ChannelModeUnset>("OnChannelModeUnset") , ircd_proto(this) , ssl(this, "ssl") , message_away(this) @@ -1604,6 +1734,15 @@ class ProtoInspIRCd20 : public Module return EVENT_CONTINUE; } + + EventReturn OnChannelModeUnset(Channel *c, const MessageSource &setter, ChannelMode *mode, const Anope::string ¶m) override + { + if ((setter.GetUser() && setter.GetUser()->server == Me) || setter.GetServer() == Me || !setter.GetServer()) + if (mode->name == "OPERPREFIX") + c->SetMode(c->ci->WhoSends(), mode, param, false); + + return EVENT_CONTINUE; + } }; MODULE_INIT(ProtoInspIRCd20) diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp index 5832da62f..dc875cdbb 100644 --- a/modules/protocol/ngircd.cpp +++ b/modules/protocol/ngircd.cpp @@ -101,7 +101,7 @@ class ngIRCdProto : public IRCDProto if (uc != NULL) uc->status.Clear(); - BotInfo *setter = BotInfo::Find(user->nick); + BotInfo *setter = BotInfo::Find(user->GetUID()); for (size_t i = 0; i < cs.Modes().length(); ++i) c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false); diff --git a/modules/protocol/plexus.cpp b/modules/protocol/plexus.cpp index 6e2930757..a804202b3 100644 --- a/modules/protocol/plexus.cpp +++ b/modules/protocol/plexus.cpp @@ -67,7 +67,7 @@ class PlexusProto : public IRCDProto if (uc != NULL) uc->status.Clear(); - BotInfo *setter = BotInfo::Find(user->nick); + BotInfo *setter = BotInfo::Find(user->GetUID()); for (size_t i = 0; i < cs.Modes().length(); ++i) c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false); @@ -333,10 +333,10 @@ class ProtoPlexus : public Module ModeManager::AddUserMode(new UserMode("CALLERID", 'g')); ModeManager::AddUserMode(new UserMode("INVIS", 'i')); ModeManager::AddUserMode(new UserModeOperOnly("LOCOPS", 'l')); - ModeManager::AddUserMode(new UserMode("OPER", 'o')); + ModeManager::AddUserMode(new UserModeOperOnly("OPER", 'o')); ModeManager::AddUserMode(new UserModeOperOnly("NETADMIN", 'N')); ModeManager::AddUserMode(new UserMode("PRIV", 'p')); - ModeManager::AddUserMode(new UserMode("ROUTING", 'q')); + ModeManager::AddUserMode(new UserModeOperOnly("ROUTING", 'q')); ModeManager::AddUserMode(new UserModeNoone("REGISTERED", 'r')); ModeManager::AddUserMode(new UserMode("REGPRIV", 'R')); ModeManager::AddUserMode(new UserModeOperOnly("SNOMASK", 's')); diff --git a/modules/protocol/ratbox.cpp b/modules/protocol/ratbox.cpp index 8a88e74a3..a0d2cf9a2 100644 --- a/modules/protocol/ratbox.cpp +++ b/modules/protocol/ratbox.cpp @@ -253,7 +253,7 @@ class ProtoRatbox : public Module // k = skill? ModeManager::AddUserMode(new UserModeOperOnly("LOCOPS", 'l')); // n = nchange - ModeManager::AddUserMode(new UserMode("OPER", 'o')); + ModeManager::AddUserMode(new UserModeOperOnly("OPER", 'o')); // r = rej ModeManager::AddUserMode(new UserModeOperOnly("SNOMASK", 's')); ModeManager::AddUserMode(new UserModeNoone("PROTECTED", 'S')); diff --git a/modules/protocol/unreal.cpp b/modules/protocol/unreal.cpp index 606f22270..721ba50c3 100644 --- a/modules/protocol/unreal.cpp +++ b/modules/protocol/unreal.cpp @@ -167,7 +167,7 @@ class UnrealIRCdProto : public IRCDProto if (uc != NULL) uc->status.Clear(); - BotInfo *setter = BotInfo::Find(user->nick); + BotInfo *setter = BotInfo::Find(user->GetUID()); for (size_t i = 0; i < cs.Modes().length(); ++i) c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false); @@ -415,17 +415,44 @@ class UnrealIRCdProto : public IRCDProto } }; -class UnrealExtBan : public ChannelModeList +class UnrealExtBan : public ChannelModeVirtual<ChannelModeList> { + char ext; + public: - UnrealExtBan(const Anope::string &mname, char modeChar) : ChannelModeList(mname, modeChar) { } + UnrealExtBan(const Anope::string &mname, const Anope::string &basename, char extban) : ChannelModeVirtual<ChannelModeList>(mname, basename) + , ext(extban) + { + } + + ChannelMode *Wrap(Anope::string ¶m) override + { + param = "~" + Anope::string(ext) + ":" + param; + return ChannelModeVirtual<ChannelModeList>::Wrap(param); + } - bool Matches(User *u, const Entry *e) override + ChannelMode *Unwrap(ChannelMode *cm, Anope::string ¶m) override { - const Anope::string &mask = e->GetMask(); + if (cm->type != MODE_LIST || param.length() < 4 || param[0] != '~' || param[1] != ext || param[2] != ':') + return cm; - if (mask.find("~c:") == 0) + param = param.substr(3); + return this; + } +}; + +namespace UnrealExtban +{ + class ChannelMatcher : public UnrealExtBan + { + public: + ChannelMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : UnrealExtBan(mname, mbase, c) { + } + + bool Matches(User *u, const Entry *e) override + { + const Anope::string &mask = e->GetMask(); Anope::string channel = mask.substr(3); ChannelMode *cm = NULL; @@ -446,38 +473,73 @@ class UnrealExtBan : public ChannelModeList if (cm == NULL || uc->status.HasMode(cm->mchar)) return true; } + + return false; } - else if (mask.find("~j:") == 0 || mask.find("~n:") == 0 || mask.find("~q:") == 0) + }; + + class EntryMatcher : public UnrealExtBan + { + public: + EntryMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : UnrealExtBan(mname, mbase, c) + { + } + + bool Matches(User *u, const Entry *e) override { + const Anope::string &mask = e->GetMask(); Anope::string real_mask = mask.substr(3); - Entry en(this->name, real_mask); - if (en.Matches(u)) - return true; + return Entry(this->name, real_mask).Matches(u); } - else if (mask.find("~r:") == 0) + }; + + class RealnameMatcher : public UnrealExtBan + { + public: + RealnameMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : UnrealExtBan(mname, mbase, c) + { + } + + bool Matches(User *u, const Entry *e) override { + const Anope::string &mask = e->GetMask(); Anope::string real_mask = mask.substr(3); - if (Anope::Match(u->realname, real_mask)) - return true; + return Anope::Match(u->realname, real_mask); } - else if (mask.find("~R:") == 0) + }; + + class RegisteredMatcher : public UnrealExtBan + { + public: + RegisteredMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : UnrealExtBan(mname, mbase, c) + { + } + + bool Matches(User *u, const Entry *e) override { - if (u->HasMode("REGISTERED") && mask.equals_ci(u->nick)) - return true; + const Anope::string &mask = e->GetMask(); + return u->HasMode("REGISTERED") && mask.equals_ci(u->nick); } - else if (mask.find("~a:") == 0) - { - Anope::string real_mask = mask.substr(3); + }; - if (u->Account() && Anope::Match(u->Account()->display, real_mask)) - return true; - } + class AccountMatcher : public UnrealExtBan + { + public: + AccountMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : UnrealExtBan(mname, mbase, c) + { + } - return false; - } -}; + bool Matches(User *u, const Entry *e) override + { + const Anope::string &mask = e->GetMask(); + Anope::string real_mask = mask.substr(3); + + return u->Account() && Anope::Match(u->Account()->display, real_mask); + } + }; +} class ChannelModeFlood : public ChannelModeParam { @@ -485,7 +547,7 @@ class ChannelModeFlood : public ChannelModeParam ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam("FLOOD", modeChar, minusNoArg) { } /* Borrowed part of this check from UnrealIRCd */ - bool IsValid(const Anope::string &value) const override + bool IsValid(Anope::string &value) const override { if (value.empty()) return false; @@ -565,13 +627,21 @@ struct IRCDMessageCapab : Message::Capab switch (modebuf[t]) { case 'b': - ModeManager::AddChannelMode(new UnrealExtBan("BAN", 'b')); + ModeManager::AddChannelMode(new ChannelModeList("BAN", 'b')); + + ModeManager::AddChannelMode(new UnrealExtban::ChannelMatcher("CHANNELBAN", "BAN", 'c')); + ModeManager::AddChannelMode(new UnrealExtban::EntryMatcher("JOINBAN", "BAN", 'j')); + ModeManager::AddChannelMode(new UnrealExtban::EntryMatcher("NONICKBAN", "BAN", 'n')); + ModeManager::AddChannelMode(new UnrealExtban::EntryMatcher("QUIET", "BAN", 'q')); + ModeManager::AddChannelMode(new UnrealExtban::RealnameMatcher("REALNAMEBAN", "BAN", 'r')); + ModeManager::AddChannelMode(new UnrealExtban::RegisteredMatcher("REGISTEREDBAN", "BAN", 'R')); + ModeManager::AddChannelMode(new UnrealExtban::AccountMatcher("ACCOUNTBAN", "BAN", 'a')); continue; case 'e': - ModeManager::AddChannelMode(new UnrealExtBan("EXCEPT", 'e')); + ModeManager::AddChannelMode(new ChannelModeList("EXCEPT", 'e')); continue; case 'I': - ModeManager::AddChannelMode(new UnrealExtBan("INVITEOVERRIDE", 'I')); + ModeManager::AddChannelMode(new ChannelModeList("INVITEOVERRIDE", 'I')); continue; default: ModeManager::AddChannelMode(new ChannelModeList("", modebuf[t])); @@ -1105,7 +1175,7 @@ class ProtoUnreal : public Module Message::Invite message_invite; Message::Join message_join; Message::Kick message_kick; - Message::Kill message_kill; + Message::Kill message_kill, message_svskill; Message::MOTD message_motd; Message::Notice message_notice; Message::Part message_part; @@ -1199,6 +1269,7 @@ class ProtoUnreal : public Module , message_quit(this) , message_squit(this) , message_stats(this) + , message_svskill(this, "SVSKILL") , message_time(this) , message_version(this) , message_whois(this) diff --git a/modules/pseudoclients/botserv/botserv.cpp b/modules/pseudoclients/botserv/botserv.cpp index cbb76599a..c4f1c3381 100644 --- a/modules/pseudoclients/botserv/botserv.cpp +++ b/modules/pseudoclients/botserv/botserv.cpp @@ -220,7 +220,7 @@ class BotServCore : public Module, public BotServ::BotServService void OnUserKicked(const MessageSource &source, User *target, const Anope::string &channel, ChannelStatus &status, const Anope::string &kickmsg) override { - BotInfo *bi = BotInfo::Find(target->nick); + BotInfo *bi = BotInfo::Find(target->GetUID()); if (bi) /* Bots get rejoined */ bi->Join(channel, &status); diff --git a/modules/pseudoclients/chanserv/channel.cpp b/modules/pseudoclients/chanserv/channel.cpp index 5364075ae..98840186f 100644 --- a/modules/pseudoclients/chanserv/channel.cpp +++ b/modules/pseudoclients/chanserv/channel.cpp @@ -58,8 +58,7 @@ ChannelImpl::ChannelImpl(const ChanServ::Channel &ci) ChanServ::AccessProvider *provider = taccess->provider; ChanServ::ChanAccess *newaccess = provider->Create(); - newaccess->ci = this; - newaccess->mask = taccess->mask; + newaccess->SetMask(taccess->Mask(), this); newaccess->creator = taccess->creator; newaccess->last_seen = taccess->last_seen; newaccess->created = taccess->created; @@ -192,7 +191,7 @@ Serializable* ChannelImpl::Unserialize(Serializable *obj, Serialize::Data &data) } catch (const ConvertException &) { } } - BotInfo *bi = BotInfo::Find(sbi); + BotInfo *bi = BotInfo::Find(sbi, true); if (*ci->bi != bi) { if (bi) @@ -322,19 +321,6 @@ BotInfo *ChannelImpl::WhoSends() const void ChannelImpl::AddAccess(ChanServ::ChanAccess *taccess) { this->access->push_back(taccess); - - const NickServ::Nick *na = NickServ::FindNick(taccess->mask); - if (na != NULL) - { - na->nc->AddChannelReference(this); - taccess->nc = na->nc; - } - else - { - ChanServ::Channel *ci = ChanServ::Find(taccess->mask); - if (ci != NULL) - ci->AddChannelReference(this->name); - } } ChanServ::ChanAccess *ChannelImpl::GetAccess(unsigned index) const diff --git a/modules/pseudoclients/chanserv/chanserv.cpp b/modules/pseudoclients/chanserv/chanserv.cpp index a667fb08d..660fab1b6 100644 --- a/modules/pseudoclients/chanserv/chanserv.cpp +++ b/modules/pseudoclients/chanserv/chanserv.cpp @@ -228,33 +228,40 @@ class ChanServCore : public Module if (it != access->ci->access->end()) access->ci->access->erase(it); - const NickServ::Nick *na = NickServ::FindNick(access->mask); + const NickServ::Nick *na = NickServ::FindNick(access->Mask()); if (na != NULL) na->nc->RemoveChannelReference(access->ci); else { - ChanServ::Channel *c = this->Find(access->mask); + ChanServ::Channel *c = this->Find(access->Mask()); if (c) c->RemoveChannelReference(access->ci->name); } } } - void Serialize(const ChanServ::ChanAccess *, Serialize::Data &data) override + void Serialize(const ChanServ::ChanAccess *access, Serialize::Data &data) override { + data["provider"] << access->provider->name; + data["ci"] << access->ci->name; + data["mask"] << access->Mask(); + data["creator"] << access->creator; + data.SetType("last_seen", Serialize::Data::DT_INT); data["last_seen"] << access->last_seen; + data.SetType("created", Serialize::Data::DT_INT); data["created"] << access->created; + data["data"] << access->AccessSerialize(); } bool Matches(const ChanServ::ChanAccess *access, const User *u, const NickServ::Account *acc, ChanServ::ChanAccess::Path &p) override { - if (access->nc) - return access->nc == acc; + if (access->GetAccount()) + return access->GetAccount() == acc; if (u) { - bool is_mask = access->mask.find_first_of("!@?*") != Anope::string::npos; - if (is_mask && Anope::Match(u->nick, access->mask)) + bool is_mask = access->Mask().find_first_of("!@?*") != Anope::string::npos; + if (is_mask && Anope::Match(u->nick, access->Mask())) return true; - else if (Anope::Match(u->GetDisplayedMask(), access->mask)) + else if (Anope::Match(u->GetDisplayedMask(), access->Mask())) return true; } @@ -263,14 +270,14 @@ class ChanServCore : public Module for (unsigned i = 0; i < acc->aliases->size(); ++i) { const NickServ::Nick *na = acc->aliases->at(i); - if (Anope::Match(na->nick, access->mask)) + if (Anope::Match(na->nick, access->Mask())) return true; } } - if (IRCD->IsChannelValid(access->mask)) + if (IRCD->IsChannelValid(access->Mask())) { - ChanServ::Channel *tci = Find(access->mask); + ChanServ::Channel *tci = Find(access->Mask()); if (tci) { for (unsigned i = 0; i < tci->GetAccessCount(); ++i) @@ -315,7 +322,9 @@ class ChanServCore : public Module else access = aprovider->Create(); access->ci = ci; - data["mask"] >> access->mask; + Anope::string m; + data["mask"] >> m; + access->SetMask(m, ci); data["creator"] >> access->creator; data["last_seen"] >> access->last_seen; data["created"] >> access->created; @@ -413,7 +422,7 @@ class ChanServCore : public Module for (unsigned j = 0; j < ci->GetAccessCount(); ++j) { const ChanServ::ChanAccess *ca = ci->GetAccess(j); - const NickServ::Account *anc = NickServ::FindAccount(ca->mask); + const NickServ::Account *anc = ca->GetAccount(); if (!anc || (!anc->IsServicesOper() && max_reg && anc->channelcount >= max_reg) || (anc == nc)) continue; @@ -421,7 +430,7 @@ class ChanServCore : public Module highest = ca; } if (highest) - newowner = NickServ::FindAccount(highest->mask); + newowner = highest->GetAccount(); } if (newowner) @@ -445,7 +454,7 @@ class ChanServCore : public Module for (unsigned j = 0; j < ci->GetAccessCount(); ++j) { const ChanServ::ChanAccess *ca = ci->GetAccess(j); - const NickServ::Account *anc = NickServ::FindAccount(ca->mask); + const NickServ::Account *anc = ca->GetAccount(); if (anc && anc == nc) { @@ -483,7 +492,7 @@ class ChanServCore : public Module { ChanServ::ChanAccess *a = c->GetAccess(j); - if (a->mask.equals_ci(ci->name)) + if (a->Mask().equals_ci(ci->name)) { delete a; break; diff --git a/modules/pseudoclients/nickserv/account.cpp b/modules/pseudoclients/nickserv/account.cpp index 55c537a0c..675a58acb 100644 --- a/modules/pseudoclients/nickserv/account.cpp +++ b/modules/pseudoclients/nickserv/account.cpp @@ -165,6 +165,10 @@ void AccountImpl::SetDisplay(const NickServ::Nick *na) NickServ::nickcore_map& map = NickServ::service->GetAccountList(); + /* this affects the serialized aliases */ + for (unsigned i = 0; i < aliases->size(); ++i) + aliases->at(i)->QueueUpdate(); + /* Remove the core from the list */ map.erase(this->display); diff --git a/modules/pseudoclients/nickserv/nickserv.cpp b/modules/pseudoclients/nickserv/nickserv.cpp index 75d68c430..895fc2937 100644 --- a/modules/pseudoclients/nickserv/nickserv.cpp +++ b/modules/pseudoclients/nickserv/nickserv.cpp @@ -29,7 +29,7 @@ class NickServCollide : public Timer Reference<NickServ::Nick> na; public: - NickServCollide(NickServ::NickServService *nss, User *user, NickServ::Nick *nick, time_t delay) : Timer(delay), service(nss), u(user), ts(user->timestamp), na(nick) + NickServCollide(Module *me, NickServ::NickServService *nss, User *user, NickServ::Nick *nick, time_t delay) : Timer(me, delay), service(nss), u(user), ts(user->timestamp), na(nick) { } @@ -52,7 +52,7 @@ class NickServHeld : public Timer Reference<NickServ::Nick> na; Anope::string nick; public: - NickServHeld(NickServ::Nick *n, long l) : Timer(l), na(n), nick(na->nick) + NickServHeld(Module *me, NickServ::Nick *n, long l) : Timer(me, l), na(n), nick(na->nick) { n->Extend<bool>("HELD"); } @@ -74,8 +74,8 @@ class NickServRelease : public User, public Timer Anope::string nick; public: - NickServRelease(NickServ::Nick *na, time_t delay) : User(na->nick, Config->GetModule("nickserv")->Get<const Anope::string>("enforceruser", "user"), - Config->GetModule("nickserv")->Get<const Anope::string>("enforcerhost", "services.localhost.net"), "", "", Me, "Services Enforcer", Anope::CurTime, "", Servers::TS6_UID_Retrieve(), NULL), Timer(delay), nick(na->nick) + NickServRelease(Module *me, NickServ::Nick *na, time_t delay) : User(na->nick, Config->GetModule("nickserv")->Get<const Anope::string>("enforceruser", "user"), + Config->GetModule("nickserv")->Get<const Anope::string>("enforcerhost", "services.localhost.net"), "", "", Me, "Services Enforcer", Anope::CurTime, "", IRCD->UID_Retrieve(), NULL), Timer(me, delay), nick(na->nick) { /* Erase the current release timer and use the new one */ Anope::map<NickServRelease *>::iterator nit = NickServReleases.find(this->nick); @@ -139,12 +139,12 @@ class NickServCore : public Module, public NickServ::NickServService { collided.Unset(na); - new NickServHeld(na, Config->GetModule("nickserv")->Get<time_t>("releasetimeout", "1m")); + new NickServHeld(this, na, Config->GetModule("nickserv")->Get<time_t>("releasetimeout", "1m")); if (IRCD->CanSVSHold) IRCD->SendSVSHold(na->nick, Config->GetModule("nickserv")->Get<time_t>("releasetimeout", "1m")); else - new NickServRelease(na, Config->GetModule("nickserv")->Get<time_t>("releasetimeout", "1m")); + new NickServRelease(this, na, Config->GetModule("nickserv")->Get<time_t>("releasetimeout", "1m")); } } @@ -249,13 +249,13 @@ class NickServCore : public Module, public NickServ::NickServService { time_t killquick = Config->GetModule("nickserv")->Get<time_t>("killquick", "20s"); u->SendMessage(*NickServ, _("If you do not change within %s, I will change your nick."), Anope::Duration(killquick, u->Account()).c_str()); - new NickServCollide(this, u, na, killquick); + new NickServCollide(this, this, u, na, killquick); } else { time_t kill = Config->GetModule("nickserv")->Get<time_t>("kill", "60s"); u->SendMessage(*NickServ, _("If you do not change within %s, I will change your nick."), Anope::Duration(kill, u->Account()).c_str()); - new NickServCollide(this, u, na, kill); + new NickServCollide(this, this, u, na, kill); } } diff --git a/modules/pseudoclients/operserv.cpp b/modules/pseudoclients/operserv.cpp index 428484f1b..2f0eaa0fc 100644 --- a/modules/pseudoclients/operserv.cpp +++ b/modules/pseudoclients/operserv.cpp @@ -55,13 +55,10 @@ class SGLineManager : public XLineManager if (!x->GetReal().empty() && !Anope::Match(u->realname, x->GetReal())) return false; - if (x->GetHost().find('/') != Anope::string::npos) - { - if (cidr(x->GetHost()).match(sockaddrs(u->ip))) - return true; - } + if (x->c && x->c->match(u->ip)) + return true; - if (x->GetHost().empty() || Anope::Match(u->host, x->GetHost()) || Anope::Match(u->ip, x->GetHost())) + if (x->GetHost().empty() || Anope::Match(u->host, x->GetHost()) || Anope::Match(u->ip.addr(), x->GetHost())) return true; return false; diff --git a/modules/webcpanel/pages/chanserv/access.cpp b/modules/webcpanel/pages/chanserv/access.cpp index 058acc457..158a71637 100644 --- a/modules/webcpanel/pages/chanserv/access.cpp +++ b/modules/webcpanel/pages/chanserv/access.cpp @@ -72,7 +72,7 @@ bool WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::s { ::ChanServ::ChanAccess *acc = ci->GetAccess(i); - if (acc->mask == message.post_data["mask"]) + if (acc->Mask() == message.post_data["mask"]) { if ((!highest || *acc >= *highest) && !u_access.founder && !has_priv) { @@ -92,8 +92,7 @@ bool WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::s else if (!denied) { ::ChanServ::ChanAccess *new_acc = a->Create(); - new_acc->ci = ci; - new_acc->mask = message.post_data["mask"]; + new_acc->SetMask(message.post_data["mask"], ci); new_acc->creator = na->nc->display; try { @@ -120,7 +119,7 @@ bool WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::s else { ci->AddAccess(new_acc); - replacements["MESSAGES"] = "Access for " + new_acc->mask + " set to " + new_acc->AccessSerialize(); + replacements["MESSAGES"] = "Access for " + new_acc->Mask() + " set to " + new_acc->AccessSerialize(); } } } @@ -135,7 +134,7 @@ bool WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::s { ::ChanServ::ChanAccess *access = ci->GetAccess(i); - replacements["MASKS"] = HTTPUtils::Escape(access->mask); + replacements["MASKS"] = HTTPUtils::Escape(access->Mask()); replacements["ACCESSES"] = HTTPUtils::Escape(access->AccessSerialize()); replacements["CREATORS"] = HTTPUtils::Escape(access->creator); } diff --git a/modules/webcpanel/pages/chanserv/modes.cpp b/modules/webcpanel/pages/chanserv/modes.cpp index 4af5dd16c..6dd0db276 100644 --- a/modules/webcpanel/pages/chanserv/modes.cpp +++ b/modules/webcpanel/pages/chanserv/modes.cpp @@ -61,7 +61,7 @@ bool WebCPanel::ChanServ::Modes::OnRequest(HTTPProvider *server, const Anope::st { ChannelMode *cm = ModeManager::GetChannelModes()[i]; - if (cm && cm->type == MODE_LIST) + if (cm->type == MODE_LIST && cm->mchar) replacements["LISTMODES"] = cm->mchar; } |
