From d585134ce1a9e26a54b791b6642b8b6de498031c Mon Sep 17 00:00:00 2001 From: LDA Date: Wed, 2 Oct 2024 21:13:28 +0200 Subject: [PATCH] [ADD/WIP] Temporary vCard avatard Gajim still reacts weirdly.... also it leaks memory related to avatars, so that sucks... --- CHANGELOG.md | 2 +- src/Commands/Plumb.c | 2 +- src/MatrixEventHandler.c | 38 +++++++++++++++++++------------------ src/Parsee/User.c | 2 +- src/Routes/UserAck.c | 2 +- src/XMPP/MUC.c | 16 +++++++++++++--- src/XMPPThread/Stanzas/IQ.c | 6 +++++- src/include/XMPP.h | 2 +- 8 files changed, 43 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b95b8f8..8a48645 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,7 +27,7 @@ of Parsee. May occasionally deadlock. Fixes some media metadata things, replaces the build system, and speeds up Parsee a tad bit. #### New things -- Start dealing with some basic PEP-based avatars. +- Start dealing with some basic PEP and vCard-based avatars. - Allows MbedTLS through a specific Cytoplasm patch. - Kicking/Banning Parsee from XMPP effectively unlinks it. - Start adding documentation to Parsee diff --git a/src/Commands/Plumb.c b/src/Commands/Plumb.c index 8d94dfc..b555b7a 100644 --- a/src/Commands/Plumb.c +++ b/src/Commands/Plumb.c @@ -63,7 +63,7 @@ CommandHead(CmdPlumb, cmd, argp) if (chat_id) { char *rev = StrConcat(2, muc, "/parsee"); - XMPPJoinMUC(args->data->jabber, "parsee", rev, false); + XMPPJoinMUC(args->data->jabber, "parsee", rev, NULL, false); Free(rev); } diff --git a/src/MatrixEventHandler.c b/src/MatrixEventHandler.c index 163baca..9f601d5 100644 --- a/src/MatrixEventHandler.c +++ b/src/MatrixEventHandler.c @@ -18,7 +18,7 @@ static const char * GetXMPPInformation(ParseeData *data, HashMap *event, char **from, char **to); static char * -JoinMUC(ParseeData *data, HashMap *event, char *jid, char *muc, char *name) +JoinMUC(ParseeData *data, HashMap *event, char *jid, char *muc, char *name, char *hash) { char *sender = GrabString(event, 1, "sender"); @@ -33,7 +33,8 @@ JoinMUC(ParseeData *data, HashMap *event, char *jid, char *muc, char *name) UnistrFree(uninick); UnistrFree(filtered); - while (!XMPPJoinMUC(data->jabber, jid, rev, true) && nonce < 32) + /* TODO: vCards! */ + while (!XMPPJoinMUC(data->jabber, jid, rev, hash, true) && nonce < 32) { char *nonce_str = StrInt(nonce); char *input = StrConcat(3, sender, name, nonce_str); @@ -101,18 +102,24 @@ ParseeMemberHandler(ParseeData *data, HashMap *event) else if (StrEquals(membership, "join") && !ParseeIsPuppet(conf, state_key)) { char *jid = ParseeEncodeMXID(state_key); + char *sha = NULL, *mime = NULL; + char *avatar = ASGetAvatar(data->config, room_id, state_key); + char *url = ParseeToUnauth(data, avatar); chat_id = ParseeGetFromRoomID(data, room_id); + + ASGetMIMESHA(data->config, avatar, &mime, &sha); + Free(avatar); + avatar = NULL; if (chat_id) { char *muc = ParseeGetMUCID(data, chat_id); char *name = ASGetName(data->config, room_id, state_key); - char *avatar = ASGetAvatar(data->config, room_id, state_key); - char *jabber = JoinMUC(data, event, jid, muc, name); - + char *jabber = JoinMUC(data, event, jid, muc, name, sha); + avatar = ASGetAvatar(data->config, room_id, state_key); Log(LOG_DEBUG, "MATRIX: Joining as '%s' (avatar=%s)", jabber, avatar); - Free(avatar); Free(jabber); + Free(avatar); Free(name); Free(muc); @@ -120,18 +127,14 @@ ParseeMemberHandler(ParseeData *data, HashMap *event) } else { - char *avatar = ASGetAvatar(data->config, room_id, state_key); - char *sha = NULL, *mime = NULL, *url = NULL; char *full_jid = StrConcat(3, jid, "@", data->config->component_host ); XMLElement *elem, *pevent, *items, *item, *meta, *info; - Log(LOG_DEBUG, "MATRIX: Got local user '%s'(mxid=%s avatar=%s)", jid, state_key, avatar); + Log(LOG_DEBUG, "MATRIX: Got local user '%s'(mxid=%s)", jid, state_key); - url = ParseeToUnauth(data, avatar); elem = XMLCreateTag("message"); - ASGetMIMESHA(data->config, avatar, &mime, &sha); { #define PUBSUB "http://jabber.org/protocol/pubsub" #define AVATAR "urn:xmpp:avatar:metadata" @@ -180,13 +183,12 @@ ParseeMemberHandler(ParseeData *data, HashMap *event) XMLFreeElement(elem); Free(full_jid); - Free(avatar); - Free(mime); - Free(sha); - Free(url); } - Free(jid); Free(chat_id); + Free(mime); + Free(sha); + Free(jid); + Free(url); } else if ((StrEquals(membership, "leave") || StrEquals(membership, "ban")) @@ -343,7 +345,7 @@ GetXMPPInformation(ParseeData *data, HashMap *event, char **from, char **to) } matrix_name = ASGetName(data->config, room_id, matrix_sender); - Free(JoinMUC(data, event, *from, muc_id, matrix_name)); + Free(JoinMUC(data, event, *from, muc_id, matrix_name, NULL)); *to = muc_id; Free(matrix_name); @@ -432,7 +434,7 @@ ParseeMessageHandler(ParseeData *data, HashMap *event) /* TODO: Avoid using the AS endpoints */ name = ASGetName(data->config, id, m_sender); - Free(JoinMUC(data, event, encoded_from, muc_id, name)); + Free(JoinMUC(data, event, encoded_from, muc_id, name, NULL)); to = muc_id; diff --git a/src/Parsee/User.c b/src/Parsee/User.c index 90c7ca5..fe7d00b 100644 --- a/src/Parsee/User.c +++ b/src/Parsee/User.c @@ -554,7 +554,7 @@ ParseeSendPresence(ParseeData *data) char *rev = StrConcat(2, muc, "/parsee"); /* Make a fake user join the MUC */ Log(LOG_NOTICE, "Sending presence to %s", rev); - XMPPJoinMUC(data->jabber, "parsee", rev, false); + XMPPJoinMUC(data->jabber, "parsee", rev, NULL, false); Free(rev); } diff --git a/src/Routes/UserAck.c b/src/Routes/UserAck.c index 828be65..54ca96e 100644 --- a/src/Routes/UserAck.c +++ b/src/Routes/UserAck.c @@ -131,7 +131,7 @@ RouteHead(RouteRoomAck, arr, argp) { char *rev = StrConcat(2, muc, "/parsee"); Log(LOG_NOTICE, "Sending presence to %s", rev); - XMPPJoinMUC(args->data->jabber, "parsee", rev, false); + XMPPJoinMUC(args->data->jabber, "parsee", rev, NULL, false); Free(rev); } diff --git a/src/XMPP/MUC.c b/src/XMPP/MUC.c index 3a81764..498ddfa 100644 --- a/src/XMPP/MUC.c +++ b/src/XMPP/MUC.c @@ -168,9 +168,9 @@ XMPPRequestVoice(XMPPComponent *jabber, char *from, char *muc) Free(identifier); } bool -XMPPJoinMUC(XMPPComponent *comp, char *fr, char *muc, bool care) +XMPPJoinMUC(XMPPComponent *comp, char *fr, char *muc, char *hash, bool ret) { - XMLElement *presence, *x, *reply, *history; + XMLElement *presence, *x, *reply, *history, *photo; char *from, *id; if (!comp || !fr || !muc) { @@ -192,6 +192,16 @@ XMPPJoinMUC(XMPPComponent *comp, char *fr, char *muc, bool care) XMLAddChild(presence, x); XMPPAnnotatePresence(presence); + if (hash) + { + x = XMLCreateTag("x"); + XMLAddAttr(x, "xmlns", "vcard-temp:x:update"); + photo = XMLCreateTag("photo"); + XMLAddChild(photo, XMLCreateText(hash)); + XMLAddChild(x, photo); + XMLAddChild(presence, x); + } + XMLEncode(comp->stream, presence); StreamFlush(comp->stream); @@ -200,7 +210,7 @@ XMPPJoinMUC(XMPPComponent *comp, char *fr, char *muc, bool care) pthread_mutex_unlock(&comp->write_lock); - if (care && (reply = ParseeAwaitStanza(id, 500))) + if (ret && (reply = ParseeAwaitStanza(id, 500))) { bool exit_code = true; diff --git a/src/XMPPThread/Stanzas/IQ.c b/src/XMPPThread/Stanzas/IQ.c index 6ff097c..c2dc3a9 100644 --- a/src/XMPPThread/Stanzas/IQ.c +++ b/src/XMPPThread/Stanzas/IQ.c @@ -78,6 +78,7 @@ GenerateAvatarData(ParseeData *data, char *mxid) end: Free(mime); Free(out); + Free(mxc); Free(b64); return elem; } @@ -395,7 +396,7 @@ IQGet(ParseeData *args, XMLElement *stanza, XMPPThread *thr) char *to_matrix = ParseeGetBridgedUser(args, stanza); char *name = ASGetName(args->config, NULL, to_matrix); XMLElement *iqVCard; - Log(LOG_DEBUG, "vCard information GET for %s", to); + Log(LOG_DEBUG, "vCard information GET for %s (%s)", to, to_matrix); if (!strncmp(to, "parsee@", 7)) { @@ -435,6 +436,9 @@ IQGet(ParseeData *args, XMLElement *stanza, XMPPThread *thr) return; } + Free(to_matrix); + to_matrix = ParseeDecodeMXID(to); + iqVCard = XMLCreateTag("iq"); XMLAddAttr(iqVCard, "from", to); XMLAddAttr(iqVCard, "to", from); diff --git a/src/include/XMPP.h b/src/include/XMPP.h index 24a23d9..0a4cfe7 100644 --- a/src/include/XMPP.h +++ b/src/include/XMPP.h @@ -30,7 +30,7 @@ extern XMPPComponent * XMPPInitialiseCompStream(char *host, int port); extern bool XMPPAuthenticateCompStream(XMPPComponent *comp, char *shared); /* Makes a user join/leave a MUC */ -extern bool XMPPJoinMUC(XMPPComponent *comp, char *fr, char *muc, bool care); +extern bool XMPPJoinMUC(XMPPComponent *comp, char *fr, char *muc, char *hash, bool ret); extern void XMPPLeaveMUC(XMPPComponent *comp, char *fr, char *muc, char *r); /* TODO: XMPP stuff, I don't fucking know, I'm not a Jabbernerd. */