mirror of
https://github.com/anope/anope.git
synced 2026-07-02 16:13:12 +02:00
Added support for extbans
This commit is contained in:
@@ -147,12 +147,6 @@ How To Add IRCd Support
|
||||
|
||||
ModeManager::AddChannelMode(new ChannelModeOper('O'));
|
||||
|
||||
The CMODE_FLOOD param also has its own class, but due to the wide range of
|
||||
valid parameters accepted across IRCds, your protocol module MUST have the
|
||||
IsValid function for this.
|
||||
|
||||
bool ChannelModeFlood::IsValid(const Anope::string &value) { }
|
||||
|
||||
4) Functions and Events
|
||||
|
||||
A brief word about functions and events. All events are captured by creating a Message struct
|
||||
|
||||
+9
-39
@@ -222,6 +222,14 @@ class CoreExport ChannelModeList : public ChannelMode
|
||||
*/
|
||||
virtual bool IsValid(const Anope::string &mask) const { return true; }
|
||||
|
||||
/** Checks if mask affects user
|
||||
* Should only be used for extbans or other weird ircd-specific things.
|
||||
* @param u The user
|
||||
* @param e The entry to match against
|
||||
* @return true on match
|
||||
*/
|
||||
virtual bool Matches(User *u, const Entry *e) { return false; }
|
||||
|
||||
/** Called when a mask is added to a channel
|
||||
* @param chan The channel
|
||||
* @param mask The mask
|
||||
@@ -233,7 +241,6 @@ class CoreExport ChannelModeList : public ChannelMode
|
||||
* @param mask The mask
|
||||
*/
|
||||
virtual void OnDel(Channel *chan, const Anope::string &mask) { }
|
||||
|
||||
};
|
||||
|
||||
/** This is a mode with a paramater, eg +k/l. These modes should use/inherit from this
|
||||
@@ -287,38 +294,11 @@ class CoreExport ChannelModeStatus : public ChannelMode
|
||||
class CoreExport ChannelModeBan : public ChannelModeList
|
||||
{
|
||||
public:
|
||||
ChannelModeBan(char modeChar) : ChannelModeList(CMODE_BAN, modeChar) { }
|
||||
ChannelModeBan(ChannelModeName mName, char modeChar) : ChannelModeList(mName, modeChar) { }
|
||||
|
||||
void OnAdd(Channel *chan, const Anope::string &mask);
|
||||
|
||||
void OnDel(Channel *chan, const Anope::string &mask);
|
||||
};
|
||||
|
||||
/** Channel mode +e
|
||||
*/
|
||||
class CoreExport ChannelModeExcept : public ChannelModeList
|
||||
{
|
||||
public:
|
||||
ChannelModeExcept(char modeChar) : ChannelModeList(CMODE_EXCEPT, modeChar) { }
|
||||
|
||||
void OnAdd(Channel *chan, const Anope::string &mask);
|
||||
|
||||
void OnDel(Channel *chan, const Anope::string &mask);
|
||||
};
|
||||
|
||||
/** Channel mode +I
|
||||
*/
|
||||
class CoreExport ChannelModeInvex : public ChannelModeList
|
||||
{
|
||||
public:
|
||||
ChannelModeInvex(char modeChar) : ChannelModeList(CMODE_INVITEOVERRIDE, modeChar) { }
|
||||
|
||||
void OnAdd(Channel *chan, const Anope::string &mask);
|
||||
|
||||
void OnDel(Channel *chan, const Anope::string &mask);
|
||||
};
|
||||
|
||||
|
||||
/** Channel mode +k (key)
|
||||
*/
|
||||
class CoreExport ChannelModeKey : public ChannelModeParam
|
||||
@@ -329,16 +309,6 @@ class CoreExport ChannelModeKey : public ChannelModeParam
|
||||
bool IsValid(const Anope::string &value) const;
|
||||
};
|
||||
|
||||
/** Channel mode +f (flood)
|
||||
*/
|
||||
class ChannelModeFlood : public ChannelModeParam
|
||||
{
|
||||
public:
|
||||
ChannelModeFlood(char modeChar, bool minusNoArg = false) : ChannelModeParam(CMODE_FLOOD, modeChar, minusNoArg) { }
|
||||
|
||||
bool IsValid(const Anope::string &value) const;
|
||||
};
|
||||
|
||||
/** This class is used for channel mode +A (Admin only)
|
||||
* Only opers can mlock it
|
||||
*/
|
||||
|
||||
+5
-3
@@ -452,7 +452,7 @@ class BotInfo;
|
||||
class ChannelInfo;
|
||||
class Channel;
|
||||
class Server;
|
||||
struct EList;
|
||||
class Entry;
|
||||
struct Session;
|
||||
|
||||
#include "threadengine.h"
|
||||
@@ -818,16 +818,18 @@ enum EntryType
|
||||
|
||||
class CoreExport Entry : public Flags<EntryType>
|
||||
{
|
||||
Anope::string mask;
|
||||
ChannelModeName modename;
|
||||
|
||||
public:
|
||||
unsigned char cidr_len;
|
||||
Anope::string mask;
|
||||
Anope::string nick, user, host;
|
||||
|
||||
/** Constructor
|
||||
* @param _host A full nick!ident@host/cidr mask
|
||||
* @param mode What mode this host is for - can be CMODE_BEGIN for unknown/no mode
|
||||
*/
|
||||
Entry(const Anope::string &_host);
|
||||
Entry(ChannelModeName mode, const Anope::string &_host);
|
||||
|
||||
/** Get the banned mask for this entry
|
||||
* @return The mask
|
||||
|
||||
@@ -219,7 +219,7 @@ class CommandCSAKick : public Command
|
||||
|
||||
ChanAccess *u2_access = ci->GetAccess(nc), *u_access = ci->GetAccess(u);
|
||||
int16 u2_level = u2_access ? u2_access->level : 0, u_level = u_access ? u_access->level : 0;
|
||||
Entry entry_mask(mask);
|
||||
Entry entry_mask(CMODE_BEGIN, mask);
|
||||
|
||||
if ((check_access(u2, ci, CA_FOUNDER) || u2_level >= u_level) && entry_mask.Matches(u2))
|
||||
{
|
||||
|
||||
@@ -91,7 +91,7 @@ class OSIgnoreService : public IgnoreService
|
||||
{
|
||||
for (; ign != ign_end; ++ign)
|
||||
{
|
||||
Entry ignore_mask(ign->mask);
|
||||
Entry ignore_mask(CMODE_BEGIN, ign->mask);
|
||||
if (ignore_mask.Matches(u))
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -410,7 +410,7 @@ class BahamutIRCdMessage : public IRCdMessage
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByChar(ch);
|
||||
if (!cm)
|
||||
{
|
||||
Log() << "Receeved unknown mode prefix " << buf[0] << " in SJOIN string";
|
||||
Log() << "Receeved unknown mode prefix " << cm << " in SJOIN string";
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -528,18 +528,24 @@ bool event_burst(const Anope::string &source, const std::vector<Anope::string> &
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChannelModeFlood::IsValid(const Anope::string &value) const
|
||||
class ChannelModeFlood : public ChannelModeParam
|
||||
{
|
||||
try
|
||||
{
|
||||
Anope::string rest;
|
||||
if (!value.empty() && value[0] != ':' && convertTo<int>(value[0] == '*' ? value.substr(1) : value, rest, false) > 0 && rest[0] == ':' && rest.length() > 1 && convertTo<int>(rest.substr(1), rest, false) > 0 && rest.empty())
|
||||
return true;
|
||||
}
|
||||
catch (const ConvertException &) { }
|
||||
public:
|
||||
ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam(CMODE_FLOOD, modeChar, minusNoArg) { }
|
||||
|
||||
return false;
|
||||
}
|
||||
bool IsValid(const Anope::string &value) const
|
||||
{
|
||||
try
|
||||
{
|
||||
Anope::string rest;
|
||||
if (!value.empty() && value[0] != ':' && convertTo<int>(value[0] == '*' ? value.substr(1) : value, rest, false) > 0 && rest[0] == ':' && rest.length() > 1 && convertTo<int>(rest.substr(1), rest, false) > 0 && rest.empty())
|
||||
return true;
|
||||
}
|
||||
catch (const ConvertException &) { }
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class ProtoBahamut : public Module
|
||||
{
|
||||
@@ -562,7 +568,7 @@ class ProtoBahamut : public Module
|
||||
ModeManager::AddUserMode(new UserMode(UMODE_DEAF, 'd'));
|
||||
|
||||
/* b/e/I */
|
||||
ModeManager::AddChannelMode(new ChannelModeBan('b'));
|
||||
ModeManager::AddChannelMode(new ChannelModeBan(CMODE_BAN, 'b'));
|
||||
|
||||
/* v/h/o/a/q */
|
||||
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+'));
|
||||
@@ -571,7 +577,7 @@ class ProtoBahamut : public Module
|
||||
/* Add channel modes */
|
||||
ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCOLOR, 'c'));
|
||||
ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, 'i'));
|
||||
ModeManager::AddChannelMode(new ChannelModeFlood('f'));
|
||||
ModeManager::AddChannelMode(new ChannelModeFlood('f', false));
|
||||
ModeManager::AddChannelMode(new ChannelModeKey('k'));
|
||||
ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, 'l'));
|
||||
ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, 'm'));
|
||||
|
||||
@@ -9,6 +9,25 @@
|
||||
* Based on the original code of Services by Andy Church.
|
||||
*/
|
||||
|
||||
class ChannelModeFlood : public ChannelModeParam
|
||||
{
|
||||
public:
|
||||
ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam(CMODE_FLOOD, modeChar, minusNoArg) { }
|
||||
|
||||
bool IsValid(const Anope::string &value) const
|
||||
{
|
||||
try
|
||||
{
|
||||
Anope::string rest;
|
||||
if (!value.empty() && value[0] != ':' && convertTo<int>(value[0] == '*' ? value.substr(1) : value, rest, false) > 0 && rest[0] == ':' && rest.length() > 1 && convertTo<int>(rest.substr(1), rest, false) > 0 && rest.empty())
|
||||
return true;
|
||||
}
|
||||
catch (const ConvertException &) { }
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class InspIRCdTS6Proto : public IRCDProto
|
||||
{
|
||||
private:
|
||||
|
||||
@@ -264,6 +264,25 @@ class InspIRCdProto : public IRCDProto
|
||||
|
||||
};
|
||||
|
||||
class ChannelModeFlood : public ChannelModeParam
|
||||
{
|
||||
public:
|
||||
ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam(CMODE_FLOOD, modeChar, minusNoArg) { }
|
||||
|
||||
bool IsValid(const Anope::string &value) const
|
||||
{
|
||||
try
|
||||
{
|
||||
Anope::string rest;
|
||||
if (!value.empty() && value[0] != ':' && convertTo<int>(value[0] == '*' ? value.substr(1) : value, rest, false) > 0 && rest[0] == ':' && rest.length() > 1 && convertTo<int>(rest.substr(1), rest, false) > 0 && rest.empty())
|
||||
return true;
|
||||
}
|
||||
catch (const ConvertException &) { }
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class InspircdIRCdMessage : public IRCdMessage
|
||||
{
|
||||
public:
|
||||
@@ -374,13 +393,13 @@ class InspircdIRCdMessage : public IRCdMessage
|
||||
switch (modebuf[t])
|
||||
{
|
||||
case 'b':
|
||||
ModeManager::AddChannelMode(new ChannelModeBan('b'));
|
||||
ModeManager::AddChannelMode(new ChannelModeBan(CMODE_BAN, 'b'));
|
||||
continue;
|
||||
case 'e':
|
||||
ModeManager::AddChannelMode(new ChannelModeExcept('e'));
|
||||
ModeManager::AddChannelMode(new ChannelModeList(CMODE_EXCEPT, 'e'));
|
||||
continue;
|
||||
case 'I':
|
||||
ModeManager::AddChannelMode(new ChannelModeInvex('I'));
|
||||
ModeManager::AddChannelMode(new ChannelModeList(CMODE_INVITEOVERRIDE, 'I'));
|
||||
continue;
|
||||
default:
|
||||
ModeManager::AddChannelMode(new ChannelModeList(CMODE_END, modebuf[t]));
|
||||
@@ -406,7 +425,7 @@ class InspircdIRCdMessage : public IRCdMessage
|
||||
switch (modebuf[t])
|
||||
{
|
||||
case 'f':
|
||||
ModeManager::AddChannelMode(new ChannelModeFlood('f'));
|
||||
ModeManager::AddChannelMode(new ChannelModeFlood('f', false));
|
||||
continue;
|
||||
case 'l':
|
||||
ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, 'l', true));
|
||||
@@ -844,19 +863,6 @@ bool event_endburst(const Anope::string &source, const std::vector<Anope::string
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChannelModeFlood::IsValid(const Anope::string &value) const
|
||||
{
|
||||
try
|
||||
{
|
||||
Anope::string rest;
|
||||
if (!value.empty() && value[0] != ':' && convertTo<int>(value[0] == '*' ? value.substr(1) : value, rest, false) > 0 && rest[0] == ':' && rest.length() > 1 && convertTo<int>(rest.substr(1), rest, false) > 0 && rest.empty())
|
||||
return true;
|
||||
}
|
||||
catch (const ConvertException &) { }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
class ProtoInspIRCd : public Module
|
||||
{
|
||||
Message message_endburst, message_rsquit, message_svsmode, message_chghost, message_chgident, message_chgname,
|
||||
|
||||
@@ -311,6 +311,60 @@ bool event_endburst(const Anope::string &source, const std::vector<Anope::string
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T> class InspIRCdExtBan : public T
|
||||
{
|
||||
public:
|
||||
InspIRCdExtBan(ChannelModeName mName, char modeChar) : T(mName, modeChar) { }
|
||||
|
||||
bool Matches(User *u, const Entry *e)
|
||||
{
|
||||
const Anope::string &mask = e->mask;
|
||||
|
||||
if (mask.find("A:") == 0 || mask.find("B:") == 0 || mask.find("c:") == 0 || mask.find("C:") == 0 ||
|
||||
mask.find("m:") == 0 || mask.find("N:") == 0 || mask.find("p:") == 0 || mask.find("Q:") == 0 ||
|
||||
mask.find("N:") == 0 || mask.find("p:") == 0 || mask.find("Q:") == 0 || mask.find("S:") == 0 ||
|
||||
mask.find("T:") == 0)
|
||||
{
|
||||
Anope::string real_mask = mask.substr(2);
|
||||
|
||||
Entry en(this->Name, real_mask);
|
||||
if (en.Matches(u))
|
||||
return true;
|
||||
}
|
||||
else if (mask.find("j:") == 0)
|
||||
{
|
||||
Anope::string real_mask = mask.substr(2);
|
||||
|
||||
Channel *c = findchan(real_mask);
|
||||
if (c != NULL && c->FindUser(u) != NULL)
|
||||
return true;
|
||||
}
|
||||
else if (mask.find("M:") == 0 || mask.find("R:") == 0)
|
||||
{
|
||||
Anope::string real_mask = mask.substr(2);
|
||||
|
||||
if (u->IsIdentified() && real_mask.equals_ci(u->Account()->display))
|
||||
return true;
|
||||
}
|
||||
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)
|
||||
{
|
||||
Anope::string real_mask = mask.substr(2);
|
||||
|
||||
if (Anope::Match(u->server->GetName(), real_mask))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class Inspircd12IRCdMessage : public InspircdIRCdMessage
|
||||
{
|
||||
public:
|
||||
@@ -388,13 +442,13 @@ class Inspircd12IRCdMessage : public InspircdIRCdMessage
|
||||
switch (modebuf[t])
|
||||
{
|
||||
case 'b':
|
||||
ModeManager::AddChannelMode(new ChannelModeBan('b'));
|
||||
ModeManager::AddChannelMode(new InspIRCdExtBan<ChannelModeBan>(CMODE_BAN, 'b'));
|
||||
continue;
|
||||
case 'e':
|
||||
ModeManager::AddChannelMode(new ChannelModeExcept('e'));
|
||||
ModeManager::AddChannelMode(new InspIRCdExtBan<ChannelModeList>(CMODE_EXCEPT, 'e'));
|
||||
continue;
|
||||
case 'I':
|
||||
ModeManager::AddChannelMode(new ChannelModeInvex('I'));
|
||||
ModeManager::AddChannelMode(new InspIRCdExtBan<ChannelModeList>(CMODE_INVITEOVERRIDE, 'I'));
|
||||
continue;
|
||||
/* InspIRCd sends q and a here if they have no prefixes */
|
||||
case 'q':
|
||||
@@ -675,19 +729,6 @@ class Inspircd12IRCdMessage : public InspircdIRCdMessage
|
||||
}
|
||||
};
|
||||
|
||||
bool ChannelModeFlood::IsValid(const Anope::string &value) const
|
||||
{
|
||||
try
|
||||
{
|
||||
Anope::string rest;
|
||||
if (!value.empty() && value[0] != ':' && convertTo<int>(value[0] == '*' ? value.substr(1) : value, rest, false) > 0 && rest[0] == ':' && rest.length() > 1 && convertTo<int>(rest.substr(1), rest, false) > 0 && rest.empty())
|
||||
return true;
|
||||
}
|
||||
catch (const CoreException &) { }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
class ProtoInspIRCd : public Module
|
||||
{
|
||||
Message message_endburst, message_time,
|
||||
|
||||
@@ -321,6 +321,81 @@ bool event_endburst(const Anope::string &source, const std::vector<Anope::string
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T> class InspIRCdExtBan : public T
|
||||
{
|
||||
public:
|
||||
InspIRCdExtBan(ChannelModeName mName, char modeChar) : T(mName, modeChar) { }
|
||||
|
||||
bool Matches(User *u, const Entry *e)
|
||||
{
|
||||
const Anope::string &mask = e->mask;
|
||||
|
||||
if (mask.find("A:") == 0 || mask.find("B:") == 0 || mask.find("c:") == 0 || mask.find("C:") == 0 ||
|
||||
mask.find("m:") == 0 || mask.find("N:") == 0 || mask.find("p:") == 0 || mask.find("Q:") == 0 ||
|
||||
mask.find("S:") == 0 || mask.find("T:") == 0)
|
||||
{
|
||||
Anope::string real_mask = mask.substr(3);
|
||||
|
||||
Entry en(this->Name, real_mask);
|
||||
if (en.Matches(u))
|
||||
return true;
|
||||
}
|
||||
else if (mask.find("j:") == 0)
|
||||
{
|
||||
Anope::string channel = mask.substr(3);
|
||||
|
||||
ChannelMode *cm = NULL;
|
||||
if (channel[0] != '#')
|
||||
{
|
||||
char modeChar = ModeManager::GetStatusChar(channel[0]);
|
||||
channel.erase(channel.begin());
|
||||
cm = ModeManager::FindChannelModeByChar(modeChar);
|
||||
if (cm != NULL && cm->Type != MODE_STATUS)
|
||||
cm = NULL;
|
||||
}
|
||||
|
||||
Channel *c = findchan(channel);
|
||||
if (c != NULL)
|
||||
{
|
||||
UserContainer *uc = c->FindUser(u);
|
||||
if (uc != NULL)
|
||||
if (cm == NULL || uc->Status->HasFlag(cm->Name))
|
||||
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;
|
||||
}
|
||||
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)
|
||||
{
|
||||
Anope::string real_mask = mask.substr(2);
|
||||
|
||||
if (Anope::Match(u->server->GetName(), real_mask))
|
||||
return true;
|
||||
}
|
||||
else if (mask.find("z:") == 0)
|
||||
{
|
||||
Anope::string real_mask = mask.substr(2);
|
||||
|
||||
if (Anope::Match(u->fingerprint, real_mask))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class Inspircd20IRCdMessage : public InspircdIRCdMessage
|
||||
{
|
||||
public:
|
||||
@@ -387,9 +462,9 @@ class Inspircd20IRCdMessage : public InspircdIRCdMessage
|
||||
else if (modename.equals_cs("auditorium"))
|
||||
cm = new ChannelMode(CMODE_AUDITORIUM, modechar[0]);
|
||||
else if (modename.equals_cs("ban"))
|
||||
cm = new ChannelModeBan(modechar[0]);
|
||||
cm = new InspIRCdExtBan<ChannelModeBan>(CMODE_BAN, modechar[0]);
|
||||
else if (modename.equals_cs("banexception"))
|
||||
cm = new ChannelModeExcept(modechar[0]);
|
||||
cm = new InspIRCdExtBan<ChannelModeList>(CMODE_EXCEPT, 'e');
|
||||
else if (modename.equals_cs("blockcaps"))
|
||||
cm = new ChannelMode(CMODE_BLOCKCAPS, modechar[0]);
|
||||
else if (modename.equals_cs("blockcolor"))
|
||||
@@ -407,7 +482,7 @@ class Inspircd20IRCdMessage : public InspircdIRCdMessage
|
||||
else if (modename.equals_cs("halfop"))
|
||||
cm = new ChannelModeStatus(CMODE_HALFOP, modechar[1], modechar[0]);
|
||||
else if (modename.equals_cs("invex"))
|
||||
cm = new ChannelModeInvex(modechar[0]);
|
||||
cm = new InspIRCdExtBan<ChannelModeList>(CMODE_INVITEOVERRIDE, 'I');
|
||||
else if (modename.equals_cs("inviteonly"))
|
||||
cm = new ChannelMode(CMODE_INVITE, modechar[0]);
|
||||
else if (modename.equals_cs("joinflood"))
|
||||
@@ -649,19 +724,6 @@ class Inspircd20IRCdMessage : public InspircdIRCdMessage
|
||||
}
|
||||
};
|
||||
|
||||
bool ChannelModeFlood::IsValid(const Anope::string &value) const
|
||||
{
|
||||
try
|
||||
{
|
||||
Anope::string rest;
|
||||
if (!value.empty() && value[0] != ':' && convertTo<int>(value[0] == '*' ? value.substr(1) : value, rest, false) > 0 && rest[0] == ':' && rest.length() > 1 && convertTo<int>(rest.substr(1), rest, false) > 0 && rest.empty())
|
||||
return true;
|
||||
}
|
||||
catch (const ConvertException &) { }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
class ProtoInspIRCd : public Module
|
||||
{
|
||||
Message message_endburst, message_time,
|
||||
|
||||
@@ -425,8 +425,8 @@ class ProtongIRCd : public Module
|
||||
ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, 'x'));
|
||||
|
||||
/* b/e/I */
|
||||
ModeManager::AddChannelMode(new ChannelModeBan('b'));
|
||||
ModeManager::AddChannelMode(new ChannelModeInvex('I'));
|
||||
ModeManager::AddChannelMode(new ChannelModeBan(CMODE_BAN, 'b'));
|
||||
ModeManager::AddChannelMode(new ChannelModeList(CMODE_INVITEOVERRIDE, 'I'));
|
||||
|
||||
/* v/h/o/a/q */
|
||||
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+'));
|
||||
|
||||
@@ -366,7 +366,7 @@ class PlexusIRCdMessage : public IRCdMessage
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByChar(ch);
|
||||
if (!cm)
|
||||
{
|
||||
Log() << "Received unknown mode prefix " << buf[0] << " in SJOIN string";
|
||||
Log() << "Received unknown mode prefix " << ch << " in SJOIN string";
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -596,9 +596,9 @@ class ProtoPlexus : public Module
|
||||
ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, 'x'));
|
||||
|
||||
/* b/e/I */
|
||||
ModeManager::AddChannelMode(new ChannelModeBan('b'));
|
||||
ModeManager::AddChannelMode(new ChannelModeExcept('e'));
|
||||
ModeManager::AddChannelMode(new ChannelModeInvex('I'));
|
||||
ModeManager::AddChannelMode(new ChannelModeBan(CMODE_BAN, 'b'));
|
||||
ModeManager::AddChannelMode(new ChannelModeList(CMODE_EXCEPT, 'e'));
|
||||
ModeManager::AddChannelMode(new ChannelModeList(CMODE_INVITEOVERRIDE, 'I'));
|
||||
|
||||
/* l/k */
|
||||
ModeManager::AddChannelMode(new ChannelModeKey('k'));
|
||||
|
||||
@@ -369,7 +369,7 @@ class RatboxIRCdMessage : public IRCdMessage
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByChar(ch);
|
||||
if (!cm)
|
||||
{
|
||||
Log() << "Received unknown mode prefix " << buf[0] << " in SJOIN string";
|
||||
Log() << "Received unknown mode prefix " << ch << " in SJOIN string";
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -546,9 +546,9 @@ class ProtoRatbox : public Module
|
||||
ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, 'w'));
|
||||
|
||||
/* b/e/I */
|
||||
ModeManager::AddChannelMode(new ChannelModeBan('b'));
|
||||
ModeManager::AddChannelMode(new ChannelModeExcept('e'));
|
||||
ModeManager::AddChannelMode(new ChannelModeInvex('I'));
|
||||
ModeManager::AddChannelMode(new ChannelModeBan(CMODE_BAN, 'b'));
|
||||
ModeManager::AddChannelMode(new ChannelModeList(CMODE_EXCEPT, 'e'));
|
||||
ModeManager::AddChannelMode(new ChannelModeList(CMODE_INVITEOVERRIDE, 'I'));
|
||||
|
||||
/* v/h/o/a/q */
|
||||
ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+'));
|
||||
|
||||
+106
-42
@@ -348,6 +348,107 @@ class UnrealIRCdProto : public IRCDProto
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> class UnrealExtBan : public T
|
||||
{
|
||||
public:
|
||||
UnrealExtBan(ChannelModeName mName, char modeChar) : T(mName, modeChar) { }
|
||||
|
||||
bool Matches(User *u, const Entry *e)
|
||||
{
|
||||
const Anope::string &mask = e->mask;
|
||||
|
||||
if (mask.find("~c:") == 0)
|
||||
{
|
||||
Anope::string channel = mask.substr(3);
|
||||
|
||||
ChannelMode *cm = NULL;
|
||||
if (channel[0] != '#')
|
||||
{
|
||||
char modeChar = ModeManager::GetStatusChar(channel[0]);
|
||||
channel.erase(channel.begin());
|
||||
cm = ModeManager::FindChannelModeByChar(modeChar);
|
||||
if (cm != NULL && cm->Type != MODE_STATUS)
|
||||
cm = NULL;
|
||||
}
|
||||
|
||||
Channel *c = findchan(channel);
|
||||
if (c != NULL)
|
||||
{
|
||||
UserContainer *uc = c->FindUser(u);
|
||||
if (uc != NULL)
|
||||
if (cm == NULL || uc->Status->HasFlag(cm->Name))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (mask.find("~j:") == 0 || mask.find("~n:") == 0 || mask.find("~q:") == 0)
|
||||
{
|
||||
Anope::string real_mask = mask.substr(3);
|
||||
|
||||
Entry en(this->Name, real_mask);
|
||||
if (en.Matches(u))
|
||||
return true;
|
||||
}
|
||||
else if (mask.find("~r:") == 0)
|
||||
{
|
||||
Anope::string real_mask = mask.substr(3);
|
||||
|
||||
if (Anope::Match(u->realname, real_mask))
|
||||
return true;
|
||||
}
|
||||
else if (mask.find("~R:") == 0)
|
||||
{
|
||||
if (u->HasMode(UMODE_REGISTERED) && mask.equals_ci(u->nick))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class ChannelModeFlood : public ChannelModeParam
|
||||
{
|
||||
public:
|
||||
ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam(CMODE_FLOOD, modeChar, minusNoArg) { }
|
||||
|
||||
/* Borrowed part of this check from UnrealIRCd */
|
||||
bool IsValid(const Anope::string &value) const
|
||||
{
|
||||
if (value.empty())
|
||||
return false;
|
||||
try
|
||||
{
|
||||
Anope::string rest;
|
||||
if (value[0] != ':' && convertTo<unsigned>(value[0] == '*' ? value.substr(1) : value, rest, false) > 0 && rest[0] == ':' && rest.length() > 1 && convertTo<unsigned>(rest.substr(1), rest, false) > 0 && rest.empty())
|
||||
return true;
|
||||
}
|
||||
catch (const ConvertException &) { }
|
||||
|
||||
/* '['<number><1 letter>[optional: '#'+1 letter],[next..]']'':'<number> */
|
||||
size_t end_bracket = value.find(']', 1);
|
||||
if (end_bracket == Anope::string::npos)
|
||||
return false;
|
||||
Anope::string xbuf = value.substr(0, end_bracket);
|
||||
if (value[end_bracket + 1] != ':')
|
||||
return false;
|
||||
commasepstream args(xbuf.substr(1));
|
||||
Anope::string arg;
|
||||
while (args.GetToken(arg))
|
||||
{
|
||||
/* <number><1 letter>[optional: '#'+1 letter] */
|
||||
size_t p = 0;
|
||||
while (p < arg.length() && isdigit(arg[p]))
|
||||
++p;
|
||||
if (p == arg.length() || !(arg[p] == 'c' || arg[p] == 'j' || arg[p] == 'k' || arg[p] == 'm' || arg[p] == 'n' || arg[p] == 't'))
|
||||
continue; /* continue instead of break for forward compatability. */
|
||||
int v = arg.substr(0, p).is_number_only() ? convertTo<int>(arg.substr(0, p)) : 0;
|
||||
if (v < 1 || v > 999)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class Unreal32IRCdMessage : public IRCdMessage
|
||||
{
|
||||
public:
|
||||
@@ -521,13 +622,13 @@ class Unreal32IRCdMessage : public IRCdMessage
|
||||
switch (modebuf[t])
|
||||
{
|
||||
case 'b':
|
||||
ModeManager::AddChannelMode(new ChannelModeBan('b'));
|
||||
ModeManager::AddChannelMode(new UnrealExtBan<ChannelModeBan>(CMODE_BAN, 'b'));
|
||||
continue;
|
||||
case 'e':
|
||||
ModeManager::AddChannelMode(new ChannelModeExcept('e'));
|
||||
ModeManager::AddChannelMode(new UnrealExtBan<ChannelModeList>(CMODE_EXCEPT, 'e'));
|
||||
continue;
|
||||
case 'I':
|
||||
ModeManager::AddChannelMode(new ChannelModeInvex('I'));
|
||||
ModeManager::AddChannelMode(new UnrealExtBan<ChannelModeList>(CMODE_INVITEOVERRIDE, 'I'));
|
||||
continue;
|
||||
default:
|
||||
ModeManager::AddChannelMode(new ChannelModeList(CMODE_END, modebuf[t]));
|
||||
@@ -543,7 +644,7 @@ class Unreal32IRCdMessage : public IRCdMessage
|
||||
ModeManager::AddChannelMode(new ChannelModeKey('k'));
|
||||
continue;
|
||||
case 'f':
|
||||
ModeManager::AddChannelMode(new ChannelModeFlood('f'));
|
||||
ModeManager::AddChannelMode(new ChannelModeFlood('f', false));
|
||||
continue;
|
||||
case 'L':
|
||||
ModeManager::AddChannelMode(new ChannelModeParam(CMODE_REDIRECT, 'L'));
|
||||
@@ -722,7 +823,7 @@ class Unreal32IRCdMessage : public IRCdMessage
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByChar(ch);
|
||||
if (!cm)
|
||||
{
|
||||
Log() << "Received unknown mode prefix " << buf[0] << " in SJOIN string";
|
||||
Log() << "Received unknown mode prefix " << ch << " in SJOIN string";
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -936,43 +1037,6 @@ bool event_sdesc(const Anope::string &source, const std::vector<Anope::string> &
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Borrowed part of this check from UnrealIRCd */
|
||||
bool ChannelModeFlood::IsValid(const Anope::string &value) const
|
||||
{
|
||||
if (value.empty())
|
||||
return false;
|
||||
try
|
||||
{
|
||||
Anope::string rest;
|
||||
if (value[0] != ':' && convertTo<unsigned>(value[0] == '*' ? value.substr(1) : value, rest, false) > 0 && rest[0] == ':' && rest.length() > 1 && convertTo<unsigned>(rest.substr(1), rest, false) > 0 && rest.empty())
|
||||
return true;
|
||||
}
|
||||
catch (const ConvertException &) { }
|
||||
|
||||
/* '['<number><1 letter>[optional: '#'+1 letter],[next..]']'':'<number> */
|
||||
size_t end_bracket = value.find(']', 1);
|
||||
if (end_bracket == Anope::string::npos)
|
||||
return false;
|
||||
Anope::string xbuf = value.substr(0, end_bracket);
|
||||
if (value[end_bracket + 1] != ':')
|
||||
return false;
|
||||
commasepstream args(xbuf.substr(1));
|
||||
Anope::string arg;
|
||||
while (args.GetToken(arg))
|
||||
{
|
||||
/* <number><1 letter>[optional: '#'+1 letter] */
|
||||
size_t p = 0;
|
||||
while (p < arg.length() && isdigit(arg[p]))
|
||||
++p;
|
||||
if (p == arg.length() || !(arg[p] == 'c' || arg[p] == 'j' || arg[p] == 'k' || arg[p] == 'm' || arg[p] == 'n' || arg[p] == 't'))
|
||||
continue; /* continue instead of break for forward compatability. */
|
||||
int v = arg.substr(0, p).is_number_only() ? convertTo<int>(arg.substr(0, p)) : 0;
|
||||
if (v < 1 || v > 999)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
class ProtoUnreal : public Module
|
||||
{
|
||||
Message message_away, message_join, message_kick,
|
||||
|
||||
+1
-1
@@ -78,7 +78,7 @@ void common_unban(ChannelInfo *ci, User *u, bool full)
|
||||
std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> bans = ci->c->GetModeList(CMODE_BAN);
|
||||
for (; bans.first != bans.second;)
|
||||
{
|
||||
Entry ban(bans.first->second);
|
||||
Entry ban(CMODE_BAN, bans.first->second);
|
||||
++bans.first;
|
||||
if (ban.Matches(u, full))
|
||||
ci->c->RemoveMode(NULL, CMODE_BAN, ban.GetMask());
|
||||
|
||||
+1
-1
@@ -179,7 +179,7 @@ void BotInfo::Join(Channel *c, ChannelStatus *status)
|
||||
/* We check for bans */
|
||||
for (; bans.first != bans.second; ++bans.first)
|
||||
{
|
||||
Entry ban(bans.first->second);
|
||||
Entry ban(CMODE_BAN, bans.first->second);
|
||||
if (ban.Matches(this))
|
||||
c->RemoveMode(NULL, CMODE_BAN, ban.GetMask());
|
||||
}
|
||||
|
||||
+21
-17
@@ -1234,9 +1234,10 @@ void MassChannelModes(BotInfo *bi, const Anope::string &modes)
|
||||
static const Anope::string EntryFlagString[] = { "ENTRYTYPE_NONE", "ENTRYTYPE_CIDR", "ENTRYTYPE_NICK_WILD", "ENTRYTYPE_NICK", "ENTRYTYPE_USER_WILD", "ENTRYTYPE_USER", "ENTRYTYPE_HOST_WILD", "ENTRYTYPE_HOST", "" };
|
||||
|
||||
/** Constructor
|
||||
* @param mode What mode this host is for - can be CMODE_BEGIN for unknown/no mode
|
||||
* @param _host A full nick!ident@host/cidr mask
|
||||
*/
|
||||
Entry::Entry(const Anope::string &_host) : Flags<EntryType>(EntryFlagString)
|
||||
Entry::Entry(ChannelModeName mode, const Anope::string &_host) : Flags<EntryType>(EntryFlagString), modename(mode)
|
||||
{
|
||||
this->SetFlag(ENTRYTYPE_NONE);
|
||||
this->cidr_len = 0;
|
||||
@@ -1330,8 +1331,7 @@ const Anope::string Entry::GetMask()
|
||||
*/
|
||||
bool Entry::Matches(User *u, bool full) const
|
||||
{
|
||||
if (!this->FlagCount())
|
||||
return false;
|
||||
bool ret = true;
|
||||
|
||||
if (this->HasFlag(ENTRYTYPE_CIDR))
|
||||
{
|
||||
@@ -1339,39 +1339,43 @@ bool Entry::Matches(User *u, bool full) const
|
||||
{
|
||||
cidr cidr_mask(this->host, this->cidr_len);
|
||||
if (!u->ip() || !cidr_mask.match(u->ip))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
ret = false;
|
||||
/* If we're not matching fully and their displayed host isnt their IP */
|
||||
else if (!full && u->ip.addr() != u->GetDisplayedHost())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
ret = false;
|
||||
}
|
||||
catch (const SocketException &)
|
||||
{
|
||||
return false;
|
||||
ret = false;
|
||||
}
|
||||
}
|
||||
if (this->HasFlag(ENTRYTYPE_NICK) && !this->nick.equals_ci(u->nick))
|
||||
return false;
|
||||
ret = false;
|
||||
if (this->HasFlag(ENTRYTYPE_USER) && !this->user.equals_ci(u->GetVIdent()) && (!full ||
|
||||
!this->user.equals_ci(u->GetIdent())))
|
||||
return false;
|
||||
ret = false;
|
||||
if (this->HasFlag(ENTRYTYPE_HOST) && !this->host.equals_ci(u->GetDisplayedHost()) && (!full ||
|
||||
(!this->host.equals_ci(u->host) && !this->host.equals_ci(u->chost) && !this->host.equals_ci(u->vhost) &&
|
||||
(!u->ip() || !this->host.equals_ci(u->ip.addr())))))
|
||||
return false;
|
||||
ret = false;
|
||||
if (this->HasFlag(ENTRYTYPE_NICK_WILD) && !Anope::Match(u->nick, this->nick))
|
||||
return false;
|
||||
ret = false;
|
||||
if (this->HasFlag(ENTRYTYPE_USER_WILD) && !Anope::Match(u->GetVIdent(), this->user) && (!full ||
|
||||
!Anope::Match(u->GetIdent(), this->user)))
|
||||
return false;
|
||||
ret = false;
|
||||
if (this->HasFlag(ENTRYTYPE_HOST_WILD) && !Anope::Match(u->GetDisplayedHost(), this->host) && (!full ||
|
||||
(!Anope::Match(u->host, this->host) && !Anope::Match(u->chost, this->host) &&
|
||||
!Anope::Match(u->vhost, this->host) && (!u->ip() || !Anope::Match(u->ip.addr(), this->host)))))
|
||||
return false;
|
||||
ret = false;
|
||||
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(this->modename);
|
||||
if (cm != NULL && cm->Type == MODE_LIST)
|
||||
{
|
||||
ChannelModeList *cml = debug_cast<ChannelModeList *>(cm);
|
||||
if (cml->Matches(u, this))
|
||||
ret = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -491,7 +491,8 @@ int main(int ac, char **av, char **envp)
|
||||
threadEngine.Process();
|
||||
|
||||
/* Process any modes that need to be (un)set */
|
||||
ModeManager::ProcessModes();
|
||||
if (Me != NULL && Me->IsSynced())
|
||||
ModeManager::ProcessModes();
|
||||
|
||||
/* Process the socket engine */
|
||||
SocketEngine->Process();
|
||||
|
||||
+1
-62
@@ -294,7 +294,7 @@ void ChannelModeBan::OnAdd(Channel *chan, const Anope::string &mask)
|
||||
{
|
||||
BotInfo *bi = chan->ci->bi;
|
||||
|
||||
Entry ban(mask);
|
||||
Entry ban(CMODE_BAN, mask);
|
||||
if (ban.Matches(bi))
|
||||
chan->RemoveMode(NULL, CMODE_BAN, mask);
|
||||
}
|
||||
@@ -302,67 +302,6 @@ void ChannelModeBan::OnAdd(Channel *chan, const Anope::string &mask)
|
||||
Log(LOG_DEBUG) << "Added ban " << mask << " to channel " << chan->name;
|
||||
}
|
||||
|
||||
/** Remove a ban from the channel
|
||||
* @param chan The channel
|
||||
* @param mask The ban
|
||||
*/
|
||||
void ChannelModeBan::OnDel(Channel *chan, const Anope::string &mask)
|
||||
{
|
||||
if (!chan || mask.empty())
|
||||
return;
|
||||
|
||||
Log(LOG_DEBUG) << "Deleted ban " << mask << " from channel " << chan->name;
|
||||
}
|
||||
|
||||
/** Add an except to the channel
|
||||
* @param chan The channel
|
||||
* @param mask The except
|
||||
*/
|
||||
void ChannelModeExcept::OnAdd(Channel *chan, const Anope::string &mask)
|
||||
{
|
||||
if (!chan || mask.empty())
|
||||
return;
|
||||
|
||||
Log(LOG_DEBUG) << "Added except " << mask << " to channel " << chan->name;
|
||||
}
|
||||
|
||||
/** Remove an except from the channel
|
||||
* @param chan The channel
|
||||
* @param mask The except
|
||||
*/
|
||||
void ChannelModeExcept::OnDel(Channel *chan, const Anope::string &mask)
|
||||
{
|
||||
if (!chan || mask.empty())
|
||||
return;
|
||||
|
||||
Log(LOG_DEBUG) << "Deleted except " << mask << " to channel " << chan->name;
|
||||
}
|
||||
|
||||
/** Add an invex to the channel
|
||||
* @param chan The channel
|
||||
* @param mask The invex
|
||||
*/
|
||||
void ChannelModeInvex::OnAdd(Channel *chan, const Anope::string &mask)
|
||||
{
|
||||
if (!chan || mask.empty())
|
||||
return;
|
||||
|
||||
Log(LOG_DEBUG) << "Added invite " << mask << " to channel " << chan->name;
|
||||
|
||||
}
|
||||
|
||||
/** Remove an invex from the channel
|
||||
* @param chan The channel
|
||||
* @param mask The index
|
||||
*/
|
||||
void ChannelModeInvex::OnDel(Channel *chan, const Anope::string &mask)
|
||||
{
|
||||
if (!chan || mask.empty())
|
||||
return;
|
||||
|
||||
Log(LOG_DEBUG) << "Deleted invite " << mask << " to channel " << chan->name;
|
||||
}
|
||||
|
||||
void StackerInfo::AddMode(Mode *mode, bool Set, const Anope::string &Param)
|
||||
{
|
||||
ChannelMode *cm = NULL;
|
||||
|
||||
+1
-1
@@ -762,7 +762,7 @@ bool ChannelInfo::CheckKick(User *user)
|
||||
}
|
||||
else
|
||||
{
|
||||
Entry akick_mask(autokick->mask);
|
||||
Entry akick_mask(CMODE_BEGIN, autokick->mask);
|
||||
if (akick_mask.Matches(user))
|
||||
do_kick = true;
|
||||
}
|
||||
|
||||
+1
-1
@@ -870,7 +870,7 @@ bool matches_list(Channel *c, User *user, ChannelModeName mode)
|
||||
std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> modes = c->GetModeList(mode);
|
||||
for (; modes.first != modes.second; ++modes.first)
|
||||
{
|
||||
Entry e(modes.first->second);
|
||||
Entry e(mode, modes.first->second);
|
||||
if (e.Matches(user))
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user