summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/commands/cs_ban.cpp47
-rw-r--r--modules/commands/cs_mode.cpp3
-rw-r--r--modules/commands/cs_unban.cpp15
-rw-r--r--modules/protocol/inspircd20.cpp195
-rw-r--r--modules/protocol/unreal.cpp124
-rw-r--r--modules/webcpanel/pages/chanserv/modes.cpp2
6 files changed, 299 insertions, 87 deletions
diff --git a/modules/commands/cs_ban.cpp b/modules/commands/cs_ban.cpp
index 0395ddd92..648e379e3 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) anope_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> &params) anope_override
{
const Anope::string &chan = params[0];
+ Configuration::Block *block = Config->GetCommand(source);
+ const Anope::string &mode = block->Get<Anope::string>("mode", "BAN");
ChannelInfo *ci = ChannelInfo::Find(chan);
if (ci == NULL)
@@ -57,9 +60,9 @@ class CommandCSBan : public Command
source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
return;
}
- else if (IRCD->GetMaxListFor(c) && c->HasMode("BAN") >= IRCD->GetMaxListFor(c))
+ else 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;
}
@@ -126,12 +129,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%s\002 expires in %s."), mask.c_str(), Anope::Duration(ban_time, source.GetAccount()).c_str());
}
}
@@ -140,10 +143,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
@@ -152,12 +158,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%s\002 expires in %s."), target.c_str(), Anope::Duration(ban_time, source.GetAccount()).c_str());
}
}
@@ -183,11 +189,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_mode.cpp b/modules/commands/cs_mode.cpp
index 941a6d183..2943c64a3 100644
--- a/modules/commands/cs_mode.cpp
+++ b/modules/commands/cs_mode.cpp
@@ -488,8 +488,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))
diff --git a/modules/commands/cs_unban.cpp b/modules/commands/cs_unban.cpp
index 56a482985..9fd6400a8 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> &params) anope_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";
@@ -80,7 +88,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%s\002."), ci->c->name.c_str());
else
diff --git a/modules/protocol/inspircd20.cpp b/modules/protocol/inspircd20.cpp
index 4e88d01a8..1e439da30 100644
--- a/modules/protocol/inspircd20.cpp
+++ b/modules/protocol/inspircd20.cpp
@@ -77,25 +77,61 @@ class InspIRCd20Proto : public IRCDProto
bool IsIdentValid(const Anope::string &ident) anope_override { return insp12->IsIdentValid(ident); }
};
-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 &param) anope_override
+ {
+ param = Anope::string(ext) + ":" + param;
+ return ChannelModeVirtual<ChannelModeList>::Wrap(param);
+ }
- bool Matches(User *u, const Entry *e) anope_override
+ ChannelMode *Unwrap(ChannelMode *cm, Anope::string &param) anope_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) anope_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) anope_override
{
+ const Anope::string &mask = e->GetMask();
+
Anope::string channel = mask.substr(3);
ChannelMode *cm = NULL;
@@ -116,39 +152,87 @@ 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) anope_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)
- {
- Anope::string real_mask = mask.substr(2);
+ };
- if (!u->fingerprint.empty() && Anope::Match(u->fingerprint, real_mask))
- return true;
+ 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) anope_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) anope_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) anope_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)
+ {
}
- return false;
- }
-};
+ bool Matches(User *u, const Entry *e) anope_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
{
@@ -304,17 +388,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"))
@@ -334,7 +427,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"))
@@ -350,17 +443,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"))
@@ -378,9 +483,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"))
@@ -481,11 +592,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)
diff --git a/modules/protocol/unreal.cpp b/modules/protocol/unreal.cpp
index d7bc8fa14..f444947f6 100644
--- a/modules/protocol/unreal.cpp
+++ b/modules/protocol/unreal.cpp
@@ -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 &param) anope_override
+ {
+ param = "~" + Anope::string(ext) + ":" + param;
+ return ChannelModeVirtual<ChannelModeList>::Wrap(param);
+ }
- bool Matches(User *u, const Entry *e) anope_override
+ ChannelMode *Unwrap(ChannelMode *cm, Anope::string &param) anope_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) anope_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) anope_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) anope_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) anope_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)
- {
+ };
+
+ class AccountMatcher : public UnrealExtBan
+ {
+ public:
+ AccountMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : UnrealExtBan(mname, mbase, c)
+ {
+ }
+
+ bool Matches(User *u, const Entry *e) anope_override
+ {
+ const Anope::string &mask = e->GetMask();
Anope::string real_mask = mask.substr(3);
- if (u->Account() && Anope::Match(u->Account()->display, real_mask))
- return true;
- }
-
- return false;
- }
-};
+ return u->Account() && Anope::Match(u->Account()->display, real_mask);
+ }
+ };
+}
class ChannelModeFlood : public ChannelModeParam
{
@@ -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]));
diff --git a/modules/webcpanel/pages/chanserv/modes.cpp b/modules/webcpanel/pages/chanserv/modes.cpp
index f087b86a9..a11d42fd9 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)
replacements["LISTMODES"] = cm->mchar;
}