[ADD/MOD] Help/stats and two-way modification

More on the Reverse Ideology!
This commit is contained in:
LDA 2024-06-29 19:10:28 +02:00
commit 8472ada953
13 changed files with 203 additions and 14 deletions

View file

@ -5,10 +5,11 @@ Somewhat implemented XEPs:
This allows reactions, which Matrix also has support to. The two This allows reactions, which Matrix also has support to. The two
systems don't seem *too* restrictive on one-another (unlike some systems don't seem *too* restrictive on one-another (unlike some
IM platforms I won't mention), so this doesn't sound too bad to do IM platforms I won't mention), so this doesn't sound too bad to do
HALF-IMPLEMENTED: Removing stickers won't work. HALF-IMPLEMENTED: Removing reacts won't work.
For future XEPs: For future XEPs:
- https://xmpp.org/extensions/xep-0421.html
Using the occupant ID in semi-anonymous MUCs is a desirable property.
- https://xmpp.org/extensions/xep-0118.html - https://xmpp.org/extensions/xep-0118.html
Informations on what a user is listening to. Matrix doesn't have Informations on what a user is listening to. Matrix doesn't have
good support for status, to be frank. Clients (including KappaChat) good support for status, to be frank. Clients (including KappaChat)
@ -18,6 +19,9 @@ For future XEPs:
As such, if _any_ client devs hear this, please consider adding these, As such, if _any_ client devs hear this, please consider adding these,
(especially if you're a smElement employee!) (especially if you're a smElement employee!)
- https://xmpp.org/extensions/xep-0080.html
Doxxing people over two protocols is great!
- https://xmpp.org/extensions/xep-0084.html - https://xmpp.org/extensions/xep-0084.html
Avatar support would be extremely useful, if just a QoL improvment. Avatar support would be extremely useful, if just a QoL improvment.
Matrix and XMPP both have support for these. Matrix and XMPP both have support for these.
@ -26,6 +30,7 @@ For future XEPs:
Stickers are great. Matrix and XMPP somewhat has support for them, so Stickers are great. Matrix and XMPP somewhat has support for them, so
might be a nice-to-have, and also to push over XMPP support. might be a nice-to-have, and also to push over XMPP support.
Not XEPs, but ideas that needs to be added: Not XEPs, but ideas that _needs_ to be added:
- "GIVE THE PUPPETS APPROPRIATE PLS/ROLES" - Hydro/t4d - "GIVE THE PUPPETS APPROPRIATE PLS/ROLES" - Hydro/t4d
"also it [Bifrost] doesn't respect voice either" "also it [Bifrost] doesn't respect voice either"
- https://www.youtube.com/watch?v=InL414iDZmY

42
src/Commands/Help.c Normal file
View file

@ -0,0 +1,42 @@
#include <Routes.h>
#include <Cytoplasm/Cytoplasm.h>
#include <Cytoplasm/Memory.h>
#include <Cytoplasm/Str.h>
#include <Matrix.h>
#include <AS.h>
CommandHead(CmdHelp, cmd, argp)
{
ParseeCmdArg *args = argp;
ParseeData *data = args->data;
HashMap *json, *event = args->event;
char *profile = StrConcat(4,
"@", data->config->sender_localpart,
":", data->config->homeserver_host
);
char *id = GrabString(event, 1, "room_id");
char *msg;
Free(ASSend(
data->config, id, profile,
"m.room.message",
MatrixCreateNotice("Commands: ")
));
#define X_COMMAND(path, name, desc) { \
msg = StrConcat(3, path, "-", desc);\
Free(ASSend( \
data->config, id, profile, \
"m.room.message", \
MatrixCreateNotice(msg) \
)); \
Free(msg); \
} \
while (0);
COMMANDS
#undef X_COMMAND
Free(profile);
}

53
src/Commands/Stats.c Normal file
View file

