From d1f6da181795e1f030110ce778d1bece19d8d7a6 Mon Sep 17 00:00:00 2001 From: Kufat Date: Mon, 8 Jun 2026 04:36:18 -0400 Subject: [PATCH] Allow specifying the order of ns_set_misc entries. --- data/nickserv.example.conf | 3 +++ include/protocol.h | 2 +- modules/nickserv/ns_set_misc.cpp | 19 +++++++++++++++---- modules/protocol/inspircd.cpp | 4 ++-- modules/protocol/unrealircd.cpp | 4 ++-- 5 files changed, 23 insertions(+), 9 deletions(-) diff --git a/data/nickserv.example.conf b/data/nickserv.example.conf index 38988c1c7..211267b7e 100644 --- a/data/nickserv.example.conf +++ b/data/nickserv.example.conf @@ -747,6 +747,9 @@ command { service = "NickServ"; name = "SASET LAYOUT"; command = "nickserv/saset * * misc_description: A description of the command to show in the help. * misc_title: A human-readable description of the stored data. + * misc_priority: Positive integer representing display order in nickserv/info + * and (if enabled) WHOIS output. Entries with unspecified + * priority will be prioritized in the order of declaration. * misc_pattern: If defined then a regex pattern (using the engine specified * in to validate the data with). * misc_syntax: If defined then the syntax to show in the help output and, if diff --git a/include/protocol.h b/include/protocol.h index 57a696b74..82d97d30b 100644 --- a/include/protocol.h +++ b/include/protocol.h @@ -279,7 +279,7 @@ public: virtual void SendSVSHold(const Anope::string &, time_t) { } virtual void SendSVSHoldDel(const Anope::string &) { } - virtual void SendSWhois(const MessageSource &source, User *target, const Anope::string &tag, const Anope::string &message) { }; + virtual void SendSWhois(const MessageSource &source, User *target, const Anope::string &tag, time_t priority, const Anope::string &message) { }; virtual void SendSWhoisDel(const MessageSource &source, User *target, const Anope::string &tag, const Anope::string &message) { } /** Introduces a server to the uplink diff --git a/modules/nickserv/ns_set_misc.cpp b/modules/nickserv/ns_set_misc.cpp index 35bb83d0e..bc88904e6 100644 --- a/modules/nickserv/ns_set_misc.cpp +++ b/modules/nickserv/ns_set_misc.cpp @@ -26,14 +26,15 @@ struct CommandData final Anope::string pattern; Anope::string syntax; Anope::string title; + time_t priority = 0; bool swhois = false; }; static Anope::map command_data; - struct NSMiscData; static Anope::map *> items; +static std::vector *>> items_by_priority; static ExtensibleItem *GetItem(const Anope::string &name) { @@ -132,7 +133,7 @@ static void CheckSWhois(User* u, const Anope::string &name, ExtensibleItemAccount(); auto *data = nc ? ext->Get(nc) : nullptr; if (data) - IRCD->SendSWhois(nickserv, u, name, Anope::Format("%s: %s", GetTitle(ext), data->data.c_str())); + IRCD->SendSWhois(nickserv, u, name, it->second.priority, Anope::Format("%s: %s", GetTitle(ext), data->data.c_str())); else IRCD->SendSWhoisDel(nickserv, u, name, ""); } @@ -327,6 +328,8 @@ public: void OnReload(Configuration::Conf &conf) override { command_data.clear(); + items_by_priority.clear(); + for (int i = 0; i < conf.CountBlock("command"); ++i) { const auto &block = conf.GetBlock("command", i); @@ -341,7 +344,7 @@ public: // Force creation of the extension item. const auto extname = GetAttribute(cname); - GetItem(extname); + auto item = GetItem(extname); auto &data = command_data[extname]; if (cmd == "nickserv/saset/misc") @@ -354,8 +357,16 @@ public: data.pattern = block.Get("misc_pattern"); data.syntax = block.Get("misc_syntax"); data.title = block.Get("misc_title"); + data.priority = block.Get("misc_priority", "0"); + if (data.priority <= 0) + { + // If no priority is specified, go by order processed + data.priority = i * 1000; + } data.swhois = block.Get("misc_swhois"); + items_by_priority.emplace_back(data.priority, item); } + std::sort(items_by_priority.begin(), items_by_priority.end()); } void OnUserLogin(User *u) override @@ -374,7 +385,7 @@ public: void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool) override { - for (const auto &[_, e] : items) + for (const auto &[_, e] : items_by_priority) { NSMiscData *data = e->Get(na->nc); diff --git a/modules/protocol/inspircd.cpp b/modules/protocol/inspircd.cpp index 7e3079e39..7bde502fc 100644 --- a/modules/protocol/inspircd.cpp +++ b/modules/protocol/inspircd.cpp @@ -587,7 +587,7 @@ public: Uplink::Send(source, "SVSPART", u->GetUID(), chan); } - void SendSWhois(const MessageSource &source, User *target, const Anope::string &tag, const Anope::string &message) override + void SendSWhois(const MessageSource &source, User *target, const Anope::string &tag, time_t priority, const Anope::string &message) override { if (!IRCD->CanSendMultipleSWhois) { @@ -598,7 +598,7 @@ public: { // New style SWHOIS. Uplink::Send("METADATA", target->GetUID(), "specialwhois", Anope::Format("+ @%s s %ld :%s", - tag.c_str(), Anope::CurTime, message.c_str())); + tag.c_str(), priority ? priority : Anope::CurTime, message.c_str())); } } diff --git a/modules/protocol/unrealircd.cpp b/modules/protocol/unrealircd.cpp index 8da16d8e8..ce975db44 100644 --- a/modules/protocol/unrealircd.cpp +++ b/modules/protocol/unrealircd.cpp @@ -346,10 +346,10 @@ private: Uplink::Send("SENDUMODE", 'o', "From " + source.GetName() + ": " + buf); } - void SendSWhois(const MessageSource &source, User *target, const Anope::string &tag, const Anope::string &message) override + void SendSWhois(const MessageSource &source, User *target, const Anope::string &tag, time_t priority, const Anope::string &message) override { const auto utag = tag.empty() ? source.GetName() : tag; - Uplink::Send(source, "SWHOIS", target->GetUID(), "+", utag, 0, message); + Uplink::Send(source, "SWHOIS", target->GetUID(), "+", utag, priority, message); } void SendSWhoisDel(const MessageSource &source, User *target, const Anope::string &tag, const Anope::string &message) override