neptune/source/listener.d

114 lines
3.6 KiB
D
Raw Permalink Normal View History

2025-03-11 01:01:54 +03:00
module listener;
import api, api_data;
import commands.util;
import main: db;
import util;
import std.stdio: writeln;
import core.thread;
import asdf: deserialize;
__gshared string syncUrl, initialBatch;
void listen(Modules...)() {
static MSG helpgen() {
MSG msg;
static foreach (mod; Modules) {
static foreach (member; __traits(allMembers, mod)) {
static foreach (attr; __traits(getAttributes, __traits(getMember, mod, member))) {
static if (is(typeof(attr) == Command)) msg.body ~= member ~ ": " ~ attr.description ~ '\n';
}
}
}
return msg;
}
auto content = Sync();
content.next_batch = initialBatch;
for (;;) {
string bthUrl = syncUrl ~ content.next_batch;
try {
content = mkhsrq(bthUrl).body.deserialize!Sync;
db.exec("update client set latest_batch = ?", content.next_batch);
} catch (Exception e) { writeln(e.msg); continue; }
// https://github.com/trikko/serverino/blob/3e3e6273a5aaa32615ae9d007a1a83877bc23ab4/source/serverino/worker.d#L168
new Thread(delegate {
foreach (room, _; content.rooms.invite) {
writeln("Joining to room: ", room);
mkhsrq("/_matrix/client/v3/rooms/"~room~"/join", "POST", "{}");
send(MSG("Йа криведко"), room);
fetchMembers(room);
}
foreach (room, roomContent; content.rooms.join) {
foreach(event; roomContent.timeline.events) {
if (event.type == "m.room.message") {
try {
auto evt = deserialize!MSG(event.content.raw);
if (!evt.body.length) break;
event.room = room;
auto argz = parseMsg(evt.body);
if (argz.command == "hlp") {
auto h = helpgen;
h.relates.reply.event_id = event.event_id;
send(h, room);
break;
}
static foreach (mod; Modules) {
static foreach (member; __traits(allMembers, mod)) {
// if (argz.command == member) {
foreach (attr; __traits(getAttributes, __traits(getMember, mod, member))) {
if (is(typeof(attr) == Command)
&& (argz.command == member
|| (argz.command == attr.name && attr.name != null)))
{
alias command = __traits(getMember, mod, member);
static if (is(typeof(command) == function))
auto content = command(argz, &event);
else static if (__traits(isStaticArray, command))
auto content = MSG(command[0], command[1]);
else auto content = MSG(command);
content.relates.reply.event_id = event.event_id;
send(content, room);
}
}
// }
}
}
} catch (Exception e) {
writeln(e.msg);
send(MSG(e.msg), room);
}
}
else if (event.type == "m.room.power_levels") {
auto pls = deserialize!(State.PowerLevels)(event.content.raw);
foreach (user, pl; pls.users) {
auto q = db.query("select pl from room_pls where room = ? and user = ?", room, user);
if (q.step) {
if (q.get!int != pl)
db.exec("update room_pls set pl = ? where room = ? and user = ?", pl, room, user);
} else db.exec("insert into room_pls (room, user, pl) values (?, ?, ?)", room, user, pl);
}
}
// else if (event.type == "m.room.encrypted") {
// import encryption;
// auto e = deserialize!Encrypted(event.content.raw);
// decrypt(&e);
// }
}
}
}).start;
}
}
void fetchMembers(string room) {
auto state = getState!(State.PowerLevels)(room, "m.room.power_levels");
foreach (user, pl; state.users) {
db.exec("insert into room_pls (room, user, pl) values (?, ?, ?)", room, user, pl);
}
}