From 59bb9d3d061035b69e33e37f8f2168a9bd01d23a Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Fri, 19 Sep 2025 11:36:57 +0100 Subject: [PATCH] Rework the InfoFormatter/ListFormatter APIs and move to textproc. --- include/lists.h | 32 -------------------------------- include/textproc.h | 31 +++++++++++++++++++++++++++++++ modules/botserv/bs_badwords.cpp | 8 +------- modules/botserv/bs_botlist.cpp | 8 +------- modules/botserv/bs_info.cpp | 14 ++------------ modules/chanserv/cs_access.cpp | 20 +++----------------- modules/chanserv/cs_akick.cpp | 8 +------- modules/chanserv/cs_entrymsg.cpp | 6 +----- modules/chanserv/cs_flags.cpp | 6 +----- modules/chanserv/cs_info.cpp | 7 +------ modules/chanserv/cs_list.cpp | 7 +------ modules/chanserv/cs_log.cpp | 7 +------ modules/chanserv/cs_mode.cpp | 7 +------ modules/chanserv/cs_xop.cpp | 6 +----- modules/global/gl_queue.cpp | 6 +----- modules/hostserv/hs_list.cpp | 6 +----- modules/hostserv/hs_request.cpp | 7 +------ modules/memoserv/ms_ignore.cpp | 7 +------ modules/memoserv/ms_list.cpp | 6 +----- modules/nickserv/ns_ajoin.cpp | 7 +------ modules/nickserv/ns_alist.cpp | 8 +------- modules/nickserv/ns_group.cpp | 7 +------ modules/nickserv/ns_info.cpp | 7 +------ modules/nickserv/ns_list.cpp | 8 +------- modules/operserv/os_akill.cpp | 8 +------- modules/operserv/os_config.cpp | 17 ++--------------- modules/operserv/os_dns.cpp | 10 ++-------- modules/operserv/os_forbid.cpp | 7 +------ modules/operserv/os_ignore.cpp | 7 +------ modules/operserv/os_list.cpp | 14 ++------------ modules/operserv/os_news.cpp | 8 +------- modules/operserv/os_session.cpp | 15 ++------------- modules/operserv/os_sxline.cpp | 7 +------ src/misc.cpp | 15 +++++++-------- 34 files changed, 76 insertions(+), 268 deletions(-) diff --git a/include/lists.h b/include/lists.h index 7bba44907..de51fdffd 100644 --- a/include/lists.h +++ b/include/lists.h @@ -57,35 +57,3 @@ public: */ virtual bool InvalidRange(const Anope::string &list); }; - -/** This class handles formatting LIST/VIEW replies. - */ -class CoreExport ListFormatter final -{ -public: - typedef std::map ListEntry; -private: - NickCore *nc; - std::vector columns; - std::vector entries; -public: - ListFormatter(NickCore *nc); - ListFormatter &AddColumn(const Anope::string &name); - void AddEntry(const ListEntry &entry); - bool IsEmpty() const; - void Process(std::vector &); -}; - -/** This class handles formatting INFO replies - */ -class CoreExport InfoFormatter final -{ - NickCore *nc; - std::vector > replies; - unsigned longest = 0; -public: - InfoFormatter(NickCore *nc); - void Process(std::vector &); - Anope::string &operator[](const Anope::string &key); - void AddOption(const Anope::string &opt); -}; diff --git a/include/textproc.h b/include/textproc.h index c5febf225..ec321d6a7 100644 --- a/include/textproc.h +++ b/include/textproc.h @@ -109,6 +109,20 @@ public: void SendTo(CommandSource &source); }; +class CoreExport InfoFormatter final +{ +private: + size_t longest = 0; + NickCore *nc; + std::vector > replies; + +public: + InfoFormatter(NickCore *nc); + Anope::string &operator[](const Anope::string &key); + void AddOption(const Anope::string &opt); + void SendTo(CommandSource &source); +}; + class CoreExport LineWrapper final { private: @@ -121,3 +135,20 @@ public: bool GetLine(Anope::string &out); }; +class CoreExport ListFormatter final +{ +public: + using ListEntry = std::map; + +private: + std::vector columns; + std::vector entries; + NickCore *nc; + +public: + ListFormatter(NickCore *nc); + ListFormatter &AddColumn(const Anope::string &name); + void AddEntry(const ListEntry &entry); + bool IsEmpty() const; + void SendTo(CommandSource &source); +}; diff --git a/modules/botserv/bs_badwords.cpp b/modules/botserv/bs_badwords.cpp index 15e97a246..f1b5a2ba3 100644 --- a/modules/botserv/bs_badwords.cpp +++ b/modules/botserv/bs_badwords.cpp @@ -305,14 +305,8 @@ private: source.Reply(_("No matching entries on %s bad words list."), ci->name.c_str()); else { - std::vector replies; - list.Process(replies); - source.Reply(_("Bad words list for %s:"), ci->name.c_str()); - - for (const auto &reply : replies) - source.Reply(reply); - + list.SendTo(source); source.Reply(_("End of bad words list.")); } } diff --git a/modules/botserv/bs_botlist.cpp b/modules/botserv/bs_botlist.cpp index c49d5bc26..fa17e6c01 100644 --- a/modules/botserv/bs_botlist.cpp +++ b/modules/botserv/bs_botlist.cpp @@ -66,9 +66,6 @@ public: } } - std::vector replies; - list.Process(replies); - if (!count) { source.Reply(_( @@ -79,10 +76,7 @@ public: else { source.Reply(_("Bot list:")); - - for (const auto &reply : replies) - source.Reply(reply); - + list.SendTo(source); source.Reply(_("%d bots available."), count); } } diff --git a/modules/botserv/bs_info.cpp b/modules/botserv/bs_info.cpp index 490529b94..69c664ab0 100644 --- a/modules/botserv/bs_info.cpp +++ b/modules/botserv/bs_info.cpp @@ -58,12 +58,7 @@ public: info[_("Used on")] = Anope::Format(Language::Translate(source.nc, bi->GetChannelCount(), N_("%u channel", "%u channels")), bi->GetChannelCount()); FOREACH_MOD(OnBotInfo, (source, bi, ci, info)); - - std::vector replies; - info.Process(replies); - - for (const auto &reply : replies) - source.Reply(reply); + info.SendTo(source); if (source.HasPriv("botserv/administration")) { @@ -89,12 +84,7 @@ public: Anope::string disabled = Language::Translate(source.nc, _("Disabled")); FOREACH_MOD(OnBotInfo, (source, bi, ci, info)); - - std::vector replies; - info.Process(replies); - - for (const auto &reply : replies) - source.Reply(reply); + info.SendTo(source); } else source.Reply(_("\002%s\002 is not a valid bot or registered channel."), query.c_str()); diff --git a/modules/chanserv/cs_access.cpp b/modules/chanserv/cs_access.cpp index 85e2d85d5..e1881212b 100644 --- a/modules/chanserv/cs_access.cpp +++ b/modules/chanserv/cs_access.cpp @@ -435,14 +435,8 @@ private: source.Reply(_("No matching entries on %s access list."), ci->name.c_str()); else { - std::vector replies; - list.Process(replies); - source.Reply(_("Access list for %s:"), ci->name.c_str()); - - for (const auto &reply : replies) - source.Reply(reply); - + list.SendTo(source); source.Reply(_("End of access list")); } @@ -744,11 +738,7 @@ class CommandCSLevels final list.AddEntry(entry); } - std::vector replies; - list.Process(replies); - - for (const auto &reply : replies) - source.Reply(reply); + list.SendTo(source); } void DoReset(CommandSource &source, ChannelInfo *ci) @@ -834,11 +824,7 @@ public: list.AddEntry(entry); } - std::vector replies; - list.Process(replies); - - for (const auto &reply : replies) - source.Reply(reply); + list.SendTo(source); } else { diff --git a/modules/chanserv/cs_akick.cpp b/modules/chanserv/cs_akick.cpp index a7a71ef3c..e5c7ba631 100644 --- a/modules/chanserv/cs_akick.cpp +++ b/modules/chanserv/cs_akick.cpp @@ -378,14 +378,8 @@ class CommandCSAKick final source.Reply(_("No matching entries on %s autokick list."), ci->name.c_str()); else { - std::vector replies; - list.Process(replies); - source.Reply(_("Autokick list for %s:"), ci->name.c_str()); - - for (const auto &reply : replies) - source.Reply(reply); - + list.SendTo(source); source.Reply(_("End of autokick list")); } } diff --git a/modules/chanserv/cs_entrymsg.cpp b/modules/chanserv/cs_entrymsg.cpp index db247a05f..6c8bbae10 100644 --- a/modules/chanserv/cs_entrymsg.cpp +++ b/modules/chanserv/cs_entrymsg.cpp @@ -140,11 +140,7 @@ private: list.AddEntry(entry); } - std::vector replies; - list.Process(replies); - for (const auto &reply : replies) - source.Reply(reply); - + list.SendTo(source); source.Reply(_("End of entry message list.")); } diff --git a/modules/chanserv/cs_flags.cpp b/modules/chanserv/cs_flags.cpp index 080e8498c..337e6e463 100644 --- a/modules/chanserv/cs_flags.cpp +++ b/modules/chanserv/cs_flags.cpp @@ -348,12 +348,8 @@ class CommandCSFlags final source.Reply(_("No matching entries on %s access list."), ci->name.c_str()); else { - std::vector replies; - list.Process(replies); - source.Reply(_("Flags list for %s"), ci->name.c_str()); - for (const auto &reply : replies) - source.Reply(reply); + list.SendTo(source); if (count == ci->GetAccessCount()) source.Reply(_("End of access list.")); else diff --git a/modules/chanserv/cs_info.cpp b/modules/chanserv/cs_info.cpp index 619a0721c..a1961acf5 100644 --- a/modules/chanserv/cs_info.cpp +++ b/modules/chanserv/cs_info.cpp @@ -62,12 +62,7 @@ public: } FOREACH_MOD(OnChanInfo, (source, ci, info, show_all)); - - std::vector replies; - info.Process(replies); - - for (const auto &reply : replies) - source.Reply(reply); + info.SendTo(source); } bool OnHelp(CommandSource &source, const Anope::string &subcommand) override diff --git a/modules/chanserv/cs_list.cpp b/modules/chanserv/cs_list.cpp index 408d4c9a8..3d1404a01 100644 --- a/modules/chanserv/cs_list.cpp +++ b/modules/chanserv/cs_list.cpp @@ -122,12 +122,7 @@ public: } } - std::vector replies; - list.Process(replies); - - for (const auto &reply : replies) - source.Reply(reply); - + list.SendTo(source); source.Reply(_("End of list - %d/%d matches shown."), nchans > listmax ? listmax : nchans, nchans); } diff --git a/modules/chanserv/cs_log.cpp b/modules/chanserv/cs_log.cpp index 797c1df35..3c13fcfb9 100644 --- a/modules/chanserv/cs_log.cpp +++ b/modules/chanserv/cs_log.cpp @@ -154,12 +154,7 @@ public: } source.Reply(_("Log list for %s:"), ci->name.c_str()); - - std::vector replies; - list.Process(replies); - - for (const auto &reply : replies) - source.Reply(reply); + list.SendTo(source); } } else if (params.size() > 2) diff --git a/modules/chanserv/cs_mode.cpp b/modules/chanserv/cs_mode.cpp index 4ba9439ec..96adfa7fd 100644 --- a/modules/chanserv/cs_mode.cpp +++ b/modules/chanserv/cs_mode.cpp @@ -466,12 +466,7 @@ class CommandCSMode final } source.Reply(_("Mode locks for %s:"), ci->name.c_str()); - - std::vector replies; - list.Process(replies); - - for (const auto &reply : replies) - source.Reply(reply); + list.SendTo(source); } } else diff --git a/modules/chanserv/cs_xop.cpp b/modules/chanserv/cs_xop.cpp index 9328ebef0..5f5b8fe03 100644 --- a/modules/chanserv/cs_xop.cpp +++ b/modules/chanserv/cs_xop.cpp @@ -453,12 +453,8 @@ private: source.Reply(_("No matching entries on %s access list."), ci->name.c_str()); else { - std::vector replies; - list.Process(replies); - source.Reply(_("%s list for %s"), source.command.nobreak().c_str(), ci->name.c_str()); - for (const auto &reply : replies) - source.Reply(reply); + list.SendTo(source); } } diff --git a/modules/global/gl_queue.cpp b/modules/global/gl_queue.cpp index 6ad164b30..90cb2579d 100644 --- a/modules/global/gl_queue.cpp +++ b/modules/global/gl_queue.cpp @@ -121,11 +121,7 @@ private: entry["Message"] = (*q)[i]; list.AddEntry(entry); } - - std::vector replies; - list.Process(replies); - for (const auto &reply : replies) - source.Reply(reply); + list.SendTo(source); } public: diff --git a/modules/hostserv/hs_list.cpp b/modules/hostserv/hs_list.cpp index 3ff6fe39d..025f0d951 100644 --- a/modules/hostserv/hs_list.cpp +++ b/modules/hostserv/hs_list.cpp @@ -112,11 +112,7 @@ public: source.Reply(_("Displayed all records (count: \002%d\002)."), display_counter); } - std::vector replies; - list.Process(replies); - - for (const auto &reply : replies) - source.Reply(reply); + list.SendTo(source); } bool OnHelp(CommandSource &source, const Anope::string &subcommand) override diff --git a/modules/hostserv/hs_request.cpp b/modules/hostserv/hs_request.cpp index dfb569e99..39e58b3bb 100644 --- a/modules/hostserv/hs_request.cpp +++ b/modules/hostserv/hs_request.cpp @@ -468,12 +468,7 @@ public: ++counter; } - std::vector replies; - list.Process(replies); - - for (const auto &reply : replies) - source.Reply(reply); - + list.SendTo(source); source.Reply(_("Displayed \002%d\002 records (\002%d\002 total)."), display_counter, counter); } diff --git a/modules/memoserv/ms_ignore.cpp b/modules/memoserv/ms_ignore.cpp index 022a95bc4..056c2571a 100644 --- a/modules/memoserv/ms_ignore.cpp +++ b/modules/memoserv/ms_ignore.cpp @@ -85,12 +85,7 @@ public: } source.Reply(_("Memo ignore list:")); - - std::vector replies; - list.Process(replies); - - for (const auto &reply : replies) - source.Reply(reply); + list.SendTo(source); } } else diff --git a/modules/memoserv/ms_list.cpp b/modules/memoserv/ms_list.cpp index 2570894ef..5d867e1b6 100644 --- a/modules/memoserv/ms_list.cpp +++ b/modules/memoserv/ms_list.cpp @@ -127,12 +127,8 @@ public: } } - std::vector replies; - list.Process(replies); - source.Reply(_("Memos for %s:"), ci ? ci->name.c_str() : source.GetNick().c_str()); - for (const auto &reply : replies) - source.Reply(reply); + list.SendTo(source); } return; } diff --git a/modules/nickserv/ns_ajoin.cpp b/modules/nickserv/ns_ajoin.cpp index 13e59d261..cbe5cbba0 100644 --- a/modules/nickserv/ns_ajoin.cpp +++ b/modules/nickserv/ns_ajoin.cpp @@ -124,12 +124,7 @@ class CommandNSAJoin final } source.Reply(_("%s's auto join list:"), nc->display.c_str()); - - std::vector replies; - list.Process(replies); - - for (const auto &reply : replies) - source.Reply(reply); + list.SendTo(source); } } diff --git a/modules/nickserv/ns_alist.cpp b/modules/nickserv/ns_alist.cpp index 359ac903f..f62348721 100644 --- a/modules/nickserv/ns_alist.cpp +++ b/modules/nickserv/ns_alist.cpp @@ -87,9 +87,6 @@ public: list.AddEntry(entry); } - std::vector replies; - list.Process(replies); - if (!chan_count) { source.Reply(_("\002%s\002 has no access in any channels."), nc->display.c_str()); @@ -97,10 +94,7 @@ public: else { source.Reply(_("Channels that \002%s\002 has access on:"), nc->display.c_str()); - - for (const auto &reply : replies) - source.Reply(reply); - + list.SendTo(source); source.Reply(_("End of list - %d channels shown."), chan_count); } } diff --git a/modules/nickserv/ns_group.cpp b/modules/nickserv/ns_group.cpp index 3572574b9..d9fcba709 100644 --- a/modules/nickserv/ns_group.cpp +++ b/modules/nickserv/ns_group.cpp @@ -354,12 +354,7 @@ public: } source.Reply(!nick.empty() ? _("List of nicknames belonging to \002%s\002:") : _("List of nicknames belonging to your account:"), nc->display.c_str()); - std::vector replies; - list.Process(replies); - - for (const auto &reply : replies) - source.Reply(reply); - + list.SendTo(source); source.Reply(nc->aliases->size(), N_("%zu nickname in the account.", "%zu nicknames in the account."), nc->aliases->size()); } diff --git a/modules/nickserv/ns_info.cpp b/modules/nickserv/ns_info.cpp index b647c9c74..858c989ab 100644 --- a/modules/nickserv/ns_info.cpp +++ b/modules/nickserv/ns_info.cpp @@ -136,12 +136,7 @@ public: } FOREACH_MOD(OnNickInfo, (source, na, info, show_hidden)); - - std::vector replies; - info.Process(replies); - - for (const auto &reply : replies) - source.Reply(reply); + info.SendTo(source); } } diff --git a/modules/nickserv/ns_list.cpp b/modules/nickserv/ns_list.cpp index fe4498506..50fd18fb5 100644 --- a/modules/nickserv/ns_list.cpp +++ b/modules/nickserv/ns_list.cpp @@ -120,13 +120,7 @@ public: } source.Reply(_("List of entries matching \002%s\002:"), pattern.c_str()); - - std::vector replies; - list.Process(replies); - - for (const auto &reply : replies) - source.Reply(reply); - + list.SendTo(source); source.Reply(_("End of list - %d/%d matches shown."), nnicks > listmax ? listmax : nnicks, nnicks); return; } diff --git a/modules/operserv/os_akill.cpp b/modules/operserv/os_akill.cpp index bbdb23763..a70b03cbe 100644 --- a/modules/operserv/os_akill.cpp +++ b/modules/operserv/os_akill.cpp @@ -337,13 +337,7 @@ private: else { source.Reply(_("Current AKILL list:")); - - std::vector replies; - list.Process(replies); - - for (const auto &reply : replies) - source.Reply(reply); - + list.SendTo(source); source.Reply(_("End of AKILL list.")); } } diff --git a/modules/operserv/os_config.cpp b/modules/operserv/os_config.cpp index 5417421b6..827df6c32 100644 --- a/modules/operserv/os_config.cpp +++ b/modules/operserv/os_config.cpp @@ -71,14 +71,8 @@ public: lflist.AddEntry(entry); } - std::vector replies; - lflist.Process(replies); - source.Reply(_("%s settings:"), block.GetName().c_str()); - - for (const auto &reply : replies) - source.Reply(reply); - + lflist.SendTo(source); source.Reply(" "); } @@ -103,15 +97,8 @@ public: lflist.AddEntry(entry); } } - - std::vector replies; - lflist.Process(replies); - source.Reply(_("Module settings:")); - - for (const auto &reply : replies) - source.Reply(reply); - + lflist.SendTo(source); source.Reply(_("End of configuration.")); } else diff --git a/modules/operserv/os_dns.cpp b/modules/operserv/os_dns.cpp index 6c7c8f5bc..f69da370b 100644 --- a/modules/operserv/os_dns.cpp +++ b/modules/operserv/os_dns.cpp @@ -269,9 +269,7 @@ class CommandOSDNS final lf.AddEntry(entry); } - - std::vector replies; - lf.Process(replies); + lf.SendTo(source); if (!zones->empty()) { @@ -295,12 +293,8 @@ class CommandOSDNS final lf2.AddEntry(entry); } - - lf2.Process(replies); + lf2.SendTo(source); } - - for (const auto &reply : replies) - source.Reply(reply); } void AddZone(CommandSource &source, const std::vector ¶ms) diff --git a/modules/operserv/os_forbid.cpp b/modules/operserv/os_forbid.cpp index 6c0ca84fb..6f8c6576e 100644 --- a/modules/operserv/os_forbid.cpp +++ b/modules/operserv/os_forbid.cpp @@ -430,12 +430,7 @@ public: else { source.Reply(_("Forbid list:")); - - std::vector replies; - list.Process(replies); - - for (const auto &reply : replies) - source.Reply(reply); + list.SendTo(source); if (shown >= forbids.size()) source.Reply(_("End of forbid list.")); diff --git a/modules/operserv/os_ignore.cpp b/modules/operserv/os_ignore.cpp index 384a62640..caae71c6b 100644 --- a/modules/operserv/os_ignore.cpp +++ b/modules/operserv/os_ignore.cpp @@ -292,12 +292,7 @@ private: } source.Reply(_("Services ignore list:")); - - std::vector replies; - list.Process(replies); - - for (const auto &reply : replies) - source.Reply(reply); + list.SendTo(source); } } diff --git a/modules/operserv/os_list.cpp b/modules/operserv/os_list.cpp index 83069ec2e..60cb9fbad 100644 --- a/modules/operserv/os_list.cpp +++ b/modules/operserv/os_list.cpp @@ -96,12 +96,7 @@ public: } } - std::vector replies; - list.Process(replies); - - for (const auto &reply : replies) - source.Reply(reply); - + list.SendTo(source); source.Reply(_("End of channel list. \002%u\002 channels shown."), count); } @@ -243,12 +238,7 @@ public: } } - std::vector replies; - list.Process(replies); - - for (const auto &reply : replies) - source.Reply(reply); - + list.SendTo(source); source.Reply(_("End of users list. \002%u\002 users shown."), count); return; } diff --git a/modules/operserv/os_news.cpp b/modules/operserv/os_news.cpp index b9283ff40..859ebd7d6 100644 --- a/modules/operserv/os_news.cpp +++ b/modules/operserv/os_news.cpp @@ -217,13 +217,7 @@ protected: } source.Reply(msgs[MSG_LIST_HEADER]); - - std::vector replies; - lflist.Process(replies); - - for (const auto &reply : replies) - source.Reply(reply); - + lflist.SendTo(source); source.Reply(_("End of news list.")); } diff --git a/modules/operserv/os_session.cpp b/modules/operserv/os_session.cpp index 0b8bf32bd..c4cb98485 100644 --- a/modules/operserv/os_session.cpp +++ b/modules/operserv/os_session.cpp @@ -249,13 +249,7 @@ private: } source.Reply(_("Hosts with at least \002%d\002 sessions:"), mincount); - - std::vector replies; - list.Process(replies); - - - for (const auto &reply : replies) - source.Reply(reply); + list.SendTo(source); } return; @@ -534,12 +528,7 @@ private: else { source.Reply(_("Current Session Limit Exception list:")); - - std::vector replies; - list.Process(replies); - - for (const auto &reply : replies) - source.Reply(reply); + list.SendTo(source); } } diff --git a/modules/operserv/os_sxline.cpp b/modules/operserv/os_sxline.cpp index cb475d98a..d6ceac347 100644 --- a/modules/operserv/os_sxline.cpp +++ b/modules/operserv/os_sxline.cpp @@ -191,12 +191,7 @@ private: else { source.Reply(_("Current %s list:"), source.command.nobreak().c_str()); - - std::vector replies; - list.Process(replies); - - for (const auto &reply : replies) - source.Reply(reply); + list.SendTo(source); } } diff --git a/src/misc.cpp b/src/misc.cpp index 444e6ed1d..8398fffca 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -141,7 +141,7 @@ bool ListFormatter::IsEmpty() const return this->entries.empty(); } -void ListFormatter::Process(std::vector &buffer) +void ListFormatter::SendTo(CommandSource &source) { std::vector tcolumns; std::map lengths; @@ -181,7 +181,7 @@ void ListFormatter::Process(std::vector &buffer) { if (breaks.count(this->columns[i])) { - buffer.push_back(s); + source.Reply(s); s = " "; } else if (!s.empty()) @@ -191,7 +191,7 @@ void ListFormatter::Process(std::vector &buffer) for (unsigned j = tcolumns[i].length(); j < lengths[this->columns[i]]; ++j) s += " "; } - buffer.push_back(s); + source.Reply(s); } for (auto &entry : this->entries) @@ -201,7 +201,7 @@ void ListFormatter::Process(std::vector &buffer) { if (breaks.count(this->columns[j])) { - buffer.push_back(s); + source.Reply(s); s = " "; } else if (!s.empty()) @@ -211,7 +211,7 @@ void ListFormatter::Process(std::vector &buffer) for (unsigned k = entry[this->columns[j]].length(); k < lengths[this->columns[j]]; ++k) s += " "; } - buffer.push_back(s); + source.Reply(s); } } @@ -219,16 +219,15 @@ InfoFormatter::InfoFormatter(NickCore *acc) : nc(acc) { } -void InfoFormatter::Process(std::vector &buffer) +void InfoFormatter::SendTo(CommandSource &source) { - buffer.clear(); for (const auto &[key, value] : this->replies) { auto line = key; line += ": "; line += Anope::string(longest - key.utf8length(), ' '); line += Language::Translate(this->nc, value.c_str()); - buffer.push_back(line); + source.Reply(line); } }