mirror of
https://github.com/anope/anope.git
synced 2026-07-08 07:43:15 +02:00
Add Uplink::Send, rework message formatting.
This is the new way of sending messages to the uplink inspired by the work done in the old git master. This will allow us to do new things involving tags in the future.
This commit is contained in:
@@ -728,6 +728,11 @@ public:
|
||||
|
||||
/** Convert something to a string
|
||||
*/
|
||||
inline Anope::string stringify(const Anope::string &x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
template<typename T> inline Anope::string stringify(const T &x)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
|
||||
+12
-2
@@ -51,10 +51,20 @@ public:
|
||||
* @return If the message was well formed then true; otherwise, false.
|
||||
*/
|
||||
virtual bool Parse(const Anope::string &message, Anope::map<Anope::string> &tags, Anope::string &source, Anope::string &command, std::vector<Anope::string> ¶ms);
|
||||
virtual Anope::string Format(const Anope::string &source, const Anope::string &message);
|
||||
|
||||
/* Formats an outgoing message so it can be sent to the IRC server.
|
||||
* @param message The location to store the formatted message.
|
||||
* @param tags IRCv3 message tags.
|
||||
* @param source Source of the message.
|
||||
* @param command Command name.
|
||||
* @param params Any extra parameters.
|
||||
* @return If the message was formatted then true; otherwise, false.
|
||||
*/
|
||||
virtual bool Format(Anope::string &message, const Anope::map<Anope::string> &tags, const MessageSource &source, const Anope::string &command, const std::vector<Anope::string> ¶ms);
|
||||
|
||||
/* Modes used by default by our clients */
|
||||
Anope::string DefaultPseudoclientModes = "+io";
|
||||
|
||||
/* Can we force change a users's nick? */
|
||||
bool CanSVSNick = false;
|
||||
|
||||
@@ -279,7 +289,7 @@ class CoreExport MessageSource final
|
||||
Server *s = nullptr;
|
||||
|
||||
public:
|
||||
MessageSource(const Anope::string &);
|
||||
explicit MessageSource(const Anope::string &);
|
||||
MessageSource(User *u);
|
||||
MessageSource(Server *s);
|
||||
const Anope::string &GetName() const;
|
||||
|
||||
+27
-1
@@ -13,10 +13,36 @@
|
||||
|
||||
#include "sockets.h"
|
||||
#include "protocol.h"
|
||||
#include "servers.h"
|
||||
|
||||
namespace Uplink
|
||||
{
|
||||
extern void Connect();
|
||||
extern CoreExport void SendInternal(const Anope::map<Anope::string> &, const MessageSource &, const Anope::string &, const std::vector<Anope::string> &);
|
||||
|
||||
template<typename... Args>
|
||||
void Send(const Anope::map<Anope::string> &tags, const MessageSource &source, const Anope::string &command, Args &&...args)
|
||||
{
|
||||
SendInternal(tags, source, command, { stringify(args)... });
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void Send(const Anope::map<Anope::string> &tags, const Anope::string &command, Args &&...args)
|
||||
{
|
||||
SendInternal(tags, Me, command, { stringify(args)... });
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void Send(const MessageSource &source, const Anope::string &command, Args &&...args)
|
||||
{
|
||||
SendInternal({}, source, command, { stringify(args)... });
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void Send(const Anope::string &command, Args &&...args)
|
||||
{
|
||||
SendInternal({}, Me, command, { stringify(args)... });
|
||||
}
|
||||
}
|
||||
|
||||
/* This is the socket to our uplink */
|
||||
@@ -33,7 +59,7 @@ public:
|
||||
void OnError(const Anope::string &) override;
|
||||
|
||||
/* A message sent over the uplink socket */
|
||||
class CoreExport Message final
|
||||
class CoreExport [[deprecated]] Message final
|
||||
{
|
||||
MessageSource source;
|
||||
std::stringstream buffer;
|
||||
|
||||
@@ -141,9 +141,9 @@ public:
|
||||
this->SendVhost(u, u->GetIdent(), "");
|
||||
}
|
||||
|
||||
Anope::string Format(const Anope::string &source, const Anope::string &message) override
|
||||
bool Format(Anope::string &message, const Anope::map<Anope::string> &tags, const MessageSource &source, const Anope::string &command, const std::vector<Anope::string> ¶ms) override
|
||||
{
|
||||
return IRCDProto::Format(source.empty() ? Me->GetSID() : source, message);
|
||||
return IRCDProto::Format(message, tags, source.GetSource().empty() ? source : Me, command, params);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+61
-5
@@ -123,12 +123,68 @@ bool IRCDProto::Parse(const Anope::string &buffer, Anope::map<Anope::string> &ta
|
||||
return true;
|
||||
}
|
||||
|
||||
Anope::string IRCDProto::Format(const Anope::string &source, const Anope::string &message)
|
||||
bool IRCDProto::Format(Anope::string &message, const Anope::map<Anope::string> &tags, const MessageSource &source, const Anope::string &command, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
if (!source.empty())
|
||||
return ":" + source + " " + message;
|
||||
else
|
||||
return message;
|
||||
std::stringstream buffer;
|
||||
if (CanSendTags && !tags.empty())
|
||||
{
|
||||
char separator = '@';
|
||||
for (const auto &[tname, tvalue] : tags)
|
||||
{
|
||||
buffer << separator << tname;
|
||||
if (!tvalue.empty())
|
||||
buffer << '=' << tvalue;
|
||||
separator = ';';
|
||||
}
|
||||
buffer << ' ';
|
||||
}
|
||||
|
||||
if (source.GetServer())
|
||||
{
|
||||
const auto *s = source.GetServer();
|
||||
if (s != Me && !s->IsJuped())
|
||||
{
|
||||
Log(LOG_DEBUG) << "Attempted to send \"" << command << "\" from " << s->GetName() << " who is not from me";
|
||||
return false;
|
||||
}
|
||||
|
||||
buffer << ':' << s->GetSID() << ' ';
|
||||
}
|
||||
else if (source.GetUser())
|
||||
{
|
||||
const auto *u = source.GetUser();
|
||||
if (u->server != Me && !u->server->IsJuped())
|
||||
{
|
||||
Log(LOG_DEBUG) << "Attempted to send \"" << command << "\" from " << u->nick << " who is not from me";
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto *bi = source.GetBot();
|
||||
if (bi && !bi->introduced)
|
||||
{
|
||||
Log(LOG_DEBUG) << "Attempted to send \"" << command << "\" from " << bi->nick << " when not introduced";
|
||||
return false;
|
||||
}
|
||||
|
||||
buffer << ':' << u->GetUID() << ' ';
|
||||
}
|
||||
|
||||
buffer << command;
|
||||
if (!params.empty())
|
||||
{
|
||||
buffer << ' ';
|
||||
for (auto it = params.begin(); it != params.end() - 1; ++it)
|
||||
buffer << *it << ' ';
|
||||
|
||||
|
||||
const auto &last = params.back();
|
||||
if (last.empty() || last[0] == ':' || last.find(' ') != std::string::npos)
|
||||
buffer << ':';
|
||||
buffer << last;
|
||||
}
|
||||
|
||||
message = buffer.str();
|
||||
return true;
|
||||
}
|
||||
|
||||
MessageTokenizer::MessageTokenizer(const Anope::string &msg)
|
||||
|
||||
+23
-46
@@ -61,6 +61,22 @@ void Uplink::Connect()
|
||||
UplinkSock->Connect(ip, u.port);
|
||||
}
|
||||
|
||||
void Uplink::SendInternal(const Anope::map<Anope::string> &tags, const MessageSource &source, const Anope::string &command, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
if (!UplinkSock)
|
||||
{
|
||||
Log(LOG_DEBUG) << "Attempted to send \"" << command << "\" from " << source.GetName() << " with a null uplink socket";
|
||||
return;
|
||||
}
|
||||
|
||||
Anope::string message;
|
||||
if (!IRCD->Format(message, tags, source, command, params))
|
||||
return;
|
||||
|
||||
UplinkSock->Write(message);
|
||||
Log(LOG_RAWIO) << "Sent: " << message;
|
||||
}
|
||||
|
||||
UplinkSocket::UplinkSocket() : Socket(-1, Config->Uplinks[Anope::CurrentUplink].protocol), ConnectionSocket(), BufferedSocket()
|
||||
{
|
||||
error = false;
|
||||
@@ -165,50 +181,11 @@ UplinkSocket::Message::Message(const MessageSource &src) : source(src)
|
||||
|
||||
UplinkSocket::Message::~Message()
|
||||
{
|
||||
Anope::string message_source;
|
||||
|
||||
if (this->source.GetServer() != NULL)
|
||||
{
|
||||
const Server *s = this->source.GetServer();
|
||||
|
||||
if (s != Me && !s->IsJuped())
|
||||
{
|
||||
Log(LOG_DEBUG) << "Attempted to send \"" << this->buffer.str() << "\" from " << s->GetName() << " who is not from me?";
|
||||
return;
|
||||
}
|
||||
|
||||
message_source = s->GetSID();
|
||||
}
|
||||
else if (this->source.GetUser() != NULL)
|
||||
{
|
||||
const User *u = this->source.GetUser();
|
||||
|
||||
if (u->server != Me && !u->server->IsJuped())
|
||||
{
|
||||
Log(LOG_DEBUG) << "Attempted to send \"" << this->buffer.str() << "\" from " << u->nick << " who is not from me?";
|
||||
return;
|
||||
}
|
||||
|
||||
const BotInfo *bi = this->source.GetBot();
|
||||
if (bi != NULL && bi->introduced == false)
|
||||
{
|
||||
Log(LOG_DEBUG) << "Attempted to send \"" << this->buffer.str() << "\" from " << bi->nick << " when not introduced";
|
||||
return;
|
||||
}
|
||||
|
||||
message_source = u->GetUID();
|
||||
}
|
||||
|
||||
if (!UplinkSock)
|
||||
{
|
||||
if (!message_source.empty())
|
||||
Log(LOG_DEBUG) << "Attempted to send \"" << message_source << " " << this->buffer.str() << "\" with UplinkSock NULL";
|
||||
else
|
||||
Log(LOG_DEBUG) << "Attempted to send \"" << this->buffer.str() << "\" with UplinkSock NULL";
|
||||
return;
|
||||
}
|
||||
|
||||
Anope::string sent = IRCD->Format(message_source, this->buffer.str());
|
||||
UplinkSock->Write(sent);
|
||||
Log(LOG_RAWIO) << "Sent: " << sent;
|
||||
// This is all temporary as UplinkSocket::Message is going to to die as soon
|
||||
// as everything is migrated to Uplink::Send.
|
||||
Anope::map<Anope::string> tags;
|
||||
Anope::string unused, command;
|
||||
std::vector<Anope::string> params;
|
||||
if (IRCD->Parse(this->buffer.str(), tags, unused, command, params))
|
||||
Uplink::SendInternal(tags, source, command, params);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user