X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fcoremods%2Fcore_channel%2Fcmd_names.cpp;h=28273c90394ce80567eadd98b24af23bc1b2e4e0;hb=f2e3fd5952b23209b084bde4f464e6643c8a00ff;hp=9ae58d6fa0d1a6b981b765107e6f7d3f8ac446d8;hpb=930fd98e48f68b050d3938607bf420844fabbc37;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/coremods/core_channel/cmd_names.cpp b/src/coremods/core_channel/cmd_names.cpp index 9ae58d6fa..28273c903 100644 --- a/src/coremods/core_channel/cmd_names.cpp +++ b/src/coremods/core_channel/cmd_names.cpp @@ -22,7 +22,7 @@ #include "core_channel.h" CommandNames::CommandNames(Module* parent) - : Command(parent, "NAMES", 0, 0) + : SplitCommand(parent, "NAMES", 0, 0) , secretmode(parent, "secret") , privatemode(parent, "private") , invisiblemode(parent, "invisible") @@ -32,13 +32,13 @@ CommandNames::CommandNames(Module* parent) /** Handle /NAMES */ -CmdResult CommandNames::Handle (const std::vector& parameters, User *user) +CmdResult CommandNames::HandleLocal(LocalUser* user, const Params& parameters) { Channel* c; - if (!parameters.size()) + if (parameters.empty()) { - user->WriteNumeric(RPL_ENDOFNAMES, "* :End of /NAMES list."); + user->WriteNumeric(RPL_ENDOFNAMES, '*', "End of /NAMES list."); return CMD_SUCCESS; } @@ -53,41 +53,39 @@ CmdResult CommandNames::Handle (const std::vector& parameters, User // - the user doing the /NAMES is inside the channel // - the user doing the /NAMES has the channels/auspex privilege - bool has_user = c->HasUser(user); - if ((!c->IsModeSet(secretmode)) || (has_user) || (user->HasPrivPermission("channels/auspex"))) + // If the user is inside the channel or has privs, instruct SendNames() to show invisible (+i) members + bool show_invisible = ((c->HasUser(user)) || (user->HasPrivPermission("channels/auspex"))); + if ((show_invisible) || (!c->IsModeSet(secretmode))) { - SendNames(user, c, has_user); + SendNames(user, c, show_invisible); return CMD_SUCCESS; } } - user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", parameters[0].c_str()); + user->WriteNumeric(Numerics::NoSuchChannel(parameters[0])); return CMD_FAILURE; } -void CommandNames::SendNames(User* user, Channel* chan, bool isinside) +void CommandNames::SendNames(LocalUser* user, Channel* chan, bool show_invisible) { - bool has_privs = user->HasPrivPermission("channels/auspex"); - - std::string list; + Numeric::Builder<' '> reply(user, RPL_NAMREPLY, false, chan->name.size() + 3); + Numeric::Numeric& numeric = reply.GetNumeric(); if (chan->IsModeSet(secretmode)) - list.push_back('@'); + numeric.push(std::string(1, '@')); else if (chan->IsModeSet(privatemode)) - list.push_back('*'); + numeric.push(std::string(1, '*')); else - list.push_back('='); + numeric.push(std::string(1, '=')); - list.push_back(' '); - list.append(chan->name).append(" :"); - std::string::size_type pos = list.size(); + numeric.push(chan->name); + numeric.push(std::string()); - const size_t maxlen = ServerInstance->Config->Limits.MaxLine - 10 - ServerInstance->Config->ServerName.size() - user->nick.size(); std::string prefixlist; std::string nick; const Channel::MemberMap& members = chan->GetUsers(); for (Channel::MemberMap::const_iterator i = members.begin(); i != members.end(); ++i) { - if ((!isinside) && (i->first->IsModeSet(invisiblemode)) && (!has_privs)) + if ((!show_invisible) && (i->first->IsModeSet(invisiblemode))) { // Member is invisible and we are not supposed to show them continue; @@ -108,21 +106,9 @@ void CommandNames::SendNames(User* user, Channel* chan, bool isinside) if (res == MOD_RES_DENY) continue; - if (list.size() + prefixlist.length() + nick.length() + 1 > maxlen) - { - // List overflowed into multiple numerics - user->WriteNumeric(RPL_NAMREPLY, list); - - // Erase all nicks, keep the constant part - list.erase(pos); - } - - list.append(prefixlist).append(nick).push_back(' '); + reply.Add(prefixlist, nick); } - // Only send the user list numeric if there is at least one user in it - if (list.size() != pos) - user->WriteNumeric(RPL_NAMREPLY, list); - - user->WriteNumeric(RPL_ENDOFNAMES, "%s :End of /NAMES list.", chan->name.c_str()); + reply.Flush(); + user->WriteNumeric(RPL_ENDOFNAMES, chan->name, "End of /NAMES list."); }