mirror of
https://github.com/anope/anope.git
synced 2026-07-01 07:16:38 +02:00
Add "virtual mode" support
This allows fully tracking extbans and other modes set by a different underlying mode, such as InspIRCd's namedmodes Add two configuration options to cs_ban to configure which mode is set and whether or not to kick banned users. Add default "mute" fantasy command to botserv.example.conf
This commit is contained in:
+162
-37
@@ -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) { }
|
||||
|
||||
bool Matches(User *u, const Entry *e) anope_override
|
||||
InspIRCdExtBan(const Anope::string &mname, const Anope::string &basename, char extban) : ChannelModeVirtual<ChannelModeList>(mname, basename)
|
||||
, ext(extban)
|
||||
{
|
||||
const Anope::string &mask = e->GetMask();
|
||||
}
|
||||
|
||||
if (mask.find("m:") == 0 || mask.find("N:") == 0)
|
||||
ChannelMode *Wrap(Anope::string ¶m) anope_override
|
||||
{
|
||||
param = Anope::string(ext) + ":" + param;
|
||||
return ChannelModeVirtual<ChannelModeList>::Wrap(param);
|
||||
}
|
||||
|
||||
ChannelMode *Unwrap(ChannelMode *cm, Anope::string ¶m) anope_override
|
||||
{
|
||||
if (cm->type != MODE_LIST || param.length() < 3 || param[0] != ext || param[1] != ':')
|
||||
return cm;
|
||||
|
||||
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);
|
||||
}
|
||||
else if (mask.find("j:") == 0)
|
||||
};
|
||||
|
||||
class ChannelMatcher : public InspIRCdExtBan
|
||||
{
|
||||
public:
|
||||
ChannelMatcher(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 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;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
else if (mask.find("R:") == 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 (u->IsIdentified() && real_mask.equals_ci(u->Account()->display))
|
||||
return true;
|
||||
return u->IsIdentified() && real_mask.equals_ci(u->Account()->display);
|
||||
}
|
||||
else if (mask.find("r:") == 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) 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)
|
||||
{
|
||||
Anope::string real_mask = mask.substr(2);
|
||||
|
||||
if (Anope::Match(u->realname, real_mask))
|
||||
return true;
|
||||
}
|
||||
else if (mask.find("s:") == 0)
|
||||
|
||||
bool Matches(User *u, const Entry *e) anope_override
|
||||
{
|
||||
Anope::string real_mask = mask.substr(2);
|
||||
|
||||
if (Anope::Match(u->server->GetName(), real_mask))
|
||||
return true;
|
||||
const Anope::string &mask = e->GetMask();
|
||||
Anope::string real_mask = mask.substr(2);
|
||||
return !u->Account() && Entry("BAN", real_mask).Matches(u);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user