mirror of
https://github.com/toast-ts/Daggerbot-TS.git
synced 2024-12-26 11:45:37 -05:00
im bit bored now, automod needs investigating.
This commit is contained in:
parent
386ee4f54e
commit
3e94afb222
2
.gitignore
vendored
2
.gitignore
vendored
@ -7,5 +7,3 @@ dist/
|
||||
# Bot stuff
|
||||
src/database/MPDB.dat
|
||||
src/commands/disabled
|
||||
src/commands/roleinfo.ts
|
||||
src/commands/rank.ts
|
@ -1,11 +1,7 @@
|
||||
{
|
||||
"name": "daggerbot-ts",
|
||||
"description": "TypeScript version of the original JavaScript-based bot for Official Daggerwin Discord.",
|
||||
"main": "src/Sharding.ts",
|
||||
"scripts": {
|
||||
"start": "ts-node src/Sharding.ts",
|
||||
"startDev": "ts-node src/index.ts"
|
||||
},
|
||||
"main": "src/index.ts",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/AnxietyisReal/Daggerbot-TS.git"
|
||||
|
@ -1,5 +0,0 @@
|
||||
import {token_toast} from './tokens.json';
|
||||
import {ShardingManager} from 'discord.js';
|
||||
const sharder = new ShardingManager('src/index.ts',{token: token_toast, totalShards: 1, mode: 'worker'});
|
||||
sharder.on('shardCreate',async(shard)=>{console.log(`Shard ${shard.id} launched`)});
|
||||
sharder.spawn();
|
@ -174,7 +174,7 @@ export class TClient extends Client {
|
||||
{name: '\u200b', value: '\u200b', inline: true}
|
||||
)
|
||||
}
|
||||
if (data.cancels) embed.addFields({name: '🔹 Overwrites', value: `This case overwrites Case #${cancels.id} \`${cancels.reason}\``});
|
||||
if (data.cancels) embed.addFields({name: '🔹 Overwrites', value: `This case overwrites Case #${cancels.id}\n\`${cancels.reason}\``});
|
||||
// send embed to log channel
|
||||
(client.channels.cache.get(client.config.mainServer.channels.logs) as Discord.TextChannel).send({embeds: [embed]})
|
||||
}
|
||||
@ -263,7 +263,7 @@ class punishments extends Database {
|
||||
switch (type) {
|
||||
case 'ban':
|
||||
const banData:Punishment={type, id: this.createId(), member: member.id, moderator, time: now};
|
||||
const dm1: Discord.Message = await member.send(`You've been banned from ${interaction.guild.name} ${timeInMillis ? `for ${this.client.formatTime(timeInMillis, 4, {longNames: true, commas: true})} (${timeInMillis}ms)` : 'forever'} for reason \`${reason || 'Reason unspecified'}\` (Case #${banData.id})`).catch(()=>{return interaction.channel.send('Failed to DM user.')})
|
||||
const dm1: Discord.Message = await member.send(`You've been banned from ${interaction.guild.name} ${timeInMillis ? `for ${this.client.formatTime(timeInMillis, 4, {longNames: true, commas: true})}` : 'forever'} for reason \`${reason || 'Reason unspecified'}\` (Case #${banData.id})`).catch(()=>{return interaction.channel.send('Failed to DM user.')})
|
||||
const banResult = await interaction.guild.bans.create(member.id, {reason: `${reason || 'Reason unspecified'} | Case #${banData.id}`}).catch((err:Error)=>err.message);
|
||||
if (typeof banResult === 'string'){
|
||||
dm1.delete()
|
||||
@ -278,13 +278,13 @@ class punishments extends Database {
|
||||
this.addData(banData).forceSave();
|
||||
return new this.client.embed().setColor(this.client.config.embedColor).setTitle(`Case #${banData.id}: Ban`).setDescription(`${member?.user?.tag ?? member?.tag}\n<@${member.id}>\n(\`${member.id}\`)`).addFields(
|
||||
{name: 'Reason', value: `\`${reason || 'Reason unspecified'}\``},
|
||||
{name: 'Duration', value: `${timeInMillis ? `for ${this.client.formatTime(timeInMillis, 4, {longNames: true, commas: true})} (${timeInMillis}ms)` : 'forever'}`}
|
||||
{name: 'Duration', value: `${timeInMillis ? `for ${this.client.formatTime(timeInMillis, 4, {longNames: true, commas: true})}` : 'forever'}`}
|
||||
)
|
||||
}
|
||||
case 'softban':
|
||||
const guild = member.guild;
|
||||
const softbanData:Punishment={type, id: this.createId(), member: member.user.id, moderator, time: now};
|
||||
const dm2 = Discord.Message = await member.send(`You've been softbanned from ${member.guild.name} ${timeInMillis ? `for ${this.client.formatTime(timeInMillis, 4, {longNames: true, commas: true})} (${timeInMillis}ms)` : 'forever'} for reason \`${reason || 'Reason unspecified'}\` (Case #${softbanData.id})`).catch(()=>{return interaction.channel.send('Failed to DM user.')})
|
||||
const dm2 = Discord.Message = await member.send(`You've been softbanned from ${member.guild.name} ${timeInMillis ? `for ${this.client.formatTime(timeInMillis, 4, {longNames: true, commas: true})}` : 'forever'} for reason \`${reason || 'Reason unspecified'}\` (Case #${softbanData.id})`).catch(()=>{return interaction.channel.send('Failed to DM user.')})
|
||||
const softbanResult = await member.ban({deleteMessageDays: 3, reason: `${reason || 'Reason unspecified'} | Case #${softbanData.id}`}).catch((err:Error)=>err.message);
|
||||
if (typeof softbanResult === 'string') {
|
||||
dm2.delete();
|
||||
@ -335,7 +335,7 @@ class punishments extends Database {
|
||||
const muteData:Punishment={type, id: this.createId(), member: member.user.id, moderator, time: now};
|
||||
let muteResult;
|
||||
if (this.client.isStaff(member)) return 'Staff cannot be muted.'
|
||||
const dm4: Discord.Message = await member.send(`You've been muted in ${member.guild.name} ${timeInMillis ? `for ${this.client.formatTime(timeInMillis, 4, {longNames: true, commas: true})} (${timeInMillis}ms)` : 'forever'} for reason \`${reason || 'Reason unspecified'}\` (Case #${muteData.id})`).catch(()=>{interaction.channel.send('Failed to DM user.'); return null});
|
||||
const dm4: Discord.Message = await member.send(`You've been muted in ${member.guild.name} ${timeInMillis ? `for ${this.client.formatTime(timeInMillis, 4, {longNames: true, commas: true})}` : 'forever'} for reason \`${reason || 'Reason unspecified'}\` (Case #${muteData.id})`).catch(()=>{interaction.channel.send('Failed to DM user.'); return null});
|
||||
if (timeInMillis) {
|
||||
muteResult = await member.timeout(timeInMillis, `${reason || 'Reason unspecified'} | Case #${muteData.id}`).catch((err:Error)=>err.message);
|
||||
} else {
|
||||
@ -354,16 +354,57 @@ class punishments extends Database {
|
||||
this.addData(muteData).forceSave();
|
||||
const embedm = new this.client.embed().setColor(this.client.config.embedColor).setTitle(`Case #${muteData.id}: Mute`).setDescription(`${member.user.tag}\n<@${member.user.id}>\n(\`${member.user.id}\`)`).addFields(
|
||||
{name: 'Reason', value: `\`${reason || 'Reason unspecified'}\``},
|
||||
{name: 'Duration',
|
||||
value: `${this.client.formatTime(timeInMillis, 4, {
|
||||
longNames: true,
|
||||
commas: true
|
||||
})} (${timeInMillis}ms)`})
|
||||
{name: 'Duration', value: `${this.client.formatTime(timeInMillis, 4, {longNames: true, commas: true})}`})
|
||||
if (moderator !== '795443537356521502') {return embedm};
|
||||
}
|
||||
}
|
||||
}
|
||||
async removePunishment(caseId:number, moderator:any, reason:string):Promise<any>{}
|
||||
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.client.makeModlogEntry(removePunishmentData, this.client);
|
||||
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.client.makeModlogEntry(removePunishmentData, this.client);
|
||||
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;
|
||||
|
@ -8,5 +8,5 @@ export default {
|
||||
},
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('botlog')
|
||||
.setDescription('Retrieves the log from host and sends it to appropriate channel.')
|
||||
.setDescription('Retrieves the log from host and sends it to development server.')
|
||||
}
|
83
src/commands/case.ts
Normal file
83
src/commands/case.ts
Normal file
@ -0,0 +1,83 @@
|
||||
import Discord,{SlashCommandBuilder} from "discord.js";
|
||||
import { TClient } from 'src/client';
|
||||
import { Punishment } from "src/typings/interfaces";
|
||||
export default {
|
||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||
if (!interaction.member.roles.cache.has(client.config.mainServer.roles.dcmod)) return client.youNeedRole(interaction, 'dcmod')
|
||||
const Subb = interaction.options.getSubcommand();
|
||||
const caseId = interaction.options.getInteger('id');
|
||||
if (Subb == 'update'){
|
||||
const reason = interaction.options.getString('reason')
|
||||
client.punishments._content.find((x:Punishment)=>x.id==caseId).reason = reason;
|
||||
client.punishments.forceSave();
|
||||
const embed = new client.embed().setColor(client.config.embedColorGreen).setTitle('Case updated').setDescription(`Case #${caseId} has been successfully updated with new reason:\n\`${reason}\``);
|
||||
await interaction.reply({embeds: [embed]})
|
||||
} else if (Subb == 'view'){
|
||||
const punishment = client.punishments._content.find((x:Punishment)=>x.id==caseId);
|
||||
if (!punishment) return interaction.reply('Invalid case #');
|
||||
const cancelledBy = punishment.expired ? client.punishments._content.find((x:Punishment)=>x.cancels==punishment.id) : null;
|
||||
const cancels = punishment.cancels ? client.punishments._content.find((x:Punishment)=>x.id==punishment.cancels) : null;
|
||||
const embed = new client.embed().setColor(client.config.embedColor).setTimestamp(punishment.time).setTitle(`${client.formatPunishmentType(punishment, client, cancels)} | Case #${punishment.id}`).addFields(
|
||||
{name: '🔹 User', value: `<@${punishment.member}> \`${punishment.member}\``, inline: true},
|
||||
{name: '🔹 Moderator', value: `<@${punishment.moderator}> \`${punishment.moderator}\``, inline: true},
|
||||
{name: '\u200b', value: '\u200b', inline: true},
|
||||
{name: '🔹 Reason', value: `\`${punishment.reason || 'Reason unspecified'}\``, inline: true})
|
||||
if (punishment.duration){
|
||||
embed.addFields({name: '🔹 Duration', value: client.formatTime(punishment.duration, 100)})
|
||||
}
|
||||
if (punishment.expired) embed.addFields({name: '🔹 Expired', value: `This case has been overwritten by case #${cancelledBy.id} for reason \`${cancelledBy.reason}\``})
|
||||
if (punishment.cancels) embed.addFields({name: '🔹 Overwrites', value: `This case overwrites case #${cancels.id} with reason \`${cancels.reason}\``})
|
||||
interaction.reply({embeds: [embed]});
|
||||
} else {
|
||||
// if caseid is user id, show their punishment history sorted by most recent.
|
||||
const userId = (interaction.options.getUser('user') as Discord.User).id;
|
||||
const userName = (interaction.options.getUser('user') as Discord.User).username;
|
||||
const punishment = client.punishments._content.find((x:Punishment)=>x.member===userId);
|
||||
if (!punishment) return interaction.reply(`<@${userId}> has a clean record.`)
|
||||
const cancels = punishment.cancels ? client.punishments._content.find((x:Punishment)=>x.id==punishment.cancels) : null;
|
||||
const userPunishment = client.punishments._content.filter((x:Punishment)=>x.member==userId).sort((a:Punishment,b:Punishment)=>a.time-b.time).map((punishment:Punishment)=>{
|
||||
return {
|
||||
name: `${client.formatPunishmentType(punishment, client, cancels)} | Case #${punishment.id}`,
|
||||
value: `Reason: \`${punishment.reason}\`\n${punishment.duration ? `Duration: ${client.formatTime(punishment.duration, 3)}\n` : ''}Moderator: <@${punishment.moderator}>${punishment.expired ? `\nOverwritten by case #${client.punishments._content.find((x:Punishment)=>x.cancels==punishment.id).id}` : ''}${punishment.cancels ? `\nOverwrites case #${punishment.cancels}` : ''}`
|
||||
}
|
||||
});
|
||||
// if caseid is not a punishment nor a user, failed
|
||||
if (!userPunishment || userPunishment.length == 0) return interaction.reply('No punishments found for that case # or User ID');
|
||||
|
||||
const pageNum = interaction.options.getInteger('page') ?? 1;
|
||||
const embed = new client.embed().setColor(client.config.embedColor).setTitle(`${userName}'s punishment history`).setDescription(`**ID:** \`${userId}\``).setFooter({text: `${userPunishment.length} total punishments. Viewing page ${pageNum} out of ${Math.ceil(userPunishment.length/6)}.`}).addFields(userPunishment.slice((pageNum - 1) * 6, pageNum * 6));
|
||||
return interaction.reply({embeds: [embed]});
|
||||
}
|
||||
},
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('case')
|
||||
.setDescription('Retrieve case information or user\'s punishment history')
|
||||
.addSubcommand((opt)=>opt
|
||||
.setName('view')
|
||||
.setDescription('View a single case.')
|
||||
.addIntegerOption((optt)=>optt
|
||||
.setName('id')
|
||||
.setDescription('Case #')
|
||||
.setRequired(true)))
|
||||
.addSubcommand((opt)=>opt
|
||||
.setName('member')
|
||||
.setDescription('View member\'s punishment history')
|
||||
.addUserOption((optt)=>optt
|
||||
.setName('user')
|
||||
.setDescription('Which user do you want to view their punishment history?')
|
||||
.setRequired(true))
|
||||
.addIntegerOption((optt)=>optt
|
||||
.setName('page')
|
||||
.setDescription('Select the page number')))
|
||||
.addSubcommand((opt)=>opt
|
||||
.setName('update')
|
||||
.setDescription('Update the case with new reason')
|
||||
.addIntegerOption((optt)=>optt
|
||||
.setName('id')
|
||||
.setDescription('Case # to be updated')
|
||||
.setRequired(true))
|
||||
.addStringOption((optt)=>optt
|
||||
.setName('reason')
|
||||
.setDescription('New reason for the case')
|
||||
.setRequired(true)))
|
||||
};
|
@ -3,6 +3,7 @@ import { TClient } from 'src/client';
|
||||
export default {
|
||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||
const embed = new client.embed().setColor(client.config.embedColor).setTitle('Daggerbot contributors').setDescription([
|
||||
'**Thanks to those below that contributed to the bot!**',
|
||||
'Toast <@190407856527376384>',
|
||||
'TÆMBØ <@615761944154210305>',
|
||||
'Buzz <@593696856165449749>',
|
||||
@ -16,5 +17,5 @@ export default {
|
||||
},
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('contributors')
|
||||
.setDescription('List of people who helped and worked on the bot.')
|
||||
.setDescription('List of people who contributed to the bot.')
|
||||
}
|
39
src/commands/faq.ts
Normal file
39
src/commands/faq.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||
import { TClient } from 'src/client';
|
||||
export default {
|
||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||
const options = interaction.options.getString('question')
|
||||
if (options == 'srp'){
|
||||
const embed = new client.embed().setColor(client.config.embedColor).setTitle('When will SRP (Survival Roleplay) return?').setImage('https://cdn.discordapp.com/attachments/898252602603610142/1013097505094893698/Screenshot_20220827-153617_YouTube.jpg');
|
||||
interaction.reply({embeds: [embed]})
|
||||
} else if (options == 'dlskin'){
|
||||
const embed1 = new client.embed().setColor(client.config.embedColor).setTitle('Hex code for Daggerwin Logistics').setDescription('The main color will be Onyx (`#353839`) with red bumpers').setImage('https://cdn.discordapp.com/attachments/801965516947324969/806871878736019456/image0.png');
|
||||
interaction.reply({embeds: [embed1]})
|
||||
} else if (options == 'vtcR'){
|
||||
interaction.reply(`You can get the <@&${client.config.mainServer.roles.vtcmember}> role from <#802283932430106624> by reacting the ProBot\'s message with :truck:\n*VTC skin can also be found in <#801975222609641472> as well.*`)
|
||||
} else if (options == 'mpR'){
|
||||
interaction.reply(`You can get the <@&${client.config.mainServer.roles.mpplayer}> role from <#802283932430106624> by reacting the ProBot\'s message with :tractor:`)
|
||||
} else if (options == 'fsShader'){
|
||||
const embed2 = new client.embed().setColor(client.config.embedColor).setTitle('Clearing your shader cache folder').setDescription('If your game kees crashing shortly after opening your game, then the shaders might be an issue.\nTo resolve this, you can go to `Documents/My Games/FarmingSimulator2022` and delete the folder called `shader_cache`').setImage('https://cdn.discordapp.com/attachments/1015195575693627442/1015195687970943016/unknown.png');
|
||||
interaction.reply({embeds: [embed2]})
|
||||
} else if (options == 'fsLogfile'){
|
||||
const embed3 = new client.embed().setColor(client.config.embedColor).setTitle('Uploading your log file').setDescription('You can find `log.txt` in `Documents/My Games/FarmingSimulator2022` and upload it into <#596989522395398144> along with your issue, so people can assist you further and help you resolve.').setImage('https://cdn.discordapp.com/attachments/1015195575693627442/1015195643528101958/unknown.png');
|
||||
interaction.reply({embeds: [embed3]})
|
||||
}
|
||||
},
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('faq')
|
||||
.setDescription('List of FAQ for users')
|
||||
.addStringOption((opt)=>opt
|
||||
.setName('question')
|
||||
.setDescription('What question do you want answered?')
|
||||
.addChoices(
|
||||
{ name: 'Survival Roleplay', value: 'srp' },
|
||||
{ name: 'Daggerwin Logistics hex code', value: 'dlskin' },
|
||||
{ name: 'VTC Role', value: 'vtcR' },
|
||||
{ name: 'MP Role', value: 'mpR' },
|
||||
{ name: '[FS22] Resolve shader_cache issue', value: 'fsShader' },
|
||||
{ name: '[FS22] Log file location', value: 'fsLogfile' }
|
||||
))
|
||||
|
||||
}
|
@ -3,7 +3,7 @@ import { TClient } from 'src/client';
|
||||
import MPDB from '../models/MPServer';
|
||||
export default {
|
||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||
if (interaction.guildId !== client.config.mainServer.id) return interaction.reply('This command doesn\'t work in this server.');
|
||||
if (interaction.guildId !== client.config.mainServer.id) return interaction.reply({content: 'This command doesn\'t work in this server.', ephemeral: true});
|
||||
if (!interaction.member.roles.cache.has(client.config.mainServer.roles.mpmanager) && !interaction.member.roles.cache.has(client.config.mainServer.roles.bottech) && !interaction.member.roles.cache.has(client.config.mainServer.roles.admin)) return client.youNeedRole(interaction, 'mpmanager');
|
||||
|
||||
MPDB.sync();
|
||||
|
37
src/commands/purge.ts
Normal file
37
src/commands/purge.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||
import { TClient } from 'src/client';
|
||||
export default {
|
||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||
if (!client.isStaff(interaction.member)) return client.youNeedRole(interaction, 'dcmod');
|
||||
const amount = interaction.options.getInteger('amount') as number;
|
||||
if (amount > 100) return interaction.reply({content: 'Discord API limits purging up to 100 messages.', ephemeral: true})
|
||||
const user = interaction.options.getUser('user');
|
||||
|
||||
let messagesArray: Array<string> = [];
|
||||
|
||||
if (user){
|
||||
(interaction.channel as Discord.TextChannel).messages.fetch({limit: 100}).then((msgs)=>{
|
||||
const msgList = msgs.filter(x=>x.author.id == user.id);
|
||||
(interaction.channel as Discord.TextChannel).bulkDelete(msgList);
|
||||
})
|
||||
} else {
|
||||
(interaction.channel as Discord.TextChannel).messages.fetch({limit: amount}).then(async messages=>{
|
||||
messages.forEach(message=>{
|
||||
messagesArray.push(message.id);
|
||||
});
|
||||
await (interaction.channel as Discord.TextChannel).bulkDelete(messagesArray);
|
||||
})
|
||||
}
|
||||
await interaction.reply({content: `Successfully purged ${amount} messages.`, ephemeral: true})
|
||||
},
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('purge')
|
||||
.setDescription('Purge the amount of messages in this channel')
|
||||
.addIntegerOption((opt)=>opt
|
||||
.setName('amount')
|
||||
.setDescription('Amount of messages to be obliterated')
|
||||
.setRequired(true))
|
||||
.addUserOption((opt)=>opt
|
||||
.setName('user')
|
||||
.setDescription('Which user to have their messages obliterated?'))
|
||||
}
|
192
src/commands/rank.ts
Normal file
192
src/commands/rank.ts
Normal file
@ -0,0 +1,192 @@
|
||||
interface UserLevels {
|
||||
messages: number,
|
||||
level: number
|
||||
}
|
||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||
import { TClient } from 'src/client';
|
||||
export default {
|
||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||
if (interaction.guildId !== client.config.mainServer.id) return interaction.reply({content: 'This command doesn\'t work in this server.', ephemeral: true});
|
||||
const subCmd = interaction.options.getSubcommand();
|
||||
|
||||
if (subCmd === "leaderboard") {
|
||||
const messageCountsTotal = Object.values<UserLevels>(client.userLevels._content).reduce((a, b) => a + b.messages, 0);
|
||||
const timeActive = Math.floor((Date.now() - client.config.LRSstart)/1000/60/60/24);
|
||||
|
||||
const data = require('../database/dailyMsgs.json').map((x: Array<number>, i: number, a: any) => {
|
||||
const yesterday = a[i - 1] || [];
|
||||
return x[1] - (yesterday[1] || x[1]);
|
||||
}).slice(1).slice(-60);
|
||||
|
||||
// handle negative days
|
||||
data.forEach((change: number, i: number) => {
|
||||
if (change < 0) data[i] = data[i - 1] || data[i + 1] || 0;
|
||||
});
|
||||
|
||||
const maxValue = Math.max(...data);
|
||||
const maxValueArr = maxValue.toString().split('');
|
||||
|
||||
const first_graph_top = Math.ceil(maxValue * 10 ** (-maxValueArr.length + 1)) * 10 ** (maxValueArr.length - 1);
|
||||
// console.log({ first_graph_top });
|
||||
|
||||
const second_graph_top = Math.ceil(maxValue * 10 ** (-maxValueArr.length + 2)) * 10 ** (maxValueArr.length - 2);
|
||||
// console.log({ second_graph_top });
|
||||
|
||||
const textSize = 32;
|
||||
|
||||
const canvas = require('canvas');
|
||||
const img = canvas.createCanvas(950, 450);
|
||||
const ctx = img.getContext('2d');
|
||||
|
||||
const graphOrigin = [10, 50];
|
||||
const graphSize = [700, 360];
|
||||
const nodeWidth = graphSize[0] / (data.length - 1);
|
||||
ctx.fillStyle = '#36393f';
|
||||
ctx.fillRect(0, 0, img.width, img.height);
|
||||
|
||||
// grey horizontal lines
|
||||
ctx.lineWidth = 3;
|
||||
|
||||
let interval_candidates = [];
|
||||
for (let i = 4; i < 10; i++) {
|
||||
const interval = first_graph_top / i;
|
||||
if (Number.isInteger(interval)) {
|
||||
let intervalString = interval.toString();
|
||||
const reference_number = i * Math.max(intervalString.split('').filter(x => x === '0').length / intervalString.length, 0.3) * (['1', '2', '4', '5', '6', '8'].includes(intervalString[0]) ? 1.5 : 0.67)
|
||||
interval_candidates.push([interval, i, reference_number]);
|
||||
}
|
||||
}
|
||||
// console.log({ interval_candidates });
|
||||
const chosen_interval = interval_candidates.sort((a, b) => b[2] - a[2])[0];
|
||||
// console.log({ chosen_interval });
|
||||
|
||||
let previousY: Array<number> = [];
|
||||
|
||||
ctx.strokeStyle = '#202225';
|
||||
for (let i = 0; i <= chosen_interval[1]; i++) {
|
||||
const y = graphOrigin[1] + graphSize[1] - (i * (chosen_interval[0] / second_graph_top) * graphSize[1]);
|
||||
if (y < graphOrigin[1]) continue;
|
||||
const even = ((i + 1) % 2) === 0;
|
||||
if (even) ctx.strokeStyle = '#2c2f33';
|
||||
ctx.beginPath();
|
||||
ctx.lineTo(graphOrigin[0], y);
|
||||
ctx.lineTo(graphOrigin[0] + graphSize[0], y);
|
||||
ctx.stroke();
|
||||
ctx.closePath();
|
||||
if (even) ctx.strokeStyle = '#202225';
|
||||
previousY = [y, i * chosen_interval[0]];
|
||||
}
|
||||
|
||||
// 30d mark
|
||||
ctx.setLineDash([8, 16]);
|
||||
ctx.beginPath();
|
||||
const lastMonthStart = graphOrigin[0] + (nodeWidth * (data.length - 30));
|
||||
ctx.lineTo(lastMonthStart, graphOrigin[1]);
|
||||
ctx.lineTo(lastMonthStart, graphOrigin[1] + graphSize[1]);
|
||||
ctx.stroke();
|
||||
ctx.closePath();
|
||||
ctx.setLineDash([]);
|
||||
|
||||
// draw points
|
||||
ctx.strokeStyle = client.config.embedColor;
|
||||
ctx.fillStyle = client.config.embedColor;
|
||||
ctx.lineWidth = 3;
|
||||
|
||||
|
||||
function getYCoordinate(value: number) {
|
||||
return ((1 - (value / second_graph_top)) * graphSize[1]) + graphOrigin[1];
|
||||
}
|
||||
|
||||
let lastCoords: Array<number> = [];
|
||||
data.forEach((val: number, i: number) => {
|
||||
ctx.beginPath();
|
||||
if (lastCoords) ctx.moveTo(...lastCoords);
|
||||
if (val < 0) val = 0;
|
||||
const x = i * nodeWidth + graphOrigin[0];
|
||||
const y = getYCoordinate(val);
|
||||
ctx.lineTo(x, y);
|
||||
lastCoords = [x, y];
|
||||
ctx.stroke();
|
||||
ctx.closePath();
|
||||
|
||||
// ball
|
||||
ctx.beginPath();
|
||||
ctx.arc(x, y, ctx.lineWidth * 1.2, 0, 2 * Math.PI)
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
});
|
||||
|
||||
// draw text
|
||||
ctx.font = '400 ' + textSize + 'px sans-serif';
|
||||
ctx.fillStyle = 'white';
|
||||
|
||||
// highest value
|
||||
//console.log(previousY)
|
||||
const maxx = graphOrigin[0] + graphSize[0] + textSize;
|
||||
const maxy = previousY[0] + (textSize / 3);
|
||||
ctx.fillText(previousY[1].toLocaleString('en-US'), maxx, maxy);
|
||||
|
||||
// lowest value
|
||||
const lowx = graphOrigin[0] + graphSize[0] + textSize;
|
||||
const lowy = graphOrigin[1] + graphSize[1] + (textSize / 3);
|
||||
ctx.fillText('0 msgs/day', lowx, lowy);
|
||||
|
||||
// 30d
|
||||
ctx.fillText('30d ago', lastMonthStart, graphOrigin[1] - (textSize / 3));
|
||||
|
||||
// time ->
|
||||
const tx = graphOrigin[0] + (textSize / 2);
|
||||
const ty = graphOrigin[1] + graphSize[1] + (textSize);
|
||||
ctx.fillText('time ->', tx, ty);
|
||||
|
||||
const yeahok = new client.attachmentBuilder(img.toBuffer(), {name: "dailymsgs.png"})
|
||||
const embed = new client.embed()
|
||||
.setTitle('Ranking leaderboard')
|
||||
.setDescription(`Level System was created **${timeActive}** days ago. Since then, a total of **${messageCountsTotal.toLocaleString('en-US')}** messages have been sent in this server.`)
|
||||
.addFields({name: 'Top users by messages sent:', value: Object.entries<UserLevels>(client.userLevels._content).sort((a, b) => b[1].messages - a[1].messages).slice(0, 10).map((x, i) => `\`${i + 1}.\` <@${x[0]}>: ${x[1].messages.toLocaleString('en-US')}`).join('\n')})
|
||||
.setImage('attachment://dailymsgs.png')
|
||||
.setColor(client.config.embedColor)
|
||||
interaction.reply({embeds: [embed], files: [yeahok]});
|
||||
return;
|
||||
} else if (subCmd === "view") {
|
||||
|
||||
// fetch user or user interaction sender
|
||||
const member = interaction.options.getMember("member") ?? interaction.member as Discord.GuildMember;
|
||||
|
||||
const embed = new client.embed().setColor(member.displayColor)
|
||||
|
||||
// information about users progress on level roles
|
||||
const information = client.userLevels._content[member.user.id];
|
||||
|
||||
const pronounBool = (you: string, they: string) => { // takes 2 words and chooses which to use based on if user did this command on themself
|
||||
if (interaction.user.id === member.user.id) return you || true;
|
||||
else return they || false;
|
||||
};
|
||||
|
||||
if (!information) {
|
||||
return interaction.reply(`${pronounBool('You', 'They')} currently don't have a level, send some messages to level up.`)
|
||||
}
|
||||
|
||||
const index = Object.entries<UserLevels>(client.userLevels._content).sort((a, b) => b[1].messages - a[1].messages).map(x => x[0]).indexOf(member.id) + 1;
|
||||
const memberDifference = information.messages - client.userLevels.algorithm(information.level);
|
||||
const levelDifference = client.userLevels.algorithm(information.level+1) - client.userLevels.algorithm(information.level);
|
||||
|
||||
embed.setThumbnail(member.user.avatarURL({ extension: 'png', size: 256}) || member.user.defaultAvatarURL)
|
||||
embed.setAuthor({name: `Ranking for ${member.user.tag}`})
|
||||
embed.setTitle(`Level: **${information.level}**\nRank: **${index ? '#' + index : 'last'}**\nProgress: **${information.messages - client.userLevels.algorithm(information.level)}/${client.userLevels.algorithm(information.level+1) - client.userLevels.algorithm(information.level)} (${(memberDifference/levelDifference*100).toFixed(2)}%)**\nTotal: **${information.messages}**`);
|
||||
interaction.reply({embeds: [embed]});
|
||||
}
|
||||
},
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('rank')
|
||||
.setDescription('Level system')
|
||||
.addSubcommand((optt)=>optt
|
||||
.setName('view')
|
||||
.setDescription('View your rank, someone else\'s rank')
|
||||
.addUserOption((opt)=>opt
|
||||
.setName('member')
|
||||
.setDescription('Which member do you want to view?')))
|
||||
.addSubcommand((optt)=>optt
|
||||
.setName('leaderboard')
|
||||
.setDescription('View top 10 users on leaderboard'))
|
||||
}
|
25
src/commands/roleinfo.ts
Normal file
25
src/commands/roleinfo.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||
import { TClient } from 'src/client';
|
||||
export default {
|
||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||
const role = interaction.options.getRole('role') as Discord.Role;
|
||||
const keyPerms = ['Administrator', 'KickMembers', 'BanMembers', 'ManageChannels', 'ManageGuild', 'ViewAuditLog', 'ManageMessages', 'MentionEveryone', 'UseExternalEmojis', 'ManageRoles', 'Manage EmojiandStickers', 'ModerateMembers']
|
||||
const permissions = role.permissions.toArray();
|
||||
const Role = role.members.map((e:Discord.GuildMember)=>`**${e.user.tag}**`).join('\n') || '';
|
||||
const embed = new client.embed().setColor(role.color || '#fefefe').setThumbnail(role?.iconURL()).setTitle(`Role Info: ${role.name}`).addFields(
|
||||
{name: '🔹 ID', value: `\`${role.id}\``, inline: true},
|
||||
{name: '🔹 Color', value: `\`${role.hexColor}\``, inline: true},
|
||||
{name: '🔹 Creation Date', value: `<t:${Math.round(role.createdTimestamp/1000)}>\n<t:${Math.round(role.createdTimestamp/1000)}:R>`, inline: true},
|
||||
{name: '🔹 Misc', value: `Hoist: \`${role.hoist}\`\nMentionable: \`${role.mentionable}\`\nPosition: \`${role.position}\` from bottom\nMembers: \`${role.members.size}\`\n${role.members.size < 21 ? Role : ''}`, inline: true},
|
||||
{name: '🔹 Permissions', value: (permissions.includes('Administrator') ? ['Administrator'] : permissions.filter((x:string)=>keyPerms.includes(x))).map((x:string)=>{return x.split('_').map((y,i)=>y).join(' ')}).join(', ') || 'None', inline: true}
|
||||
)
|
||||
interaction.reply({embeds: [embed]})
|
||||
},
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('roleinfo')
|
||||
.setDescription('View information about the selected role')
|
||||
.addRoleOption((opt)=>opt
|
||||
.setName('role')
|
||||
.setDescription('Role name to view information')
|
||||
.setRequired(true))
|
||||
}
|
11
src/commands/smell.ts
Normal file
11
src/commands/smell.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||
import { TClient } from 'src/client';
|
||||
export default {
|
||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||
const embed = new client.embed().setColor(client.config.embedColor).setTitle('Who smells?').setDescription('Dave and Monster! (Monster smells of staircases)').setImage('https://media.tenor.com/QW9S-Oq9INQAAAAC/patrick-smell.gif')
|
||||
interaction.reply({embeds: [embed]});
|
||||
},
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('smell')
|
||||
.setDescription('Who smells?')
|
||||
}
|
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
[[0,674965],[1,675885],[2,676639],[3,677245],[4,677609],[5,678188],[6,678916],[7,679465],[8,679938],[9,680540],[10,681614],[11,682079],[12,682780],[13,683187],[14,683547],[15,683900],[16,684592],[17,685466],[18,686078],[19,686481],[20,676748],[21,676968],[22,677427],[23,677592],[24,677894],[25,678116],[26,676785],[27,677570],[28,678491],[29,679137],[30,679818],[31,680094],[32,680417],[33,680783],[34,681563],[35,682070],[36,682670],[37,683504],[38,684078],[39,684383],[40,684692],[41,685448],[42,685664],[43,685994],[44,686366],[45,687118],[46,687626],[47,688008],[48,688754],[49,688942],[50,689107],[51,689472],[52,690143],[53,690644],[54,691124],[55,692196],[56,692624],[57,692906],[58,693456],[59,693952],[60,694586],[61,695070],[62,696163],[63,696564],[64,697315],[65,698548],[66,699138],[67,699558],[68,700307],[69,701063],[70,701394],[71,701868],[72,702453],[73,702917],[76,705187],[77,705243],[78,705488],[79,705961],[80,706585],[81,707467],[82,708212],[83,709024],[84,709773],[85,710256],[86,710980]]
|
||||
[[0,674965],[1,675885],[2,676639],[3,677245],[4,677609],[5,678188],[6,678916],[7,679465],[8,679938],[9,680540],[10,681614],[11,682079],[12,682780],[13,683187],[14,683547],[15,683900],[16,684592],[17,685466],[18,686078],[19,686481],[20,676748],[21,676968],[22,677427],[23,677592],[24,677894],[25,678116],[26,676785],[27,677570],[28,678491],[29,679137],[30,679818],[31,680094],[32,680417],[33,680783],[34,681563],[35,682070],[36,682670],[37,683504],[38,684078],[39,684383],[40,684692],[41,685448],[42,685664],[43,685994],[44,686366],[45,687118],[46,687626],[47,688008],[48,688754],[49,688942],[50,689107],[51,689472],[52,690143],[53,690644],[54,691124],[55,692196],[56,692624],[57,692906],[58,693456],[59,693952],[60,694586],[61,695070],[62,696163],[63,696564],[64,697315],[65,698548],[66,699138],[67,699558],[68,700307],[69,701063],[70,701394],[71,701868],[72,702453],[73,702917],[76,705187],[77,705243],[78,705488],[79,705961],[80,706585],[81,707467],[82,708212],[83,709024],[84,709773],[85,710256],[86,710980],[87,711220]]
|
@ -1,30 +1,30 @@
|
||||
{
|
||||
"190407856527376384": {
|
||||
"messages": 53029,
|
||||
"messages": 53026,
|
||||
"level": 59
|
||||
},
|
||||
"593696856165449749": {
|
||||
"messages": 51456,
|
||||
"messages": 51467,
|
||||
"level": 58
|
||||
},
|
||||
"141304507249197057": {
|
||||
"messages": 67631,
|
||||
"messages": 67632,
|
||||
"level": 67
|
||||
},
|
||||
"533707949831487488": {
|
||||
"messages": 57038,
|
||||
"messages": 57042,
|
||||
"level": 61
|
||||
},
|
||||
"532662366354276352": {
|
||||
"messages": 33775,
|
||||
"messages": 33785,
|
||||
"level": 47
|
||||
},
|
||||
"824043915539513406": {
|
||||
"messages": 18452,
|
||||
"messages": 18457,
|
||||
"level": 35
|
||||
},
|
||||
"178941218510602240": {
|
||||
"messages": 6394,
|
||||
"messages": 6396,
|
||||
"level": 20
|
||||
},
|
||||
"215497515934416896": {
|
||||
@ -32,15 +32,15 @@
|
||||
"level": 46
|
||||
},
|
||||
"301350210926280704": {
|
||||
"messages": 14334,
|
||||
"messages": 14343,
|
||||
"level": 30
|
||||
},
|
||||
"695323013813633076": {
|
||||
"messages": 14090,
|
||||
"messages": 14092,
|
||||
"level": 30
|
||||
},
|
||||
"389237487094071337": {
|
||||
"messages": 12254,
|
||||
"messages": 12256,
|
||||
"level": 28
|
||||
},
|
||||
"716355511552966737": {
|
||||
@ -68,7 +68,7 @@
|
||||
"level": 20
|
||||
},
|
||||
"475037861725339649": {
|
||||
"messages": 10201,
|
||||
"messages": 10207,
|
||||
"level": 26
|
||||
},
|
||||
"392699530912727041": {
|
||||
@ -76,15 +76,15 @@
|
||||
"level": 18
|
||||
},
|
||||
"468837263577579524": {
|
||||
"messages": 7695,
|
||||
"messages": 7696,
|
||||
"level": 22
|
||||
},
|
||||
"734703851558535188": {
|
||||
"messages": 20211,
|
||||
"messages": 20224,
|
||||
"level": 36
|
||||
},
|
||||
"488683638310043677": {
|
||||
"messages": 15477,
|
||||
"messages": 15478,
|
||||
"level": 32
|
||||
},
|
||||
"606595407769894995": {
|
||||
@ -92,7 +92,7 @@
|
||||
"level": 39
|
||||
},
|
||||
"322835877027905547": {
|
||||
"messages": 10019,
|
||||
"messages": 10021,
|
||||
"level": 25
|
||||
},
|
||||
"485793265568841728": {
|
||||
@ -100,7 +100,7 @@
|
||||
"level": 50
|
||||
},
|
||||
"837979120142778388": {
|
||||
"messages": 3636,
|
||||
"messages": 3637,
|
||||
"level": 15
|
||||
},
|
||||
"509467946146332682": {
|
||||
@ -112,7 +112,7 @@
|
||||
"level": 18
|
||||
},
|
||||
"690090143008555064": {
|
||||
"messages": 9978,
|
||||
"messages": 9981,
|
||||
"level": 25
|
||||
},
|
||||
"849633082440941628": {
|
||||
@ -124,7 +124,7 @@
|
||||
"level": 6
|
||||
},
|
||||
"452576735494406175": {
|
||||
"messages": 1684,
|
||||
"messages": 1685,
|
||||
"level": 10
|
||||
},
|
||||
"763055599654666291": {
|
||||
@ -148,8 +148,8 @@
|
||||
"level": 0
|
||||
},
|
||||
"169891949464125441": {
|
||||
"messages": 538,
|
||||
"level": 5
|
||||
"messages": 541,
|
||||
"level": 6
|
||||
},
|
||||
"718453763932946432": {
|
||||
"messages": 13549,
|
||||
@ -164,7 +164,7 @@
|
||||
"level": 6
|
||||
},
|
||||
"931816463113814066": {
|
||||
"messages": 673,
|
||||
"messages": 674,
|
||||
"level": 6
|
||||
},
|
||||
"958108557503524904": {
|
||||
@ -224,11 +224,11 @@
|
||||
"level": 0
|
||||
},
|
||||
"528003225375473674": {
|
||||
"messages": 79,
|
||||
"messages": 80,
|
||||
"level": 2
|
||||
},
|
||||
"645342896312156181": {
|
||||
"messages": 693,
|
||||
"messages": 696,
|
||||
"level": 6
|
||||
},
|
||||
"488505753133645826": {
|
||||
@ -236,7 +236,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"313461397457600512": {
|
||||
"messages": 79,
|
||||
"messages": 80,
|
||||
"level": 2
|
||||
},
|
||||
"848489550065827850": {
|
||||
@ -272,8 +272,8 @@
|
||||
"level": 1
|
||||
},
|
||||
"771433946890108989": {
|
||||
"messages": 21,
|
||||
"level": 0
|
||||
"messages": 22,
|
||||
"level": 1
|
||||
},
|
||||
"847575717369872384": {
|
||||
"messages": 10,
|
||||
@ -348,7 +348,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"549295707304099846": {
|
||||
"messages": 46,
|
||||
"messages": 47,
|
||||
"level": 1
|
||||
},
|
||||
"759390179064283178": {
|
||||
@ -512,7 +512,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"660117183699091506": {
|
||||
"messages": 9,
|
||||
"messages": 10,
|
||||
"level": 0
|
||||
},
|
||||
"634416842152345630": {
|
||||
@ -524,7 +524,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"398164488077180938": {
|
||||
"messages": 8,
|
||||
"messages": 9,
|
||||
"level": 0
|
||||
},
|
||||
"818595993121062974": {
|
||||
@ -540,7 +540,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"869718328313278555": {
|
||||
"messages": 98,
|
||||
"messages": 101,
|
||||
"level": 2
|
||||
},
|
||||
"772197160372404234": {
|
||||
@ -1340,7 +1340,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"98464148379148288": {
|
||||
"messages": 1504,
|
||||
"messages": 1507,
|
||||
"level": 10
|
||||
},
|
||||
"1025723411680460840": {
|
||||
@ -1472,7 +1472,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"889624632724963329": {
|
||||
"messages": 51,
|
||||
"messages": 54,
|
||||
"level": 1
|
||||
},
|
||||
"687692546314600530": {
|
||||
@ -1856,7 +1856,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"1031950921233600662": {
|
||||
"messages": 17,
|
||||
"messages": 19,
|
||||
"level": 1
|
||||
},
|
||||
"907951346769092618": {
|
||||
@ -1924,7 +1924,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"813866707365265419": {
|
||||
"messages": 114,
|
||||
"messages": 119,
|
||||
"level": 2
|
||||
},
|
||||
"726188513518813275": {
|
||||
@ -2048,7 +2048,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"1023915974690340946": {
|
||||
"messages": 21,
|
||||
"messages": 22,
|
||||
"level": 1
|
||||
},
|
||||
"871113268633174128": {
|
||||
@ -2312,7 +2312,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"231907580748759040": {
|
||||
"messages": 2,
|
||||
"messages": 3,
|
||||
"level": 0
|
||||
},
|
||||
"461177771801182223": {
|
||||
@ -2320,7 +2320,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"1029465066174677132": {
|
||||
"messages": 11,
|
||||
"messages": 12,
|
||||
"level": 0
|
||||
},
|
||||
"387345064927428611": {
|
||||
@ -2544,7 +2544,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"697953686487564348": {
|
||||
"messages": 123,
|
||||
"messages": 128,
|
||||
"level": 2
|
||||
},
|
||||
"664233182941413427": {
|
||||
@ -2592,7 +2592,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"340587045250531358": {
|
||||
"messages": 86,
|
||||
"messages": 90,
|
||||
"level": 2
|
||||
},
|
||||
"911709434554777660": {
|
||||
@ -2680,7 +2680,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"999736341220839464": {
|
||||
"messages": 9,
|
||||
"messages": 11,
|
||||
"level": 0
|
||||
},
|
||||
"901565970974392331": {
|
||||
@ -2700,7 +2700,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"995622955897864272": {
|
||||
"messages": 92,
|
||||
"messages": 96,
|
||||
"level": 2
|
||||
},
|
||||
"153323923633733632": {
|
||||
@ -2772,6 +2772,10 @@
|
||||
"level": 0
|
||||
},
|
||||
"248226483967885312": {
|
||||
"messages": 3,
|
||||
"level": 0
|
||||
},
|
||||
"985545842368864326": {
|
||||
"messages": 2,
|
||||
"level": 0
|
||||
}
|
||||
|
@ -7,10 +7,12 @@ export default {
|
||||
const channel = client.channels.resolve(client.config.mainServer.channels.logs) as Discord.TextChannel;
|
||||
if (msg.partial) return;
|
||||
if (msg.author.bot) return;
|
||||
const embed = new client.embed().setColor(client.config.embedColorRed).setTimestamp().setAuthor({name: `Author: ${msg.author.tag} (${msg.author.id})`, iconURL: `${msg.author.displayAvatarURL()}`}).setTitle('Message deleted').setDescription(`<@${msg.author.id}>\nContent:\n\`\`\`\n${msg.content}\n\`\`\`\nChannel: <#${msg.channelId}>`)
|
||||
channel.send({embeds: [embed]})
|
||||
const embed = new client.embed().setColor(client.config.embedColorRed).setTimestamp().setAuthor({name: `Author: ${msg.author.tag} (${msg.author.id})`, iconURL: `${msg.author.displayAvatarURL()}`}).setTitle('Message deleted').setDescription(`<@${msg.author.id}>\nContent:\n\`\`\`\n${msg?.content}\n\`\`\`\nChannel: <#${msg.channelId}>`)
|
||||
let image;
|
||||
if (msg.attachments?.first()?.width && ['png', 'jpeg', 'jpg', 'gif', 'webp'].some(x=>((msg.attachments.first() as Discord.Attachment).name as string).endsWith(x))) {
|
||||
embed.setImage(`${[msg.attachments?.first() as Discord.Attachment]}`)
|
||||
}
|
||||
image = msg.attachments?.first().url
|
||||
embed.setImage(image)
|
||||
}
|
||||
channel.send({embeds: [embed]})
|
||||
}
|
||||
}
|
@ -5,11 +5,11 @@ export default {
|
||||
execute: async(client:TClient, messages:Discord.Collection<Snowflake, Message>)=>{
|
||||
const channel = client.channels.resolve(client.config.mainServer.channels.logs) as Discord.TextChannel;
|
||||
if (!client.config.botSwitches.logs) return;
|
||||
let text = '';
|
||||
let msgArray: Array<string> = [];
|
||||
messages.forEach((m)=>{
|
||||
text += `${m.author.username}: ${m.content}\n`;
|
||||
msgArray.push(`${m.author.username}: ${m.content}`);
|
||||
});
|
||||
const embed = new client.embed().setColor(client.config.embedColorRed).setTimestamp().setTitle(`${messages.size} messages were purged`).setDescription(`\`\`\`${text}\`\`\``.slice(0,3900)).addFields({name: 'Channel', value: `<#${(messages.first() as Discord.Message).channel.id}>`});
|
||||
const embed = new client.embed().setColor(client.config.embedColorRed).setTimestamp().setTitle(`${messages.size} messages were purged`).setDescription(`\`\`\`${msgArray.reverse().join('\n')}\`\`\``.slice(0,3900)).addFields({name: 'Channel', value: `<#${(messages.first() as Discord.Message).channel.id}>`});
|
||||
channel.send({embeds: [embed]})
|
||||
}
|
||||
}
|
17
src/index.ts
17
src/index.ts
@ -1,15 +1,10 @@
|
||||
interface punOpt {
|
||||
time?: string,
|
||||
reason?: string,
|
||||
interaction?: any
|
||||
}
|
||||
import Discord from 'discord.js';
|
||||
import { TClient } from './client';
|
||||
const client = new TClient;
|
||||
client.init();
|
||||
import fs from 'node:fs';
|
||||
import MPDB from './models/MPServer';
|
||||
import { Punishment } from './typings/interfaces';
|
||||
import { Punishment, punOpt } from './typings/interfaces';
|
||||
|
||||
client.on('ready', async()=>{
|
||||
client.guilds.cache.forEach(async(e: { members: { fetch: () => any; }; })=>{await e.members.fetch()});
|
||||
@ -190,7 +185,7 @@ Object.assign(client.punishments,{
|
||||
const banData: Punishment = {type, id: this.createId(), member: member.id, moderator, time: now};
|
||||
let dm1:any;
|
||||
try {
|
||||
dm1 = await member.send(`You've been banned from ${interaction.guild.name} ${timeInMillis ? `for ${client.formatTime(timeInMillis, 4, {longNames: true, commas: true})} (${timeInMillis}ms)` : 'forever'} for reason \`${reason || 'Reason unspecified'}\` (Case #${banData.id})`)
|
||||
dm1 = await member.send(`You've been banned from ${interaction.guild.name} ${timeInMillis ? `for ${client.formatTime(timeInMillis, 4, {longNames: true, commas: true})}` : 'forever'} for reason \`${reason || 'Reason unspecified'}\` (Case #${banData.id})`)
|
||||
} catch (err) {
|
||||
setTimeout(()=>interaction.channel.send('Failed to DM user.'), 500)
|
||||
}
|
||||
@ -209,7 +204,7 @@ Object.assign(client.punishments,{
|
||||
this.forceSave();
|
||||
return new client.embed().setColor(client.config.embedColor).setTitle(`Case #${banData.id}: Ban`).setDescription(`${member.tag}\n<@${member.id}>\n(\`${member.id}\`)`).addFields(
|
||||
{name: 'Reason', value: `\`${reason || 'Reason unspecified'}\``},
|
||||
{name: 'Duration', value: `${timeInMillis ? `for ${client.formatTime(timeInMillis, 4, {longNames: true, commas: true})} (${timeInMillis}ms)` : 'forever'}`}
|
||||
{name: 'Duration', value: `${timeInMillis ? `for ${client.formatTime(timeInMillis, 4, {longNames: true, commas: true})}` : 'forever'}`}
|
||||
)
|
||||
}
|
||||
case 'softban':
|
||||
@ -253,7 +248,7 @@ Object.assign(client.punishments,{
|
||||
case 'mute':
|
||||
const muteData: Punishment = {type, id: this.createId(), member: member.user.id, moderator, time: now};
|
||||
let muteResult;
|
||||
const dm4 = await member.send(`You've been muted in ${member.guild.name} ${timeInMillis ? `for ${client.formatTime(timeInMillis, 4, {longNames: true, commas: true})} (${timeInMillis}ms)` : 'forever'} for reason \`${reason || 'Reason unspecified'}\` (Case #${muteData.id})`).catch((err:Error)=>setTimeout(()=>interaction.channel.send('Failed to DM user.'), 500));
|
||||
const dm4 = await member.send(`You've been muted in ${member.guild.name} ${timeInMillis ? `for ${client.formatTime(timeInMillis, 4, {longNames: true, commas: true})}` : 'forever'} for reason \`${reason || 'Reason unspecified'}\` (Case #${muteData.id})`).catch((err:Error)=>setTimeout(()=>interaction.channel.send('Failed to DM user.'), 500));
|
||||
if (timeInMillis){
|
||||
muteResult = await member.timeout(timeInMillis, `${reason || 'Reason unspecified'} | Case #${muteData.id}`).catch((err: Error)=>err.message);
|
||||
} else {
|
||||
@ -273,7 +268,7 @@ Object.assign(client.punishments,{
|
||||
this.forceSave();
|
||||
const embedm = new client.embed().setColor(client.config.embedColor).setTitle(`Case #${muteData.id}: Mute`).setDescription(`${member.user.tag}\n<@${member.user.id}>\n(\`${member.user.id}\`)`).addFields(
|
||||
{name: 'Reason', value: `\`${reason || 'Reason unspecified'}\``},
|
||||
{name: 'Duration', value: `${client.formatTime(timeInMillis, 4, {longNames: true, commas: true})} (${timeInMillis}ms)`}
|
||||
{name: 'Duration', value: `${client.formatTime(timeInMillis, 4, {longNames: true, commas: true})}`}
|
||||
)
|
||||
if (moderator !== '795443537356521502') {return embedm};
|
||||
}
|
||||
@ -328,7 +323,7 @@ Object.assign(client.punishments,{
|
||||
client.makeModlogEntry(removePunishmentData, client);
|
||||
this._content[this._content.findIndex(x=>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'}\``;
|
||||
return `Successfully ${punishment.type === 'ban' ? 'unbanned' : 'unmuted'} **${removePunishmentResult?.tag}** (\`${removePunishmentResult?.id}\`) for reason \`${reason || 'Reason unspecified'}\``;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
|
Loading…
Reference in New Issue
Block a user