diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/channels.cpp | 51 | ||||
-rw-r--r-- | src/config.cpp | 9 | ||||
-rw-r--r-- | src/modes.cpp | 33 |
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); |