summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2012-02-26 23:23:15 -0500
committerAdam <Adam@anope.org>2012-02-26 23:23:15 -0500
commita5b9e235ae240439608aa743c9ebb3bf6e7d342a (patch)
tree9c3040b865ace191c224a94ef525ab60581c6ba5 /src
parenta78790eac4da788a8432d0b83fa72de7853dd697 (diff)
Added chanserv:require config option to set which modes must be on all registered channels. Prevents the core from always enforcing +r on every channel, even if chanserv is not loaded.
Diffstat (limited to 'src')
-rw-r--r--src/channels.cpp124
-rw-r--r--src/chanserv.cpp83
-rw-r--r--src/config.cpp5
-rw-r--r--src/modes.cpp2
-rw-r--r--src/servers.cpp2
5 files changed, 79 insertions, 137 deletions
diff --git a/src/channels.cpp b/src/channels.cpp
index a04abff52..92bf9b7e3 100644
--- a/src/channels.cpp
+++ b/src/channels.cpp
@@ -91,7 +91,8 @@ void Channel::Reset()
}
}
- check_modes(this);
+ this->CheckModes();
+
for (CUserList::const_iterator it = this->users.begin(), it_end = this->users.end(); it != it_end; ++it)
chan_set_correct_modes((*it)->user, this, 1);
@@ -107,13 +108,81 @@ void Channel::Sync()
}
if (this->ci)
{
- check_modes(this);
+ this->CheckModes();
if (Me && Me->IsSynced())
this->ci->RestoreTopic();
}
}
+void Channel::CheckModes()
+{
+ if (this->bouncy_modes)
+ return;
+
+ /* Check for mode bouncing */
+ if (this->server_modecount >= 3 && this->chanserv_modecount >= 3)
+ {
+ Log() << "Warning: unable to set modes on channel " << this->name << ". Are your servers' U:lines configured correctly?";
+ this->bouncy_modes = 1;
+ return;
+ }
+
+ if (this->chanserv_modetime != Anope::CurTime)
+ {
+ this->chanserv_modecount = 0;
+ this->chanserv_modetime = Anope::CurTime;
+ }
+ this->chanserv_modecount++;
+
+ EventReturn MOD_RESULT;
+ FOREACH_RESULT(I_OnCheckModes, OnCheckModes(this));
+ if (MOD_RESULT == EVENT_STOP)
+ return;
+
+ if (this->ci)
+ for (std::multimap<ChannelModeName, ModeLock>::const_iterator it = this->ci->GetMLock().begin(), it_end = this->ci->GetMLock().end(); it != it_end; ++it)
+ {
+ const ModeLock &ml = it->second;
+ ChannelMode *cm = ModeManager::FindChannelModeByName(ml.name);
+ if (!cm)
+ continue;
+
+ if (cm->Type == MODE_REGULAR)
+ {
+ if (!this->HasMode(cm->Name) && ml.set)
+ this->SetMode(NULL, cm);
+ else if (this->HasMode(cm->Name) && !ml.set)
+ this->RemoveMode(NULL, cm);
+ }
+ else if (cm->Type == MODE_PARAM)
+ {
+ /* If the channel doesnt have the mode, or it does and it isn't set correctly */
+ if (ml.set)
+ {
+ Anope::string param;
+ this->GetParam(cm->Name, param);
+
+ if (!this->HasMode(cm->Name) || (!param.empty() && !ml.param.empty() && !param.equals_cs(ml.param)))
+ this->SetMode(NULL, cm, ml.param);
+ }
+ else
+ {
+ if (this->HasMode(cm->Name))
+ this->RemoveMode(NULL, cm);
+ }
+
+ }
+ else if (cm->Type == MODE_LIST)
+ {
+ if (ml.set)
+ this->SetMode(NULL, cm, ml.param);
+ else
+ this->RemoveMode(NULL, cm, ml.param);
+ }
+ }
+}
+
void Channel::JoinUser(User *user)
{
Log(user, this, "join");
@@ -333,43 +402,7 @@ void Channel::SetModeInternal(ChannelMode *cm, const Anope::string &param, bool
if (!EnforceMLock || MOD_RESULT == EVENT_STOP)
return;
- /* Non registered channels can not be +r */
- if (!ci && HasMode(CMODE_REGISTERED))
- RemoveMode(NULL, CMODE_REGISTERED);
-
- /* Non registered channel has no mlock */
- if (!ci)
- return;
-
- ModeLock *ml = ci->GetMLock(cm->Name, cm->Type == MODE_PARAM ? "" : param);
- if (ml)
- {
- if (ml->set && cm->Type == MODE_PARAM)
- {
- Anope::string cparam;
- this->GetParam(cm->Name, cparam);
-
- /* We have the wrong param set */
- if (cparam.empty() || ml->param.empty() || !cparam.equals_cs(ml->param))
- /* Reset the mode with the correct param */
- this->SetMode(NULL, cm, ml->param);
- }
- else if (!ml->set)
- {
- if (cm->Type == MODE_REGULAR)
- this->RemoveMode(NULL, cm);
- else if (cm->Type == MODE_PARAM)
- {
- Anope::string cparam;
- this->GetParam(cm->Name, cparam);
- this->RemoveMode(NULL, cm, cparam);
- }
- else if (cm->Type == MODE_LIST)
- {
- this->RemoveMode(NULL, cm, param);
- }
- }
- }
+ this->CheckModes();
}
/** Remove a mode internally on a channel, this is not sent out to the IRCd
@@ -459,19 +492,10 @@ void Channel::RemoveModeInternal(ChannelMode *cm, const Anope::string &param, bo
/* Check for mlock */
- /* Non registered channel, no mlock */
- if (!ci || !EnforceMLock || MOD_RESULT == EVENT_STOP)
+ if (!EnforceMLock || MOD_RESULT == EVENT_STOP)
return;
- ModeLock *ml = ci->GetMLock(cm->Name, param);
- /* This channel has this the mode locked on */
- if (ml && ml->set)
- {
- if (cm->Type == MODE_REGULAR)
- this->SetMode(NULL, cm);
- else if (cm->Type == MODE_PARAM || cm->Type == MODE_LIST)
- this->SetMode(NULL, cm, ml->param);
- }
+ this->CheckModes();
}
/** Set a mode on a channel
diff --git a/src/chanserv.cpp b/src/chanserv.cpp
index f18c919cc..fd7fb88f9 100644
--- a/src/chanserv.cpp
+++ b/src/chanserv.cpp
@@ -22,89 +22,6 @@ registered_channel_map RegisteredChannelList;
/*************************************************************************/
-/* Check the current modes on a channel; if they conflict with a mode lock,
- * fix them.
- */
-
-void check_modes(Channel *c)
-{
- if (!c)
- {
- Log() << "check_modes called with NULL values";
- return;
- }
-
- if (c->bouncy_modes)
- return;
-
- /* Check for mode bouncing */
- if (c->server_modecount >= 3 && c->chanserv_modecount >= 3)
- {
- Log() << "Warning: unable to set modes on channel " << c->name << ". Are your servers' U:lines configured correctly?";
- c->bouncy_modes = 1;
- return;
- }
-
- if (c->chanserv_modetime != Anope::CurTime)
- {
- c->chanserv_modecount = 0;
- c->chanserv_modetime = Anope::CurTime;
- }
- c->chanserv_modecount++;
-
- /* Check if the channel is registered; if not remove mode -r */
- ChannelInfo *ci = c->ci;
- if (!ci)
- {
- if (c->HasMode(CMODE_REGISTERED))
- c->RemoveMode(NULL, CMODE_REGISTERED);
- return;
- }
-
- for (std::multimap<ChannelModeName, ModeLock>::const_iterator it = ci->GetMLock().begin(), it_end = ci->GetMLock().end(); it != it_end; ++it)
- {
- const ModeLock &ml = it->second;
- ChannelMode *cm = ModeManager::FindChannelModeByName(ml.name);
- if (!cm)
- continue;
-
- if (cm->Type == MODE_REGULAR)
- {
- if (!c->HasMode(cm->Name) && ml.set)
- c->SetMode(NULL, cm);
- else if (c->HasMode(cm->Name) && !ml.set)
- c->RemoveMode(NULL, cm);
- }
- else if (cm->Type == MODE_PARAM)
- {
- Anope::string param;
- c->GetParam(cm->Name, param);
-
- /* If the channel doesnt have the mode, or it does and it isn't set correctly */
- if (ml.set)
- {
- if (!c->HasMode(cm->Name) || (!param.empty() && !ml.param.empty() && !param.equals_cs(ml.param)))
- c->SetMode(NULL, cm, ml.param);
- }
- else
- {
- if (c->HasMode(cm->Name))
- c->RemoveMode(NULL, cm);
- }
-
- }
- else if (cm->Type == MODE_LIST)
- {
- if (ml.set)
- c->SetMode(NULL, cm, ml.param);
- else
- c->RemoveMode(NULL, cm, ml.param);
- }
- }
-}
-
-/*************************************************************************/
-
ChannelInfo *cs_findchan(const Anope::string &chan)
{
FOREACH_MOD(I_OnFindChan, OnFindChan(chan));
diff --git a/src/config.cpp b/src/config.cpp
index 524e669fa..5093e9963 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -1153,8 +1153,6 @@ ConfigItems::ConfigItems(ServerConfig *conf)
{"options", "restrictopernicks", "no", new ValueContainerBool(&conf->RestrictOperNicks), DT_BOOLEAN, NoValidation},
{"options", "newscount", "3", new ValueContainerUInt(&conf->NewsCount), DT_UINTEGER, NoValidation},
{"options", "ulineservers", "", new ValueContainerString(&UlineServers), DT_STRING, NoValidation},
- {"options", "mlock", "+nrt", new ValueContainerString(&conf->MLock), DT_STRING, NoValidation},
- {"options", "nomlock", "", new ValueContainerString(&conf->NoMLock), DT_STRING, NoValidation},
{"options", "botmodes", "", new ValueContainerString(&conf->BotModes), DT_STRING, NoValidation},
{"options", "retrywait", "60", new ValueContainerInt(&conf->RetryWait), DT_INTEGER, ValidateNotZero},
{"options", "hideprivilegedcommands", "no", new ValueContainerBool(&conf->HidePrivilegedCommands), DT_BOOLEAN, NoValidation},
@@ -1217,6 +1215,9 @@ ConfigItems::ConfigItems(ServerConfig *conf)
{"chanserv", "inhabit", "0", new ValueContainerTime(&conf->CSInhabit), DT_TIME, ValidateChanServ},
{"chanserv", "listmax", "0", new ValueContainerUInt(&conf->CSListMax), DT_UINTEGER, ValidateChanServ},
{"chanserv", "opersonly", "no", new ValueContainerBool(&conf->CSOpersOnly), DT_BOOLEAN, ValidateChanServ},
+ {"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},
{"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},
diff --git a/src/modes.cpp b/src/modes.cpp
index 580c9f2d7..cbfdc093b 100644
--- a/src/modes.cpp
+++ b/src/modes.cpp
@@ -178,7 +178,7 @@ ChannelMode::~ChannelMode()
*/
bool ChannelMode::CanSet(User *u) const
{
- if (Config->NoMLock.find(this->ModeChar) != Anope::string::npos)
+ if (Config->NoMLock.find(this->ModeChar) != Anope::string::npos || Config->CSRequire.find(this->ModeChar) != Anope::string::npos)
return false;
return true;
}
diff --git a/src/servers.cpp b/src/servers.cpp
index 944285c42..51b47f6c7 100644
--- a/src/servers.cpp
+++ b/src/servers.cpp
@@ -313,7 +313,7 @@ void Server::Sync(bool SyncLinks)
for (channel_map::const_iterator it = ChannelList.begin(), it_end = ChannelList.end(); it != it_end; ++it)
{
Channel *c = it->second;
- check_modes(c);
+ c->CheckModes();
if (c->ci)
c->ci->RestoreTopic();
}