From e24b163a34d44233a872cd3d57834d6e382eb492 Mon Sep 17 00:00:00 2001 From: powermaker450 Date: Mon, 21 Oct 2024 12:37:14 -0400 Subject: [PATCH] Separate user and confession bans --- src/commands/confessmod.ts | 85 ++++++++++++++++++++++++++++++-------- src/storeman/client.ts | 30 ++++++++++++-- src/storeman/types.ts | 8 +++- 3 files changed, 102 insertions(+), 21 deletions(-) diff --git a/src/commands/confessmod.ts b/src/commands/confessmod.ts index 6441b71..20a7246 100644 --- a/src/commands/confessmod.ts +++ b/src/commands/confessmod.ts @@ -18,11 +18,16 @@ import { ChatInputCommandInteraction, + heading, + HeadingLevel, + inlineCode, + italic, PermissionFlagsBits, SlashCommandBuilder } from "discord.js"; import { dt } from "../main"; import Logger from "../utils/Logger"; +import { BanReason } from "../storeman"; const logger = new Logger("(/) confessban"); @@ -33,7 +38,7 @@ export const data = new SlashCommandBuilder() .addSubcommand(ban => ban .setName("ban") - .setDescription("Ban a user from confessions") + .setDescription("Ban an ID from confessions") .addStringOption(option => option .setName("id") @@ -43,6 +48,14 @@ export const data = new SlashCommandBuilder() .setRequired(true) ) ) + .addSubcommand(banuser => + banuser + .setName("banuser") + .setDescription("Ban a user from confessions") + .addUserOption(user => + user.setName("user").setDescription("The user to ban").setRequired(true) + ) + ) .addSubcommand(list => list.setName("list").setDescription("Show the list of banned users") ) @@ -78,7 +91,7 @@ export async function execute(interaction: ChatInputCommandInteraction) { } } - const result = dt.addBan(guildId, confessionId); + const result = dt.addBanById(guildId, confessionId); try { return result @@ -93,34 +106,72 @@ export async function execute(interaction: ChatInputCommandInteraction) { } catch (err) { logger.error("A ban interaction error occured:", err); } + // /confessmod banuser + } else if (interaction.options.getSubcommand() === "banuser") { + const { id: userId } = interaction.options.getUser("user")!; + + const result = dt.addBanByUser(guildId, userId); + + try { + return result + ? interaction.reply({ + content: "User was banned.", + ephemeral: true + }) + : interaction.reply({ + content: "How did we get here? (An error occured.)}", + ephemeral: true + }); + } catch (err) { + logger.error("A banuser interaction error occured:", err); + } // /confessmod list } else if (interaction.options.getSubcommand() === "list") { const bannedMembers = dt.getBans(guildId); - let content = bannedMembers.length - ? "Banned Members:\n" - : "There are no banned members."; + const determineContent = () => { + if (!bannedMembers.length) { + return "There are no bans."; + } - // For each member, add them to the message content. - // It will end up looking something like this: - // - // Banned Members: - // - // @user1 | a1b2 - // @user2 | c3d4 - // @user3 | e5f6 - // - for (const member of bannedMembers) { - content += `\n<@${member.user}> | \`${member.confessionId}\``; + let userHead = heading("Users:", HeadingLevel.Two); + let userCount = false; + + let idHead = "\n" + heading("Confessions:", HeadingLevel.Two); + let idCount = false; + for (const member of bannedMembers) { + + if (member.method === BanReason.ByUser) { + userHead += "\n" + `<@${member.user}>`; + userCount = true; + } else if (member.method === BanReason.ById) { + const confession = dt.getConfession(guildId, member.confessionId!)!; + idHead += `\nConfession ${inlineCode(member.confessionId!)}: ${italic(confession.content)}`; + idCount = true; + } + } + + // If there are users and confessions use both headers, otherwise use whichever is populated + if (userCount && idCount) { + return userHead + idHead; + } else { + return userCount + ? userHead + : idHead; + } } try { return interaction.reply({ - content: content, + content: determineContent(), ephemeral: true }); } catch (err) { logger.error("A banlist interaction error occured:", err); + return interaction.reply({ + content: "A server-side error occurred when getting the ban list.", + ephemeral: true + }); } // /confessmod pardon } else if (interaction.options.getSubcommand() === "pardon") { diff --git a/src/storeman/client.ts b/src/storeman/client.ts index 451b85b..1e883dc 100644 --- a/src/storeman/client.ts +++ b/src/storeman/client.ts @@ -18,7 +18,13 @@ import fs from "fs"; import crypto from "crypto"; -import { Confession, ConfessionBan, GuildData, GuildSettings } from "./types"; +import { + BanReason, + Confession, + ConfessionBan, + GuildData, + GuildSettings +} from "./types"; import { DATA_DIR } from "./config"; import { CommandInteraction, Message } from "discord.js"; import Logger from "../utils/Logger"; @@ -254,7 +260,7 @@ export class StoreMan { } // Attempts to ban a user from confessions. - public addBan(guildId: string, confessionId: string): boolean { + public addBanById(guildId: string, confessionId: string): boolean { const confession = this.getConfession(guildId, confessionId); for (const guild of this.data) { @@ -264,7 +270,8 @@ export class StoreMan { !this.isBannedByUser(guildId, confession.authorId) && guild.settings.bans.push({ user: confession.authorId, - confessionId: confessionId + confessionId: confessionId, + method: BanReason.ById }); this.saveFile(); @@ -276,6 +283,23 @@ export class StoreMan { return false; } + public addBanByUser(guildId: string, userId: string): boolean { + for (const guild of this.data) { + if (guild.id === guildId) { + // Only add the user to the ban list if they aren't banned already + !this.isBannedByUser(guildId, userId) && guild.settings.bans.push({ + user: userId, + method: BanReason.ByUser + }); + + this.saveFile(); + return true; + } + } + + return false; + } + // Attempts to pardon a user from a ban. If sucessfully completed, returns true, false if otherwise. public removeBan(guildId: string, confessionId: string): boolean { for (const guild of this.data) { diff --git a/src/storeman/types.ts b/src/storeman/types.ts index 78e2974..df8f8b0 100644 --- a/src/storeman/types.ts +++ b/src/storeman/types.ts @@ -25,9 +25,15 @@ export interface Confession { attachment?: string; } +export enum BanReason { + ById, + ByUser +} + export interface ConfessionBan { user: string; - confessionId: string; + confessionId?: string; + method: BanReason; } export interface GuildSettings {