1
0
mirror of https://github.com/toast-ts/Daggerbot-TS.git synced 2024-11-17 04:10:59 -05:00

Compare commits

..

3 Commits

Author SHA1 Message Date
AnxietyisReal
c4b5d59033 Add dedicated class for music module 2023-08-30 10:34:22 +10:00
AnxietyisReal
159d4e68d6 Forgot the index.ts 2023-08-30 10:25:44 +10:00
AnxietyisReal
51629142ec Create MessageTool 2023-08-30 10:21:53 +10:00
11 changed files with 63 additions and 45 deletions

View File

@ -1,11 +1,12 @@
import Discord from 'discord.js';
import TClient from '../client.js';
import MessageTool from '../helpers/MessageTool.js';
export default {
run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
interaction.reply({embeds: [new client.embed().setColor(client.config.embedColor).setTitle('Daggerbot contributors').setDescription([
interaction.reply({embeds: [new client.embed().setColor(client.config.embedColor).setTitle('Daggerbot contributors').setDescription(MessageTool.concatMessage(
'**Thanks to those below that contributed to/developed the bot!**',
client.config.contribList.map(id=>{const member = interaction.guild.members.cache.get(id); return `${member?.user?.username ?? 'N/A'} <@${id}>`}).join('\n')
].join('\n'))]})
))]})
},
data: new Discord.SlashCommandBuilder()
.setName('contributors')

View File

