mirror of
https://github.com/anope/anope.git
synced 2026-06-30 09:16:38 +02:00
Allowing adding hostmasks to channel access lists
This commit is contained in:
+1
-4
@@ -63,8 +63,6 @@ E Channel *findchan(const Anope::string &chan);
|
||||
|
||||
E User *nc_on_chan(Channel *c, const NickCore *nc);
|
||||
|
||||
E int get_access_level(ChannelInfo *ci, NickAlias *na);
|
||||
E int get_access_level(ChannelInfo *ci, NickCore *nc);
|
||||
E Anope::string get_xop_level(int level);
|
||||
|
||||
E void do_cmode(const Anope::string &source, const Anope::string &channel, const Anope::string &modes, const Anope::string &ts);
|
||||
@@ -91,7 +89,7 @@ E void get_chanserv_stats(long *nrec, long *memuse);
|
||||
E void reset_levels(ChannelInfo *ci);
|
||||
E void cs_init();
|
||||
E void expire_chans();
|
||||
E void cs_remove_nick(const NickCore *nc);
|
||||
E void cs_remove_nick(NickCore *nc);
|
||||
|
||||
E void check_modes(Channel *c);
|
||||
E int check_valid_admin(User *user, Channel *chan, int servermode);
|
||||
@@ -100,7 +98,6 @@ E int check_valid_op(User *user, Channel *chan, int servermode);
|
||||
E ChannelInfo *cs_findchan(const Anope::string &chan);
|
||||
E int check_access(User *user, ChannelInfo *ci, int what);
|
||||
E bool IsFounder(User *user, ChannelInfo *ci);
|
||||
E int get_access(User *user, ChannelInfo *ci);
|
||||
E void update_cs_lastseen(User *user, ChannelInfo *ci);
|
||||
E int get_idealban(ChannelInfo *ci, User *u, Anope::string &ret);
|
||||
|
||||
|
||||
@@ -392,7 +392,6 @@ enum LanguageString
|
||||
CHAN_XOP_NOT_AVAILABLE,
|
||||
CHAN_QOP_SYNTAX,
|
||||
CHAN_QOP_DISABLED,
|
||||
CHAN_QOP_NICKS_ONLY,
|
||||
CHAN_QOP_ADDED,
|
||||
CHAN_QOP_MOVED,
|
||||
CHAN_QOP_NO_SUCH_ENTRY,
|
||||
@@ -406,7 +405,6 @@ enum LanguageString
|
||||
CHAN_QOP_CLEAR,
|
||||
CHAN_AOP_SYNTAX,
|
||||
CHAN_AOP_DISABLED,
|
||||
CHAN_AOP_NICKS_ONLY,
|
||||
CHAN_AOP_ADDED,
|
||||
CHAN_AOP_MOVED,
|
||||
CHAN_AOP_NO_SUCH_ENTRY,
|
||||
@@ -420,7 +418,6 @@ enum LanguageString
|
||||
CHAN_AOP_CLEAR,
|
||||
CHAN_HOP_SYNTAX,
|
||||
CHAN_HOP_DISABLED,
|
||||
CHAN_HOP_NICKS_ONLY,
|
||||
CHAN_HOP_ADDED,
|
||||
CHAN_HOP_MOVED,
|
||||
CHAN_HOP_NO_SUCH_ENTRY,
|
||||
@@ -434,7 +431,6 @@ enum LanguageString
|
||||
CHAN_HOP_CLEAR,
|
||||
CHAN_SOP_SYNTAX,
|
||||
CHAN_SOP_DISABLED,
|
||||
CHAN_SOP_NICKS_ONLY,
|
||||
CHAN_SOP_ADDED,
|
||||
CHAN_SOP_MOVED,
|
||||
CHAN_SOP_NO_SUCH_ENTRY,
|
||||
@@ -448,7 +444,6 @@ enum LanguageString
|
||||
CHAN_SOP_CLEAR,
|
||||
CHAN_VOP_SYNTAX,
|
||||
CHAN_VOP_DISABLED,
|
||||
CHAN_VOP_NICKS_ONLY,
|
||||
CHAN_VOP_ADDED,
|
||||
CHAN_VOP_MOVED,
|
||||
CHAN_VOP_NO_SUCH_ENTRY,
|
||||
@@ -466,7 +461,6 @@ enum LanguageString
|
||||
CHAN_ACCESS_DISABLED,
|
||||
CHAN_ACCESS_LEVEL_NONZERO,
|
||||
CHAN_ACCESS_LEVEL_RANGE,
|
||||
CHAN_ACCESS_NICKS_ONLY,
|
||||
CHAN_ACCESS_REACHED_LIMIT,
|
||||
CHAN_ACCESS_LEVEL_UNCHANGED,
|
||||
CHAN_ACCESS_LEVEL_CHANGED,
|
||||
|
||||
+6
-8
@@ -723,25 +723,23 @@ class CoreExport Module : public Extensible
|
||||
/** Called when access is deleted from a channel
|
||||
* @param ci The channel
|
||||
* @param u The user who removed the access
|
||||
* @param nc The user who was deleted
|
||||
* @param access The access entry being removed
|
||||
*/
|
||||
virtual void OnAccessDel(ChannelInfo *ci, User *u, NickCore *nc) { }
|
||||
virtual void OnAccessDel(ChannelInfo *ci, User *u, ChanAccess *access) { }
|
||||
|
||||
/** Called when access is changed
|
||||
* @param ci The channel
|
||||
* @param u The user who changed the access
|
||||
* @param nc The nick whos access was changed
|
||||
* @param level The level of the new access
|
||||
* @param u access The access changed
|
||||
*/
|
||||
virtual void OnAccessChange(ChannelInfo *ci, User *u, NickCore *nc, int level) { }
|
||||
virtual void OnAccessChange(ChannelInfo *ci, User *u, ChanAccess *access) { }
|
||||
|
||||
/** Called when access is added
|
||||
* @param ci The channel
|
||||
* @param u The user who added the access
|
||||
* @para nc The nick who was added to access
|
||||
* @param level The level they were added at
|
||||
* @param access The access changed
|
||||
*/
|
||||
virtual void OnAccessAdd(ChannelInfo *ci, User *u, NickCore *nc, int level) { }
|
||||
virtual void OnAccessAdd(ChannelInfo *ci, User *u, ChanAccess *access) { }
|
||||
|
||||
/** Called when the access list is cleared
|
||||
* @param ci The channel
|
||||
|
||||
+33
-4
@@ -132,14 +132,15 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
|
||||
|
||||
/** Add an entry to the channel access list
|
||||
*
|
||||
* @param nc The NickCore of the user that the access entry should be tied to
|
||||
* @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.
|
||||
*/
|
||||
void AddAccess(NickCore *nc, int16 level, const Anope::string &creator, int32 last_seen = 0);
|
||||
ChanAccess *AddAccess(const Anope::string &mask, int16 level, const Anope::string &creator, int32 last_seen = 0);
|
||||
|
||||
/** Get an entry from the channel access list by index
|
||||
*
|
||||
@@ -150,15 +151,35 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
|
||||
*/
|
||||
ChanAccess *GetAccess(unsigned index);
|
||||
|
||||
/** Get an entry from the channel access list by User
|
||||
*
|
||||
* @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 User, or NULL if not found
|
||||
*
|
||||
* Retrieves an entry from the access list that matches the given User, optionally also matching a certain level.
|
||||
*/
|
||||
ChanAccess *GetAccess(User *u, int16 level = 0);
|
||||
|
||||
/** Get an entry from the channel access list by NickCore
|
||||
*
|
||||
* @param nc The NickCore to find within the access list vector
|
||||
* @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 *GetAccess(const NickCore *nc, int16 level = 0);
|
||||
ChanAccess *GetAccess(NickCore *nc, int16 level = 0);
|
||||
|
||||
/** 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
|
||||
* @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 *GetAccess(const Anope::string &mask, int16 level = 0);
|
||||
|
||||
/** Get the size of the accss vector for this channel
|
||||
* @return The access vector size
|
||||
@@ -173,6 +194,14 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
|
||||
*/
|
||||
void EraseAccess(unsigned index);
|
||||
|
||||
/** Erase an entry from the channel access list
|
||||
*
|
||||
* @param access The access to remove
|
||||
*
|
||||
* Clears the memory used by the given access entry and removes it from the vector.
|
||||
*/
|
||||
void EraseAccess(ChanAccess *access);
|
||||
|
||||
/** Clear the entire channel access list
|
||||
*
|
||||
* Clears the entire access list by deleting every item and then clearing the vector.
|
||||
|
||||
+2
-1
@@ -571,7 +571,8 @@ enum AccessLevel
|
||||
struct ChanAccess
|
||||
{
|
||||
int16 level;
|
||||
NickCore *nc; /* Guaranteed to be non-NULL if in use, NULL if not */
|
||||
Anope::string mask; /* Mask of the access entry */
|
||||
NickCore *nc; /* NC of the entry, if the entry is a valid nickcore */
|
||||
time_t last_seen;
|
||||
Anope::string creator;
|
||||
};
|
||||
|
||||
+47
-64
@@ -50,10 +50,10 @@ class AccessListCallback : public NumberList
|
||||
if (source.ci->HasFlag(CI_XOP))
|
||||
{
|
||||
Anope::string xop = get_xop_level(access->level);
|
||||
source.Reply(CHAN_ACCESS_LIST_XOP_FORMAT, Number + 1, xop.c_str(), access->nc->display.c_str());
|
||||
source.Reply(CHAN_ACCESS_LIST_XOP_FORMAT, Number + 1, xop.c_str(), access->mask.c_str());
|
||||
}
|
||||
else
|
||||
source.Reply(CHAN_ACCESS_LIST_AXS_FORMAT, Number + 1, access->level, access->nc->display.c_str());
|
||||
source.Reply(CHAN_ACCESS_LIST_AXS_FORMAT, Number + 1, access->level, access->mask.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -93,10 +93,10 @@ class AccessViewCallback : public AccessListCallback
|
||||
if (ci->HasFlag(CI_XOP))
|
||||
{
|
||||
Anope::string xop = get_xop_level(access->level);
|
||||
source.Reply(CHAN_ACCESS_VIEW_XOP_FORMAT, Number + 1, xop.c_str(), access->nc->display.c_str(), access->creator.c_str(), timebuf.c_str());
|
||||
source.Reply(CHAN_ACCESS_VIEW_XOP_FORMAT, Number + 1, xop.c_str(), access->mask.c_str(), access->creator.c_str(), timebuf.c_str());
|
||||
}
|
||||
else
|
||||
source.Reply(CHAN_ACCESS_VIEW_AXS_FORMAT, Number + 1, access->level, access->nc->display.c_str(), access->creator.c_str(), timebuf.c_str());
|
||||
source.Reply(CHAN_ACCESS_VIEW_AXS_FORMAT, Number + 1, access->level, access->mask.c_str(), access->creator.c_str(), timebuf.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -142,7 +142,9 @@ class AccessDelCallback : public NumberList
|
||||
|
||||
ChanAccess *access = ci->GetAccess(Number - 1);
|
||||
|
||||
if (get_access(u, ci) <= access->level && !u->Account()->HasPriv("chanserv/access/modify"))
|
||||
ChanAccess *u_access = ci->GetAccess(u);
|
||||
int16 u_level = u_access ? u_access->level : 0;
|
||||
if (u_level <= access->level && !u->Account()->HasPriv("chanserv/access/modify"))
|
||||
{
|
||||
Denied = true;
|
||||
return;
|
||||
@@ -150,11 +152,11 @@ class AccessDelCallback : public NumberList
|
||||
|
||||
++Deleted;
|
||||
if (!Nicks.empty())
|
||||
Nicks += ", " + access->nc->display;
|
||||
Nicks += ", " + access->mask;
|
||||
else
|
||||
Nicks = access->nc->display;
|
||||
Nicks = access->mask;
|
||||
|
||||
FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, access->nc));
|
||||
FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, access));
|
||||
|
||||
ci->EraseAccess(Number - 1);
|
||||
}
|
||||
@@ -167,11 +169,12 @@ class CommandCSAccess : public Command
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
const Anope::string &nick = params[2];
|
||||
Anope::string mask = params[2];
|
||||
int level = params[3].is_number_only() ? convertTo<int>(params[3]) : ACCESS_INVALID;
|
||||
int ulev = get_access(u, ci);
|
||||
|
||||
if (level >= ulev && !u->Account()->HasPriv("chanserv/access/modify"))
|
||||
ChanAccess *u_access = ci->GetAccess(u);
|
||||
int16 u_level = u_access ? u_access->level : 0;
|
||||
if (level >= u_level && !u->Account()->HasPriv("chanserv/access/modify"))
|
||||
{
|
||||
source.Reply(ACCESS_DENIED);
|
||||
return MOD_CONT;
|
||||
@@ -188,41 +191,37 @@ class CommandCSAccess : public Command
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool override = !check_access(u, ci, CA_ACCESS_CHANGE) || level >= ulev;
|
||||
bool override = !check_access(u, ci, CA_ACCESS_CHANGE) || level >= u_level;
|
||||
|
||||
NickAlias *na = findnick(nick);
|
||||
if (!na)
|
||||
NickAlias *na = findnick(mask);
|
||||
if (!na && mask.find_first_of("!@*") == Anope::string::npos)
|
||||
mask += "!*@*";
|
||||
else if (na && na->HasFlag(NS_FORBIDDEN))
|
||||
{
|
||||
source.Reply(CHAN_ACCESS_NICKS_ONLY);
|
||||
return MOD_CONT;
|
||||
}
|
||||
else if (na->HasFlag(NS_FORBIDDEN))
|
||||
{
|
||||
source.Reply(NICK_X_FORBIDDEN, nick.c_str());
|
||||
source.Reply(NICK_X_FORBIDDEN, mask.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
NickCore *nc = na->nc;
|
||||
ChanAccess *access = ci->GetAccess(nc);
|
||||
ChanAccess *access = ci->GetAccess(mask);
|
||||
if (access)
|
||||
{
|
||||
/* Don't allow lowering from a level >= ulev */
|
||||
if (access->level >= ulev && !u->Account()->HasPriv("chanserv/access/modify"))
|
||||
/* Don't allow lowering from a level >= u_level */
|
||||
if (access->level >= u_level && !u->Account()->HasPriv("chanserv/access/modify"))
|
||||
{
|
||||
source.Reply(ACCESS_DENIED);
|
||||
return MOD_CONT;
|
||||
}
|
||||
if (access->level == level)
|
||||
{
|
||||
source.Reply(CHAN_ACCESS_LEVEL_UNCHANGED, access->nc->display.c_str(), ci->name.c_str(), level);
|
||||
source.Reply(CHAN_ACCESS_LEVEL_UNCHANGED, access->mask.c_str(), ci->name.c_str(), level);
|
||||
return MOD_CONT;
|
||||
}
|
||||
access->level = level;
|
||||
|
||||
FOREACH_MOD(I_OnAccessChange, OnAccessChange(ci, u, na->nc, level));
|
||||
FOREACH_MOD(I_OnAccessChange, OnAccessChange(ci, u, access));
|
||||
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << na->nick << " (group: " << nc->display << ") (level: " << level << ") as level " << ulev;
|
||||
source.Reply(CHAN_ACCESS_LEVEL_CHANGED, nc->display.c_str(), ci->name.c_str(), level);
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << na->nick << " (level: " << level << ") as level " << u_level;
|
||||
source.Reply(CHAN_ACCESS_LEVEL_CHANGED, access->mask.c_str(), ci->name.c_str(), level);
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
@@ -232,12 +231,12 @@ class CommandCSAccess : public Command
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
ci->AddAccess(nc, level, u->nick);
|
||||
access = ci->AddAccess(mask, level, u->nick);
|
||||
|
||||
FOREACH_MOD(I_OnAccessAdd, OnAccessAdd(ci, u, nc, level));
|
||||
FOREACH_MOD(I_OnAccessAdd, OnAccessAdd(ci, u, access));
|
||||
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << na->nick << " (group: " << nc->display << ") (level: " << level << ") as level " << ulev;
|
||||
source.Reply(CHAN_ACCESS_ADDED, nc->display.c_str(), ci->name.c_str(), level);
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << mask << " (level: " << level << ") as level " << u_level;
|
||||
source.Reply(CHAN_ACCESS_ADDED, access->mask.c_str(), ci->name.c_str(), level);
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
@@ -247,49 +246,33 @@ class CommandCSAccess : public Command
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
const Anope::string &nick = params[2];
|
||||
const Anope::string &mask = params[2];
|
||||
|
||||
if (!ci->GetAccessCount())
|
||||
source.Reply(CHAN_ACCESS_LIST_EMPTY, ci->name.c_str());
|
||||
else if (isdigit(nick[0]) && nick.find_first_not_of("1234567890,-") == Anope::string::npos)
|
||||
else if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
|
||||
{
|
||||
AccessDelCallback list(source, this, nick);
|
||||
AccessDelCallback list(source, this, mask);
|
||||
list.Process();
|
||||
}
|
||||
else
|
||||
{
|
||||
NickAlias *na = findnick(nick);
|
||||
if (!na)
|
||||
{
|
||||
source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
NickCore *nc = na->nc;
|
||||
|
||||
unsigned i, end;
|
||||
ChanAccess *access = NULL;
|
||||
for (i = 0, end = ci->GetAccessCount(); i < end; ++i)
|
||||
{
|
||||
access = ci->GetAccess(i);
|
||||
|
||||
if (access->nc == nc)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == end)
|
||||
source.Reply(CHAN_ACCESS_NOT_FOUND, nick.c_str(), ci->name.c_str());
|
||||
else if (nc != u->Account() && check_access(u, ci, CA_NOJOIN) && get_access(u, ci) <= access->level && !u->Account()->HasPriv("chanserv/access/modify"))
|
||||
ChanAccess *access = ci->GetAccess(mask);
|
||||
ChanAccess *u_access = ci->GetAccess(u);
|
||||
int16 u_level = u_access ? u_access->level : 0;
|
||||
if (!access)
|
||||
source.Reply(CHAN_ACCESS_NOT_FOUND, mask.c_str(), ci->name.c_str());
|
||||
else if (access->nc != u->Account() && check_access(u, ci, CA_NOJOIN) && u_level <= access->level && !u->Account()->HasPriv("chanserv/access/modify"))
|
||||
source.Reply(ACCESS_DENIED);
|
||||
else
|
||||
{
|
||||
source.Reply(CHAN_ACCESS_DELETED, access->nc->display.c_str(), ci->name.c_str());
|
||||
bool override = !check_access(u, ci, CA_ACCESS_CHANGE) && nc != u->Account();
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DEL " << na->nick << " (group: " << access->nc->display << ") from level " << access->level;
|
||||
source.Reply(CHAN_ACCESS_DELETED, access->mask.c_str(), ci->name.c_str());
|
||||
bool override = !check_access(u, ci, CA_ACCESS_CHANGE) && access->nc != u->Account();
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DEL " << access->mask << " from level " << access->level;
|
||||
|
||||
FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, na->nc));
|
||||
FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, access));
|
||||
|
||||
ci->EraseAccess(i);
|
||||
ci->EraseAccess(access);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -317,7 +300,7 @@ class CommandCSAccess : public Command
|
||||
{
|
||||
ChanAccess *access = ci->GetAccess(i);
|
||||
|
||||
if (!nick.empty() && access->nc && !Anope::Match(access->nc->display, nick))
|
||||
if (!nick.empty() && !Anope::Match(access->mask, nick))
|
||||
continue;
|
||||
|
||||
if (!SentHeader)
|
||||
@@ -359,7 +342,7 @@ class CommandCSAccess : public Command
|
||||
{
|
||||
ChanAccess *access = ci->GetAccess(i);
|
||||
|
||||
if (!nick.empty() && access->nc && !Anope::Match(access->nc->display, nick))
|
||||
if (!nick.empty() && !Anope::Match(access->mask, nick))
|
||||
continue;
|
||||
|
||||
if (!SentHeader)
|
||||
|
||||
@@ -202,7 +202,9 @@ class CommandCSAKick : public Command
|
||||
* or whether the mask matches a user with higher/equal access - Viper */
|
||||
if (ci->HasFlag(CI_PEACE) && nc)
|
||||
{
|
||||
if (nc == ci->founder || get_access_level(ci, nc) >= get_access(u, ci))
|
||||
ChanAccess *nc_access = ci->GetAccess(nc), *u_access = ci->GetAccess(u);
|
||||
int16 nc_level = nc_access ? nc_access->level : 0, u_level = u_access ? u_access->level : 0;
|
||||
if (nc == ci->founder || nc_level >= u_level)
|
||||
{
|
||||
source.Reply(ACCESS_DENIED);
|
||||
return;
|
||||
@@ -216,7 +218,9 @@ class CommandCSAKick : public Command
|
||||
{
|
||||
User *u2 = *it;
|
||||
|
||||
if ((check_access(u2, ci, CA_FOUNDER) || get_access(u2, ci) >= get_access(u, ci)) && match_usermask(mask, u2))
|
||||
ChanAccess *u2_access = ci->GetAccess(nc), *u_access = ci->GetAccess(u);
|
||||
int16 u2_level = u2_access ? u2_access->level : 0, u_level = u_access ? u_access->level : 0;
|
||||
if ((check_access(u2, ci, CA_FOUNDER) || u2_level >= u_level) && match_usermask(mask, u2))
|
||||
{
|
||||
source.Reply(ACCESS_DENIED);
|
||||
return;
|
||||
@@ -232,7 +236,9 @@ class CommandCSAKick : public Command
|
||||
if (na2->HasFlag(NS_FORBIDDEN))
|
||||
continue;
|
||||
|
||||
if (na2->nc && (na2->nc == ci->founder || get_access_level(ci, na2->nc) >= get_access(u, ci)))
|
||||
ChanAccess *na2_access = ci->GetAccess(na2->nc), *u_access = ci->GetAccess(u);
|
||||
int16 na2_level = na2_access ? na2_access->level : 0, u_level = u_access ? u_access->level : 0;
|
||||
if (na2->nc && (na2->nc == ci->founder || na2_level >= u_level))
|
||||
{
|
||||
Anope::string buf = na2->nick + "!" + na2->last_usermask;
|
||||
if (Anope::Match(buf, mask))
|
||||
|
||||
@@ -29,17 +29,19 @@ class CommandCSBan : public Command
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
Channel *c = ci->c;
|
||||
User *u2;
|
||||
|
||||
bool is_same = target.equals_ci(u->nick);
|
||||
User *u2 = is_same ? u : finduser(target);
|
||||
|
||||
ChanAccess *u_access = ci->GetAccess(u), *u2_access = ci->GetAccess(u2);
|
||||
uint16 u_level = u_access ? u_access->level : 0, u2_level = u2_access ? u2_access->level : 0;
|
||||
|
||||
if (!c)
|
||||
source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
|
||||
else if (is_same ? !(u2 = u) : !(u2 = finduser(target)))
|
||||
else if (!u2)
|
||||
source.Reply(NICK_X_NOT_IN_USE, target.c_str());
|
||||
else if (!is_same ? !check_access(u, ci, CA_BAN) : !check_access(u, ci, CA_BANME))
|
||||
source.Reply(ACCESS_DENIED);
|
||||
else if (!is_same && (ci->HasFlag(CI_PEACE)) && (get_access(u2, ci) >= get_access(u, ci)))
|
||||
else if (!is_same && ci->HasFlag(CI_PEACE) && u2_level >= u_level)
|
||||
source.Reply(ACCESS_DENIED);
|
||||
/*
|
||||
* Dont ban/kick the user on channels where he is excepted
|
||||
|
||||
@@ -108,7 +108,7 @@ public:
|
||||
for (unsigned i = 0; i < ci->GetAccessCount(); ++i)
|
||||
{
|
||||
ChanAccess *access = ci->GetAccess(i);
|
||||
target_ci->AddAccess(access->nc, access->level, access->creator, access->last_seen);
|
||||
target_ci->AddAccess(access->mask, access->level, access->creator, access->last_seen);
|
||||
}
|
||||
|
||||
source.Reply(CHAN_CLONED_ACCESS, channel.c_str(), target.c_str());
|
||||
|
||||
@@ -29,17 +29,19 @@ class CommandCSKick : public Command
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
Channel *c = ci->c;
|
||||
User *u2;
|
||||
|
||||
bool is_same = target.equals_ci(u->nick);
|
||||
User *u2 = is_same ? u : finduser(target);
|
||||
|
||||
ChanAccess *u_access = ci->GetAccess(u), *u2_access = ci->GetAccess(u2);
|
||||
uint16 u_level = u_access ? u_access->level : 0, u2_level = u2_access ? u2_access->level : 0;
|
||||
|
||||
if (!c)
|
||||
source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
|
||||
else if (is_same ? !(u2 = u) : !(u2 = finduser(target)))
|
||||
else if (!u2)
|
||||
source.Reply(NICK_X_NOT_IN_USE, target.c_str());
|
||||
else if (!is_same ? !check_access(u, ci, CA_KICK) : !check_access(u, ci, CA_KICKME))
|
||||
source.Reply(ACCESS_DENIED);
|
||||
else if (!is_same && (ci->HasFlag(CI_PEACE)) && get_access(u2, ci) >= get_access(u, ci))
|
||||
else if (!is_same && (ci->HasFlag(CI_PEACE)) && u2_level >= u_level)
|
||||
source.Reply(ACCESS_DENIED);
|
||||
else if (u2->IsProtected())
|
||||
source.Reply(ACCESS_DENIED);
|
||||
|
||||
@@ -30,18 +30,20 @@ static CommandReturn do_util(CommandSource &source, Command *com, ChannelMode *c
|
||||
User *u = source.u;
|
||||
Channel *c = findchan(chan);
|
||||
ChannelInfo *ci = c ? c->ci : NULL;
|
||||
User *u2;
|
||||
|
||||
Anope::string realnick = (!nick.empty() ? nick : u->nick);
|
||||
bool is_same = u->nick.equals_ci(realnick);
|
||||
User *u2 = is_same ? u : finduser(realnick);
|
||||
|
||||
ChanAccess *u_access = ci->GetAccess(u), *u2_access = ci->GetAccess(u2);
|
||||
uint16 u_level = u_access ? u_access->level : 0, u2_level = u2_access ? u2_access->level : 0;
|
||||
|
||||
if (!c)
|
||||
source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
|
||||
else if (is_same ? !(u2 = u) : !(u2 = finduser(realnick)))
|
||||
else if (!u2)
|
||||
source.Reply(NICK_X_NOT_IN_USE, realnick.c_str());
|
||||
else if (is_same ? !check_access(u, ci, levelself) : !check_access(u, ci, level))
|
||||
source.Reply(ACCESS_DENIED);
|
||||
else if (!set && !is_same && (ci->HasFlag(CI_PEACE)) && (get_access(u2, ci) >= get_access(u, ci)))
|
||||
else if (!set && !is_same && ci->HasFlag(CI_PEACE) && u2_level >= u_level)
|
||||
source.Reply(ACCESS_DENIED);
|
||||
else if (!set && u2->IsProtected() && !is_same)
|
||||
source.Reply(ACCESS_DENIED);
|
||||
|
||||
@@ -28,7 +28,7 @@ class CommandCSRegister : public Command
|
||||
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
Channel *c = ci->c;
|
||||
Channel *c = findchan(chan);
|
||||
|
||||
if (readonly)
|
||||
{
|
||||
@@ -42,7 +42,7 @@ class CommandCSRegister : public Command
|
||||
source.Reply(CHAN_SYMBOL_REQUIRED);
|
||||
else if (!ircdproto->IsChannelValid(chan))
|
||||
source.Reply(CHAN_X_INVALID, chan.c_str());
|
||||
else if ((ci = cs_findchan(chan)))
|
||||
else if (ci)
|
||||
source.Reply(CHAN_ALREADY_REGISTERED, chan.c_str());
|
||||
else if (c && !c->HasUserStatus(u, CMODE_OP))
|
||||
source.Reply(CHAN_MUST_BE_CHANOP);
|
||||
|
||||
@@ -26,8 +26,9 @@ class CommandCSStatus : public Command
|
||||
const Anope::string &nick = params[1];
|
||||
|
||||
User *u2 = finduser(nick);
|
||||
ChanAccess *u2_access = ci->GetAccess(u2);
|
||||
if (u2)
|
||||
source.Reply(CHAN_STATUS_INFO, ci->name.c_str(), u2->nick.c_str(), get_access(u2, ci));
|
||||
source.Reply(CHAN_STATUS_INFO, ci->name.c_str(), u2->nick.c_str(), u2_access ? u2_access->level : 0);
|
||||
else /* !u2 */
|
||||
source.Reply(CHAN_STATUS_NOTONLINE, nick.c_str());
|
||||
return MOD_CONT;
|
||||
|
||||
+46
-73
@@ -26,7 +26,6 @@ enum
|
||||
enum
|
||||
{
|
||||
XOP_DISABLED,
|
||||
XOP_NICKS_ONLY,
|
||||
XOP_ADDED,
|
||||
XOP_MOVED,
|
||||
XOP_NO_SUCH_ENTRY,
|
||||
@@ -43,7 +42,6 @@ enum
|
||||
|
||||
LanguageString xop_msgs[XOP_TYPES][XOP_MESSAGES] = {
|
||||
{CHAN_AOP_DISABLED,
|
||||
CHAN_AOP_NICKS_ONLY,
|
||||
CHAN_AOP_ADDED,
|
||||
CHAN_AOP_MOVED,
|
||||
CHAN_AOP_NO_SUCH_ENTRY,
|
||||
@@ -56,7 +54,6 @@ LanguageString xop_msgs[XOP_TYPES][XOP_MESSAGES] = {
|
||||
CHAN_AOP_LIST_HEADER,
|
||||
CHAN_AOP_CLEAR},
|
||||
{CHAN_SOP_DISABLED,
|
||||
CHAN_SOP_NICKS_ONLY,
|
||||
CHAN_SOP_ADDED,
|
||||
CHAN_SOP_MOVED,
|
||||
CHAN_SOP_NO_SUCH_ENTRY,
|
||||
@@ -69,7 +66,6 @@ LanguageString xop_msgs[XOP_TYPES][XOP_MESSAGES] = {
|
||||
CHAN_SOP_LIST_HEADER,
|
||||
CHAN_SOP_CLEAR},
|
||||
{CHAN_VOP_DISABLED,
|
||||
CHAN_VOP_NICKS_ONLY,
|
||||
CHAN_VOP_ADDED,
|
||||
CHAN_VOP_MOVED,
|
||||
CHAN_VOP_NO_SUCH_ENTRY,
|
||||
@@ -82,7 +78,6 @@ LanguageString xop_msgs[XOP_TYPES][XOP_MESSAGES] = {
|
||||
CHAN_VOP_LIST_HEADER,
|
||||
CHAN_VOP_CLEAR},
|
||||
{CHAN_HOP_DISABLED,
|
||||
CHAN_HOP_NICKS_ONLY,
|
||||
CHAN_HOP_ADDED,
|
||||
CHAN_HOP_MOVED,
|
||||
CHAN_HOP_NO_SUCH_ENTRY,
|
||||
@@ -95,7 +90,6 @@ LanguageString xop_msgs[XOP_TYPES][XOP_MESSAGES] = {
|
||||
CHAN_HOP_LIST_HEADER,
|
||||
CHAN_HOP_CLEAR},
|
||||
{CHAN_QOP_DISABLED,
|
||||
CHAN_QOP_NICKS_ONLY,
|
||||
CHAN_QOP_ADDED,
|
||||
CHAN_QOP_MOVED,
|
||||
CHAN_QOP_NO_SUCH_ENTRY,
|
||||
@@ -141,7 +135,7 @@ class XOPListCallback : public NumberList
|
||||
|
||||
static void DoList(CommandSource &source, ChanAccess *access, unsigned index, int level, LanguageString *messages)
|
||||
{
|
||||
source.Reply(CHAN_XOP_LIST_FORMAT, index, access->nc->display.c_str());
|
||||
source.Reply(CHAN_XOP_LIST_FORMAT, index, access->mask.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -182,11 +176,11 @@ class XOPDelCallback : public NumberList
|
||||
|
||||
++Deleted;
|
||||
if (!Nicks.empty())
|
||||
Nicks += ", " + access->nc->display;
|
||||
Nicks += ", " + access->mask;
|
||||
else
|
||||
Nicks = access->nc->display;
|
||||
Nicks = access->mask;
|
||||
|
||||
FOREACH_MOD(I_OnAccessDel, OnAccessDel(source.ci, source.u, access->nc));
|
||||
FOREACH_MOD(I_OnAccessDel, OnAccessDel(source.ci, source.u, access));
|
||||
|
||||
source.ci->EraseAccess(Number - 1);
|
||||
}
|
||||
@@ -200,11 +194,10 @@ class XOPBase : public Command
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
const Anope::string &nick = params.size() > 2 ? params[2] : "";
|
||||
ChanAccess *access;
|
||||
Anope::string mask = params.size() > 2 ? params[2] : "";
|
||||
int change = 0;
|
||||
|
||||
if (nick.empty())
|
||||
if (mask.empty())
|
||||
{
|
||||
this->OnSyntaxError(source, "ADD");
|
||||
return MOD_CONT;
|
||||
@@ -216,7 +209,8 @@ class XOPBase : public Command
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
short ulev = get_access(u, ci);
|
||||
ChanAccess *access = ci->GetAccess(u);
|
||||
uint16 ulev = access ? access->level : 0;
|
||||
|
||||
if ((level >= ulev || ulev < ACCESS_AOP) && !u->Account()->HasPriv("chanserv/access/modify"))
|
||||
{
|
||||
@@ -224,20 +218,16 @@ class XOPBase : public Command
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
NickAlias *na = findnick(nick);
|
||||
if (!na)
|
||||
{
|
||||
source.Reply(messages[XOP_NICKS_ONLY]);
|
||||
return MOD_CONT;
|
||||
}
|
||||
else if (na->HasFlag(NS_FORBIDDEN))
|
||||
NickAlias *na = findnick(mask);
|
||||
if (!na && mask.find_first_of("!@*") == Anope::string::npos)
|
||||
mask += "!*@*";
|
||||
else if (na && na->HasFlag(NS_FORBIDDEN))
|
||||
{
|
||||
source.Reply(NICK_X_FORBIDDEN, na->nick.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
NickCore *nc = na->nc;
|
||||
access = ci->GetAccess(nc);
|
||||
access = ci->GetAccess(mask);
|
||||
if (access)
|
||||
{
|
||||
/**
|
||||
@@ -258,7 +248,7 @@ class XOPBase : public Command
|
||||
}
|
||||
|
||||
if (!change)
|
||||
ci->AddAccess(nc, level, u->nick);
|
||||
access = ci->AddAccess(mask, level, u->nick);
|
||||
else
|
||||
{
|
||||
access->level = level;
|
||||
@@ -267,17 +257,17 @@ class XOPBase : public Command
|
||||
}
|
||||
|
||||
bool override = (level >= ulev || ulev < ACCESS_AOP || (access && access->level > ulev));
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << na->nick << " (group: " << nc->display << ") as level " << level;
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << mask << " as level " << level;
|
||||
|
||||
if (!change)
|
||||
{
|
||||
FOREACH_MOD(I_OnAccessAdd, OnAccessAdd(ci, u, nc, level));
|
||||
source.Reply(messages[XOP_ADDED], nc->display.c_str(), ci->name.c_str());
|
||||
FOREACH_MOD(I_OnAccessAdd, OnAccessAdd(ci, u, access));
|
||||
source.Reply(messages[XOP_ADDED], access->mask.c_str(), ci->name.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
FOREACH_MOD(I_OnAccessChange, OnAccessChange(ci, u, na->nc, level));
|
||||
source.Reply(messages[XOP_MOVED], nc->display.c_str(), ci->name.c_str());
|
||||
FOREACH_MOD(I_OnAccessChange, OnAccessChange(ci, u, access));
|
||||
source.Reply(messages[XOP_MOVED], access->mask.c_str(), ci->name.c_str());
|
||||
}
|
||||
|
||||
return MOD_CONT;
|
||||
@@ -288,10 +278,9 @@ class XOPBase : public Command
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
const Anope::string &nick = params.size() > 2 ? params[2] : "";
|
||||
ChanAccess *access;
|
||||
const Anope::string &mask = params.size() > 2 ? params[2] : "";
|
||||
|
||||
if (nick.empty())
|
||||
if (mask.empty())
|
||||
{
|
||||
this->OnSyntaxError(source, "DEL");
|
||||
return MOD_CONT;
|
||||
@@ -309,62 +298,43 @@ class XOPBase : public Command
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
NickAlias *na = NULL;
|
||||
if (!isdigit(nick[0]))
|
||||
{
|
||||
na = findnick(nick);
|
||||
if (!na)
|
||||
{
|
||||
source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
}
|
||||
ChanAccess *access = ci->GetAccess(u);
|
||||
uint16 ulev = access ? access->level : 0;
|
||||
|
||||
short ulev = get_access(u, ci);
|
||||
|
||||
if ((!na || na->nc != u->Account()) && (level >= ulev || ulev < ACCESS_AOP) && !u->Account()->HasPriv("chanserv/access/modify"))
|
||||
if ((!access || access->nc != u->Account()) && (level >= ulev || ulev < ACCESS_AOP) && !u->Account()->HasPriv("chanserv/access/modify"))
|
||||
{
|
||||
source.Reply(ACCESS_DENIED);
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
access = ci->GetAccess(mask);
|
||||
|
||||
/* Special case: is it a number/list? Only do search if it isn't. */
|
||||
if (isdigit(nick[0]) && nick.find_first_not_of("1234567890,-") == Anope::string::npos)
|
||||
if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
|
||||
{
|
||||
bool override = level >= ulev || ulev < ACCESS_AOP;
|
||||
XOPDelCallback list(source, this, messages, override, nick);
|
||||
XOPDelCallback list(source, this, messages, override, mask);
|
||||
list.Process();
|
||||
}
|
||||
else if (!access)
|
||||
{
|
||||
source.Reply(messages[XOP_NOT_FOUND], mask.c_str(), ci->name.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
else
|
||||
{
|
||||
NickCore *nc = na->nc;
|
||||
unsigned i, end;
|
||||
for (i = 0, end = ci->GetAccessCount(); i < end; ++i)
|
||||
{
|
||||
access = ci->GetAccess(nc, level);
|
||||
|
||||
if (access->nc == nc)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == end)
|
||||
{
|
||||
source.Reply(messages[XOP_NOT_FOUND], nick.c_str(), ci->name.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (nc != u->Account() && ulev <= access->level && !u->Account()->HasPriv("chanserv/access/modify"))
|
||||
if (access->nc != u->Account() && ulev <= access->level && !u->Account()->HasPriv("chanserv/access/modify"))
|
||||
source.Reply(ACCESS_DENIED);
|
||||
else
|
||||
{
|
||||
bool override = ulev <= access->level;
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DEL " << access->nc->display;
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DEL " << access->mask;
|
||||
|
||||
source.Reply(messages[XOP_DELETED], access->nc->display.c_str(), ci->name.c_str());
|
||||
source.Reply(messages[XOP_DELETED], access->mask.c_str(), ci->name.c_str());
|
||||
|
||||
FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, na->nc));
|
||||
FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, access));
|
||||
|
||||
ci->EraseAccess(i);
|
||||
ci->EraseAccess(access);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -378,13 +348,16 @@ class XOPBase : public Command
|
||||
|
||||
const Anope::string &nick = params.size() > 2 ? params[2] : "";
|
||||
|
||||
if (!get_access(u, ci) && !u->Account()->HasCommand("chanserv/access/list"))
|
||||
ChanAccess *access = ci->GetAccess(u);
|
||||
uint16 ulev = access ? access->level : 0;
|
||||
|
||||
if (!ulev && !u->Account()->HasCommand("chanserv/access/list"))
|
||||
{
|
||||
source.Reply(ACCESS_DENIED);
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool override = !get_access(u, ci);
|
||||
bool override = !ulev;
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci);
|
||||
|
||||
if (!ci->GetAccessCount())
|
||||
@@ -404,11 +377,11 @@ class XOPBase : public Command
|
||||
|
||||
for (unsigned i = 0, end = ci->GetAccessCount(); i < end; ++i)
|
||||
{
|
||||
ChanAccess *access = ci->GetAccess(i);
|
||||
access = ci->GetAccess(i);
|
||||
|
||||
if (access->level != level)
|
||||
continue;
|
||||
else if (!nick.empty() && access->nc && !Anope::Match(access->nc->display, nick))
|
||||
else if (!nick.empty() && !Anope::Match(access->mask, nick))
|
||||
continue;
|
||||
|
||||
if (!SentHeader)
|
||||
@@ -489,7 +462,7 @@ class XOPBase : public Command
|
||||
return MOD_CONT;
|
||||
}
|
||||
public:
|
||||
XOPBase(const Anope::string &command) : Command(command, 2, 3)
|
||||
XOPBase(const Anope::string &command) : Command(command, 2, 4)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -697,17 +697,9 @@ class DBPlain : public Module
|
||||
}
|
||||
else if (key.equals_ci("ACCESS"))
|
||||
{
|
||||
NickCore *nc = findcore(params[0]);
|
||||
if (!nc)
|
||||
{
|
||||
std::stringstream reason;
|
||||
reason << "Access entry for nonexistant core " << params[0] << " on " << ci->name;
|
||||
throw DatabaseException(reason.str());
|
||||
}
|
||||
|
||||
int level = params[1].is_number_only() ? convertTo<int>(params[1]) : 0;
|
||||
time_t last_seen = params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : 0;
|
||||
ci->AddAccess(nc, level, params[3], last_seen);
|
||||
ci->AddAccess(params[0], level, params[3], last_seen);
|
||||
}
|
||||
else if (key.equals_ci("AKICK"))
|
||||
{
|
||||
@@ -972,7 +964,7 @@ class DBPlain : public Module
|
||||
db << "MD FORBID " << ci->forbidby << " :" << ci->forbidreason << endl;
|
||||
}
|
||||
for (unsigned k = 0, end = ci->GetAccessCount(); k < end; ++k)
|
||||
db << "MD ACCESS " << ci->GetAccess(k)->nc->display << " " << ci->GetAccess(k)->level << " " << ci->GetAccess(k)->last_seen << " " << ci->GetAccess(k)->creator << endl;
|
||||
db << "MD ACCESS " << ci->GetAccess(k)->mask << " " << ci->GetAccess(k)->level << " " << ci->GetAccess(k)->last_seen << " " << ci->GetAccess(k)->creator << endl;
|
||||
for (unsigned k = 0, end = ci->GetAkickCount(); k < end; ++k)
|
||||
{
|
||||
db << "MD AKICK 0 " << (ci->GetAkick(k)->HasFlag(AK_ISNICK) ? "NICK " : "MASK ") <<
|
||||
|
||||
@@ -22,7 +22,6 @@ class CommandMSStaff : public Command
|
||||
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
User *u = source.u;
|
||||
const Anope::string &text = params[0];
|
||||
|
||||
if (readonly)
|
||||
|
||||
@@ -47,7 +47,6 @@ class CommandNSAccess : public Command
|
||||
|
||||
CommandReturn DoAdd(CommandSource &source, NickCore *nc, const Anope::string &mask)
|
||||
{
|
||||
User *u = source.u;
|
||||
|
||||
if (mask.empty())
|
||||
{
|
||||
@@ -75,8 +74,6 @@ class CommandNSAccess : public Command
|
||||
|
||||
CommandReturn DoDel(CommandSource &source, NickCore *nc, const Anope::string &mask)
|
||||
{
|
||||
User *u = source.u;
|
||||
|
||||
if (mask.empty())
|
||||
{
|
||||
this->OnSyntaxError(source, "DEL");
|
||||
|
||||
@@ -84,7 +84,6 @@ class CommandNSAList : public Command
|
||||
source.Reply(CHAN_ACCESS_LEVEL_RANGE, ACCESS_INVALID + 1, ACCESS_FOUNDER - 1);
|
||||
else
|
||||
{
|
||||
int level;
|
||||
int chan_count = 0;
|
||||
int match_count = 0;
|
||||
|
||||
@@ -94,23 +93,24 @@ class CommandNSAList : public Command
|
||||
{
|
||||
ChannelInfo *ci = it->second;
|
||||
|
||||
if ((level = get_access_level(ci, na)))
|
||||
ChanAccess *access = ci->GetAccess(na->nc);
|
||||
if (access)
|
||||
{
|
||||
++chan_count;
|
||||
|
||||
if (min_level > level)
|
||||
if (min_level > access->level)
|
||||
continue;
|
||||
|
||||
++match_count;
|
||||
|
||||
if (ci->HasFlag(CI_XOP) || level == ACCESS_FOUNDER)
|
||||
if (ci->HasFlag(CI_XOP) || access->level == ACCESS_FOUNDER)
|
||||
{
|
||||
Anope::string xop = get_xop_level(level);
|
||||
Anope::string xop = get_xop_level(access->level);
|
||||
|
||||
source.Reply(NICK_ALIST_XOP_FORMAT, match_count, ci->HasFlag(CI_NO_EXPIRE) ? '!' : ' ', ci->name.c_str(), xop.c_str(), !ci->desc.empty() ? ci->desc.c_str() : "");
|
||||
}
|
||||
else
|
||||
source.Reply(NICK_ALIST_ACCESS_FORMAT, match_count, ci->HasFlag(CI_NO_EXPIRE) ? '!' : ' ', ci->name.c_str(), level, !ci->desc.empty() ? ci->desc.c_str() : "");
|
||||
source.Reply(NICK_ALIST_ACCESS_FORMAT, match_count, ci->HasFlag(CI_NO_EXPIRE) ? '!' : ' ', ci->name.c_str(), access->level, !ci->desc.empty() ? ci->desc.c_str() : "");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -750,14 +750,7 @@ class DBMySQL : public Module
|
||||
continue;
|
||||
}
|
||||
|
||||
NickCore *nc = findcore(r.Get(i, "display"));
|
||||
if (!nc)
|
||||
{
|
||||
Log() << "MySQL: Channel access entry for " << ci->name << " with nonexistant nick " << r.Get(i, "display");
|
||||
continue;
|
||||
}
|
||||
|
||||
ci->AddAccess(nc, atoi(r.Get(i, "level").c_str()), r.Get(i, "creator"), (r.Get(i, "last_seen").is_pos_number_only() ? convertTo<time_t>(r.Get(i, "last_seen")) : Anope::CurTime));
|
||||
ci->AddAccess(r.Get(i, "display"), atoi(r.Get(i, "level").c_str()), r.Get(i, "creator"), (r.Get(i, "last_seen").is_pos_number_only() ? convertTo<time_t>(r.Get(i, "last_seen")) : Anope::CurTime));
|
||||
}
|
||||
|
||||
r = SQL->RunQuery("SELECT * FROM `anope_cs_akick`");
|
||||
@@ -1216,19 +1209,19 @@ class DBMySQL : public Module
|
||||
this->RunQuery("UPDATE `anope_ns_core` SET `flags` = '" + BuildFlagsList(na->nc) + "' WHERE `display` = '" + this->Escape(na->nc->display) + "'");
|
||||
}
|
||||
|
||||
void OnAccessAdd(ChannelInfo *ci, User *u, NickCore *nc, int level)
|
||||
void OnAccessAdd(ChannelInfo *ci, User *u, ChanAccess *access)
|
||||
{
|
||||
this->RunQuery("INSERT INTO `anope_cs_access` (level, display, channel, last_seen, creator) VALUES (" + stringify(level) + ", '" + this->Escape(nc->display) + "', '" + this->Escape(ci->name) + "', " + stringify(Anope::CurTime) + ", '" + this->Escape(u->nick) + "')");
|
||||
this->RunQuery("INSERT INTO `anope_cs_access` (level, display, channel, last_seen, creator) VALUES (" + stringify(access->level) + ", '" + this->Escape(access->mask) + "', '" + this->Escape(ci->name) + "', " + stringify(Anope::CurTime) + ", '" + this->Escape(u->nick) + "')");
|
||||
}
|
||||
|
||||
void OnAccessDel(ChannelInfo *ci, User *u, NickCore *nc)
|
||||
void OnAccessDel(ChannelInfo *ci, User *u, ChanAccess *access)
|
||||
{
|
||||
this->RunQuery("DELETE FROM `anope_cs_access` WHERE `display` = '" + this->Escape(nc->display) + "' AND `channel` = '" + this->Escape(ci->name) + "'");
|
||||
this->RunQuery("DELETE FROM `anope_cs_access` WHERE `display` = '" + this->Escape(access->mask) + "' AND `channel` = '" + this->Escape(ci->name) + "'");
|
||||
}
|
||||
|
||||
void OnAccessChange(ChannelInfo *ci, User *u, NickAlias *na, int level)
|
||||
void OnAccessChange(ChannelInfo *ci, User *u, ChanAccess *access)
|
||||
{
|
||||
this->RunQuery("INSERT INTO `anope_cs_access` (level, display, channel, last_seen, creator) VALUES (" + stringify(level) + ", '" + this->Escape(na->nc->display) + "', '" + this->Escape(ci->name) + "', " + stringify(Anope::CurTime) + ", '" + this->Escape(u->nick) + "') ON DUPLICATE KEY UPDATE level=VALUES(level), display=VALUES(display), channel=VALUES(channel), last_seen=VALUES(last_seen), creator=VALUES(creator)");
|
||||
this->RunQuery("INSERT INTO `anope_cs_access` (level, display, channel, last_seen, creator) VALUES (" + stringify(access->level) + ", '" + this->Escape(access->mask) + "', '" + this->Escape(ci->name) + "', " + stringify(Anope::CurTime) + ", '" + this->Escape(u->nick) + "') ON DUPLICATE KEY UPDATE level=VALUES(level), display=VALUES(display), channel=VALUES(channel), last_seen=VALUES(last_seen), creator=VALUES(creator)");
|
||||
}
|
||||
|
||||
void OnAccessClear(ChannelInfo *ci, User *u)
|
||||
@@ -1565,7 +1558,7 @@ static void SaveDatabases()
|
||||
{
|
||||
ChanAccess *access = ci->GetAccess(j);
|
||||
|
||||
me->RunQuery(Anope::string("INSERT INTO `anope_cs_access` (level, display, channel, last_seen, creator) VALUES('") + access->level + "', " + me->Escape(access->nc->display) + ", " + me->Escape(ci->name) + ", " + access->last_seen + ", " + me->Escape(access->creator) + ") ON DUPLICATE KEY UPDATE level=VALUES(level), last_seen=VALUES(last_seen), creator=VALUES(creator)");
|
||||
me->RunQuery(Anope::string("INSERT INTO `anope_cs_access` (level, display, channel, last_seen, creator) VALUES('") + access->level + "', " + me->Escape(access->mask) + ", " + me->Escape(ci->name) + ", " + access->last_seen + ", " + me->Escape(access->creator) + ") ON DUPLICATE KEY UPDATE level=VALUES(level), last_seen=VALUES(last_seen), creator=VALUES(creator)");
|
||||
}
|
||||
|
||||
for (unsigned j = 0, end = ci->GetAkickCount(); j < end; ++j)
|
||||
|
||||
+12
-6
@@ -511,7 +511,7 @@ void bot_raw_ban(User *requester, ChannelInfo *ci, const Anope::string &nick, co
|
||||
Anope::string mask;
|
||||
User *u = finduser(nick);
|
||||
|
||||
if (!u)
|
||||
if (!u || !ci)
|
||||
return;
|
||||
|
||||
if (ModeManager::FindUserModeByName(UMODE_PROTECTED) && u->IsProtected() && requester != u)
|
||||
@@ -520,7 +520,9 @@ void bot_raw_ban(User *requester, ChannelInfo *ci, const Anope::string &nick, co
|
||||
return;
|
||||
}
|
||||
|
||||
if (ci->HasFlag(CI_PEACE) && !requester->nick.equals_ci(nick) && get_access(u, ci) >= get_access(requester, ci))
|
||||
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(nick) && u_level >= req_level)
|
||||
return;
|
||||
|
||||
if (ModeManager::FindChannelModeByName(CMODE_EXCEPT) && is_excepted(ci, u) == 1)
|
||||
@@ -548,7 +550,7 @@ void bot_raw_kick(User *requester, ChannelInfo *ci, const Anope::string &nick, c
|
||||
{
|
||||
User *u = finduser(nick);
|
||||
|
||||
if (!u || !ci->c->FindUser(u))
|
||||
if (!u || !ci || !ci->c || !ci->c->FindUser(u))
|
||||
return;
|
||||
|
||||
if (ModeManager::FindUserModeByName(UMODE_PROTECTED) && u->IsProtected() && requester != u)
|
||||
@@ -557,7 +559,9 @@ void bot_raw_kick(User *requester, ChannelInfo *ci, const Anope::string &nick, c
|
||||
return;
|
||||
}
|
||||
|
||||
if (ci->HasFlag(CI_PEACE) && !requester->nick.equals_ci(nick) && get_access(u, ci) >= get_access(requester, ci))
|
||||
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(nick) && u_level >= req_level)
|
||||
return;
|
||||
|
||||
if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !check_access(requester, ci, CA_SIGNKICK)))
|
||||
@@ -577,7 +581,7 @@ void bot_raw_mode(User *requester, ChannelInfo *ci, const Anope::string &mode, c
|
||||
|
||||
u = finduser(nick);
|
||||
|
||||
if (!u || !ci->c->FindUser(u))
|
||||
if (!u || !ci || !ci->c || !ci->c->FindUser(u))
|
||||
return;
|
||||
|
||||
snprintf(buf, BUFSIZE - 1, "%ld", static_cast<long>(Anope::CurTime));
|
||||
@@ -588,7 +592,9 @@ void bot_raw_mode(User *requester, ChannelInfo *ci, const Anope::string &mode, c
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode[0] == '-' && ci->HasFlag(CI_PEACE) && !requester->nick.equals_ci(nick) && get_access(u, ci) >= get_access(requester, ci))
|
||||
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 (mode[0] == '-' && ci->HasFlag(CI_PEACE) && !requester->nick.equals_ci(nick) && u_level >= req_level)
|
||||
return;
|
||||
|
||||
ci->c->SetModes(NULL, "%s %s", mode.c_str(), nick.c_str());
|
||||
|
||||
+3
-3
@@ -459,7 +459,7 @@ void Channel::RemoveModeInternal(ChannelMode *cm, const Anope::string ¶m, bo
|
||||
|
||||
/* Enforce secureops, etc */
|
||||
if (EnforceMLock)
|
||||
chan_set_correct_modes(u, this, 1);
|
||||
chan_set_correct_modes(u, this, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1207,9 +1207,9 @@ void chan_set_correct_modes(User *user, Channel *c, int give_modes)
|
||||
{
|
||||
if ((ml.set && !c->HasUserStatus(user, ml.name)) || (!ml.set && c->HasUserStatus(user, ml.name)))
|
||||
{
|
||||
if (ml.set && give_modes)
|
||||
if (ml.set)
|
||||
c->SetMode(NULL, cm, user->nick, false);
|
||||
else if (!ml.set && !give_modes)
|
||||
else if (!ml.set)
|
||||
c->RemoveMode(NULL, cm, user->nick, false);
|
||||
}
|
||||
}
|
||||
|
||||
+7
-73
@@ -401,19 +401,15 @@ void expire_chans()
|
||||
/*************************************************************************/
|
||||
|
||||
// XXX this is slightly inefficient
|
||||
void cs_remove_nick(const NickCore *nc)
|
||||
void cs_remove_nick(NickCore *nc)
|
||||
{
|
||||
for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(), it_end = RegisteredChannelList.end(); it != it_end; ++it)
|
||||
{
|
||||
ChannelInfo *ci = it->second;
|
||||
|
||||
for (unsigned j = ci->GetAccessCount(); j > 0; --j)
|
||||
{
|
||||
ChanAccess *ca = ci->GetAccess(j - 1);
|
||||
|
||||
if (ca->nc == nc)
|
||||
ci->EraseAccess(j - 1);
|
||||
}
|
||||
ChanAccess *access = ci->GetAccess(nc);
|
||||
if (access)
|
||||
ci->EraseAccess(access);
|
||||
|
||||
for (unsigned j = ci->GetAkickCount(); j > 0; --j)
|
||||
{
|
||||
@@ -497,7 +493,8 @@ int check_access(User *user, ChannelInfo *ci, int what)
|
||||
if (!user || !ci)
|
||||
return 0;
|
||||
|
||||
level = get_access(user, ci);
|
||||
ChanAccess *u_access = ci->GetAccess(user);
|
||||
level = u_access ? u_access->level : 0;
|
||||
limit = ci->levels[what];
|
||||
|
||||
/* Resetting the last used time */
|
||||
@@ -564,45 +561,6 @@ bool IsFounder(User *user, ChannelInfo *ci)
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Return the access level for the user on the channel.
|
||||
* If the channel doesn't exist, the user isn't on the access list, or the
|
||||
* channel is CI_SECURE and the user isn't identified, return 0
|
||||
* @param user The user
|
||||
* @param ci The cahnnel
|
||||
* @return The level, or 0
|
||||
*/
|
||||
int get_access(User *user, ChannelInfo *ci)
|
||||
{
|
||||
ChanAccess *access = NULL;
|
||||
|
||||
if (!ci || !user)
|
||||
return 0;
|
||||
|
||||
/* SuperAdmin always has highest level */
|
||||
if (user->isSuperAdmin)
|
||||
return ACCESS_SUPERADMIN;
|
||||
|
||||
if (IsFounder(user, ci))
|
||||
return ACCESS_FOUNDER;
|
||||
|
||||
if (user->IsIdentified())
|
||||
{
|
||||
access = ci->GetAccess(user->Account());
|
||||
if (access)
|
||||
return access->level;
|
||||
}
|
||||
else
|
||||
{
|
||||
NickAlias *na = findnick(user->nick);
|
||||
if (na)
|
||||
access = ci->GetAccess(na->nc);
|
||||
if (access && user->IsRecognized() && !ci->HasFlag(CI_SECURE))
|
||||
return access->level;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
void update_cs_lastseen(User *user, ChannelInfo *ci)
|
||||
@@ -613,7 +571,7 @@ void update_cs_lastseen(User *user, ChannelInfo *ci)
|
||||
return;
|
||||
|
||||
if (IsFounder(user, ci) || user->IsIdentified() || (user->IsRecognized() && !ci->HasFlag(CI_SECURE)))
|
||||
if ((access = ci->GetAccess(user->Account())))
|
||||
if ((access = ci->GetAccess(user)))
|
||||
access->last_seen = Anope::CurTime;
|
||||
}
|
||||
|
||||
@@ -658,30 +616,6 @@ int get_idealban(ChannelInfo *ci, User *u, Anope::string &ret)
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
int get_access_level(ChannelInfo *ci, NickCore *nc)
|
||||
{
|
||||
if (!ci || !nc)
|
||||
return 0;
|
||||
|
||||
if (nc == ci->founder)
|
||||
return ACCESS_FOUNDER;
|
||||
|
||||
ChanAccess *access = ci->GetAccess(nc);
|
||||
|
||||
if (!access)
|
||||
return 0;
|
||||
else
|
||||
return access->level;
|
||||
}
|
||||
|
||||
int get_access_level(ChannelInfo *ci, NickAlias *na)
|
||||
{
|
||||
if (!na)
|
||||
return 0;
|
||||
|
||||
return get_access_level(ci, na->nc);
|
||||
}
|
||||
|
||||
Anope::string get_xop_level(int level)
|
||||
{
|
||||
ChannelMode *halfop = ModeManager::FindChannelModeByName(CMODE_HALFOP);
|
||||
|
||||
+20
-30
@@ -958,8 +958,6 @@ const char *const language_strings[LANG_STRING_COUNT] = {
|
||||
_("QOP channel {ADD|DEL|LIST|CLEAR} [nick | entry-list]"),
|
||||
/* CHAN_QOP_DISABLED */
|
||||
_("Sorry, channel QOP list modification is temporarily disabled."),
|
||||
/* CHAN_QOP_NICKS_ONLY */
|
||||
_("Channel QOP lists may only contain registered nicknames."),
|
||||
/* CHAN_QOP_ADDED */
|
||||
_("%s added to %s QOP list."),
|
||||
/* CHAN_QOP_MOVED */
|
||||
@@ -987,8 +985,6 @@ const char *const language_strings[LANG_STRING_COUNT] = {
|
||||
_("AOP channel {ADD|DEL|LIST|CLEAR} [nick | entry-list]"),
|
||||
/* CHAN_AOP_DISABLED */
|
||||
_("Sorry, channel AOP list modification is temporarily disabled."),
|
||||
/* CHAN_AOP_NICKS_ONLY */
|
||||
_("Channel AOP lists may only contain registered nicknames."),
|
||||
/* CHAN_AOP_ADDED */
|
||||
_("%s added to %s AOP list."),
|
||||
/* CHAN_AOP_MOVED */
|
||||
@@ -1016,8 +1012,6 @@ const char *const language_strings[LANG_STRING_COUNT] = {
|
||||
_("HOP channel {ADD|DEL|LIST|CLEAR} [nick | entry-list]"),
|
||||
/* CHAN_HOP_DISABLED */
|
||||
_("Sorry, channel HOP list modification is temporarily disabled."),
|
||||
/* CHAN_HOP_NICKS_ONLY */
|
||||
_("Channel HOP lists may only contain registered nicknames."),
|
||||
/* CHAN_HOP_ADDED */
|
||||
_("%s added to %s HOP list."),
|
||||
/* CHAN_HOP_MOVED */
|
||||
@@ -1045,8 +1039,6 @@ const char *const language_strings[LANG_STRING_COUNT] = {
|
||||
_("SOP channel {ADD|DEL|LIST|CLEAR} [nick | entry-list]"),
|
||||
/* CHAN_SOP_DISABLED */
|
||||
_("Sorry, channel SOP list modification is temporarily disabled."),
|
||||
/* CHAN_SOP_NICKS_ONLY */
|
||||
_("Channel SOP lists may only contain registered nicknames."),
|
||||
/* CHAN_SOP_ADDED */
|
||||
_("%s added to %s SOP list."),
|
||||
/* CHAN_SOP_MOVED */
|
||||
@@ -1074,8 +1066,6 @@ const char *const language_strings[LANG_STRING_COUNT] = {
|
||||
_("VOP channel {ADD|DEL|LIST|CLEAR} [nick | entry-list]"),
|
||||
/* CHAN_VOP_DISABLED */
|
||||
_("Sorry, channel VOP list modification is temporarily disabled."),
|
||||
/* CHAN_VOP_NICKS_ONLY */
|
||||
_("Channel VOP lists may only contain registered nicknames."),
|
||||
/* CHAN_VOP_ADDED */
|
||||
_("%s added to %s VOP list."),
|
||||
/* CHAN_VOP_MOVED */
|
||||
@@ -1100,7 +1090,7 @@ const char *const language_strings[LANG_STRING_COUNT] = {
|
||||
/* CHAN_VOP_CLEAR */
|
||||
_("Channel %s VOP list has been cleared."),
|
||||
/* CHAN_ACCESS_SYNTAX */
|
||||
_("ACCESS channel {ADD|DEL|LIST|VIEW|CLEAR} [nick [level] | entry-list]"),
|
||||
_("ACCESS channel {ADD|DEL|LIST|VIEW|CLEAR} [mask [level] | entry-list]"),
|
||||
/* CHAN_ACCESS_XOP */
|
||||
_("You can't use this command. \n"
|
||||
"Use the AOP, SOP and VOP commands instead.\n"
|
||||
@@ -1115,8 +1105,6 @@ const char *const language_strings[LANG_STRING_COUNT] = {
|
||||
_("Access level must be non-zero."),
|
||||
/* CHAN_ACCESS_LEVEL_RANGE */
|
||||
_("Access level must be between %d and %d inclusive."),
|
||||
/* CHAN_ACCESS_NICKS_ONLY */
|
||||
_("Channel access lists may only contain registered nicknames."),
|
||||
/* CHAN_ACCESS_REACHED_LIMIT */
|
||||
_("Sorry, you can only have %d access entries on a channel."),
|
||||
/* CHAN_ACCESS_LEVEL_UNCHANGED */
|
||||
@@ -1139,7 +1127,7 @@ const char *const language_strings[LANG_STRING_COUNT] = {
|
||||
_("%s access list is empty."),
|
||||
/* CHAN_ACCESS_LIST_HEADER */
|
||||
_("Access list for %s:\n"
|
||||
" Num Lev Nick"),
|
||||
" Num Lev Mask"),
|
||||
/* CHAN_ACCESS_LIST_FOOTER */
|
||||
_("End of access list."),
|
||||
/* CHAN_ACCESS_LIST_XOP_FORMAT */
|
||||
@@ -3625,8 +3613,8 @@ const char *const language_strings[LANG_STRING_COUNT] = {
|
||||
"channel whenever the OP or DEOP commands are used for a user\n"
|
||||
"in the channel."),
|
||||
/* CHAN_HELP_QOP */
|
||||
_("Syntax: QOP channel ADD nick\n"
|
||||
" QOP channel DEL {nick | entry-num | list}\n"
|
||||
_("Syntax: QOP channel ADD mask\n"
|
||||
" QOP channel DEL {mask | entry-num | list}\n"
|
||||
" QOP channel LIST [mask | list]\n"
|
||||
" QOP channel CLEAR\n"
|
||||
" \n"
|
||||
@@ -3662,8 +3650,8 @@ const char *const language_strings[LANG_STRING_COUNT] = {
|
||||
"and %R%S HELP SET XOP to know how to toggle between \n"
|
||||
"the access list and xOP list systems."),
|
||||
/* CHAN_HELP_AOP */
|
||||
_("Syntax: AOP channel ADD nick\n"
|
||||
" AOP channel DEL {nick | entry-num | list}\n"
|
||||
_("Syntax: AOP channel ADD mask\n"
|
||||
" AOP channel DEL {mask | entry-num | list}\n"
|
||||
" AOP channel LIST [mask | list]\n"
|
||||
" AOP channel CLEAR\n"
|
||||
" \n"
|
||||
@@ -3701,8 +3689,8 @@ const char *const language_strings[LANG_STRING_COUNT] = {
|
||||
"and %R%S HELP SET XOP to know how to toggle between \n"
|
||||
"the access list and xOP list systems."),
|
||||
/* CHAN_HELP_HOP */
|
||||
_("Syntax: HOP channel ADD nick\n"
|
||||
" HOP channel DEL {nick | entry-num | list}\n"
|
||||
_("Syntax: HOP channel ADD mask\n"
|
||||
" HOP channel DEL {mask | entry-num | list}\n"
|
||||
" HOP channel LIST [mask | list]\n"
|
||||
" HOP channel CLEAR\n"
|
||||
" \n"
|
||||
@@ -3738,8 +3726,8 @@ const char *const language_strings[LANG_STRING_COUNT] = {
|
||||
"and %R%S HELP SET XOP to know how to toggle between \n"
|
||||
"the access list and xOP list systems."),
|
||||
/* CHAN_HELP_SOP */
|
||||
_("Syntax: SOP channel ADD nick\n"
|
||||
" SOP channel DEL {nick | entry-num | list}\n"
|
||||
_("Syntax: SOP channel ADD mask\n"
|
||||
" SOP channel DEL {mask | entry-num | list}\n"
|
||||
" SOP channel LIST [mask | list]\n"
|
||||
" SOP channel CLEAR\n"
|
||||
" \n"
|
||||
@@ -3776,8 +3764,8 @@ const char *const language_strings[LANG_STRING_COUNT] = {
|
||||
"and %R%S HELP SET XOP to know how to toggle between \n"
|
||||
"the access list and xOP list systems."),
|
||||
/* CHAN_HELP_VOP */
|
||||
_("Syntax: VOP channel ADD nick\n"
|
||||
" VOP channel DEL {nick | entry-num | list}\n"
|
||||
_("Syntax: VOP channel ADD mask\n"
|
||||
" VOP channel DEL {mask | entry-num | list}\n"
|
||||
" VOP channel LIST [mask | list]\n"
|
||||
" VOP channel CLEAR\n"
|
||||
" \n"
|
||||
@@ -3813,8 +3801,8 @@ const char *const language_strings[LANG_STRING_COUNT] = {
|
||||
"and %R%S HELP SET XOP to know how to toggle between \n"
|
||||
"the access list and xOP list systems."),
|
||||
/* CHAN_HELP_ACCESS */
|
||||
_("Syntax: ACCESS channel ADD nick level\n"
|
||||
" ACCESS channel DEL {nick | entry-num | list}\n"
|
||||
_("Syntax: ACCESS channel ADD mask level\n"
|
||||
" ACCESS channel DEL {mask | entry-num | list}\n"
|
||||
" ACCESS channel LIST [mask | list]\n"
|
||||
" ACCESS channel VIEW [mask | list]\n"
|
||||
" ACCESS channel CLEAR\n"
|
||||
@@ -3827,14 +3815,16 @@ const char *const language_strings[LANG_STRING_COUNT] = {
|
||||
"specific information. Any nick not on the access list has\n"
|
||||
"a user level of 0.\n"
|
||||
" \n"
|
||||
"The ACCESS ADD command adds the given nickname to the\n"
|
||||
"access list with the given user level; if the nick is\n"
|
||||
"The ACCESS ADD command adds the given mask to the\n"
|
||||
"access list with the given user level; if the mask is\n"
|
||||
"already present on the list, its access level is changed to\n"
|
||||
"the level specified in the command. The level specified\n"
|
||||
"must be less than that of the user giving the command, and\n"
|
||||
"if the nick is already on the access list, the current\n"
|
||||
"if the mask is already on the access list, the current\n"
|
||||
"access level of that nick must be less than the access level\n"
|
||||
"of the user giving the command.\n"
|
||||
"of the user giving the command. When a user joins the channel\n"
|
||||
"the access they receive is from the highest level entry in the\n"
|
||||
"access list.\n"
|
||||
" \n"
|
||||
"The ACCESS DEL command removes the given nick from the\n"
|
||||
"access list. If a list of entry numbers is given, those\n"
|
||||
|
||||
+118
-12
@@ -12,6 +12,9 @@
|
||||
#include "services.h"
|
||||
#include "modules.h"
|
||||
|
||||
// Awesome channel access hack for superadmin and founder
|
||||
static ChanAccess dummy_access;
|
||||
|
||||
/** Default constructor
|
||||
* @param chname The channel name
|
||||
*/
|
||||
@@ -87,7 +90,7 @@ ChannelInfo::ChannelInfo(ChannelInfo *ci)
|
||||
for (unsigned i = 0; i < ci->GetAccessCount(); ++i)
|
||||
{
|
||||
ChanAccess *access = ci->GetAccess(i);
|
||||
this->AddAccess(access->nc, access->level, access->creator, access->last_seen);
|
||||
this->AddAccess(access->mask, access->level, access->creator, access->last_seen);
|
||||
}
|
||||
for (unsigned i = 0; i < ci->GetAkickCount(); ++i)
|
||||
{
|
||||
@@ -145,18 +148,20 @@ ChannelInfo::~ChannelInfo()
|
||||
|
||||
/** Add an entry to the channel access list
|
||||
*
|
||||
* @param nc The NickCore of the user that the access entry should be tied to
|
||||
* @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.
|
||||
*/
|
||||
|
||||
void ChannelInfo::AddAccess(NickCore *nc, int16 level, const Anope::string &creator, int32 last_seen)
|
||||
ChanAccess *ChannelInfo::AddAccess(const Anope::string &mask, int16 level, const Anope::string &creator, int32 last_seen)
|
||||
{
|
||||
ChanAccess *new_access = new ChanAccess();
|
||||
new_access->nc = nc;
|
||||
new_access->mask = mask;
|
||||
new_access->nc = findcore(mask);
|
||||
new_access->level = level;
|
||||
new_access->last_seen = last_seen;
|
||||
if (!creator.empty())
|
||||
@@ -165,6 +170,8 @@ void ChannelInfo::AddAccess(NickCore *nc, int16 level, const Anope::string &crea
|
||||
new_access->creator = "Unknown";
|
||||
|
||||
this->access.push_back(new_access);
|
||||
|
||||
return new_access;
|
||||
}
|
||||
|
||||
/** Get an entry from the channel access list by index
|
||||
@@ -184,22 +191,102 @@ ChanAccess *ChannelInfo::GetAccess(unsigned index)
|
||||
|
||||
/** Get an entry from the channel access list by NickCore
|
||||
*
|
||||
* @param nc The NickCore to find within the access list vector
|
||||
* @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
|
||||
*
|
||||
* Retrieves an entry from the access list that matches the given NickCore, optionally also matching a certain level.
|
||||
*/
|
||||
|
||||
ChanAccess *ChannelInfo::GetAccess(const NickCore *nc, int16 level)
|
||||
ChanAccess *ChannelInfo::GetAccess(User *u, int16 level)
|
||||
{
|
||||
if (this->access.empty())
|
||||
if (!u)
|
||||
return NULL;
|
||||
|
||||
for (unsigned i = 0, end = this->access.size(); i < end; ++i)
|
||||
if (this->access[i]->nc == nc && (level ? this->access[i]->level == level : true))
|
||||
return this->access[i];
|
||||
if (u->isSuperAdmin || IsFounder(u, this))
|
||||
{
|
||||
dummy_access.level = u->isSuperAdmin ? ACCESS_SUPERADMIN : ACCESS_FOUNDER;
|
||||
dummy_access.mask = u->nick + "!*@*";
|
||||
dummy_access.nc = NULL;
|
||||
dummy_access.last_seen = Anope::CurTime;
|
||||
return &dummy_access;
|
||||
}
|
||||
|
||||
if (this->access.empty())
|
||||
return NULL;
|
||||
|
||||
NickAlias *na = NULL;
|
||||
if (!u->IsIdentified())
|
||||
na = findnick(u->nick);
|
||||
|
||||
ChanAccess *highest = NULL;
|
||||
for (unsigned i = 0, end = this->access.size(); i < end; ++i)
|
||||
{
|
||||
ChanAccess *access = this->access[i];
|
||||
|
||||
if (level && level != access->level)
|
||||
continue;
|
||||
/* Access entry is a mask and we match it */
|
||||
if (!access->nc && (Anope::Match(u->nick, access->mask) || Anope::Match(u->GetDisplayedMask(), access->mask)))
|
||||
;
|
||||
/* Access entry is a nick core and we are identified for that account */
|
||||
else if (access->nc && u->IsIdentified() && u->Account() == access->nc)
|
||||
;
|
||||
/* User is not identified but on a registered nick, and is recognized, and is on an insecure channel */
|
||||
else if (na && u->IsRecognized() && !this->HasFlag(CI_SECURE))
|
||||
;
|
||||
else
|
||||
continue;
|
||||
|
||||
/* Use the highest level access available */
|
||||
if (!highest || access->level > highest->level)
|
||||
highest = access;
|
||||
}
|
||||
|
||||
return highest;
|
||||
}
|
||||
|
||||
/** 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)
|
||||
{
|
||||
if (nc == this->founder)
|
||||
{
|
||||
dummy_access.level = ACCESS_FOUNDER;
|
||||
dummy_access.mask = nc->display;
|
||||
dummy_access.nc = nc;
|
||||
dummy_access.last_seen = Anope::CurTime;
|
||||
return &dummy_access;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
/** 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
|
||||
* @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)
|
||||
{
|
||||
for (unsigned i = 0, end = this->access.size(); i < end; ++i)
|
||||
if (Anope::Match(this->access[i]->mask, mask))
|
||||
return this->access[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -226,14 +313,33 @@ void ChannelInfo::EraseAccess(unsigned index)
|
||||
this->access.erase(this->access.begin() + index);
|
||||
}
|
||||
|
||||
/** Erase an entry from the channel access list
|
||||
*
|
||||
* @param access The access to remove
|
||||
*
|
||||
* Clears the memory used by the given access entry and removes it from the vector.
|
||||
*/
|
||||
void ChannelInfo::EraseAccess(ChanAccess *access)
|
||||
{
|
||||
for (unsigned i = 0, end = this->access.size(); i < end; ++i)
|
||||
{
|
||||
if (this->access[i] == access)
|
||||
{
|
||||
this->access.erase(this->access.begin() + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Clear the entire channel access list
|
||||
*
|
||||
* Clears the entire access list by deleting every item and then clearing the vector.
|
||||
*/
|
||||
void ChannelInfo::ClearAccess()
|
||||
{
|
||||
while (!this->access.empty())
|
||||
EraseAccess(0);
|
||||
for (unsigned i = this->access.size(); i > 0; --i)
|
||||
delete this->access[i - 1];
|
||||
this->access.clear();
|
||||
}
|
||||
|
||||
/** Add an akick entry to the channel by NickCore
|
||||
|
||||
Reference in New Issue
Block a user