|
@@ -1,6 +1,6 @@
|
|
import { Plugin, ICommandData, Command, Event, BotEventData } from "src/model/plugin";
|
|
import { Plugin, ICommandData, Command, Event, BotEventData } from "src/model/plugin";
|
|
import { parseArgs, tryDo, parseDuration, UNIT_MEASURES, Option } from "src/util";
|
|
import { parseArgs, tryDo, parseDuration, UNIT_MEASURES, Option } from "src/util";
|
|
-import { GuildMember, Guild, MessageEmbed, Message, TextChannel, PartialGuildMember } from "discord.js";
|
|
|
|
|
|
+import { GuildMember, Guild, MessageEmbed, Message, TextChannel, PartialGuildMember, User } from "discord.js";
|
|
import { logger } from "src/logging";
|
|
import { logger } from "src/logging";
|
|
import { client } from "src/client";
|
|
import { client } from "src/client";
|
|
import humanizeDuration from "humanize-duration";
|
|
import humanizeDuration from "humanize-duration";
|
|
@@ -154,6 +154,15 @@ export class ViolationPlugin {
|
|
await this.sendViolationMessage(message, info, "User has been muted for server violation");
|
|
await this.sendViolationMessage(message, info, "User has been muted for server violation");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ @Command({
|
|
|
|
+ type: "prefix",
|
|
|
|
+ pattern: "unmute",
|
|
|
|
+ auth: true
|
|
|
|
+ })
|
|
|
|
+ async unmuteUser({ message }: ICommandData): Promise<void> {
|
|
|
|
+ await this.removeTimedViolation(Mute, message, "mute");
|
|
|
|
+ }
|
|
|
|
+
|
|
private getViolationHandler(type: ObjectType<TimedViolation>): TimedViolationStopHandler {
|
|
private getViolationHandler(type: ObjectType<TimedViolation>): TimedViolationStopHandler {
|
|
for (const handler of this.timedViolationHandlers) {
|
|
for (const handler of this.timedViolationHandlers) {
|
|
if (handler.type == type)
|
|
if (handler.type == type)
|
|
@@ -162,6 +171,57 @@ export class ViolationPlugin {
|
|
throw new Error("Couldn't find handler for violation type!");
|
|
throw new Error("Couldn't find handler for violation type!");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ private async removeTimedViolation<T extends TimedViolation>(type: ObjectType<T>, message: Message, command = "violation") {
|
|
|
|
+ if (!message.guild) {
|
|
|
|
+ await message.reply("cannot do in DMs!");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const settingsRepo = getRepository(GuildViolationSettings);
|
|
|
|
+ const settings = await settingsRepo.findOne(message.guild.id);
|
|
|
|
+ if (!settings) {
|
|
|
|
+ message.reply("this guild doesn't have violation settings set up!");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const [, userId] = parseArgs(message.content);
|
|
|
|
+ if (!userId) {
|
|
|
|
+ await message.reply("no user specified!");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ if (userId == message.author.id) {
|
|
|
|
+ await message.reply(`cannot ${command} yourself!`);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const user = await this.resolveUser(userId);
|
|
|
|
+ if (!user) {
|
|
|
|
+ await message.reply("couldn't find the given user!");
|
|
|
|
+ logger.error("Tried to un-%s user %s but couldn't find them by id!", command, userId);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const violationRepo = getRepository(type);
|
|
|
|
+ const existingViolation = await violationRepo.findOne({
|
|
|
|
+ where: {
|
|
|
|
+ guildId: message.guild.id,
|
|
|
|
+ userId: user.id,
|
|
|
|
+ valid: true
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ if (!existingViolation) {
|
|
|
|
+ await message.reply(`user has no existing active ${command}s in the DB!`);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ await violationRepo.update({ id: existingViolation.id } as unknown as FindConditions<T>, { valid: false } as unknown as QueryDeepPartialEntity<T>);
|
|
|
|
+ delete this.jobs[existingViolation.id];
|
|
|
|
+
|
|
|
|
+ const handler = this.getViolationHandler(type);
|
|
|
|
+ await handler.stop(message.guild, user.id, settings);
|
|
|
|
+ await message.reply(`removed ${command} on user!`);
|
|
|
|
+ }
|
|
|
|
+
|
|
private async applyTimedViolation<T extends TimedViolation>(type: ObjectType<T>, info: ViolationInfo, command = "violation", apply: StartViolationFunction, remove: StopViolationFunction) {
|
|
private async applyTimedViolation<T extends TimedViolation>(type: ObjectType<T>, info: ViolationInfo, command = "violation", apply: StartViolationFunction, remove: StopViolationFunction) {
|
|
if (info.dryRun)
|
|
if (info.dryRun)
|
|
return;
|
|
return;
|
|
@@ -230,16 +290,16 @@ export class ViolationPlugin {
|
|
};
|
|
};
|
|
}
|
|
}
|
|
|
|
|
|
- private async resolveUser(guild: Guild, id: string): Promise<GuildMember | undefined> {
|
|
|
|
|
|
+ private async resolveUser(id: string): Promise<User | undefined> {
|
|
const result = MENTION_PATTERN.exec(id);
|
|
const result = MENTION_PATTERN.exec(id);
|
|
if (result) {
|
|
if (result) {
|
|
const userId = result[1];
|
|
const userId = result[1];
|
|
- const fetchResult = await tryDo(guild.members.fetch(userId));
|
|
|
|
|
|
+ const fetchResult = await tryDo(client.bot.users.fetch(userId));
|
|
if (fetchResult.ok)
|
|
if (fetchResult.ok)
|
|
return fetchResult.result;
|
|
return fetchResult.result;
|
|
}
|
|
}
|
|
|
|
|
|
- const fetchResult = await tryDo(guild.members.fetch(id));
|
|
|
|
|
|
+ const fetchResult = await tryDo(client.bot.users.fetch(id));
|
|
if (!fetchResult.ok)
|
|
if (!fetchResult.ok)
|
|
return undefined;
|
|
return undefined;
|
|
return fetchResult.result;
|
|
return fetchResult.result;
|
|
@@ -279,14 +339,21 @@ export class ViolationPlugin {
|
|
return { ok: false };
|
|
return { ok: false };
|
|
}
|
|
}
|
|
|
|
|
|
- const member = await this.resolveUser(message.guild, userId);
|
|
|
|
|
|
+ const user = await this.resolveUser(userId);
|
|
|
|
|
|
- if (!member) {
|
|
|
|
|
|
+ if (!user) {
|
|
await message.reply("couldn't find the given user!");
|
|
await message.reply("couldn't find the given user!");
|
|
logger.error("Tried to %s user %s but couldn't find them by id!", command, userId);
|
|
logger.error("Tried to %s user %s but couldn't find them by id!", command, userId);
|
|
return { ok: false };
|
|
return { ok: false };
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ const memberResolve = await tryDo(message.guild.members.fetch(user));
|
|
|
|
+ if (!memberResolve.ok) {
|
|
|
|
+ await message.reply("user is not member of the server anymore!");
|
|
|
|
+ logger.error("Tried to %s user %s but they are not on the server anymore!", command, userId);
|
|
|
|
+ return { ok: false };
|
|
|
|
+ }
|
|
|
|
+
|
|
let durationMs = parseDuration(duration);
|
|
let durationMs = parseDuration(duration);
|
|
let reasonArray = rest;
|
|
let reasonArray = rest;
|
|
|
|
|
|
@@ -306,7 +373,7 @@ export class ViolationPlugin {
|
|
duration: durationMs,
|
|
duration: durationMs,
|
|
endDate: endDate,
|
|
endDate: endDate,
|
|
guild: message.guild,
|
|
guild: message.guild,
|
|
- member: member,
|
|
|
|
|
|
+ member: memberResolve.result,
|
|
reason: reason,
|
|
reason: reason,
|
|
settings: settings,
|
|
settings: settings,
|
|
dryRun: dryRun,
|
|
dryRun: dryRun,
|