From a78cecbeb9c677bdd4b2f44c01195759af63485b Mon Sep 17 00:00:00 2001 From: brain Date: Thu, 14 Dec 2006 17:46:47 +0000 Subject: Refactor userrec::chans. Old way: A vector of ucrec, MAXCHANS in size by default populated by NULLS, so you have to scan the vector to find an empty slot when joining a user, parting a user etc New way: std::map (the char holds their basic core permissions on the channel [voice, halfop, op]) This increases speed a ton, and removes some wtf-age. git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@5986 e03df62e-2008-0410-955e-edbf42e46eb7 --- include/channels.h | 29 +------ include/users.h | 3 +- src/channels.cpp | 163 ++++++++++++++++----------------------- src/cmd_who.cpp | 12 +-- src/mode.cpp | 82 +++++++++----------- src/modules.cpp | 19 ++--- src/modules/m_blockamsg.cpp | 4 +- src/modules/m_httpd_stats.cpp | 13 ++-- src/modules/m_nonicks.cpp | 17 ++-- src/modules/m_restrictbanned.cpp | 11 +-- src/users.cpp | 146 ++++++++++++----------------------- 11 files changed, 186 insertions(+), 313 deletions(-) diff --git a/include/channels.h b/include/channels.h index e382b73e1..b480d7789 100644 --- a/include/channels.h +++ b/include/channels.h @@ -95,33 +95,6 @@ enum UserChannelModes { UCMODE_HOP = 4 }; -/** Holds a user's modes on a channel - * This class associates a users privilages with a channel by creating a pointer link between - * a userrec and chanrec class. The uc_modes member holds a bitmask of which privilages the user - * has on the channel, such as op, voice, etc. - */ -class ucrec : public classbase -{ - public: - /** Contains a bitmask of the UCMODE_OP ... UCMODE_FOUNDER values. - * If this value is zero, the user has no privilages upon the channel. - */ - char uc_modes; - - /** Points to the channel record where the given modes apply. - * If the record is not in use, this value will be NULL. - */ - chanrec *channel; - - /** Constructor for ucrec - */ - ucrec() : uc_modes(0), channel(NULL) { /* stub */ } - - /** Destructor for ucrec - */ - virtual ~ucrec() { /* stub */ } -}; - class InspIRCd; /** A stored prefix and its rank @@ -150,7 +123,7 @@ class chanrec : public Extensible /** Connect a chanrec to a userrec */ - static chanrec* ForceChan(InspIRCd* Instance, chanrec* Ptr,ucrec *a,userrec* user, const std::string &privs); + static chanrec* ForceChan(InspIRCd* Instance, chanrec* Ptr, userrec* user, const std::string &privs); prefixlist prefixes; diff --git a/include/users.h b/include/users.h index 677f8816d..429606344 100644 --- a/include/users.h +++ b/include/users.h @@ -146,7 +146,8 @@ typedef std::vector ClassVector; /** Typedef for the list of user-channel records for a user */ -typedef std::vector UserChanList; +typedef std::map UserChanList; +typedef UserChanList::iterator UCListIter; /** Holds all information about a user * This class stores all information about a user connected to the irc server. Everything about a diff --git a/src/channels.cpp b/src/channels.cpp index b96b4588e..3f9391bea 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -320,37 +320,27 @@ chanrec* chanrec::JoinUser(InspIRCd* Instance, userrec *user, const char* cn, bo } } - for (UserChanList::const_iterator index = user->chans.begin(); index != user->chans.end(); index++) - { - if ((*index)->channel == NULL) - { - return chanrec::ForceChan(Instance, Ptr, *index, user, privs); - } - } - - /* - * XXX: If the user is an oper here, we can just extend their user->chans vector by one - * and put the channel in here. Same for remote users which are not bound by - * the channel limits. Otherwise, nope, youre boned. + /* NOTE: If the user is an oper here, we can extend their user->chans by up to + * OPERMAXCHANS. For remote users which are not bound by the channel limits, + * we can extend infinitely. Otherwise, nope, youre restricted to MAXCHANS. */ if (!IS_LOCAL(user) || override == true) /* was a check on fd < 0 */ { - ucrec* a = new ucrec(); - chanrec* c = chanrec::ForceChan(Instance, Ptr, a, user, privs); - user->chans.push_back(a); - return c; + return chanrec::ForceChan(Instance, Ptr, user, privs); } else if (*user->oper) { /* Oper allows extension up to the OPERMAXCHANS value */ if (user->chans.size() < OPERMAXCHANS) { - ucrec* a = new ucrec(); - chanrec* c = chanrec::ForceChan(Instance, Ptr, a, user, privs); - user->chans.push_back(a); - return c; + return chanrec::ForceChan(Instance, Ptr, user, privs); } } + else if (user->chans.size() < MAXCHANS) + { + return chanrec::ForceChan(Instance, Ptr, user, privs); + } + user->WriteServ("405 %s %s :You are on too many channels",user->nick, cname); @@ -364,39 +354,18 @@ chanrec* chanrec::JoinUser(InspIRCd* Instance, userrec *user, const char* cn, bo Ptr->DelUser(user); DELETE(Ptr); Instance->chanlist.erase(n); - for (unsigned int index =0; index < user->chans.size(); index++) - { - if (user->chans[index]->channel == Ptr) - { - user->chans[index]->channel = NULL; - user->chans[index]->uc_modes = 0; - } - } - } - } - else - { - for (unsigned int index =0; index < user->chans.size(); index++) - { - if (user->chans[index]->channel == Ptr) - { - user->chans[index]->channel = NULL; - user->chans[index]->uc_modes = 0; - } } } + return NULL; } -chanrec* chanrec::ForceChan(InspIRCd* Instance, chanrec* Ptr,ucrec *a,userrec* user, const std::string &privs) +chanrec* chanrec::ForceChan(InspIRCd* Instance, chanrec* Ptr, userrec* user, const std::string &privs) { userrec* dummyuser = new userrec(Instance); std::string nick = user->nick; - a->uc_modes = 0; dummyuser->SetFd(FD_MAGIC_NUMBER); - - a->channel = Ptr; Ptr->AddUser(user); user->ModChannelCount(1); @@ -409,6 +378,27 @@ chanrec* chanrec::ForceChan(InspIRCd* Instance, chanrec* Ptr,ucrec *a,userrec* u Ptr->SetPrefix(user, status, mh->GetPrefixRank(), true); /* Make sure that the mode handler knows this mode was now set */ mh->OnModeChange(dummyuser, dummyuser, Ptr, nick, true); + + switch (mh->GetPrefix()) + { + /* These logic ops are SAFE IN THIS CASE + * because if the entry doesnt exist, + * addressing operator[] creates it. + * If they do exist, it points to it. + * At all other times where we dont want + * to create an item if it doesnt exist, we + * must stick to ::find(). + */ + case '@': + user->chans[Ptr] |= STATUS_OP; + break; + case '%': + user->chans[Ptr] |= STATUS_HOP; + break; + case '+': + user->chans[Ptr] |= STATUS_VOICE; + break; + } } } @@ -468,19 +458,14 @@ long chanrec::PartUser(userrec *user, const char* reason) if (!user) return this->GetUserCounter(); - for (unsigned int i =0; i < user->chans.size(); i++) + UCListIter i = user->chans.find(this); + if (i != user->chans.end()) { - /* zap it from the channel list of the user */ - if (user->chans[i]->channel == this) - { - FOREACH_MOD(I_OnUserPart,OnUserPart(user, this, reason ? reason : "")); - this->WriteChannel(user, "PART %s%s%s", this->name, reason ? " :" : "", reason ? reason : ""); - user->chans[i]->uc_modes = 0; - user->chans[i]->channel = NULL; - user->ModChannelCount(-1); - this->RemoveAllPrefixes(user); - break; - } + FOREACH_MOD(I_OnUserPart,OnUserPart(user, this, reason ? reason : "")); + this->WriteChannel(user, "PART %s%s%s", this->name, reason ? " :" : "", reason ? reason : ""); + user->chans.erase(i); + user->ModChannelCount(-1); + this->RemoveAllPrefixes(user); } if (!this->DelUser(user)) /* if there are no users left on the channel... */ @@ -518,16 +503,12 @@ long chanrec::ServerKickUser(userrec* user, const char* reason, bool triggereven FOREACH_MOD(I_OnUserKick,OnUserKick(NULL,user,this,reason)); } - for (unsigned int i =0; i < user->chans.size(); i++) + UCListIter i = user->chans.find(this); + if (i != user->chans.end()) { - if (user->chans[i]->channel == this) - { - this->WriteChannelWithServ(ServerInstance->Config->ServerName, "KICK %s %s :%s", this->name, user->nick, reason); - user->chans[i]->uc_modes = 0; - user->chans[i]->channel = NULL; - this->RemoveAllPrefixes(user); - break; - } + this->WriteChannelWithServ(ServerInstance->Config->ServerName, "KICK %s %s :%s", this->name, user->nick, reason); + user->chans.erase(i); + this->RemoveAllPrefixes(user); } if (!this->DelUser(user)) @@ -592,18 +573,14 @@ long chanrec::KickUser(userrec *src, userrec *user, const char* reason) } FOREACH_MOD(I_OnUserKick,OnUserKick(src,user,this,reason)); - - for (UserChanList::const_iterator i = user->chans.begin(); i != user->chans.end(); i++) + + UCListIter i = user->chans.find(this); + if (i != user->chans.end()) { /* zap it from the channel list of the user */ - if ((*i)->channel == this) - { - this->WriteChannel(src, "KICK %s %s :%s", this->name, user->nick, reason); - (*i)->uc_modes = 0; - (*i)->channel = NULL; - this->RemoveAllPrefixes(user); - break; - } + this->WriteChannel(src, "KICK %s %s :%s", this->name, user->nick, reason); + user->chans.erase(i); + this->RemoveAllPrefixes(user); } if (!this->DelUser(user)) @@ -960,43 +937,37 @@ unsigned int chanrec::GetPrefixValue(userrec* user) return 0; } - int chanrec::GetStatusFlags(userrec *user) { - for (std::vector::const_iterator i = user->chans.begin(); i != user->chans.end(); i++) + UCListIter i = user->chans.find(this); + if (i != user->chans.end()) { - if ((*i)->channel == this) - { - return (*i)->uc_modes; - } + return i->second; } return 0; } - int chanrec::GetStatus(userrec *user) { if (ServerInstance->ULine(user->server)) return STATUS_OP; - for (std::vector::const_iterator i = user->chans.begin(); i != user->chans.end(); i++) + UCListIter i = user->chans.find(this); + if (i != user->chans.end()) { - if ((*i)->channel == this) + if ((i->second & UCMODE_OP) > 0) { - if (((*i)->uc_modes & UCMODE_OP) > 0) - { - return STATUS_OP; - } - if (((*i)->uc_modes & UCMODE_HOP) > 0) - { - return STATUS_HOP; - } - if (((*i)->uc_modes & UCMODE_VOICE) > 0) - { - return STATUS_VOICE; - } - return STATUS_NORMAL; + return STATUS_OP; + } + if ((i->second & UCMODE_HOP) > 0) + { + return STATUS_HOP; + } + if ((i->second & UCMODE_VOICE) > 0) + { + return STATUS_VOICE; } + return STATUS_NORMAL; } return STATUS_NORMAL; } diff --git a/src/cmd_who.cpp b/src/cmd_who.cpp index 725d19bb7..112d2e030 100644 --- a/src/cmd_who.cpp +++ b/src/cmd_who.cpp @@ -23,15 +23,11 @@ /* get the last 'visible' chan of a user */ static char *getlastchanname(userrec *u) { - for (std::vector::const_iterator v = u->chans.begin(); v != u->chans.end(); v++) + UCListIter i = u->chans.begin(); + if (i != u->chans.end()) { - ucrec* temp = (ucrec*)*v; - - if (temp->channel) - { - if (!temp->channel->IsModeSet('s')) - return temp->channel->name; - } + if (!i->first->IsModeSet('s')) + return i->first->name; } return "*"; diff --git a/src/mode.cpp b/src/mode.cpp index eee50c293..d56e6ec38 100644 --- a/src/mode.cpp +++ b/src/mode.cpp @@ -175,31 +175,28 @@ const char* ModeParser::Grant(userrec *d,chanrec *chan,int MASK) if (!chan) return ""; - for (std::vector::const_iterator i = d->chans.begin(); i != d->chans.end(); i++) + UCListIter n = d->chans.find(chan); + if (n != d->chans.end()) { - ucrec* n = (ucrec*)(*i); - if (n->channel == chan) + if (n->second & MASK) { - if (n->uc_modes & MASK) - { - return ""; - } - n->uc_modes = n->uc_modes | MASK; - switch (MASK) - { - case UCMODE_OP: - n->channel->AddOppedUser(d); - break; - case UCMODE_HOP: - n->channel->AddHalfoppedUser(d); - break; - case UCMODE_VOICE: - n->channel->AddVoicedUser(d); - break; - } - ServerInstance->Log(DEBUG,"grant: %s %s",n->channel->name,d->nick); - return d->nick; + return ""; + } + n->second = n->second | MASK; + switch (MASK) + { + case UCMODE_OP: + n->first->AddOppedUser(d); + break; + case UCMODE_HOP: + n->first->AddHalfoppedUser(d); + break; + case UCMODE_VOICE: + n->first->AddVoicedUser(d); + break; } + ServerInstance->Log(DEBUG,"grant: %s %s",n->first->name,d->nick); + return d->nick; } return ""; } @@ -209,31 +206,28 @@ const char* ModeParser::Revoke(userrec *d,chanrec *chan,int MASK) if (!chan) return ""; - for (std::vector::const_iterator i = d->chans.begin(); i != d->chans.end(); i++) + UCListIter n = d->chans.find(chan); + if (n != d->chans.end()) { - ucrec* n = (ucrec*)(*i); - if (n->channel == chan) + if ((n->second & MASK) == 0) { - if ((n->uc_modes & MASK) == 0) - { - return ""; - } - n->uc_modes ^= MASK; - switch (MASK) - { - case UCMODE_OP: - n->channel->DelOppedUser(d); - break; - case UCMODE_HOP: - n->channel->DelHalfoppedUser(d); - break; - case UCMODE_VOICE: - n->channel->DelVoicedUser(d); - break; - } - ServerInstance->Log(DEBUG,"revoke: %s %s",n->channel->name,d->nick); - return d->nick; + return ""; + } + n->second ^= MASK; + switch (MASK) + { + case UCMODE_OP: + n->first->DelOppedUser(d); + break; + case UCMODE_HOP: + n->first->DelHalfoppedUser(d); + break; + case UCMODE_VOICE: + n->first->DelVoicedUser(d); + break; } + ServerInstance->Log(DEBUG,"revoke: %s %s",n->first->name,d->nick); + return d->nick; } return ""; } diff --git a/src/modules.cpp b/src/modules.cpp index b670291ec..16631c1f2 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -472,20 +472,17 @@ bool InspIRCd::PseudoToUser(userrec* alive, userrec* zombie, const std::string & } // Fix by brain - cant write the user until their fd table entry is updated zombie->Write(":%s!%s@%s NICK %s",oldnick.c_str(),oldident.c_str(),oldhost.c_str(),zombie->nick); - for (std::vector::const_iterator i = zombie->chans.begin(); i != zombie->chans.end(); i++) + for (UCListIter i = zombie->chans.begin(); i != zombie->chans.end(); i++) { - if (((ucrec*)(*i))->channel != NULL) + chanrec* Ptr = i->first; + zombie->WriteFrom(zombie,"JOIN %s",Ptr->name); + if (Ptr->topicset) { - chanrec* Ptr = ((ucrec*)(*i))->channel; - zombie->WriteFrom(zombie,"JOIN %s",Ptr->name); - if (Ptr->topicset) - { - zombie->WriteServ("332 %s %s :%s", zombie->nick, Ptr->name, Ptr->topic); - zombie->WriteServ("333 %s %s %s %d", zombie->nick, Ptr->name, Ptr->setby, Ptr->topicset); - } - Ptr->UserList(zombie); - zombie->WriteServ("366 %s %s :End of /NAMES list.", zombie->nick, Ptr->name); + zombie->WriteServ("332 %s %s :%s", zombie->nick, Ptr->name, Ptr->topic); + zombie->WriteServ("333 %s %s %s %d", zombie->nick, Ptr->name, Ptr->setby, Ptr->topicset); } + Ptr->UserList(zombie); + zombie->WriteServ("366 %s %s :End of /NAMES list.", zombie->nick, Ptr->name); } if ((find(local_users.begin(),local_users.end(),zombie) == local_users.end()) && (zombie->GetFd() != FD_MAGIC_NUMBER)) local_users.push_back(zombie); diff --git a/src/modules/m_blockamsg.cpp b/src/modules/m_blockamsg.cpp index 1b5fee40b..87cba2972 100644 --- a/src/modules/m_blockamsg.cpp +++ b/src/modules/m_blockamsg.cpp @@ -122,9 +122,7 @@ public: if((*c == ',') && *(c+1) && (*(c+1) == '#')) targets++; - for(std::vector::iterator f = user->chans.begin(); f != user->chans.end(); f++) - if(((ucrec*)(*f))->channel) - userchans++; + userchans = user->chans.size(); // Check that this message wasn't already sent within a few seconds. BlockedMessage* m; diff --git a/src/modules/m_httpd_stats.cpp b/src/modules/m_httpd_stats.cpp index eda5b6f66..fb5499c2d 100644 --- a/src/modules/m_httpd_stats.cpp +++ b/src/modules/m_httpd_stats.cpp @@ -212,16 +212,13 @@ class ModuleHttpStats : public Module void OnUserQuit(userrec* user, const std::string &message) { - for (std::vector::const_iterator v = user->chans.begin(); v != user->chans.end(); v++) + for (UCListIter v = user->chans.begin(); v != user->chans.end(); v++) { - if (((ucrec*)(*v))->channel) + chanrec* c = v->first; + StatsIter a = sh->find(c->name); + if (a != sh->end()) { - chanrec* c = ((ucrec*)(*v))->channel; - StatsIter a = sh->find(c->name); - if (a != sh->end()) - { - a->second--; - } + a->second--; } } this->changed = true; diff --git a/src/modules/m_nonicks.cpp b/src/modules/m_nonicks.cpp index 90fd93f1c..df4552860 100644 --- a/src/modules/m_nonicks.cpp +++ b/src/modules/m_nonicks.cpp @@ -87,18 +87,15 @@ class ModuleNoNickChange : public Module irc::string me = ServerInstance->Config->ServerName; if (server == me) { - for (std::vector::iterator i = user->chans.begin(); i != user->chans.end(); i++) + for (UCListIter i = user->chans.begin(); i != user->chans.end(); i++) { - if (((ucrec*)(*i))->channel != NULL) + chanrec* curr = i->first; + if ((curr->IsModeSet('N')) && (!*user->oper)) { - chanrec* curr = ((ucrec*)(*i))->channel; - if ((curr->IsModeSet('N')) && (!*user->oper)) - { - // don't allow the nickchange, theyre on at least one channel with +N set - // and theyre not an oper - user->WriteServ("447 %s :Can't change nickname while on %s (+N is set)",user->nick,curr->name); - return 1; - } + // don't allow the nickchange, theyre on at least one channel with +N set + // and theyre not an oper + user->WriteServ("447 %s :Can't change nickname while on %s (+N is set)", user->nick, curr->name); + return 1; } } } diff --git a/src/modules/m_restrictbanned.cpp b/src/modules/m_restrictbanned.cpp index 51ff39772..c37951eea 100644 --- a/src/modules/m_restrictbanned.cpp +++ b/src/modules/m_restrictbanned.cpp @@ -69,15 +69,10 @@ class ModuleRestrictBanned : public Module return 0; /* bit of a special case. */ - for (std::vector::iterator i = user->chans.begin(); i != user->chans.end(); i++) + for (UCListIter i = user->chans.begin(); i != user->chans.end(); i++) { - if (((ucrec*)(*i))->channel != NULL) - { - chanrec *channel = ((ucrec*)(*i))->channel; - - if (CheckRestricted(user, channel, "change your nickname") == 1) - return 1; - } + if (CheckRestricted(user, i->first, "change your nickname") == 1) + return 1; } return 0; diff --git a/src/users.cpp b/src/users.cpp index 3a20444e5..4bfb8955a 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -309,26 +309,12 @@ userrec::userrec(InspIRCd* Instance) : ServerInstance(Instance) ip = NULL; chans.clear(); invites.clear(); - chans.resize(MAXCHANS); memset(modes,0,sizeof(modes)); memset(snomasks,0,sizeof(snomasks)); - - for (unsigned int n = 0; n < MAXCHANS; n++) - { - chans[n] = new ucrec(); - chans[n]->channel = NULL; - chans[n]->uc_modes = 0; - } } userrec::~userrec() { - for (std::vector::iterator n = chans.begin(); n != chans.end(); n++) - { - ucrec* x = (ucrec*)*n; - delete x; - } - if (ip) { clonemap::iterator x = ServerInstance->local_clones.find(this->GetIPString()); @@ -1589,21 +1575,16 @@ void userrec::WriteCommon(const std::string &text) uniq_id++; - for (std::vector::const_iterator v = this->chans.begin(); v != this->chans.end(); v++) + for (UCListIter v = this->chans.begin(); v != this->chans.end(); v++) { - ucrec *n = *v; - if (n->channel) + CUList* ulist = v->first->GetUsers(); + for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++) { - CUList *ulist= n->channel->GetUsers(); - - for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++) + if ((IS_LOCAL(i->second)) && (already_sent[i->second->fd] != uniq_id)) { - if ((IS_LOCAL(i->second)) && (already_sent[i->second->fd] != uniq_id)) - { - already_sent[i->second->fd] = uniq_id; - i->second->WriteFrom(this, std::string(text)); - sent_to_at_least_one = true; - } + already_sent[i->second->fd] = uniq_id; + i->second->WriteFrom(this, std::string(text)); + sent_to_at_least_one = true; } } } @@ -1692,25 +1673,20 @@ void userrec::WriteCommonExcept(const std::string &text) } } - for (std::vector::const_iterator v = this->chans.begin(); v != this->chans.end(); v++) + for (UCListIter v = this->chans.begin(); v != this->chans.end(); v++) { - ucrec* n = *v; - if (n->channel) + CUList *ulist = v->first->GetUsers(); + for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++) { - CUList *ulist= n->channel->GetUsers(); - - for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++) + if (this != i->second) { - if (this != i->second) + if ((IS_LOCAL(i->second)) && (already_sent[i->second->fd] != uniq_id)) { - if ((IS_LOCAL(i->second)) && (already_sent[i->second->fd] != uniq_id)) - { - already_sent[i->second->fd] = uniq_id; - if (quit_munge) - i->second->WriteFrom(this, *i->second->oper ? std::string(oper_quit) : std::string(textbuffer)); - else - i->second->WriteFrom(this, std::string(textbuffer)); - } + already_sent[i->second->fd] = uniq_id; + if (quit_munge) + i->second->WriteFrom(this, *i->second->oper ? std::string(oper_quit) : std::string(textbuffer)); + else + i->second->WriteFrom(this, std::string(textbuffer)); } } } @@ -1774,19 +1750,13 @@ bool userrec::SharesChannelWith(userrec *other) return false; /* Outer loop */ - for (std::vector::const_iterator i = this->chans.begin(); i != this->chans.end(); i++) + for (UCListIter i = this->chans.begin(); i != this->chans.end(); i++) { - /* Fetch the channel from the user */ - ucrec* user_channel = *i; - - if (user_channel->channel) - { - /* Eliminate the inner loop (which used to be ~equal in size to the outer loop) - * by replacing it with a map::find which *should* be more efficient - */ - if (user_channel->channel->HasUser(other)) - return true; - } + /* Eliminate the inner loop (which used to be ~equal in size to the outer loop) + * by replacing it with a map::find which *should* be more efficient + */ + if (i->first->HasUser(other)) + return true; } return false; } @@ -1839,15 +1809,12 @@ bool userrec::ChangeDisplayedHost(const char* host) if (this->ServerInstance->Config->CycleHosts) { - for (std::vector::const_iterator i = this->chans.begin(); i != this->chans.end(); i++) + for (UCListIter i = this->chans.begin(); i != this->chans.end(); i++) { - if ((*i)->channel) - { - (*i)->channel->WriteAllExceptSender(this, false, 0, "JOIN %s", (*i)->channel->name); - std::string n = this->ServerInstance->Modes->ModeString(this, (*i)->channel); - if (n.length() > 0) - (*i)->channel->WriteAllExceptSender(this, true, 0, "MODE %s +%s", (*i)->channel->name, n.c_str()); - } + i->first->WriteAllExceptSender(this, false, 0, "JOIN %s", i->first->name); + std::string n = this->ServerInstance->Modes->ModeString(this, i->first); + if (n.length() > 0) + i->first->WriteAllExceptSender(this, true, 0, "MODE %s +%s", i->first->name, n.c_str()); } } @@ -1869,15 +1836,12 @@ bool userrec::ChangeIdent(const char* newident) if (this->ServerInstance->Config->CycleHosts) { - for (std::vector::const_iterator i = this->chans.begin(); i != this->chans.end(); i++) + for (UCListIter i = this->chans.begin(); i != this->chans.end(); i++) { - if ((*i)->channel) - { - (*i)->channel->WriteAllExceptSender(this, false, 0, "JOIN %s", (*i)->channel->name); - std::string n = this->ServerInstance->Modes->ModeString(this, (*i)->channel); - if (n.length() > 0) - (*i)->channel->WriteAllExceptSender(this, true, 0, "MODE %s +%s", (*i)->channel->name, n.c_str()); - } + i->first->WriteAllExceptSender(this, false, 0, "JOIN %s", i->first->name); + std::string n = this->ServerInstance->Modes->ModeString(this, i->first); + if (n.length() > 0) + i->first->WriteAllExceptSender(this, true, 0, "MODE %s +%s", i->first->name, n.c_str()); } } @@ -1909,20 +1873,15 @@ std::string userrec::ChannelList(userrec* source) try { std::string list; - for (std::vector::const_iterator i = this->chans.begin(); i != this->chans.end(); i++) + for (UCListIter i = this->chans.begin(); i != this->chans.end(); i++) { - ucrec* rec = *i; - - if(rec->channel && rec->channel->name) + /* If the target is the same as the sender, let them see all their channels. + * If the channel is NOT private/secret OR the user shares a common channel + * If the user is an oper, and the option is set. + */ + if ((source == this) || (*source->oper && ServerInstance->Config->OperSpyWhois) || (((!i->first->modes[CM_PRIVATE]) && (!i->first->modes[CM_SECRET])) || (i->first->HasUser(source)))) { - /* If the target is the same as the sender, let them see all their channels. - * If the channel is NOT private/secret OR the user shares a common channel - * If the user is an oper, and the option is set. - */ - if ((source == this) || (*source->oper && ServerInstance->Config->OperSpyWhois) || (((!rec->channel->modes[CM_PRIVATE]) && (!rec->channel->modes[CM_SECRET])) || (rec->channel->HasUser(source)))) - { - list.append(rec->channel->GetPrefixChar(this)).append(rec->channel->name).append(" "); - } + list.append(i->first->GetPrefixChar(this)).append(i->first->name).append(" "); } } return list; @@ -2001,24 +1960,19 @@ void userrec::PurgeEmptyChannels() std::vector to_delete; // firstly decrement the count on each channel - for (std::vector::iterator f = this->chans.begin(); f != this->chans.end(); f++) + for (UCListIter f = this->chans.begin(); f != this->chans.end(); f++) { - ucrec* uc = *f; - if (uc->channel) + f->first->RemoveAllPrefixes(this); + if (f->first->DelUser(this) == 0) { - uc->channel->RemoveAllPrefixes(this); - if (uc->channel->DelUser(this) == 0) + /* No users left in here, mark it for deletion */ + try { - /* No users left in here, mark it for deletion */ - try - { - to_delete.push_back(uc->channel); - } - catch (...) - { - ServerInstance->Log(DEBUG,"Exception in userrec::PurgeEmptyChannels to_delete.push_back()"); - } - uc->channel = NULL; + to_delete.push_back(f->first); + } + catch (...) + { + ServerInstance->Log(DEBUG,"Exception in userrec::PurgeEmptyChannels to_delete.push_back()"); } } } -- cgit v1.2.3