mirror of
https://forge.fsky.io/lda/Parsee.git
synced 2026-03-13 12:15:12 +00:00
Still need to grab it on the room-level from the room state if possible, otherwise just rollback to the MXID. I also need to consider profile pictures and bridging media, and check if the nick was present XMPP-side first, as that can and will cause issues, especially around semi-anonymous MUCs.
145 lines
4.3 KiB
C
145 lines
4.3 KiB
C
#include <Parsee.h>
|
|
|
|
#include <pthread.h>
|
|
#include <string.h>
|
|
|
|
#include <Cytoplasm/Memory.h>
|
|
#include <Cytoplasm/Log.h>
|
|
#include <Cytoplasm/Str.h>
|
|
|
|
#include <Matrix.h>
|
|
#include <XMPP.h>
|
|
#include <XML.h>
|
|
#include <AS.h>
|
|
|
|
|
|
static pthread_mutex_t cond_var_lock = PTHREAD_MUTEX_INITIALIZER;
|
|
static pthread_cond_t cond_var = PTHREAD_COND_INITIALIZER;
|
|
|
|
void
|
|
ParseeWakeupThread(void)
|
|
{
|
|
pthread_mutex_lock(&cond_var_lock);
|
|
pthread_cond_signal(&cond_var);
|
|
pthread_mutex_unlock(&cond_var_lock);
|
|
}
|
|
|
|
static void
|
|
ParseeDMHandler(char *room, char *from, XMLElement *data, const ParseeConfig *c)
|
|
{
|
|
ASSend(
|
|
c, room, from,
|
|
"m.room.message", MatrixCreateMessage(data->data)
|
|
);
|
|
}
|
|
|
|
void *
|
|
ParseeXMPPThread(void *argp)
|
|
{
|
|
ParseeData *args = argp;
|
|
XMPPComponent *jabber = args->jabber;
|
|
XMLElement *stanza = NULL;
|
|
while (true)
|
|
{
|
|
XMLElement *body = NULL;
|
|
XMLElement *data = NULL;
|
|
XMLElement *stanza_id = NULL;
|
|
char *to, *room, *from, *from_matrix;
|
|
char *chat_id, *mroom_id;
|
|
|
|
stanza = XMLDecode(jabber->stream, false);
|
|
if (!stanza)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (StrEquals(stanza->name, "presence"))
|
|
{
|
|
XMLFreeElement(stanza);
|
|
continue;
|
|
}
|
|
else if (StrEquals(stanza->name, "message"))
|
|
{
|
|
size_t i;
|
|
if (XMPPIsKiller(stanza))
|
|
{
|
|
const char *killer = "killer";
|
|
const char *suspend="suspend";
|
|
from = HashMapGet(stanza->attrs, "from");
|
|
if (!strncmp(from, killer, strlen(killer)))
|
|
{
|
|
XMLFreeElement(stanza);
|
|
break;
|
|
}
|
|
else if (!strncmp(from, suspend, strlen(suspend)))
|
|
{
|
|
XMLFreeElement(stanza);
|
|
pthread_mutex_lock(&cond_var_lock);
|
|
pthread_cond_wait(&cond_var, &cond_var_lock);
|
|
pthread_mutex_unlock(&cond_var_lock);
|
|
continue;
|
|
}
|
|
}
|
|
body = XMLookForUnique(stanza, "body");
|
|
if (!body)
|
|
{
|
|
XMLFreeElement(stanza);
|
|
continue;
|
|
}
|
|
stanza_id = XMLookForUnique(stanza, "stanza-id");
|
|
|
|
to = ParseeDecodeMXID(HashMapGet(stanza->attrs, "to"));
|
|
from = HashMapGet(stanza->attrs, "from");
|
|
from_matrix = ParseeEncodeJID(args->config, from, true);
|
|
room = ParseeFindDMRoom(args, to, from);
|
|
data = ArrayGet(body->children, 0);
|
|
|
|
/* TODO: Consider having rich messages, and move that out
|
|
* to separate functions */
|
|
chat_id = ParseeGetFromMUCID(args, from);
|
|
mroom_id = ParseeGetRoomID(args, chat_id);
|
|
if (room)
|
|
{
|
|
ParseeDMHandler(room, from_matrix, data, args->config);
|
|
}
|
|
if (mroom_id && !XMPPIsParseeStanza(stanza))
|
|
{
|
|
char *res = ParseeGetResource(from);
|
|
char *encoded = ParseeEncodeJID(args->config, from, false);
|
|
char *s_id_str = HashMapGet(stanza_id->attrs, "id");
|
|
|
|
/* TODO: Create smarter puppet names, and send presence
|
|
* in every room at Parsee's bootup. */
|
|
if (ParseeVerifyStanza(args, chat_id, s_id_str))
|
|
{
|
|
ASRegisterUser(args->config, encoded);
|
|
ASSetName(args->config, encoded, res);
|
|
ASJoin(args->config, mroom_id, encoded);
|
|
ASSend(
|
|
args->config, mroom_id, encoded,
|
|
"m.room.message", MatrixCreateMessage(data->data)
|
|
);
|
|
ParseePushStanza(args, chat_id, s_id_str);
|
|
}
|
|
|
|
Free(res);
|
|
Free(encoded);
|
|
}
|
|
Free(chat_id);
|
|
Free(mroom_id);
|
|
Free(from_matrix);
|
|
Free(room);
|
|
Free(to);
|
|
}
|
|
else
|
|
{
|
|
Log(LOG_WARNING, "Unknown stanza '%s':", stanza->name);
|
|
XMLEncode(StreamStdout(), stanza);
|
|
StreamPrintf(StreamStdout(), "\n");
|
|
StreamFlush(StreamStdout());
|
|
}
|
|
XMLFreeElement(stanza);
|
|
}
|
|
|
|
return NULL;
|
|
}
|