summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2012-05-23 19:35:56 -0400
committerAdam <Adam@anope.org>2012-05-23 19:35:56 -0400
commit70fb5900a2cc8eb00d1d25b39bd137488e845338 (patch)
tree134683df2a07d7bbabb8d78c3284096f687eadc7
parentbf7d1a55afd4e082813e995fd967ad1dae8df26d (diff)
Add support for inspircd2.0+s mlock, improved on Unreal's, and made server side mlock usage configurable
-rw-r--r--data/chanserv.example.conf6
-rw-r--r--include/config.h2
-rw-r--r--modules/protocol/inspircd20.cpp47
-rw-r--r--modules/protocol/unreal.cpp23
-rw-r--r--src/config.cpp1
5 files changed, 74 insertions, 5 deletions
diff --git a/data/chanserv.example.conf b/data/chanserv.example.conf
index 4eaa51f6e..2b82b05d8 100644
--- a/data/chanserv.example.conf
+++ b/data/chanserv.example.conf
@@ -192,6 +192,12 @@ chanserv
* These modes can not be locked or unlocked.
*/
require = "r"
+
+ /*
+ * Some IRCds can enforce mode locks server-side. This reduces the spam caused by
+ * services immediately reversing mode changes for locked modes.
+ */
+ use_server_side_mlock = yes
}
/*
diff --git a/include/config.h b/include/config.h
index 9c6e9a143..0ab3c287b 100644
--- a/include/config.h
+++ b/include/config.h
@@ -451,6 +451,8 @@ class CoreExport ServerConfig
Anope::string NoMLock;
/* Modes that are required to be on registered channels */
Anope::string CSRequire;
+ /* Use server side mlock */
+ bool UseServerSideMLock;
/* Default botmodes on channels, defaults to ao */
Anope::string BotModes;
/* THe actual modes */
diff --git a/modules/protocol/inspircd20.cpp b/modules/protocol/inspircd20.cpp
index 8f1bc38e6..1cf00f5a1 100644
--- a/modules/protocol/inspircd20.cpp
+++ b/modules/protocol/inspircd20.cpp
@@ -730,7 +730,7 @@ class ProtoInspIRCd : public Module
Capab.insert("NOQUIT");
- Implementation i[] = { I_OnUserNickChange, I_OnServerSync };
+ Implementation i[] = { I_OnUserNickChange, I_OnServerSync, I_OnChannelCreate, I_OnChanRegistered, I_OnDelChan, I_OnMLock, I_OnUnMLock };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
if (Config->Numeric.empty())
@@ -766,6 +766,51 @@ class ProtoInspIRCd : public Module
nickserv->Validate(u);
}
}
+
+ void OnChannelCreate(Channel *c) anope_override
+ {
+ if (c->ci && Config->UseServerSideMLock)
+ this->OnChanRegistered(c->ci);
+ }
+
+ void OnChanRegistered(ChannelInfo *ci) anope_override
+ {
+ if (!Config->UseServerSideMLock)
+ return;
+ Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "");
+ UplinkSocket::Message(Me) << "METADATA " << ci->name << " mlock :" << modes;
+ }
+
+ void OnDelChan(ChannelInfo *ci) anope_override
+ {
+ if (!Config->UseServerSideMLock)
+ return;
+ UplinkSocket::Message(Me) << "METADATA " << ci->name << " mlock :";
+ }
+
+ EventReturn OnMLock(ChannelInfo *ci, ModeLock *lock) anope_override
+ {
+ ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
+ if (cm && ci->c && (cm->Type == MODE_REGULAR || cm->Type == MODE_PARAM) && Config->UseServerSideMLock)
+ {
+ Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "") + cm->ModeChar;
+ UplinkSocket::Message(Me) << "METADATA " << ci->name << " mlock :" << modes;
+ }
+
+ return EVENT_CONTINUE;
+ }
+
+ EventReturn OnUnMLock(ChannelInfo *ci, ModeLock *lock) anope_override
+ {
+ ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
+ if (cm && ci->c && (cm->Type == MODE_REGULAR || cm->Type == MODE_PARAM) && Config->UseServerSideMLock)
+ {
+ Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "").replace_all_cs(cm->ModeChar, "");
+ UplinkSocket::Message(Me) << "METADATA " << ci->name << " mlock :" << modes;
+ }
+
+ return EVENT_CONTINUE;
+ }
};
MODULE_INIT(ProtoInspIRCd)
diff --git a/modules/protocol/unreal.cpp b/modules/protocol/unreal.cpp
index 0fdb0d1e0..9b6bf73ce 100644
--- a/modules/protocol/unreal.cpp
+++ b/modules/protocol/unreal.cpp
@@ -1212,7 +1212,7 @@ class ProtoUnreal : public Module
this->AddModes();
- Implementation i[] = { I_OnUserNickChange, I_OnChannelCreate, I_OnMLock, I_OnUnMLock };
+ Implementation i[] = { I_OnUserNickChange, I_OnChannelCreate, I_OnChanRegistered, I_OnDelChan, I_OnMLock, I_OnUnMLock };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
ModuleManager::SetPriority(this, PRIORITY_FIRST);
}
@@ -1232,17 +1232,32 @@ class ProtoUnreal : public Module
void OnChannelCreate(Channel *c) anope_override
{
- if (Capab.count("MLOCK") > 0 && c->ci)
+ if (Config->UseServerSideMLock && Capab.count("MLOCK") > 0 && c->ci)
{
Anope::string modes = c->ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "");
UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(c->creation_time) << " " << c->ci->name << " " << modes;
}
}
+ void OnChanRegistered(ChannelInfo *ci) anope_override
+ {
+ if (!ci->c || !Config->UseServerSideMLock)
+ return;
+ Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "");
+ UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes;
+ }
+
+ void OnDelChan(ChannelInfo *ci) anope_override
+ {
+ if (!ci->c || !Config->UseServerSideMLock)
+ return;
+ UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " :";
+ }
+
EventReturn OnMLock(ChannelInfo *ci, ModeLock *lock) anope_override
{
ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
- if (cm && ci->c && (cm->Type == MODE_REGULAR || cm->Type == MODE_PARAM) && Capab.count("MLOCK") > 0)
+ if (cm && ci->c && (cm->Type == MODE_REGULAR || cm->Type == MODE_PARAM) && Capab.count("MLOCK") > 0 && Config->UseServerSideMLock)
{
Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "") + cm->ModeChar;
UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes;
@@ -1254,7 +1269,7 @@ class ProtoUnreal : public Module
EventReturn OnUnMLock(ChannelInfo *ci, ModeLock *lock) anope_override
{
ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
- if (cm && ci->c && (cm->Type == MODE_REGULAR || cm->Type == MODE_PARAM) && Capab.count("MLOCK") > 0)
+ if (cm && ci->c && (cm->Type == MODE_REGULAR || cm->Type == MODE_PARAM) && Capab.count("MLOCK") > 0 && Config->UseServerSideMLock)
{
Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "").replace_all_cs(cm->ModeChar, "");
UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes;
diff --git a/src/config.cpp b/src/config.cpp
index f192eb3cf..8e45097a7 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -1253,6 +1253,7 @@ ConfigItems::ConfigItems(ServerConfig *conf)
{"chanserv", "mlock", "+nrt", new ValueContainerString(&conf->MLock), DT_STRING | DT_ALLOW_EMPTY, NoValidation},
{"chanserv", "nomlock", "", new ValueContainerString(&conf->NoMLock), DT_STRING, NoValidation},
{"chanserv", "require", "", new ValueContainerString(&conf->CSRequire), DT_STRING, NoValidation},
+ {"chanserv", "use_server_side_mlock", "yes", new ValueContainerBool(&conf->UseServerSideMLock), DT_BOOLEAN, NoValidation},
{"memoserv", "name", "", new ValueContainerString(&conf->MemoServ), DT_STRING, NoValidation},
{"memoserv", "maxmemos", "0", new ValueContainerUInt(&conf->MSMaxMemos), DT_UINTEGER, NoValidation},
{"memoserv", "senddelay", "0", new ValueContainerTime(&conf->MSSendDelay), DT_TIME, NoValidation},