@ -2,6 +2,7 @@ import Discord from 'discord.js';
import {Octokit} from '@octokit/rest';
import {createTokenAuth} from '@octokit/auth-token';
import {exec} from 'node:child_process';
import MessageTool from '../helpers/MessageTool.js';
import fs from 'node:fs';
import util from 'node:util';
import TClient from '../client.js';
@ -92,13 +93,13 @@ export default {
if (name) currentActivities[0].name = name;
if (url) currentActivities[0].url = url;
client.user.setPresence(client.config.botPresence);
interaction.reply([
interaction.reply(MessageTool.concatMessage(
'Presence updated:',
`Status: **${client.config.botPresence.status}**`,
`Type: **${convertType(currentActivities[0].type)}**`,
`Name: **${currentActivities[0].name}**`,
`URL: \`${currentActivities[0].url}\``
].join('\n'))
))
},
statsgraph: ()=>{
client.statsGraph = -(interaction.options.getInteger('number', true));

View File

@ -1,14 +1,9 @@
import Discord from 'discord.js';
import TClient from '../client.js';
import MessageTool from '../helpers/MessageTool.js';
export default {
run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
function faqEmbed(color:Discord.ColorResolvable,title:string,description?:string|null,image?:string|null){
const embed = new client.embed().setColor(color).setTitle(title);
if (description) embed.setDescription(description);
if (image) embed.setImage(image);
return embed
} // I am loving this fancy idea, pretty simplified!
const joinVerifyFaqDesc = [
const verifyFaq = MessageTool.concatMessage(
'```ansi',
'Steam (Top panel)',
'1. Go to your game library and right click on Farming Simulator 22',
@ -21,17 +16,17 @@ export default {
'2. Click on Manage and click on "Verify"',
'3. Epic Launcher will scan your game installation directory and will re-download anything that is corrupted or tampered with.',
'```'
].join('\n');
);
({
srp: ()=>interaction.reply('[Ballyspring](<https://www.farming-simulator.com/mod.php?mod_id=270745>) is the map that is used in Survival Roleplay S4.\n\n> __Note__\n> The map won\'t look closely like the one in SRP as it is privately edited version of the public map.'),
vtcR: ()=>interaction.reply(`You can get the <@&${client.config.mainServer.roles.vtcmember}> role from <#802283932430106624> by clicking :truck: button on a webhook's message\n*VTC skin can also be found in <#801975222609641472> as well.*`),
mpR: ()=>interaction.reply(`You can get the <@&${client.config.mainServer.roles.mpplayer}> role from <#802283932430106624> by clicking :tractor: button on webhook's message`),
ytscam: ()=>interaction.reply({embeds: [faqEmbed(client.config.embedColor, 'Scammers in YouTube comments section', 'If you ever see a comment mentioning a giveaway or anything else, **it\'s a scam!**\nYou should report it to YouTube and move on or ignore it.\nP.S: They\'re on every channel and not just Daggerwin.', 'https://cdn.discordapp.com/attachments/1015195575693627442/1068078284996345916/image.png')]}),
steamscam: ()=>interaction.reply({embeds: [faqEmbed(client.config.embedColor, 'Steam account report scam', 'If you received a DM about this, please report it to Discord Moderators or open a [ticket](https://discord.com/channels/468835415093411861/942173932339986472/1054128182468546631)', 'https://cdn.discordapp.com/attachments/1091300529696673792/1122266621088645130/image.png')]}),
fsVerifyGame: ()=>interaction.reply({embeds: [faqEmbed(client.config.embedColor, 'Verifying your game files', `You can verify your game files if you experience any issues with your game.\n${joinVerifyFaqDesc}`, 'https://cdn.discordapp.com/attachments/1015195575693627442/1138185771971526757/Steam-Epic-VerifyGamesLocation.png')]}),
fsShader: ()=>interaction.reply({embeds: [faqEmbed(client.config.embedColor, 'Clearing your shader cache folder', 'If your game keeps 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`', 'https://cdn.discordapp.com/attachments/1015195575693627442/1015195687970943016/unknown.png')]}),
fsLogfile: ()=>interaction.reply({embeds: [faqEmbed(client.config.embedColor, 'Uploading your log file', '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.', 'https://cdn.discordapp.com/attachments/1015195575693627442/1015195643528101958/unknown.png')]}),
fsDevConsole: ()=>interaction.reply({embeds: [faqEmbed(client.config.embedColor, 'Enabling the development console', 'Head over to `game.xml` in `Documents/My Games/FarmingSimulator2022` and find the section that mentions `<controls>false</controls>` inside development section, change it to `true` then you are good to go!\nFYI: The keybind to open console is \``\u200b\` (backtick).', 'https://cdn.discordapp.com/attachments/1015195575693627442/1097273921444790322/image.png')]})
ytscam: ()=>interaction.reply({embeds: [MessageTool.embedStruct(client.config.embedColor, 'Scammers in YouTube comments section', 'If you ever see a comment mentioning a giveaway or anything else, **it\'s a scam!**\nYou should report it to YouTube and move on or ignore it.\nP.S: They\'re on every channel and not just Daggerwin.', 'https://cdn.discordapp.com/attachments/1015195575693627442/1068078284996345916/image.png')]}),
steamscam: ()=>interaction.reply({embeds: [MessageTool.embedStruct(client.config.embedColor, 'Steam account report scam', 'If you received a DM about this, please report it to Discord Moderators or open a [ticket](https://discord.com/channels/468835415093411861/942173932339986472/1054128182468546631)', 'https://cdn.discordapp.com/attachments/1091300529696673792/1122266621088645130/image.png')]}),
fsVerifyGame: ()=>interaction.reply({embeds: [MessageTool.embedStruct(client.config.embedColor, 'Verifying your game files', `You can verify your game files if you experience any issues with your game.\n${verifyFaq}`, 'https://cdn.discordapp.com/attachments/1015195575693627442/1138185771971526757/Steam-Epic-VerifyGamesLocation.png')]}),
fsShader: ()=>interaction.reply({embeds: [MessageTool.embedStruct(client.config.embedColor, 'Clearing your shader cache folder', 'If your game keeps 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`', 'https://cdn.discordapp.com/attachments/1015195575693627442/1015195687970943016/unknown.png')]}),
fsLogfile: ()=>interaction.reply({embeds: [MessageTool.embedStruct(client.config.embedColor, 'Uploading your log file', '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.', 'https://cdn.discordapp.com/attachments/1015195575693627442/1015195643528101958/unknown.png')]}),
fsDevConsole: ()=>interaction.reply({embeds: [MessageTool.embedStruct(client.config.embedColor, 'Enabling the development console', 'Head over to `game.xml` in `Documents/My Games/FarmingSimulator2022` and find the section that mentions `<controls>false</controls>` inside development section, change it to `true` then you are good to go!\nFYI: The keybind to open console is \``\u200b\` (backtick).', 'https://cdn.discordapp.com/attachments/1015195575693627442/1097273921444790322/image.png')]})
} as any)[interaction.options.getString('question', true)]();
},
data: new Discord.SlashCommandBuilder()

View File

@ -1,16 +1,17 @@
import Discord from 'discord.js';
import TClient from '../client.js';
import MessageTool from '../helpers/MessageTool.js';
export default {
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
await client.fetchInvite(interaction.options.getString('code',true).replace(/(https:\/\/|discord.gg\/)/g,'')).then(async inviteData=>
await interaction.reply({embeds:[new client.embed()
.setColor(client.config.embedColor).setURL(`https://discord.gg/${inviteData.code}`).setTitle(inviteData.guild.name).setDescription([
.setColor(client.config.embedColor).setURL(`https://discord.gg/${inviteData.code}`).setTitle(inviteData.guild.name).setDescription(MessageTool.concatMessage(
`ID: \`${inviteData.guild.id}\``,
`Description: \`\`\`${inviteData.guild.description != null ? inviteData.guild.description : 'No description set.'}`,
`\`\`\`Total server boosts: \`${inviteData.guild.premiumSubscriptionCount}\``,
`Total members: \`${inviteData.presenceCount}\`**/**\`${inviteData.memberCount}\``,
`Channel: \`#${inviteData.channel.name}\``,
].join('\n')).setThumbnail(inviteData.guild.iconURL({size:1024,extension:'webp'})).setImage(inviteData.guild.bannerURL({size:2048,extension:'webp'}))
)).setThumbnail(inviteData.guild.iconURL({size:1024,extension:'webp'})).setImage(inviteData.guild.bannerURL({size:2048,extension:'webp'}))
]})).catch((err:Discord.DiscordAPIError)=>interaction.reply(err.message));
},
data: new Discord.SlashCommandBuilder()

View File

@ -2,6 +2,7 @@ import Discord from 'discord.js';
import TClient from '../client.js';
import path from 'node:path';
import canvas from 'canvas';
import MessageTool from '../helpers/MessageTool.js';
import {readFileSync} from 'node:fs';
import {FSData} from 'src/typings/interfaces.js';
@ -178,7 +179,7 @@ export default {
info: async()=>{
if (!endpoint) return console.log('Endpoint failed - info')
if (endpoint.server.name.length < 1) embed.setFooter({text: 'Server is currently offline.'})
interaction.reply({embeds: [embed.setColor(client.config.embedColor).setDescription([
interaction.reply({embeds: [embed.setColor(client.config.embedColor).setDescription(MessageTool.concatMessage(
`**Server name**: \`${endpoint?.server.name.length === 0 ? '\u200b' : endpoint.server.name}\``,
'**Password:** `mf4700`',
'**Crossplay server**',
@ -186,7 +187,7 @@ export default {
`**Mods:** [Click here](${database[serverSelector].ip}/mods.html) **|** [Direct Download](${database[serverSelector].ip}/all_mods_download?onlyActive=true)`,
'**Filters:** [Click here](https://discord.com/channels/468835415093411861/468835769092669461/926581585938120724)',
'Please see <#543494084363288637> for additional information.'
].join('\n'))]});
))]});
},
/* url: async()=>{
if (client.config.mainServer.id == interaction.guildId) {

View File

@ -1,5 +1,6 @@
import Discord from 'discord.js';
import pkg from 'typescript';
import MessageTool from '../helpers/MessageTool.js';
import si from 'systeminformation';
import TClient from '../client.js';
import os from 'node:os';
@ -15,7 +16,7 @@ export default {
const columns = ['Command name', 'Count'];
const includedCommands = client.commands.filter(x=>x.uses).sort((a,b)=>b.uses - a.uses);
if (includedCommands.size === 0) return interaction.reply(`No commands have been used yet.\nUptime: **${client.formatTime(client.uptime as number, 3, {longNames: true, commas: true})}**`);
if (includedCommands.size === 0) return interaction.reply(`No commands have been used yet.\nUptime: **${client.formatTime(client.uptime, 3, {longNames: true, commas: true})}**`);
const nameLength = Math.max(...includedCommands.map(x=>x.command.default.data.name.length), columns[0].length) + 2;
const amountLength = Math.max(...includedCommands.map(x=>x.uses.toString().length), columns[1].length) + 1;
const rows = [`${columns[0] + ' '.repeat(nameLength - columns[0].length)}|${' '.repeat(amountLength - columns[1].length) + columns[1]}\n`, '-'.repeat(nameLength) + '-'.repeat(amountLength) + '\n'];
@ -25,10 +26,10 @@ export default {
rows.push(`${name + ' '.repeat(nameLength - name.length)}${' '.repeat(amountLength - count.length) + count}\n`);
});
const embed = new client.embed().setColor(client.config.embedColor).setTitle('Statistics: Command Usage')
.setDescription([
.setDescription(MessageTool.concatMessage(
'List of commands that have been used in this session, ordered by amount of use. Table contains command name and amount of uses.',
`Total amount of commands used in this session: ${client.commands.filter(x=>x.uses).map(x=>x.uses).reduce((a,b)=>a+b, 0)}`
].join('\n'))
));
if (rows.join('').length > 1024){
let fieldValue = '';
rows.forEach(row=>{
@ -40,20 +41,20 @@ export default {
embed.addFields({name: '\u200b', value: `\`\`\`\n${fieldValue}\`\`\``});
} else embed.addFields({name: '\u200b', value: `\`\`\`\n${rows.join('')}\`\`\``});
embed.addFields(
{name: '> __Dependencies__', value: [
{name: '> __Dependencies__', value: MessageTool.concatMessage(
`**TypeScript:** ${pkg.version}`,
`**NodeJS:** ${process.version}`,
`**DiscordJS:** ${Discord.version}`,
`**Yarn:** ${packageJson.packageManager.slice(5)}`
].join('\n')},
{name: '> __Host__', value: [
)},
{name: '> __Host__', value: MessageTool.concatMessage(
`**Operating System:** ${osInfo.distro + ' ' + osInfo.release}`,
`**CPU:** ${cpu.manufacturer} ${cpu.brand}`,
`**Memory:** ${client.formatBytes(ram.used)}/${client.formatBytes(ram.total)}`,
`**Process:** ${client.formatBytes(process.memoryUsage().heapUsed)}/${client.formatBytes(process.memoryUsage().heapTotal)}`,
`**Load Usage:**\nUser: ${currentLoad.currentLoadUser.toFixed(1)}%\nSystem: ${currentLoad.currentLoadSystem.toFixed(1)}%`,
`**Uptime:**\nHost: ${client.formatTime((os.uptime()*1000), 2, {longNames: true, commas: true})}\nBot: ${client.formatTime(client.uptime, 2, {commas: true, longNames: true})}`
].join('\n')}
)}
);
waitForData.edit({content:null,embeds:[embed]}).then(x=>x.edit({embeds:[new client.embed(x.embeds[0].data).setFooter({text: `Load time: ${client.formatTime(x.createdTimestamp - interaction.createdTimestamp, 2, {longNames: true, commas: true})}`})]}))
},

View File

@ -1,5 +1,6 @@
import Discord from 'discord.js';
import TClient from '../client.js';
import MessageTool from '../helpers/MessageTool.js';
export default {
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
const replyInDM = interaction.options.getString('message');
@ -20,10 +21,10 @@ export default {
.setTitle(`Suggestion ID: ${suggestionID}`)
.setAuthor({name: interaction.user.username, iconURL: interaction.user.avatarURL({size: 256})})
.setFooter({text: `Timestamp: ${timeFormatting}`})
.setDescription([
.setDescription(MessageTool.concatMessage(
'> **Suggestion:**',
suggestionText
].join('\n'));
));
if (suggestionImage) notifEmbed.setImage(suggestionImage.url);
webhook.send({embeds: [notifEmbed], username: `${client.user.username} Notification`, avatarURL: client.user.avatarURL({size: 256})}
).catch(e=>{

View File

@ -1,5 +1,6 @@
import Discord from 'discord.js';
import TClient from '../client.js';
import MessageTool from '../helpers/MessageTool.js';
export default {
async autocomplete(client: TClient, interaction: Discord.AutocompleteInteraction){
const array = (await client.tags?._content.find())?.map(x=>x._id).filter(c=>c.startsWith(interaction.options.getFocused()));
@ -22,13 +23,13 @@ export default {
const targetMember = interaction.options.getMember('target_user');
if (targetMember) targetField = `*This tag is for <@${targetMember.id}>*`;
const embedTemplate = new client.embed().setColor(client.config.embedColor).setTitle(await tagMeta.title()).setDescription(await tagMeta.message()).setFooter({text: `Tag creator: ${await tagMeta.creatorName()}`});
const messageTemplate = [
const messageTemplate = MessageTool.concatMessage(
targetField ? targetField : '',
`**${await tagMeta.title()}**`,
await tagMeta.message(),
'',
`Tag creator: **${await tagMeta.creatorName()}**`
].join('\n');
);
if (await tagMeta.isEmbedTrue()) return interaction.reply({content: targetField ? targetField : null, embeds: [embedTemplate], allowedMentions:{parse:['users']}});
else return interaction.reply({content: messageTemplate, allowedMentions:{parse:['users']}})
},

View File

@ -1,5 +1,6 @@
import Discord from 'discord.js';
import TClient from '../client.js';
import MessageTool from '../helpers/MessageTool.js';
export default {
async run(client:TClient, member:Discord.GuildMember){
if (member.partial || member.guild?.id != client.config.mainServer.id) return;
@ -27,10 +28,10 @@ export default {
{name: '🔹 Invite Data:', value: usedInvite ? `Invite: \`${usedInvite.code}\`\nCreated by: **${usedInvite.inviter?.username}**\nChannel: **#${usedInvite.channel.name}**` : 'No invite data could be fetched.'}
)]});
if (await client.punishments._content.findOne({'member': member.user.id, type: 'mute', expired: undefined})){
(client.channels.resolve(client.config.mainServer.channels.dcmod_chat) as Discord.TextChannel).send({embeds: [new client.embed().setColor(client.config.embedColorYellow).setTitle('Case evasion detected').setDescription([
(client.channels.resolve(client.config.mainServer.channels.dcmod_chat) as Discord.TextChannel).send({embeds: [new client.embed().setColor(client.config.embedColorYellow).setTitle('Case evasion detected').setDescription(MessageTool.concatMessage(
`**${member.user.username}** (\`${member.user.id}\`) has been detected for case evasion.`,
'Timeout has been automatically added. (25 days)'
].join('\n')).setTimestamp()]});
)).setTimestamp()]});
await client.punishments.addPunishment('mute', {time: '25d'}, client.user.id, '[AUTOMOD] Case evasion', member.user, member)
}
}

View File

@ -0,0 +1,20 @@
import Discord from 'discord.js';
export default class MessageTool {
static embedMusic(color:Discord.ColorResolvable, title:string, thumbnail?:string, footer?:string){
const embed = new Discord.EmbedBuilder().setColor(color).setTitle(title);
if (thumbnail) embed.setThumbnail(thumbnail);
if (footer) embed.setFooter({text: footer});
return embed
}
static embedStruct(color:Discord.ColorResolvable, title:string, description?:string|null, image?:string|null){
const embed = new Discord.EmbedBuilder().setColor(color).setTitle(title);
if (description) embed.setDescription(description);
if (image) embed.setImage(image);
return embed
}
static concatMessage(...messages:string[]){
return messages.join('\n')
}
}
// I want to come up with better name instead of calling this file "MessageTool", but I am super bad at naming things.

View File

@ -5,6 +5,7 @@ client.init();
import MPLoop from './funcs/MPLoop.js';
import {Player} from 'discord-player';
const player = Player.singleton(client);
import MessageTool from './helpers/MessageTool.js';
import {writeFileSync, readFileSync} from 'node:fs';
// Error handler
@ -24,19 +25,13 @@ client.on('error', (error: Error)=>DZ(error, 'clientError'));
// Audio Player event handling
if (client.config.botSwitches.music){
const playerEmbed =(color:Discord.ColorResolvable,title:string,thumbnail?:string,footer?:string)=>{
const embed = new client.embed().setColor(color).setTitle(title);
if (thumbnail) embed.setThumbnail(thumbnail);
if (footer) embed.setFooter({text:footer})
return embed
}
player.events.on('playerStart', (queue,track)=>queue.channel.send({embeds:[playerEmbed(client.config.embedColor, `Next up: ${track.raw.title} - ${track.raw.author}`,track.raw.thumbnail)]}));
player.events.on('audioTrackAdd', (queue,track)=>queue.channel.send({embeds:[playerEmbed(client.config.embedColorGreen, `Added: ${track.raw.title} - ${track.raw.author}`,track.raw.thumbnail)]}));
player.events.on('audioTrackRemove', (queue, track)=>queue.channel.send({embeds:[playerEmbed(client.config.embedColor, `Removed: ${track.raw.title} - ${track.raw.author}`,track.raw.thumbnail)]}));
player.events.on('playerStart', (queue,track)=>queue.channel.send({embeds:[MessageTool.embedMusic(client.config.embedColor, `Next up: ${track.raw.title} - ${track.raw.author}`,track.raw.thumbnail)]}));
player.events.on('audioTrackAdd', (queue,track)=>queue.channel.send({embeds:[MessageTool.embedMusic(client.config.embedColorGreen, `Added: ${track.raw.title} - ${track.raw.author}`,track.raw.thumbnail)]}));
player.events.on('audioTrackRemove', (queue, track)=>queue.channel.send({embeds:[MessageTool.embedMusic(client.config.embedColor, `Removed: ${track.raw.title} - ${track.raw.author}`,track.raw.thumbnail)]}));
player.events.on('emptyQueue', queue=>{
if (queue.tracks.size < 1) return queue.channel.send('There\'s no songs left in the queue, leaving voice channel in 15 seconds.').then(()=>setTimeout(()=>queue.connection.disconnect(), 15000))
});
player.events.on('playerPause', queue=>queue.channel.send({embeds:[playerEmbed(client.config.embedColor, 'Player has been paused.\nRun the command to unpause it')]}));
player.events.on('playerPause', queue=>queue.channel.send({embeds:[MessageTool.embedMusic(client.config.embedColor, 'Player has been paused.\nRun the command to unpause it')]}));
player.events.on('playerError', (queue, error)=>DZ(error, 'playerError')); // I don't know if both of these actually works, because most
player.events.on('error', (queue, error)=>DZ(error, 'playerInternalError')); // errors from the player is coming from unhandledRejection
}