summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdam- <Adam-@5417fbe8-f217-4b02-8779-1006273d7864>2010-01-21 06:31:17 +0000
committerAdam- <Adam-@5417fbe8-f217-4b02-8779-1006273d7864>2010-01-21 06:31:17 +0000
commit0ed0fa4af62554a7281d403b6895b29e198e8186 (patch)
tree4b0509084ef8181790f19c258c3bc1f5e38b80cc /src
parent15817208aae1c80e2b03668981ac9268d6a02dde (diff)
Rewrote how Anope stores channel status modes on users.
This allows 3rd party modules to add and track their own status mode. Additionally we now store a users status in both the UserContainer and ChannelContainer. This also fixes the ModeStacker to not send any mode strings unnecessarially and shuffles some code around so we don't have to manually remove channels from users lists everywhere. git-svn-id: http://anope.svn.sourceforge.net/svnroot/anope/trunk@2775 5417fbe8-f217-4b02-8779-1006273d7864
Diffstat (limited to 'src')
-rw-r--r--src/botserv.c27
-rw-r--r--src/channels.c377
-rw-r--r--src/core/cs_ban.c2
-rw-r--r--src/core/cs_clear.c40
-rw-r--r--src/core/cs_invite.c2
-rw-r--r--src/core/cs_kick.c2
-rw-r--r--src/core/cs_modes.c2
-rw-r--r--src/core/cs_register.c2
-rw-r--r--src/core/os_clearmodes.c30
-rw-r--r--src/modes.cpp4
-rw-r--r--src/nickserv.c62
-rw-r--r--src/protocol/bahamut.c4
-rw-r--r--src/protocol/inspircd11.c10
-rw-r--r--src/protocol/inspircd12.cpp10
-rw-r--r--src/protocol/ratbox.c4
-rw-r--r--src/protocol/unreal32.c10
-rw-r--r--src/users.c20
17 files changed, 196 insertions, 412 deletions
diff --git a/src/botserv.c b/src/botserv.c
index 25bebaed3..74066fe9a 100644
--- a/src/botserv.c
+++ b/src/botserv.c
@@ -132,16 +132,14 @@ void botmsgs(User * u, BotInfo * bi, char *buf)
void botchanmsgs(User * u, ChannelInfo * ci, char *buf)
{
int c;
- int16 cstatus = 0;
char *cmd;
UserData *ud;
bool was_action = false;
Command *command;
std::string bbuf;
- if (!u || !buf || !ci) {
+ if (!u || !buf || !ci || !ci->c)
return;
- }
/* Answer to ping if needed, without breaking the buffer. */
if (!strnicmp(buf, "\1PING", 5)) {
@@ -167,15 +165,16 @@ void botchanmsgs(User * u, ChannelInfo * ci, char *buf)
* way.
*/
- /* We first retrieve the user status on the channel if needed */
- if (ci->botflags.HasFlag(BS_DONTKICKOPS) || ci->botflags.HasFlag(BS_DONTKICKVOICES))
- cstatus = chan_get_user_status(ci->c, u);
-
- if (buf && !check_access(u, ci, CA_NOKICK) &&
- (!ci->botflags.HasFlag(BS_DONTKICKOPS)
- || !(cstatus & (CUS_HALFOP | CUS_OP | CUS_OWNER | CUS_PROTECT)))
- && (!ci->botflags.HasFlag(BS_DONTKICKVOICES) || !(cstatus & CUS_VOICE))) {
-
+ bool Allow = false;
+ if (!ci->botflags.HasFlag(BS_DONTKICKOPS) && !ci->botflags.HasFlag(BS_DONTKICKVOICES))
+ Allow = true;
+ else if (ci->botflags.HasFlag(BS_DONTKICKOPS) && (ci->c->HasUserStatus(u, CMODE_HALFOP) || ci->c->HasUserStatus(u, CMODE_OP) || ci->c->HasUserStatus(u, CMODE_PROTECT) || ci->c->HasUserStatus(u, CMODE_OWNER)))
+ Allow = true;
+ else if (ci->botflags.HasFlag(BS_DONTKICKVOICES) && ci->c->HasUserStatus(u, CMODE_VOICE))
+ Allow = true;
+
+ if (buf && !check_access(u, ci, CA_NOKICK) && Allow)
+ {
/* Bolds kicker */
if (ci->botflags.HasFlag(BS_KICK_BOLDS) && strchr(buf, 2)) {
check_ban(ci, u, TTB_BOLDS);
@@ -759,7 +758,7 @@ void bot_raw_kick(User * requester, ChannelInfo * ci, char *nick, const char *re
{
User *u = finduser(nick);
- if (!u || !is_on_chan(ci->c, u))
+ if (!u || !ci->c->FindUser(u))
return;
if ((ModeManager::FindUserModeByName(UMODE_PROTECTED)))
@@ -791,7 +790,7 @@ void bot_raw_mode(User * requester, ChannelInfo * ci, const char *mode, char *ni
*buf = '\0';
u = finduser(nick);
- if (!u || !is_on_chan(ci->c, u))
+ if (!u || !ci->c->FindUser(u))
return;
snprintf(buf, BUFSIZE - 1, "%ld", static_cast<long>(time(NULL)));
diff --git a/src/channels.c b/src/channels.c
index f0c6e704e..7f2467f62 100644
--- a/src/channels.c
+++ b/src/channels.c
@@ -129,10 +129,13 @@ void Channel::JoinUser(User *user)
if (debug)
alog("debug: %s joins %s", user->nick.c_str(), this->name.c_str());
+ Flags<ChannelModeName> *Status = new Flags<ChannelModeName>;
ChannelContainer *cc = new ChannelContainer(this);
+ cc->Status = Status;
user->chans.push_back(cc);
UserContainer *uc = new UserContainer(user);
+ uc->Status = Status;
this->users.push_back(uc);
if (get_ignore(user->nick.c_str()) == NULL)
@@ -188,17 +191,30 @@ void Channel::DeleteUser(User *user)
if (this->ci)
update_cs_lastseen(user, this->ci);
- CUserList::iterator it;
- for (it = this->users.begin(); (*it)->user != user && it != this->users.end(); ++it);
- if (it == this->users.end())
+ CUserList::iterator cit;
+ for (cit = this->users.begin(); (*cit)->user != user && cit != this->users.end(); ++cit);
+ if (cit == this->users.end())
{
if (debug)
- alog("debug: Channel::DelUser() tried to delete nonexistnat user %s from channel %s", user->nick.c_str(), this->name.c_str());
+ alog("debug: Channel::DeleteUser() tried to delete nonexistnat user %s from channel %s", user->nick.c_str(), this->name.c_str());
return;
}
- delete *it;
- this->users.erase(it);
+ delete (*cit)->Status;
+ delete *cit;
+ this->users.erase(cit);
+
+ UChannelList::iterator uit;
+ for (uit = user->chans.begin(); (*uit)->chan != this && uit != user->chans.end(); ++uit);
+ if (uit == user->chans.end())
+ {
+ if (debug)
+ alog("debug: Channel::DeleteUser() tried to delete nonexistant channel %s from %s's channel list", this->name.c_str(), user->nick.c_str());
+ return;
+ }
+
+ delete *uit;
+ user->chans.erase(uit);
/* Channel is persistant, it shouldn't be deleted and the service bot should stay */
if (this->HasFlag(CH_PERSIST) || (this->ci && this->ci->HasFlag(CI_PERSIST)))
@@ -221,6 +237,52 @@ void Channel::DeleteUser(User *user)
delete this;
}
+/** Check if the user is on the channel
+ * @param u The user
+ * @return A user container if found, else NULL
+ */
+UserContainer *Channel::FindUser(User *u)
+{
+ for (CUserList::iterator it = this->users.begin(); it != this->users.end(); ++it)
+ if ((*it)->user == u)
+ return *it;
+ return NULL;
+}
+
+/** Check if a user has a status on a channel
+ * @param u The user
+ * @param cms The status mode, or NULL to represent no status
+ * @return true or false
+ */
+bool Channel::HasUserStatus(User *u, ChannelModeStatus *cms)
+{
+ if (!u || (cms && cms->Type != MODE_STATUS))
+ throw CoreException("Channel::HasUserStatus got bad mode");
+
+ /* Usually its more efficient to search the users channels than the channels users */
+ ChannelContainer *cc = u->FindChannel(this);
+ if (cc)
+ {
+ if (cms)
+ return cc->Status->HasFlag(cms->Name);
+ else
+ return !cc->Status->FlagCount();
+ }
+
+ return false;
+}
+
+/** Check if a user has a status on a channel
+ * Use the overloaded function for ChannelModeStatus* to check for no status
+ * @param u The user
+ * @param Name The Mode name, eg CMODE_OP, CMODE_VOICE
+ * @return true or false
+ */
+bool Channel::HasUserStatus(User *u, ChannelModeName Name)
+{
+ return HasUserStatus(u, dynamic_cast<ChannelModeStatus *>(ModeManager::FindChannelModeByName(Name)));
+}
+
/**
* See if a channel has a mode
* @param Name The mode name
@@ -268,9 +330,13 @@ void Channel::SetModeInternal(ChannelMode *cm, const std::string &param, bool En
if (debug)
alog("debug: Setting +%c on %s for %s", cm->ModeChar, this->name.c_str(), u->nick.c_str());
- ChannelModeStatus *cms = dynamic_cast<ChannelModeStatus *>(cm);
- /* Set the new status on the user */
- chan_set_user_status(this, u, cms->Status);
+ /* Set the status on the user */
+ ChannelContainer *cc = u->FindChannel(this);
+ if (cc)
+ {
+ cc->Status->SetFlag(cm->Name);
+ }
+
/* Enforce secureops, etc */
chan_set_correct_modes(u, this, 0);
return;
@@ -399,8 +465,13 @@ void Channel::RemoveModeInternal(ChannelMode *cm, const std::string &param, bool
if (debug)
alog("debug: Setting -%c on %s for %s", cm->ModeChar, this->name.c_str(), u->nick.c_str());
- ChannelModeStatus *cms = dynamic_cast<ChannelModeStatus *>(cm);
- chan_remove_user_status(this, u, cms->Status);
+ /* Remove the status on the user */
+ ChannelContainer *cc = u->FindChannel(this);
+ if (cc)
+ {
+ cc->Status->UnsetFlag(cm->Name);
+ }
+
return;
}
/* Setting b/e/I etc */
@@ -489,13 +560,8 @@ void Channel::SetMode(BotInfo *bi, ChannelMode *cm, const std::string &param, bo
else if (cm->Type == MODE_STATUS)
{
User *u = finduser(param);
- if (u)
- {
- if (chan_has_user_status(this, u, dynamic_cast<ChannelModeStatus *>(cm)->Status))
- {
- return;
- }
- }
+ if (u && HasUserStatus(u, dynamic_cast<ChannelModeStatus *>(cm)))
+ return;
}
ModeManager::StackerAdd(bi, this, cm, true, param);
@@ -543,13 +609,8 @@ void Channel::RemoveMode(BotInfo *bi, ChannelMode *cm, const std::string &param,
else if (cm->Type == MODE_STATUS)
{
User *u = finduser(param);
- if (u)
- {
- if (!chan_has_user_status(this, u, dynamic_cast<ChannelModeStatus *>(cm)->Status))
- {
- return;
- }
- }
+ if (u && !HasUserStatus(u, dynamic_cast<ChannelModeStatus *>(cm)))
+ return;
}
ModeManager::StackerAdd(bi, this, cm, false, param);
@@ -872,16 +933,10 @@ void Channel::KickInternal(const std::string &source, const std::string &nick, c
if (debug)
alog("debug: Channel::KickInternal kicking %s from %s", user->nick.c_str(), this->name.c_str());
- UChannelList::iterator it;
- for (it = user->chans.begin(); (*it)->chan != this && it != user->chans.end(); ++it);
- if (it != user->chans.end())
+ if (user->FindChannel(this))
{
- ChannelContainer *cc = *it;
-
- FOREACH_MOD(I_OnUserKicked, OnUserKicked(cc->chan, user, source, reason));
- cc->chan->DeleteUser(user);
- delete cc;
- user->chans.erase(it);
+ FOREACH_MOD(I_OnUserKicked, OnUserKicked(this, user, source, reason));
+ this->DeleteUser(user);
}
else if (debug)
alog("debug: Channel::KickInternal got kick for user %s who isn't on channel %s ?", user->nick.c_str(), this->name.c_str());
@@ -974,96 +1029,6 @@ char *chan_get_modes(Channel * chan, int complete, int plus)
/*************************************************************************/
-/* Retrieves the status of an user on a channel */
-
-int chan_get_user_status(Channel * chan, User * user)
-{
- for (UChannelList::iterator it = user->chans.begin(); it != user->chans.end(); ++it)
- if ((*it)->chan == chan)
- return (*it)->status;
-
- return 0;
-}
-
-/*************************************************************************/
-
-/* Has the given user the given status on the given channel? :p */
-
-int chan_has_user_status(Channel * chan, User * user, int16 status)
-{
- for (UChannelList::iterator it = user->chans.begin(); it != user->chans.end(); ++it)
- {
- ChannelContainer *cc = *it;
-
- if (cc->chan == chan)
- {
- if (debug)
- alog("debug: chan_has_user_status wanted %d the user is %d", status, cc->status);
- return (cc->status & status);
- }
- }
- return 0;
-}
-
-/*************************************************************************/
-
-/* Remove the status of an user on a channel */
-
-void chan_remove_user_status(Channel * chan, User * user, int16 status)
-{
- if (debug >= 2)
- alog("debug: removing user status (%d) from %s for %s", status,
- user->nick.c_str(), chan->name.c_str());
-
- for (UChannelList::iterator it = user->chans.begin(); it != user->chans.end(); ++it)
- {
- ChannelContainer *cc = *it;
-
- if (cc->chan == chan)
- {
- cc->status &= ~status;
- break;
- }
- }
-}
-
-/*************************************************************************/
-
-/* Set the status of an user on a channel */
-
-void chan_set_user_status(Channel * chan, User * user, int16 status)
-{
- UserMode *um;
-
- if (debug >= 2)
- alog("debug: setting user status (%d) on %s for %s", status,
- user->nick.c_str(), chan->name.c_str());
-
- if (Config.HelpChannel && ((um = ModeManager::FindUserModeByName(UMODE_HELPOP))) && (status & CUS_OP)
- && (stricmp(chan->name.c_str(), Config.HelpChannel) == 0)
- && (!chan->ci || check_access(user, chan->ci, CA_AUTOOP))) {
- if (debug) {
- alog("debug: %s being given helpop for having %d status in %s",
- user->nick.c_str(), status, chan->name.c_str());
- }
-
- user->SetMode(NULL, um);
- }
-
- for (UChannelList::iterator it = user->chans.begin(); it != user->chans.end(); ++it)
- {
- ChannelContainer *cc = *it;
-
- if (cc->chan == chan)
- {
- cc->status |= status;
- break;
- }
- }
-}
-
-/*************************************************************************/
-
/* Return the Channel structure corresponding to the named channel, or NULL
* if the channel was not found. chan is assumed to be non-NULL and valid
* (i.e. pointing to a channel name of 2 or more characters). */
@@ -1178,19 +1143,6 @@ void get_channel_stats(long *nrec, long *memuse)
/*************************************************************************/
-/* Is the given nick on the given channel? */
-
-int is_on_chan(Channel * c, User * u)
-{
- for (UChannelList::iterator it = u->chans.begin(); it != u->chans.end(); ++it)
- if ((*it)->chan == c)
- return 1;
-
- return 0;
-}
-
-/*************************************************************************/
-
/* Is the given nick on the given channel?
This function supports links. */
@@ -1236,7 +1188,8 @@ void do_join(const char *source, int ac, const char **av)
ci::string buf;
while (sep.GetToken(buf))
{
- if (buf[0] == '0') {
+ if (buf[0] == '0')
+ {
for (UChannelList::iterator it = user->chans.begin(); it != user->chans.end();)
{
ChannelContainer *cc = *it++;
@@ -1245,8 +1198,6 @@ void do_join(const char *source, int ac, const char **av)
FOREACH_MOD(I_OnPrePartChannel, OnPrePartChannel(user, cc->chan));
cc->chan->DeleteUser(user);
FOREACH_MOD(I_OnPartChannel, OnPartChannel(user, findchan(channame.c_str()), channame, ""));
- delete cc;
- user->chans.erase(it);
}
user->chans.clear();
continue;
@@ -1338,14 +1289,11 @@ void do_kick(const std::string &source, int ac, const char **av)
void do_part(const char *source, int ac, const char **av)
{
- User *user;
-
- user = finduser(source);
- if (!user) {
- if (debug) {
- alog("debug: PART from nonexistent user %s: %s", source,
- merge_args(ac, av));
- }
+ User *user = finduser(source);
+ if (!user)
+ {
+ if (debug)
+ alog("debug: PART from nonexistent user %s: %s", source, merge_args(ac, av));
return;
}
@@ -1353,24 +1301,26 @@ void do_part(const char *source, int ac, const char **av)
ci::string buf;
while (sep.GetToken(buf))
{
- if (debug)
- alog("debug: %s leaves %s", source, buf.c_str());
- UChannelList::iterator it;
- for (it = user->chans.begin(); buf != (*it)->chan->name && it != user->chans.end(); ++it);
- if (it != user->chans.end())
+ Channel *c = findchan(buf.c_str());
+
+ if (!c)
{
- ChannelContainer *cc = *it;
-
- FOREACH_MOD(I_OnPrePartChannel, OnPrePartChannel(user, cc->chan));
- std::string ChannelName = cc->chan->name;
-
- cc->chan->DeleteUser(user);
+ if (debug)
+ alog("debug: Recieved PART from %s for nonexistant channel %s", user->nick.c_str(), buf.c_str());
+ }
- delete *it;
- user->chans.erase(it);
+ if (debug)
+ alog("debug: %s leaves %s", source, buf.c_str());
+ if (user->FindChannel(c))
+ {
+ FOREACH_MOD(I_OnPrePartChannel, OnPrePartChannel(user, c));
+ std::string ChannelName = c->name;
+ c->DeleteUser(user);
FOREACH_MOD(I_OnPartChannel, OnPartChannel(user, findchan(ChannelName.c_str()), ChannelName, av[1] ? av[1] : ""));
}
+ else if (debug)
+ alog("debug: Recieved PART from %s for %s, but %s isn't in %s ?", user->nick.c_str(), c->name.c_str(), user->nick.c_str(), c->name.c_str());
}
}
@@ -1535,9 +1485,6 @@ void do_topic(const char *source, int ac, const char **av)
**/
void chan_set_correct_modes(User * user, Channel * c, int give_modes)
{
- int status;
- int add_modes = 0;
- int rem_modes = 0;
ChannelInfo *ci;
ChannelMode *owner, *admin, *op, *halfop, *voice;
@@ -1553,118 +1500,40 @@ void chan_set_correct_modes(User * user, Channel * c, int give_modes)
if ((ci->HasFlag(CI_FORBIDDEN)) || (*(c->name.c_str()) == '+'))
return;
- status = chan_get_user_status(c, user);
-
if (debug)
- alog("debug: Setting correct user modes for %s on %s (current status: %d, %sgiving modes)", user->nick.c_str(), c->name.c_str(), status, (give_modes ? "" : "not "));
+ alog("debug: Setting correct user modes for %s on %s (%sgiving modes)", user->nick.c_str(), c->name.c_str(), (give_modes ? "" : "not "));
- /* Changed the second line of this if a bit, to make sure unregistered
- * users can always get modes (IE: they always have autoop enabled). Before
- * this change, you were required to have a registered nick to be able
- * to receive modes. I wonder who added that... *looks at Rob* ;) -GD
- */
- if (give_modes && (get_ignore(user->nick.c_str()) == NULL)
- && (!user->nc || !user->nc->HasFlag(NI_AUTOOP))) {
- if (owner && check_access(user, ci, CA_AUTOOWNER))
- add_modes |= CUS_OWNER;
- else if (admin && check_access(user, ci, CA_AUTOPROTECT))
- add_modes |= CUS_PROTECT;
- if (op && check_access(user, ci, CA_AUTOOP))
- add_modes |= CUS_OP;
- else if (halfop && check_access(user, ci, CA_AUTOHALFOP))
- add_modes |= CUS_HALFOP;
- else if (voice && check_access(user, ci, CA_AUTOVOICE))
- add_modes |= CUS_VOICE;
- }
-
- /* We check if every mode they have is legally acquired here, and remove
- * the modes that they're not allowed to have. But only if SECUREOPS is
- * on, because else every mode is legal. -GD
- * Unless the channel has just been created. -heinz
- * Or the user matches CA_AUTODEOP... -GD
- */
- if (((ci->HasFlag(CI_SECUREOPS)) || (c->users.size() == 1)
- || check_access(user, ci, CA_AUTODEOP))
- && !is_ulined(user->server->name)) {
- if (owner && (status & CUS_OWNER) && !IsFounder(user, ci))
- rem_modes |= CUS_OWNER;
- if (admin && (status & CUS_PROTECT)
- && !check_access(user, ci, CA_AUTOPROTECT)
- && !check_access(user, ci, CA_PROTECTME))
- rem_modes |= CUS_PROTECT;
- if (op && (status & CUS_OP) && !check_access(user, ci, CA_AUTOOP)
- && !check_access(user, ci, CA_OPDEOPME))
- rem_modes |= CUS_OP;
- if (halfop && (status & CUS_HALFOP)
- && !check_access(user, ci, CA_AUTOHALFOP)
- && !check_access(user, ci, CA_HALFOPME))
- rem_modes |= CUS_HALFOP;
- }
-
- /* No modes to add or remove, exit function -GD */
- if (!add_modes && !rem_modes)
- return;
-
- if (add_modes > 0)
+ if (give_modes && !get_ignore(user->nick.c_str()) && (!user->nc || !user->nc->HasFlag(NI_AUTOOP)))
{
- if (owner && (add_modes & CUS_OWNER) && !(status & CUS_OWNER))
+ if (owner && check_access(user, ci, CA_AUTOOWNER))
c->SetMode(NULL, CMODE_OWNER, user->nick);
- else
- add_modes &= ~CUS_OWNER;
- if (admin && (add_modes & CUS_PROTECT) && !(status & CUS_PROTECT))
+ if (admin && check_access(user, ci, CA_AUTOPROTECT))
c->SetMode(NULL, CMODE_PROTECT, user->nick);
- else
- add_modes &= ~CUS_PROTECT;
- if (op && (add_modes & CUS_OP) && !(status & CUS_OP))
+ if (op && check_access(user, ci, CA_AUTOOP))
c->SetMode(NULL, CMODE_OP, user->nick);
- else
- add_modes &= ~CUS_OP;
- if (halfop && (add_modes & CUS_HALFOP) && !(status & CUS_HALFOP))
+ if (halfop && check_access(user, ci, CA_AUTOHALFOP))
c->SetMode(NULL, CMODE_HALFOP, user->nick);
- else
- add_modes &= ~CUS_HALFOP;
- if (voice && (add_modes & CUS_VOICE) && !(status & CUS_VOICE))
+ if (voice && check_access(user, ci, CA_AUTOVOICE))
c->SetMode(NULL, CMODE_VOICE, user->nick);
- else
- add_modes &= ~CUS_VOICE;
}
- if (rem_modes > 0)
+ if ((ci->HasFlag(CI_SECUREOPS) || check_access(user, ci, CA_AUTODEOP)) && !is_ulined(user->server->name))
{
- if (owner && rem_modes & CUS_OWNER)
- {
+ if (owner && !IsFounder(user, ci))
c->RemoveMode(NULL, CMODE_OWNER, user->nick);
- }
- if (admin && rem_modes & CUS_PROTECT)
- {
+ if (admin && !check_access(user, ci, CA_AUTOPROTECT) && !check_access(user, ci, CA_PROTECTME))
c->RemoveMode(NULL, CMODE_PROTECT, user->nick);
- }
- if (op && rem_modes & CUS_OP)
- {
+ if (op && !check_access(user, ci, CA_AUTOOP) && !check_access(user, ci, CA_OPDEOPME))
c->RemoveMode(NULL, CMODE_OP, user->nick);
- }
- if (halfop && rem_modes & CUS_HALFOP)
- {
+ if (halfop && !check_access(user, ci, CA_AUTOHALFOP) && !check_access(user, ci, CA_HALFOPME))
c->RemoveMode(NULL, CMODE_HALFOP, user->nick);
- }
}
-
- /* Here, both can be empty again due to the "isn't it set already?"
- * checks above. -GD
- */
- if (!add_modes && !rem_modes)
- return;
-
- if (add_modes > 0)
- chan_set_user_status(c, user, add_modes);
- if (rem_modes > 0)
- chan_remove_user_status(c, user, rem_modes);
}
/*************************************************************************/
diff --git a/src/core/cs_ban.c b/src/core/cs_ban.c
index 7edbe0944..0d07dd370 100644
--- a/src/core/cs_ban.c
+++ b/src/core/cs_ban.c
@@ -72,7 +72,7 @@ class CommandCSBan : public Command
c->SetMode(NULL, CMODE_BAN, mask);
/* We still allow host banning while not allowing to kick */
- if (!is_on_chan(c, u2))
+ if (c->FindUser(u2))
return MOD_CONT;
if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !check_access(u, ci, CA_SIGNKICK)))
diff --git a/src/core/cs_clear.c b/src/core/cs_clear.c
index 5f95e0cdc..0e8312f37 100644
--- a/src/core/cs_clear.c
+++ b/src/core/cs_clear.c
@@ -71,8 +71,6 @@ class CommandCSClear : public Command
}
else if (what == "ops")
{
- int isop, isadmin, isown;
-
if (ircd->svsmode_ucmode)
{
ircdproto->SendSVSModeChan(c, "-o", NULL);
@@ -94,18 +92,11 @@ class CommandCSClear : public Command
{
UserContainer *uc = *it;
- isop = chan_has_user_status(c, uc->user, CUS_OP);
- isadmin = chan_has_user_status(c, uc->user, CUS_PROTECT);
- isown = chan_has_user_status(c, uc->user, CUS_OWNER);
-
- if (!isop && !isadmin && !isown)
- continue;
-
- if (isown)
+ if (uc->Status->HasFlag(CMODE_OWNER))
c->RemoveMode(NULL, CMODE_OWNER, uc->user->nick);
- if (admin)
+ if (uc->Status->HasFlag(CMODE_PROTECT))
c->RemoveMode(NULL, CMODE_PROTECT, uc->user->nick);
- if (isop)
+ if (uc->Status->HasFlag(CMODE_OP))
c->RemoveMode(NULL, CMODE_OP, uc->user->nick);
}
}
@@ -115,18 +106,11 @@ class CommandCSClear : public Command
{
UserContainer *uc = *it;
- isop = chan_has_user_status(c, uc->user, CUS_OP);
- isadmin = chan_has_user_status(c, uc->user, CUS_PROTECT);
- isown = chan_has_user_status(c, uc->user, CUS_OWNER);
-
- if (!isop && !isadmin && !isown)
- continue;
-
- if (isown)
+ if (uc->Status->HasFlag(CMODE_OWNER))
c->RemoveMode(NULL, CMODE_OWNER, uc->user->nick);
- if (isadmin)
+ if (uc->Status->HasFlag(CMODE_PROTECT))
c->RemoveMode(NULL, CMODE_PROTECT, uc->user->nick);
- if (isop)
+ if (uc->Status->HasFlag(CMODE_OP))
c->RemoveMode(NULL, CMODE_OP, uc->user->nick);
}
}
@@ -139,10 +123,8 @@ class CommandCSClear : public Command
{
UserContainer *uc = *it;
- if (!chan_has_user_status(c, uc->user, CUS_HALFOP))
- continue;
-
- c->RemoveMode(NULL, CMODE_HALFOP, uc->user->nick);
+ if (uc->Status->HasFlag(CMODE_HALFOP))
+ c->RemoveMode(NULL, CMODE_HALFOP, uc->user->nick);
}
notice_lang(Config.s_ChanServ, u, CHAN_CLEARED_HOPS, chan);
@@ -153,10 +135,8 @@ class CommandCSClear : public Command
{
UserContainer *uc = *it;
- if (!chan_has_user_status(c, uc->user, CUS_VOICE))
- continue;
-
- c->RemoveMode(NULL, CMODE_VOICE, uc->user->nick);
+ if (uc->Status->HasFlag(CMODE_VOICE))
+ c->RemoveMode(NULL, CMODE_VOICE, uc->user->nick);
}
notice_lang(Config.s_ChanServ, u, CHAN_CLEARED_VOICES, chan);
diff --git a/src/core/cs_invite.c b/src/core/cs_invite.c
index 86a4f9b38..4dd17a335 100644
--- a/src/core/cs_invite.c
+++ b/src/core/cs_invite.c
@@ -54,7 +54,7 @@ class CommandCSInvite : public Command
}
}
- if (is_on_chan(c, u2))
+ if (c->FindUser(u2))
notice_lang(Config.s_ChanServ, u, CHAN_INVITE_ALREADY_IN, c->name.c_str());
else
{
diff --git a/src/core/cs_kick.c b/src/core/cs_kick.c
index 2ea506c04..7c0c57b51 100644
--- a/src/core/cs_kick.c
+++ b/src/core/cs_kick.c
@@ -52,7 +52,7 @@ class CommandCSKick : public Command
notice_lang(Config.s_ChanServ, u, CHAN_X_NOT_IN_USE, chan);
} else if (is_same ? !(u2 = u) : !(u2 = finduser(target))) {
notice_lang(Config.s_ChanServ, u, NICK_X_NOT_IN_USE, target);
- } else if (!is_on_chan(c, u2)) {
+ } else if (!c->FindUser(u2)) {
notice_lang(Config.s_ChanServ, u, NICK_X_NOT_ON_CHAN, u2->nick.c_str(), c->name.c_str());
} else if (!is_same ? !check_access(u, ci, CA_KICK) :
!check_access(u, ci, CA_KICKME)) {
diff --git a/src/core/cs_modes.c b/src/core/cs_modes.c
index bbd9e7a42..d3525d7cc 100644
--- a/src/core/cs_modes.c
+++ b/src/core/cs_modes.c
@@ -46,7 +46,7 @@ static CommandReturn do_util(User *u, ChannelMode *cm, const char *chan, const c
notice_lang(Config.s_ChanServ, u, CHAN_X_NOT_IN_USE, chan);
else if (is_same ? !(u2 = u) : !(u2 = finduser(nick)))
notice_lang(Config.s_ChanServ, u, NICK_X_NOT_IN_USE, nick);
- else if (!is_on_chan(c, u2))
+ else if (!c->FindUser(u2))
notice_lang(Config.s_ChanServ, u, NICK_X_NOT_ON_CHAN, u2->nick.c_str(), c->name.c_str());
else if (is_same ? !check_access(u, ci, levelself) : !check_access(u, ci, level))
notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
diff --git a/src/core/cs_register.c b/src/core/cs_register.c
index bf3472c5a..d934afb6e 100644
--- a/src/core/cs_register.c
+++ b/src/core/cs_register.c
@@ -49,7 +49,7 @@ class CommandCSRegister : public Command
notice_lang(Config.s_ChanServ, u, CHAN_ALREADY_REGISTERED, chan);
else if (!stricmp(chan, "#"))
notice_lang(Config.s_ChanServ, u, CHAN_MAY_NOT_BE_REGISTERED, chan);
- else if (!chan_has_user_status(c, u, CUS_OP))
+ else if (!c->HasUserStatus(u, CMODE_OP))
notice_lang(Config.s_ChanServ, u, CHAN_MUST_BE_CHANOP);
else if (Config.CSMaxReg && u->nc->channelcount >= Config.CSMaxReg && !u->nc->HasPriv("chanserv/no-register-limit"))
notice_lang(Config.s_ChanServ, u, u->nc->channelcount > Config.CSMaxReg ? CHAN_EXCEEDED_CHANNEL_LIMIT : CHAN_REACHED_CHANNEL_LIMIT, Config.CSMaxReg);
diff --git a/src/core/os_clearmodes.c b/src/core/os_clearmodes.c
index d0bc4c44b..f52cd12ae 100644
--- a/src/core/os_clearmodes.c
+++ b/src/core/os_clearmodes.c
@@ -65,10 +65,8 @@ class CommandOSClearModes : public Command
{
UserContainer *uc = *it;
- if (!chan_has_user_status(c, uc->user, CUS_OP))
- continue;
-
- c->RemoveMode(NULL, CMODE_OP, uc->user->nick);
+ if (uc->Status->HasFlag(CMODE_OP))
+ c->RemoveMode(NULL, CMODE_OP, uc->user->nick);
}
}
@@ -81,10 +79,8 @@ class CommandOSClearModes : public Command
{
UserContainer *uc = *it;
- if (!chan_has_user_status(c, uc->user, CUS_VOICE))
- continue;
-
- c->RemoveMode(NULL, CMODE_VOICE, uc->user->nick);
+ if (uc->Status->HasFlag(CMODE_VOICE))
+ c->RemoveMode(NULL, CMODE_VOICE, uc->user->nick);
}
}
@@ -99,10 +95,8 @@ class CommandOSClearModes : public Command
{
UserContainer *uc = *it;
- if (!chan_has_user_status(c, uc->user, CUS_HALFOP))
- continue;
-
- c->RemoveMode(NULL, CMODE_HALFOP, uc->user->nick);
+ if (uc->Status->HasFlag(CMODE_HALFOP))
+ c->RemoveMode(NULL, CMODE_HALFOP, uc->user->nick);
}
}
}
@@ -121,10 +115,8 @@ class CommandOSClearModes : public Command
{
UserContainer *uc = *it;
- if (!chan_has_user_status(c, uc->user, CUS_OWNER))
- continue;
-
- c->RemoveMode(NULL, CMODE_OWNER, uc->user->nick);
+ if (uc->Status->HasFlag(CMODE_OWNER))
+ c->RemoveMode(NULL, CMODE_OWNER, uc->user->nick);
}
}
}
@@ -143,10 +135,8 @@ class CommandOSClearModes : public Command
{
UserContainer *uc = *it;
- if (!chan_has_user_status(c, uc->user, CUS_PROTECT))
- continue;
-
- c->RemoveMode(NULL, CMODE_PROTECT, uc->user->nick);
+ if (uc->Status->HasFlag(CMODE_PROTECT))
+ c->RemoveMode(NULL, CMODE_PROTECT, uc->user->nick);
}
}
}
diff --git a/src/modes.cpp b/src/modes.cpp
index c634f7f53..31ec6545f 100644
--- a/src/modes.cpp
+++ b/src/modes.cpp
@@ -146,14 +146,12 @@ ChannelModeParam::~ChannelModeParam()
/** Default constructor
* @param mName The mode name
- * @param mStatus A CUS_ value
* @param mSymbol The symbol for the mode, eg @ % +
* @param mProtectBotServ Should botserv clients reset this on themself if it gets unset?
*/
-ChannelModeStatus::ChannelModeStatus(ChannelModeName mName, int16 mStatus, char mSymbol, bool mProtectBotServ) : ChannelMode(mName)
+ChannelModeStatus::ChannelModeStatus(ChannelModeName mName, char mSymbol, bool mProtectBotServ) : ChannelMode(mName)
{
this->Type = MODE_STATUS;
- this->Status = mStatus;
this->Symbol = mSymbol;
this->ProtectBotServ = mProtectBotServ;
}
diff --git a/src/nickserv.c b/src/nickserv.c
index 4ab8fc4b8..506e56ef4 100644
--- a/src/nickserv.c
+++ b/src/nickserv.c
@@ -868,68 +868,6 @@ void SetOperType(NickCore *nc)
/*********************** NickServ command routines ***********************/
/*************************************************************************/
-
-/* We don't use this function but we keep it for module coders -certus */
-int should_mode_change(int16 status, int16 mode)
-{
- switch (mode)
- {
- case CUS_OP:
- if (status & CUS_OP)
- {
- return 0;
- }
- break;
- case CUS_VOICE:
- if (status & CUS_OP)
- {
- return 0;
- }
- if (status & CUS_HALFOP)
- {
- return 0;
- }
- if (status & CUS_VOICE)
- {
- return 0;
- }
- return 1;
- break;
- case CUS_HALFOP:
- if (status & CUS_OP)
- {
- return 0;
- }
- if (status & CUS_HALFOP)
- {
- return 0;
- }
- return 1;
- break;
- case CUS_OWNER:
- if (ModeManager::FindChannelModeByName(CMODE_OWNER))
- {
- if (status & CUS_OWNER)
- {
- return 0;
- }
- }
- break;
- case CUS_PROTECT:
- if (ModeManager::FindChannelModeByName(CMODE_PROTECT))
- {
- if (status & CUS_PROTECT)
- {
- return 0;
- }
- }
- break;
- }
- return 1;
-}
-
-/*************************************************************************/
-
int do_setmodes(User * u)
{
Channel *c;
diff --git a/src/protocol/bahamut.c b/src/protocol/bahamut.c
index e57604b8b..d3c92df86 100644
--- a/src/protocol/bahamut.c
+++ b/src/protocol/bahamut.c
@@ -828,8 +828,8 @@ void moduleAddModes()
ModeManager::AddChannelMode('b', new ChannelModeBan());
/* v/h/o/a/q */
- ModeManager::AddChannelMode('v', new ChannelModeStatus(CMODE_VOICE, CUS_VOICE, '+'));
- ModeManager::AddChannelMode('o', new ChannelModeStatus(CMODE_OP, CUS_OP, '@', true));
+ ModeManager::AddChannelMode('v', new ChannelModeStatus(CMODE_VOICE, '+'));
+ ModeManager::AddChannelMode('o', new ChannelModeStatus(CMODE_OP, '@', true));
/* Add channel modes */
ModeManager::AddChannelMode('c', new ChannelMode(CMODE_BLOCKCOLOR));
diff --git a/src/protocol/inspircd11.c b/src/protocol/inspircd11.c
index a4f4fc55d..85612f010 100644
--- a/src/protocol/inspircd11.c
+++ b/src/protocol/inspircd11.c
@@ -1058,11 +1058,11 @@ void moduleAddModes()
ModeManager::AddChannelMode('b', new ChannelModeBan());
/* v/h/o/a/q */
- ModeManager::AddChannelMode('v', new ChannelModeStatus(CMODE_VOICE, CUS_VOICE, '+'));
- ModeManager::AddChannelMode('h', new ChannelModeStatus(CMODE_HALFOP, CUS_HALFOP, '%'));
- ModeManager::AddChannelMode('o', new ChannelModeStatus(CMODE_OP, CUS_OP, '@', true));
- ModeManager::AddChannelMode('a', new ChannelModeStatus(CMODE_PROTECT, CUS_PROTECT, '&', true));
- ModeManager::AddChannelMode('q', new ChannelModeStatus(CMODE_OWNER, CUS_OWNER, '~'));
+ ModeManager::AddChannelMode('v', new ChannelModeStatus(CMODE_VOICE, '+'));
+ ModeManager::AddChannelMode('h', new ChannelModeStatus(CMODE_HALFOP, '%'));
+ ModeManager::AddChannelMode('o', new ChannelModeStatus(CMODE_OP, '@', true));
+ ModeManager::AddChannelMode('a', new ChannelModeStatus(CMODE_PROTECT, '&', true));
+ ModeManager::AddChannelMode('q', new ChannelModeStatus(CMODE_OWNER, '~'));
/* Add channel modes */
ModeManager::AddChannelMode('c', new ChannelMode(CMODE_BLOCKCOLOR));
diff --git a/src/protocol/inspircd12.cpp b/src/protocol/inspircd12.cpp
index f07d5896e..f7f57971e 100644
--- a/src/protocol/inspircd12.cpp
+++ b/src/protocol/inspircd12.cpp
@@ -1236,11 +1236,11 @@ void moduleAddModes()
ModeManager::AddChannelMode('b', new ChannelModeBan());
/* v/h/o/a/q */
- ModeManager::AddChannelMode('v', new ChannelModeStatus(CMODE_VOICE, CUS_VOICE, '+'));
- ModeManager::AddChannelMode('h', new ChannelModeStatus(CMODE_HALFOP, CUS_HALFOP, '%'));
- ModeManager::AddChannelMode('o', new ChannelModeStatus(CMODE_OP, CUS_OP, '@', true));
- ModeManager::AddChannelMode('a', new ChannelModeStatus(CMODE_PROTECT, CUS_PROTECT, '&', true));
- ModeManager::AddChannelMode('q', new ChannelModeStatus(CMODE_OWNER, CUS_OWNER, '~'));
+ ModeManager::AddChannelMode('v', new ChannelModeStatus(CMODE_VOICE, '+'));
+ ModeManager::AddChannelMode('h', new ChannelModeStatus(CMODE_HALFOP, '%'));
+ ModeManager::AddChannelMode('o', new ChannelModeStatus(CMODE_OP, '@', true));
+ ModeManager::AddChannelMode('a', new ChannelModeStatus(CMODE_PROTECT, '&', true));
+ ModeManager::AddChannelMode('q', new ChannelModeStatus(CMODE_OWNER, '~'));
/* Add channel modes */
ModeManager::AddChannelMode('i', new ChannelMode(CMODE_INVITE));
diff --git a/src/protocol/ratbox.c b/src/protocol/ratbox.c
index 11141b6a5..46431c38c 100644
--- a/src/protocol/ratbox.c
+++ b/src/protocol/ratbox.c
@@ -931,8 +931,8 @@ void moduleAddModes()
ModeManager::AddChannelMode('I', new ChannelModeInvite());
/* v/h/o/a/q */
- ModeManager::AddChannelMode('v', new ChannelModeStatus(CMODE_VOICE, CUS_VOICE, '+'));
- ModeManager::AddChannelMode('o', new ChannelModeStatus(CMODE_OP, CUS_OP, '@', true));
+ ModeManager::AddChannelMode('v', new ChannelModeStatus(CMODE_VOICE, '+'));
+ ModeManager::AddChannelMode('o', new ChannelModeStatus(CMODE_OP, '@', true));
/* Add channel modes */
ModeManager::AddChannelMode('i', new ChannelMode(CMODE_INVITE));
diff --git a/src/protocol/unreal32.c b/src/protocol/unreal32.c
index 76411ed51..e2b66b2ea 100644
--- a/src/protocol/unreal32.c
+++ b/src/protocol/unreal32.c
@@ -1261,12 +1261,12 @@ void moduleAddModes()
ModeManager::AddChannelMode('I', new ChannelModeInvite());
/* v/h/o/a/q */
- ModeManager::AddChannelMode('v', new ChannelModeStatus(CMODE_VOICE, CUS_VOICE, '+'));
- ModeManager::AddChannelMode('h', new ChannelModeStatus(CMODE_HALFOP, CUS_HALFOP, '%'));
- ModeManager::AddChannelMode('o', new ChannelModeStatus(CMODE_OP, CUS_OP, '@', true));
- ModeManager::AddChannelMode('a', new ChannelModeStatus(CMODE_PROTECT, CUS_PROTECT, '&', true));
+ ModeManager::AddChannelMode('v', new ChannelModeStatus(CMODE_VOICE, '+'));
+ ModeManager::AddChannelMode('h', new ChannelModeStatus(CMODE_HALFOP, '%'));
+ ModeManager::AddChannelMode('o', new ChannelModeStatus(CMODE_OP, '@', true));
+ ModeManager::AddChannelMode('a', new ChannelModeStatus(CMODE_PROTECT, '&', true));
/* Unreal sends +q as * */
- ModeManager::AddChannelMode('q', new ChannelModeStatus(CMODE_OWNER, CUS_OWNER, '*'));
+ ModeManager::AddChannelMode('q', new ChannelModeStatus(CMODE_OWNER, '*'));
/* Add channel modes */
ModeManager::AddChannelMode('c', new ChannelMode(CMODE_BLOCKCOLOR));
diff --git a/src/users.c b/src/users.c
index a1f9fb05c..c67d1a762 100644
--- a/src/users.c
+++ b/src/users.c
@@ -272,10 +272,7 @@ User::~User()
while (!this->chans.empty())
{
- ChannelContainer *cc = this->chans.front();
- cc->chan->DeleteUser(this);
- delete cc;
- this->chans.pop_front();
+ this->chans.front()->chan->DeleteUser(this);
}
/* Cancel pending nickname enforcers, etc */
@@ -609,13 +606,26 @@ void User::SetModes(BotInfo *bi, const char *modes, ...)
else
this->SetMode(bi, um);
}
- else if (add == 0)
+ else
{
this->RemoveMode(bi, um);
}
}
}
+/** Find the channel container for Channel c that the user is on
+ * This is preferred over using FindUser in Channel, as there are usually more users in a channel
+ * than channels a user is in
+ * @param c The channel
+ * @return The channel container, or NULL
+ */
+ChannelContainer *User::FindChannel(Channel *c)
+{
+ for (UChannelList::iterator it = this->chans.begin(); it != this->chans.end(); ++it)
+ if ((*it)->chan == c)
+ return *it;
+ return NULL;
+}
/*************************************************************************/