Compare commits
3 commits
main
...
feat/sqlit
Author | SHA1 | Date | |
---|---|---|---|
4c1698e12f | |||
34118d5e47 | |||
97abd1fcee |
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -1,4 +1,6 @@
|
|||
.env
|
||||
node_modules/
|
||||
dist/
|
||||
persist/
|
||||
dist/
|
||||
prisma/migrations/
|
||||
prisma/persist/
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
"author": "powermaker450",
|
||||
"license": "AGPLv3",
|
||||
"dependencies": {
|
||||
"@prisma/client": "^6.2.1",
|
||||
"chalk": "^4.1.0",
|
||||
"discord.js": "^14.16.3",
|
||||
"dotenv": "^16.4.5",
|
||||
|
@ -21,6 +22,7 @@
|
|||
"devDependencies": {
|
||||
"@types/node": "^22.7.5",
|
||||
"prettier": "^3.3.3",
|
||||
"prisma": "^6.2.1",
|
||||
"typescript": "^5.6.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,9 @@ importers:
|
|||
|
||||
.:
|
||||
dependencies:
|
||||
'@prisma/client':
|
||||
specifier: ^6.2.1
|
||||
version: 6.2.1(prisma@6.2.1)
|
||||
chalk:
|
||||
specifier: ^4.1.0
|
||||
version: 4.1.2
|
||||
|
@ -27,6 +30,9 @@ importers:
|
|||
prettier:
|
||||
specifier: ^3.3.3
|
||||
version: 3.3.3
|
||||
prisma:
|
||||
specifier: ^6.2.1
|
||||
version: 6.2.1
|
||||
typescript:
|
||||
specifier: ^5.6.3
|
||||
version: 5.6.3
|
||||
|
@ -61,6 +67,30 @@ packages:
|
|||
resolution: {integrity: sha512-PZ+vLpxGCRtmr2RMkqh8Zp+BenUaJqlS6xhgWKEZcgC/vfHLEzpHtKkB0sl3nZWpwtcKk6YWy+pU3okL2I97FA==}
|
||||
engines: {node: '>=16.11.0'}
|
||||
|
||||
'@prisma/client@6.2.1':
|
||||
resolution: {integrity: sha512-msKY2iRLISN8t5X0Tj7hU0UWet1u0KuxSPHWuf3IRkB4J95mCvGpyQBfQ6ufcmvKNOMQSq90O2iUmJEN2e5fiA==}
|
||||
engines: {node: '>=18.18'}
|
||||
peerDependencies:
|
||||
prisma: '*'
|
||||
peerDependenciesMeta:
|
||||
prisma:
|
||||
optional: true
|
||||
|
||||
'@prisma/debug@6.2.1':
|
||||
resolution: {integrity: sha512-0KItvt39CmQxWkEw6oW+RQMD6RZ43SJWgEUnzxN8VC9ixMysa7MzZCZf22LCK5DSooiLNf8vM3LHZm/I/Ni7bQ==}
|
||||
|
||||
'@prisma/engines-version@6.2.0-14.4123509d24aa4dede1e864b46351bf2790323b69':
|
||||
resolution: {integrity: sha512-7tw1qs/9GWSX6qbZs4He09TOTg1ff3gYsB3ubaVNN0Pp1zLm9NC5C5MZShtkz7TyQjx7blhpknB7HwEhlG+PrQ==}
|
||||
|
||||
'@prisma/engines@6.2.1':
|
||||
resolution: {integrity: sha512-lTBNLJBCxVT9iP5I7Mn6GlwqAxTpS5qMERrhebkUhtXpGVkBNd/jHnNJBZQW4kGDCKaQg/r2vlJYkzOHnAb7ZQ==}
|
||||
|
||||
'@prisma/fetch-engine@6.2.1':
|
||||
resolution: {integrity: sha512-OO7O9d6Mrx2F9i+Gu1LW+DGXXyUFkP7OE5aj9iBfA/2jjDXEJjqa9X0ZmM9NZNo8Uo7ql6zKm6yjDcbAcRrw1A==}
|
||||
|
||||
'@prisma/get-platform@6.2.1':
|
||||
resolution: {integrity: sha512-zp53yvroPl5m5/gXYLz7tGCNG33bhG+JYCm74ohxOq1pPnrL47VQYFfF3RbTZ7TzGWCrR3EtoiYMywUBw7UK6Q==}
|
||||
|
||||
'@sapphire/async-queue@1.5.3':
|
||||
resolution: {integrity: sha512-x7zadcfJGxFka1Q3f8gCts1F0xMwCKbZweM85xECGI0hBTeIZJGGCrHgLggihBoprlQ/hBmDR5LKfIPqnmHM3w==}
|
||||
engines: {node: '>=v14.0.0', npm: '>=7.0.0'}
|
||||
|
@ -118,6 +148,11 @@ packages:
|
|||
fast-deep-equal@3.1.3:
|
||||
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
||||
|
||||
fsevents@2.3.3:
|
||||
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
|
||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||
os: [darwin]
|
||||
|
||||
has-flag@4.0.0:
|
||||
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
@ -139,6 +174,11 @@ packages:
|
|||
engines: {node: '>=14'}
|
||||
hasBin: true
|
||||
|
||||
prisma@6.2.1:
|
||||
resolution: {integrity: sha512-hhyM0H13pQleQ+br4CkzGizS5I0oInoeTw3JfLw1BRZduBSQxPILlJLwi+46wZzj9Je7ndyQEMGw/n5cN2fknA==}
|
||||
engines: {node: '>=18.18'}
|
||||
hasBin: true
|
||||
|
||||
supports-color@7.2.0:
|
||||
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
|
||||
engines: {node: '>=8'}
|
||||
|
@ -225,6 +265,31 @@ snapshots:
|
|||
- bufferutil
|
||||
- utf-8-validate
|
||||
|
||||
'@prisma/client@6.2.1(prisma@6.2.1)':
|
||||
optionalDependencies:
|
||||
prisma: 6.2.1
|
||||
|
||||
'@prisma/debug@6.2.1': {}
|
||||
|
||||
'@prisma/engines-version@6.2.0-14.4123509d24aa4dede1e864b46351bf2790323b69': {}
|
||||
|
||||
'@prisma/engines@6.2.1':
|
||||
dependencies:
|
||||
'@prisma/debug': 6.2.1
|
||||
'@prisma/engines-version': 6.2.0-14.4123509d24aa4dede1e864b46351bf2790323b69
|
||||
'@prisma/fetch-engine': 6.2.1
|
||||
'@prisma/get-platform': 6.2.1
|
||||
|
||||
'@prisma/fetch-engine@6.2.1':
|
||||
dependencies:
|
||||
'@prisma/debug': 6.2.1
|
||||
'@prisma/engines-version': 6.2.0-14.4123509d24aa4dede1e864b46351bf2790323b69
|
||||
'@prisma/get-platform': 6.2.1
|
||||
|
||||
'@prisma/get-platform@6.2.1':
|
||||
dependencies:
|
||||
'@prisma/debug': 6.2.1
|
||||
|
||||
'@sapphire/async-queue@1.5.3': {}
|
||||
|
||||
'@sapphire/shapeshift@4.0.0':
|
||||
|
@ -287,6 +352,9 @@ snapshots:
|
|||
|
||||
fast-deep-equal@3.1.3: {}
|
||||
|
||||
fsevents@2.3.3:
|
||||
optional: true
|
||||
|
||||
has-flag@4.0.0: {}
|
||||
|
||||
lodash.snakecase@4.1.1: {}
|
||||
|
@ -299,6 +367,12 @@ snapshots:
|
|||
|
||||
prettier@3.3.3: {}
|
||||
|
||||
prisma@6.2.1:
|
||||
dependencies:
|
||||
'@prisma/engines': 6.2.1
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.3
|
||||
|
||||
supports-color@7.2.0:
|
||||
dependencies:
|
||||
has-flag: 4.0.0
|
||||
|
|
38
prisma/schema.prisma
Normal file
38
prisma/schema.prisma
Normal file
|
@ -0,0 +1,38 @@
|
|||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "sqlite"
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
model Guild {
|
||||
guildId String @id
|
||||
confessChannel String @unique
|
||||
modChannel String? @unique
|
||||
|
||||
confessions Confession[]
|
||||
bans Ban[]
|
||||
}
|
||||
|
||||
model Confession {
|
||||
id String @id
|
||||
messageId String @unique
|
||||
author String
|
||||
authorId String
|
||||
guildId String
|
||||
content String
|
||||
attachment String?
|
||||
|
||||
guild Guild @relation(fields: [guildId], references: [guildId])
|
||||
}
|
||||
|
||||
model Ban {
|
||||
authorId String @id
|
||||
guildId String
|
||||
confessionId String?
|
||||
reason Int
|
||||
|
||||
guild Guild @relation(fields: [guildId], references: [guildId])
|
||||
}
|
|
@ -92,7 +92,7 @@ export async function execute(interaction: ChatInputCommandInteraction) {
|
|||
if (interaction.options.getSubcommand() === "ban") {
|
||||
const confessionId = interaction.options.getString("id")!;
|
||||
|
||||
if (dt.isBannedById(guildId, confessionId)) {
|
||||
if (await dt.isBannedById(guildId, confessionId)) {
|
||||
return interaction
|
||||
.reply({
|
||||
content: "That user is already banned!",
|
||||
|
@ -101,7 +101,7 @@ export async function execute(interaction: ChatInputCommandInteraction) {
|
|||
.catch(err => logger.error("A ban interaction error occured:", err));
|
||||
}
|
||||
|
||||
const result = dt.addBanById(guildId, confessionId);
|
||||
const result = await dt.addBanById(guildId, confessionId);
|
||||
|
||||
return interaction
|
||||
.reply({
|
||||
|
@ -116,7 +116,7 @@ export async function execute(interaction: ChatInputCommandInteraction) {
|
|||
} else if (interaction.options.getSubcommand() === "banuser") {
|
||||
const { id: userId } = interaction.options.getUser("user")!;
|
||||
|
||||
const result = dt.addBanByUser(guildId, userId);
|
||||
const result = await dt.addBanByUser(guildId, userId);
|
||||
|
||||
return interaction
|
||||
.reply({
|
||||
|
@ -127,9 +127,9 @@ export async function execute(interaction: ChatInputCommandInteraction) {
|
|||
|
||||
// /confessmod list
|
||||
} else if (interaction.options.getSubcommand() === "list") {
|
||||
const bannedMembers = dt.getBans(guildId);
|
||||
const bannedMembers = await dt.getBans(guildId);
|
||||
|
||||
const determineContent = () => {
|
||||
const determineContent = async () => {
|
||||
if (!bannedMembers.length) {
|
||||
return "There are no bans.";
|
||||
}
|
||||
|
@ -140,11 +140,11 @@ export async function execute(interaction: ChatInputCommandInteraction) {
|
|||
let idHead = "\n" + heading("Confessions:", HeadingLevel.Two);
|
||||
let idCount = false;
|
||||
for (const member of bannedMembers) {
|
||||
if (member.method === BanReason.ByUser) {
|
||||
userHead += "\n" + `<@${member.user}>`;
|
||||
if (member.reason === BanReason.ByUser) {
|
||||
userHead += "\n" + `<@${member.authorId}>`;
|
||||
userCount = true;
|
||||
} else if (member.method === BanReason.ById) {
|
||||
const confession = dt.getConfession(guildId, member.confessionId!)!;
|
||||
} else if (member.reason === BanReason.ById) {
|
||||
const confession = (await dt.getConfession(guildId, member.confessionId!))!;
|
||||
idHead += `\nConfession ${inlineCode(member.confessionId!)}: ${italic(confession.content)}`;
|
||||
idCount = true;
|
||||
}
|
||||
|
@ -160,14 +160,14 @@ export async function execute(interaction: ChatInputCommandInteraction) {
|
|||
|
||||
return interaction
|
||||
.reply({
|
||||
content: determineContent(),
|
||||
content: await determineContent(),
|
||||
...messageOpts
|
||||
})
|
||||
.catch(err => logger.error("A banlist interaction error occured:", err));
|
||||
|
||||
// /confessmod pardon <id>
|
||||
} else if (interaction.options.getSubcommand() === "pardon") {
|
||||
const result = dt.removeBanById(
|
||||
const result = await dt.removeBanById(
|
||||
guildId,
|
||||
interaction.options.getString("id")!
|
||||
);
|
||||
|
@ -185,7 +185,7 @@ export async function execute(interaction: ChatInputCommandInteraction) {
|
|||
} else if (interaction.options.getSubcommand() === "pardonuser") {
|
||||
const { id: userId } = interaction.options.getUser("user")!;
|
||||
|
||||
const result = dt.removeBanByUser(guildId, userId);
|
||||
const result = await dt.removeBanByUser(guildId, userId);
|
||||
|
||||
return interaction
|
||||
.reply({
|
||||
|
|
|
@ -42,7 +42,7 @@ export async function execute(interaction: CommandInteraction) {
|
|||
const { id: guildId } = interaction.guild!;
|
||||
const { displayName: username } = interaction.user;
|
||||
|
||||
if (dt.checkSetup(guildId)) {
|
||||
if (await dt.checkSetup(guildId)) {
|
||||
return interaction
|
||||
.reply({
|
||||
content: "This guild has already been set up!",
|
||||
|
|
|
@ -38,7 +38,7 @@ export async function deleteConfession(
|
|||
const { id: guildId } = interaction.guild!;
|
||||
const { id: userId } = interaction.user;
|
||||
|
||||
const result = dt.getConfession(guildId, idVal);
|
||||
const result = await dt.getConfession(guildId, idVal);
|
||||
// If there is a result, and the user is either an author or has manage messages
|
||||
const allowedByUser = result && result.authorId === userId;
|
||||
const allowedByMod =
|
||||
|
@ -48,8 +48,8 @@ export async function deleteConfession(
|
|||
// If a confession is found with the given ID, check if the user is the one that posted it, and delete it if they are.
|
||||
// Otherwise, don't let the user delete anything.
|
||||
if (allowedByUser || allowedByMod) {
|
||||
const confession = dt.getConfession(guildId, idVal)!.messageId;
|
||||
const channelId = dt.getGuildInfo(guildId)!.settings.confessChannel;
|
||||
const confession = (await dt.getConfession(guildId, idVal))!.messageId;
|
||||
const channelId = (await dt.getGuildInfo(guildId))!.confessChannel;
|
||||
const emptyEmbed = new EmbedBuilder()
|
||||
.setColor(getRandomColor())
|
||||
.setTitle("Confession Deleted")
|
||||
|
|
|
@ -27,7 +27,7 @@ export async function submitConfession(
|
|||
const { id: userId, displayName: username } = interaction.user;
|
||||
|
||||
// If the user is banned in this guild, don't let them post
|
||||
if (dt.isBannedByUser(guildId, userId)) {
|
||||
if (await dt.isBannedByUser(guildId, userId)) {
|
||||
return interaction.reply({
|
||||
content: "You are banned from confessions in this server!",
|
||||
...messageOpts
|
||||
|
@ -35,7 +35,7 @@ export async function submitConfession(
|
|||
}
|
||||
|
||||
// If no guild info is present for this guild, don't let the user post
|
||||
if (!dt.getGuildInfo(guildId)) {
|
||||
if (!(await dt.getGuildInfo(guildId))) {
|
||||
return interaction.reply({
|
||||
content:
|
||||
"The bot hasn't been set up yet! Ask the server admins to set it up.",
|
||||
|
@ -43,8 +43,7 @@ export async function submitConfession(
|
|||
});
|
||||
}
|
||||
|
||||
const confessChannel = dt.getGuildInfo(guildId)!.settings.confessChannel;
|
||||
const adminChannel = dt.getGuildInfo(guildId)?.settings.modChannel;
|
||||
const { confessChannel, modChannel } = (await dt.getGuildInfo(guildId))!;
|
||||
|
||||
const isAttachment = (text: string | null) =>
|
||||
text && (text.startsWith("http://") || text.startsWith("https://"));
|
||||
|
@ -125,10 +124,10 @@ export async function submitConfession(
|
|||
components: [actionRow]
|
||||
});
|
||||
|
||||
adminChannel &&
|
||||
(await (BotClient.channels.cache.get(adminChannel!) as TextChannel).send({
|
||||
modChannel &&
|
||||
(BotClient.channels.cache.get(modChannel!) as TextChannel).send({
|
||||
embeds: [adminConfessionEmbed]
|
||||
}));
|
||||
});
|
||||
|
||||
const fields: readonly [Message, string, string, string, string] = [
|
||||
message,
|
||||
|
@ -142,23 +141,12 @@ export async function submitConfession(
|
|||
? dt.addConfession(...fields, attachmentContent)
|
||||
: dt.addConfession(...fields);
|
||||
|
||||
const confessionsLength = dt.getGuildInfo(guildId)!.confessions.length;
|
||||
const confessions = await dt.getConfessions(guildId);
|
||||
|
||||
// If there are 2 or more confessions, remove the previous confession's button components
|
||||
if (confessionsLength >= 2) {
|
||||
(BotClient.channels.cache.get(confessChannel) as TextChannel).messages
|
||||
.fetch(
|
||||
dt.getGuildInfo(guildId)!.confessions[confessionsLength - 2].messageId
|
||||
)
|
||||
.then(message => {
|
||||
message.edit({ components: [] });
|
||||
})
|
||||
.catch(err => {
|
||||
logger.error(
|
||||
"An error occured removing embeds from the previous message:",
|
||||
err
|
||||
);
|
||||
});
|
||||
if (confessions.length >= 2) {
|
||||
const previousMessage = await (BotClient.channels.cache.get(confessChannel) as TextChannel).messages.fetch(confessions[confessions.length - 2].messageId);
|
||||
previousMessage.edit({ components: [] }).catch(err => logger.error("An error occured removing embeds from the previous message:", err));
|
||||
}
|
||||
|
||||
return interaction.reply({
|
||||
|
|
|
@ -47,7 +47,7 @@ export async function execute(interaction: ContextMenuCommandInteraction) {
|
|||
});
|
||||
}
|
||||
|
||||
const { id: confessionId } = dt.getConfessionById(guildId!, targetId)!;
|
||||
const { id: confessionId } = (await dt.getConfessionById(guildId!, targetId))!;
|
||||
|
||||
try {
|
||||
deleteConfession(interaction, confessionId);
|
||||
|
|
24
src/main.ts
24
src/main.ts
|
@ -29,7 +29,7 @@ import { messageOpts } from "./constants";
|
|||
import { submitConfession } from "./commandutils";
|
||||
import { contextCommands } from "./contextcommands";
|
||||
|
||||
export const dt = new StoreMan(StoreMan.checkFile());
|
||||
export const dt = new StoreMan();
|
||||
const logger = new Logger("Main");
|
||||
|
||||
BotClient.once("ready", client => {
|
||||
|
@ -75,25 +75,7 @@ BotClient.on(Events.InteractionCreate, async interaction => {
|
|||
}
|
||||
});
|
||||
|
||||
BotClient.on(Events.MessageDelete, async message => {
|
||||
const guildId = message.guild?.id!;
|
||||
if (!dt.getGuildInfo(guildId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const messageId = message.id;
|
||||
const confessions = dt.getGuildInfo(guildId)?.confessions!;
|
||||
|
||||
for (const confession of confessions) {
|
||||
if (confession.messageId === messageId) {
|
||||
dt.adminDelConfession(guildId, confession.id);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.error("An error occured:", err);
|
||||
}
|
||||
});
|
||||
// BotClient.on(Events.MessageDelete, async message => {});
|
||||
|
||||
// Submit Confession button
|
||||
BotClient.on(Events.InteractionCreate, async interaction => {
|
||||
|
@ -108,7 +90,7 @@ BotClient.on(Events.InteractionCreate, async interaction => {
|
|||
|
||||
if (requestSubmit) {
|
||||
// Check if the user is banned from confessions before showing the modal
|
||||
dt.isBannedByUser(interaction.guild?.id!, interaction.user.id)
|
||||
await dt.isBannedByUser(interaction.guild?.id!, interaction.user.id)
|
||||
? interaction
|
||||
.reply({
|
||||
content: "You are banned from confessions in this server!",
|
||||
|
|
|
@ -16,341 +16,179 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import fs from "fs";
|
||||
import crypto from "crypto";
|
||||
import {
|
||||
BanReason,
|
||||
Confession,
|
||||
ConfessionBan,
|
||||
GuildData,
|
||||
GuildSettings
|
||||
} from "./types";
|
||||
import { DATA_DIR } from "./config";
|
||||
import { CommandInteraction, Message } from "discord.js";
|
||||
import { Guild, Confession, PrismaClient, Ban } from "@prisma/client";
|
||||
import Logger from "../utils/Logger";
|
||||
|
||||
export class StoreMan {
|
||||
public static readonly fullPath: string =
|
||||
(DATA_DIR ?? "./persist/") + "data.json";
|
||||
private static logger = new Logger("StoreMan");
|
||||
private data: GuildData[];
|
||||
private static checkResult = (result: any | null) => result ? true : false;
|
||||
|
||||
constructor(existingData: GuildData[] = []) {
|
||||
this.data = existingData;
|
||||
private client: PrismaClient;
|
||||
|
||||
constructor() {
|
||||
this.client = new PrismaClient();
|
||||
}
|
||||
|
||||
public static genId = () => crypto.randomBytes(2).toString("hex");
|
||||
|
||||
public static toConfession(
|
||||
message: Message,
|
||||
id: string,
|
||||
author: string,
|
||||
authorId: string,
|
||||
content: string,
|
||||
attachment?: string
|
||||
): Confession {
|
||||
return {
|
||||
id: id,
|
||||
messageId: message.id,
|
||||
author: author,
|
||||
authorId: authorId,
|
||||
content: content,
|
||||
attachment: attachment
|
||||
};
|
||||
}
|
||||
|
||||
public static checkFile(): GuildData[] {
|
||||
let final: GuildData[];
|
||||
|
||||
if (fs.existsSync(StoreMan.fullPath)) {
|
||||
const data = fs.readFileSync(StoreMan.fullPath);
|
||||
|
||||
// Read the file if it isn't empty, else set final to an empty array
|
||||
final = !data.toString().trim() ? [] : JSON.parse(data.toString());
|
||||
} else {
|
||||
// If the directory doesn't exist, make it
|
||||
!fs.existsSync(DATA_DIR ?? "./persist/") &&
|
||||
fs.mkdirSync(DATA_DIR ?? "./persist/");
|
||||
fs.createWriteStream(StoreMan.fullPath);
|
||||
final = [];
|
||||
}
|
||||
|
||||
return final;
|
||||
}
|
||||
|
||||
public async saveFile(): Promise<void> {
|
||||
fs.writeFile(
|
||||
StoreMan.fullPath,
|
||||
JSON.stringify(this.data, null, 2),
|
||||
"utf8",
|
||||
err => err && StoreMan.logger.error("A write error occured:", err)
|
||||
);
|
||||
}
|
||||
|
||||
// Checks if a guild is not set up
|
||||
public checkSetup(guildId: string): boolean {
|
||||
for (const guild of this.data) {
|
||||
if (guild.id === guildId) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public async checkSetup(guildId: string): Promise<boolean> {
|
||||
const result = await this.client.guild.findFirst({ where: { guildId } }).then(StoreMan.checkResult);
|
||||
|
||||
return false;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Sets up a guild and stores it in the persistent file
|
||||
public setup(guildId: string, opts: GuildSettings): void {
|
||||
this.data.push({
|
||||
id: guildId,
|
||||
confessions: [],
|
||||
settings: opts
|
||||
});
|
||||
|
||||
this.saveFile();
|
||||
public async setup(guildId: string, { confessChannel, modChannel }: GuildSettings): Promise<void> {
|
||||
await this.client.guild.create({ data: { guildId, confessChannel, modChannel } }).then(() => StoreMan.logger.log("Guild created"));
|
||||
}
|
||||
|
||||
// Clear the settings for a given guild
|
||||
public clearSettings(guildId: string): void {
|
||||
this.data = this.data.filter(guild => {
|
||||
return guild.id !== guildId;
|
||||
});
|
||||
this.saveFile();
|
||||
public async clearSettings(guildId: string): Promise<void> {
|
||||
await this.client.confession.deleteMany({ where: { guildId } });
|
||||
await this.client.ban.deleteMany({ where: { guildId } });
|
||||
await this.client.guild.delete({ where: { guildId } });
|
||||
}
|
||||
|
||||
public getGuildInfo(guildId: string): GuildData | null {
|
||||
for (const guild of this.data) {
|
||||
if (guild.id === guildId) {
|
||||
return guild;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
public async getGuildInfo(guildId: string): Promise<Guild | null> {
|
||||
return await this.client.guild.findFirst({ where: { guildId } });
|
||||
}
|
||||
|
||||
// Attempts to add a confession. Returns true if the confession is sent, false if otherwise.
|
||||
public addConfession(
|
||||
public async addConfession(
|
||||
message: Message,
|
||||
id: string,
|
||||
author: string,
|
||||
authorId: string,
|
||||
content: string,
|
||||
attachment?: string
|
||||
): boolean {
|
||||
): Promise<boolean> {
|
||||
const { id: guildId } = message.guild!;
|
||||
const { id: messageId } = message;
|
||||
|
||||
for (const guild of this.data) {
|
||||
if (guild.id === guildId) {
|
||||
// If the author's user ID is in the ban list, don't let them post a confession.
|
||||
if (this.isBannedByUser(guildId, author)) {
|
||||
const ban = await this.client.ban.findFirst({ where: { guildId, authorId } }).then(StoreMan.checkResult);
|
||||
|
||||
if (ban) {
|
||||
return false;
|
||||
}
|
||||
|
||||
guild.confessions.push(
|
||||
StoreMan.toConfession(
|
||||
message,
|
||||
id,
|
||||
author,
|
||||
authorId,
|
||||
content,
|
||||
attachment
|
||||
)
|
||||
);
|
||||
this.saveFile();
|
||||
await this.client.confession.create({ data: { id, messageId, author, authorId, guildId, content, attachment } })
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
`No guild with id ${id} was found. Something's pretty wrong.`
|
||||
);
|
||||
}
|
||||
|
||||
public getConfession(
|
||||
public async getConfession(
|
||||
guildId: string,
|
||||
confessionId: string
|
||||
): Confession | null {
|
||||
for (const guild of this.data) {
|
||||
if (guild.id === guildId) {
|
||||
for (const confession of guild.confessions) {
|
||||
if (confession.id === confessionId) {
|
||||
return confession;
|
||||
}
|
||||
}
|
||||
}
|
||||
id: string
|
||||
): Promise<Confession | null> {
|
||||
return await this.client.confession.findFirst({ where: { guildId, id } });
|
||||
}
|
||||
|
||||
return null;
|
||||
public async getConfessions(guildId: string): Promise<Confession[]> {
|
||||
return await this.client.confession.findMany({ where: { guildId } });
|
||||
}
|
||||
|
||||
public getConfessionById(guildId: string, messageId: string): Confession | null {
|
||||
for (const guild of this.data) {
|
||||
if (guild.id === guildId) {
|
||||
for (const confession of guild.confessions) {
|
||||
if (confession.messageId === messageId) {
|
||||
return confession;
|
||||
}
|
||||
}
|
||||
}
|
||||
public async getConfessionById(guildId: string, messageId: string): Promise<Confession | null> {
|
||||
return await this.client.confession.findFirst({ where: { guildId, messageId } });
|
||||
}
|
||||
|
||||
return null;
|
||||
/**
|
||||
* Delete a confession from the database.
|
||||
*
|
||||
* @param interaction - Used to obtain the guild and authorId
|
||||
* @param id - The confession ID to delete
|
||||
*
|
||||
* @returns true if the confession was sucessfully deleted, false if otherwise.
|
||||
*/
|
||||
public async delConfesssion(
|
||||
{ guild, user: { id: authorId } }: CommandInteraction,
|
||||
id: string
|
||||
): Promise<boolean> {
|
||||
const { id: guildId } = guild!;
|
||||
const result = await this.client.confession.delete({ where: { guildId, authorId, id } }).then(StoreMan.checkResult);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Attempts to delete a confession. If it is sucessfully deleted, returns true, else false.
|
||||
public delConfesssion(
|
||||
{ guild, user }: CommandInteraction,
|
||||
confessionId: string
|
||||
): boolean {
|
||||
const guildId = guild?.id;
|
||||
const userId = user.id;
|
||||
|
||||
for (const guild of this.data) {
|
||||
if (guild.id === guildId) {
|
||||
for (const confession of guild.confessions) {
|
||||
if (confession.authorId === userId) {
|
||||
guild.confessions = guild.confessions.filter(confession => {
|
||||
return confession.id !== confessionId;
|
||||
});
|
||||
|
||||
this.saveFile();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public adminDelConfession(guildId: string, confessionId: string): void {
|
||||
for (const guild of this.data) {
|
||||
if (guild.id === guildId) {
|
||||
guild.confessions = guild.confessions.filter(confession => {
|
||||
return confession.id !== confessionId;
|
||||
});
|
||||
|
||||
this.saveFile();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Delete a confession from the database as an admin.
|
||||
*
|
||||
* @param guildId - The ID of the guild to delete from
|
||||
* @param id - The ID of the confession to delete
|
||||
*/
|
||||
public async adminDelConfession(guildId: string, id: string): Promise<void> {
|
||||
await this.client.confession.delete({ where: { guildId, id } });
|
||||
}
|
||||
|
||||
// Check if a certain user is banned within a guild.
|
||||
public isBannedByUser(guildId: string, userId: string): boolean {
|
||||
for (const guild of this.data) {
|
||||
if (guild.id === guildId) {
|
||||
for (const ban of guild.settings.bans) {
|
||||
if (ban.user === userId) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
public async isBannedByUser(guildId: string, authorId: string): Promise<boolean> {
|
||||
const result = await this.client.ban.findFirst({ where: { guildId, authorId } }).then(StoreMan.checkResult);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async isBannedById(guildId: string, confessionId: string): Promise<boolean> {
|
||||
const result = await this.client.ban.findFirst({ where: { guildId, confessionId } }).then(StoreMan.checkResult);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async getBans(guildId: string): Promise<Ban[]> {
|
||||
return await this.client.ban.findMany({ where: { guildId } });
|
||||
}
|
||||
|
||||
/**
|
||||
* Ban a user by confession id.
|
||||
*
|
||||
* @param guildId - The ID of the guild to ban from
|
||||
* @param confessionId - The ID of the confession to ban for
|
||||
*/
|
||||
public async addBanById(guildId: string, confessionId: string): Promise<boolean> {
|
||||
const alreadyBanned = await this.isBannedById(guildId, confessionId);
|
||||
|
||||
if (alreadyBanned) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public isBannedById(guildId: string, confessionId: string): boolean {
|
||||
for (const guild of this.data) {
|
||||
if (guild.id === guildId) {
|
||||
for (const ban of guild.settings.bans) {
|
||||
if (ban.confessionId === confessionId) {
|
||||
const { authorId } = await this.client.confession.findFirstOrThrow({ where: { guildId, id: confessionId } });
|
||||
await this.client.ban.create({ data: { guildId, authorId, confessionId, reason: BanReason.ById } });
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async addBanByUser(guildId: string, authorId: string): Promise<boolean> {
|
||||
const alreadyBanned = await this.isBannedByUser(guildId, authorId);
|
||||
|
||||
if (alreadyBanned) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public getBans(guildId: string): ConfessionBan[] {
|
||||
for (const guild of this.data) {
|
||||
if (guild.id === guildId) {
|
||||
return guild.settings.bans;
|
||||
}
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
// Attempts to ban a user from confessions.
|
||||
public addBanById(guildId: string, confessionId: string): boolean {
|
||||
const confession = this.getConfession(guildId, confessionId);
|
||||
|
||||
for (const guild of this.data) {
|
||||
if (guild.id === guildId) {
|
||||
if (confession) {
|
||||
// Only add the user to the ban list if they aren't banned already
|
||||
!this.isBannedByUser(guildId, confession.authorId) &&
|
||||
guild.settings.bans.push({
|
||||
user: confession.authorId,
|
||||
confessionId: confessionId,
|
||||
method: BanReason.ById
|
||||
});
|
||||
|
||||
this.saveFile();
|
||||
await this.client.ban.create({ data: { guildId, authorId, reason: BanReason.ByUser } });
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 removeBanById(guildId: string, confessionId: string): boolean {
|
||||
for (const guild of this.data) {
|
||||
if (guild.id === guildId) {
|
||||
if (this.getConfession(guildId, confessionId)) {
|
||||
guild.settings.bans = guild.settings.bans.filter(ban => {
|
||||
return (
|
||||
ban.user !== this.getConfession(guildId, confessionId)?.authorId!
|
||||
);
|
||||
});
|
||||
|
||||
this.saveFile();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async removeBanById(guildId: string, confessionId: string): Promise<boolean> {
|
||||
if (await this.isBannedById(guildId, confessionId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public removeBanByUser(guildId: string, userId: string): boolean {
|
||||
for (const guild of this.data) {
|
||||
if (guild.id === guildId) {
|
||||
for (const ban of guild.settings.bans) {
|
||||
if (ban.method === BanReason.ByUser && ban.user === userId) {
|
||||
guild.settings.bans = guild.settings.bans.filter(ban => {
|
||||
return ban.user !== userId;
|
||||
});
|
||||
const { authorId } = await this.client.ban.findFirstOrThrow({ where: { guildId, confessionId } });
|
||||
|
||||
this.saveFile();
|
||||
await this.client.ban.delete({ where: { guildId, confessionId, authorId } });
|
||||
return true;
|
||||
}
|
||||
|
||||
public async removeBanByUser(guildId: string, authorId: string): Promise<boolean> {
|
||||
if (await this.isBannedByUser(guildId, authorId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
await this.client.ban.delete({ where: { guildId, authorId } });
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue