[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

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")
));
}
char *
MatrixGetEdit(HashMap *event)
{
if (!event)
{
return NULL;
}
return StrDuplicate(JsonValueAsString(
JsonGet(event, 3, "content",
"m.relates_to", "event_id")
));
}
HashMap *
MatrixCreateReplace(char *event, char *body)
{

View file

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

View file

@ -36,7 +36,7 @@ ParseeInitData(XMPPComponent *comp)
while (0);
ROUTES
#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
#undef X_COMMAND
return data;

View file

@ -599,6 +599,38 @@ end:
DbUnlock(data->db, ref);
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>
char *

View file

@ -8,7 +8,7 @@
#include <XML.h>
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;
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 */
}
if (edit)
{
XMLElement *xedit = XMLCreateTag("replace");
XMLAddAttr(xedit, "xmlns", "urn:xmpp:message-correct:0");
XMLAddAttr(xedit, "id", edit);
XMLAddChild(message, xedit);
}
if (oob)
{
XMLElement *xoob, *oob_data, *oob_url;

View file

@ -64,6 +64,12 @@ MessageStanza(ParseeData *args, XMLElement *stanza)
to = ParseeDecodeMXID(HashMapGet(stanza->attrs, "to"));
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);
from_matrix = ParseeEncodeJID(args->config, decode_from, true);
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 */
extern char * MatrixGetReply(HashMap *event);
extern char * MatrixGetEdit(HashMap *event);
#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 */
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 */
extern void ParseeSendPresence(ParseeData *);

View file

@ -14,12 +14,32 @@ typedef struct ParseeCmdArg {
} ParseeCmdArg;
/* A list of all commands. */
#define COMMANDS X_COMMAND("ban-user", CmdBanUser) \
X_COMMAND("ban-list", CmdNoFlyList) \
X_COMMAND("list-bans", CmdListBans) \
X_COMMAND("set-pl", CmdSetPL) \
#define COMMANDS X_COMMAND( \
"ban-user", CmdBanUser, \
"Bans a user from a room or a MUC" \
) \
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
#undef X_COMMAND
#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);
/* 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. */
extern void XMPPEndCompStream(XMPPComponent *stream);