diff --git a/include/protocol.h b/include/protocol.h index eac0b1964..07da69275 100644 --- a/include/protocol.h +++ b/include/protocol.h @@ -80,6 +80,9 @@ public: /** Can we force servers to remove opers? */ bool CanSVSNOOP = false; + /** Can we send multiple swhois messages? */ + bool CanSendMultipleSWhois = false; + /* Can we set vhosts on users? */ bool CanSetVHost = false; @@ -276,7 +279,8 @@ public: virtual void SendSVSHold(const Anope::string &, time_t) { } virtual void SendSVSHoldDel(const Anope::string &) { } - virtual void SendSWhois(const MessageSource &, const Anope::string &, const Anope::string &) { } + virtual void SendSWhois(const MessageSource &source, User *target, const Anope::string &tag, 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/protocol/inspircd.cpp b/modules/protocol/inspircd.cpp index 6f620b51a..3455d9486 100644 --- a/modules/protocol/inspircd.cpp +++ b/modules/protocol/inspircd.cpp @@ -587,10 +587,36 @@ public: Uplink::Send(source, "SVSPART", u->GetUID(), chan); } - void SendSWhois(const MessageSource &bi, const Anope::string &who, const Anope::string &mask) override + void SendSWhois(const MessageSource &source, User *target, const Anope::string &tag, const Anope::string &message) override { - User *u = User::Find(who); - Uplink::Send("METADATA", u->GetUID(), "swhois", mask); + if (!IRCD->CanSendMultipleSWhois) + { + // Old style SWHOIS. + Uplink::Send("METADATA", target->GetUID(), "swhois", message); + } + else + { + // New style SWHOIS. + Uplink::Send("METADATA", target->GetUID(), "specialwhois", Anope::Format("+ @%s s %ld :%s", + tag.c_str(), Anope::CurTime, message.c_str())); + } + } + + void SendSWhoisDel(const MessageSource &source, User *target, const Anope::string &tag, const Anope::string &message) override + { + if (!IRCD->CanSendMultipleSWhois) + { + // Old style SWHOIS. + Uplink::Send("METADATA", target->GetUID(), "swhois", ""); + } + else + { + // New style SWHOIS. + if (tag.empty()) + Uplink::Send("METADATA", target->GetUID(), "specialwhois", Anope::Format("- :%s", message.c_str())); + else + Uplink::Send("METADATA", target->GetUID(), "specialwhois", Anope::Format("- @%s", tag.c_str())); + } } void SendBOB() override @@ -1492,6 +1518,9 @@ struct IRCDMessageCapab final else if (modname.equals_cs("services")) Servers::Capab.insert("SERVICES"); + + else if (modname.equals_cs("swhois_ext")) + IRCD->CanSendMultipleSWhois = true; } const auto &anoperegex = Config->GetBlock("options").Get("regexengine"); @@ -1879,6 +1908,9 @@ private: else if (modname.equals_cs("services")) required = true; + else if (modname.equals_cs("swhois_ext")) + IRCD->CanSendMultipleSWhois = plus; + else return; diff --git a/modules/protocol/unrealircd.cpp b/modules/protocol/unrealircd.cpp index 5de685feb..2629823ed 100644 --- a/modules/protocol/unrealircd.cpp +++ b/modules/protocol/unrealircd.cpp @@ -55,6 +55,7 @@ public: CanSVSNick = true; CanSVSJoin = true; CanSVSNOOP = true; + CanSendMultipleSWhois = true; CanSetVHost = true; CanSetVIdent = true; CanSNLine = true; @@ -246,13 +247,14 @@ private: // BIGLINES: enable sending lines up to 16384 characters in length. // EAUTH: communicates information about the local server. + // EXTSWHOIS: enable receiving extended SWHOIS messages. // MLOCK: enable receiving the MLOCK message when a mode lock changes. // MTAGS: enable receiving IRCv3 message tags. // NEXTBANS: enables receiving named extended bans. // SJSBY: enables receiving list mode setters and set timestamps. // SID: communicates the unique identifier of the local server. // VHP: enable receiving the vhost in UID. - Uplink::Send("PROTOCTL", "BIGLINES", "MLOCK", "MTAGS", "NEXTBANS", "SJSBY", "VHP"); + Uplink::Send("PROTOCTL", "BIGLINES", "EXTSWHOIS", "MLOCK", "MTAGS", "NEXTBANS", "SJSBY", "VHP"); Uplink::Send("PROTOCTL", "EAUTH=" + Me->GetName() + ",,,Anope-" + Anope::VersionShort()); Uplink::Send("PROTOCTL", "SID=" + Me->GetSID()); @@ -342,9 +344,16 @@ private: Uplink::Send("SENDUMODE", 'o', "From " + source.GetName() + ": " + buf); } - void SendSWhois(const MessageSource &source, const Anope::string &who, const Anope::string &mask) override + void SendSWhois(const MessageSource &source, User *target, const Anope::string &tag, const Anope::string &message) override { - Uplink::Send("SWHOIS", who, mask); + const auto utag = tag.empty() ? source.GetName() : tag; + Uplink::Send(source, "SWHOIS", target->GetUID(), "+", utag, 0, message); + } + + void SendSWhoisDel(const MessageSource &source, User *target, const Anope::string &tag, const Anope::string &message) override + { + const auto utag = tag.empty() ? source.GetName() : tag; + Uplink::Send(source, "SWHOIS", target->GetUID(), "-", utag, 0, message.empty() ? "*" : message); } void SendEOB() override