summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2011-08-01 22:37:27 -0400
committerAdam <Adam@anope.org>2011-08-01 22:37:27 -0400
commitf7adc0b35b50f06706872a161f1c7476e6e6981e (patch)
tree91fbe281f2772136a327fd4fc4c64740d1ab65ab /src
parent710c02f3bd3581b7c5b3d48e7604756975219fc8 (diff)
Rewrote the access systems and added a flags access system
Diffstat (limited to 'src')
-rw-r--r--src/access.cpp140
-rw-r--r--src/botserv.cpp14
-rw-r--r--src/channels.cpp38
-rw-r--r--src/chanserv.cpp189
-rw-r--r--src/config.cpp2
-rw-r--r--src/regchannel.cpp195
6 files changed, 223 insertions, 355 deletions
diff --git a/src/access.cpp b/src/access.cpp
new file mode 100644
index 000000000..5fba02c98
--- /dev/null
+++ b/src/access.cpp
@@ -0,0 +1,140 @@
+/*
+ *
+ * (C) 2003-2011 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ */
+
+#include "services.h"
+#include "modules.h"
+#include "access.h"
+
+AccessProvider::AccessProvider(Module *o, const Anope::string &n) : Service(o, n)
+{
+}
+
+AccessProvider::~AccessProvider()
+{
+}
+
+ChanAccess::ChanAccess(AccessProvider *p) : provider(p)
+{
+}
+
+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)))
+ 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)))
+ return true;
+ return false;
+}
+
+bool ChanAccess::operator>=(ChanAccess &other)
+{
+ for (size_t i = CA_SIZE; i > 0; --i)
+ {
+ bool this_p = this->HasPriv(static_cast<ChannelAccess>(i - 1)),
+ other_p = other.HasPriv(static_cast<ChannelAccess>(i - 1));
+
+ if ((this_p && !other_p) || (this_p && other_p))
+ return true;
+ }
+
+ return false;
+}
+
+bool ChanAccess::operator<=(ChanAccess &other)
+{
+ for (size_t i = CA_SIZE; i > 0; --i)
+ {
+ bool this_p = this->HasPriv(static_cast<ChannelAccess>(i - 1)),
+ other_p = other.HasPriv(static_cast<ChannelAccess>(i - 1));
+
+ if ((!this_p && other_p) || (this_p && other_p))
+ return true;
+ }
+
+ return false;
+}
+
+AccessGroup::AccessGroup() : std::vector<ChanAccess *>()
+{
+}
+
+bool AccessGroup::HasPriv(ChannelAccess priv) const
+{
+ for (unsigned i = this->size(); i > 0; --i)
+ if (this->at(i - 1)->HasPriv(priv))
+ return true;
+ return false;
+}
+
+ChanAccess *AccessGroup::Highest() const
+{
+ for (size_t i = CA_SIZE; i > 0; --i)
+ for (unsigned j = this->size(); j > 0; --j)
+ if (this->at(j - 1)->HasPriv(static_cast<ChannelAccess>(i - 1)))
+ return this->at(j - 1);
+ return NULL;
+}
+
+bool AccessGroup::operator>(const AccessGroup &other) const
+{
+ for (size_t i = CA_SIZE; i > 0; --i)
+ if (this->HasPriv(static_cast<ChannelAccess>(i - 1)) && !other.HasPriv(static_cast<ChannelAccess>(i - 1)))
+ return true;
+ return true;
+}
+
+bool AccessGroup::operator<(const AccessGroup &other) const
+{
+ for (size_t i = CA_SIZE; i > 0; --i)
+ if (!this->HasPriv(static_cast<ChannelAccess>(i - 1)) && other.HasPriv(static_cast<ChannelAccess>(i - 1)))
+ return true;
+ return false;
+}
+
+bool AccessGroup::operator>=(const AccessGroup &other) const
+{
+ for (size_t i = CA_SIZE; i > 0; --i)
+ {
+ bool this_p = this->HasPriv(static_cast<ChannelAccess>(i - 1)),
+ other_p = other.HasPriv(static_cast<ChannelAccess>(i - 1));
+
+ if ((this_p && !other_p) || (this_p && other_p))
+ return true;
+ }
+
+ return false;
+}
+
+bool AccessGroup::operator<=(const AccessGroup &other) const
+{
+ for (size_t i = CA_SIZE; i > 0; --i)
+ {
+ bool this_p = this->HasPriv(static_cast<ChannelAccess>(i - 1)),
+ other_p = other.HasPriv(static_cast<ChannelAccess>(i - 1));
+
+ if ((!this_p && other_p) || (this_p && other_p))
+ return true;
+ }
+
+ return false;
+}
+
diff --git a/src/botserv.cpp b/src/botserv.cpp
index 9d7c38817..1670283be 100644
--- a/src/botserv.cpp
+++ b/src/botserv.cpp
@@ -55,9 +55,8 @@ void bot_raw_ban(User *requester, ChannelInfo *ci, User *u, const Anope::string
return;
}
- ChanAccess *u_access = ci->GetAccess(u), *req_access = ci->GetAccess(requester);
- int16 u_level = u_access ? u_access->level : 0, req_level = req_access ? req_access->level : 0;
- if (ci->HasFlag(CI_PEACE) && !requester->nick.equals_ci(u->nick) && u_level >= req_level)
+ AccessGroup u_access = ci->AccessFor(u), req_access = ci->AccessFor(requester);
+ if (ci->HasFlag(CI_PEACE) && u != requester && u_access >= req_access)
return;
if (matches_list(ci->c, u, CMODE_EXCEPT))
@@ -72,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) && !check_access(requester, ci, CA_SIGNKICK)))
+ if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !req_access.HasPriv(CA_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());
@@ -97,12 +96,11 @@ void bot_raw_kick(User *requester, ChannelInfo *ci, User *u, const Anope::string
return;
}
- ChanAccess *u_access = ci->GetAccess(u), *req_access = ci->GetAccess(requester);
- int16 u_level = u_access ? u_access->level : 0, req_level = req_access ? req_access->level : 0;
- if (ci->HasFlag(CI_PEACE) && !requester->nick.equals_ci(u->nick) && u_level >= req_level)
+ AccessGroup u_access = ci->AccessFor(u), req_access = ci->AccessFor(requester);
+ if (ci->HasFlag(CI_PEACE) && requester != u && u_access >= req_access)
return;
- if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !check_access(requester, ci, CA_SIGNKICK)))
+ if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !req_access.HasPriv(CA_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 fe97c5b46..17ed8a629 100644
--- a/src/channels.cpp
+++ b/src/channels.cpp
@@ -1071,47 +1071,51 @@ void do_cmode(const Anope::string &source, const Anope::string &channel, const A
**/
void chan_set_correct_modes(User *user, Channel *c, int give_modes)
{
- ChannelInfo *ci;
- ChannelMode *owner, *admin, *op, *halfop, *voice;
+ ChannelMode *owner = ModeManager::FindChannelModeByName(CMODE_OWNER),
+ *admin = ModeManager::FindChannelModeByName(CMODE_PROTECT),
+ *op = ModeManager::FindChannelModeByName(CMODE_OP),
+ *halfop = ModeManager::FindChannelModeByName(CMODE_HALFOP),
+ *voice = ModeManager::FindChannelModeByName(CMODE_VOICE);
- owner = ModeManager::FindChannelModeByName(CMODE_OWNER);
- admin = ModeManager::FindChannelModeByName(CMODE_PROTECT);
- op = ModeManager::FindChannelModeByName(CMODE_OP);
- halfop = ModeManager::FindChannelModeByName(CMODE_HALFOP);
- voice = ModeManager::FindChannelModeByName(CMODE_VOICE);
+ if (user == NULL || c == NULL)
+ return;
+
+ ChannelInfo *ci = c->ci;
- if (!c || !(ci = c->ci))
+ if (ci == NULL)
return;
Log(LOG_DEBUG) << "Setting correct user modes for " << user->nick << " on " << c->name << " (" << (give_modes ? "" : "not ") << "giving modes)";
+ AccessGroup u_access = ci->AccessFor(user);
+
if (give_modes && (!user->Account() || user->Account()->HasFlag(NI_AUTOOP)))
{
- if (owner && check_access(user, ci, CA_AUTOOWNER))
+ if (owner && u_access.HasPriv(CA_AUTOOWNER))
c->SetMode(NULL, CMODE_OWNER, user->nick);
- else if (admin && check_access(user, ci, CA_AUTOPROTECT))
+ else if (admin && u_access.HasPriv(CA_AUTOPROTECT))
c->SetMode(NULL, CMODE_PROTECT, user->nick);
- if (op && check_access(user, ci, CA_AUTOOP))
+ if (op && u_access.HasPriv(CA_AUTOOP))
c->SetMode(NULL, CMODE_OP, user->nick);
- else if (halfop && check_access(user, ci, CA_AUTOHALFOP))
+ else if (halfop && u_access.HasPriv(CA_AUTOHALFOP))
c->SetMode(NULL, CMODE_HALFOP, user->nick);
- else if (voice && check_access(user, ci, CA_AUTOVOICE))
+ else if (voice && u_access.HasPriv(CA_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 && c->HasUserStatus(user, CMODE_OWNER) && !check_access(user, ci, CA_FOUNDER))
+ if (owner && c->HasUserStatus(user, CMODE_OWNER) && !u_access.HasPriv(CA_AUTOOWNER) && !u_access.HasPriv(CA_PROTECTME))
c->RemoveMode(NULL, CMODE_OWNER, user->nick);
- if (admin && c->HasUserStatus(user, CMODE_PROTECT) && !check_access(user, ci, CA_AUTOPROTECT) && !check_access(user, ci, CA_PROTECTME))
+ if (admin && c->HasUserStatus(user, CMODE_PROTECT) && !u_access.HasPriv(CA_AUTOPROTECT) && !u_access.HasPriv(CA_PROTECTME))
c->RemoveMode(NULL, CMODE_PROTECT, user->nick);
- if (op && c->HasUserStatus(user, CMODE_OP) && !check_access(user, ci, CA_AUTOOP) && !check_access(user, ci, CA_OPDEOPME))
+ if (op && c->HasUserStatus(user, CMODE_OP) && !u_access.HasPriv(CA_AUTOOP) && !u_access.HasPriv(CA_OPDEOPME))
c->RemoveMode(NULL, CMODE_OP, user->nick);
- if (halfop && c->HasUserStatus(user, CMODE_HALFOP) && !check_access(user, ci, CA_AUTOHALFOP) && !check_access(user, ci, CA_HALFOPME))
+ if (halfop && c->HasUserStatus(user, CMODE_HALFOP) && !u_access.HasPriv(CA_AUTOHALFOP) && !u_access.HasPriv(CA_HALFOPME))
c->RemoveMode(NULL, CMODE_HALFOP, user->nick);
}
diff --git a/src/chanserv.cpp b/src/chanserv.cpp
index 6a39340ae..c7bbe11f8 100644
--- a/src/chanserv.cpp
+++ b/src/chanserv.cpp
@@ -16,93 +16,6 @@
registered_channel_map RegisteredChannelList;
-static int def_levels[][2] = {
- { CA_AUTOOP, 5 },
- { CA_AUTOVOICE, 3 },
- { CA_NOJOIN, -2 },
- { CA_INVITE, 5 },
- { CA_AKICK, 10 },
- { CA_SET, ACCESS_QOP },
- { CA_UNBAN, 5 },
- { CA_OPDEOP, 5 },
- { CA_ACCESS_LIST, 1 },
- { CA_ACCESS_CHANGE, 10 },
- { CA_MEMO, 10 },
- { CA_ASSIGN, ACCESS_FOUNDER },
- { CA_BADWORDS, 10 },
- { CA_NOKICK, 1 },
- { CA_FANTASIA, 3 },
- { CA_SAY, 5 },
- { CA_GREET, 5 },
- { CA_VOICEME, 3 },
- { CA_VOICE, 5 },
- { CA_GETKEY, 5 },
- { CA_AUTOHALFOP, 4 },
- { CA_AUTOPROTECT, 10 },
- { CA_OPDEOPME, 5 },
- { CA_HALFOPME, 4 },
- { CA_HALFOP, 5 },
- { CA_PROTECTME, 10 },
- { CA_PROTECT, ACCESS_QOP },
- { CA_KICKME, 5 },
- { CA_KICK, 5 },
- { CA_SIGNKICK, ACCESS_FOUNDER },
- { CA_BANME, 5 },
- { CA_BAN, 5 },
- { CA_TOPIC, ACCESS_FOUNDER },
- { CA_MODE, ACCESS_FOUNDER },
- { CA_INFO, ACCESS_QOP },
- { CA_AUTOOWNER, ACCESS_QOP },
- { CA_OWNER, ACCESS_FOUNDER },
- { CA_OWNERME, ACCESS_QOP },
- { CA_FOUNDER, ACCESS_QOP },
- { -1 }
-};
-
-LevelInfo levelinfo[] = {
- { CA_AUTOHALFOP, "AUTOHALFOP", _("Automatic mode +h") },
- { CA_AUTOOP, "AUTOOP", _("Automatic channel operator status") },
- { CA_AUTOPROTECT, "AUTOPROTECT", _("Automatic mode +a") },
- { CA_AUTOVOICE, "AUTOVOICE", _("Automatic mode +v") },
- { CA_NOJOIN, "NOJOIN", _("Not allowed to join channel") },
- { CA_SIGNKICK, "SIGNKICK", _("No signed kick when SIGNKICK LEVEL is used") },
- { CA_ACCESS_LIST, "ACC-LIST", _("Allowed to view the access list") },
- { CA_ACCESS_CHANGE, "ACC-CHANGE", _("Allowed to modify the access list") },
- { CA_AKICK, "AKICK", _("Allowed to use AKICK command") },
- { CA_SET, "SET", _("Allowed to use SET command (not FOUNDER/PASSWORD)"), },
- { CA_BAN, "BAN", _("Allowed to use BAN command") },
- { CA_BANME, "BANME", _("Allowed to ban him/herself") },
- { CA_GETKEY, "GETKEY", _("Allowed to use GETKEY command") },
- { CA_HALFOP, "HALFOP", _("Allowed to (de)halfop him/herself") },
- { CA_HALFOPME, "HALFOPME", _("Allowed to (de)halfop him/herself") },
- { CA_INFO, "INFO", _("Allowed to use INFO command with ALL option") },
- { CA_KICK, "KICK", _("Allowed to use KICK command") },
- { CA_KICKME, "KICKME", _("Allowed to kick him/herself") },
- { CA_INVITE, "INVITE", _("Allowed to use INVITE command") },
- { CA_OPDEOP, "OPDEOP", _("Allowed to use OP/DEOP commands") },
- { CA_OPDEOPME, "OPDEOPME", _("Allowed to (de)op him/herself") },
- { CA_PROTECT, "PROTECT", _("Allowed to use PROTECT/DEPROTECT commands") },
- { CA_PROTECTME, "PROTECTME", _("Allowed to (de)protect him/herself"), },
- { CA_TOPIC, "TOPIC", _("Allowed to use TOPIC command") },
- { CA_MODE, "MODE", _("Allowed to use MODE command") },
- { CA_UNBAN, "UNBAN", _("Allowed to use UNBAN command") },
- { CA_VOICE, "VOICE", _("Allowed to use VOICE/DEVOICE commands") },
- { CA_VOICEME, "VOICEME", _("Allowed to (de)voice him/herself") },
- { CA_MEMO, "MEMO", _("Allowed to list/read channel memos") },
- { CA_ASSIGN, "ASSIGN", _("Allowed to assign/unassign a bot") },
- { CA_BADWORDS, "BADWORDS", _("Allowed to use BADWORDS command") },
- { CA_FANTASIA, "FANTASIA", _("Allowed to use fantaisist commands") },
- { CA_GREET, "GREET", _("Greet message displayed") },
- { CA_NOKICK, "NOKICK", _("Never kicked by the bot's kickers") },
- { CA_SAY, "SAY", _("Allowed to use SAY and ACT commands") },
- { CA_AUTOOWNER, "AUTOOWNER", _("Automatic mode +q") },
- { CA_OWNER, "OWNER", _("Allowed to use OWNER command") },
- { CA_OWNERME, "OWNERME", _("Allowed to (de)owner him/herself") },
- { CA_FOUNDER, "FOUNDER", _("Allowed to issue commands restricted to channel founders") },
- { -1 }
-};
-int levelinfo_maxwidth = 0;
-
/*************************************************************************/
/* Check the current modes on a channel; if they conflict with a mode lock,
@@ -201,72 +114,6 @@ ChannelInfo *cs_findchan(const Anope::string &chan)
/*************************************************************************/
-/* Return 1 if the user's access level on the given channel falls into the
- * given category, 0 otherwise. Note that this may seem slightly confusing
- * in some cases: for example, check_access(..., CA_NOJOIN) returns true if
- * the user does _not_ have access to the channel (i.e. matches the NOJOIN
- * criterion). */
-
-int check_access(User *user, ChannelInfo *ci, int what)
-{
- int level, limit;
-
- if (!user || !ci)
- return 0;
-
- ChanAccess *u_access = ci->GetAccess(user);
- level = u_access ? u_access->level : 0;
- limit = ci->levels[what];
-
- // Set should never be disabled, if it is it is db-converter screwup
- // This all needs rewritten anyway...
- if (what == CA_SET && limit == ACCESS_INVALID)
- {
- ci->levels[what] = ACCESS_FOUNDER;
- limit = ACCESS_FOUNDER;
- }
-
- /* Resetting the last used time */
- if (level > 0)
- ci->last_used = Anope::CurTime;
-
- /* Superadmin always wins. Always. */
- if (user->isSuperAdmin)
- return what == CA_NOJOIN ? 0 : 1;
- /* If the access of the level we are checking is disabled, they *always* get denied */
- if (limit == ACCESS_INVALID)
- return 0;
- /* If the level of the user is >= the level for "founder" of this channel and "founder" isn't disabled, they can do anything */
- if (ci->levels[CA_FOUNDER] != ACCESS_INVALID && level >= ci->levels[CA_FOUNDER])
- return what == CA_NOJOIN ? 0 : 1;
-
- if (what == CA_NOJOIN)
- return level <= ci->levels[what];
- else
- return level >= ci->levels[what];
-}
-
-/* Reset channel access level values to their default state. */
-
-void reset_levels(ChannelInfo *ci)
-{
- int i;
-
- if (!ci)
- {
- Log() << "reset_levels() called with NULL values";
- return;
- }
-
- if (ci->levels)
- delete [] ci->levels;
- ci->levels = new int16[CA_SIZE];
- for (i = 0; def_levels[i][0] >= 0; ++i)
- ci->levels[def_levels[i][0]] = def_levels[i][1];
-}
-
-/*************************************************************************/
-
/** Is the user the real founder?
* @param user The user
* @param ci The channel
@@ -290,14 +137,12 @@ bool IsFounder(User *user, ChannelInfo *ci)
void update_cs_lastseen(User *user, ChannelInfo *ci)
{
- ChanAccess *access;
-
- if (!ci || !user || !user->Account())
+ if (!ci || !user)
return;
-
- if (IsFounder(user, ci) || user->IsIdentified() || (user->IsRecognized() && !ci->HasFlag(CI_SECURE)))
- if ((access = ci->GetAccess(user)))
- access->last_seen = Anope::CurTime;
+
+ AccessGroup u_access = ci->AccessFor(user);
+ for (unsigned i = u_access.size(); i > 0; --i)
+ u_access[i - 1]->last_seen = Anope::CurTime;
}
/*************************************************************************/
@@ -339,30 +184,6 @@ int get_idealban(ChannelInfo *ci, User *u, Anope::string &ret)
}
}
-/*************************************************************************/
-
-Anope::string get_xop_level(int level)
-{
- ChannelMode *halfop = ModeManager::FindChannelModeByName(CMODE_HALFOP);
-
- if (level < ACCESS_VOP)
- return "Err";
- else if (halfop && level < ACCESS_HOP)
- return "VOP";
- else if (!halfop && level < ACCESS_AOP)
- return "VOP";
- else if (halfop && level < ACCESS_AOP)
- return "HOP";
- else if (level < ACCESS_SOP)
- return "AOP";
- else if (level < ACCESS_QOP)
- return "SOP";
- else if (level < ACCESS_FOUNDER)
- return "QOP";
- else
- return "Founder";
-}
-
ChanServTimer::ChanServTimer(Channel *chan) : Timer(Config->CSInhabit), c(chan)
{
BotInfo *bi = findbot(Config->ChanServ);
diff --git a/src/config.cpp b/src/config.cpp
index 5938d3f67..4790cd34d 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -110,8 +110,6 @@ ServerConfig::ServerConfig() : config_data(), NSDefFlags(NickCoreFlagStrings), C
this->CSDefFlags.SetFlag(CI_SIGNKICK_LEVEL);
else if (option.equals_ci("opnotice"))
this->CSDefFlags.SetFlag(CI_OPNOTICE);
- else if (option.equals_ci("xop"))
- this->CSDefFlags.SetFlag(CI_XOP);
else if (option.equals_ci("peace"))
this->CSDefFlags.SetFlag(CI_PEACE);
else if (option.equals_ci("persist"))
diff --git a/src/regchannel.cpp b/src/regchannel.cpp
index 65613097b..1220669e0 100644
--- a/src/regchannel.cpp
+++ b/src/regchannel.cpp
@@ -12,25 +12,6 @@
#include "services.h"
#include "modules.h"
-ChanAccess::ChanAccess(const Anope::string &umask)
-{
- NickAlias *na = findnick(umask);
- if (na != NULL)
- this->nc = na->nc;
- else
- {
- this->nc = NULL;
- this->mask = umask;
- }
-}
-
-const Anope::string &ChanAccess::GetMask()
-{
- if (this->nc != NULL)
- return this->nc->display;
- return this->mask;
-}
-
/** Default constructor
* @param chname The channel name
*/
@@ -41,7 +22,6 @@ ChannelInfo::ChannelInfo(const Anope::string &chname) : Flags<ChannelInfoFlag, C
this->founder = this->successor = NULL;
this->last_topic_time = 0;
- this->levels = NULL;
this->c = findchan(chname);
if (this->c)
this->c->ci = this;
@@ -69,12 +49,12 @@ ChannelInfo::ChannelInfo(const Anope::string &chname) : Flags<ChannelInfoFlag, C
this->memos.memomax = Config->MSMaxMemos;
this->last_used = this->time_registered = Anope::CurTime;
- this->ttb = new int16[TTB_SIZE];
+ for (int i = 0; i < CA_SIZE; ++i)
+ this->levels[i] = 0;
+
for (int i = 0; i < TTB_SIZE; ++i)
this->ttb[i] = 0;
- reset_levels(this);
-
RegisteredChannelList[this->name] = this;
}
@@ -95,19 +75,11 @@ ChannelInfo::ChannelInfo(ChannelInfo *ci) : Flags<ChannelInfoFlag, CI_END>(Chann
if (this->bi)
++this->bi->chancount;
- this->ttb = new int16[TTB_SIZE];
for (int i = 0; i < TTB_SIZE; ++i)
this->ttb[i] = ci->ttb[i];
+
+ // XXX access
- this->levels = new int16[CA_SIZE];
- for (int i = 0; i < CA_SIZE; ++i)
- this->levels[i] = ci->levels[i];
-
- for (unsigned i = 0; i < ci->GetAccessCount(); ++i)
- {
- ChanAccess *taccess = ci->GetAccess(i);
- this->AddAccess(taccess->GetMask(), taccess->level, taccess->creator, taccess->last_seen);
- }
for (unsigned i = 0; i < ci->GetAkickCount(); ++i)
{
AutoKick *takick = ci->GetAkick(i);
@@ -145,8 +117,6 @@ ChannelInfo::~ChannelInfo()
this->ClearAccess();
this->ClearAkick();
this->ClearBadWords();
- if (this->levels)
- delete [] this->levels;
if (!this->memos.memos.empty())
{
@@ -155,9 +125,6 @@ ChannelInfo::~ChannelInfo()
this->memos.memos.clear();
}
- if (this->ttb)
- delete [] this->ttb;
-
if (this->founder)
--this->founder->channelcount;
}
@@ -200,29 +167,11 @@ BotInfo *ChannelInfo::WhoSends()
}
/** Add an entry to the channel access list
- *
- * @param mask The mask of the access entry
- * @param level The channel access level the user has on the channel
- * @param creator The user who added the access
- * @param last_seen When the user was last seen within the channel
- * @return The new access class
- *
- * Creates a new access list entry and inserts it into the access list.
+ * @param access The entry
*/
-
-ChanAccess *ChannelInfo::AddAccess(const Anope::string &mask, int16 level, const Anope::string &creator, int32 last_seen)
+void ChannelInfo::AddAccess(ChanAccess *access)
{
- ChanAccess *new_access = new ChanAccess(mask);
- new_access->level = level;
- new_access->last_seen = last_seen;
- if (!creator.empty())
- new_access->creator = creator;
- else
- new_access->creator = "Unknown";
-
- this->access.push_back(new_access);
-
- return new_access;
+ this->access.push_back(access);
}
/** Get an entry from the channel access list by index
@@ -240,104 +189,68 @@ ChanAccess *ChannelInfo::GetAccess(unsigned index)
return this->access[index];
}
-/** Get an entry from the channel access list by NickCore
+/** Check if a user has a privilege on a channel
*
* @param u The User to find within the access list vector
- * @param level Optional channel access level to compare the access entries to
- * @return A ChanAccess struct corresponding to the NickCore, or NULL if not found
+ * @param priv The privilege to check for.
+ * @return true if the user has the privilege
*
- * Retrieves an entry from the access list that matches the given NickCore, optionally also matching a certain level.
+ * Retrieves an entry from the access list that matches the given User and NickCore.
*/
-
-ChanAccess *ChannelInfo::GetAccess(User *u, int16 level)
+bool ChannelInfo::HasPriv(User *u, ChannelAccess priv)
{
- if (!u)
- return NULL;
+ AccessGroup group = this->AccessFor(u);
- if (u->isSuperAdmin || IsFounder(u, this))
+ if (this->founder && u->Account() == this->founder)
{
- static ChanAccess dummy_access("");
- new(&dummy_access) ChanAccess(u->nick + "!*@*");
- dummy_access.level = u->isSuperAdmin ? ACCESS_SUPERADMIN : ACCESS_FOUNDER;
- dummy_access.last_seen = Anope::CurTime;
- return &dummy_access;
+ switch (priv)
+ {
+ case CA_AUTOOWNER:
+ case CA_AUTOPROTECT:
+ case CA_AUTOOP:
+ case CA_AUTOHALFOP:
+ case CA_AUTOVOICE:
+ break;
+ default:
+ return true;
+ }
}
-
- if (this->access.empty())
- return NULL;
-
- ChanAccess *highest = NULL;
- for (unsigned i = 0, end = this->access.size(); i < end; ++i)
- {
- ChanAccess *taccess = this->access[i];
- if (level && level != taccess->level)
- continue;
- /* Access entry is a mask and we match it */
- else if (!taccess->nc && (Anope::Match(u->nick, taccess->GetMask()) || Anope::Match(u->GetDisplayedMask(), taccess->GetMask())))
- ;
- /* Access entry is a nick core and we are identified for that account */
- else if (taccess->nc && (u->IsIdentified() || (u->IsRecognized() && !this->HasFlag(CI_SECURE))) && u->Account() == taccess->nc)
- ;
- else
- continue;
- /* Use the highest level access available */
- if (!highest || taccess->level > highest->level)
- highest = taccess;
- }
+ if (group.HasPriv(CA_FOUNDER) || group.HasPriv(priv))
+ return true;
- return highest;
+ return false;
}
-/** Get an entry from the channel access list by NickCore
- *
- * @param u The NickCore to find within the access list vector
- * @param level Optional channel access level to compare the access entries to
- * @return A ChanAccess struct corresponding to the NickCore, or NULL if not found
- *
- * Retrieves an entry from the access list that matches the given NickCore, optionally also matching a certain level.
- */
-ChanAccess *ChannelInfo::GetAccess(NickCore *nc, int16 level)
+AccessGroup ChannelInfo::AccessFor(User *u)
{
- if (nc == this->founder)
+ NickCore *nc = u->Account();
+ if (nc == NULL && u->IsRecognized())
{
- static ChanAccess dummy_access("");
- new(&dummy_access) ChanAccess(nc->display);
- dummy_access.level = ACCESS_FOUNDER;
- dummy_access.last_seen = Anope::CurTime;
- return &dummy_access;
+ NickAlias *na = findnick(u->nick);
+ if (na != NULL)
+ nc = na->nc;
}
+
+ AccessGroup group;
+
for (unsigned i = 0, end = this->access.size(); i < end; ++i)
- {
- if (level && this->access[i]->level != level)
- continue;
- if (this->access[i]->nc && this->access[i]->nc == nc)
- return this->access[i];
- }
- return NULL;
+ if (this->access[i]->Matches(u, nc))
+ group.push_back(this->access[i]);
+
+ return group;
}
-/** Get an entry from the channel access list by mask
- *
- * @param u The mask to find within the access list vector
- * @param level Optional channel access level to compare the access entries to
- * @param wildcard True to match using wildcards
- * @return A ChanAccess struct corresponding to the mask, or NULL if not found
- *
- * Retrieves an entry from the access list that matches the given mask, optionally also matching a certain level.
- */
-ChanAccess *ChannelInfo::GetAccess(const Anope::string &mask, int16 level, bool wildcard)
+AccessGroup ChannelInfo::AccessFor(NickCore *nc)
{
+ AccessGroup group;
+
for (unsigned i = 0, end = this->access.size(); i < end; ++i)
- if (this->access[i]->nc != NULL)
- {
- if (wildcard ? Anope::Match(this->access[i]->nc->display, mask) : this->access[i]->nc->display.equals_ci(mask))
- return this->access[i];
- }
- else if (wildcard ? Anope::Match(this->access[i]->GetMask(), mask) : this->access[i]->GetMask().equals_ci(mask))
- return this->access[i];
- return NULL;
+ if (this->access[i]->Matches(NULL, nc))
+ group.push_back(this->access[i]);
+
+ return group;
}
/** Get the size of the accss vector for this channel
@@ -345,7 +258,7 @@ ChanAccess *ChannelInfo::GetAccess(const Anope::string &mask, int16 level, bool
*/
unsigned ChannelInfo::GetAccessCount() const
{
- return this->access.empty() ? 0 : this->access.size();
+ return this->access.size();
}
/** Erase an entry from the channel access list
@@ -375,6 +288,7 @@ void ChannelInfo::EraseAccess(ChanAccess *taccess)
{
if (this->access[i] == taccess)
{
+ delete this->access[i];
this->access.erase(this->access.begin() + i);
break;
}
@@ -838,13 +752,6 @@ bool ChannelInfo::CheckKick(User *user)
}
}
- if (!do_kick && check_access(user, this, CA_NOJOIN))
- {
- get_idealban(this, user, mask);
- reason = translate(user, CHAN_NOT_ALLOWED_TO_JOIN);
- do_kick = true;
- }
-
if (!do_kick)
return false;