aboutsummaryrefslogtreecommitdiff
path: root/modules/spanningtree/msgbuilder.cpp
blob: 4b7b73301d95d7adbfb828aa4584402421343632 (about) (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
 * InspIRCd -- Internet Relay Chat Daemon
 *
 *   Copyright (C) 2026 Sadie Powell <sadie@witchery.services>
 *
 * This file is part of InspIRCd.  InspIRCd is free software: you can
 * redistribute it and/or modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation, version 2.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <sstream>

#include "main.h"
#include "msgbuilder.h"

void MessageBuilder::Broadcast(const TreeServer* omit)
{
	for (const auto* server : Utils->TreeRoot->GetChildren())
	{
		if (!omit || omit != server)
			Unicast(server->GetSocket());
	}
}

MessageBuilder& MessageBuilder::PushParams(const CommandBase::Params& newparams)
{
	for (const auto& param : newparams)
		Push(param);
	PushTags(newparams.GetTags());
	return *this;
}

MessageBuilder& MessageBuilder::PushTags(ClientProtocol::TagMap newtags)
{
	auto& oldtags = this->parameters.GetTags();
	newtags.insert(oldtags.begin(), oldtags.end());
	std::swap(oldtags, newtags);
	return *this;
}

void MessageBuilder::Finalize()
{
	if (!Utils || this->finalized)
		return; // Should never happen

	Utils->Creator->messageeventprov.Call(&ServerProtocol::MessageEventListener::OnServerMessage,
		this->source, this->command, this->parameters);

	finalized = true;
}

std::string MessageBuilder::ToRFC1459() const
{
	std::stringstream buffer;

	const auto& tags = this->parameters.GetTags();
	if (!tags.empty())
	{
		auto separator = '@';
		for (const auto &[tname, tinfo] : tags)
		{
			buffer << separator << tname;
			if (!tinfo.value.empty())
				buffer << '=' << tinfo.value;
			separator = ';';
		}
		if (separator != '@')
			buffer << ' ';
	}

	if (this->source)
		buffer << ':' << source->uuid << ' ';

	buffer << command;
	if (!this->parameters.empty())
	{
		buffer << ' ';
		for (auto it = this->parameters.begin(); it != this->parameters.end() - 1; ++it)
			buffer << *it << ' ';

		const auto &last = this->parameters.back();
		if (last.empty() || last[0] == ':' || last.find(' ') != std::string::npos)
			buffer << ':';
		buffer << last;
	}

	return buffer.str();
}

void MessageBuilder::Unicast(TreeServer* server)
{
	if (server->GetSocket())
		Unicast(server->GetSocket());
}

void MessageBuilder::Unicast(TreeSocket* socket)
{
	this->Finalize();
	socket->SendMessage(*this);
}

void MessageBuilder::Unicast(const User* user)
{
	if (user->server)
		Unicast(static_cast<TreeServer*>(user->server));
}