@ -0,0 +1,53 @@
#include <Routes.h>
#include <Cytoplasm/Cytoplasm.h>
#include <Cytoplasm/Memory.h>
#include <Cytoplasm/Str.h>
#include <Matrix.h>
#include <AS.h>
CommandHead(CmdStats, cmd, argp)
{
ParseeCmdArg *args = argp;
ParseeData *data = args->data;
HashMap *json, *event = args->event;
char *profile = StrConcat(4,
"@", data->config->sender_localpart,
":", data->config->homeserver_host
);
char *id = GrabString(event, 1, "room_id");
char *msg;
size_t alloc = MemoryAllocated();
size_t kb = alloc >> 10;
size_t mb = kb >> 10;
size_t gb = mb >> 10;
size_t min = gb ? gb : (mb ? mb : (kb ? kb : alloc));
char *unit = gb ? "GB" : (mb ? "MB" : (kb ? "KB" : "B"));
char *l = StrInt(min);
msg = StrConcat(3,
"Information for " NAME " (",
CytoplasmGetVersionStr(), ")"
);
Free(ASSend(
data->config, id, profile,
"m.room.message",
MatrixCreateNotice(msg)
));
Free(msg);
msg = StrConcat(5,
"- Memory usage: ", l, " ", unit,
" (reported by Cytoplasm)"
);
Free(ASSend(
data->config, id, profile,
"m.room.message",
MatrixCreateNotice(msg)
));
Free(msg);
Free(l);
Free(profile);
}

View file

@ -129,6 +129,19 @@ MatrixGetReply(HashMap *event)
"event_id") "event_id")
)); ));
} }
char *
MatrixGetEdit(HashMap *event)
{
if (!event)
{
return NULL;
}
return StrDuplicate(JsonValueAsString(
JsonGet(event, 3, "content",
"m.relates_to", "event_id")
));
}
HashMap * HashMap *
MatrixCreateReplace(char *event, char *body) MatrixCreateReplace(char *event, char *body)
{ {

View file

@ -112,7 +112,6 @@ ParseeBotHandler(ParseeData *data, HashMap *event)
arg.data = data; arg.data = data;
arg.event = event; arg.event = event;
Log(LOG_INFO, "Routing...");
RouteCommand(data->handler, cmd, &arg); RouteCommand(data->handler, cmd, &arg);
} }
end: end:
@ -171,7 +170,7 @@ ParseeMessageHandler(ParseeData *data, HashMap *event)
char *user = GrabString(json, 1, "xmpp_user"); char *user = GrabString(json, 1, "xmpp_user");
char *local = ParseeEncodeMXID(sender); char *local = ParseeEncodeMXID(sender);
XMPPSendPlain(jabber, local, user, body, NULL, NULL, NULL, ev_id, NULL); XMPPSendPlain(jabber, local, user, body, NULL, NULL, NULL, ev_id, NULL, NULL);
DbUnlock(data->db, ref); DbUnlock(data->db, ref);
Free(chat_id); Free(chat_id);
@ -198,21 +197,30 @@ ParseeMessageHandler(ParseeData *data, HashMap *event)
char *stanza = NULL, *sender = NULL; char *stanza = NULL, *sender = NULL;
char *url = GrabString(event, 2, "content", "url"); char *url = GrabString(event, 2, "content", "url");
char *unauth = ParseeToUnauth(data, url); char *unauth = ParseeToUnauth(data, url);
char *unedited_id = MatrixGetEdit(event);
char *origin_id = NULL;
if (reply_id) if (reply_id)
{ {
ParseeGetStanzaInfo(data, chat_id, reply_id, &stanza, &sender); ParseeGetStanzaInfo(data, chat_id, reply_id, &stanza, &sender);
} }
else if (unedited_id)
{
ParseeGetOrigin(data, chat_id, unedited_id, &origin_id);
}
XMPPJoinMUC(jabber, jid, rev); XMPPJoinMUC(jabber, jid, rev);
XMPPSendPlain( XMPPSendPlain(
jabber, jid, muc_id, jabber, jid, muc_id,
xepd ? xepd : body, "groupchat", xepd ? xepd : body, "groupchat",
stanza, sender, ev_id, unauth stanza, sender, ev_id, unauth, origin_id
); );
Free(rev); Free(rev);
Free(name); Free(name);
Free(stanza); Free(stanza);
Free(sender); Free(sender);
Free(unauth); Free(unauth);
Free(origin_id);
Free(unedited_id);
} }
Free(chat_id); Free(chat_id);
Free(muc_id); Free(muc_id);

