summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAttila Molnar <attilamolnar@hush.com>2015-12-30 13:41:20 +0100
committerAttila Molnar <attilamolnar@hush.com>2015-12-30 13:41:20 +0100
commita956c5d10879f9286c9878ea2e35d5eb469f901f (patch)
treee5d2195999b34117d7097ce700c1efb48f463bb1
parent5d050846f7f3f152422e56e5c871302ee7a5a1ed (diff)
core_whois Switch to Numeric::Builder
-rw-r--r--src/coremods/core_whois.cpp128
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());