diff options
author | Attila Molnar <attilamolnar@hush.com> | 2015-05-16 16:49:37 +0200 |
---|---|---|
committer | Attila Molnar <attilamolnar@hush.com> | 2015-05-16 16:49:37 +0200 |
commit | 930fd98e48f68b050d3938607bf420844fabbc37 (patch) | |
tree | 196f7099593b0f5d1a50de6c2f76a5254621d447 /src | |
parent | 127fe6ed1076c294e01925e4fa8ab2bd64c1b0e0 (diff) |
Move Channel::UserList() from core to cmd_names
Diffstat (limited to 'src')
-rw-r--r-- | src/channels.cpp | 63 | ||||
-rw-r--r-- | src/coremods/core_channel/cmd_names.cpp | 66 | ||||
-rw-r--r-- | src/coremods/core_channel/core_channel.cpp | 4 | ||||
-rw-r--r-- | src/coremods/core_channel/core_channel.h | 9 |
4 files changed, 77 insertions, 65 deletions
diff --git a/src/channels.cpp b/src/channels.cpp index adfb32c3e..f79b5b89f 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -32,9 +32,6 @@ namespace ChanModeReference inviteonlymode(NULL, "inviteonly"); ChanModeReference keymode(NULL, "key"); ChanModeReference limitmode(NULL, "limit"); - ChanModeReference secretmode(NULL, "secret"); - ChanModeReference privatemode(NULL, "private"); - UserModeReference invisiblemode(NULL, "invisible"); } Channel::Channel(const std::string &cname, time_t ts) @@ -576,66 +573,6 @@ const char* Channel::ChanModes(bool showkey) return scratch.c_str(); } -/* compile a userlist of a channel into a string, each nick seperated by - * spaces and op, voice etc status shown as @ and +, and send it to 'user' - */ -void Channel::UserList(User* user, bool has_user) -{ - bool has_privs = user->HasPrivPermission("channels/auspex"); - std::string list; - list.push_back(this->IsModeSet(secretmode) ? '@' : this->IsModeSet(privatemode) ? '*' : '='); - list.push_back(' '); - list.append(this->name).append(" :"); - std::string::size_type pos = list.size(); - - const size_t maxlen = ServerInstance->Config->Limits.MaxLine - 10 - ServerInstance->Config->ServerName.size() - user->nick.size(); - std::string prefixlist; - std::string nick; - for (MemberMap::iterator i = userlist.begin(); i != userlist.end(); ++i) - { - if ((!has_user) && (i->first->IsModeSet(invisiblemode)) && (!has_privs)) - { - /* - * user is +i, and source not on the channel, does not show - * nick in NAMES list - */ - continue; - } - - Membership* memb = i->second; - - prefixlist.clear(); - char prefix = memb->GetPrefixChar(); - if (prefix) - prefixlist.push_back(prefix); - nick = i->first->nick; - - ModResult res; - FIRST_MOD_RESULT(OnNamesListItem, res, (user, memb, prefixlist, nick)); - - // See if a module wants us to exclude this user from NAMES - 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(' '); - } - - // 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.", this->name.c_str()); -} - /* returns the status character for a given user on a channel, e.g. @ for op, * % for halfop etc. If the user has several modes set, the highest mode * the user has must be returned. diff --git a/src/coremods/core_channel/cmd_names.cpp b/src/coremods/core_channel/cmd_names.cpp index 20faae774..9ae58d6fa 100644 --- a/src/coremods/core_channel/cmd_names.cpp +++ b/src/coremods/core_channel/cmd_names.cpp @@ -24,6 +24,8 @@ CommandNames::CommandNames(Module* parent) : Command(parent, "NAMES", 0, 0) , secretmode(parent, "secret") + , privatemode(parent, "private") + , invisiblemode(parent, "invisible") { syntax = "{<channel>{,<channel>}}"; } @@ -54,7 +56,7 @@ CmdResult CommandNames::Handle (const std::vector<std::string>& parameters, User bool has_user = c->HasUser(user); if ((!c->IsModeSet(secretmode)) || (has_user) || (user->HasPrivPermission("channels/auspex"))) { - c->UserList(user, has_user); + SendNames(user, c, has_user); return CMD_SUCCESS; } } @@ -62,3 +64,65 @@ CmdResult CommandNames::Handle (const std::vector<std::string>& parameters, User user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", parameters[0].c_str()); return CMD_FAILURE; } + +void CommandNames::SendNames(User* user, Channel* chan, bool isinside) +{ + bool has_privs = user->HasPrivPermission("channels/auspex"); + + std::string list; + if (chan->IsModeSet(secretmode)) + list.push_back('@'); + else if (chan->IsModeSet(privatemode)) + list.push_back('*'); + else + list.push_back('='); + + list.push_back(' '); + list.append(chan->name).append(" :"); + std::string::size_type pos = list.size(); + + 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)) + { + // Member is invisible and we are not supposed to show them + continue; + } + + Membership* const memb = i->second; + + prefixlist.clear(); + char prefix = memb->GetPrefixChar(); + if (prefix) + prefixlist.push_back(prefix); + nick = i->first->nick; + + ModResult res; + FIRST_MOD_RESULT(OnNamesListItem, res, (user, memb, prefixlist, nick)); + + // See if a module wants us to exclude this user from NAMES + 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(' '); + } + + // 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()); +} diff --git a/src/coremods/core_channel/core_channel.cpp b/src/coremods/core_channel/core_channel.cpp index ac590ebcc..99ad74d3d 100644 --- a/src/coremods/core_channel/core_channel.cpp +++ b/src/coremods/core_channel/core_channel.cpp @@ -42,7 +42,9 @@ class CoreModChannel : public Module { if (chan->topicset) Topic::ShowTopic(localuser, chan); - chan->UserList(localuser); + + // Show all members of the channel, including invisible (+i) users + cmdnames.SendNames(localuser, chan, true); } } diff --git a/src/coremods/core_channel/core_channel.h b/src/coremods/core_channel/core_channel.h index f3efa3d67..7e213b5a5 100644 --- a/src/coremods/core_channel/core_channel.h +++ b/src/coremods/core_channel/core_channel.h @@ -86,6 +86,8 @@ class CommandTopic : public SplitCommand class CommandNames : public Command { ChanModeReference secretmode; + ChanModeReference privatemode; + UserModeReference invisiblemode; public: /** Constructor for names. @@ -98,6 +100,13 @@ class CommandNames : public Command * @return A value from CmdResult to indicate command success or failure. */ CmdResult Handle(const std::vector<std::string>& parameters, User *user); + + /** Spool the NAMES list for a given channel to the given user + * @param user User to spool the NAMES list to + * @param chan Channel whose nicklist to send + * @param isinside If true, the user is inside the channel, if not then false + */ + void SendNames(User* user, Channel* chan, bool isinside); }; /** Handle /KICK. |