1
0
mirror of https://github.com/anope/anope.git synced 2026-06-18 11:24:46 +02:00

Compare commits

..

32 Commits

Author SHA1 Message Date
Sadie Powell 3acf74483c Release 2.0.16. 2024-07-19 12:49:56 +01:00
Sadie Powell a3ec8329f4 Document the previous commit. 2024-07-19 12:48:44 +01:00
Sadie Powell 31bc597c81 Send the vhost/vident before the account name on InspIRCd.
This fixes IRCd-side account cloaks causing CHGHOST spam.
2024-07-19 01:11:32 +01:00
Sadie Powell 2de0dddb1c Fix joining channels with keys on InspIRCd v3. 2024-07-14 16:39:37 +01:00
Sadie Powell 41ea346551 Update the change log. 2024-07-11 01:13:59 +01:00
Sadie Powell 439ad3e736 Make it clear that inspircd3 also works with InspIRCd 4. 2024-07-11 01:13:59 +01:00
Sadie Powell 8105607257 Fix the default config for channel suspensions. 2024-06-23 13:51:53 +01:00
Sadie Powell ccc088d946 Log a user out fully when their nick gets suspended.
Closes #409.
2024-06-04 22:41:32 +01:00
Sadie Powell 8bb83f6b1a Explicitly specify ROW_FORMAT=DYNAMIC when creating tables.
Resolves the issues some people were having with extremely wide rows.
2024-05-16 17:29:25 +01:00
Sadie Powell da99a53dfa Don't specify a width for DT_INT columns.
This isn't actually used by MySQL for the column width.
2024-05-16 17:28:15 +01:00
Sadie Powell a9e9ac32a0 Store boolean extension items as DT_INT. 2024-05-16 17:28:15 +01:00
Sadie Powell 05e6df23a2 Mark boolean columns as DT_INT in bs_kick. 2024-05-16 16:50:41 +01:00
Sadie Powell 3f9fc23270 Remove some unnecessary advice. 2024-05-16 16:44:38 +01:00
Sadie Powell afe87bf693 Ensure we are connected to MySQL before trying to escape data. 2024-05-11 11:36:29 +01:00
Sadie Powell 0c5bf51378 Skip serializing data without a type in db_flatfile. 2024-04-29 08:16:45 +01:00
Sadie Powell d41764bfd6 Fix sending emails to nicks ending with a backslash. 2024-03-15 18:52:12 +00:00
Sadie Powell 10f4724b6b Dependabot requires that the target-branch is a string. 2024-03-15 12:17:15 +00:00
Sadie Powell 8d5be77c93 Send dependabot pull requests to the 2.1 branch. 2024-03-15 11:56:56 +00:00
Sadie Powell f4bd43e898 Add a workaround for users matching expired sqlines.
I'll fix this properly in 2.1 because I don't want to make big
changes to 2.0.

Closes #384.
2024-03-12 16:47:57 +00:00
Sadie Powell 7d7664444a Fix expiring forbids. 2024-03-12 16:26:33 +00:00
Sadie Powell 1a8bbd6004 Respect --noexpire in cs_suspend and ns_suspend. 2024-03-12 14:43:12 +00:00
Sadie Powell e725c880a9 Fix expiring channel suspensions.
Closes #386.
2024-03-12 14:12:37 +00:00
Sadie Powell f5abcd1c4c Fix expiring nick suspensions.
Closes #376.
2024-03-12 14:02:16 +00:00
Sadie Powell 1986aa6581 Fix duplicate messages when synconset/syncongroup is set.
Closes #366.
2024-03-12 13:26:25 +00:00
Sadie Powell 1a6060ac5b Fix sending SVSTOPIC when topiclock is loaded on InspIRCd. 2024-03-12 11:46:41 +00:00
Sadie Powell 6f57907416 Fix the TIME message on InspIRCd. 2024-03-11 22:38:15 +00:00
Bram Matthys b09632d1c3 Fix OS SQLINE expiry with UnrealIRCd 2024-03-11 18:30:55 +00:00
Sadie Powell cd614831de Fix feature detection on InspIRCd. 2024-03-08 16:49:55 +00:00
Sadie Powell 9649dc78a1 When using ldap/sql auth prevent displays expiring before their group.
This prevents zombie accounts from being left around that can't be
authenticated to.

