diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/botserv.c | 27 | ||||
-rw-r--r-- | src/channels.c | 377 | ||||
-rw-r--r-- | src/core/cs_ban.c | 2 | ||||
-rw-r--r-- | src/core/cs_clear.c | 40 | ||||
-rw-r--r-- | src/core/cs_invite.c | 2 | ||||
-rw-r--r-- | src/core/cs_kick.c | 2 | ||||
-rw-r--r-- | src/core/cs_modes.c | 2 | ||||
-rw-r--r-- | src/core/cs_register.c | 2 | ||||
-rw-r--r-- | src/core/os_clearmodes.c | 30 | ||||
-rw-r--r-- | src/modes.cpp | 4 | ||||
-rw-r--r-- | src/nickserv.c | 62 | ||||
-rw-r--r-- | src/protocol/bahamut.c | 4 | ||||
-rw-r--r-- | src/protocol/inspircd11.c | 10 | ||||
-rw-r--r-- | src/protocol/inspircd12.cpp | 10 | ||||
-rw-r--r-- | src/protocol/ratbox.c | 4 | ||||
-rw-r--r-- | src/protocol/unreal32.c | 10 | ||||
-rw-r--r-- | src/users.c | 20 |
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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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; +} /*************************************************************************/ |