summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
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;
+}
/*************************************************************************/