mirror of
https://forge.fsky.io/lda/Parsee.git
synced 2026-03-14 00:45:10 +00:00
[ADD/WIP] Start unifying DMs and MUCs
I really need to dispatch XMPP stanza management.
This commit is contained in:
parent
6b0f08c49e
commit
5f2c3a9cb8
10 changed files with 570 additions and 87 deletions
161
src/XMPPThread.c
161
src/XMPPThread.c
|
|
@ -15,15 +15,15 @@
|
|||
#include <AS.h>
|
||||
|
||||
#define IQ_ADVERT \
|
||||
AdvertiseSimple("http://jabber.org/protocol/caps") \
|
||||
AdvertiseSimple("http://jabber.org/protocol/chatstates") \
|
||||
AdvertiseSimple("http://jabber.org/protocol/caps") \
|
||||
AdvertiseSimple("urn:xmpp:avatar:metadata+notify") \
|
||||
AdvertiseSimple("urn:xmpp:message-correct:0") \
|
||||
AdvertiseSimple("urn:xmpp:reactions:0") \
|
||||
AdvertiseSimple("urn:xmpp:styling:0") \
|
||||
AdvertiseSimple("urn:xmpp:reply:0") \
|
||||
AdvertiseSimple("jabber:x:oob") \
|
||||
AdvertiseSimple("vcard-temp") \
|
||||
AdvertiseSimple("urn:xmpp:avatar:metadata+notify") \
|
||||
AdvertiseSimple("jabber:iq:version") \
|
||||
AdvertiseSimple("urn:parsee:x-parsee:0") \
|
||||
AdvertiseSimple("urn:parsee:jealousy:0")
|
||||
|
|
@ -162,13 +162,112 @@ ParseeWakeupThread(void)
|
|||
pthread_mutex_unlock(&cond_var_lock);
|
||||
}
|
||||
|
||||
static void
|
||||
ParseeDMHandler(char *room, char *from, XMLElement *data, const ParseeConfig *c)
|
||||
static char *
|
||||
ParseeGetBridgedRoom(ParseeData *data, XMLElement *stanza)
|
||||
{
|
||||
Free(ASSend(
|
||||
c, room, from,
|
||||
"m.room.message", MatrixCreateMessage(data->data)
|
||||
));
|
||||
char *to = ParseeDecodeMXID(HashMapGet(stanza->attrs, "to"));
|
||||
char *from = (HashMapGet(stanza->attrs, "from"));
|
||||
char *chat_id = ParseeGetFromMUCID(data, from);
|
||||
char *mroom_id = ParseeGetRoomID(data, chat_id);
|
||||
char *ret;
|
||||
|
||||
Free(chat_id);
|
||||
if (mroom_id)
|
||||
{
|
||||
Free(to);
|
||||
return mroom_id;
|
||||
}
|
||||
|
||||
/* Not a MUC, find the DMd room. */
|
||||
ret = ParseeFindDMRoom(data, to, from);
|
||||
Free(to);
|
||||
return ret;
|
||||
}
|
||||
static char *
|
||||
ParseeGetEventFromID(ParseeData *data, XMLElement *stanza, char *id)
|
||||
{
|
||||
char *from = (HashMapGet(stanza->attrs, "from"));
|
||||
char *chat_id = ParseeGetFromMUCID(data, from);
|
||||
char *ret = ParseeEventFromSID(data, chat_id, id);
|
||||
char *mroom_id = ParseeGetBridgedRoom(data, stanza);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
Free(ret);
|
||||
ret = ParseeEventFromID(data, chat_id, id);
|
||||
}
|
||||
|
||||
Free(chat_id);
|
||||
if (ret)
|
||||
{
|
||||
Free(mroom_id);
|
||||
return ret;
|
||||
}
|
||||
ret = ParseeDMEventFromID(data, mroom_id, id);
|
||||
Free(mroom_id);
|
||||
|
||||
return ret;
|
||||
}
|
||||
static char *
|
||||
ParseeGetReactedEvent(ParseeData *data, XMLElement *stanza)
|
||||
{
|
||||
XMLElement *reactions = XMLookForTKV(stanza,
|
||||
"reactions", "xmlns", "urn:xmpp:reactions:0"
|
||||
);
|
||||
char *from = (HashMapGet(stanza->attrs, "from"));
|
||||
char *reacted_id = reactions ? HashMapGet(reactions->attrs, "id") : NULL;
|
||||
|
||||
return ParseeGetEventFromID(data, stanza, reacted_id);
|
||||
}
|
||||
|
||||
static void
|
||||
ParseePushAllStanza(ParseeData *args, XMLElement *stanza, char *event)
|
||||
{
|
||||
char *xmpp_from = HashMapGet(stanza->attrs, "from");
|
||||
char *mroom_id = ParseeGetBridgedRoom(args, stanza);
|
||||
char *chat_id = ParseeGetFromMUCID(args, xmpp_from);
|
||||
|
||||
char *id_str = HashMapGet(stanza->attrs, "id");
|
||||
char *s_id_str = XMPPGetStanzaID(stanza);
|
||||
char *o_id_str = XMPPGetOriginID(stanza);
|
||||
|
||||
if (!chat_id)
|
||||
{
|
||||
ParseePushDMStanza(
|
||||
args, mroom_id, s_id_str,
|
||||
id_str, event, xmpp_from
|
||||
);
|
||||
}
|
||||
ParseePushStanza(args, chat_id, s_id_str, id_str, event, xmpp_from);
|
||||
Free(mroom_id);
|
||||
Free(chat_id);
|
||||
}
|
||||
|
||||
static bool
|
||||
ParseeVerifyAllStanza(ParseeData *args, XMLElement *stanza)
|
||||
{
|
||||
char *to, *room;
|
||||
char *from = HashMapGet(stanza->attrs, "from");
|
||||
char *id = HashMapGet(stanza->attrs, "id");
|
||||
char *chat_id = ParseeGetFromMUCID(args, from);
|
||||
bool ret;
|
||||
|
||||
if (chat_id)
|
||||
{
|
||||
char *s_id_str = XMPPGetStanzaID(stanza);
|
||||
ret = ParseeVerifyStanza(args, chat_id, s_id_str);
|
||||
|
||||
Free(chat_id);
|
||||
return ret;
|
||||
}
|
||||
to = ParseeDecodeMXID(HashMapGet(stanza->attrs, "to"));
|
||||
room = ParseeFindDMRoom(args, to, from);
|
||||
ret = ParseeVerifyDMStanza(args, chat_id, id);
|
||||
|
||||
Free(room);
|
||||
Free(to);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* TODO: Clean up all of this. We are currently separating DMs from MUCs,
|
||||
|
|
@ -225,7 +324,6 @@ MessageStanza(ParseeData *args, XMLElement *stanza)
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* TODO: On semi-anonymous MUCs, it might be preferable to use a
|
||||
* form of the occupant ID as the base, as it is more unique, and
|
||||
* less prone to trigger the character limit on Matrix.
|
||||
|
|
@ -237,12 +335,7 @@ MessageStanza(ParseeData *args, XMLElement *stanza)
|
|||
room = ParseeFindDMRoom(args, to, from);
|
||||
data = ArrayGet(body->children, 0);
|
||||
|
||||
chat_id = ParseeGetFromMUCID(args, from);
|
||||
mroom_id = ParseeGetRoomID(args, chat_id);
|
||||
if (room)
|
||||
{
|
||||
ParseeDMHandler(room, from_matrix, data, args->config);
|
||||
}
|
||||
mroom_id = ParseeGetBridgedRoom(args, stanza);
|
||||
if (mroom_id && !XMPPIsParseeStanza(stanza))
|
||||
{
|
||||
char *res = ParseeGetResource(from);
|
||||
|
|
@ -253,13 +346,24 @@ MessageStanza(ParseeData *args, XMLElement *stanza)
|
|||
char *event_id = NULL;
|
||||
char *replaced = XMPPGetReplacedID(stanza);
|
||||
char *reply_to = XMPPGetReply(stanza);
|
||||
bool chat = false;
|
||||
|
||||
if (ParseeVerifyStanza(args, chat_id, s_id_str) && !replaced)
|
||||
if (StrEquals(HashMapGet(stanza->attrs, "type"), "chat"))
|
||||
{
|
||||
Free(encoded);
|
||||
encoded = StrDuplicate(from_matrix);
|
||||
chat = true;
|
||||
}
|
||||
|
||||
if (ParseeVerifyAllStanza(args, stanza) && !replaced)
|
||||
{
|
||||
XMLElement *oob, *oob_data;
|
||||
|
||||
ASRegisterUser(args->config, encoded);
|
||||
ASSetName(args->config, encoded, res);
|
||||
if (!chat)
|
||||
{
|
||||
ASSetName(args->config, encoded, res);
|
||||
}
|
||||
ASInvite(args->config, mroom_id, encoded);
|
||||
ASJoin(args->config, mroom_id, encoded);
|
||||
|
||||
|
|
@ -290,7 +394,7 @@ MessageStanza(ParseeData *args, XMLElement *stanza)
|
|||
char *reacted_id = HashMapGet(reactions->attrs, "id");
|
||||
Array *react_child = reactions->children;
|
||||
size_t reacts = ArraySize(react_child);
|
||||
event_id = ParseeEventFromSID(args, chat_id, reacted_id);
|
||||
event_id = ParseeGetReactedEvent(args, stanza);
|
||||
for (i = 0; i < reacts; i++)
|
||||
{
|
||||
XMLElement *reaction, *react_data;
|
||||
|
|
@ -311,15 +415,13 @@ MessageStanza(ParseeData *args, XMLElement *stanza)
|
|||
{
|
||||
/* TODO: Use HTML-formatted bodies, and respect the fallback
|
||||
* trims the stanza provides us if possible. Element does
|
||||
* not like raw bodies on replies. Go figure. */
|
||||
* not like raw bodies on replies too. Go figure. */
|
||||
size_t off =
|
||||
reply_to ? ParseeFindDatastart(data->data) : 0;
|
||||
HashMap *ev = MatrixCreateMessage(data->data + off);
|
||||
if (reply_to)
|
||||
{
|
||||
char *reply_id = ParseeEventFromSID(
|
||||
args, chat_id, reply_to
|
||||
);
|
||||
char *reply_id = ParseeGetEventFromID(args, stanza, reply_to);
|
||||
MatrixSetReply(ev, reply_id);
|
||||
Free(reply_id);
|
||||
}
|
||||
|
|
@ -328,16 +430,17 @@ MessageStanza(ParseeData *args, XMLElement *stanza)
|
|||
"m.room.message", ev
|
||||
);
|
||||
}
|
||||
ParseePushStanza(args, chat_id, s_id_str, id_str, event_id, from);
|
||||
ParseePushAllStanza(args, stanza, event_id);
|
||||
Free(event_id);
|
||||
}
|
||||
else if (replaced)
|
||||
{
|
||||
event_id = ParseeEventFromID(args, chat_id, replaced);
|
||||
event_id = ParseeGetEventFromID(args, stanza, replaced);
|
||||
Free(ASSend(
|
||||
args->config, mroom_id, encoded,
|
||||
"m.room.message", MatrixCreateReplace(event_id, data->data)
|
||||
));
|
||||
ParseePushAllStanza(args, stanza, event_id);
|
||||
|
||||
Free(event_id);
|
||||
}
|
||||
|
|
@ -345,19 +448,16 @@ MessageStanza(ParseeData *args, XMLElement *stanza)
|
|||
Free(res);
|
||||
Free(encoded);
|
||||
}
|
||||
else if (mroom_id)
|
||||
else
|
||||
{
|
||||
XMLElement *parsee = XMLookForUnique(stanza, "x-parsee");
|
||||
XMLElement *event = XMLookForUnique(parsee, "event-id");
|
||||
XMLElement *e_d = ArrayGet(event ? event->children : NULL, 0);
|
||||
char *s_id_str = XMPPGetStanzaID(stanza);
|
||||
char *id_str = HashMapGet(stanza->attrs, "id");
|
||||
if (ParseeVerifyStanza(args, chat_id, s_id_str))
|
||||
{
|
||||
ParseePushStanza(args, chat_id, s_id_str, id_str, e_d->data, from);
|
||||
}
|
||||
|
||||
ParseePushAllStanza(args, stanza, e_d->data);
|
||||
}
|
||||
Free(chat_id);
|
||||
Free(mroom_id);
|
||||
Free(from_matrix);
|
||||
Free(decode_from);
|
||||
|
|
@ -579,6 +679,7 @@ ParseeXMPPThread(void *argp)
|
|||
const char *killer = "killer";
|
||||
const char *suspend="suspend";
|
||||
from = HashMapGet(stanza->attrs, "from");
|
||||
Log(LOG_INFO, "Killer.");
|
||||
if (!strncmp(from, killer, strlen(killer)))
|
||||
{
|
||||
XMLFreeElement(stanza);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue