X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fchannels.cpp;h=9f1eafd0cb1f1e9654a8d3890310a46ac98af26a;hb=748b3a0d89e7ecc9a766471b79fb78f63a5ca2bb;hp=229e2b8eaf0696846334da78fadd56141406bbc5;hpb=58212b3d2b7197fa7e89de4c97848cdc937b32c3;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/channels.cpp b/src/channels.cpp index 229e2b8ea..9f1eafd0c 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -31,12 +31,10 @@ Channel::Channel(const std::string &cname, time_t ts) { - chan_hash::iterator findchan = ServerInstance->chanlist->find(cname); - if (findchan != ServerInstance->chanlist->end()) + if (!ServerInstance->chanlist->insert(std::make_pair(cname, this)).second) throw CoreException("Cannot create duplicate channel " + cname); - (*(ServerInstance->chanlist))[cname.c_str()] = this; - this->name.assign(cname, 0, ServerInstance->Config->Limits.ChanMax); + this->name = cname; this->age = ts ? ts : ServerInstance->Time(); maxbans = topicset = 0; @@ -118,16 +116,8 @@ int Channel::SetTopic(User *u, std::string &ntopic, bool forceset) } this->topic.assign(ntopic, 0, ServerInstance->Config->Limits.MaxTopic); - if (u) - { - this->setby.assign(ServerInstance->Config->FullHostInTopic ? u->GetFullHost() : u->nick, 0, 128); - this->WriteChannel(u, "TOPIC %s :%s", this->name.c_str(), this->topic.c_str()); - } - else - { - this->setby.assign(ServerInstance->Config->ServerName); - this->WriteChannelWithServ(ServerInstance->Config->ServerName, "TOPIC %s :%s", this->name.c_str(), this->topic.c_str()); - } + this->setby.assign(ServerInstance->Config->FullHostInTopic ? u->GetFullHost() : u->nick, 0, 128); + this->WriteChannel(u, "TOPIC %s :%s", this->name.c_str(), this->topic.c_str()); this->topicset = ServerInstance->Time(); @@ -212,10 +202,18 @@ void Channel::SetDefaultModes() if (mode) { if (mode->GetNumParams(true)) + { list.GetToken(parameter); + // If the parameter begins with a ':' then it's invalid + if (parameter.c_str()[0] == ':') + continue; + } else parameter.clear(); + if ((mode->GetNumParams(true)) && (parameter.empty())) + continue; + mode->OnModeChange(ServerInstance->FakeClient, ServerInstance->FakeClient, this, parameter, true); } } @@ -675,7 +673,6 @@ void Channel::WriteAllExcept(User* user, bool serversource, char status, CUList char tb[MAXBUF]; snprintf(tb,MAXBUF,":%s %s", serversource ? ServerInstance->Config->ServerName.c_str() : user->GetFullHost().c_str(), text.c_str()); - std::string out = tb; this->RawWriteAllExcept(user, serversource, status, except_list, std::string(tb)); } @@ -769,33 +766,39 @@ char* Channel::ChanModes(bool showkey) */ void Channel::UserList(User *user) { - char list[MAXBUF]; - size_t dlen, curlen; - if (!IS_LOCAL(user)) return; - if (this->IsModeSet('s') && !this->HasUser(user) && !user->HasPrivPermission("channels/auspex")) + bool has_privs = user->HasPrivPermission("channels/auspex"); + + if (this->IsModeSet('s') && !this->HasUser(user) && !has_privs) { user->WriteNumeric(ERR_NOSUCHNICK, "%s %s :No such nick/channel",user->nick.c_str(), this->name.c_str()); return; } - dlen = curlen = snprintf(list,MAXBUF,"%s %c %s :", user->nick.c_str(), this->IsModeSet('s') ? '@' : this->IsModeSet('p') ? '*' : '=', this->name.c_str()); + std::string list = user->nick; + list.push_back(' '); + list.push_back(this->IsModeSet('s') ? '@' : this->IsModeSet('p') ? '*' : '='); + list.push_back(' '); + list.append(this->name).append(" :"); + std::string::size_type pos = list.size(); - int numusers = 0; - char* ptr = list + dlen; + bool has_one = false; /* Improvement by Brain - this doesnt change in value, so why was it inside * the loop? */ bool has_user = this->HasUser(user); - for (UserMembIter i = userlist.begin(); i != userlist.end(); i++) + const size_t maxlen = MAXBUF - 10 - ServerInstance->Config->ServerName.size(); + std::string prefixlist; + std::string nick; + for (UserMembIter i = userlist.begin(); i != userlist.end(); ++i) { if (i->first->quitting) continue; - if ((!has_user) && (i->first->IsModeSet('i'))) + if ((!has_user) && (i->first->IsModeSet('i')) && (!has_privs)) { /* * user is +i, and source not on the channel, does not show @@ -804,8 +807,8 @@ void Channel::UserList(User *user) continue; } - std::string prefixlist = this->GetPrefixChar(i->first); - std::string nick = i->first->nick; + prefixlist = this->GetPrefixChar(i->first); + nick = i->first->nick; FOREACH_MOD(I_OnNamesListItem, OnNamesListItem(user, i->second, prefixlist, nick)); @@ -813,32 +816,25 @@ void Channel::UserList(User *user) if (nick.empty()) continue; - size_t ptrlen = 0; - - if (curlen + prefixlist.length() + nick.length() + 1 > 480) + if (list.size() + prefixlist.length() + nick.length() + 1 > maxlen) { /* list overflowed into multiple numerics */ - user->WriteNumeric(RPL_NAMREPLY, std::string(list)); + user->WriteNumeric(RPL_NAMREPLY, list); - /* reset our lengths */ - dlen = curlen = snprintf(list,MAXBUF,"%s %c %s :", user->nick.c_str(), this->IsModeSet('s') ? '@' : this->IsModeSet('p') ? '*' : '=', this->name.c_str()); - ptr = list + dlen; - - numusers = 0; + // Erase all nicks, keep the constant part + list.erase(pos); + has_one = false; } - ptrlen = snprintf(ptr, MAXBUF, "%s%s ", prefixlist.c_str(), nick.c_str()); - - curlen += ptrlen; - ptr += ptrlen; + list.append(prefixlist).append(nick).push_back(' '); - numusers++; + has_one = true; } /* if whats left in the list isnt empty, send it */ - if (numusers) + if (has_one) { - user->WriteNumeric(RPL_NAMREPLY, std::string(list)); + user->WriteNumeric(RPL_NAMREPLY, list); } user->WriteNumeric(RPL_ENDOFNAMES, "%s %s :End of /NAMES list.", user->nick.c_str(), this->name.c_str());