mirror of
https://github.com/toast-ts/Daggerbot-TS.git
synced 2024-11-17 08:20:58 -05:00
:stuff: lighting a fire.
This commit is contained in:
parent
15747d1bed
commit
0a752f11f9
231
src/client.ts
231
src/client.ts
@ -1,8 +1,8 @@
|
|||||||
import Discord, { Client, GatewayIntentBits, Partials } from 'discord.js';
|
import Discord, { Client, GatewayIntentBits, Partials } from 'discord.js';
|
||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
import { Database } from './database';
|
|
||||||
import timeNames from './timeNames';
|
import timeNames from './timeNames';
|
||||||
import { Punishment, formatTimeOpt, punOpt, Tokens, Config } from './typings/interfaces';
|
import { Punishment, formatTimeOpt, Tokens, Config } from './typings/interfaces';
|
||||||
|
import { bannedWords, bonkCount, userLevels, punishments } from './schoolClassroom';
|
||||||
import MPDB from './models/MPServer';
|
import MPDB from './models/MPServer';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
@ -19,7 +19,7 @@ try{
|
|||||||
console.log('Using production config')
|
console.log('Using production config')
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TClient extends Client {
|
export default class TClient extends Client {
|
||||||
invites: Map<any, any>;
|
invites: Map<any, any>;
|
||||||
commands: Discord.Collection<string, any>;
|
commands: Discord.Collection<string, any>;
|
||||||
registry: Array<Discord.ApplicationCommandDataResolvable>;
|
registry: Array<Discord.ApplicationCommandDataResolvable>;
|
||||||
@ -187,228 +187,3 @@ export class TClient extends Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//class
|
|
||||||
class bannedWords extends Database {
|
|
||||||
client: TClient;
|
|
||||||
constructor(client: TClient){
|
|
||||||
super('src/database/bannedWords.json', 'array');
|
|
||||||
this.client = client;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
class punishments extends Database {
|
|
||||||
client: TClient;
|
|
||||||
constructor(client: TClient){
|
|
||||||
super('src/database/punishments.json', 'array');
|
|
||||||
this.client = client;
|
|
||||||
}
|
|
||||||
createId(){
|
|
||||||
return Math.max(...this.client.punishments._content.map((x:Punishment)=>x.id), 0)+1;
|
|
||||||
}
|
|
||||||
makeModlogEntry(data: Punishment) {
|
|
||||||
const cancels = data.cancels ? this.client.punishments._content.find((x: Punishment) => x.id === data.cancels) : null;
|
|
||||||
const channelId = ['kick', 'ban'].includes(data.type) ? '1048341961901363352' : this.client.config.mainServer.channels.logs;
|
|
||||||
|
|
||||||
// format data into embed
|
|
||||||
const embed = new this.client.embed()
|
|
||||||
.setTitle(`${this.client.formatPunishmentType(data, this.client, cancels)} | Case #${data.id}`)
|
|
||||||
.addFields(
|
|
||||||
{name: '🔹 User', value: `<@${data.member}> \`${data.member}\``, inline: true},
|
|
||||||
{name: '🔹 Moderator', value: `<@${data.moderator}> \`${data.moderator}\``, inline: true},
|
|
||||||
{name: '\u200b', value: '\u200b', inline: true},
|
|
||||||
{name: '🔹 Reason', value: `\`${data.reason}\``, inline: true})
|
|
||||||
.setColor(this.client.config.embedColor)
|
|
||||||
.setTimestamp(data.time)
|
|
||||||
if (data.duration) {
|
|
||||||
embed.addFields(
|
|
||||||
{name: '🔹 Duration', value: this.client.formatTime(data.duration, 100), inline: true},
|
|
||||||
{name: '\u200b', value: '\u200b', inline: true}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (data.cancels) embed.addFields({name: '🔹 Overwrites', value: `This case overwrites Case #${cancels.id}\n\`${cancels.reason}\``});
|
|
||||||
|
|
||||||
// send embed in modlog channel
|
|
||||||
(this.client.channels.cache.get(channelId) as Discord.TextChannel).send({embeds: [embed]});
|
|
||||||
};
|
|
||||||
getTense(type: string) { // Get past tense form of punishment type, grammar yes
|
|
||||||
switch (type) {
|
|
||||||
case 'ban':
|
|
||||||
return 'banned';
|
|
||||||
case 'softban':
|
|
||||||
return 'softbanned';
|
|
||||||
case 'kick':
|
|
||||||
return 'kicked';
|
|
||||||
case 'mute':
|
|
||||||
return 'muted';
|
|
||||||
case 'warn':
|
|
||||||
return 'warned';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
async addPunishment(type: string, options: punOpt, moderator: string, reason: string, User: Discord.User, GuildMember?: Discord.GuildMember) {
|
|
||||||
const { time, interaction } = options;
|
|
||||||
const ms = require('ms');
|
|
||||||
const now = Date.now();
|
|
||||||
const guild = this.client.guilds.cache.get(this.client.config.mainServer.id) as Discord.Guild;
|
|
||||||
const punData: Punishment = { type, id: this.createId(), member: User.id, reason, moderator, time: now }
|
|
||||||
const embed = new this.client.embed()
|
|
||||||
.setColor(this.client.config.embedColor)
|
|
||||||
.setTitle(`Case #${punData.id}: ${type[0].toUpperCase() + type.slice(1)}`)
|
|
||||||
.setDescription(`${User.tag}\n<@${User.id}>\n(\`${User.id}\`)`)
|
|
||||||
.addFields({name: 'Reason', value: reason})
|
|
||||||
let punResult: any;
|
|
||||||
let timeInMillis: number;
|
|
||||||
let DM: Discord.Message<false> | undefined;
|
|
||||||
|
|
||||||
if (type == "mute") {
|
|
||||||
timeInMillis = time ? ms(time) : 2419140000; // Timeouts have a limit of 4 weeks
|
|
||||||
} else {
|
|
||||||
timeInMillis = time ? ms(time) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add field for duration if time is specified
|
|
||||||
if (time) embed.addFields({name: 'Duration', value: `${timeInMillis ? `for ${this.client.formatTime(timeInMillis, 4, { longNames: true, commas: true })}` : "forever"}`})
|
|
||||||
|
|
||||||
if (GuildMember) {
|
|
||||||
try {
|
|
||||||
DM = await GuildMember.send(`You've been ${this.getTense(type)} ${['warn', 'mute'].includes(type) ? 'in' : 'from'} ${guild.name}${time ? (timeInMillis ? ` for ${this.client.formatTime(timeInMillis, 4, { longNames: true, commas: true })}` : 'forever') : ''} for reason \`${reason}\` (Case #${punData.id})`);
|
|
||||||
} catch (err: any) {
|
|
||||||
embed.setFooter({text: 'Failed to DM member of punishment'});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (['ban', 'softban'].includes(type)) {
|
|
||||||
const banned = await guild.bans.fetch(User.id).catch(() => undefined);
|
|
||||||
if (!banned) {
|
|
||||||
punResult = await guild.bans.create(User.id, {reason: `${reason} | Case #${punData.id}`}).catch((err: Error) => err.message);
|
|
||||||
} else {
|
|
||||||
punResult = 'User is already banned.';
|
|
||||||
}
|
|
||||||
} else if (type == 'kick') {
|
|
||||||
punResult = await GuildMember?.kick(`${reason} | Case #${punData.id}`).catch((err: Error) => err.message);
|
|
||||||
} else if (type == 'mute') {
|
|
||||||
punResult = await GuildMember?.timeout(timeInMillis, `${reason} | Case #${punData.id}`).catch((err: Error) => err.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == 'softban' && typeof punResult != 'string') { // If type was softban and it was successful, continue with softban (unban)
|
|
||||||
punResult = await guild.bans.remove(User.id, `${reason} | Case #${punData.id}`).catch((err: Error) => err.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (timeInMillis && ['mute', 'ban'].includes(type)) { // If type is mute or ban, specify duration and endTime
|
|
||||||
punData.endTime = now + timeInMillis;
|
|
||||||
punData.duration = timeInMillis;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof punResult == 'string') { // Punishment was unsuccessful
|
|
||||||
if (DM) DM.delete();
|
|
||||||
if (interaction) {
|
|
||||||
return interaction.editReply(punResult);
|
|
||||||
} else {
|
|
||||||
return punResult;
|
|
||||||
}
|
|
||||||
} else { // Punishment was successful
|
|
||||||
this.makeModlogEntry(punData);
|
|
||||||
this.client.punishments.addData(punData).forceSave();
|
|
||||||
|
|
||||||
if (interaction) {
|
|
||||||
return interaction.editReply({embeds: [embed]});
|
|
||||||
} else {
|
|
||||||
return punResult;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
async removePunishment(caseId:number, moderator:any, reason:string):Promise<any>{
|
|
||||||
const now = Date.now()
|
|
||||||
const punishment = this._content.find((x:Punishment)=>x.id === caseId);
|
|
||||||
const id = this.createId();
|
|
||||||
if (!punishment) return 'Punishment not found';
|
|
||||||
if (['ban','mute'].includes(punishment.type)) {
|
|
||||||
const guild = this.client.guilds.cache.get(this.client.config.mainServer.id) as Discord.Guild;
|
|
||||||
let removePunishmentResult;
|
|
||||||
if (punishment.type === 'ban'){
|
|
||||||
removePunishmentResult = await guild.members.unban(punishment.member, `${reason || 'Reason unspecified'} | Case #${id}`).catch((err:TypeError)=>err.message);
|
|
||||||
} else if (punishment.type === 'mute'){
|
|
||||||
const member = await guild.members.fetch(punishment.member).catch(err=>undefined);
|
|
||||||
if (member){
|
|
||||||
removePunishmentResult = await member
|
|
||||||
if (typeof removePunishmentResult !== 'string'){
|
|
||||||
member.timeout(null, `${reason || 'Reason unspecified'} | Case #${id}`)
|
|
||||||
removePunishmentResult.send(`You've been unmuted in ${removePunishmentResult.guild.name}.`);
|
|
||||||
removePunishmentResult = removePunishmentResult.user;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// user probably left, quietly remove punishment
|
|
||||||
const removePunishmentData = {type: `un${punishment.type}`, id, cancels: punishment.id, member: punishment.member, reason, moderator, time: now};
|
|
||||||
this._content[this._content.findIndex((x:Punishment)=>x.id === punishment.id)].expired = true
|
|
||||||
this.addData(removePunishmentData).forceSave();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (typeof removePunishmentResult === 'string') return `Un${punishment.type} was unsuccessful: ${removePunishmentResult}`;
|
|
||||||
else {
|
|
||||||
const removePunishmentData = {type: `un${punishment.type}`, id, cancels: punishment.id, member: punishment.member, reason, moderator, time: now};
|
|
||||||
this.makeModlogEntry(removePunishmentData);
|
|
||||||
this._content[this._content.findIndex((x:Punishment)=>x.id === punishment.id)].expired = true;
|
|
||||||
this.addData(removePunishmentData).forceSave();
|
|
||||||
return `Successfully ${punishment.type === 'ban' ? 'unbanned' : 'unmuted'} **${removePunishmentResult?.tag}** (${removePunishmentResult?.id}) for reason \`${reason || 'Reason unspecified'}\``
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
const removePunishmentData = {type: 'removeOtherPunishment', id, cancels: punishment.id, member: punishment.member, reason, moderator, time: now};
|
|
||||||
this.makeModlogEntry(removePunishmentData);
|
|
||||||
this._content[this._content.findIndex((x:Punishment)=>x.id === punishment.id)].expired = true;
|
|
||||||
this.addData(removePunishmentData).forceSave();
|
|
||||||
return `Successfully removed Case #${punishment.id} (type: ${punishment.type}, user: ${punishment.member}).`;
|
|
||||||
} catch (error:any){
|
|
||||||
return `${punishment.type[0].toUpperCase() + punishment.type.slice(1)} removal was unsuccessful: ${error.message}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
class userLevels extends Database {
|
|
||||||
client: TClient;
|
|
||||||
constructor(client: TClient){
|
|
||||||
super('src/database/userLevels.json', 'object');
|
|
||||||
this.client = client
|
|
||||||
}
|
|
||||||
incrementUser(userid: string){
|
|
||||||
const data = this._content[userid];// User's data. Integer for old format, object for new format.
|
|
||||||
|
|
||||||
if (typeof data == 'number'){// If user's data is an integer, convert it into object for new format.
|
|
||||||
this._content[userid] = {messages: data, level: 0};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data) {// If user exists on file...
|
|
||||||
this._content[userid].messages++;// Increment their message count
|
|
||||||
if (data.messages >= this.algorithm(data.level+2)){// Quietly level up users who can surpass more than 2 levels at once, usually due to manually updating their message count
|
|
||||||
while (data.messages > this.algorithm(data.level+1)){
|
|
||||||
this._content[userid].level++;
|
|
||||||
console.log(`${userid} EXTENDED LEVELUP ${this._content[userid].level}`)
|
|
||||||
}
|
|
||||||
} else if (data.messages >= this.algorithm(data.level+1)){// If user's message count meets/exceeds message requirement for next level...
|
|
||||||
this._content[userid].level++;// Level them up.
|
|
||||||
(this.client.channels.resolve(this.client.config.mainServer.channels.botcommands) as Discord.TextChannel).send({content: `<@${userid}> has reached level **${data.level}**. GG!`, allowedMentions: {parse: ['users']}})
|
|
||||||
}
|
|
||||||
} else {// If user doesn't exist on file, create an object for it.
|
|
||||||
this._content[userid] = {messages: 1, level: 0};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
algorithm(level: number){// Algorithm for determining levels. If adjusting, recommended to only change the integer at the end of equation.
|
|
||||||
return level*level*15;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
class bonkCount extends Database {
|
|
||||||
client: TClient;
|
|
||||||
constructor(client: TClient){
|
|
||||||
super('src/database/bonkCount.json', 'object')
|
|
||||||
this.client = client
|
|
||||||
}
|
|
||||||
_incrementUser(userid: string){
|
|
||||||
const amount = this._content[userid];
|
|
||||||
if(amount) this._content[userid]++;
|
|
||||||
else this._content[userid] = 1;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
getUser(userid: string){
|
|
||||||
return this._content[userid] || 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||||
import { TClient } from 'src/client';
|
import TClient from 'src/client';
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
client.punish(client, interaction, 'ban');
|
client.punish(client, interaction, 'ban');
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||||
import { TClient } from 'src/client';
|
import TClient from 'src/client';
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
if (!client.isStaff(interaction.member) && !client.config.eval.whitelist.includes(interaction.member.id)) return client.youNeedRole(interaction, 'admin')
|
if (!client.isStaff(interaction.member) && !client.config.eval.whitelist.includes(interaction.member.id)) return client.youNeedRole(interaction, 'admin')
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||||
import { TClient } from 'src/client';
|
import TClient from 'src/client';
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
//if (!client.isStaff(interaction.member) && interaction.channelId == '468835415093411863') return interaction.reply('This command is restricted to staff only in this channel due to high usage.')
|
//if (!client.isStaff(interaction.member) && interaction.channelId == '468835415093411863') return interaction.reply('This command is restricted to staff only in this channel due to high usage.')
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord,{SlashCommandBuilder} from "discord.js";
|
import Discord,{SlashCommandBuilder} from "discord.js";
|
||||||
import { TClient } from 'src/client';
|
import TClient from 'src/client';
|
||||||
import { Punishment } from "src/typings/interfaces";
|
import { Punishment } from "src/typings/interfaces";
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||||
import { TClient } from 'src/client';
|
import TClient from 'src/client';
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
const embed = new client.embed().setColor(client.config.embedColor).setTitle('Daggerbot contributors').setDescription([
|
const embed = new client.embed().setColor(client.config.embedColor).setTitle('Daggerbot contributors').setDescription([
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||||
import { TClient } from 'src/client';
|
import TClient from 'src/client';
|
||||||
import * as util from 'node:util';
|
import * as util from 'node:util';
|
||||||
import {exec} from 'node:child_process';
|
import {exec} from 'node:child_process';
|
||||||
import { readFileSync } from 'node:fs';
|
import { readFileSync } from 'node:fs';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||||
import { TClient } from 'src/client';
|
import TClient from 'src/client';
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
switch(interaction.options.getString('question')){
|
switch(interaction.options.getString('question')){
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||||
import { TClient } from 'src/client';
|
import TClient from 'src/client';
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
client.punish(client, interaction, 'kick');
|
client.punish(client, interaction, 'kick');
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord,{EmbedBuilder, SlashCommandBuilder} from 'discord.js';
|
import Discord,{EmbedBuilder, SlashCommandBuilder} from 'discord.js';
|
||||||
import { TClient } from 'src/client';
|
import TClient from 'src/client';
|
||||||
import MPDB from '../models/MPServer';
|
import MPDB from '../models/MPServer';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||||
import { TClient } from 'src/client';
|
import TClient from 'src/client';
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
client.punish(client, interaction, 'mute');
|
client.punish(client, interaction, 'mute');
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||||
import { TClient } from 'src/client';
|
import TClient from 'src/client';
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
const msg = await interaction.reply({content: 'Pinging...', fetchReply: true})
|
const msg = await interaction.reply({content: 'Pinging...', fetchReply: true})
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||||
import { TClient } from 'src/client';
|
import TClient from 'src/client';
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
if (!client.isStaff(interaction.member)) return client.youNeedRole(interaction, 'dcmod');
|
if (!client.isStaff(interaction.member)) return client.youNeedRole(interaction, 'dcmod');
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||||
import { TClient } from 'src/client';
|
import TClient from 'src/client';
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
const embed = new client.embed().setColor(Math.floor(Math.random()*16777215));
|
const embed = new client.embed().setColor(Math.floor(Math.random()*16777215));
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||||
import { TClient } from 'src/client';
|
import TClient from 'src/client';
|
||||||
import { UserLevels } from 'src/typings/interfaces';
|
import { UserLevels } from 'src/typings/interfaces';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||||
import { TClient } from 'src/client';
|
import TClient from 'src/client';
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
const role = interaction.options.getRole('role') as Discord.Role;
|
const role = interaction.options.getRole('role') as Discord.Role;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||||
import { TClient } from 'src/client';
|
import TClient from 'src/client';
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
client.punish(client, interaction, 'softban');
|
client.punish(client, interaction, 'softban');
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||||
import { TClient } from 'src/client';
|
import TClient from 'src/client';
|
||||||
import si from 'systeminformation';
|
import si from 'systeminformation';
|
||||||
import os from 'node:os';
|
import os from 'node:os';
|
||||||
import { version } from 'typescript';
|
import { version } from 'typescript';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||||
import { TClient } from 'src/client';
|
import TClient from 'src/client';
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
client.unPunish(client, interaction)
|
client.unPunish(client, interaction)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||||
import { TClient } from 'src/client';
|
import TClient from 'src/client';
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
client.punish(client, interaction, 'warn');
|
client.punish(client, interaction, 'warn');
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||||
import { TClient } from 'src/client';
|
import TClient from 'src/client';
|
||||||
|
|
||||||
function convert(status:string){
|
function convert(status:string){
|
||||||
switch (status){
|
switch (status){
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord, { AuditLogEvent } from 'discord.js';
|
import Discord, { AuditLogEvent } from 'discord.js';
|
||||||
import { TClient } from '../client';
|
import TClient from '../client';
|
||||||
export default {
|
export default {
|
||||||
async run(client:TClient, member:Discord.GuildMember){
|
async run(client:TClient, member:Discord.GuildMember){
|
||||||
if (member.guild?.id != client.config.mainServer.id) return;
|
if (member.guild?.id != client.config.mainServer.id) return;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord, { AuditLogEvent } from 'discord.js';
|
import Discord, { AuditLogEvent } from 'discord.js';
|
||||||
import { TClient } from '../client';
|
import TClient from '../client';
|
||||||
export default {
|
export default {
|
||||||
async run(client:TClient, member:Discord.GuildMember){
|
async run(client:TClient, member:Discord.GuildMember){
|
||||||
if (member.guild?.id != client.config.mainServer.id) return;
|
if (member.guild?.id != client.config.mainServer.id) return;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord from 'discord.js';
|
import Discord from 'discord.js';
|
||||||
import { TClient } from '../client';
|
import TClient from '../client';
|
||||||
export default {
|
export default {
|
||||||
async run(client:TClient, member:Discord.GuildMember){
|
async run(client:TClient, member:Discord.GuildMember){
|
||||||
if (
|
if (
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord from 'discord.js';
|
import Discord from 'discord.js';
|
||||||
import { TClient } from '../client';
|
import TClient from '../client';
|
||||||
export default {
|
export default {
|
||||||
async run(client:TClient, member:Discord.GuildMember){
|
async run(client:TClient, member:Discord.GuildMember){
|
||||||
if (!client.config.botSwitches.logs) return;
|
if (!client.config.botSwitches.logs) return;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord from 'discord.js';
|
import Discord from 'discord.js';
|
||||||
import { TClient } from '../client';
|
import TClient from '../client';
|
||||||
export default {
|
export default {
|
||||||
async run(client:TClient, oldMember:Discord.GuildMember, newMember:Discord.GuildMember){
|
async run(client:TClient, oldMember:Discord.GuildMember, newMember:Discord.GuildMember){
|
||||||
if (oldMember.guild.id != client.config.mainServer.id) return;
|
if (oldMember.guild.id != client.config.mainServer.id) return;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord from 'discord.js';
|
import Discord from 'discord.js';
|
||||||
import { TClient } from '../client';
|
import TClient from '../client';
|
||||||
export default {
|
export default {
|
||||||
async run(client:TClient, interaction:Discord.ChatInputCommandInteraction){
|
async run(client:TClient, interaction:Discord.ChatInputCommandInteraction){
|
||||||
if (!interaction.inGuild() || !interaction.inCachedGuild() || !interaction.command) return;
|
if (!interaction.inGuild() || !interaction.inCachedGuild() || !interaction.command) return;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord from 'discord.js';
|
import Discord from 'discord.js';
|
||||||
import { TClient } from '../client';
|
import TClient from '../client';
|
||||||
export default {
|
export default {
|
||||||
async run(client:TClient, invite: Discord.Invite){
|
async run(client:TClient, invite: Discord.Invite){
|
||||||
if (!invite.guild) return;
|
if (!invite.guild) return;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord from 'discord.js';
|
import Discord from 'discord.js';
|
||||||
import { TClient } from '../client';
|
import TClient from '../client';
|
||||||
export default {
|
export default {
|
||||||
async run(client:TClient, invite: Discord.Invite){
|
async run(client:TClient, invite: Discord.Invite){
|
||||||
client.invites.delete(invite.code)
|
client.invites.delete(invite.code)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord, { ChannelType } from 'discord.js';
|
import Discord, { ChannelType } from 'discord.js';
|
||||||
import { TClient } from '../client';
|
import TClient from '../client';
|
||||||
export default {
|
export default {
|
||||||
async run(client:TClient, message:Discord.Message){
|
async run(client:TClient, message:Discord.Message){
|
||||||
if (
|
if (
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord from 'discord.js';
|
import Discord from 'discord.js';
|
||||||
import { TClient } from '../client';
|
import TClient from '../client';
|
||||||
export default {
|
export default {
|
||||||
async run(client:TClient, msg:Discord.Message){
|
async run(client:TClient, msg:Discord.Message){
|
||||||
if (!client.config.botSwitches.logs) return;
|
if (!client.config.botSwitches.logs) return;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord from 'discord.js';
|
import Discord from 'discord.js';
|
||||||
import { TClient } from '../client';
|
import TClient from '../client';
|
||||||
export default {
|
export default {
|
||||||
async run(client:TClient, messages:Discord.Collection<string, Discord.Message<boolean>>){
|
async run(client:TClient, messages:Discord.Collection<string, Discord.Message<boolean>>){
|
||||||
const channel = client.channels.resolve(client.config.mainServer.channels.logs) as Discord.TextChannel;
|
const channel = client.channels.resolve(client.config.mainServer.channels.logs) as Discord.TextChannel;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord, { ActionRowBuilder, ButtonBuilder } from 'discord.js';
|
import Discord, { ActionRowBuilder, ButtonBuilder } from 'discord.js';
|
||||||
import { TClient } from '../client';
|
import TClient from '../client';
|
||||||
export default {
|
export default {
|
||||||
async run(client:TClient, oldMsg:Discord.Message, newMsg:Discord.Message){
|
async run(client:TClient, oldMsg:Discord.Message, newMsg:Discord.Message){
|
||||||
if (!client.config.botSwitches.logs) return;
|
if (!client.config.botSwitches.logs) return;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord, { AuditLogEvent } from 'discord.js';
|
import Discord, { AuditLogEvent } from 'discord.js';
|
||||||
import { TClient } from '../client';
|
import TClient from '../client';
|
||||||
export default {
|
export default {
|
||||||
async run(client:TClient, oldRole:Discord.Role, newRole:Discord.Role){
|
async run(client:TClient, oldRole:Discord.Role, newRole:Discord.Role){
|
||||||
const fetchRoleUpdoot = await client.guilds.cache.get(oldRole.guild.id).fetchAuditLogs({
|
const fetchRoleUpdoot = await client.guilds.cache.get(oldRole.guild.id).fetchAuditLogs({
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Discord from 'discord.js';
|
import Discord from 'discord.js';
|
||||||
import { TClient } from './client';
|
import TClient from './client';
|
||||||
const client = new TClient;
|
const client = new TClient;
|
||||||
client.init();
|
client.init();
|
||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
|
228
src/schoolClassroom.ts
Normal file
228
src/schoolClassroom.ts
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
import TClient from './client';
|
||||||
|
import Discord from 'discord.js';
|
||||||
|
import { Database } from './database';
|
||||||
|
import { Punishment, punOpt } from './typings/interfaces';
|
||||||
|
|
||||||
|
export class bannedWords extends Database {
|
||||||
|
client: TClient;
|
||||||
|
constructor(client: TClient){
|
||||||
|
super('src/database/bannedWords.json', 'array');
|
||||||
|
this.client = client;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export class bonkCount extends Database {
|
||||||
|
client: TClient;
|
||||||
|
constructor(client: TClient){
|
||||||
|
super('src/database/bonkCount.json', 'object')
|
||||||
|
this.client = client
|
||||||
|
}
|
||||||
|
_incrementUser(userid: string){
|
||||||
|
const amount = this._content[userid];
|
||||||
|
if(amount) this._content[userid]++;
|
||||||
|
else this._content[userid] = 1;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
getUser(userid: string){
|
||||||
|
return this._content[userid] || 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export class userLevels extends Database {
|
||||||
|
client: TClient;
|
||||||
|
constructor(client: TClient){
|
||||||
|
super('src/database/userLevels.json', 'object');
|
||||||
|
this.client = client
|
||||||
|
}
|
||||||
|
incrementUser(userid: string){
|
||||||
|
const data = this._content[userid];// User's data. Integer for old format, object for new format.
|
||||||
|
|
||||||
|
if (typeof data == 'number'){// If user's data is an integer, convert it into object for new format.
|
||||||
|
this._content[userid] = {messages: data, level: 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data) {// If user exists on file...
|
||||||
|
this._content[userid].messages++;// Increment their message count
|
||||||
|
if (data.messages >= this.algorithm(data.level+2)){// Quietly level up users who can surpass more than 2 levels at once, usually due to manually updating their message count
|
||||||
|
while (data.messages > this.algorithm(data.level+1)){
|
||||||
|
this._content[userid].level++;
|
||||||
|
console.log(`${userid} EXTENDED LEVELUP ${this._content[userid].level}`)
|
||||||
|
}
|
||||||
|
} else if (data.messages >= this.algorithm(data.level+1)){// If user's message count meets/exceeds message requirement for next level...
|
||||||
|
this._content[userid].level++;// Level them up.
|
||||||
|
(this.client.channels.resolve(this.client.config.mainServer.channels.botcommands) as Discord.TextChannel).send({content: `<@${userid}> has reached level **${data.level}**. GG!`, allowedMentions: {parse: ['users']}})
|
||||||
|
}
|
||||||
|
} else {// If user doesn't exist on file, create an object for it.
|
||||||
|
this._content[userid] = {messages: 1, level: 0};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
algorithm(level: number){// Algorithm for determining levels. If adjusting, recommended to only change the integer at the end of equation.
|
||||||
|
return level*level*15;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export class punishments extends Database {
|
||||||
|
client: TClient;
|
||||||
|
constructor(client: TClient){
|
||||||
|
super('src/database/punishments.json', 'array');
|
||||||
|
this.client = client;
|
||||||
|
}
|
||||||
|
createId(){
|
||||||
|
return Math.max(...this.client.punishments._content.map((x:Punishment)=>x.id), 0)+1;
|
||||||
|
}
|
||||||
|
makeModlogEntry(data: Punishment) {
|
||||||
|
const cancels = data.cancels ? this.client.punishments._content.find((x: Punishment) => x.id === data.cancels) : null;
|
||||||
|
const channelId = ['kick', 'ban'].includes(data.type) ? '1048341961901363352' : this.client.config.mainServer.channels.logs;
|
||||||
|
|
||||||
|
// format data into embed
|
||||||
|
const embed = new this.client.embed()
|
||||||
|
.setTitle(`${this.client.formatPunishmentType(data, this.client, cancels)} | Case #${data.id}`)
|
||||||
|
.addFields(
|
||||||
|
{name: '🔹 User', value: `<@${data.member}> \`${data.member}\``, inline: true},
|
||||||
|
{name: '🔹 Moderator', value: `<@${data.moderator}> \`${data.moderator}\``, inline: true},
|
||||||
|
{name: '\u200b', value: '\u200b', inline: true},
|
||||||
|
{name: '🔹 Reason', value: `\`${data.reason}\``, inline: true})
|
||||||
|
.setColor(this.client.config.embedColor)
|
||||||
|
.setTimestamp(data.time)
|
||||||
|
if (data.duration) {
|
||||||
|
embed.addFields(
|
||||||
|
{name: '🔹 Duration', value: this.client.formatTime(data.duration, 100), inline: true},
|
||||||
|
{name: '\u200b', value: '\u200b', inline: true}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (data.cancels) embed.addFields({name: '🔹 Overwrites', value: `This case overwrites Case #${cancels.id}\n\`${cancels.reason}\``});
|
||||||
|
|
||||||
|
// send embed in modlog channel
|
||||||
|
(this.client.channels.cache.get(channelId) as Discord.TextChannel).send({embeds: [embed]});
|
||||||
|
};
|
||||||
|
getTense(type: string) { // Get past tense form of punishment type, grammar yes
|
||||||
|
switch (type) {
|
||||||
|
case 'ban':
|
||||||
|
return 'banned';
|
||||||
|
case 'softban':
|
||||||
|
return 'softbanned';
|
||||||
|
case 'kick':
|
||||||
|
return 'kicked';
|
||||||
|
case 'mute':
|
||||||
|
return 'muted';
|
||||||
|
case 'warn':
|
||||||
|
return 'warned';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async addPunishment(type: string, options: punOpt, moderator: string, reason: string, User: Discord.User, GuildMember?: Discord.GuildMember) {
|
||||||
|
const { time, interaction } = options;
|
||||||
|
const ms = require('ms');
|
||||||
|
const now = Date.now();
|
||||||
|
const guild = this.client.guilds.cache.get(this.client.config.mainServer.id) as Discord.Guild;
|
||||||
|
const punData: Punishment = { type, id: this.createId(), member: User.id, reason, moderator, time: now }
|
||||||
|
const embed = new this.client.embed()
|
||||||
|
.setColor(this.client.config.embedColor)
|
||||||
|
.setTitle(`Case #${punData.id}: ${type[0].toUpperCase() + type.slice(1)}`)
|
||||||
|
.setDescription(`${User.tag}\n<@${User.id}>\n(\`${User.id}\`)`)
|
||||||
|
.addFields({name: 'Reason', value: reason})
|
||||||
|
let punResult: any;
|
||||||
|
let timeInMillis: number;
|
||||||
|
let DM: Discord.Message<false> | undefined;
|
||||||
|
|
||||||
|
if (type == "mute") {
|
||||||
|
timeInMillis = time ? ms(time) : 2419140000; // Timeouts have a limit of 4 weeks
|
||||||
|
} else {
|
||||||
|
timeInMillis = time ? ms(time) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add field for duration if time is specified
|
||||||
|
if (time) embed.addFields({name: 'Duration', value: `${timeInMillis ? `for ${this.client.formatTime(timeInMillis, 4, { longNames: true, commas: true })}` : "forever"}`})
|
||||||
|
|
||||||
|
if (GuildMember) {
|
||||||
|
try {
|
||||||
|
DM = await GuildMember.send(`You've been ${this.getTense(type)} ${['warn', 'mute'].includes(type) ? 'in' : 'from'} ${guild.name}${time ? (timeInMillis ? ` for ${this.client.formatTime(timeInMillis, 4, { longNames: true, commas: true })}` : 'forever') : ''} for reason \`${reason}\` (Case #${punData.id})`);
|
||||||
|
} catch (err: any) {
|
||||||
|
embed.setFooter({text: 'Failed to DM member of punishment'});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (['ban', 'softban'].includes(type)) {
|
||||||
|
const banned = await guild.bans.fetch(User.id).catch(() => undefined);
|
||||||
|
if (!banned) {
|
||||||
|
punResult = await guild.bans.create(User.id, {reason: `${reason} | Case #${punData.id}`}).catch((err: Error) => err.message);
|
||||||
|
} else {
|
||||||
|
punResult = 'User is already banned.';
|
||||||
|
}
|
||||||
|
} else if (type == 'kick') {
|
||||||
|
punResult = await GuildMember?.kick(`${reason} | Case #${punData.id}`).catch((err: Error) => err.message);
|
||||||
|
} else if (type == 'mute') {
|
||||||
|
punResult = await GuildMember?.timeout(timeInMillis, `${reason} | Case #${punData.id}`).catch((err: Error) => err.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == 'softban' && typeof punResult != 'string') { // If type was softban and it was successful, continue with softban (unban)
|
||||||
|
punResult = await guild.bans.remove(User.id, `${reason} | Case #${punData.id}`).catch((err: Error) => err.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timeInMillis && ['mute', 'ban'].includes(type)) { // If type is mute or ban, specify duration and endTime
|
||||||
|
punData.endTime = now + timeInMillis;
|
||||||
|
punData.duration = timeInMillis;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof punResult == 'string') { // Punishment was unsuccessful
|
||||||
|
if (DM) DM.delete();
|
||||||
|
if (interaction) {
|
||||||
|
return interaction.editReply(punResult);
|
||||||
|
} else {
|
||||||
|
return punResult;
|
||||||
|
}
|
||||||
|
} else { // Punishment was successful
|
||||||
|
this.makeModlogEntry(punData);
|
||||||
|
this.client.punishments.addData(punData).forceSave();
|
||||||
|
|
||||||
|
if (interaction) {
|
||||||
|
return interaction.editReply({embeds: [embed]});
|
||||||
|
} else {
|
||||||
|
return punResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
async removePunishment(caseId:number, moderator:any, reason:string):Promise<any>{
|
||||||
|
const now = Date.now()
|
||||||
|
const punishment = this._content.find((x:Punishment)=>x.id === caseId);
|
||||||
|
const id = this.createId();
|
||||||
|
if (!punishment) return 'Punishment not found';
|
||||||
|
if (['ban','mute'].includes(punishment.type)) {
|
||||||
|
const guild = this.client.guilds.cache.get(this.client.config.mainServer.id) as Discord.Guild;
|
||||||
|
let removePunishmentResult;
|
||||||
|
if (punishment.type === 'ban'){
|
||||||
|
removePunishmentResult = await guild.members.unban(punishment.member, `${reason || 'Reason unspecified'} | Case #${id}`).catch((err:TypeError)=>err.message);
|
||||||
|
} else if (punishment.type === 'mute'){
|
||||||
|
const member = await guild.members.fetch(punishment.member).catch(err=>undefined);
|
||||||
|
if (member){
|
||||||
|
removePunishmentResult = await member
|
||||||
|
if (typeof removePunishmentResult !== 'string'){
|
||||||
|
member.timeout(null, `${reason || 'Reason unspecified'} | Case #${id}`)
|
||||||
|
removePunishmentResult.send(`You've been unmuted in ${removePunishmentResult.guild.name}.`);
|
||||||
|
removePunishmentResult = removePunishmentResult.user;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// user probably left, quietly remove punishment
|
||||||
|
const removePunishmentData = {type: `un${punishment.type}`, id, cancels: punishment.id, member: punishment.member, reason, moderator, time: now};
|
||||||
|
this._content[this._content.findIndex((x:Punishment)=>x.id === punishment.id)].expired = true
|
||||||
|
this.addData(removePunishmentData).forceSave();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (typeof removePunishmentResult === 'string') return `Un${punishment.type} was unsuccessful: ${removePunishmentResult}`;
|
||||||
|
else {
|
||||||
|
const removePunishmentData = {type: `un${punishment.type}`, id, cancels: punishment.id, member: punishment.member, reason, moderator, time: now};
|
||||||
|
this.makeModlogEntry(removePunishmentData);
|
||||||
|
this._content[this._content.findIndex((x:Punishment)=>x.id === punishment.id)].expired = true;
|
||||||
|
this.addData(removePunishmentData).forceSave();
|
||||||
|
return `Successfully ${punishment.type === 'ban' ? 'unbanned' : 'unmuted'} **${removePunishmentResult?.tag}** (${removePunishmentResult?.id}) for reason \`${reason || 'Reason unspecified'}\``
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
const removePunishmentData = {type: 'removeOtherPunishment', id, cancels: punishment.id, member: punishment.member, reason, moderator, time: now};
|
||||||
|
this.makeModlogEntry(removePunishmentData);
|
||||||
|
this._content[this._content.findIndex((x:Punishment)=>x.id === punishment.id)].expired = true;
|
||||||
|
this.addData(removePunishmentData).forceSave();
|
||||||
|
return `Successfully removed Case #${punishment.id} (type: ${punishment.type}, user: ${punishment.member}).`;
|
||||||
|
} catch (error:any){
|
||||||
|
return `${punishment.type[0].toUpperCase() + punishment.type.slice(1)} removal was unsuccessful: ${error.message}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user