114 lines
3.6 KiB
D
114 lines
3.6 KiB
D
|
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);
|
||
|
}
|
||
|
}
|