neptune/source/commands/moderation.d

128 lines
3.8 KiB
D

module commands.moderation;
import util, api_data, api;
import asdf;
import core.stdc.time: time;
import commands.util;
import main: db;
enum TimeErr: int {
@("Not enough arguments") NotEnoughArguments = -1,
@("Invalid date") InvalidDate = -2,
@("Invalid unit") InvalidUnit = -3
}
int parseTime(string str) @nogc pure {
if (str.length < 2) return TimeErr.NotEnoughArguments;
foreach (short c; str[0..$-1])
if (!(c >= 48 && c <= 57))
return TimeErr.InvalidDate;
static foreach(unit; __traits(allMembers, Time))
if (str[$-1] == __traits(getAttributes, __traits(getMember, Time, unit))[0])
return strToInt(str[0..$-1]) * __traits(getMember, Time, unit);
return TimeErr.InvalidUnit;
}
@Command("Admin tools")
MSG nctl(Arguments arg, EventWithoutRoomID* evt) {
if (arg.parsed.length != 2) return MSG("❌️ Not enough arguments");
if (getUsrPL(evt.room, evt.sender) < 50) return MSG("❌️ Unauthorized");
db.exec("create table if not exists nctl (room string, user string, nc string, type string, unt integer)");
bool wd, err;
string cntnt, type;
int dur;
auto durStr = arg.getArg("D");
if (durStr) dur = parseTime(durStr);
if (dur < 0) {
static foreach(Terr; __traits(allMembers, TimeErr)) {
if (dur == __traits(getMember, TimeErr, Terr)) {
return MSG("💥 " ~ __traits(getAttributes, __traits(getMember, TimeErr, Terr))[0]);
}
}
}
void mrq(string ep) {
short rq = mkhsrq(
"/_matrix/client/v3/rooms/"~evt.room~'/'~ep,
"POST",
Moderate(arg.parsed[1], "Moderated by "~evt.sender).serializeToJson
).status;
if (rq != 200) err = true;
}
void setpl(short pl) {
auto pls = State.PowerLevels(getUsrsPLs(evt.room));
if (dur) cntnt = pls.serializeToJson;
pls.users[arg.parsed[1]] = pl;
state(evt.room, "m.room.power_levels", pls);
}
bool c() {
if (db.query("select type from nctl where room = ? and user = ?",evt.room, arg.parsed[1]).step)
return true;
return false;
}
switch (arg.parsed[0]) {
case "ban":
wd = true;
mrq("ban");
break;
case "kick", "unban":
mrq(arg.parsed[0]);
break;
case "mute":
if(c) goto e;
type = "m.room.power_levels";
wd = true;
setpl(-100);
break;
case "unmute": setpl(0); break;
case "acl", "delete-acl":
State.ACL acls = getState!(State.ACL)(evt.room, "m.room.server_acl");
if (dur) cntnt = acls.serializeToJson;
if (arg.parsed[0] == "acl") {
if(c) goto e;
type = "m.room.server_acl";
wd = true;
acls.deny ~= arg.parsed[1];
} else {
foreach (n, srv; acls.deny) {
if (srv == arg.parsed[1])
acls.deny = acls.deny[0..n] ~ acls.deny[n+1..$];
}
}
state(evt.room, "m.room.server_acl", acls);
break;
default: return MSG("❓️ Invalid argument");
}
if (err) return MSG("💥 Something went wrong");
if (dur && wd) {
import std.datetime.systime: SysTime;
auto untill = time(null) + dur;
db.exec(
"insert into nctl (room, user, nc, type, unt) values (?,?,?,?,?)",
evt.room,
arg.parsed[1],
cntnt,
type,
untill
);
return MSG("✅️ Blocked untill " ~ SysTime.fromUnixTime(untill).toSimpleString);
}
return MSG("✅️");
e: return MSG("💥 Already moderated!");
}