diff options
author | Attila Molnar <attilamolnar@hush.com> | 2015-12-30 13:41:20 +0100 |
---|---|---|
committer | Attila Molnar <attilamolnar@hush.com> | 2015-12-30 13:41:20 +0100 |
commit | a956c5d10879f9286c9878ea2e35d5eb469f901f (patch) | |
tree | e5d2195999b34117d7097ce700c1efb48f463bb1 | |
parent | 5d050846f7f3f152422e56e5c871302ee7a5a1ed (diff) |
core_whois Switch to Numeric::Builder
-rw-r--r-- | src/coremods/core_whois.cpp | 128 |
1 files changed, 75 insertions, 53 deletions
diff --git a/src/coremods/core_whois.cpp b/src/coremods/core_whois.cpp index 1cd622092..703ebbed3 100644 --- a/src/coremods/core_whois.cpp +++ b/src/coremods/core_whois.cpp @@ -59,9 +59,8 @@ class CommandWhois : public SplitCommand Events::ModuleEventProvider evprov; Events::ModuleEventProvider lineevprov; - void SplitChanList(WhoisContextImpl& whois, const std::string& cl); void DoWhois(LocalUser* user, User* dest, unsigned long signon, unsigned long idle); - std::string ChannelList(User* source, User* dest, bool spy); + void SendChanList(WhoisContextImpl& whois); public: /** Constructor for whois. @@ -87,56 +86,94 @@ class CommandWhois : public SplitCommand CmdResult HandleRemote(const std::vector<std::string>& parameters, RemoteUser* target); }; -std::string CommandWhois::ChannelList(User* source, User* dest, bool spy) +class WhoisNumericSink { - std::string list; + WhoisContextImpl& whois; + public: + WhoisNumericSink(WhoisContextImpl& whoisref) + : whois(whoisref) + { + } - for (User::ChanList::iterator i = dest->chans.begin(); i != dest->chans.end(); i++) + void operator()(unsigned int numeric, const std::string& text) const { - Membership* memb = *i; - Channel* c = memb->chan; - /* If the target is the sender, neither +p nor +s is set, or - * the channel contains the user, it is not a spy channel - */ - if (spy != (source == dest || !(c->IsModeSet(privatemode) || c->IsModeSet(secretmode)) || c->HasUser(source))) - { - char prefix = memb->GetPrefixChar(); - if (prefix) - list.push_back(prefix); - list.append(c->name).push_back(' '); - } + whois.SendLine(numeric, text); } +}; - return list; -} +class WhoisChanListNumericBuilder : public Numeric::GenericBuilder<' ', false, WhoisNumericSink> +{ + public: + WhoisChanListNumericBuilder(WhoisContextImpl& whois) + : GenericBuilder<' ', false, WhoisNumericSink>(WhoisNumericSink(whois), 319, true, whois.GetSource()->nick.size() + whois.GetTarget()->nick.size() + 1) + { + } +}; -void CommandWhois::SplitChanList(WhoisContextImpl& whois, const std::string& cl) +class WhoisChanList { - std::string line(1, ':'); - std::string::size_type start, pos; + const ServerConfig::OperSpyWhoisState spywhois; + WhoisChanListNumericBuilder num; + WhoisChanListNumericBuilder spynum; + std::string prefixstr; - // ":server.name 319 source target " ... "\r\n" - const std::string::size_type maxlen = ServerInstance->Config->Limits.MaxLine - 10 - ServerInstance->Config->ServerName.length() - whois.GetTarget()->nick.length() - whois.GetSource()->nick.length(); + void AddMember(Membership* memb, WhoisChanListNumericBuilder& out) + { + prefixstr.clear(); + const char prefix = memb->GetPrefixChar(); + if (prefix) + prefixstr.push_back(prefix); + out.Add(prefixstr, memb->chan->name); + } - for (start = 0; (pos = cl.find(' ', start)) != std::string::npos; start = pos+1) + public: + WhoisChanList(WhoisContextImpl& whois) + : spywhois(whois.GetSource()->HasPrivPermission("users/auspex") ? ServerInstance->Config->OperSpyWhois : ServerConfig::SPYWHOIS_NONE) + , num(whois) + , spynum(whois) { - if (line.length() + pos - start > maxlen) - { - // Erase last ' ' and send - line.erase(line.length()-1); - whois.SendLine(319, line); - line.erase(1); - } + } + + void AddVisible(Membership* memb) + { + AddMember(memb, num); + } + + void AddHidden(Membership* memb) + { + if (spywhois == ServerConfig::SPYWHOIS_NONE) + return; + AddMember(memb, (spywhois == ServerConfig::SPYWHOIS_SPLITMSG ? spynum : num)); + } - line.append(cl, start, pos - start + 1); + void Flush(WhoisContextImpl& whois) + { + num.Flush(); + if (!spynum.IsEmpty()) + whois.SendLine(336, ":is on private/secret channels:"); + spynum.Flush(); } +}; + +void CommandWhois::SendChanList(WhoisContextImpl& whois) +{ + WhoisChanList chanlist(whois); - if (line.length() > 1) + User* const target = whois.GetTarget(); + for (User::ChanList::iterator i = target->chans.begin(); i != target->chans.end(); ++i) { - // Erase last ' ' and send - line.erase(line.length()-1); - whois.SendLine(319, line); + Membership* memb = *i; + Channel* c = memb->chan; + /* If the target is the sender, neither +p nor +s is set, or + * the channel contains the user, it is not a spy channel + */ + if ((whois.IsSelfWhois()) || ((!c->IsModeSet(privatemode)) && (!c->IsModeSet(secretmode))) || (c->HasUser(whois.GetSource()))) + chanlist.AddVisible(memb); + else + chanlist.AddHidden(memb); } + + chanlist.Flush(whois); } void CommandWhois::DoWhois(LocalUser* user, User* dest, unsigned long signon, unsigned long idle) @@ -149,23 +186,8 @@ void CommandWhois::DoWhois(LocalUser* user, User* dest, unsigned long signon, un whois.SendLine(378, ":is connecting from %s@%s %s", dest->ident.c_str(), dest->host.c_str(), dest->GetIPString().c_str()); } - std::string cl = ChannelList(user, dest, false); - const ServerConfig::OperSpyWhoisState state = user->HasPrivPermission("users/auspex") ? ServerInstance->Config->OperSpyWhois : ServerConfig::SPYWHOIS_NONE; - - if (state == ServerConfig::SPYWHOIS_SINGLEMSG) - cl.append(ChannelList(user, dest, true)); + SendChanList(whois); - SplitChanList(whois, cl); - - if (state == ServerConfig::SPYWHOIS_SPLITMSG) - { - std::string scl = ChannelList(user, dest, true); - if (scl.length()) - { - whois.SendLine(336, ":is on private/secret channels:"); - SplitChanList(whois, scl); - } - } if (!whois.IsSelfWhois() && !ServerInstance->Config->HideWhoisServer.empty() && !user->HasPrivPermission("servers/auspex")) { whois.SendLine(312, "%s :%s", ServerInstance->Config->HideWhoisServer.c_str(), ServerInstance->Config->Network.c_str()); |