diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/commands/cs_access.cpp | 75 | ||||
-rw-r--r-- | modules/commands/cs_mode.cpp | 20 | ||||
-rw-r--r-- | modules/extra/cs_statusupdate.cpp | 41 | ||||
-rw-r--r-- | modules/protocol/inspircd11.cpp | 2 | ||||
-rw-r--r-- | modules/protocol/inspircd12.cpp | 2 | ||||
-rw-r--r-- | modules/protocol/inspircd20.cpp | 4 |
6 files changed, 80 insertions, 64 deletions
diff --git a/modules/commands/cs_access.cpp b/modules/commands/cs_access.cpp index 3a4bdff54..86ce37a51 100644 --- a/modules/commands/cs_access.cpp +++ b/modules/commands/cs_access.cpp @@ -15,6 +15,49 @@ static std::map<Anope::string, int16_t, ci::less> defaultLevels; +static struct +{ + Anope::string name; + Anope::string desc; +} descriptions[] = { + {"ACCESS_CHANGE", _("Allowed to modify the access list")}, + {"ACCESS_LIST", _("Allowed to view the access list")}, + {"AKICK", _("Allowed to use the AKICK command")}, + {"ASSIGN", _("Allowed to assign/unassign a bot")}, + {"AUTOHALFOP", _("Automatic halfop upon join")}, + {"AUTOOP", _("Automatic channel operator status upon join")}, + {"AUTOOWNER", _("Automatic owner upon join")}, + {"AUTOPROTECT", _("Automatic protect upon join")}, + {"AUTOVOICE", _("Automatic voice on join")}, + {"BADWORDS", _("Allowed to modify channel badwords list")}, + {"BAN", _("Allowed to ban users")}, + {"FANTASIA", _("Allowed to use fantasy commands")}, + {"FOUNDER", _("Allowed to issue commands restricted to channel founders")}, + {"GETKEY", _("Allowed to use GETKEY command")}, + {"GREET", _("Greet message displayed on join")}, + {"HALFOP", _("Allowed to (de)halfop users")}, + {"HALFOPME", _("Allowed to (de)halfop him/herself")}, + {"INFO", _("Allowed to get full INFO output")}, + {"INVITE", _("Allowed to use the INVITE command")}, + {"KICK", _("Allowed to use the KICK command")}, + {"MEMO", _("Allowed to read channel memos")}, + {"MODE", _("Allowed to use the MODE command")}, + {"NOKICK", _("Prevents users being kicked by Services")}, + {"OPDEOP", _("Allowed to (de)op users")}, + {"OPDEOPME", _("Allowed to (de)op him/herself")}, + {"OWNER", _("Allowed to (de)owner users")}, + {"OWNERME", _("Allowed to (de)owner him/herself")}, + {"PROTECT", _("Allowed to (de)protect users")}, + {"PROTECTME", _("Allowed to (de)protect him/herself")}, + {"SAY", _("Allowed to use SAY and ACT commands")}, + {"SET", _("Allowed to set channel settings")}, + {"SIGNKICK", _("No signed kick when SIGNKICK LEVEL is used")}, + {"TOPIC", _("Allowed to change channel topics")}, + {"UNBAN", _("Allowed to unban users")}, + {"VOICE", _("Allowed to (de)voice users")}, + {"VOICEME", _("Allowed to (de)voice him/herself")} +}; + static inline void reset_levels(ChannelInfo *ci) { ci->ClearLevels(); @@ -552,22 +595,8 @@ class CommandCSAccess : public Command " \n" "The \002ACCESS CLEAR\002 command clears all entries of the\n" "access list.")); - source.Reply(_("\002User access levels\002\n" - " \n" - "By default, the following access levels are defined:\n" - " \n" - " \002Founder\002 Full access to %s functions; automatic\n" - " opping upon entering channel. Note\n" - " that only one person may have founder\n" - " status (it cannot be given using the\n" - " \002ACCESS\002 command).\n" - " \002 10\002 Access to AKICK command; automatic opping.\n" - " \002 5\002 Automatic opping.\n" - " \002 3\002 Automatic voicing.\n" - " \002 0\002 No special privileges; can be opped by other\n" - " ops (unless \002secure-ops\002 is set).\n" - " \n" - "These levels may be changed, or new ones added, using the\n" + source.Reply(" "); + source.Reply(_("\002User access levels\002 can be seen by using the\n" "\002LEVELS\002 command; type \002%s%s HELP LEVELS\002 for\n" "information."), source.service->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str()); return true; @@ -806,14 +835,7 @@ class CSAccess : public Module Implementation i[] = { I_OnReload, I_OnCreateChan, I_OnGroupCheckPriv }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - try - { - this->OnReload(); - } - catch (const ConfigException &ex) - { - throw ModuleException(ex.GetReason()); - } + this->OnReload(); } void OnReload() anope_override @@ -829,6 +851,11 @@ class CSAccess : public Module if (p == NULL) continue; + if (p->desc.empty()) + for (unsigned j = 0; j < sizeof(descriptions) / sizeof(*descriptions); ++j) + if (descriptions[j].name == pname) + p->desc = descriptions[j].desc; + const Anope::string &value = config.ReadValue("privilege", "level", "", i); if (value.empty()) continue; diff --git a/modules/commands/cs_mode.cpp b/modules/commands/cs_mode.cpp index 1d0f0985b..f0f7894cf 100644 --- a/modules/commands/cs_mode.cpp +++ b/modules/commands/cs_mode.cpp @@ -20,25 +20,7 @@ class CommandCSMode : public Command if (!ci || !cm || cm->type != MODE_STATUS) return false; - const Anope::string accesses[] = { "VOICE", "HALFOP", "OPDEOP", "PROTECT", "OWNER", "" }, - accesses_self[] = { "VOICEME", "HALFOPME", "OPDEOPME", "PROTECTME", "OWNERME", "" }; - const Anope::string modes[] = { "VOICE", "HALFOP", "OP", "PROTECT", "OWNER" }; - ChannelModeStatus *cms = anope_dynamic_static_cast<ChannelModeStatus *>(cm); - AccessGroup access = source.AccessFor(ci); - short u_level = -1; - - for (int i = 0; !accesses[i].empty(); ++i) - if (access.HasPriv(self ? accesses_self[i] : accesses[i])) - { - ChannelMode *cm2 = ModeManager::FindChannelModeByName(modes[i]); - if (cm2 == NULL || cm2->type != MODE_STATUS) - continue; - ChannelModeStatus *cms2 = anope_dynamic_static_cast<ChannelModeStatus *>(cm2); - if (cms2->level > u_level) - u_level = cms2->level; - } - - return u_level >= cms->level; + return source.AccessFor(ci).HasPriv(cm->name + (self ? "ME" : "")); } void DoLock(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms) diff --git a/modules/extra/cs_statusupdate.cpp b/modules/extra/cs_statusupdate.cpp index 4a53956d7..934b928d1 100644 --- a/modules/extra/cs_statusupdate.cpp +++ b/modules/extra/cs_statusupdate.cpp @@ -7,19 +7,6 @@ #include "module.h" -static struct ModeInfo -{ - Anope::string priv; - Anope::string name; -} modeInfo[] = { - { "AUTOOWNER", "OWNER" }, - { "AUTOPROTECT", "PROTECT" }, - { "AUTOOP", "OP" }, - { "AUTOHALFOP", "HALFOP" }, - { "AUTOVOICE", "VOICE" }, - { "", "" } -}; - class StatusUpdate : public Module { public: @@ -38,11 +25,14 @@ class StatusUpdate : public Module { User *user = it->second->user; - if (access->Matches(user, user->Account())) + if (user->server != Me && access->Matches(user, user->Account())) { - for (int i = 0; !modeInfo[i].priv.empty(); ++i) - if (!access->HasPriv(modeInfo[i].priv)) - ci->c->RemoveMode(NULL, modeInfo[i].name, user->nick); + for (unsigned i = 0; i < ModeManager::GetStatusChannelModesByRank().size(); ++i) + { + ChannelModeStatus *cms = ModeManager::GetStatusChannelModesByRank()[i]; + if (!access->HasPriv("AUTO" + cms->name)) + ci->c->RemoveMode(NULL, cms, user->GetUID()); + } ci->c->SetCorrectModes(user, true, false); } } @@ -55,11 +45,20 @@ class StatusUpdate : public Module { User *user = it->second->user; - if (access->Matches(user, user->Account())) + if (user->server != Me && access->Matches(user, user->Account())) { - for (int i = 0; !modeInfo[i].priv.empty(); ++i) - if (access->HasPriv(modeInfo[i].priv)) - ci->c->RemoveMode(NULL, modeInfo[i].name, user->nick); + /* Get user's current access and remove the entry about to be deleted */ + AccessGroup ag = ci->AccessFor(user); + AccessGroup::iterator iter = std::find(ag.begin(), ag.end(), access); + if (iter != ag.end()) + ag.erase(iter); + + for (unsigned i = 0; i < ModeManager::GetStatusChannelModesByRank().size(); ++i) + { + ChannelModeStatus *cms = ModeManager::GetStatusChannelModesByRank()[i]; + if (!ag.HasPriv("AUTO" + cms->name)) + ci->c->RemoveMode(NULL, cms, user->GetUID()); + } } } } diff --git a/modules/protocol/inspircd11.cpp b/modules/protocol/inspircd11.cpp index b6cb905c2..34b807983 100644 --- a/modules/protocol/inspircd11.cpp +++ b/modules/protocol/inspircd11.cpp @@ -531,6 +531,8 @@ struct IRCDMessageCapab : Message::Capab ModeManager::AddChannelMode(new ChannelModeStatus("", modes[t], chars[t], level--)); } } + + ModeManager::RebuildStatusModes(); } else if (capab.find("MAXMODES=") != Anope::string::npos) { diff --git a/modules/protocol/inspircd12.cpp b/modules/protocol/inspircd12.cpp index deb7bbbf1..dcabbac7f 100644 --- a/modules/protocol/inspircd12.cpp +++ b/modules/protocol/inspircd12.cpp @@ -717,6 +717,8 @@ struct IRCDMessageCapab : Message::Capab ModeManager::AddChannelMode(new ChannelModeStatus("", modes[t], chars[t], level--)); } } + + ModeManager::RebuildStatusModes(); } else if (capab.find("MAXMODES=") != Anope::string::npos) { diff --git a/modules/protocol/inspircd20.cpp b/modules/protocol/inspircd20.cpp index 0af696bf0..ac970ddf9 100644 --- a/modules/protocol/inspircd20.cpp +++ b/modules/protocol/inspircd20.cpp @@ -469,7 +469,11 @@ struct IRCDMessageCapab : Message::Capab ChannelModeStatus *cms = anope_dynamic_static_cast<ChannelModeStatus *>(cm); cms->level = level--; + + Log(LOG_DEBUG) << cms->name << " is now level " << cms->level; } + + ModeManager::RebuildStatusModes(); } } } |