summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/channels.cpp51
-rw-r--r--src/config.cpp9
-rw-r--r--src/modes.cpp33
3 files changed, 54 insertions, 39 deletions
diff --git a/src/channels.cpp b/src/channels.cpp
index f3a061e94..62c6462d6 100644
--- a/src/channels.cpp
+++ b/src/channels.cpp
@@ -922,13 +922,6 @@ void Channel::Hold()
void Channel::SetCorrectModes(User *user, bool give_modes, bool check_noop)
{
- ChannelMode *owner = ModeManager::FindChannelModeByName("OWNER"),
- *admin = ModeManager::FindChannelModeByName("PROTECT"),
- *op = ModeManager::FindChannelModeByName("OP"),
- *halfop = ModeManager::FindChannelModeByName("HALFOP"),
- *voice = ModeManager::FindChannelModeByName("VOICE"),
- *registered = ModeManager::FindChannelModeByName("REGISTERED");
-
if (user == NULL)
return;
@@ -938,39 +931,33 @@ void Channel::SetCorrectModes(User *user, bool give_modes, bool check_noop)
Log(LOG_DEBUG) << "Setting correct user modes for " << user->nick << " on " << this->name << " (" << (give_modes ? "" : "not ") << "giving modes)";
AccessGroup u_access = ci->AccessFor(user);
+ ChannelMode *registered = ModeManager::FindChannelModeByName("REGISTERED");
- if (give_modes && (!user->Account() || user->Account()->HasExt("AUTOOP")) && (!check_noop || !ci->HasExt("NOAUTOOP")))
- {
- if (owner && u_access.HasPriv("AUTOOWNER"))
- this->SetMode(NULL, owner, user->GetUID());
- else if (admin && u_access.HasPriv("AUTOPROTECT"))
- this->SetMode(NULL, admin, user->GetUID());
-
- if (op && u_access.HasPriv("AUTOOP"))
- this->SetMode(NULL, op, user->GetUID());
- else if (halfop && u_access.HasPriv("AUTOHALFOP"))
- this->SetMode(NULL, halfop, user->GetUID());
- else if (voice && u_access.HasPriv("AUTOVOICE"))
- this->SetMode(NULL, voice, user->GetUID());
- }
+ /* Only give modes if autoop isn't set */
+ give_modes &= (!user->Account() || user->Account()->HasExt("AUTOOP")) && (!check_noop || !ci->HasExt("NOAUTOOP"));
/* If this channel has secureops, or the registered channel mode exists and the channel does not have +r set (aka the channel
* was created just now or while we were off), or the registered channel mode does not exist and channel is syncing (aka just
* created *to us*) and the user's server is synced (aka this isn't us doing our initial uplink - without this we would be deopping all
* users with no access on a non-secureops channel on startup), and the user's server isn't ulined, then set negative modes.
*/
- if ((ci->HasExt("SECUREOPS") || (registered && !this->HasMode("REGISTERED")) || (!registered && this->HasExt("SYNCING") && user->server->IsSynced())) && !user->server->IsULined())
- {
- if (owner && !u_access.HasPriv("AUTOOWNER") && !u_access.HasPriv("OWNERME"))
- this->RemoveMode(NULL, owner, user->GetUID());
+ bool take_modes = (ci->HasExt("SECUREOPS") || (registered && !this->HasMode("REGISTERED")) || (!registered && this->HasExt("SYNCING") && user->server->IsSynced())) && !user->server->IsULined();
- if (admin && !u_access.HasPriv("AUTOPROTECT") && !u_access.HasPriv("PROTECTME"))
- this->RemoveMode(NULL, admin, user->GetUID());
-
- if (op && this->HasUserStatus(user, "OP") && !u_access.HasPriv("AUTOOP") && !u_access.HasPriv("OPDEOPME"))
- this->RemoveMode(NULL, op, user->GetUID());
+ bool given = false;
+ for (unsigned i = 0; i < ModeManager::GetStatusChannelModesByRank().size(); ++i)
+ {
+ ChannelModeStatus *cm = ModeManager::GetStatusChannelModesByRank()[i];
+ bool has_priv = u_access.HasPriv("AUTO" + cm->name);
- if (halfop && !u_access.HasPriv("AUTOHALFOP") && !u_access.HasPriv("HALFOPME"))
- this->RemoveMode(NULL, halfop, user->GetUID());
+ /* If we have already given one mode, don't give more until it has a symbol */
+ if (give_modes && has_priv && (!given || cm->symbol))
+ {
+ this->SetMode(NULL, cm, user->GetUID());
+ /* Now if this contains a symbol don't give any more modes, to prevent setting +qaohv etc on users */
+ give_modes = !cm->symbol;
+ given = true;
+ }
+ else if (take_modes && !has_priv)
+ this->RemoveMode(NULL, cm, user->GetUID());
}
// Check mlock
diff --git a/src/config.cpp b/src/config.cpp
index 4d1267f23..d49d9e8d9 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -812,18 +812,13 @@ static bool InitPrivileges(ServerConfig *config, const Anope::string &)
static bool DoPrivileges(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
{
Anope::string name = values[0].GetValue();
- Anope::string desc = values[1].GetValue();
- int rank = values[2].GetInteger();
+ int rank = values[1].GetInteger();
ValueItem vi(name);
if (!ValidateNotEmpty(config, "privilege", "name", vi))
throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
- vi = ValueItem(desc);
- if (!ValidateNotEmpty(config, "privilege", "desc", vi))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
-
- PrivilegeManager::AddPrivilege(Privilege(name, desc, rank));
+ PrivilegeManager::AddPrivilege(Privilege(name, "", rank));
return true;
}
diff --git a/src/modes.cpp b/src/modes.cpp
index a1ecdbfee..6cdeb6565 100644
--- a/src/modes.cpp
+++ b/src/modes.cpp
@@ -25,6 +25,9 @@ std::vector<UserMode *> ModeManager::UserModes;
static std::map<Anope::string, ChannelMode *> ChannelModesByName;
static std::map<Anope::string, UserMode *> UserModesByName;
+/* Sorted by status */
+static std::vector<ChannelModeStatus *> ChannelModesByStatus;
+
/* Number of generic modes we support */
unsigned ModeManager::GenericChannelModes = 0, ModeManager::GenericUserModes = 0;
@@ -349,6 +352,8 @@ bool ModeManager::AddChannelMode(ChannelMode *cm)
if (want >= ModeManager::ChannelModes.size())
ModeManager::ChannelModes.resize(want + 1);
ModeManager::ChannelModes[want] = cms;
+
+ RebuildStatusModes();
}
ChannelModesByName[cm->name] = cm;
@@ -406,6 +411,8 @@ void ModeManager::RemoveChannelMode(ChannelMode *cm)
return;
ModeManager::ChannelModes[want] = NULL;
+
+ RebuildStatusModes();
}
ChannelModesByName.erase(cm->name);
@@ -470,6 +477,32 @@ const std::vector<UserMode *> &ModeManager::GetUserModes()
return UserModes;
}
+const std::vector<ChannelModeStatus *> &ModeManager::GetStatusChannelModesByRank()
+{
+ return ChannelModesByStatus;
+}
+
+static struct StatusSort
+{
+ bool operator()(ChannelModeStatus *cm1, ChannelModeStatus *cm2) const
+ {
+ return cm1->level > cm2->level;
+ }
+} statuscmp;
+
+void ModeManager::RebuildStatusModes()
+{
+ ChannelModesByStatus.clear();
+ for (unsigned j = 0; j < ModeManager::GetChannelModes().size(); ++j)
+ {
+ ChannelMode *cm = ModeManager::GetChannelModes()[j];
+
+ if (cm && cm->type == MODE_STATUS && std::find(ChannelModesByStatus.begin(), ChannelModesByStatus.end(), cm) == ChannelModesByStatus.end())
+ ChannelModesByStatus.push_back(anope_dynamic_static_cast<ChannelModeStatus *>(cm));
+ }
+ std::sort(ChannelModesByStatus.begin(), ChannelModesByStatus.end(), statuscmp);
+}
+
void ModeManager::StackerAdd(const BotInfo *bi, Channel *c, ChannelMode *cm, bool Set, const Anope::string &Param)
{
StackerInfo *s = GetInfo(ChannelStackerObjects, c);