Closes #355.
2024-03-04 12:08:28 +00:00
Sadie Powell ee7455daa8 Fix a copy/paste error in webcpanel. 2024-02-29 16:27:24 +00:00
Sadie Powell 5f735b2570 Fix matching extbans on InspIRCd and implement missing matchers. 2024-02-27 20:33:43 +00:00
Sadie Powell 4ea2bc5e46 Mark as 2.0.16-git. 2024-02-17 20:08:10 +00:00
24 changed files with 222 additions and 91 deletions
+1
View File
@@ -4,3 +4,4 @@ updates:
directory: /
schedule:
interval: monthly
target-branch: "2.1"
+2 -3
View File
@@ -109,10 +109,9 @@ module
/*
* The length of time before a channel registration expires.
*
* This directive is optional, but recommended.
* If not set, the default is 14 days.
* This directive is optional. If not set, the default is never.
*/
expire = 14d
#expire = 90d
/*
* The maximum number of entries on a channel's access list.
+1 -6
View File
@@ -259,7 +259,7 @@ serverinfo
* - hybrid
* - inspircd12
* - inspircd20
* - inspircd3
* - inspircd3 (for 3.x and 4.x)
* - ngircd
* - plexus
* - ratbox
@@ -1153,11 +1153,6 @@ module
* This is only useful with very large databases, with hundreds
* of thousands of objects, that have a noticeable delay from
* writing databases.
*
* If your database is large enough cause a noticeable delay when
* saving you should consider a more powerful alternative such
* as db_sql or db_redis, which incrementally update their
* databases asynchronously in real time.
*/
fork = no
}
+1 -1
View File
@@ -256,7 +256,7 @@ serverinfo
* - hybrid
* - inspircd12
* - inspircd20
* - inspircd3
* - inspircd3 (for 3.x and 4.x)
* - ngircd
* - plexus
* - ratbox
+25
View File
@@ -1,3 +1,28 @@
Anope Version 2.0.16
--------------------
Added a workaround for users matching expired sqlines.
Fixed a copy/paste error in webcpanel.
Fixed a crash in db_flatfile caused by trying to serialize data without a type.
Fixed duplicate messages when synconset/syncongroup is set.
Fixed expiring channel suspensions.
Fixed expiring forbids.
Fixed expiring nick suspensions.
Fixed feature detection on InspIRCd.
Fixed InspIRCd account cloaks causing CHGHOST spam when a user also has a services vhost.
Fixed joining users to channels with a key set on InspIRCd.
Fixed logging users out fully when their nick gets suspended.
Fixed marking boolean columns in SQL as TEXT instead of INT.
Fixed matching extbans on InspIRCd and implement missing matchers.
Fixed operserv/sqline expiry on UnrealIRCd
Fixed respecting --noexpire in cs_suspend and ns_suspend.
Fixed sending emails to nicks ending with a backslash.
Fixed sending SVSTOPIC when topiclock is loaded on InspIRCd.
Fixed some SQL tables taking up too much space on disk.
Fixed the default config for channel suspensions.
Fixed the TIME message on InspIRCd.
Fixed trying to escape SQL data when not connected to MySQL.
Fixed {ldap,sql}_authentication creating zombie accounts on expiry.
Anope Version 2.0.15
--------------------
Fixed a race condition in changing the nick of a user.
+4
View File
@@ -1,3 +1,7 @@
Anope Version 2.0.16
--------------------
No significant changes.
Anope Version 2.0.15
--------------------
No significant changes.
+1
View File
@@ -190,6 +190,7 @@ class SerializableExtensibleItem<bool> : public PrimitiveExtensibleItem<bool>
void ExtensibleSerialize(const Extensible *e, const Serializable *s, Serialize::Data &data) const anope_override
{
data.SetType(this->name, Serialize::Data::DT_INT);
data[this->name] << true;
}
+10 -11
View File
@@ -51,17 +51,16 @@ struct KickerDataImpl : KickerData
if (kd == NULL)
return;
data["kickerdata:amsgs"] << kd->amsgs;
data["kickerdata:badwords"] << kd->badwords;
data["kickerdata:bolds"] << kd->bolds;
data["kickerdata:caps"] << kd->caps;
data["kickerdata:colors"] << kd->colors;
data["kickerdata:flood"] << kd->flood;
data["kickerdata:italics"] << kd->italics;
data["kickerdata:repeat"] << kd->repeat;
data["kickerdata:reverses"] << kd->reverses;
data["kickerdata:underlines"] << kd->underlines;
data.SetType("kickerdata:amsgs", Serialize::Data::DT_INT); data["kickerdata:amsgs"] << kd->amsgs;
data.SetType("kickerdata:badwords", Serialize::Data::DT_INT); data["kickerdata:badwords"] << kd->badwords;
data.SetType("kickerdata:bolds", Serialize::Data::DT_INT); data["kickerdata:bolds"] << kd->bolds;
data.SetType("kickerdata:caps", Serialize::Data::DT_INT); data["kickerdata:caps"] << kd->caps;
data.SetType("kickerdata:colors", Serialize::Data::DT_INT); data["kickerdata:colors"] << kd->colors;
data.SetType("kickerdata:flood", Serialize::Data::DT_INT); data["kickerdata:flood"] << kd->flood;
data.SetType("kickerdata:italics", Serialize::Data::DT_INT); data["kickerdata:italics"] << kd->italics;
data.SetType("kickerdata:repeat", Serialize::Data::DT_INT); data["kickerdata:repeat"] << kd->repeat;
data.SetType("kickerdata:reverses", Serialize::Data::DT_INT); data["kickerdata:reverses"] << kd->reverses;
data.SetType("kickerdata:underlines", Serialize::Data::DT_INT); data["kickerdata:underlines"] << kd->underlines;
data.SetType("capsmin", Serialize::Data::DT_INT); data["capsmin"] << kd->capsmin;
data.SetType("capspercent", Serialize::Data::DT_INT); data["capspercent"] << kd->capspercent;
data.SetType("floodlines", Serialize::Data::DT_INT); data["floodlines"] << kd->floodlines;
+20 -8
View File
@@ -210,6 +210,13 @@ class CSSuspend : public Module
}
};
void Expire(ChannelInfo *ci)
{
suspend.Unset(ci);
Log(this) << "Expiring suspend for " << ci->name;
}
bool Show(CommandSource &source, const Anope::string &what) const
{
return source.IsOper() || std::find(show.begin(), show.end(), what) != show.end();
@@ -255,23 +262,28 @@ class CSSuspend : public Module
expire = false;
if (!si->expires)
return;
if (si->expires < Anope::CurTime)
if (!Anope::NoExpire && si->expires && si->expires < Anope::CurTime)
{
ci->last_used = Anope::CurTime;
suspend.Unset(ci);
Log(this) << "Expiring suspend for " << ci->name;
Expire(ci);
}
}
EventReturn OnCheckKick(User *u, Channel *c, Anope::string &mask, Anope::string &reason) anope_override
{
if (u->HasMode("OPER") || !c->ci || !suspend.HasExt(c->ci))
if (u->HasMode("OPER") || !c->ci)
return EVENT_CONTINUE;
CSSuspendInfo *si = suspend.Get(c->ci);
if (!si)
return EVENT_CONTINUE;
if (!Anope::NoExpire && si->expires && si->expires < Anope::CurTime)
{
Expire(c->ci);
return EVENT_CONTINUE;
}
reason = Language::Translate(u, _("This channel may not be used."));
return EVENT_STOP;
}
+1 -1
View File
@@ -28,7 +28,7 @@ class CommandHSGroup : public Command
for (unsigned i = 0; i < na->nc->aliases->size(); ++i)
{
NickAlias *nick = na->nc->aliases->at(i);
if (nick)
if (nick && nick != na)
{
nick->SetVhost(na->GetVhostIdent(), na->GetVhostHost(), na->GetVhostCreator());
FOREACH_MOD(OnSetVhost, (nick));
+1 -1
View File
@@ -114,7 +114,7 @@ class CommandHSSetAll : public Command
for (unsigned i = 0; i < na->nc->aliases->size(); ++i)
{
NickAlias *nick = na->nc->aliases->at(i);
if (nick)
if (nick && nick != na)
nick->SetVhost(na->GetVhostIdent(), na->GetVhostHost(), na->GetVhostCreator());
}
}
+16 -7
View File
@@ -127,6 +127,8 @@ class CommandNSSuspend : public Command
User *u2 = User::Find(na2->nick, true);
if (u2)
{
IRCD->SendLogout(u2);
u2->RemoveMode(source.service, "REGISTERED");
u2->Logout();
if (nickserv)
nickserv->Collide(u2, na2);
@@ -222,6 +224,12 @@ class NSSuspend : public Module
return source.IsOper() || std::find(show.begin(), show.end(), what) != show.end();
}
void Expire(NickAlias *na)
{
suspend.Unset(na->nc);
Log(LOG_NORMAL, "nickserv/expire", Config->GetClient("NickServ")) << "Expiring suspend for " << na->nick;
}
public:
NSSuspend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
commandnssuspend(this), commandnsunsuspend(this), suspend(this, "NS_SUSPENDED"),
@@ -262,15 +270,10 @@ class NSSuspend : public Module
expire = false;
if (!s->expires)
return;
if (s->expires < Anope::CurTime)
if (!Anope::NoExpire && s->expires && s->expires < Anope::CurTime)
{
na->last_seen = Anope::CurTime;
suspend.Unset(na->nc);
Log(LOG_NORMAL, "nickserv/expire", Config->GetClient("NickServ")) << "Expiring suspend for " << na->nick;
Expire(na);
}
}
@@ -280,6 +283,12 @@ class NSSuspend : public Module
if (!s)
return EVENT_CONTINUE;
if (!Anope::NoExpire && s->expires && s->expires < Anope::CurTime)
{
Expire(na);
return EVENT_CONTINUE;
}
u->SendMessage(Config->GetClient("NickServ"), NICK_X_SUSPENDED, u->nick.c_str());
return EVENT_STOP;
}
+40 -13
View File
@@ -65,6 +65,33 @@ class MyForbidService : public ForbidService
inline std::vector<ForbidData *>& forbids(unsigned t) { return (*this->forbid_data)[t - 1]; }
void Expire(ForbidData *fd, unsigned ft, size_t idx)
{
Anope::string typestr;
switch (ft)
{
case FT_NICK:
typestr = "nick";
break;
case FT_CHAN:
typestr = "chan";
break;
case FT_EMAIL:
typestr = "email";
break;
case FT_REGISTER:
typestr = "register";
break;
default:
typestr = "unknown";
break;
}
Log(LOG_NORMAL, "expire/forbid", Config->GetClient("OperServ")) << "Expiring forbid for " << fd->mask << " type " << typestr;
this->forbids(ft).erase(this->forbids(ft).begin() + idx);
delete fd;
}
public:
MyForbidService(Module *m) : ForbidService(m), forbid_data("ForbidData") { }
@@ -99,6 +126,12 @@ class MyForbidService : public ForbidService
{
ForbidData *d = this->forbids(ftype)[i - 1];
if (!Anope::NoExpire && d->expires && Anope::CurTime >= d->expires)
{
Expire(d, ftype, i - 1);
continue;
}
if (Anope::Match(mask, d->mask, false, true))
return d;
}
@@ -111,6 +144,12 @@ class MyForbidService : public ForbidService
{
ForbidData *d = this->forbids(ftype)[i - 1];
if (!Anope::NoExpire && d->expires && Anope::CurTime >= d->expires)
{
Expire(d, ftype, i - 1);
continue;
}
if (d->mask.equals_ci(mask))
return d;
}
@@ -126,19 +165,7 @@ class MyForbidService : public ForbidService
ForbidData *d = this->forbids(j).at(i - 1);
if (d->expires && !Anope::NoExpire && Anope::CurTime >= d->expires)
{
Anope::string ftype = "none";
if (d->type == FT_NICK)
ftype = "nick";
else if (d->type == FT_CHAN)
ftype = "chan";
else if (d->type == FT_EMAIL)
ftype = "email";
Log(LOG_NORMAL, "expire/forbid", Config->GetClient("OperServ")) << "Expiring forbid for " << d->mask << " type " << ftype;
this->forbids(j).erase(this->forbids(j).begin() + i - 1);
delete d;
}
Expire(d, j, i - 1);
else
f.push_back(d);
}
+2
View File
@@ -324,6 +324,8 @@ class DBFlatFile : public Module, public Pipe
{
Serializable *base = *it;
Serialize::Type *s_type = base->GetSerializableType();
if (!s_type)
continue;
data.fs = databases[s_type->GetOwner()];
if (!data.fs || !data.fs->is_open())
+9
View File
@@ -299,6 +299,15 @@ class ModuleLDAPAuthentication : public Module
Anope::string new_dn = username_attribute + "=" + na->nick + "," + basedn;
this->ldap->Add(&this->orinterface, new_dn, attributes);
}
void OnPreNickExpire(NickAlias *na, bool &expire) anope_override
{
// We can't let nicks expire if they still have a group or
// there will be a zombie account left over that can't be
// authenticated to.
if (na->nick == na->nc->display && na->nc->aliases->size() > 1)
expire = false;
}
};
MODULE_INIT(ModuleLDAPAuthentication)
+10 -5
View File
@@ -339,9 +339,14 @@ Result MySQLService::RunQuery(const Query &query)
{
this->Lock.Lock();
Anope::string real_query = this->BuildQuery(query);
if (!this->CheckConnection())
{
this->Lock.Unlock();
return MySQLResult(query, query.query, mysql_error(this->sql));
}
if (this->CheckConnection() && !mysql_real_query(this->sql, real_query.c_str(), real_query.length()))
Anope::string real_query = this->BuildQuery(query);
if (!mysql_real_query(this->sql, real_query.c_str(), real_query.length()))
{
MYSQL_RES *res = mysql_store_result(this->sql);
unsigned int id = mysql_insert_id(this->sql);
@@ -395,11 +400,11 @@ std::vector<Query> MySQLService::CreateTable(const Anope::string &table, const D
query_text += ", `" + it->first + "` ";
if (data.GetType(it->first) == Serialize::Data::DT_INT)
query_text += "int(11)";
query_text += "int";
else
query_text += "text";
}
query_text += ", PRIMARY KEY (`id`), KEY `timestamp_idx` (`timestamp`))";
query_text += ", PRIMARY KEY (`id`), KEY `timestamp_idx` (`timestamp`)) ROW_FORMAT=DYNAMIC";
queries.push_back(query_text);
}
else
@@ -412,7 +417,7 @@ std::vector<Query> MySQLService::CreateTable(const Anope::string &table, const D
Anope::string query_text = "ALTER TABLE `" + table + "` ADD `" + it->first + "` ";
if (data.GetType(it->first) == Serialize::Data::DT_INT)
query_text += "int(11)";
query_text += "int";
else
query_text += "text";
+9
View File
@@ -143,6 +143,15 @@ class ModuleSQLAuthentication : public Module
Log(LOG_DEBUG) << "m_sql_authentication: Checking authentication for " << req->GetAccount();
}
void OnPreNickExpire(NickAlias *na, bool &expire) anope_override
{
// We can't let nicks expire if they still have a group or
// there will be a zombie account left over that can't be
// authenticated to.
if (na->nick == na->nc->display && na->nc->aliases->size() > 1)
expire = false;
}
};
MODULE_INIT(ModuleSQLAuthentication)
+2 -2
View File
@@ -139,7 +139,7 @@ namespace InspIRCdExtban
bool Matches(User *u, const Entry *e) anope_override
{
const Anope::string &mask = e->GetMask();
Anope::string real_mask = mask.substr(3);
Anope::string real_mask = mask.substr(2);
return Entry(this->name, real_mask).Matches(u);
}
@@ -156,7 +156,7 @@ namespace InspIRCdExtban
{
const Anope::string &mask = e->GetMask();
Anope::string channel = mask.substr(3);
Anope::string channel = mask.substr(2);
ChannelMode *cm = NULL;
if (channel[0] != '#')
+60 -29
View File
@@ -66,9 +66,7 @@ class InspIRCd3Proto : public IRCDProto
CanSetVHost = true;
CanSetVIdent = true;
CanSQLine = true;
CanSQLineChannel = true;
CanSZLine = true;
CanSVSHold = true;
CanCertFP = true;
RequiresID = true;
MaxModes = 20;
@@ -182,7 +180,7 @@ class InspIRCd3Proto : public IRCDProto
void SendTopic(const MessageSource &source, Channel *c) anope_override
{
if (Servers::Capab.count("SVSTOPIC"))
if (Servers::Capab.count("TOPICLOCK"))
{
UplinkSocket::Message(c->WhoSends()) << "SVSTOPIC " << c->name << " " << c->topic_ts << " " << c->topic_setter << " :" << c->topic;
}
@@ -396,9 +394,12 @@ class InspIRCd3Proto : public IRCDProto
SendAddLine("Z", x->GetHost(), timeleft, x->by, x->GetReason());
}
void SendSVSJoin(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &other) anope_override
void SendSVSJoin(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &key) anope_override
{
UplinkSocket::Message(source) << "SVSJOIN " << u->GetUID() << " " << chan;
if (key.empty())
UplinkSocket::Message(source) << "SVSJOIN " << u->GetUID() << " " << chan;
else
UplinkSocket::Message(source) << "SVSJOIN " << u->GetUID() << " " << chan << " :" << key;
}
void SendSVSPart(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &param) anope_override
@@ -444,6 +445,7 @@ class InspIRCd3Proto : public IRCDProto
if (na->nc->HasExt("UNCONFIRMED"))
return;
IRCD->SendVhost(u, na->GetVhostIdent(), na->GetVhostHost());
UplinkSocket::Message(Me) << "METADATA " << u->GetUID() << " accountid :" << na->nc->GetId();
UplinkSocket::Message(Me) << "METADATA " << u->GetUID() << " accountname :" << na->nc->display;
}
@@ -539,6 +541,12 @@ class InspIRCdAutoOpMode : public ChannelModeList
}
};
// NOTE: matchers for the following extbans have not been implemented:
//
// * class(n): data not available
// * country(G): data not available
// * gateway(w): data not available in v3
// * realmask(a): todo
class InspIRCdExtBan : public ChannelModeVirtual<ChannelModeList>
{
char ext;
@@ -577,7 +585,7 @@ namespace InspIRCdExtban
bool Matches(User *u, const Entry *e) anope_override
{
const Anope::string &mask = e->GetMask();
Anope::string real_mask = mask.substr(3);
Anope::string real_mask = mask.substr(2);
return Entry(this->name, real_mask).Matches(u);
}
@@ -594,7 +602,7 @@ namespace InspIRCdExtban
{
const Anope::string &mask = e->GetMask();
Anope::string channel = mask.substr(3);
Anope::string channel = mask.substr(2);
ChannelMode *cm = NULL;
if (channel[0] != '#')
@@ -694,6 +702,25 @@ namespace InspIRCdExtban
return !u->Account() && Entry("BAN", real_mask).Matches(u);
}
};
class OperTypeMatcher : public InspIRCdExtBan
{
public:
OperTypeMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : InspIRCdExtBan(mname, mbase, c)
{
}
bool Matches(User *u, const Entry *e) anope_override
{
Anope::string *opertype = u->GetExt<Anope::string>("opertype");
if (!opertype)
return false; // Not an operator.
const Anope::string &mask = e->GetMask();
Anope::string real_mask = mask.substr(2);
return Anope::Match(opertype->replace_all_cs(' ', '_'), real_mask);
}
};
}
class ColonDelimitedParamMode : public ChannelModeParam
@@ -906,8 +933,7 @@ struct IRCDMessageCapab : Message::Capab
}
/* reset CAPAB */
Servers::Capab.insert("SERVERS");
Servers::Capab.insert("TOPICLOCK");
Servers::Capab.clear();
IRCD->CanSQLineChannel = false;
IRCD->CanSVSHold = false;
IRCD->DefaultPseudoclientModes = "+oI";
@@ -1012,7 +1038,10 @@ struct IRCDMessageCapab : Message::Capab
else if (mode.name.equals_cs("op"))
cm = new ChannelModeStatus("OP", mode.letter, mode.symbol, mode.level);
else if (mode.name.equals_cs("operonly"))
{
cm = new ChannelModeOperOnly("OPERONLY", mode.letter);
ModeManager::AddChannelMode(new InspIRCdExtban::OperTypeMatcher("OPERTYPEBAN", "BAN", 'O'));
}
else if (mode.name.equals_cs("operprefix"))
cm = new ChannelModeStatus("OPERPREFIX", mode.letter, mode.symbol, mode.level);
else if (mode.name.equals_cs("permanent"))
@@ -1210,11 +1239,15 @@ struct IRCDMessageCapab : Message::Capab
return;
}
if (!IRCD->CanSVSHold)
Log() << "SVSHOLD missing, Usage disabled until module is loaded.";
Log() << "The remote server does not have the svshold module; fake users will be used for nick protection until the module is loaded.";
if (!IRCD->CanSQLineChannel)
Log() << "The remote server does not have the cban module; services will manually enforce forbidden channels until the module is loaded.";
if (!Servers::Capab.count("CHGHOST"))
Log() << "CHGHOST missing, Usage disabled until module is loaded.";
Log() << "The remote server does not have the chghost module; vhosts are disabled until the module is loaded.";
if (!Servers::Capab.count("CHGIDENT"))
Log() << "CHGIDENT missing, Usage disabled until module is loaded.";
Log() << "The remote server does not have the chgident module; vidents are disabled until the module is loaded.";
if (!Servers::Capab.count("GLOBOPS"))
Log() << "The remote server does not have the globops module; oper notices will be sent as announcements until the module is loaded.";
}
Message::Capab::Run(source, params);
@@ -1456,12 +1489,16 @@ class IRCDMessageMetadata : IRCDMessage
required = true;
else if (module.equals_cs("m_hidechans.so"))
required = true;
else if (module.equals_cs("m_cban.so=glob") && plus)
IRCD->CanSQLineChannel = true;
if (module.equals_cs("m_cban.so") && !plus)
IRCD->CanSQLineChannel = false;
else if (module.equals_cs("m_chghost.so"))
capab = "CHGHOST";
else if (module.equals_cs("m_chgident.so"))
capab = "CHGIDENT";
else if (module.equals_cs("m_svshold.so"))
capab = "SVSHOLD";
IRCD->CanSVSHold = plus;
else if (module.equals_cs("m_rline.so"))
capab = "RLINE";
else if (module.equals_cs("m_topiclock.so"))
@@ -1476,9 +1513,9 @@ class IRCDMessageMetadata : IRCDMessage
}
else
{
if (plus)
if (plus && !capab.empty())
Servers::Capab.insert(capab);
else
else if (!capab.empty())
Servers::Capab.erase(capab);
Log() << "InspIRCd " << (plus ? "loaded" : "unloaded") << " module " << module << ", adjusted functionality";
@@ -1702,7 +1739,9 @@ struct IRCDMessageNick : IRCDMessage
struct IRCDMessageOperType : IRCDMessage
{
IRCDMessageOperType(Module *creator) : IRCDMessage(creator, "OPERTYPE", 0) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); SetFlag(IRCDMESSAGE_REQUIRE_USER); }
PrimitiveExtensibleItem<Anope::string> opertype;
IRCDMessageOperType(Module *creator) : IRCDMessage(creator, "OPERTYPE", 1), opertype(creator, "opertype") { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
{
@@ -1711,6 +1750,8 @@ struct IRCDMessageOperType : IRCDMessage
User *u = source.GetUser();
if (!u->HasMode("OPER"))
u->SetModesInternal(source, "+o");
opertype.Set(u, params[0]);
}
};
@@ -1796,16 +1837,6 @@ struct IRCDMessageSQuit : Message::SQuit
}
};
struct IRCDMessageTime : IRCDMessage
{
IRCDMessageTime(Module *creator) : IRCDMessage(creator, "TIME", 2) { }
void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
{
UplinkSocket::Message(Me) << "TIME " << source.GetSource() << " " << params[1] << " " << Anope::CurTime;
}
};
struct IRCDMessageUID : IRCDMessage
{
IRCDMessageUID(Module *creator) : IRCDMessage(creator, "UID", 8) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
@@ -1869,6 +1900,7 @@ class ProtoInspIRCd3 : public Module
Message::Privmsg message_privmsg;
Message::Quit message_quit;
Message::Stats message_stats;
Message::Time message_time;
/* Our message handlers */
IRCDMessageAway message_away;
@@ -1892,7 +1924,6 @@ class ProtoInspIRCd3 : public Module
IRCDMessageSave message_save;
IRCDMessageServer message_server;
IRCDMessageSQuit message_squit;
IRCDMessageTime message_time;
IRCDMessageUID message_uid;
bool use_server_side_topiclock, use_server_side_mlock;
@@ -1906,12 +1937,12 @@ class ProtoInspIRCd3 : public Module
ProtoInspIRCd3(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR),
ircd_proto(this), ssl(this, "ssl"),
message_error(this), message_invite(this), message_kill(this), message_motd(this), message_notice(this),
message_part(this), message_privmsg(this), message_quit(this), message_stats(this),
message_part(this), message_privmsg(this), message_quit(this), message_stats(this), message_time(this),
message_away(this), message_capab(this), message_encap(this), message_endburst(this), message_fhost(this),
message_fident(this), message_fjoin(this), message_fmode(this), message_ftopic(this), message_idle(this),
message_ijoin(this), message_kick(this), message_metadata(this, use_server_side_topiclock, use_server_side_mlock, ircd_proto.maxlist),
message_mode(this), message_nick(this), message_opertype(this), message_ping(this), message_rsquit(this),
message_save(this), message_server(this), message_squit(this), message_time(this), message_uid(this)
message_save(this), message_server(this), message_squit(this), message_uid(this)
{
}
+1 -1
View File
@@ -196,7 +196,7 @@ class UnrealIRCdProto : public IRCDProto
*/
void SendSQLine(User *, const XLine *x) anope_override
{
UplinkSocket::Message() << "SQLINE " << x->mask << " :" << x->GetReason();
UplinkSocket::Message() << "TKL + Q * " << x->mask << " " << x->by << " " << x->expires << " " << x->created << " :" << x->GetReason();
}
/* Functions that use serval cmd functions */
+3
View File
@@ -126,6 +126,9 @@ class SQLineManager : public XLineManager
{
XLine *x = *it;
if (!Anope::NoExpire && x->expires && x->expires < Anope::CurTime)
continue; // Skip expired lines.
if (x->regex)
{
if (x->regex->Matches(c->name))
+1 -1
View File
@@ -50,7 +50,7 @@ bool WebCPanel::ChanServ::Set::OnRequest(HTTPProvider *server, const Anope::stri
ci->Extend<bool>("KEEPTOPIC");
else
ci->Shrink<bool>("KEEPTOPIC");
replacements["MESSAGES"] = "Secure updated";
replacements["MESSAGES"] = "Keeptopic updated";
}
if (ci->HasExt("PEACE") != message.post_data.count("peace"))
{
+1 -1
View File
@@ -48,7 +48,7 @@ void Mail::Message::Run()
if (this->dont_quote_addresses)
fprintf(pipe, "To: %s <%s>\r\n", mail_to.c_str(), addr.c_str());
else
fprintf(pipe, "To: \"%s\" <%s>\r\n", mail_to.c_str(), addr.c_str());
fprintf(pipe, "To: \"%s\" <%s>\r\n", mail_to.replace_all_cs("\\", "\\\\").c_str(), addr.c_str());
fprintf(pipe, "Subject: %s\r\n", subject.c_str());
fprintf(pipe, "Content-Type: %s\r\n", content_type.c_str());
fprintf(pipe, "Content-Transfer-Encoding: 8bit\r\n");
+1 -1
View File
@@ -2,5 +2,5 @@
VERSION_MAJOR=2
VERSION_MINOR=0
VERSION_PATCH=15
VERSION_PATCH=16
VERSION_EXTRA=""