View file

@ -36,7 +36,7 @@ ParseeInitData(XMPPComponent *comp)
while (0); while (0);
ROUTES ROUTES
#undef X_ROUTE #undef X_ROUTE
#define X_COMMAND(path, name) CommandAddCommand(data->handler, path, name); #define X_COMMAND(path,n,d) CommandAddCommand(data->handler, path, n);
COMMANDS COMMANDS
#undef X_COMMAND #undef X_COMMAND
return data; return data;

View file

@ -599,6 +599,38 @@ end:
DbUnlock(data->db, ref); DbUnlock(data->db, ref);
return ret; return ret;
} }
bool
ParseeGetOrigin(ParseeData *data, char *chat_id, char *ev, char **o)
{
DbRef *ref = NULL;
HashMap *j = NULL;
HashMap *event = NULL;
bool ret = false;
if (!data || !chat_id || !ev || !o)
{
return false;
}
ref = DbLock(data->db, 2, "chats", chat_id);
j = DbJson(ref);
if (!ref)
{
goto end;
}
event = JsonValueAsObject(JsonGet(j, 2, "events", ev));
if (!event)
{
goto end;
}
*o = StrDuplicate(JsonValueAsString(HashMapGet(event, "origin")));
ret = true;
end:
DbUnlock(data->db, ref);
return ret;
}
#include <Cytoplasm/Uri.h> #include <Cytoplasm/Uri.h>
char * char *

View file

@ -8,7 +8,7 @@
#include <XML.h> #include <XML.h>
void void
XMPPSendPlain(XMPPComponent *comp, char *fr, char *to, char *msg, char *type, char *rst, char *rse, char *event_id, char *oob) XMPPSendPlain(XMPPComponent *comp, char *fr, char *to, char *msg, char *type, char *rst, char *rse, char *event_id, char *oob, char *edit)
{ {
XMLElement *message, *body, *data, *parsee; XMLElement *message, *body, *data, *parsee;
char *from; char *from;
@ -65,6 +65,14 @@ XMPPSendPlain(XMPPComponent *comp, char *fr, char *to, char *msg, char *type, ch
/* TODO: Add custom fields depending on the caller's wishes */ /* TODO: Add custom fields depending on the caller's wishes */
} }
if (edit)
{
XMLElement *xedit = XMLCreateTag("replace");
XMLAddAttr(xedit, "xmlns", "urn:xmpp:message-correct:0");
XMLAddAttr(xedit, "id", edit);
XMLAddChild(message, xedit);
}
if (oob) if (oob)
{ {
XMLElement *xoob, *oob_data, *oob_url; XMLElement *xoob, *oob_data, *oob_url;

View file

@ -64,6 +64,12 @@ MessageStanza(ParseeData *args, XMLElement *stanza)
to = ParseeDecodeMXID(HashMapGet(stanza->attrs, "to")); to = ParseeDecodeMXID(HashMapGet(stanza->attrs, "to"));
from = HashMapGet(stanza->attrs, "from"); from = HashMapGet(stanza->attrs, "from");
/* 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.
*
* See: https://xmpp.org/extensions/xep-0421.html */
decode_from = ParseeLookupJID(from); decode_from = ParseeLookupJID(from);
from_matrix = ParseeEncodeJID(args->config, decode_from, true); from_matrix = ParseeEncodeJID(args->config, decode_from, true);
room = ParseeFindDMRoom(args, to, from); room = ParseeFindDMRoom(args, to, from);

View file

@ -28,4 +28,5 @@ extern HashMap * MatrixCreateNickChange(char *nick);
/* Get the event ID of the reply if existent */ /* Get the event ID of the reply if existent */
extern char * MatrixGetReply(HashMap *event); extern char * MatrixGetReply(HashMap *event);
extern char * MatrixGetEdit(HashMap *event);
#endif #endif

View file

@ -165,6 +165,7 @@ extern bool ParseeVerifyStanza(ParseeData *, char *chat_id, char *stanza_id);
/* Gets the stanza ID and sender of an event */ /* Gets the stanza ID and sender of an event */
extern bool ParseeGetStanzaInfo(ParseeData *, char *c_id, char *e, char **st, char **se); extern bool ParseeGetStanzaInfo(ParseeData *, char *c_id, char *e, char **st, char **se);
extern bool ParseeGetOrigin(ParseeData *data, char *chat_id, char *ev, char **o);
/* Sends presence requests for every MUC around as a fake JID */ /* Sends presence requests for every MUC around as a fake JID */
extern void ParseeSendPresence(ParseeData *); extern void ParseeSendPresence(ParseeData *);

View file

@ -14,12 +14,32 @@ typedef struct ParseeCmdArg {
} ParseeCmdArg; } ParseeCmdArg;
/* A list of all commands. */ /* A list of all commands. */
#define COMMANDS X_COMMAND("ban-user", CmdBanUser) \ #define COMMANDS X_COMMAND( \
X_COMMAND("ban-list", CmdNoFlyList) \ "ban-user", CmdBanUser, \
X_COMMAND("list-bans", CmdListBans) \ "Bans a user from a room or a MUC" \
X_COMMAND("set-pl", CmdSetPL) \ ) \
X_COMMAND( \
"ban-list", CmdNoFlyList, \
"Globally bans a user from using Parsee" \
) \
X_COMMAND( \
"list-bans", CmdListBans, \
"Shows all global bans from Parsee" \
) \
X_COMMAND( \
"set-pl", CmdSetPL, \
"Sets the power level in a Parsee room" \
) \
X_COMMAND( \
"help", CmdHelp, \
"Shows the command list" \
) \
X_COMMAND( \
"stats", CmdStats, \
"Shows some Parsee statistics." \
)
#define X_COMMAND(path, name) extern void name(Command *, void *); #define X_COMMAND(path, name,d) extern void name(Command *, void *);
COMMANDS COMMANDS
#undef X_COMMAND #undef X_COMMAND
#define CommandHead(name, cmd, argp) void \ #define CommandHead(name, cmd, argp) void \

View file

@ -28,7 +28,7 @@ extern bool XMPPAuthenticateCompStream(XMPPComponent *comp, char *shared);
extern void XMPPJoinMUC(XMPPComponent *comp, char *fr, char *muc); extern void XMPPJoinMUC(XMPPComponent *comp, char *fr, char *muc);
/* TODO: XMPP stuff, I don't fucking know, I'm not a Jabbernerd. */ /* TODO: XMPP stuff, I don't fucking know, I'm not a Jabbernerd. */
extern void XMPPSendPlain(XMPPComponent *comp, char *fr, char *to, char *msg, char *type, char *rst, char *rse, char *event_id, char *oob); extern void XMPPSendPlain(XMPPComponent *comp, char *fr, char *to, char *msg, char *type, char *rst, char *rse, char *event_id, char *oob, char *id);
/* Closes a raw component stream. */ /* Closes a raw component stream. */
extern void XMPPEndCompStream(XMPPComponent *stream); extern void XMPPEndCompStream(XMPPComponent *stream);