summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2011-08-28 15:46:15 -0400
committerAdam <Adam@anope.org>2011-09-10 02:05:00 -0400
commit700a585b1bb38a9dc0ac3e749083250d405488f8 (patch)
tree8af306bd60778815fe5a137590d3b888213ad231
parent62752db4c49a8679b51d5996003fd3a23c2a3f2d (diff)
Allow modules to add their own channel levels
-rw-r--r--data/chanserv.example.conf8
-rw-r--r--data/tables.sql4
-rw-r--r--include/access.h59
-rw-r--r--include/anope.h22
-rw-r--r--include/extern.h2
-rw-r--r--include/modules.h8
-rw-r--r--include/regchannel.h24
-rw-r--r--include/services.h2
-rw-r--r--modules/commands/bs_assign.cpp8
-rw-r--r--modules/commands/bs_badwords.cpp12
-rw-r--r--modules/commands/bs_control.cpp4
-rw-r--r--modules/commands/bs_info.cpp2
-rw-r--r--modules/commands/bs_kick.cpp8
-rw-r--r--modules/commands/bs_set.cpp4
-rw-r--r--modules/commands/cs_access.cpp213
-rw-r--r--modules/commands/cs_akick.cpp18
-rw-r--r--modules/commands/cs_appendtopic.cpp4
-rw-r--r--modules/commands/cs_ban.cpp4
-rw-r--r--modules/commands/cs_clearusers.cpp2
-rw-r--r--modules/commands/cs_clone.cpp2
-rw-r--r--modules/commands/cs_drop.cpp4
-rw-r--r--modules/commands/cs_enforce.cpp2
-rw-r--r--modules/commands/cs_flags.cpp111
-rw-r--r--modules/commands/cs_getkey.cpp4
-rw-r--r--modules/commands/cs_info.cpp2
-rw-r--r--modules/commands/cs_invite.cpp2
-rw-r--r--modules/commands/cs_kick.cpp4
-rw-r--r--modules/commands/cs_mode.cpp6
-rw-r--r--modules/commands/cs_modes.cpp24
-rw-r--r--modules/commands/cs_saset_noexpire.cpp2
-rw-r--r--modules/commands/cs_set_bantype.cpp2
-rw-r--r--modules/commands/cs_set_description.cpp2
-rw-r--r--modules/commands/cs_set_founder.cpp4
-rw-r--r--modules/commands/cs_set_keeptopic.cpp2
-rw-r--r--modules/commands/cs_set_misc.cpp2
-rw-r--r--modules/commands/cs_set_peace.cpp2
-rw-r--r--modules/commands/cs_set_persist.cpp2
-rw-r--r--modules/commands/cs_set_private.cpp2
-rw-r--r--modules/commands/cs_set_restricted.cpp2
-rw-r--r--modules/commands/cs_set_secure.cpp2
-rw-r--r--modules/commands/cs_set_securefounder.cpp2
-rw-r--r--modules/commands/cs_set_secureops.cpp2
-rw-r--r--modules/commands/cs_set_signkick.cpp2
-rw-r--r--modules/commands/cs_set_successor.cpp4
-rw-r--r--modules/commands/cs_set_topiclock.cpp2
-rw-r--r--modules/commands/cs_tban.cpp2
-rw-r--r--modules/commands/cs_topic.cpp4
-rw-r--r--modules/commands/cs_unban.cpp2
-rw-r--r--modules/commands/cs_xop.cpp94
-rw-r--r--modules/commands/ms_del.cpp2
-rw-r--r--modules/commands/ms_ignore.cpp2
-rw-r--r--modules/commands/ms_info.cpp2
-rw-r--r--modules/commands/ms_list.cpp2
-rw-r--r--modules/commands/ms_read.cpp2
-rw-r--r--modules/commands/ms_set.cpp2
-rw-r--r--modules/commands/ns_ajoin.cpp4
-rw-r--r--modules/database/db_mysql.cpp42
-rw-r--r--modules/database/db_plain.cpp65
-rw-r--r--modules/extra/m_helpchan.cpp2
-rw-r--r--modules/extra/m_statusupdate.cpp18
-rw-r--r--modules/pseudoclients/botserv.cpp4
-rw-r--r--modules/pseudoclients/memoserv.cpp4
-rw-r--r--src/access.cpp141
-rw-r--r--src/botserv.cpp4
-rw-r--r--src/channels.cpp18
-rw-r--r--src/init.cpp1
-rw-r--r--src/regchannel.cpp28
67 files changed, 530 insertions, 520 deletions
diff --git a/data/chanserv.example.conf b/data/chanserv.example.conf
index cc2bbaef6..d9bd6eb0c 100644
--- a/data/chanserv.example.conf
+++ b/data/chanserv.example.conf
@@ -184,8 +184,8 @@ chanserv
* The level "disabled" is a special level that means the level is disabled, even from people
* with founder level access.
*/
- level_change = 10
- level_list = 1
+ level_access_change = 10
+ level_access_list = 1
level_akick = 10
level_assign = "founder"
level_autohalfop = 4
@@ -226,8 +226,8 @@ chanserv
*
* These flags are used by the chanserv/flags access system.
*/
- flag_change = "f"
- flag_list = "l"
+ flag_access_change = "f"
+ flag_access_list = "l"
flag_akick = "K"
flag_assign = "s"
flag_autohalfop = "H"
diff --git a/data/tables.sql b/data/tables.sql
index 69e694a32..ec99b7479 100644
--- a/data/tables.sql
+++ b/data/tables.sql
@@ -140,9 +140,9 @@ CREATE TABLE IF NOT EXISTS `anope_cs_info_metadata` (
CREATE TABLE IF NOT EXISTS `anope_cs_levels` (
`channel` varchar(255) NOT NULL DEFAULT '',
- `position` int(11) NOT NULL DEFAULT '0',
+ `name` varchar(255) NOT NULL DEFAULT '',
`level` int(11) NOT NULL DEFAULT '0',
- UNIQUE KEY `channel` (`channel`,`position`)
+ UNIQUE KEY `channel` (`channel`,`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
diff --git a/include/access.h b/include/access.h
index 0c730c9ff..6557d40c6 100644
--- a/include/access.h
+++ b/include/access.h
@@ -1,45 +1,24 @@
#ifndef ACCESS_H
#define ACCESS_H
-enum ChannelAccess
+struct Privilege
{
- CA_ACCESS_LIST,
- CA_NOKICK,
- CA_FANTASIA,
- CA_GREET,
- CA_AUTOVOICE,
- CA_VOICEME,
- CA_VOICE,
- CA_INFO,
- CA_SAY,
- CA_AUTOHALFOP,
- CA_HALFOPME,
- CA_HALFOP,
- CA_KICK,
- CA_SIGNKICK,
- CA_BAN,
- CA_TOPIC,
- CA_MODE,
- CA_GETKEY,
- CA_INVITE,
- CA_UNBAN,
- CA_AUTOOP,
- CA_OPDEOPME,
- CA_OPDEOP,
- CA_AUTOPROTECT,
- CA_AKICK,
- CA_BADWORDS,
- CA_ASSIGN,
- CA_MEMO,
- CA_ACCESS_CHANGE,
- CA_PROTECTME,
- CA_PROTECT,
- CA_SET,
- CA_AUTOOWNER,
- CA_OWNERME,
- CA_OWNER,
- CA_FOUNDER,
- CA_SIZE
+ Anope::string name;
+ Anope::string desc;
+
+ Privilege(const Anope::string &n, const Anope::string &d);
+ bool operator==(const Privilege &other);
+};
+
+class PrivilegeManager
+{
+ static std::vector<Privilege> privs;
+ public:
+ static void AddPrivilege(Privilege p, int pos = -1, int def = 0);
+ static void RemovePrivilege(Privilege &p);
+ static Privilege *FindPrivilege(const Anope::string &name);
+ static void Init();
+ static std::vector<Privilege> &GetPrivileges();
};
class ChanAccess;
@@ -65,7 +44,7 @@ class CoreExport ChanAccess
ChanAccess(AccessProvider *p);
virtual ~ChanAccess();
virtual bool Matches(User *u, NickCore *nc) = 0;
- virtual bool HasPriv(ChannelAccess priv) = 0;
+ virtual bool HasPriv(const Anope::string &name) = 0;
virtual Anope::string Serialize() = 0;
virtual void Unserialize(const Anope::string &data) = 0;
@@ -82,7 +61,7 @@ class CoreExport AccessGroup : public std::vector<ChanAccess *>
NickCore *nc;
bool SuperAdmin, Founder;
AccessGroup();
- bool HasPriv(ChannelAccess priv) const;
+ bool HasPriv(const Anope::string &priv) const;
ChanAccess *Highest() const;
bool operator>(const AccessGroup &other) const;
bool operator<(const AccessGroup &other) const;
diff --git a/include/anope.h b/include/anope.h
index 5eeee0a04..3eec3d4e4 100644
--- a/include/anope.h
+++ b/include/anope.h
@@ -259,6 +259,28 @@ namespace Anope
}
/**
+ * Get the string in lowercase.
+ */
+ inline string lower()
+ {
+ Anope::string new_string = *this;
+ for (size_type i = 0; i < new_string.length(); ++i)
+ new_string[i] = tolower(new_string[i]);
+ return new_string;
+ }
+
+ /**
+ * Get the string in uppercase.
+ */
+ inline string upper()
+ {
+ Anope::string new_string = *this;
+ for (size_type i = 0; i < new_string.length(); ++i)
+ new_string[i] = toupper(new_string[i]);
+ return new_string;
+ }
+
+ /**
* Get a substring of the string.
*/
inline string substr(size_type pos = 0, size_type n = npos) const { return string(this->_string.substr(pos, n)); }
diff --git a/include/extern.h b/include/extern.h
index b62997aad..4b15d81ac 100644
--- a/include/extern.h
+++ b/include/extern.h
@@ -152,8 +152,6 @@ E bool OnError(const Anope::string &, const std::vector<Anope::string> &);
/**** misc.c ****/
E bool IsFile(const Anope::string &filename);
-E int toupper(char);
-E int tolower(char);
E time_t dotime(const Anope::string &s);
E Anope::string duration(const time_t &seconds, NickCore *nc = NULL);
diff --git a/include/modules.h b/include/modules.h
index a34b7f64d..f76a1f58a 100644
--- a/include/modules.h
+++ b/include/modules.h
@@ -662,10 +662,10 @@ class CoreExport Module : public Extensible
/** Called when a level for a channel is changed
* @param u The user changing the level
* @param ci The channel the level was changed on
- * @param pos The level position, can be -1 for resetting levels
+ * @param priv The privilege changed
* @param what The new level
*/
- virtual void OnLevelChange(User *u, ChannelInfo *ci, int pos, int what) { }
+ virtual void OnLevelChange(User *u, ChannelInfo *ci, const Anope::string &priv, int16 what) { }
/** Called when a channel is dropped
* @param chname The channel name
@@ -751,14 +751,14 @@ class CoreExport Module : public Extensible
* @param priv The privilege being checked for
* @return EVENT_ALLOW for yes, EVENT_STOP to stop all processing
*/
- virtual EventReturn OnCheckPriv(ChanAccess *access, ChannelAccess priv) { return EVENT_CONTINUE; }
+ virtual EventReturn OnCheckPriv(ChanAccess *access, const Anope::string &priv) { return EVENT_CONTINUE; }
/** Check whether an access group has a privilege
* @param group The group
* @param priv The privilege
* @return MOD_ALLOW to allow, MOD_STOP to stop
*/
- virtual EventReturn OnGroupCheckPriv(const AccessGroup *group, ChannelAccess priv) { return EVENT_CONTINUE; }
+ virtual EventReturn OnGroupCheckPriv(const AccessGroup *group, const Anope::string &priv) { return EVENT_CONTINUE; }
/** Called when a nick is dropped
* @param u The user dropping the nick
diff --git a/include/regchannel.h b/include/regchannel.h
index 71136a73b..1d071fb0f 100644
--- a/include/regchannel.h
+++ b/include/regchannel.h
@@ -103,6 +103,7 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
std::vector<ChanAccess *> access; /* List of authorized users */
std::vector<AutoKick *> akick; /* List of users to kickban */
std::vector<BadWord *> badwords; /* List of badwords */
+ std::map<Anope::string, int16> levels;
public:
typedef std::multimap<ChannelModeName, ModeLock> ModeList;
@@ -134,7 +135,6 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
time_t last_topic_time; /* Time */
int16 bantype;
- int16 levels[CA_SIZE];
MemoInfo memos;
@@ -345,6 +345,28 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
* and after uplink sync
*/
void RestoreTopic();
+
+ /** Get the level for a privilege
+ * @param priv The privilege name
+ * @return the level
+ * @throws CoreException if priv is not a valid privilege
+ */
+ int16 GetLevel(const Anope::string &priv);
+
+ /** Set the level for a privilege
+ * @param priv The privilege priv
+ * @param level The new level
+ */
+ void SetLevel(const Anope::string &priv, int16 level);
+
+ /** Remove a privilege from the channel
+ * @param priv The privilege
+ */
+ void RemoveLevel(const Anope::string &priv);
+
+ /** Clear all privileges from the channel
+ */
+ void ClearLevels();
};
/** A timer used to keep the BotServ bot/ChanServ in the channel
diff --git a/include/services.h b/include/services.h
index d6db4e9ed..3a7ff65c2 100644
--- a/include/services.h
+++ b/include/services.h
@@ -98,6 +98,8 @@ extern int strncasecmp(const char *, const char *, size_t);
#undef toupper
#define tolower tolower_
#define toupper toupper_
+extern int toupper(char);
+extern int tolower(char);
/** This definition is used as shorthand for the various classes
* and functions needed to make a module loadable by the OS.
diff --git a/modules/commands/bs_assign.cpp b/modules/commands/bs_assign.cpp
index 13f3e4403..64ae9064d 100644
--- a/modules/commands/bs_assign.cpp
+++ b/modules/commands/bs_assign.cpp
@@ -49,7 +49,7 @@ class CommandBSAssign : public Command
return;
}
- if (ci->botflags.HasFlag(BS_NOBOT) || (!ci->AccessFor(u).HasPriv(CA_ASSIGN) && !u->HasPriv("botserv/administration")))
+ if (ci->botflags.HasFlag(BS_NOBOT) || (!ci->AccessFor(u).HasPriv("ASSIGN") && !u->HasPriv("botserv/administration")))
{
source.Reply(ACCESS_DENIED);
return;
@@ -67,7 +67,7 @@ class CommandBSAssign : public Command
return;
}
- bool override = !ci->AccessFor(u).HasPriv(CA_ASSIGN);
+ bool override = !ci->AccessFor(u).HasPriv("ASSIGN");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "for " << bi->nick;
bi->Assign(u, ci);
@@ -111,7 +111,7 @@ class CommandBSUnassign : public Command
return;
}
- if (!u->HasPriv("botserv/administration") && !ci->AccessFor(u).HasPriv(CA_ASSIGN))
+ if (!u->HasPriv("botserv/administration") && !ci->AccessFor(u).HasPriv("ASSIGN"))
{
source.Reply(ACCESS_DENIED);
return;
@@ -129,7 +129,7 @@ class CommandBSUnassign : public Command
return;
}
- bool override = !ci->AccessFor(u).HasPriv(CA_ASSIGN);
+ bool override = !ci->AccessFor(u).HasPriv("ASSIGN");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "for " << ci->bi->nick;
ci->bi->UnAssign(u, ci);
diff --git a/modules/commands/bs_badwords.cpp b/modules/commands/bs_badwords.cpp
index 15298d5eb..db3843cf4 100644
--- a/modules/commands/bs_badwords.cpp
+++ b/modules/commands/bs_badwords.cpp
@@ -60,7 +60,7 @@ class BadwordsDelCallback : public NumberList
public:
BadwordsDelCallback(CommandSource &_source, ChannelInfo *_ci, Command *_c, const Anope::string &list) : NumberList(list, true), source(_source), ci(_ci), c(_c), Deleted(0), override(false)
{
- if (!ci->AccessFor(source.u).HasPriv(CA_BADWORDS) && source.u->HasPriv("botserv/administration"))
+ if (!ci->AccessFor(source.u).HasPriv("BADWORDS") && source.u->HasPriv("botserv/administration"))
this->override = true;
}
@@ -90,7 +90,7 @@ class CommandBSBadwords : public Command
private:
void DoList(CommandSource &source, ChannelInfo *ci, const Anope::string &word)
{
- bool override = !ci->AccessFor(source.u).HasPriv(CA_BADWORDS);
+ bool override = !ci->AccessFor(source.u).HasPriv("BADWORDS");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, this, ci) << "LIST";
if (!ci->GetBadWordCount())
@@ -167,7 +167,7 @@ class CommandBSBadwords : public Command
}
}
- bool override = !ci->AccessFor(source.u).HasPriv(CA_BADWORDS);
+ bool override = !ci->AccessFor(source.u).HasPriv("BADWORDS");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, this, ci) << "ADD " << realword;
ci->AddBadWord(realword, type);
@@ -203,7 +203,7 @@ class CommandBSBadwords : public Command
return;
}
- bool override = !ci->AccessFor(source.u).HasPriv(CA_BADWORDS);
+ bool override = !ci->AccessFor(source.u).HasPriv("BADWORDS");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, this, ci) << "DEL " << badword->word;
source.Reply(_("\002%s\002 deleted from %s bad words list."), badword->word.c_str(), ci->name.c_str());
@@ -216,7 +216,7 @@ class CommandBSBadwords : public Command
void DoClear(CommandSource &source, ChannelInfo *ci)
{
- bool override = !ci->AccessFor(source.u).HasPriv(CA_BADWORDS);
+ bool override = !ci->AccessFor(source.u).HasPriv("BADWORDS");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, this, ci) << "CLEAR";
ci->ClearBadWords();
@@ -254,7 +254,7 @@ class CommandBSBadwords : public Command
}
- if (!ci->AccessFor(u).HasPriv(CA_BADWORDS) && (!need_args || !u->HasPriv("botserv/administration")))
+ if (!ci->AccessFor(u).HasPriv("BADWORDS") && (!need_args || !u->HasPriv("botserv/administration")))
{
source.Reply(ACCESS_DENIED);
return;
diff --git a/modules/commands/bs_control.cpp b/modules/commands/bs_control.cpp
index b464a4520..164542daf 100644
--- a/modules/commands/bs_control.cpp
+++ b/modules/commands/bs_control.cpp
@@ -35,7 +35,7 @@ class CommandBSSay : public Command
return;
}
- if (!ci->AccessFor(u).HasPriv(CA_SAY))
+ if (!ci->AccessFor(u).HasPriv("SAY"))
{
source.Reply(ACCESS_DENIED);
return;
@@ -98,7 +98,7 @@ class CommandBSAct : public Command
return;
}
- if (!ci->AccessFor(u).HasPriv(CA_SAY))
+ if (!ci->AccessFor(u).HasPriv("SAY"))
{
source.Reply(ACCESS_DENIED);
return;
diff --git a/modules/commands/bs_info.cpp b/modules/commands/bs_info.cpp
index d6668184d..0dbec9e29 100644
--- a/modules/commands/bs_info.cpp
+++ b/modules/commands/bs_info.cpp
@@ -70,7 +70,7 @@ class CommandBSInfo : public Command
}
else if ((ci = cs_findchan(query)))
{
- if (!ci->AccessFor(u).HasPriv(CA_FOUNDER) && !u->HasPriv("botserv/administration"))
+ if (!ci->AccessFor(u).HasPriv("FOUNDER") && !u->HasPriv("botserv/administration"))
{
source.Reply(ACCESS_DENIED);
return;
diff --git a/modules/commands/bs_kick.cpp b/modules/commands/bs_kick.cpp
index 107e78d64..74ccaf05c 100644
--- a/modules/commands/bs_kick.cpp
+++ b/modules/commands/bs_kick.cpp
@@ -41,13 +41,13 @@ class CommandBSKick : public Command
this->OnSyntaxError(source, "");
else if (!value.equals_ci("ON") && !value.equals_ci("OFF"))
this->OnSyntaxError(source, "");
- else if (!ci->AccessFor(u).HasPriv(CA_SET) && !u->HasPriv("botserv/administration"))
+ else if (!ci->AccessFor(u).HasPriv("SET") && !u->HasPriv("botserv/administration"))
source.Reply(ACCESS_DENIED);
else if (!ci->bi)
source.Reply(BOT_NOT_ASSIGNED);
else
{
- bool override = !ci->AccessFor(u).HasPriv(CA_SET);
+ bool override = !ci->AccessFor(u).HasPriv("SET");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << option << " " << value;
if (option.equals_ci("BADWORDS"))
@@ -767,7 +767,7 @@ class BSKick : public Module
return;
bool Allow = true;
- if (ci->AccessFor(u).HasPriv(CA_NOKICK))
+ if (ci->AccessFor(u).HasPriv("NOKICK"))
Allow = false;
else if (ci->botflags.HasFlag(BS_DONTKICKOPS) && (c->HasUserStatus(u, CMODE_HALFOP) || c->HasUserStatus(u, CMODE_OP) || c->HasUserStatus(u, CMODE_PROTECT) || c->HasUserStatus(u, CMODE_OWNER)))
Allow = false;
@@ -992,7 +992,7 @@ class BSKick : public Module
Channel *chan = (*it)->chan;
++it;
- if (chan->ci != NULL && chan->ci->botflags.HasFlag(BS_KICK_AMSGS) && !chan->ci->AccessFor(u).HasPriv(CA_NOKICK))
+ if (chan->ci != NULL && chan->ci->botflags.HasFlag(BS_KICK_AMSGS) && !chan->ci->AccessFor(u).HasPriv("NOKICK"))
{
check_ban(chan->ci, u, TTB_AMSGS);
bot_kick(chan->ci, u, _("Don't use AMSGs!"));
diff --git a/modules/commands/bs_set.cpp b/modules/commands/bs_set.cpp
index be699c3e8..b38c05d60 100644
--- a/modules/commands/bs_set.cpp
+++ b/modules/commands/bs_set.cpp
@@ -59,11 +59,11 @@ class CommandBSSet : public Command
}
else if (!(ci = cs_findchan(chan)))
source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
- else if (!u->HasPriv("botserv/administration") && !ci->AccessFor(u).HasPriv(CA_SET))
+ else if (!u->HasPriv("botserv/administration") && !ci->AccessFor(u).HasPriv("SET"))
source.Reply(ACCESS_DENIED);
else
{
- bool override = !ci->AccessFor(u).HasPriv(CA_SET);
+ bool override = !ci->AccessFor(u).HasPriv("SET");
Log(override ? LOG_ADMIN : LOG_COMMAND, u, this, ci) << option << " " << value;
if (option.equals_ci("DONTKICKOPS"))
diff --git a/modules/commands/cs_access.cpp b/modules/commands/cs_access.cpp
index 2dd7da51c..8c3e1a1ca 100644
--- a/modules/commands/cs_access.cpp
+++ b/modules/commands/cs_access.cpp
@@ -19,57 +19,13 @@ enum
ACCESS_FOUNDER = 10001
};
-static struct AccessLevels
-{
- ChannelAccess priv;
- int default_level;
- Anope::string config_name;
- Anope::string name;
- Anope::string desc;
-} defaultLevels[] = {
- { CA_ACCESS_CHANGE, 10, "level_change", "ACC-CHANGE", _("Allowed to modify the access list") },
- { CA_ACCESS_LIST, 1, "level_list", "ACC-LIST", _("Allowed to view the access list") },
- { CA_AKICK, 10, "level_akick", "AKICK", _("Allowed to use AKICK command") },
- { CA_ASSIGN, ACCESS_FOUNDER, "level_assign", "ASSIGN", _("Allowed to assign/unassign a bot") },
- { CA_AUTOHALFOP, 4, "level_autohalfop", "AUTOHALFOP", _("Automatic mode +h") },
- { CA_AUTOOP, 5, "level_autoop", "AUTOOP", _("Automatic channel operator status") },
- { CA_AUTOOWNER, 10000, "level_autoowner", "AUTOOWNER", _("Automatic mode +q") },
- { CA_AUTOPROTECT, 10, "level_autoprotect", "AUTOPROTECT", _("Automatic mode +a") },
- { CA_AUTOVOICE, 3, "level_autovoice", "AUTOVOICE", _("Automatic mode +v") },
- { CA_BADWORDS, 10, "level_badwords", "BADWORDS", _("Allowed to modify channel badwords list") },
- { CA_BAN, 4, "level_ban", "BAN", _("Allowed to use ban users") },
- { CA_FANTASIA, 3, "level_fantasia", "FANTASIA", _("Allowed to use fantaisist commands") },
- { CA_FOUNDER, ACCESS_FOUNDER, "level_founder", "FOUNDER", _("Allowed to issue commands restricted to channel founders") },
- { CA_GETKEY, 5, "level_getkey", "GETKEY", _("Allowed to use GETKEY command") },
- { CA_GREET, 5, "level_greet", "GREET", _("Greet message displayed") },
- { CA_HALFOP, 5, "level_halfop", "HALFOP", _("Allowed to (de)halfop users") },
- { CA_HALFOPME, 4, "level_halfopme", "HALFOPME", _("Allowed to (de)halfop him/herself") },
- { CA_INFO, 10000, "level_info", "INFO", _("Allowed to use INFO command with ALL option") },
- { CA_INVITE, 5, "level_invite", "INVITE", _("Allowed to use the INVITE command") },
- { CA_KICK, 4, "level_kick", "KICK", _("Allowed to use the KICK command") },
- { CA_MEMO, 10, "level_memo", "MEMO", _("Allowed to read channel memos") },
- { CA_MODE, 5, "level_mode", "MODE", _("Allowed to change channel modes") },
- { CA_NOKICK, 1, "level_nokick", "NOKICK", _("Never kicked by the bot's kickers") },
- { CA_OPDEOP, 5, "level_opdeop", "OPDEOP", _("Allowed to (de)op users") },
- { CA_OPDEOPME, 5, "level_opdeopme", "OPDEOPME", _("Allowed to (de)op him/herself") },
- { CA_OWNER, ACCESS_FOUNDER, "level_owner", "OWNER", _("Allowed to use (de)owner users") },
- { CA_OWNERME, 10000, "level_ownerme", "OWNERME", _("Allowed to (de)owner him/herself") },
- { CA_PROTECT, 10000, "level_protect", "PROTECT", _("Allowed to (de)protect users") },
- { CA_PROTECTME, 10, "level_protectme", "PROTECTME", _("Allowed to (de)protect him/herself"), },
- { CA_SAY, 5, "level_say", "SAY", _("Allowed to use SAY and ACT commands") },
- { CA_SIGNKICK, ACCESS_FOUNDER, "level_signkick", "SIGNKICK", _("No signed kick when SIGNKICK LEVEL is used") },
- { CA_SET, 10000, "level_set", "SET", _("Allowed to set channel settings") },
- { CA_TOPIC, 5, "level_topic", "TOPIC", _("Allowed to change channel topics") },
- { CA_UNBAN, 4, "level_unban", "UNBAN", _("Allowed to unban users") },
- { CA_VOICE, 4, "level_voice", "VOICE", _("Allowed to (de)voice users") },
- { CA_VOICEME, 3, "level_voiceme", "VOICEME", _("Allowed to (de)voice him/herself") },
- { CA_SIZE, -1, "", "", "" }
-};
+static std::map<Anope::string, int16> defaultLevels;
static void reset_levels(ChannelInfo *ci)
{
- for (int i = 0; defaultLevels[i].priv != CA_SIZE; ++i)
- ci->levels[defaultLevels[i].priv] = defaultLevels[i].default_level;
+ ci->ClearLevels();
+ for (std::map<Anope::string, int16>::iterator it = defaultLevels.begin(), it_end = defaultLevels.end(); it != it_end; ++it)
+ ci->SetLevel(it->first, it->second);
}
class AccessChanAccess : public ChanAccess
@@ -90,12 +46,9 @@ class AccessChanAccess : public ChanAccess
return false;
}
- bool HasPriv(ChannelAccess priv)
+ bool HasPriv(const Anope::string &name)
{
- for (int i = 0; defaultLevels[i].priv != CA_SIZE; ++i)
- if (defaultLevels[i].priv == priv)
- return this->ci->levels[priv] != ACCESS_INVALID && DetermineLevel(this) >= this->ci->levels[priv];
- return false;
+ return this->ci->GetLevel(name) != ACCESS_INVALID && this->level >= this->ci->GetLevel(name);
}
Anope::string Serialize()
@@ -118,11 +71,18 @@ class AccessChanAccess : public ChanAccess
else
{
int highest = 1;
- for (int i = 0; defaultLevels[i].priv != CA_SIZE; ++i)
- if (access->ci->levels[defaultLevels[i].priv] > highest && access->HasPriv(defaultLevels[i].priv))
- highest = access->ci->levels[defaultLevels[i].priv];
+ const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges();
+
+ for (unsigned i = 0; i < privs.size(); ++i)
+ {
+ const Privilege &p = privs[i];
+ if (access->ci->GetLevel(p.name) > highest && access->HasPriv(p.name))
+ highest = access->ci->GetLevel(p.name);
+ }
+
if (highest >= ACCESS_FOUNDER)
highest = ACCESS_FOUNDER - 1;
+
return highest;
}
}
@@ -232,7 +192,7 @@ class AccessDelCallback : public NumberList
public:
AccessDelCallback(CommandSource &_source, ChannelInfo *_ci, Command *_c, const Anope::string &numlist) : NumberList(numlist, true), source(_source), ci(_ci), c(_c), Deleted(0), Denied(false)
{
- if (!ci->AccessFor(source.u).HasPriv(CA_ACCESS_CHANGE) && source.u->HasPriv("chanserv/access/modify"))
+ if (!ci->AccessFor(source.u).HasPriv("ACCESS_CHANGE") && source.u->HasPriv("chanserv/access/modify"))
this->override = true;
}
@@ -318,7 +278,7 @@ class CommandCSAccess : public Command
return;
}
- bool override = !ci->AccessFor(u).HasPriv(CA_ACCESS_CHANGE) || (level >= u_level && !u_access.Founder);
+ bool override = !ci->AccessFor(u).HasPriv("ACCESS_CHANGE") || (level >= u_level && !u_access.Founder);
if (mask.find_first_of("!*@") == Anope::string::npos && findnick(mask) == NULL)
mask += "!*@*";
@@ -395,7 +355,7 @@ class CommandCSAccess : public Command
else
{
source.Reply(_("\002%s\002 deleted from %s access list."), access->mask.c_str(), ci->name.c_str());
- bool override = !u_access.Founder && !u_access.HasPriv(CA_ACCESS_CHANGE) && !access->mask.equals_ci(u->Account()->display);
+ bool override = !u_access.Founder && !u_access.HasPriv("ACCESS_CHANGE") && !access->mask.equals_ci(u->Account()->display);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DEL " << access->mask;
FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, access));
@@ -544,9 +504,9 @@ class CommandCSAccess : public Command
bool has_access = false;
if (u->HasPriv("chanserv/access/modify"))
has_access = true;
- else if (is_list && ci->AccessFor(u).HasPriv(CA_ACCESS_LIST))
+ else if (is_list && ci->AccessFor(u).HasPriv("ACCESS_LIST"))
has_access = true;
- else if (ci->AccessFor(u).HasPriv(CA_ACCESS_CHANGE))
+ else if (ci->AccessFor(u).HasPriv("ACCESS_CHANGE"))
has_access = true;
else if (is_del)
{
@@ -676,30 +636,23 @@ class CommandCSLevels : public Command
source.Reply(_("Level must be between %d and %d inclusive."), ACCESS_INVALID + 1, ACCESS_FOUNDER - 1);
else
{
- for (int i = 0; defaultLevels[i].priv != CA_SIZE; ++i)
+ Privilege *p = PrivilegeManager::FindPrivilege(what);
+ if (p == NULL)
+ source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS \002 for a list of valid settings."), what.c_str(), Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str());
+ else
{
- AccessLevels &l = defaultLevels[i];
+ ci->SetLevel(p->name, level);
+ FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, p->name, level));
- if (what.equals_ci(l.name))
- {
- ci->levels[l.priv] = level;
- FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, i, level));
-
- bool override = !ci->AccessFor(u).HasPriv(CA_FOUNDER);
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "SET " << l.name << " to " << level;
+ bool override = !ci->AccessFor(u).HasPriv("FOUNDER");
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "SET " << p->name << " to " << level;
- if (level == ACCESS_FOUNDER)
- source.Reply(_("Level for %s on channel %s changed to founder only."), l.name.c_str(), ci->name.c_str());
- else
- source.Reply(_("Level for \002%s\002 on channel %s changed to \002%d\002."), l.name.c_str(), ci->name.c_str(), level);
- return;
- }
+ if (level == ACCESS_FOUNDER)
+ source.Reply(_("Level for %s on channel %s changed to founder only."), p->name.c_str(), ci->name.c_str());
+ else
+ source.Reply(_("Level for \002%s\002 on channel %s changed to \002%d\002."), p->name.c_str(), ci->name.c_str(), level);
}
-
- source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS \002 for a list of valid settings."), what.c_str(), Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str());
}
-
- return;
}
void DoDisable(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
@@ -710,22 +663,20 @@ class CommandCSLevels : public Command
/* Don't allow disabling of the founder level. It would be hard to change it back if you dont have access to use this command */
if (!what.equals_ci("FOUNDER"))
- for (int i = 0; defaultLevels[i].priv != CA_SIZE; ++i)
+ {
+ Privilege *p = PrivilegeManager::FindPrivilege(what);
+ if (p != NULL)
{
- AccessLevels &l = defaultLevels[i];
-
- if (what.equals_ci(l.name))
- {
- ci->levels[l.priv] = ACCESS_INVALID;
- FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, i, l.priv));
+ ci->SetLevel(p->name, ACCESS_INVALID);
+ FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, p->name, ACCESS_INVALID));
- bool override = !ci->AccessFor(u).HasPriv(CA_FOUNDER);
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DISABLE " << l.name;
+ bool override = !ci->AccessFor(u).HasPriv("FOUNDER");
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DISABLE " << p->name;
- source.Reply(_("\002%s\002 disabled on channel %s."), l.name.c_str(), ci->name.c_str());
- return;
- }
+ source.Reply(_("\002%s\002 disabled on channel %s."), p->name.c_str(), ci->name.c_str());
+ return;
}
+ }
source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS \002 for a list of valid settings."), what.c_str(), Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str());
@@ -736,30 +687,29 @@ class CommandCSLevels : public Command
{
source.Reply(_("Access level settings for channel %s:"), ci->name.c_str());
+ const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges();
if (!levelinfo_maxwidth)
- for (int i = 0; defaultLevels[i].priv != CA_SIZE; ++i)
+ for (unsigned i = 0; i < privs.size(); ++i)
{
- AccessLevels &l = defaultLevels[i];
+ const Privilege &p = privs[i];
- int len = l.name.length();
+ int len = p.name.length();
if (len > levelinfo_maxwidth)
levelinfo_maxwidth = len;
}
- for (int i = 0; defaultLevels[i].priv != CA_SIZE; ++i)
+ for (unsigned i = 0; i < privs.size(); ++i)
{
- AccessLevels &l = defaultLevels[i];
- int j = ci->levels[l.priv];
+ const Privilege &p = privs[i];
+ int16 j = ci->GetLevel(p.name);
if (j == ACCESS_INVALID)
- source.Reply(_(" %-*s (disabled)"), levelinfo_maxwidth, l.name.c_str());
+ source.Reply(_(" %-*s (disabled)"), levelinfo_maxwidth, p.name.c_str());
else if (j == ACCESS_FOUNDER)
- source.Reply(_(" %-*s (founder only)"), levelinfo_maxwidth, l.name.c_str());
+ source.Reply(_(" %-*s (founder only)"), levelinfo_maxwidth, p.name.c_str());
else
- source.Reply(_(" %-*s %d"), levelinfo_maxwidth, l.name.c_str(), j);
+ source.Reply(_(" %-*s %d"), levelinfo_maxwidth, p.name.c_str(), j);
}
-
- return;
}
void DoReset(CommandSource &source, ChannelInfo *ci)
@@ -767,9 +717,9 @@ class CommandCSLevels : public Command
User *u = source.u;
reset_levels(ci);
- FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, -1, 0));
+ FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, "ALL", 0));
- bool override = !ci->AccessFor(u).HasPriv(CA_FOUNDER);
+ bool override = !ci->AccessFor(u).HasPriv("FOUNDER");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "RESET";
source.Reply(_("Access levels for \002%s\002 reset to defaults."), ci->name.c_str());
@@ -806,7 +756,7 @@ class CommandCSLevels : public Command
*/
if (cmd.equals_ci("SET") ? s.empty() : (cmd.substr(0, 3).equals_ci("DIS") ? (what.empty() || !s.empty()) : !what.empty()))
this->OnSyntaxError(source, cmd);
- else if (!ci->AccessFor(u).HasPriv(CA_FOUNDER) && !u->HasPriv("chanserv/access/modify"))
+ else if (!ci->AccessFor(u).HasPriv("FOUNDER") && !u->HasPriv("chanserv/access/modify"))
source.Reply(ACCESS_DENIED);
else if (cmd.equals_ci("SET"))
this->DoSet(source, ci, params);
@@ -827,19 +777,20 @@ class CommandCSLevels : public Command
if (subcommand.equals_ci("DESC"))
{
source.Reply(_("The following feature/function names are understood."));
+ const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges();
if (!levelinfo_maxwidth)
- for (int i = 0; defaultLevels[i].priv != CA_SIZE; ++i)
+ for (unsigned i = 0; i < privs.size(); ++i)
{
- AccessLevels &l = defaultLevels[i];
+ const Privilege &p = privs[i];
- int len = l.name.length();
+ int len = p.name.length();
if (len > levelinfo_maxwidth)
levelinfo_maxwidth = len;
}
- for (int i = 0; defaultLevels[i].priv != CA_SIZE; ++i)
+ for (unsigned i = 0; i < privs.size(); ++i)
{
- AccessLevels &l = defaultLevels[i];
- source.Reply(_(" %-*s %s"), levelinfo_maxwidth, l.name.c_str(), translate(source.u, l.desc.c_str()));
+ const Privilege &p = privs[i];
+ source.Reply(_(" %-*s %s"), levelinfo_maxwidth, p.name.c_str(), translate(source.u, p.desc.c_str()));
}
}
else
@@ -883,33 +834,41 @@ class CSAccess : public Module
this->SetAuthor("Anope");
- Implementation i[] = { I_OnReload, I_OnChanRegistered, I_OnCreateChan, I_OnGroupCheckPriv };
+ Implementation i[] = { I_OnReload, I_OnCreateChan, I_OnGroupCheckPriv };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
- this->OnReload();
+ try
+ {
+ this->OnReload();
+ }
+ catch (const ConfigException &ex)
+ {
+ throw ModuleException(ex.GetReason());
+ }
}
void OnReload()
{
+ std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges();
+ std::map<Anope::string, int16> tLevels;
ConfigReader config;
- for (int i = 0; defaultLevels[i].priv != CA_SIZE; ++i)
+ for (unsigned i = 0; i < privs.size(); ++i)
{
- AccessLevels &l = defaultLevels[i];
+ Privilege &p = privs[i];
- const Anope::string &value = config.ReadValue("chanserv", l.config_name, "", 0);
- if (value.equals_ci("founder"))
- l.default_level = ACCESS_FOUNDER;
+ const Anope::string &value = config.ReadValue("chanserv", "level_" + p.name.lower(), "", 0);
+ if (value.empty())
+ throw ConfigException("The value for <chanserv:level_" + p.name.lower() + "> must not be empty!");
+ else if (value.equals_ci("founder"))
+ tLevels[p.name] = ACCESS_FOUNDER;
else if (value.equals_ci("disabled"))
- l.default_level = ACCESS_INVALID;
+ tLevels[p.name] = ACCESS_INVALID;
else
- l.default_level = config.ReadInteger("chanserv", l.config_name, 0, false);
+ tLevels[p.name] = config.ReadInteger("chanserv", "level_" + p.name.lower(), 0, false);
}
- }
- void OnChanRegistered(ChannelInfo *ci)
- {
- reset_levels(ci);
+ defaultLevels = tLevels;
}
void OnCreateChan(ChannelInfo *ci)
@@ -917,12 +876,12 @@ class CSAccess : public Module
reset_levels(ci);
}
- EventReturn OnGroupCheckPriv(const AccessGroup *group, ChannelAccess priv)
+ EventReturn OnGroupCheckPriv(const AccessGroup *group, const Anope::string &priv)
{
if (group->ci == NULL)
return EVENT_CONTINUE;
/* Special case. Allows a level of < 0 to match anyone, and a level of 0 to match anyone identified. */
- int16 level = group->ci->levels[priv];
+ int16 level = group->ci->GetLevel(priv);
if (level < 0)
return EVENT_ALLOW;
else if (level == 0 && group->nc)
diff --git a/modules/commands/cs_akick.cpp b/modules/commands/cs_akick.cpp
index 594544e22..86c245059 100644
--- a/modules/commands/cs_akick.cpp
+++ b/modules/commands/cs_akick.cpp
@@ -134,7 +134,7 @@ class AkickDelCallback : public NumberList
~AkickDelCallback()
{
User *u = source.u;
- bool override = !ci->AccessFor(u).HasPriv(CA_AKICK);
+ bool override = !ci->AccessFor(u).HasPriv("AKICK");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, c, ci) << "DEL on " << Deleted << " users";
if (!Deleted)
@@ -213,7 +213,7 @@ class CommandCSAKick : public Command
AccessGroup nc_access = ci->AccessFor(nc), u_access = ci->AccessFor(u);
Entry entry_mask(CMODE_BEGIN, mask);
- if ((ci->AccessFor(u2).HasPriv(CA_FOUNDER) || nc_access >= u_access) && entry_mask.Matches(u2))
+ if ((ci->AccessFor(u2).HasPriv("FOUNDER") || nc_access >= u_access) && entry_mask.Matches(u2))
{
source.Reply(ACCESS_DENIED);
return;
@@ -260,7 +260,7 @@ class CommandCSAKick : public Command
else
akick = ci->AddAkick(u->nick, mask, reason);
- bool override = !ci->AccessFor(u).HasPriv(CA_AKICK);
+ bool override = !ci->AccessFor(u).HasPriv("AKICK");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << mask << ": " << reason;
FOREACH_MOD(I_OnAkickAdd, OnAkickAdd(u, ci, akick));
@@ -309,7 +309,7 @@ class CommandCSAKick : public Command
return;
}
- bool override = !ci->AccessFor(u).HasPriv(CA_AKICK);
+ bool override = !ci->AccessFor(u).HasPriv("AKICK");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DEL " << mask;
ci->EraseAkick(i);
@@ -324,7 +324,7 @@ class CommandCSAKick : public Command
const Anope::string &mask = params.size() > 2 ? params[2] : "";
- bool override = !ci->AccessFor(u).HasPriv(CA_AKICK);
+ bool override = !ci->AccessFor(u).HasPriv("AKICK");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "LIST";
if (!ci->GetAkickCount())
@@ -374,7 +374,7 @@ class CommandCSAKick : public Command
const Anope::string &mask = params.size() > 2 ? params[2] : "";
- bool override = !ci->AccessFor(u).HasPriv(CA_AKICK);
+ bool override = !ci->AccessFor(u).HasPriv("AKICK");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "VIEW";
if (!ci->GetAkickCount())
@@ -438,7 +438,7 @@ class CommandCSAKick : public Command
++count;
}
- bool override = !ci->AccessFor(u).HasPriv(CA_AKICK);
+ bool override = !ci->AccessFor(u).HasPriv("AKICK");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ENFORCE, affects " << count << " users";
source.Reply(_("AKICK ENFORCE for \002%s\002 complete; \002%d\002 users were affected."), ci->name.c_str(), count);
@@ -447,7 +447,7 @@ class CommandCSAKick : public Command
void DoClear(CommandSource &source, ChannelInfo *ci)
{
User *u = source.u;
- bool override = !ci->AccessFor(u).HasPriv(CA_AKICK);
+ bool override = !ci->AccessFor(u).HasPriv("AKICK");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "CLEAR";
ci->ClearAkick();
@@ -483,7 +483,7 @@ class CommandCSAKick : public Command
if (mask.empty() && (cmd.equals_ci("ADD") || cmd.equals_ci("DEL")))
this->OnSyntaxError(source, cmd);
- else if (!ci->AccessFor(u).HasPriv(CA_AKICK) && !u->HasPriv("chanserv/access/modify"))
+ else if (!ci->AccessFor(u).HasPriv("AKICK") && !u->HasPriv("chanserv/access/modify"))
source.Reply(ACCESS_DENIED);
else if (!cmd.equals_ci("LIST") && !cmd.equals_ci("VIEW") && !cmd.equals_ci("ENFORCE") && readonly)
source.Reply(_("Sorry, channel autokick list modification is temporarily disabled."));
diff --git a/modules/commands/cs_appendtopic.cpp b/modules/commands/cs_appendtopic.cpp
index bc4db7cba..013e91046 100644
--- a/modules/commands/cs_appendtopic.cpp
+++ b/modules/commands/cs_appendtopic.cpp
@@ -58,7 +58,7 @@ class CommandCSAppendTopic : public Command
source.Reply(CHAN_X_NOT_IN_USE, params[0].c_str());
else if (!c->ci)
source.Reply(CHAN_X_NOT_REGISTERED, c->name.c_str());
- else if (!c->ci->AccessFor(u).HasPriv(CA_TOPIC))
+ else if (!c->ci->AccessFor(u).HasPriv("TOPIC"))
source.Reply(ACCESS_DENIED);
else
{
@@ -77,7 +77,7 @@ class CommandCSAppendTopic : public Command
if (has_topiclock)
c->ci->SetFlag(CI_TOPICLOCK);
- bool override = c->ci->AccessFor(u).HasPriv(CA_TOPIC);
+ bool override = c->ci->AccessFor(u).HasPriv("TOPIC");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, c->ci) << "changed topic to " << topic;
}
return;
diff --git a/modules/commands/cs_ban.cpp b/modules/commands/cs_ban.cpp
index 0aae3f9bd..cb4066aca 100644
--- a/modules/commands/cs_ban.cpp
+++ b/modules/commands/cs_ban.cpp
@@ -46,7 +46,7 @@ class CommandCSBan : public Command
source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
else if (!u2)
source.Reply(NICK_X_NOT_IN_USE, target.c_str());
- else if (!ci->AccessFor(u).HasPriv(CA_BAN))
+ else if (!ci->AccessFor(u).HasPriv("BAN"))
source.Reply(ACCESS_DENIED);
else if (!is_same && ci->HasFlag(CI_PEACE) && u2_access >= u_access)
source.Reply(ACCESS_DENIED);
@@ -72,7 +72,7 @@ class CommandCSBan : public Command
if (!c->FindUser(u2))
return;
- if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !ci->AccessFor(u).HasPriv(CA_SIGNKICK)))
+ if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !ci->AccessFor(u).HasPriv("SIGNKICK")))
c->Kick(ci->WhoSends(), u2, "%s (%s)", reason.c_str(), u->nick.c_str());
else
c->Kick(ci->WhoSends(), u2, "%s", reason.c_str());
diff --git a/modules/commands/cs_clearusers.cpp b/modules/commands/cs_clearusers.cpp
index e8f47bac4..b89a68e6e 100644
--- a/modules/commands/cs_clearusers.cpp
+++ b/modules/commands/cs_clearusers.cpp
@@ -34,7 +34,7 @@ class CommandCSClearUsers : public Command
source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
else if (!c->ci)
source.Reply(CHAN_X_NOT_REGISTERED, c->name.c_str());
- else if (!c->ci->AccessFor(u).HasPriv(CA_FOUNDER))
+ else if (!c->ci->AccessFor(u).HasPriv("FOUNDER"))
{
source.Reply(ACCESS_DENIED);
return;
diff --git a/modules/commands/cs_clone.cpp b/modules/commands/cs_clone.cpp
index 8a242c532..6f67f01a0 100644
--- a/modules/commands/cs_clone.cpp
+++ b/modules/commands/cs_clone.cpp
@@ -36,7 +36,7 @@ public:
return;
}
- if (!ci->AccessFor(u).HasPriv(CA_SET))
+ if (!ci->AccessFor(u).HasPriv("SET"))
{
source.Reply(ACCESS_DENIED);
return;
diff --git a/modules/commands/cs_drop.cpp b/modules/commands/cs_drop.cpp
index 7056f5c35..dd7c9fa2e 100644
--- a/modules/commands/cs_drop.cpp
+++ b/modules/commands/cs_drop.cpp
@@ -47,7 +47,7 @@ class CommandCSDrop : public Command
return;
}
- if ((ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !ci->AccessFor(u).HasPriv(CA_FOUNDER)) && !u->HasCommand("chanserv/drop"))
+ if ((ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !ci->AccessFor(u).HasPriv("FOUNDER")) && !u->HasCommand("chanserv/drop"))
{
source.Reply(ACCESS_DENIED);
return;
@@ -56,7 +56,7 @@ class CommandCSDrop : public Command
if (ci->c && ModeManager::FindChannelModeByName(CMODE_REGISTERED))
ci->c->RemoveMode(NULL, CMODE_REGISTERED, "", false);
- bool override = (ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !ci->AccessFor(u).HasPriv(CA_FOUNDER));
+ bool override = (ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !ci->AccessFor(u).HasPriv("FOUNDER"));
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "founder: " << (ci->GetFounder() ? ci->GetFounder()->display : "none");
delete ci;
diff --git a/modules/commands/cs_enforce.cpp b/modules/commands/cs_enforce.cpp
index 78a2a9950..f64c7776d 100644
--- a/modules/commands/cs_enforce.cpp
+++ b/modules/commands/cs_enforce.cpp
@@ -129,7 +129,7 @@ class CommandCSEnforce : public Command
source.Reply(CHAN_X_NOT_IN_USE, params[0].c_str());
else if (!c->ci)
source.Reply(CHAN_X_NOT_REGISTERED, c->name.c_str());
- else if (!c->ci->AccessFor(u).HasPriv(CA_AKICK))
+ else if (!c->ci->AccessFor(u).HasPriv("AKICK"))
source.Reply(ACCESS_DENIED);
else
{
diff --git a/modules/commands/cs_flags.cpp b/modules/commands/cs_flags.cpp
index 8bec73ae0..64ecb7323 100644
--- a/modules/commands/cs_flags.cpp
+++ b/modules/commands/cs_flags.cpp
@@ -13,51 +13,7 @@
#include "module.h"
-static struct FlagLevels
-{
- ChannelAccess priv;
- char default_char;
- Anope::string config_name;
- Anope::string desc;
-} flagLevels[] = {
- { CA_ACCESS_CHANGE, 'f', "flag_change", _("Allowed to modify the access list") },
- { CA_ACCESS_LIST, 'l', "flag_list", _("Allowed to view the access list") },
- { CA_AKICK, 'K', "flag_akick", _("Allowed to use AKICK command") },
- { CA_ASSIGN, 's', "flag_assign", _("Allowed to assign/unassign a bot") },
- { CA_AUTOHALFOP, 'H', "flag_autohalfop", _("Automatic mode +h") },
- { CA_AUTOOP, 'O', "flag_autoop", _("Automatic channel operator status") },
- { CA_AUTOOWNER, 'Q', "flag_autoowner", _("Automatic mode +q") },
- { CA_AUTOPROTECT, 'A', "flag_autoprotect", _("Automatic mode +a") },
- { CA_AUTOVOICE, 'V', "flag_autovoice", _("Automatic mode +v") },
- { CA_BADWORDS, 'k', "flag_badwords", _("Allowed to modify channel badwords list") },
- { CA_BAN, 'b', "flag_ban", _("Allowed to use ban users") },
- { CA_FANTASIA, 'c', "flag_fantasia", _("Allowed to use fantasy commands") },
- { CA_FOUNDER, 'F', "flag_founder", _("Allowed to issue commands restricted to channel founders") },
- { CA_GETKEY, 'G', "flag_getkey", _("Allowed to use GETKEY command") },
- { CA_GREET, 'g', "flag_greet", _("Greet message displayed") },
- { CA_HALFOP, 'h', "flag_halfop", _("Allowed to (de)halfop users") },
- { CA_HALFOPME, 'h', "flag_halfopme", _("Allowed to (de)halfop him/herself") },
- { CA_INFO, 'I', "flag_info", _("Allowed to use INFO command with ALL option") },
- { CA_INVITE, 'i', "flag_invite", _("Allowed to use the INVITE command") },
- { CA_KICK, 'k', "flag_kick", _("Allowed to use the KICK command") },
- { CA_MEMO, 'm', "flag_memo", _("Allowed to read channel memos") },
- { CA_MODE, 's', "flag_mode", _("Allowed to change channel modes") },
- { CA_NOKICK, 'N', "flag_nokick", _("Prevents users being kicked by Services") },
- { CA_OPDEOP, 'o', "flag_opdeop", _("Allowed to (de)op users") },
- { CA_OPDEOPME, 'o', "flag_opdeopme", _("Allowed to (de)op him/herself") },
- { CA_OWNER, 'q', "flag_owner", _("Allowed to use (de)owner users") },
- { CA_OWNERME, 'q', "flag_ownerme", _("Allowed to (de)owner him/herself") },
- { CA_PROTECT, 'a', "flag_protect", _("Allowed to (de)protect users") },
- { CA_PROTECTME, 'a', "flag_protectme", _("Allowed to (de)protect him/herself"), },
- { CA_SAY, 'B', "flag_say", _("Allowed to use SAY and ACT commands") },
- { CA_SET, 's', "flag_set", _("Allowed to set channel settings") },
- { CA_SIGNKICK, 'K', "flag_signkick", _("Prevents kicks from being signed") },
- { CA_TOPIC, 't', "flag_topic", _("Allowed to change channel topics") },
- { CA_UNBAN, 'u', "flag_unban", _("Allowed to unban users") },
- { CA_VOICE, 'v', "flag_voice", _("Allowed to (de)voice users") },
- { CA_VOICEME, 'v', "flag_voiceme", _("Allowed to (de)voice him/herself") },
- { CA_SIZE, -1, "", "" }
-};
+static std::map<Anope::string, char> defaultFlags;
class FlagsChanAccess : public ChanAccess
{
@@ -77,12 +33,11 @@ class FlagsChanAccess : public ChanAccess
return false;
}
- bool HasPriv(ChannelAccess priv)
+ bool HasPriv(const Anope::string &priv)
{
- for (int i = 0; flagLevels[i].priv != CA_SIZE; ++i)
- if (flagLevels[i].priv == priv)
- return this->flags.count(flagLevels[i].default_char);
-
+ std::map<Anope::string, char>::iterator it = defaultFlags.find(priv);
+ if (it != defaultFlags.end() && this->flags.count(it->second) > 0)
+ return true;
return false;
}
@@ -104,13 +59,9 @@ class FlagsChanAccess : public ChanAccess
std::set<char> buffer;
- for (int i = 0; flagLevels[i].priv != CA_SIZE; ++i)
- {
- FlagLevels &l = flagLevels[i];
-
- if (access->HasPriv(l.priv))
- buffer.insert(l.default_char);
- }
+ for (std::map<Anope::string, char>::iterator it = defaultFlags.begin(), it_end = defaultFlags.end(); it != it_end; ++it)
+ if (access->HasPriv(it->first))
+ buffer.insert(it->second);
return Anope::string(buffer.begin(), buffer.end());
}
@@ -186,10 +137,9 @@ class CommandCSFlags : public Command
case '*':
if (add == -1)
break;
- for (int j = 0; flagLevels[j].priv != CA_SIZE; ++j)
+ for (std::map<Anope::string, char>::iterator it = defaultFlags.begin(), it_end = defaultFlags.end(); it != it_end; ++it)
{
- FlagLevels &l = flagLevels[j];
- if (!u_access.HasPriv(l.priv))
+ if (!u_access.HasPriv(it->first))
{
if (u->HasPriv("chanserv/access/modify"))
override = true;
@@ -197,20 +147,19 @@ class CommandCSFlags : public Command
continue;
}
if (add == 1)
- current_flags.insert(l.default_char);
+ current_flags.insert(it->second);
else if (add == 0)
- current_flags.erase(l.default_char);
+ current_flags.erase(it->second);
}
break;
default:
if (add == -1)
break;
- for (int j = 0; flagLevels[j].priv != CA_SIZE; ++j)
+ for (std::map<Anope::string, char>::iterator it = defaultFlags.begin(), it_end = defaultFlags.end(); it != it_end; ++it)
{
- FlagLevels &l = flagLevels[j];
- if (f != l.default_char)
+ if (f != it->second)
continue;
- else if (!u_access.HasPriv(l.priv))
+ else if (!u_access.HasPriv(it->first))
{
if (u->HasPriv("chanserv/access/modify"))
override = true;
@@ -361,9 +310,9 @@ class CommandCSFlags : public Command
bool has_access = false;
if (u->HasPriv("chanserv/access/modify"))
has_access = true;
- else if (is_list && ci->AccessFor(u).HasPriv(CA_ACCESS_LIST))
+ else if (is_list && ci->AccessFor(u).HasPriv("ACCESS_LIST"))
has_access = true;
- else if (ci->AccessFor(u).HasPriv(CA_ACCESS_CHANGE))
+ else if (ci->AccessFor(u).HasPriv("ACCESS_CHANGE"))
has_access = true;
if (!has_access)
@@ -403,13 +352,17 @@ class CommandCSFlags : public Command
source.Reply(" ");
source.Reply(_("The available flags are:"));
- std::multimap<char, FlagLevels *, std::less<ci::string> > levels;
- for (int i = 0; flagLevels[i].priv != CA_SIZE; ++i)
- levels.insert(std::make_pair(flagLevels[i].default_char, &flagLevels[i]));
- for (std::multimap<char, FlagLevels *, std::less<ci::string> >::iterator it = levels.begin(), it_end = levels.end(); it != it_end; ++it)
+ typedef std::multimap<char, Anope::string, std::less<ci::string> > reverse_map;
+ reverse_map reverse;
+ for (std::map<Anope::string, char>::iterator it = defaultFlags.begin(), it_end = defaultFlags.end(); it != it_end; ++it)
+ reverse.insert(std::make_pair(it->second, it->first));
+
+ for (reverse_map::iterator it = reverse.begin(), it_end = reverse.end(); it != it_end; ++it)
{
- FlagLevels *l = it->second;
- source.Reply(" %c - %s", l->default_char, translate(source.u->Account(), l->desc.c_str()));
+ Privilege *p = PrivilegeManager::FindPrivilege(it->second);
+ if (p == NULL)
+ continue;
+ source.Reply(" %c - %s", it->first, translate(source.u->Account(), p->desc.c_str()));
}
return true;
@@ -437,15 +390,15 @@ class CSFlags : public Module
void OnReload()
{
ConfigReader config;
+ std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges();
- for (int i = 0; flagLevels[i].priv != CA_SIZE; ++i)
+ for (unsigned i = 0; i < privs.size(); ++i)
{
- FlagLevels &l = flagLevels[i];
-
- const Anope::string &value = config.ReadValue("chanserv", l.config_name, "", 0);
+ Privilege &p = privs[i];
+ const Anope::string &value = config.ReadValue("chanserv", "flag_" + p.name, "", 0);
if (value.empty())
continue;
- l.default_char = value[0];
+ defaultFlags[p.name] = value[0];
}
}
};
diff --git a/modules/commands/cs_getkey.cpp b/modules/commands/cs_getkey.cpp
index cfb148134..680745170 100644
--- a/modules/commands/cs_getkey.cpp
+++ b/modules/commands/cs_getkey.cpp
@@ -35,7 +35,7 @@ class CommandCSGetKey : public Command
}
- if (!ci->AccessFor(u).HasPriv(CA_GETKEY) && !u->HasCommand("chanserv/getkey"))
+ if (!ci->AccessFor(u).HasPriv("GETKEY") && !u->HasCommand("chanserv/getkey"))
{
source.Reply(ACCESS_DENIED);
return;
@@ -48,7 +48,7 @@ class CommandCSGetKey : public Command
return;
}
- bool override = !ci->AccessFor(u).HasPriv(CA_GETKEY);
+ bool override = !ci->AccessFor(u).HasPriv("GETKEY");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci);
source.Reply(_("Key for channel \002%s\002 is \002%s\002."), chan.c_str(), key.c_str());
diff --git a/modules/commands/cs_info.cpp b/modules/commands/cs_info.cpp
index 54f14cd0c..5fc85666a 100644
--- a/modules/commands/cs_info.cpp
+++ b/modules/commands/cs_info.cpp
@@ -50,7 +50,7 @@ class CommandCSInfo : public Command
bool show_all = false;
/* Should we show all fields? Only for sadmins and identified users */
- if (has_auspex || ci->AccessFor(u).HasPriv(CA_INFO))
+ if (has_auspex || ci->AccessFor(u).HasPriv("INFO"))
show_all = true;
source.Reply(CHAN_INFO_HEADER, chan.c_str());
diff --git a/modules/commands/cs_invite.cpp b/modules/commands/cs_invite.cpp
index f6ed44685..122171b90 100644
--- a/modules/commands/cs_invite.cpp
+++ b/modules/commands/cs_invite.cpp
@@ -42,7 +42,7 @@ class CommandCSInvite : public Command
return;
}
- if (!ci->AccessFor(u).HasPriv(CA_INVITE))
+ if (!ci->AccessFor(u).HasPriv("INVITE"))
{
source.Reply(ACCESS_DENIED);
return;
diff --git a/modules/commands/cs_kick.cpp b/modules/commands/cs_kick.cpp
index b9c0f7b41..c00025671 100644
--- a/modules/commands/cs_kick.cpp
+++ b/modules/commands/cs_kick.cpp
@@ -42,7 +42,7 @@ class CommandCSKick : public Command
source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
else if (!u2)
source.Reply(NICK_X_NOT_IN_USE, target.c_str());
- else if (!ci->AccessFor(u).HasPriv(CA_KICK))
+ else if (!ci->AccessFor(u).HasPriv("KICK"))
source.Reply(ACCESS_DENIED);
else if (!is_same && (ci->HasFlag(CI_PEACE)) && u2_access >= u_access)
source.Reply(ACCESS_DENIED);
@@ -55,7 +55,7 @@ class CommandCSKick : public Command
// XXX
Log(LOG_COMMAND, u, this, ci) << "for " << u2->nick;
- if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !ci->AccessFor(u).HasPriv(CA_SIGNKICK)))
+ if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !ci->AccessFor(u).HasPriv("SIGNKICK")))
ci->c->Kick(ci->WhoSends(), u2, "%s (%s)", reason.c_str(), u->nick.c_str());
else
ci->c->Kick(ci->WhoSends(), u2, "%s", reason.c_str());
diff --git a/modules/commands/cs_mode.cpp b/modules/commands/cs_mode.cpp
index 3e4ed784c..a36e68690 100644
--- a/modules/commands/cs_mode.cpp
+++ b/modules/commands/cs_mode.cpp
@@ -20,13 +20,13 @@ class CommandCSMode : public Command
if (!u || !ci || !cm || cm->Type != MODE_STATUS)
return false;
- const ChannelAccess accesses[] = { CA_VOICE, CA_HALFOP, CA_OPDEOP, CA_PROTECT, CA_OWNER, CA_SIZE };
+ const Anope::string accesses[] = { "VOICE", "HALFOP", "OPDEOP", "PROTECT", "OWNER", "" };
const ChannelModeName modes[] = { CMODE_VOICE, CMODE_HALFOP, CMODE_OP, CMODE_PROTECT, CMODE_OWNER };
ChannelModeStatus *cms = debug_cast<ChannelModeStatus *>(cm);
AccessGroup access = ci->AccessFor(u);
unsigned short u_level = 0;
- for (int i = 0; accesses[i] != CA_SIZE; ++i)
+ for (int i = 0; !accesses[i].empty(); ++i)
if (access.HasPriv(accesses[i]))
{
ChannelMode *cm2 = ModeManager::FindChannelModeByName(modes[i]);
@@ -319,7 +319,7 @@ class CommandCSMode : public Command
if (!ci || !ci->c)
source.Reply(CHAN_X_NOT_IN_USE, params[0].c_str());
- else if (!ci->AccessFor(u).HasPriv(CA_MODE) && !u->HasCommand("chanserv/mode"))
+ else if (!ci->AccessFor(u).HasPriv("MODE") && !u->HasCommand("chanserv/mode"))
source.Reply(ACCESS_DENIED);
else if (subcommand.equals_ci("LOCK"))
this->DoLock(source, ci, params);
diff --git a/modules/commands/cs_modes.cpp b/modules/commands/cs_modes.cpp
index fb2fcb727..a393ecaf9 100644
--- a/modules/commands/cs_modes.cpp
+++ b/modules/commands/cs_modes.cpp
@@ -15,7 +15,7 @@
class CommandModeBase : public Command
{
- void do_mode(CommandSource &source, Command *com, ChannelMode *cm, const Anope::string &chan, const Anope::string &nick, bool set, ChannelAccess level, ChannelAccess levelself)
+ void do_mode(CommandSource &source, Command *com, ChannelMode *cm, const Anope::string &chan, const Anope::string &nick, bool set, const Anope::string &level, const Anope::string &levelself)
{
User *u = source.u;
User *u2 = finduser(nick);
@@ -62,7 +62,7 @@ class CommandModeBase : public Command
* @param level The acecss level required to set this mode on someone else
* @param levelself The access level required to set this mode on yourself
*/
- void do_util(CommandSource &source, Command *com, ChannelMode *cm, const Anope::string &chan, const Anope::string &nick, bool set, ChannelAccess level, ChannelAccess levelself)
+ void do_util(CommandSource &source, Command *com, ChannelMode *cm, const Anope::string &chan, const Anope::string &nick, bool set, const Anope::string &level, const Anope::string &levelself)
{
User *u = source.u;
@@ -94,7 +94,7 @@ class CommandCSOp : public CommandModeBase
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OP);
- return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, CA_OPDEOP, CA_OPDEOPME);
+ return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, "OPDEOP", "OPDEOPME");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
@@ -123,7 +123,7 @@ class CommandCSDeOp : public CommandModeBase
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OP);
- return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, CA_OPDEOP, CA_OPDEOPME);
+ return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, "OPDEOP", "OPDEOPME");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
@@ -152,7 +152,7 @@ class CommandCSVoice : public CommandModeBase
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_VOICE);
- return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, CA_VOICE, CA_VOICEME);
+ return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, "VOICE", "VOICEME");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
@@ -182,7 +182,7 @@ class CommandCSDeVoice : public CommandModeBase
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_VOICE);
- return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, CA_VOICE, CA_VOICEME);
+ return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, "VOICE", "VOICEME");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
@@ -215,7 +215,7 @@ class CommandCSHalfOp : public CommandModeBase
if (!cm)
return;
- return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, CA_HALFOP, CA_HALFOPME);
+ return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, "HALFOP", "HALFOPME");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
@@ -247,7 +247,7 @@ class CommandCSDeHalfOp : public CommandModeBase
if (!cm)
return;
- return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, CA_HALFOP, CA_HALFOPME);
+ return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, "HALFOP", "HALFOPME");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
@@ -280,7 +280,7 @@ class CommandCSProtect : public CommandModeBase
if (!cm)
return;
- return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, CA_PROTECT, CA_PROTECTME);
+ return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, "PROTECT", "PROTECTME");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
@@ -312,7 +312,7 @@ class CommandCSDeProtect : public CommandModeBase
if (!cm)
return;
- return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, CA_PROTECT, CA_PROTECTME);
+ return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, "PROTECT", "PROTECTME");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
@@ -343,7 +343,7 @@ class CommandCSOwner : public CommandModeBase
if (!cm)
return;
- return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, CA_OWNER, CA_OWNERME);
+ return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, "OWNER", "OWNERME");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
@@ -374,7 +374,7 @@ class CommandCSDeOwner : public CommandModeBase
if (!cm)
return;
- return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, CA_OWNER, CA_OWNERME);
+ return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, "OWNER", "OWNERME");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
diff --git a/modules/commands/cs_saset_noexpire.cpp b/modules/commands/cs_saset_noexpire.cpp
index 1f645304a..52754215a 100644
--- a/modules/commands/cs_saset_noexpire.cpp
+++ b/modules/commands/cs_saset_noexpire.cpp
@@ -32,7 +32,7 @@ class CommandCSSASetNoexpire : public Command
return;
}
- if (source.permission.empty() && !ci->AccessFor(u).HasPriv(CA_SET))
+ if (source.permission.empty() && !ci->AccessFor(u).HasPriv("SET"))
{
source.Reply(ACCESS_DENIED);
return;
diff --git a/modules/commands/cs_set_bantype.cpp b/modules/commands/cs_set_bantype.cpp
index 468a3cb86..afc15963b 100644
--- a/modules/commands/cs_set_bantype.cpp
+++ b/modules/commands/cs_set_bantype.cpp
@@ -32,7 +32,7 @@ class CommandCSSetBanType : public Command
return;
}
- if (source.permission.empty() && !ci->AccessFor(u).HasPriv(CA_SET))
+ if (source.permission.empty() && !ci->AccessFor(u).HasPriv("SET"))
{
source.Reply(ACCESS_DENIED);
return;
diff --git a/modules/commands/cs_set_description.cpp b/modules/commands/cs_set_description.cpp
index acd30e68b..d65731273 100644
--- a/modules/commands/cs_set_description.cpp
+++ b/modules/commands/cs_set_description.cpp
@@ -32,7 +32,7 @@ class CommandCSSetDescription : public Command
return;
}
- if (source.permission.empty() && !ci->AccessFor(u).HasPriv(CA_SET))
+ if (source.permission.empty() && !ci->AccessFor(u).HasPriv("SET"))
{
source.Reply(ACCESS_DENIED);
return;
diff --git a/modules/commands/cs_set_founder.cpp b/modules/commands/cs_set_founder.cpp
index ac7ece637..7ef553a78 100644
--- a/modules/commands/cs_set_founder.cpp
+++ b/modules/commands/cs_set_founder.cpp
@@ -32,13 +32,13 @@ class CommandCSSetFounder : public Command
return;
}
- if (source.permission.empty() && !ci->AccessFor(u).HasPriv(CA_SET))
+ if (source.permission.empty() && !ci->AccessFor(u).HasPriv("SET"))
{
source.Reply(ACCESS_DENIED);
return;
}
- if (source.permission.empty() && (ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !ci->AccessFor(u).HasPriv(CA_FOUNDER)))
+ if (source.permission.empty() && (ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !ci->AccessFor(u).HasPriv("FOUNDER")))
{
source.Reply(ACCESS_DENIED);
return;
diff --git a/modules/commands/cs_set_keeptopic.cpp b/modules/commands/cs_set_keeptopic.cpp
index 58c88a73c..5227cde21 100644
--- a/modules/commands/cs_set_keeptopic.cpp
+++ b/modules/commands/cs_set_keeptopic.cpp
@@ -32,7 +32,7 @@ class CommandCSSetKeepTopic : public Command
return;
}
- if (source.permission.empty() && !ci->AccessFor(u).HasPriv(CA_SET))
+ if (source.permission.empty() && !ci->AccessFor(u).HasPriv("SET"))
{
source.Reply(ACCESS_DENIED);
return;
diff --git a/modules/commands/cs_set_misc.cpp b/modules/commands/cs_set_misc.cpp
index a64bbf6ea..61c8c163b 100644
--- a/modules/commands/cs_set_misc.cpp
+++ b/modules/commands/cs_set_misc.cpp
@@ -28,7 +28,7 @@ class CommandCSSetMisc : public Command
source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
- else if (source.permission.empty() && !ci->AccessFor(source.u).HasPriv(CA_SET))
+ else if (source.permission.empty() && !ci->AccessFor(source.u).HasPriv("SET"))
{
source.Reply(ACCESS_DENIED);
return;
diff --git a/modules/commands/cs_set_peace.cpp b/modules/commands/cs_set_peace.cpp
index a5bdd7cd5..32a452ddd 100644
--- a/modules/commands/cs_set_peace.cpp
+++ b/modules/commands/cs_set_peace.cpp
@@ -32,7 +32,7 @@ class CommandCSSetPeace : public Command
return;
}
- if (source.permission.empty() && !ci->AccessFor(u).HasPriv(CA_SET))
+ if (source.permission.empty() && !ci->AccessFor(u).HasPriv("SET"))
{
source.Reply(ACCESS_DENIED);
return;
diff --git a/modules/commands/cs_set_persist.cpp b/modules/commands/cs_set_persist.cpp
index 000389ef1..22766d1f5 100644
--- a/modules/commands/cs_set_persist.cpp
+++ b/modules/commands/cs_set_persist.cpp
@@ -32,7 +32,7 @@ class CommandCSSetPersist : public Command
return;
}
- if (source.permission.empty() && !ci->AccessFor(u).HasPriv(CA_SET))
+ if (source.permission.empty() && !ci->AccessFor(u).HasPriv("SET"))
{
source.Reply(ACCESS_DENIED);
return;
diff --git a/modules/commands/cs_set_private.cpp b/modules/commands/cs_set_private.cpp
index 39fd8b414..9902e765d 100644
--- a/modules/commands/cs_set_private.cpp
+++ b/modules/commands/cs_set_private.cpp
@@ -32,7 +32,7 @@ class CommandCSSetPrivate : public Command
return;
}
- if (source.permission.empty() && !ci->AccessFor(u).HasPriv(CA_SET))
+ if (source.permission.empty() && !ci->AccessFor(u).HasPriv("SET"))
{
source.Reply(ACCESS_DENIED);
return;
diff --git a/modules/commands/cs_set_restricted.cpp b/modules/commands/cs_set_restricted.cpp
index bc04297f1..afddff5f9 100644
--- a/modules/commands/cs_set_restricted.cpp
+++ b/modules/commands/cs_set_restricted.cpp
@@ -31,7 +31,7 @@ class CommandCSSetRestricted : public Command
return;
}
- if (source.permission.empty() && !ci->AccessFor(u).HasPriv(CA_SET))
+ if (source.permission.empty() && !ci->AccessFor(u).HasPriv("SET"))
{
source.Reply(ACCESS_DENIED);
return;
diff --git a/modules/commands/cs_set_secure.cpp b/modules/commands/cs_set_secure.cpp
index 63671588b..1980a9d1e 100644
--- a/modules/commands/cs_set_secure.cpp
+++ b/modules/commands/cs_set_secure.cpp
@@ -32,7 +32,7 @@ class CommandCSSetSecure : public Command
return;
}
- if (source.permission.empty() && !ci->AccessFor(u).HasPriv(CA_SET))
+ if (source.permission.empty() && !ci->AccessFor(u).HasPriv("SET"))
{
source.Reply(ACCESS_DENIED);
return;
diff --git a/modules/commands/cs_set_securefounder.cpp b/modules/commands/cs_set_securefounder.cpp
index 746555814..5a41c8ec6 100644
--- a/modules/commands/cs_set_securefounder.cpp
+++ b/modules/commands/cs_set_securefounder.cpp
@@ -33,7 +33,7 @@ class CommandCSSetSecureFounder : public Command
}
- if (source.permission.empty() && ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !ci->AccessFor(u).HasPriv(CA_FOUNDER))
+ if (source.permission.empty() && ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !ci->AccessFor(u).HasPriv("FOUNDER"))
{
source.Reply(ACCESS_DENIED);
return;
diff --git a/modules/commands/cs_set_secureops.cpp b/modules/commands/cs_set_secureops.cpp
index 3dcc7b301..1a8b04807 100644
--- a/modules/commands/cs_set_secureops.cpp
+++ b/modules/commands/cs_set_secureops.cpp
@@ -32,7 +32,7 @@ class CommandCSSetSecureOps : public Command
return;
}
- if (source.permission.empty() && !ci->AccessFor(u).HasPriv(CA_SET))
+ if (source.permission.empty() && !ci->AccessFor(u).HasPriv("SET"))
{
source.Reply(ACCESS_DENIED);
return;
diff --git a/modules/commands/cs_set_signkick.cpp b/modules/commands/cs_set_signkick.cpp
index 3a4177b83..0eb372141 100644
--- a/modules/commands/cs_set_signkick.cpp
+++ b/modules/commands/cs_set_signkick.cpp
@@ -32,7 +32,7 @@ class CommandCSSetSignKick : public Command
return;
}
- if (source.permission.empty() && !ci->AccessFor(u).HasPriv(CA_SET))
+ if (source.permission.empty() && !ci->AccessFor(u).HasPriv("SET"))
{
source.Reply(ACCESS_DENIED);
return;
diff --git a/modules/commands/cs_set_successor.cpp b/modules/commands/cs_set_successor.cpp
index efd09bb6d..c670df15e 100644
--- a/modules/commands/cs_set_successor.cpp
+++ b/modules/commands/cs_set_successor.cpp
@@ -32,13 +32,13 @@ class CommandCSSetSuccessor : public Command
return;
}
- if (source.permission.empty() && !ci->AccessFor(u).HasPriv(CA_SET))
+ if (source.permission.empty() && !ci->AccessFor(u).HasPriv("SET"))
{
source.Reply(ACCESS_DENIED);
return;
}
- if (source.permission.empty() && ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !ci->AccessFor(u).HasPriv(CA_FOUNDER))
+ if (source.permission.empty() && ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !ci->AccessFor(u).HasPriv("FOUNDER"))
{
source.Reply(ACCESS_DENIED);
return;
diff --git a/modules/commands/cs_set_topiclock.cpp b/modules/commands/cs_set_topiclock.cpp
index 02f9151a0..67aa243e1 100644
--- a/modules/commands/cs_set_topiclock.cpp
+++ b/modules/commands/cs_set_topiclock.cpp
@@ -32,7 +32,7 @@ class CommandCSSetTopicLock : public Command
return;
}
- if (source.permission.empty() && !ci->AccessFor(u).HasPriv(CA_SET))
+ if (source.permission.empty() && !ci->AccessFor(u).HasPriv("SET"))
{
source.Reply(ACCESS_DENIED);
return;
diff --git a/modules/commands/cs_tban.cpp b/modules/commands/cs_tban.cpp
index 0e7b8978e..b7d1399fa 100644
--- a/modules/commands/cs_tban.cpp
+++ b/modules/commands/cs_tban.cpp
@@ -40,7 +40,7 @@ static bool CanBanUser(CommandSource &source, Channel *c, User *u2)
User *u = source.u;
ChannelInfo *ci = c->ci;
bool ok = false;
- if (!ci->AccessFor(u).HasPriv(CA_BAN))
+ if (!ci->AccessFor(u).HasPriv("BAN"))
source.Reply(ACCESS_DENIED);
else if (matches_list(c, u2, CMODE_EXCEPT))
source.Reply(CHAN_EXCEPTED, u2->nick.c_str(), ci->name.c_str());
diff --git a/modules/commands/cs_topic.cpp b/modules/commands/cs_topic.cpp
index a55c969f7..2210aed01 100644
--- a/modules/commands/cs_topic.cpp
+++ b/modules/commands/cs_topic.cpp
@@ -37,7 +37,7 @@ class CommandCSTopic : public Command
if (!ci->c)
source.Reply(CHAN_X_NOT_IN_USE, ci->name.c_str());
- else if (!ci->AccessFor(u).HasPriv(CA_TOPIC) && !u->HasCommand("chanserv/topic"))
+ else if (!ci->AccessFor(u).HasPriv("TOPIC") && !u->HasCommand("chanserv/topic"))
source.Reply(ACCESS_DENIED);
else
{
@@ -47,7 +47,7 @@ class CommandCSTopic : public Command
if (has_topiclock)
ci->SetFlag(CI_TOPICLOCK);
- bool override = !ci->AccessFor(u).HasPriv(CA_TOPIC);
+ bool override = !ci->AccessFor(u).HasPriv("TOPIC");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "to change the topic to " << (!topic.empty() ? topic : "No topic");
}
return;
diff --git a/modules/commands/cs_unban.cpp b/modules/commands/cs_unban.cpp
index c78b3a7d1..8d6357745 100644
--- a/modules/commands/cs_unban.cpp
+++ b/modules/commands/cs_unban.cpp
@@ -39,7 +39,7 @@ class CommandCSUnban : public Command
return;
}
- if (!ci->AccessFor(u).HasPriv(CA_UNBAN))
+ if (!ci->AccessFor(u).HasPriv("UNBAN"))
{
source.Reply(ACCESS_DENIED);
return;
diff --git a/modules/commands/cs_xop.cpp b/modules/commands/cs_xop.cpp
index 27f200b9b..b2aaffde6 100644
--- a/modules/commands/cs_xop.cpp
+++ b/modules/commands/cs_xop.cpp
@@ -27,63 +27,63 @@ static struct XOPAccess
{
XOPType type;
Anope::string name;
- ChannelAccess access[CA_SIZE];
+ Anope::string access[10];
} xopAccess[] = {
{ XOP_QOP, "QOP",
{
- CA_SIGNKICK,
- CA_SET,
- CA_AUTOOWNER,
- CA_OWNERME,
- CA_PROTECT,
- CA_INFO,
- CA_ASSIGN,
- CA_TOPIC,
- CA_SIZE
+ "SIGNKICK",
+ "SET",
+ "AUTOOWNER",
+ "OWNERME",
+ "PROTECT",
+ "INFO",
+ "ASSIGN",
+ "TOPIC",
+ ""
}
},
{ XOP_SOP, "SOP",
{
- CA_AUTOPROTECT,
- CA_AKICK,
- CA_BADWORDS,
- CA_MEMO,
- CA_ACCESS_CHANGE,
- CA_PROTECTME,
- CA_OPDEOP,
- CA_SIZE
+ "AUTOPROTECT",
+ "AKICK",
+ "BADWORDS",
+ "MEMO",
+ "ACCESS_CHANGE",
+ "PROTECTME",
+ "OPDEOP",
+ ""
}
},
{ XOP_AOP, "AOP",
{
- CA_MODE,
- CA_GETKEY,
- CA_INVITE,
- CA_UNBAN,
- CA_AUTOOP,
- CA_OPDEOPME,
- CA_HALFOP,
- CA_SAY,
- CA_NOKICK,
- CA_SIZE
+ "MODE",
+ "GETKEY",
+ "INVITE",
+ "UNBAN",
+ "AUTOOP",
+ "OPDEOPME",
+ "HALFOP",
+ "SAY",
+ "NOKICK",
+ ""
}
},
{ XOP_HOP, "HOP",
{
- CA_AUTOHALFOP,
- CA_HALFOPME,
- CA_KICK,
- CA_BAN,
- CA_FANTASIA,
- CA_SIZE
+ "AUTOHALFOP",
+ "HALFOPME",
+ "KICK",
+ "BAN",
+ "FANTASIA",
+ ""
}
},
{ XOP_VOP, "VOP",
{
- CA_AUTOVOICE,
- CA_VOICEME,
- CA_ACCESS_LIST,
- CA_SIZE
+ "AUTOVOICE",
+ "VOICEME",
+ "ACCESS_LIST",
+ ""
}
},
{ XOP_UNKNOWN, "", { }
@@ -108,7 +108,7 @@ class XOPChanAccess : public ChanAccess
return false;
}
- bool HasPriv(ChannelAccess priv)
+ bool HasPriv(const Anope::string &priv)
{
for (int i = 0; xopAccess[i].type != XOP_UNKNOWN; ++i)
{
@@ -117,7 +117,7 @@ class XOPChanAccess : public ChanAccess
if (this->type > x.type)
continue;
- for (int j = 0; x.access[j] != CA_SIZE; ++j)
+ for (int j = 0; !x.access[j].empty(); ++j)
if (x.access[j] == priv)
return true;
}
@@ -171,7 +171,7 @@ class XOPChanAccess : public ChanAccess
{
XOPAccess &x = xopAccess[i];
- for (int j = 0; x.access[j] != CA_SIZE; ++j)
+ for (int j = 0; !x.access[j].empty(); ++j)
if (access->HasPriv(x.access[j]))
++count[x.type];
}
@@ -316,7 +316,7 @@ class XOPBase : public Command
ChanAccess *highest = access.Highest();
int u_level = (highest ? XOPChanAccess::DetermineLevel(highest) : 0);
- if ((!access.Founder && !access.HasPriv(CA_ACCESS_CHANGE) && !u->HasPriv("chanserv/access/modify")) || (level <= u_level && !access.Founder))
+ if ((!access.Founder && !access.HasPriv("ACCESS_CHANGE") && !u->HasPriv("chanserv/access/modify")) || (level <= u_level && !access.Founder))
{
source.Reply(ACCESS_DENIED);
return;
@@ -360,7 +360,7 @@ class XOPBase : public Command
acc->created = Anope::CurTime;
ci->AddAccess(acc);
- bool override = (level >= u_level && !access.Founder) || !access.HasPriv(CA_ACCESS_CHANGE);
+ bool override = (level >= u_level && !access.Founder) || !access.HasPriv("ACCESS_CHANGE");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << mask;
FOREACH_MOD(I_OnAccessAdd, OnAccessAdd(ci, u, acc));
@@ -394,7 +394,7 @@ class XOPBase : public Command
AccessGroup access = ci->AccessFor(u);
ChanAccess *highest = access.Highest();
bool override = false;
- if ((!mask.equals_ci(u->Account()->display) && !access.HasPriv(CA_ACCESS_CHANGE) && !access.Founder) || ((!highest || level <= XOPChanAccess::DetermineLevel(highest)) && !access.Founder))
+ if ((!mask.equals_ci(u->Account()->display) && !access.HasPriv("ACCESS_CHANGE") && !access.Founder) || ((!highest || level <= XOPChanAccess::DetermineLevel(highest)) && !access.Founder))
{
if (u->HasPriv("chanserv/access/modify"))
override = true;
@@ -443,7 +443,7 @@ class XOPBase : public Command
AccessGroup access = ci->AccessFor(u);
bool override = false;
- if (!access.HasPriv(CA_ACCESS_LIST))
+ if (!access.HasPriv("ACCESS_LIST"))
{
if (u->HasCommand("chanserv/access/list"))
override = true;
@@ -512,13 +512,13 @@ class XOPBase : public Command
return;
}
- if (!ci->AccessFor(u).HasPriv(CA_FOUNDER) && !u->HasPriv("chanserv/access/modify"))
+ if (!ci->AccessFor(u).HasPriv("FOUNDER") && !u->HasPriv("chanserv/access/modify"))
{
source.Reply(ACCESS_DENIED);
return;
}
- bool override = !ci->AccessFor(u).HasPriv(CA_FOUNDER);
+ bool override = !ci->AccessFor(u).HasPriv("FOUNDER");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "CLEAR";
for (unsigned i = ci->GetAccessCount(); i > 0; --i)
diff --git a/modules/commands/ms_del.cpp b/modules/commands/ms_del.cpp
index 8f75b0da9..d1aeaa4d1 100644
--- a/modules/commands/ms_del.cpp
+++ b/modules/commands/ms_del.cpp
@@ -70,7 +70,7 @@ class CommandMSDel : public Command
source.Reply(READ_ONLY_MODE);
return;
}
- else if (!ci->AccessFor(u).HasPriv(CA_MEMO))
+ else if (!ci->AccessFor(u).HasPriv("MEMO"))
{
source.Reply(ACCESS_DENIED);
return;
diff --git a/modules/commands/ms_ignore.cpp b/modules/commands/ms_ignore.cpp
index b0c6cfd4f..cfb863ebb 100644
--- a/modules/commands/ms_ignore.cpp
+++ b/modules/commands/ms_ignore.cpp
@@ -43,7 +43,7 @@ class CommandMSIgnore : public Command
ChannelInfo *ci = cs_findchan(channel);
if (!mi)
source.Reply(ischan ? CHAN_X_NOT_REGISTERED : _(NICK_X_NOT_REGISTERED), channel.c_str());
- else if (ischan && !ci->AccessFor(u).HasPriv(CA_MEMO))
+ else if (ischan && !ci->AccessFor(u).HasPriv("MEMO"))
source.Reply(ACCESS_DENIED);
else if (command.equals_ci("ADD") && !param.empty())
{
diff --git a/modules/commands/ms_info.cpp b/modules/commands/ms_info.cpp
index 741be799a..03df6d973 100644
--- a/modules/commands/ms_info.cpp
+++ b/modules/commands/ms_info.cpp
@@ -50,7 +50,7 @@ class CommandMSInfo : public Command
source.Reply(CHAN_X_NOT_REGISTERED, nname.c_str());
return;
}
- else if (!ci->AccessFor(u).HasPriv(CA_MEMO))
+ else if (!ci->AccessFor(u).HasPriv("MEMO"))
{
source.Reply(ACCESS_DENIED);
return;
diff --git a/modules/commands/ms_list.cpp b/modules/commands/ms_list.cpp
index e6d7a691d..9087ad2c5 100644
--- a/modules/commands/ms_list.cpp
+++ b/modules/commands/ms_list.cpp
@@ -74,7 +74,7 @@ class CommandMSList : public Command
source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
return;
}
- else if (!ci->AccessFor(u).HasPriv(CA_MEMO))
+ else if (!ci->AccessFor(u).HasPriv("MEMO"))
{
source.Reply(ACCESS_DENIED);
return;
diff --git a/modules/commands/ms_read.cpp b/modules/commands/ms_read.cpp
index 87a5cb648..779a0c759 100644
--- a/modules/commands/ms_read.cpp
+++ b/modules/commands/ms_read.cpp
@@ -109,7 +109,7 @@ class CommandMSRead : public Command
source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
return;
}
- else if (!ci->AccessFor(u).HasPriv(CA_MEMO))
+ else if (!ci->AccessFor(u).HasPriv("MEMO"))
{
source.Reply(ACCESS_DENIED);
return;
diff --git a/modules/commands/ms_set.cpp b/modules/commands/ms_set.cpp
index a4fef31a8..ef3480fd5 100644
--- a/modules/commands/ms_set.cpp
+++ b/modules/commands/ms_set.cpp
@@ -91,7 +91,7 @@ class CommandMSSet : public Command
source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
return;
}
- else if (!is_servadmin && !ci->AccessFor(u).HasPriv(CA_MEMO))
+ else if (!is_servadmin && !ci->AccessFor(u).HasPriv("MEMO"))
{
source.Reply(ACCESS_DENIED);
return;
diff --git a/modules/commands/ns_ajoin.cpp b/modules/commands/ns_ajoin.cpp
index ca7b656a6..bed0442d7 100644
--- a/modules/commands/ns_ajoin.cpp
+++ b/modules/commands/ns_ajoin.cpp
@@ -165,7 +165,7 @@ class NSAJoin : public Module
Anope::string k;
if (c->GetParam(CMODE_KEY, k))
{
- if (ci->AccessFor(u).HasPriv(CA_GETKEY))
+ if (ci->AccessFor(u).HasPriv("GETKEY"))
key = k;
else if (key != k)
need_invite = true;
@@ -190,7 +190,7 @@ class NSAJoin : public Module
if (need_invite)
{
BotInfo *bi = findbot(Config->NickServ);
- if (!bi || !ci->AccessFor(u).HasPriv(CA_INVITE))
+ if (!bi || !ci->AccessFor(u).HasPriv("INVITE"))
continue;
ircdproto->SendInvite(bi, channels[i].first, u->nick);
}
diff --git a/modules/database/db_mysql.cpp b/modules/database/db_mysql.cpp
index a90276274..163bb5a44 100644
--- a/modules/database/db_mysql.cpp
+++ b/modules/database/db_mysql.cpp
@@ -482,7 +482,7 @@ class DBMySQL : public Module
continue;
}
- ci->levels[atoi(r.Get(i, "position").c_str())] = atoi(r.Get(i, "level").c_str());
+ ci->SetLevel(r.Get(i, "name"), atoi(r.Get(i, "level").c_str()));
}
query = "SELECT * FROM `anope_cs_info_metadata`";
@@ -792,7 +792,7 @@ class DBMySQL : public Module
ChannelInfo *ci = cs_findchan(params[0]);
if (!ci)
return;
- if (!ci->AccessFor(u).HasPriv(CA_SET) && !u->HasPriv("botserv/administration"))
+ if (!ci->AccessFor(u).HasPriv("SET") && !u->HasPriv("botserv/administration"))
return;
if (params[1].equals_ci("BADWORDS") || params[1].equals_ci("BOLDS") || params[1].equals_ci("CAPS") || params[1].equals_ci("COLORS") || params[1].equals_ci("FLOOD") || params[1].equals_ci("REPEAT") || params[1].equals_ci("REVERSES") || params[1].equals_ci("UNDERLINES"))
{
@@ -843,7 +843,7 @@ class DBMySQL : public Module
else if (command->name == "botserv/set" && params.size() > 1)
{
ChannelInfo *ci = cs_findchan(params[0]);
- if (ci && !ci->AccessFor(u).HasPriv(CA_SET) && !u->HasPriv("botserv/administration"))
+ if (ci && !ci->AccessFor(u).HasPriv("SET") && !u->HasPriv("botserv/administration"))
return;
BotInfo *bi = NULL;
if (!ci)
@@ -880,7 +880,7 @@ class DBMySQL : public Module
else
{
ci = cs_findchan(target);
- if (!ci || !ci->AccessFor(u).HasPriv(CA_MEMO))
+ if (!ci || !ci->AccessFor(u).HasPriv("MEMO"))
return;
}
@@ -1029,27 +1029,27 @@ class DBMySQL : public Module
this->RunQuery(query);
}
- void OnLevelChange(User *u, ChannelInfo *ci, int pos, int what)
+ void OnLevelChange(User *u, ChannelInfo *ci, const Anope::string &priv, int16 what)
{
- if (pos >= 0)
- {
- SQLQuery query("UPDATE `anope_cs_levels` SET `level` = @level WHERE `channel` = @channel AND `position` = @pos");
- query.setValue("level", what);
- query.setValue("channel", ci->name);
- query.setValue("pos", pos);
- this->RunQuery(query);
- }
- else
+ SQLQuery query("UPDATE `anope_cs_levels` SET `level` = @level WHERE `channel` = @channel AND `name` = @name ON DUPLICATE KEY UPDATE level=VALUES(level), name=VALUES(name)");
+ query.setValue("channel", ci->name);
+ if (priv == "ALL")
{
- SQLQuery query("INSERT INTO `anope_cs_levels` (level, channel, position) VALUES(@level, @channel, @pos) ON DUPLICATE KEY UPDATE level=VALUES(level), channel=VALUES(channel), position=VALUES(position)");
- query.setValue("channel", ci->name);
- for (int i = 0; i < CA_SIZE; ++i)
+ const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges();
+ for (unsigned i = 0; i < privs.size(); ++i)
{
- query.setValue("level", ci->levels[i]);
- query.setValue("pos", i);
+ const Privilege &p = privs[i];
+ query.setValue("level", ci->GetLevel(p.name));
+ query.setValue("name", p.name);
this->RunQuery(query);
}
}
+ else
+ {
+ query.setValue("level", what);
+ query.setValue("name", name);
+ this->RunQuery(query);
+ }
}
void OnChanForbidden(ChannelInfo *ci)
@@ -1538,7 +1538,11 @@ static void SaveDatabases()
me->OnAkickAdd(ci, ak);
}
+<<<<<<< HEAD
me->OnLevelChange(NULL, ci, -1, -1);
+=======
+ me->OnLevelChange(NULL, ci, "ALL", -1);
+>>>>>>> 348a3db... Allow modules to add their own channel levels
for (unsigned j = 0, end = ci->memos.memos.size(); j < end; ++j)
{
diff --git a/modules/database/db_plain.cpp b/modules/database/db_plain.cpp
index 340775e0c..83098ced9 100644
--- a/modules/database/db_plain.cpp
+++ b/modules/database/db_plain.cpp
@@ -179,52 +179,6 @@ static void ReadDatabase(Module *m = NULL)
db.close();
}
-struct ChannelLevel
-{
- ChannelAccess Level;
- Anope::string Name;
-};
-
-ChannelLevel ChannelLevels[] = {
- { CA_ACCESS_LIST, "ACCESS_LIST" },
- { CA_NOKICK, "NOKICK" },
- { CA_FANTASIA, "FANTASIA" },
- { CA_GREET, "GREET" },
- { CA_AUTOVOICE, "AUTOVOICE" },
- { CA_VOICEME, "VOICEME" },
- { CA_VOICE, "VOICE" },
- { CA_INFO, "INFO" },
- { CA_SAY, "SAY" },
- { CA_AUTOHALFOP, "AUTOHALFOP" },
- { CA_HALFOPME, "HALFOPME" },
- { CA_HALFOP, "HALFOP" },
- { CA_KICK, "KICK" },
- { CA_SIGNKICK, "SIGNKICK" },
- { CA_BAN, "BAN" },
- { CA_TOPIC, "TOPIC" },
- { CA_MODE, "MODE" },
- { CA_GETKEY, "GETKEY" },
- { CA_INVITE, "INVITE" },
- { CA_UNBAN, "UNBAN" },
- { CA_AUTOOP, "AUTOOP" },
- { CA_OPDEOPME, "OPDEOPME" },
- { CA_OPDEOP, "OPDEOP" },
- { CA_AUTOPROTECT, "AUTOPROTECT" },
- { CA_AKICK, "AKICK" },
- { CA_BADWORDS, "BADWORDS" },
- { CA_ASSIGN, "ASSIGN" },
- { CA_MEMO, "MEMO" },
- { CA_ACCESS_CHANGE, "ACCESS_CHANGE" },
- { CA_PROTECTME, "PROTECTME" },
- { CA_PROTECT, "PROTECT" },
- { CA_SET, "SET" },
- { CA_AUTOOWNER, "AUTOOWNER" },
- { CA_OWNERME, "OWNERME" },
- { CA_OWNER, "OWNER" },
- { CA_FOUNDER, "FOUNDER" },
- { CA_SIZE, "" }
-};
-
static Anope::string ToString(const std::vector<Anope::string> &strings)
{
Anope::string ret;
@@ -532,9 +486,12 @@ class DBPlain : public Module
else if (key.equals_ci("LEVELS"))
{
for (unsigned j = 0, end = params.size(); j < end; j += 2)
- for (int i = 0; ChannelLevels[i].Level != CA_SIZE; ++i)
- if (params[j].equals_ci(ChannelLevels[i].Name))
- ci->levels[ChannelLevels[i].Level] = params[j + 1].is_number_only() ? convertTo<int16>(params[j + 1]) : 0;
+ {
+ Privilege *p = PrivilegeManager::FindPrivilege(params[j]);
+ if (p == NULL)
+ continue;
+ ci->SetLevel(p->name, params[j + 1].is_number_only() ? convertTo<int16>(params[j + 1]) : 0);
+ }
}
else if (key.equals_ci("FLAGS"))
ci->FromString(params);
@@ -555,7 +512,7 @@ class DBPlain : public Module
{
service_reference<AccessProvider> provider("access/access");
if (!provider)
- throw DatabaseException("Access entry for nonexistant provider " + params[0]);
+ throw DatabaseException("Old access entry for nonexistant provider");
ChanAccess *access = provider->Create();
access->ci = ci;
@@ -799,8 +756,12 @@ class DBPlain : public Module
if (!ci->last_topic.empty())
db_buffer << "MD TOPIC " << ci->last_topic_setter << " " << ci->last_topic_time << " :" << ci->last_topic << endl;
db_buffer << "MD LEVELS";
- for (int j = 0; ChannelLevels[j].Level != CA_SIZE; ++j)
- db_buffer << " " << ChannelLevels[j].Name << " " << ci->levels[ChannelLevels[j].Level];
+ const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges();
+ for (unsigned i = 0; i < privs.size(); ++i)
+ {
+ const Privilege &p = privs[i];
+ db_buffer << p.name << " " << ci->GetLevel(p.name);
+ }
db_buffer << endl;
if (ci->FlagCount())
db_buffer << "MD FLAGS " << ToString(ci->ToString()) << endl;
diff --git a/modules/extra/m_helpchan.cpp b/modules/extra/m_helpchan.cpp
index 6efcea572..83477da94 100644
--- a/modules/extra/m_helpchan.cpp
+++ b/modules/extra/m_helpchan.cpp
@@ -28,7 +28,7 @@ class HelpChannel : public Module
{
User *u = finduser(param);
- if (u && c->ci->AccessFor(u).HasPriv(CA_OPDEOPME))
+ if (u && c->ci->AccessFor(u).HasPriv("OPDEOPME"))
u->SetMode(findbot(Config->OperServ), UMODE_HELPOP);
}
diff --git a/modules/extra/m_statusupdate.cpp b/modules/extra/m_statusupdate.cpp
index 6f98c1345..8fff6e4c3 100644
--- a/modules/extra/m_statusupdate.cpp
+++ b/modules/extra/m_statusupdate.cpp
@@ -9,15 +9,15 @@
static struct ModeInfo
{
- ChannelAccess priv;
+ Anope::string priv;
ChannelModeName name;
} modeInfo[] = {
- { CA_AUTOOWNER, CMODE_OWNER },
- { CA_AUTOPROTECT, CMODE_PROTECT },
- { CA_AUTOOP, CMODE_OP },
- { CA_AUTOHALFOP, CMODE_HALFOP },
- { CA_AUTOVOICE, CMODE_VOICE },
- { CA_SIZE, CMODE_END }
+ { "AUTOOWNER", CMODE_OWNER },
+ { "AUTOPROTECT", CMODE_PROTECT },
+ { "AUTOOP", CMODE_OP },
+ { "AUTOHALFOP", CMODE_HALFOP },
+ { "AUTOVOICE", CMODE_VOICE },
+ { "", CMODE_END }
};
class StatusUpdate : public Module
@@ -40,7 +40,7 @@ class StatusUpdate : public Module
if (access->Matches(user, user->Account()))
{
- for (int i = 0; modeInfo[i].priv != CA_SIZE; ++i)
+ for (int i = 0; !modeInfo[i].priv.empty(); ++i)
if (!access->HasPriv(modeInfo[i].priv))
ci->c->RemoveMode(NULL, modeInfo[i].name, user->nick);
chan_set_correct_modes(user, ci->c, 1);
@@ -57,7 +57,7 @@ class StatusUpdate : public Module
if (access->Matches(user, user->Account()))
{
- for (int i = 0; modeInfo[i].priv != CA_SIZE; ++i)
+ for (int i = 0; !modeInfo[i].priv.empty(); ++i)
if (access->HasPriv(modeInfo[i].priv))
ci->c->RemoveMode(NULL, modeInfo[i].name, user->nick);
}
diff --git a/modules/pseudoclients/botserv.cpp b/modules/pseudoclients/botserv.cpp
index a286c54e7..802e1e82e 100644
--- a/modules/pseudoclients/botserv.cpp
+++ b/modules/pseudoclients/botserv.cpp
@@ -81,7 +81,7 @@ class BotServCore : public Module
if (bi == NULL || !bi->commands.count(command))
return;
- if (c->ci->AccessFor(u).HasPriv(CA_FANTASIA))
+ if (c->ci->AccessFor(u).HasPriv("FANTASIA"))
{
this->fantasy_channel = c;
@@ -133,7 +133,7 @@ class BotServCore : public Module
* to has synced, or we'll get greet-floods when the net
* recovers from a netsplit. -GD
*/
- if (c->FindUser(c->ci->bi) && c->ci->botflags.HasFlag(BS_GREET) && user->Account() && !user->Account()->greet.empty() && c->ci->AccessFor(user).HasPriv(CA_GREET) && user->server->IsSynced())
+ if (c->FindUser(c->ci->bi) && c->ci->botflags.HasFlag(BS_GREET) && user->Account() && !user->Account()->greet.empty() && c->ci->AccessFor(user).HasPriv("GREET") && user->server->IsSynced())
{
ircdproto->SendPrivmsg(c->ci->bi, c->name, "[%s] %s", user->Account()->display.c_str(), user->Account()->greet.c_str());
c->ci->bi->lastmsg = Anope::CurTime;
diff --git a/modules/pseudoclients/memoserv.cpp b/modules/pseudoclients/memoserv.cpp
index 987dec16b..ca131b0de 100644
--- a/modules/pseudoclients/memoserv.cpp
+++ b/modules/pseudoclients/memoserv.cpp
@@ -102,7 +102,7 @@ class MyMemoServService : public MemoServService
{
UserContainer *cu = *it;
- if (ci->AccessFor(cu->user).HasPriv(CA_MEMO))
+ if (ci->AccessFor(cu->user).HasPriv("MEMO"))
{
if (cu->user->Account() && cu->user->Account()->HasFlag(NI_MEMO_RECEIVE))
cu->user->SendMessage(MemoServ, MEMO_NEW_X_MEMO_ARRIVED, ci->name.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->MemoServ.c_str(), ci->name.c_str(), mi->memos.size());
@@ -181,7 +181,7 @@ class MemoServCore : public Module
void OnJoinChannel(User *u, Channel *c)
{
- if (c->ci && c->ci->AccessFor(u).HasPriv(CA_MEMO) && c->ci->memos.memos.size() > 0)
+ if (c->ci && c->ci->AccessFor(u).HasPriv("MEMO") && c->ci->memos.memos.size() > 0)
{
if (c->ci->memos.memos.size() == 1)
u->SendMessage(MemoServ, _("There is \002%d\002 memo on channel %s."), c->ci->memos.memos.size(), c->ci->name.c_str());
diff --git a/src/access.cpp b/src/access.cpp
index b9b3e1e9a..49636cd04 100644
--- a/src/access.cpp
+++ b/src/access.cpp
@@ -19,6 +19,84 @@ enum
ACCESS_FOUNDER = 10001
};
+Privilege::Privilege(const Anope::string &n, const Anope::string &d) : name(n), desc(d)
+{
+}
+
+bool Privilege::operator==(const Privilege &other)
+{
+ return this->name == other.name;
+}
+
+std::vector<Privilege> PrivilegeManager::privs;
+
+void PrivilegeManager::AddPrivilege(Privilege p, int pos, int def)
+{
+ if (pos < 0 || static_cast<size_t>(pos) > privs.size())
+ pos = privs.size();
+ privs.insert(privs.begin() + pos, p);
+ for (registered_channel_map::const_iterator cit = RegisteredChannelList.begin(), cit_end = RegisteredChannelList.end(); cit != cit_end; ++cit)
+ cit->second->SetLevel(p.name, def);
+}
+
+void PrivilegeManager::RemovePrivilege(Privilege &p)
+{
+ std::vector<Privilege>::iterator it = std::find(privs.begin(), privs.end(), p);
+ if (it != privs.end())
+ privs.erase(it);
+ for (registered_channel_map::const_iterator cit = RegisteredChannelList.begin(), cit_end = RegisteredChannelList.end(); cit != cit_end; ++cit)
+ cit->second->RemoveLevel(p.name);
+}
+
+Privilege *PrivilegeManager::FindPrivilege(const Anope::string &name)
+{
+ for (unsigned i = privs.size(); i > 0; --i)
+ if (privs[i - 1].name == name)
+ return &privs[i - 1];
+ return NULL;
+}
+
+void PrivilegeManager::Init()
+{
+ AddPrivilege(Privilege("ACCESS_LIST", _("Allowed to view the access list")));
+ AddPrivilege(Privilege("NOKICK", _("Prevents users being kicked by Services")));
+ AddPrivilege(Privilege("FANTASIA", _("Allowed to use fantasy commands")));
+ AddPrivilege(Privilege("FOUNDER", _("Allowed to issue commands restricted to channel founders")));
+ AddPrivilege(Privilege("GREET", _("Greet message displayed")));
+ AddPrivilege(Privilege("AUTOVOICE", _("Automatic mode +v")));
+ AddPrivilege(Privilege("VOICEME", _("Allowed to (de)voice him/herself")));
+ AddPrivilege(Privilege("VOICE", _("Allowed to (de)voice users")));
+ AddPrivilege(Privilege("INFO", _("Allowed to use INFO command with ALL option")));
+ AddPrivilege(Privilege("SAY", _("Allowed to use SAY and ACT commands")));
+ AddPrivilege(Privilege("AUTOHALFOP", _("Automatic mode +h")));
+ AddPrivilege(Privilege("HALFOPME", _("Allowed to (de)halfop him/herself")));
+ AddPrivilege(Privilege("HALFOP", _("Allowed to (de)halfop users")));
+ AddPrivilege(Privilege("KICK", _("Allowed to use the KICK command")));
+ AddPrivilege(Privilege("SIGNKICK", _("No signed kick when SIGNKICK LEVEL is used")));
+ AddPrivilege(Privilege("BAN", _("Allowed to use ban users")));
+ AddPrivilege(Privilege("TOPIC", _("Allowed to change channel topics")));
+ AddPrivilege(Privilege("MODE", _("Allowed to change channel modes")));
+ AddPrivilege(Privilege("GETKEY", _("Allowed to use GETKEY command")));
+ AddPrivilege(Privilege("INVITE", _("Allowed to use the INVITE command")));
+ AddPrivilege(Privilege("UNBAN", _("Allowed to unban users")));
+ AddPrivilege(Privilege("AUTOOP", _("Automatic channel operator status")));
+ AddPrivilege(Privilege("AUTOOWNER", _("Automatic mode +q")));
+ AddPrivilege(Privilege("OPDEOPME", _("Allowed to (de)op him/herself")));
+ AddPrivilege(Privilege("OPDEOP", _("Allowed to (de)op users")));
+ AddPrivilege(Privilege("AUTOPROTECT", _("Automatic mode +a")));
+ AddPrivilege(Privilege("AKICK", _("Allowed to use AKICK command")));
+ AddPrivilege(Privilege("BADWORDS", _("Allowed to modify channel badwords list")));
+ AddPrivilege(Privilege("ASSIGN", _("Allowed to assign/unassign a bot")));
+ AddPrivilege(Privilege("MEMO", _("Allowed to read channel memos")));
+ AddPrivilege(Privilege("ACCESS_CHANGE", _("Allowed to modify the access list")));
+ AddPrivilege(Privilege("PROTECTME", _("Allowed to (de)protect him/herself")));
+}
+
+std::vector<Privilege> &PrivilegeManager::GetPrivileges()
+{
+ return privs;
+}
+
AccessProvider::AccessProvider(Module *o, const Anope::string &n) : Service<AccessProvider>(o, n)
{
}
@@ -37,26 +115,29 @@ ChanAccess::~ChanAccess()
bool ChanAccess::operator>(ChanAccess &other)
{
- for (size_t i = CA_SIZE; i > 0; --i)
- if (this->HasPriv(static_cast<ChannelAccess>(i - 1)) && !other.HasPriv(static_cast<ChannelAccess>(i - 1)))
+ const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges();
+ for (unsigned i = privs.size(); i > 0; --i)
+ if (this->HasPriv(privs[i - 1].name) && !other.HasPriv(privs[i - 1].name))
return true;
return false;
}
bool ChanAccess::operator<(ChanAccess &other)
{
- for (size_t i = CA_SIZE; i > 0; --i)
- if (!this->HasPriv(static_cast<ChannelAccess>(i - 1)) && other.HasPriv(static_cast<ChannelAccess>(i - 1)))
+ const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges();
+ for (unsigned i = privs.size(); i > 0; --i)
+ if (!this->HasPriv(privs[i - 1].name) && other.HasPriv(privs[i - 1].name))
return true;
return false;
}
bool ChanAccess::operator>=(ChanAccess &other)
{
- for (size_t i = CA_SIZE; i > 0; --i)
+ const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges();
+ for (unsigned i = privs.size(); i > 0; --i)
{
- bool this_p = this->HasPriv(static_cast<ChannelAccess>(i - 1)),
- other_p = other.HasPriv(static_cast<ChannelAccess>(i - 1));
+ bool this_p = this->HasPriv(privs[i - 1].name),
+ other_p = other.HasPriv(privs[i - 1].name);
if ((this_p && !other_p) || (this_p && other_p))
return true;
@@ -67,10 +148,11 @@ bool ChanAccess::operator>=(ChanAccess &other)
bool ChanAccess::operator<=(ChanAccess &other)
{
- for (size_t i = CA_SIZE; i > 0; --i)
+ const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges();
+ for (unsigned i = privs.size(); i > 0; --i)
{
- bool this_p = this->HasPriv(static_cast<ChannelAccess>(i - 1)),
- other_p = other.HasPriv(static_cast<ChannelAccess>(i - 1));
+ bool this_p = this->HasPriv(privs[i - 1].name),
+ other_p = other.HasPriv(privs[i - 1].name);
if ((!this_p && other_p) || (this_p && other_p))
return true;
@@ -86,23 +168,23 @@ AccessGroup::AccessGroup() : std::vector<ChanAccess *>()
this->SuperAdmin = this->Founder = false;
}
-bool AccessGroup::HasPriv(ChannelAccess priv) const
+bool AccessGroup::HasPriv(const Anope::string &name) const
{
if (this->SuperAdmin)
return true;
- else if (ci->levels[priv] == ACCESS_INVALID)
+ else if (ci->GetLevel(name) == ACCESS_INVALID)
return false;
else if (this->Founder)
return true;
EventReturn MOD_RESULT;
- FOREACH_RESULT(I_OnGroupCheckPriv, OnGroupCheckPriv(this, priv));
+ FOREACH_RESULT(I_OnGroupCheckPriv, OnGroupCheckPriv(this, name));
if (MOD_RESULT != EVENT_CONTINUE)
return MOD_RESULT == EVENT_ALLOW;
for (unsigned i = this->size(); i > 0; --i)
{
ChanAccess *access = this->at(i - 1);
- FOREACH_RESULT(I_OnCheckPriv, OnCheckPriv(access, priv));
- if (MOD_RESULT == EVENT_ALLOW || access->HasPriv(priv))
+ FOREACH_RESULT(I_OnCheckPriv, OnCheckPriv(access, name));
+ if (MOD_RESULT == EVENT_ALLOW || access->HasPriv(name))
return true;
}
return false;
@@ -110,9 +192,10 @@ bool AccessGroup::HasPriv(ChannelAccess priv) const
ChanAccess *AccessGroup::Highest() const
{
- for (size_t i = CA_SIZE; i > 0; --i)
+ const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges();
+ for (unsigned i = privs.size(); i > 0; --i)
for (unsigned j = this->size(); j > 0; --j)
- if (this->at(j - 1)->HasPriv(static_cast<ChannelAccess>(i - 1)))
+ if (this->at(j - 1)->HasPriv(privs[ - 1].name))
return this->at(j - 1);
return NULL;
}
@@ -127,8 +210,9 @@ bool AccessGroup::operator>(const AccessGroup &other) const
return true;
else if (!this->Founder && other.Founder)
return false;
- for (size_t i = CA_SIZE; i > 0; --i)
- if (this->HasPriv(static_cast<ChannelAccess>(i - 1)) && !other.HasPriv(static_cast<ChannelAccess>(i - 1)))
+ const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges();
+ for (unsigned i = privs.size(); i > 0; --i)
+ if (this->HasPriv(privs[i - 1].name) && !other.HasPriv(privs[i - 1].name))
return true;
return false;
}
@@ -143,8 +227,9 @@ bool AccessGroup::operator<(const AccessGroup &other) const
return true;
else if (this->Founder && !other.Founder)
return false;
- for (size_t i = CA_SIZE; i > 0; --i)
- if (!this->HasPriv(static_cast<ChannelAccess>(i - 1)) && other.HasPriv(static_cast<ChannelAccess>(i - 1)))
+ const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges();
+ for (unsigned i = privs.size(); i > 0; --i)
+ if (!this->HasPriv(privs[i - 1].name) && other.HasPriv(privs[i - 1].name))
return true;
return false;
}
@@ -159,10 +244,11 @@ bool AccessGroup::operator>=(const AccessGroup &other) const
return true;
else if (other.Founder)
return false;
- for (size_t i = CA_SIZE; i > 0; --i)
+ const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges();
+ for (unsigned i = privs.size(); i > 0; --i)
{
- bool this_p = this->HasPriv(static_cast<ChannelAccess>(i - 1)),
- other_p = other.HasPriv(static_cast<ChannelAccess>(i - 1));
+ bool this_p = this->HasPriv(privs[i - 1].name),
+ other_p = other.HasPriv(privs[i - 1].name);
if ((this_p && !other_p) || (this_p && other_p))
return true;
@@ -181,10 +267,11 @@ bool AccessGroup::operator<=(const AccessGroup &other) const
return true;
else if (this->Founder)
return false;
- for (size_t i = CA_SIZE; i > 0; --i)
+ const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges();
+ for (unsigned i = privs.size(); i > 0; --i)
{
- bool this_p = this->HasPriv(static_cast<ChannelAccess>(i - 1)),
- other_p = other.HasPriv(static_cast<ChannelAccess>(i - 1));
+ bool this_p = this->HasPriv(privs[i - 1].name),
+ other_p = other.HasPriv(privs[i - 1].name);
if ((!this_p && other_p) || (this_p && other_p))
return true;
diff --git a/src/botserv.cpp b/src/botserv.cpp
index 1670283be..c388b8a94 100644
--- a/src/botserv.cpp
+++ b/src/botserv.cpp
@@ -71,7 +71,7 @@ void bot_raw_ban(User *requester, ChannelInfo *ci, User *u, const Anope::string
ci->c->SetMode(NULL, CMODE_BAN, mask);
/* Check if we need to do a signkick or not -GD */
- if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !req_access.HasPriv(CA_SIGNKICK)))
+ if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !req_access.HasPriv("SIGNKICK")))
ci->c->Kick(ci->bi, u, "%s (%s)", !reason.empty() ? reason.c_str() : ci->bi->nick.c_str(), requester->nick.c_str());
else
ci->c->Kick(ci->bi, u, "%s", !reason.empty() ? reason.c_str() : ci->bi->nick.c_str());
@@ -100,7 +100,7 @@ void bot_raw_kick(User *requester, ChannelInfo *ci, User *u, const Anope::string
if (ci->HasFlag(CI_PEACE) && requester != u && u_access >= req_access)
return;
- if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !req_access.HasPriv(CA_SIGNKICK)))
+ if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !req_access.HasPriv("SIGNKICK")))
ci->c->Kick(ci->bi, u, "%s (%s)", !reason.empty() ? reason.c_str() : ci->bi->nick.c_str(), requester->nick.c_str());
else
ci->c->Kick(ci->bi, u, "%s", !reason.empty() ? reason.c_str() : ci->bi->nick.c_str());
diff --git a/src/channels.cpp b/src/channels.cpp
index 52b0b86c5..1778b9f01 100644
--- a/src/channels.cpp
+++ b/src/channels.cpp
@@ -1091,31 +1091,31 @@ void chan_set_correct_modes(User *user, Channel *c, int give_modes)
if (give_modes && (!user->Account() || user->Account()->HasFlag(NI_AUTOOP)))
{
- if (owner && u_access.HasPriv(CA_AUTOOWNER))
+ if (owner && u_access.HasPriv("AUTOOWNER"))
c->SetMode(NULL, CMODE_OWNER, user->nick);
- else if (admin && u_access.HasPriv(CA_AUTOPROTECT))
+ else if (admin && u_access.HasPriv("AUTOPROTECT"))
c->SetMode(NULL, CMODE_PROTECT, user->nick);
- if (op && u_access.HasPriv(CA_AUTOOP))
+ if (op && u_access.HasPriv("AUTOOP"))
c->SetMode(NULL, CMODE_OP, user->nick);
- else if (halfop && u_access.HasPriv(CA_AUTOHALFOP))
+ else if (halfop && u_access.HasPriv("AUTOHALFOP"))
c->SetMode(NULL, CMODE_HALFOP, user->nick);
- else if (voice && u_access.HasPriv(CA_AUTOVOICE))
+ else if (voice && u_access.HasPriv("AUTOVOICE"))
c->SetMode(NULL, CMODE_VOICE, user->nick);
}
/* If this channel has secureops or the channel is syncing and they are not ulined, check to remove modes */
if ((ci->HasFlag(CI_SECUREOPS) || (c->HasFlag(CH_SYNCING) && user->server->IsSynced())) && !user->server->IsULined())
{
- if (owner && !u_access.HasPriv(CA_AUTOOWNER) && !u_access.HasPriv(CA_OWNERME))
+ if (owner && !u_access.HasPriv("AUTOOWNER") && !u_access.HasPriv("OWNERME"))
c->RemoveMode(NULL, CMODE_OWNER, user->nick);
- if (admin && !u_access.HasPriv(CA_AUTOPROTECT) && !u_access.HasPriv(CA_PROTECTME))
+ if (admin && !u_access.HasPriv("AUTOPROTECT") && !u_access.HasPriv("PROTECTME"))
c->RemoveMode(NULL, CMODE_PROTECT, user->nick);
- if (op && c->HasUserStatus(user, CMODE_OP) && !u_access.HasPriv(CA_AUTOOP) && !u_access.HasPriv(CA_OPDEOPME))
+ if (op && c->HasUserStatus(user, CMODE_OP) && !u_access.HasPriv("AUTOOP") && !u_access.HasPriv("OPDEOPME"))
c->RemoveMode(NULL, CMODE_OP, user->nick);
- if (halfop && !u_access.HasPriv(CA_AUTOHALFOP) && !u_access.HasPriv(CA_HALFOPME))
+ if (halfop && !u_access.HasPriv("AUTOHALFOP") && !u_access.HasPriv("HALFOPME"))
c->RemoveMode(NULL, CMODE_HALFOP, user->nick);
}
diff --git a/src/init.cpp b/src/init.cpp
index 4cff3fc91..76ba350bb 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -355,6 +355,7 @@ void Init(int ac, char **av)
/* Initialize the socket engine */
SocketEngine::Init();
+ PrivilegeManager::Init();
/* Create me */
Me = new Server(NULL, Config->ServerName, 0, Config->ServerDesc, Config->Numeric);
diff --git a/src/regchannel.cpp b/src/regchannel.cpp
index 882649d54..7eceb5942 100644
--- a/src/regchannel.cpp
+++ b/src/regchannel.cpp
@@ -49,9 +49,6 @@ ChannelInfo::ChannelInfo(const Anope::string &chname) : Flags<ChannelInfoFlag, C
this->memos.memomax = Config->MSMaxMemos;
this->last_used = this->time_registered = Anope::CurTime;
- for (int i = 0; i < CA_SIZE; ++i)
- this->levels[i] = 0;
-
for (int i = 0; i < TTB_SIZE; ++i)
this->ttb[i] = 0;
@@ -781,3 +778,28 @@ void ChannelInfo::RestoreTopic()
}
}
+int16 ChannelInfo::GetLevel(const Anope::string &priv)
+{
+ if (PrivilegeManager::FindPrivilege(priv) == NULL)
+ throw CoreException("Unknown privilege " + priv);
+
+ if (this->levels.count(priv) == 0)
+ this->levels[priv] = 0;
+ return this->levels[priv];
+}
+
+void ChannelInfo::SetLevel(const Anope::string &priv, int16 level)
+{
+ this->levels[priv] = level;
+}
+
+void ChannelInfo::RemoveLevel(const Anope::string &priv)
+{
+ this->levels.erase(priv);
+}
+
+void ChannelInfo::ClearLevels()
+{
+ this->levels.clear();
+}
+