From 560b4f67812d4504aa87f0c0c0c903b4bea052c0 Mon Sep 17 00:00:00 2001 From: sectapunterx Date: Sat, 18 Jan 2025 18:16:49 +0300 Subject: [PATCH] add MUC join/leave and group message support --- library/include/larra/group_chat.hpp | 91 ++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 library/include/larra/group_chat.hpp diff --git a/library/include/larra/group_chat.hpp b/library/include/larra/group_chat.hpp new file mode 100644 index 0000000..4859c39 --- /dev/null +++ b/library/include/larra/group_chat.hpp @@ -0,0 +1,91 @@ +#pragma once +#include + +#include +#include +#include +#include +#include +#include + +namespace larra::xmpp::muc { + +struct JoinMuc { + BareJid room; + std::string nickname; + std::optional password; + struct History { + std::optional maxchars; + std::optional maxstanzas; + std::optional seconds; + std::optional since; + }; + std::optional 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