add MUC join/leave and group message support
Some checks failed
PR Check / on-push-commit-check (push) Failing after 2m54s

This commit is contained in:
sectapunterx 2025-01-18 18:16:49 +03:00
parent 7f5c9cfd49
commit 560b4f6781

View file

@ -0,0 +1,91 @@
#pragma once
#include <libxml++/libxml++.h>
#include <format>
#include <larra/jid.hpp>
#include <larra/utils.hpp>
#include <larra/xml_stream.hpp>
#include <optional>
#include <string>
namespace larra::xmpp::muc {
struct JoinMuc {
BareJid room;
std::string nickname;
std::optional<std::string> password;
struct History {
std::optional<int> maxchars;
std::optional<int> maxstanzas;
std::optional<int> seconds;
std::optional<std::string> since;
};
std::optional<History> history;
friend auto operator<<(xmlpp::Element* element, const JoinMuc& self) -> void {
element->set_name("presence");
std::string occupantJid;
if(self.room.server.empty()) {
occupantJid = std::format("{}@conference.unknown/{}", self.room.username, self.nickname);
} else {
occupantJid = std::format("{}@{}/{}", self.room.username, self.room.server, self.nickname);
}
element->set_attribute("to", occupantJid);
auto* xNode = element->add_child_element("x");
xNode->set_namespace("http://jabber.org/protocol/muc");
if(self.password) {
auto* passwordNode = xNode->add_child_element("password");
passwordNode->add_child_text(*self.password);
}
if(self.history) {
auto* historyNode = xNode->add_child_element("history");
if(self.history->maxchars) {
historyNode->set_attribute("maxchars", std::to_string(*self.history->maxchars));
}
if(self.history->maxstanzas) {
historyNode->set_attribute("maxstanzas", std::to_string(*self.history->maxstanzas));
}
if(self.history->seconds) {
historyNode->set_attribute("seconds", std::to_string(*self.history->seconds));
}
if(self.history->since) {
historyNode->set_attribute("since", *self.history->since);
}
}
}
};
struct LeaveMuc {
BareJid room;
std::string nickname;
friend auto operator<<(xmlpp::Element* element, const LeaveMuc& self) -> void {
element->set_name("presence");
std::string occupantJid;
if(self.room.server.empty()) {
occupantJid = std::format("{}@conference.unknown/{}", self.room.username, self.nickname);
} else {
occupantJid = std::format("{}@{}/{}", self.room.username, self.room.server, self.nickname);
}
element->set_attribute("to", occupantJid);
element->set_attribute("type", "unavailable");
}
};
struct GroupChatMessage {
BareJid room;
std::string body;
friend auto operator<<(xmlpp::Element* element, const GroupChatMessage& self) -> void {
element->set_name("message");
std::string to;
if(self.room.server.empty()) {
to = std::format("{}@conference.unknown", self.room.username);
} else {
to = std::format("{}@{}", self.room.username, self.room.server);
}
element->set_attribute("to", to);
element->set_attribute("type", "groupchat");
auto* bodyNode = element->add_child_element("body");
bodyNode->add_child_text(self.body);
}
};
} // namespace larra::xmpp::muc