1
0
mirror of https://github.com/musix-org/musix-oss synced 2024-09-19 22:11:55 +00:00

Fix code to work on this decade 1/x

This commit is contained in:
Christer Warén 2024-02-09 11:53:30 +02:00
parent d609687957
commit 9049a5e6b8
53 changed files with 2455 additions and 1704 deletions

View File

@ -1,12 +1,18 @@
const { Client, Collection } = require('discord.js'); const { Client, Collection } = require('discord.js');
const admin = require('firebase-admin'); const admin = require('firebase-admin');
const serviceAccount = require('./serviceAccount.json'); require('dotenv/config');
module.exports = class extends Client { module.exports = class extends Client {
constructor() { constructor() {
super({ super({
disableEveryone: true, intents: [
disabledEvents: ['TYPING_START'] "Guilds",
"GuildMessages",
"GuildVoiceStates",
"MessageContent"
],
disableMentions: "everyone",
disabledEvents: ["TYPING_START"]
}); });
this.commands = new Collection(); this.commands = new Collection();
@ -26,15 +32,9 @@ module.exports = class extends Client {
this.funcs.handleVideo = require('./funcs/handleVideo.js'); this.funcs.handleVideo = require('./funcs/handleVideo.js');
this.funcs.play = require('./funcs/play.js'); this.funcs.play = require('./funcs/play.js');
this.funcs.msToTime = require('./funcs/msToTime.js'); this.funcs.msToTime = require('./funcs/msToTime.js');
this.funcs.dbget = require('./funcs/dbget.js');
this.funcs.exe = require('./funcs/exe.js'); this.funcs.exe = require('./funcs/exe.js');
this.funcs.ffmpeg = require('./funcs/ffmpeg.js');
admin.initializeApp({ this.config = require('./config.js');
credential: admin.credential.cert(serviceAccount),
});
this.db = admin.firestore();
this.global = { this.global = {
db: { db: {
@ -43,6 +43,16 @@ module.exports = class extends Client {
}, },
}; };
this.db.FieldValue = require('firebase-admin').firestore.FieldValue; if(this.config.firebase.serviceAccount){
this.funcs.dbget = require('./funcs/dbget.js');
admin.initializeApp({
credential: admin.credential.cert(this.config.firebase.serviceAccount),
});
this.db = admin.firestore();
this.db.FieldValue = require('firebase-admin').firestore.FieldValue;
}
} }
}; };

View File

@ -3,6 +3,9 @@ FROM docker.io/node:20-alpine
#Dependencies #Dependencies
RUN apk add --virtual .build-deps python3 make g++ gcc git RUN apk add --virtual .build-deps python3 make g++ gcc git
#Code Dependencies
RUN apk add --virtual .code-deps ffmpeg
WORKDIR /usr/src/app WORKDIR /usr/src/app
COPY / /usr/src/app/ COPY / /usr/src/app/

View File

@ -1,16 +0,0 @@
module.exports = function (message, args, client, Discord, prefix, command) {
const permissions = message.channel.permissionsFor(message.client.user);
if (!permissions.has('EMBED_LINKS')) return message.channel.send(':x: I cannot send embeds (Embed links), make sure I have the proper permissions!');
try {
command.uses++;
command.execute(message, args, client, Discord, prefix);
} catch (error) {
message.reply(`:x: there was an error trying to execute that command! Please contact support with \`${prefix}bug\`!`);
const embed = new Discord.RichEmbed()
.setTitle(`Musix ${error.toString()}`)
.setDescription(error.stack.replace(/at /g, '**at **'))
.setColor('#b50002');
client.fetchUser(client.config.devId).then(user => user.send(embed)).catch(console.error);
client.channels.get(client.config.debug_channel).send(embed);
}
};

View File

@ -1,7 +0,0 @@
module.exports = async function (client) {
try {
await client.channels.get('570531724002328577').join()
} catch (error) {
client.channels.get(client.config.debug_channel).send("Error detected: " + error);
}
};

View File

@ -1,40 +0,0 @@
module.exports = async function (guild, song, client, message, seek, play) {
const Discord = require('discord.js');
const ytdl = require('ytdl-core');
const serverQueue = client.queue.get(guild.id);
if (!song) {
console.log('No song')
serverQueue.voiceChannel.leave();
client.queue.delete(guild.id);
return;
}
const dispatcher = serverQueue.connection
.playStream(ytdl(song.url, { filter: "audio", highWaterMark: 1 << 25 }), { seek: seek, bitrate: 1024, passes: 10, volume: 1 })
.on("end", reason => {
if (reason === "Stream is not generating quickly enough.") {
console.log("Song ended");
} else if (reason === "seek") {
return;
} else {
console.log(reason);
}
serverQueue.playing = false;
if (serverQueue.looping) {
serverQueue.songs.push(serverQueue.songs[0]);
}
serverQueue.songs.shift();
client.funcs.play(guild, serverQueue.songs[0], client, message);
});
dispatcher.setVolume(serverQueue.volume / 10);
dispatcher.on("error", error => console.error(error));
if (client.global.db.guilds[guild.id].startPlaying || play) {
let data = await Promise.resolve(ytdl.getInfo(serverQueue.songs[0].url));
let songtime = (data.length_seconds * 1000).toFixed(0);
const embed = new Discord.RichEmbed()
.setTitle(`:musical_note: Start playing: **${song.title}**`)
.setDescription(`Song duration: \`${client.funcs.msToTime(songtime)}\``)
.setColor("#b50002")
serverQueue.textChannel.send(embed);
}
serverQueue.playing = true;
}

View File

@ -1,14 +0,0 @@
module.exports = {
name: 'bug',
description: 'Report a bug',
alias: 'bug',
cooldown: 5,
onlyDev: false,
async execute(message, args, client, Discord, prefix) {
const embed = new Discord.RichEmbed()
.setTitle(`Found a bug with ${client.user.username}?\nDM the core developer:`)
.setDescription(`Matte#0002\nOr join the support server: https://discord.gg/rvHuJtB`)
.setColor(client.config.embedColor);
message.channel.send(embed);
},
};

View File

@ -1,9 +1,11 @@
const { EmbedBuilder } = require("discord.js");
module.exports = { module.exports = {
name: 'cmduses', name: 'cmduses',
usage: '', usage: '',
description: 'Command usage statistics', description: 'Command usage statistics',
uses: 0, uses: 0,
async execute(msg, args, client, Discord) { async execute(msg, args, client) {
const cmduses = []; const cmduses = [];
client.commands.forEach((value, key) => { client.commands.forEach((value, key) => {
cmduses.push([key, value.uses]); cmduses.push([key, value.uses]);
@ -17,12 +19,12 @@ module.exports = {
cmduses.forEach(x => { cmduses.forEach(x => {
if (x[1] > 0) markdownrows.push(x[0] + '.'.repeat(cmdnamelength - x[0].length) + ' '.repeat(numberlength - x[1].toString().length) + x[1].toString()); if (x[1] > 0) markdownrows.push(x[0] + '.'.repeat(cmdnamelength - x[0].length) + ' '.repeat(numberlength - x[1].toString().length) + x[1].toString());
}); });
const embed = new Discord.RichEmbed(); const embed = new EmbedBuilder();
embed embed
.setTitle('Musix Command Usage During Current Uptime') .setTitle('Musix Command Usage During Current Uptime')
.setDescription('```ml\n' + markdownrows.join('\n') + '\n```') .setDescription('```ml\n' + markdownrows.join('\n') + '\n```')
.setFooter('These statistics are from the current uptime.') .setFooter({ text: 'These statistics are from the current uptime.' })
.setColor(client.config.embedColor); .setColor(client.config.embedColor);
msg.channel.send(embed); msg.channel.send({ embeds: [embed] });
}, },
}; };

View File

@ -1,26 +0,0 @@
module.exports = {
name: 'eval',
description: 'Evaluation command',
alias: 'eval',
cooldown: 5,
onlyDev: true,
async execute(message, args, client, Discord, prefix) {
const ytdl = require('ytdl-core');
const serverQueue = client.queue.get(message.guild.id);
if (serverQueue) {
let data = await Promise.resolve(ytdl.getInfo(serverQueue.songs[0].url));
}
const input = message.content.slice(prefix.length + 4);
let output;
try {
output = await eval(input);
} catch (error) {
output = error.toString();
}
const embed = new Discord.RichEmbed()
.setTitle('Evaluation Command')
.setColor(client.config.embedColor)
.setDescription(`Input: \`\`\`js\n${input.replace(/; /g, ';').replace(/;/g, ';\n')}\n\`\`\`\nOutput: \`\`\`\n${output}\n\`\`\``);
return message.channel.send(embed);
},
};

View File

@ -1,11 +0,0 @@
module.exports = {
name: 'forcestop',
description: 'force stop command.',
alias: 'fs',
cooldown: 5,
onlyDev: true,
execute(message, args, client, Discord, prefix) {
client.queue.delete(message.guild.id);
message.channel.send('queue deleted')
}
};

View File

@ -1,29 +1,32 @@
const { EmbedBuilder } = require("discord.js");
module.exports = { module.exports = {
name: 'help', name: 'help',
description: 'Help command.', description: 'Help command.',
alias: 'help', alias: 'help',
cooldown: 5, cooldown: 5,
onlyDev: false, execute(message, args, client, prefix) {
execute(message, args, client, Discord, prefix) { const embed = new EmbedBuilder()
const embed = new Discord.RichEmbed()
.setTitle(`Commands for ${client.user.username}!`) .setTitle(`Commands for ${client.user.username}!`)
.addField(`${prefix}play | ${prefix}p`, 'Play a song.', true) .addFields(
.addField(`${prefix}skip | ${prefix}s`, 'Skip a song.', true) { name: `${prefix}play | ${prefix}p`, value: 'Play a song.', inline: true },
.addField(`${prefix}queue | ${prefix}q`, 'Display the queue.', true) { name: `${prefix}skip | ${prefix}s`, value: 'Skip a song.', inline: true },
.addField(`${prefix}nowplaying | ${prefix}np`, 'Display what\'s currently playing.', true) { name: `${prefix}queue | ${prefix}q`, value: 'Display the queue.', inline: true },
.addField(`${prefix}remove | ${prefix}rm`, 'Remove songs from the queue.', true) { name: `${prefix}nowplaying | ${prefix}np`, value: 'Display what\'s currently playing.', inline: true },
.addField(`${prefix}volume`, 'Change or check the volume.', true) { name: `${prefix}remove | ${prefix}rm`, value: 'Remove songs from the queue.', inline: true },
.addField(`${prefix}pause`, 'Pause the music.', true) { name: `${prefix}volume`, value: 'Change or check the volume.', inline: true },
.addField(`${prefix}resume`, 'Resume the music.', true) { name: `${prefix}pause`, value: 'Pause the music.', inline: true },
.addField(`${prefix}loop`, 'Loop the queue.', true) { name: `${prefix}resume`, value: 'Resume the music.', inline: true },
.addField(`${prefix}stop`, 'Stop the music, Clear the queue and leave the current voice channel.', true) { name: `${prefix}loop`, value: 'Loop the queue.', inline: true },
.addField(`${prefix}invite`, 'Invite Musix.', true) { name: `${prefix}seek`, value: 'Seek music.', inline: true },
.addField(`${prefix}status`, 'See different information for Musix.', true) { name: `${prefix}stop`, value: 'Stop the music, Clear the queue and leave the current voice channel.', inline: true },
.addField(`${prefix}bug`, 'Report a bug.', true) { name: `${prefix}invite`, value: 'Invite Musix.', inline: true },
.addField(`${prefix}settings`, 'Change the guild specific settings.', true) { name: `${prefix}status`, value: 'See different information for Musix.', inline: true },
.addField(`${prefix}help`, 'Display the help.', true) { name: `${prefix}settings`, value: 'Change the guild specific settings.', inline: true },
.setAuthor(message.member.username, message.member.displayAvatarURL) { name: `${prefix}help`, value: 'Display the help.', inline: true }
)
.setAuthor({ name: client.user.username, iconURL: client.user.avatarURL()})
.setColor(client.config.embedColor) .setColor(client.config.embedColor)
return message.channel.send(embed); return message.channel.send({ embeds: [embed] });
} }
}; };

View File

@ -1,14 +1,15 @@
const { EmbedBuilder } = require("discord.js");
module.exports = { module.exports = {
name: 'invite', name: 'invite',
description: 'Invite command.', description: 'Invite command.',
alias: 'invite', alias: 'invite',
cooldown: 5, cooldown: 5,
onlyDev: false, execute(message, args, client, prefix) {
execute(message, args, client, Discord, prefix) { const embed = new EmbedBuilder()
const embed = new Discord.RichEmbed()
.setTitle(`Invite ${client.user.username} to your Discord server!`) .setTitle(`Invite ${client.user.username} to your Discord server!`)
.setURL(client.config.invite) .setURL(`https://discord.com/oauth2/authorize?client_id=${client.user.id}&permissions=2184465408&scope=applications.commands+bot`)
.setColor(client.config.embedColor) .setColor(client.config.embedColor)
return message.channel.send(embed); return message.channel.send({ embeds: [embed] });
} }
}; };

View File

@ -1,28 +1,27 @@
const { PermissionFlagsBits } = require('discord.js');
module.exports = { module.exports = {
name: 'loop', name: 'loop',
description: 'loop command.', description: 'loop command.',
alias: 'loop', alias: 'loop',
cooldown: 10, cooldown: 10,
onlyDev: false, async execute(message, args, client, prefix) {
async execute(message, args, client, Discord, prefix) {
const serverQueue = client.queue.get(message.guild.id); const serverQueue = client.queue.get(message.guild.id);
const permissions = message.channel.permissionsFor(message.author); const permissions = message.channel.permissionsFor(message.author);
const { voiceChannel } = message.member; const voiceChannel = message.member.voice.channel;
if (!serverQueue) return message.channel.send(':x: There is nothing playing.'); if (!serverQueue) return message.channel.send(':x: There is nothing playing.');
if (message.author.id !== client.config.devId) { if (voiceChannel !== serverQueue.voiceChannel) return message.channel.send(':x: I\'m sorry but you need to be in the same voice channel as Musix to loop the queue!');
if (voiceChannel !== serverQueue.voiceChannel) return message.channel.send(':x: I\'m sorry but you need to be in the same voice channel as Musix to loop the queue!'); if (client.global.db.guilds[message.guild.id].permissions === true) {
if (client.global.db.guilds[message.guild.id].permissions === true) { if (client.global.db.guilds[message.guild.id].dj) {
if (client.global.db.guilds[message.guild.id].dj) { if (!message.member.roles.cache.has(client.global.db.guilds[message.guild.id].djrole)) return message.channel.send(':x: You need the `DJ` role to loop the queue!');
if (!message.member.roles.has(client.global.db.guilds[message.guild.id].djrole)) return message.channel.send(':x: You need the `DJ` role to loop the queue!'); } else if (!permissions.has(PermissionFlagsBits.ManageChannels)) return message.channel.send(':x: You need the `MANAGE_MESSAGES` permission to loop the queue!');
} else if (!permissions.has('MANAGE_MESSAGES')) return message.channel.send(':x: You need the `MANAGE_MESSAGES` permission to loop the queue!'); }
} if (!serverQueue.looping) {
} serverQueue.looping = true;
if (!serverQueue.looping) { message.channel.send(':repeat: Looping the queue now!');
serverQueue.looping = true; } else {
message.channel.send(':repeat: Looping the queue now!'); serverQueue.looping = false;
} else { message.channel.send(':repeat: No longer looping the queue!');
serverQueue.looping = false; }
message.channel.send(':repeat: No longer looping the queue!');
}
} }
}; };

View File

@ -1,10 +1,11 @@
const { EmbedBuilder } = require('discord.js');
module.exports = { module.exports = {
name: 'nowplaying', name: 'nowplaying',
description: 'Now playing command.', description: 'Now playing command.',
alias: 'np', alias: 'np',
cooldown: 5, cooldown: 5,
onlyDev: false, async execute(message, args, client, prefix) {
async execute(message, args, client, Discord, prefix) {
const ytdl = require('ytdl-core'); const ytdl = require('ytdl-core');
const serverQueue = client.queue.get(message.guild.id); const serverQueue = client.queue.get(message.guild.id);
if (!serverQueue) return message.channel.send(':x: There is nothing playing.'); if (!serverQueue) return message.channel.send(':x: There is nothing playing.');
@ -15,13 +16,12 @@ module.exports = {
let barlength = 30; let barlength = 30;
let completedpercent = ((completed / songtime) * barlength).toFixed(0); let completedpercent = ((completed / songtime) * barlength).toFixed(0);
let array = []; for (let i = 0; i < completedpercent - 1; i++) { array.push('⎯'); } array.push('⭗'); for (let i = 0; i < barlength - completedpercent - 1; i++) { array.push('⎯'); } let array = []; for (let i = 0; i < completedpercent - 1; i++) { array.push('⎯'); } array.push('⭗'); for (let i = 0; i < barlength - completedpercent - 1; i++) { array.push('⎯'); }
const embed = new Discord.RichEmbed() const embed = new EmbedBuilder()
.setTitle("__Now playing__") .setTitle("__Now playing__")
.setDescription(`🎶**Now playing:** ${serverQueue.songs[0].title}\n${array.join('')} | \`${client.funcs.msToTime(completed)} / ${client.funcs.msToTime(songtime)}\``) .setDescription(`🎶**Now playing:** ${serverQueue.songs[0].title}\n${array.join('')} | \`${client.funcs.msToTime(completed)} / ${client.funcs.msToTime(songtime)}\``)
.setFooter(`Queued by ${serverQueue.songs[0].author.tag}`) .setFooter({ text: `Queued by ${serverQueue.songs[0].author.tag}` })
.setURL(serverQueue.songs[0].url) .setURL(serverQueue.songs[0].url)
.setColor(client.config.embedColor) .setColor(client.config.embedColor)
return message.channel.send(embed); return message.channel.send({ embeds: [embed] });
} }
}; };

View File

@ -1,25 +1,24 @@
const { PermissionFlagsBits } = require('discord.js');
module.exports = { module.exports = {
name: 'pause', name: 'pause',
description: 'Pause command.', description: 'Pause command.',
alias: 'pause', alias: 'pause',
cooldown: 5, cooldown: 5,
onlyDev: false, execute(message, args, client, prefix) {
execute(message, args, client, Discord, prefix) {
const serverQueue = client.queue.get(message.guild.id); const serverQueue = client.queue.get(message.guild.id);
const permissions = message.channel.permissionsFor(message.author); const permissions = message.channel.permissionsFor(message.author);
const { voiceChannel } = message.member; const voiceChannel = message.member.voice.channel;
if (!serverQueue) return message.channel.send(':x: There is nothing playing.'); if (!serverQueue) return message.channel.send(':x: There is nothing playing.');
if (serverQueue.playing && !serverQueue.paused) { if (serverQueue.playing && !serverQueue.paused) {
if (voiceChannel !== serverQueue.voiceChannel) return message.channel.send(':x: I\'m sorry but you need to be in the same voice channel as Musix to pause the music!'); if (voiceChannel !== serverQueue.voiceChannel) return message.channel.send(':x: I\'m sorry but you need to be in the same voice channel as Musix to pause the music!');
if (message.author.id !== client.config.devId) { if (client.global.db.guilds[message.guild.id].permissions === true) {
if (client.global.db.guilds[message.guild.id].permissions === true) { if (client.global.db.guilds[message.guild.id].dj) {
if (client.global.db.guilds[message.guild.id].dj) { if (!message.member.roles.cache.has(client.global.db.guilds[message.guild.id].djrole)) return message.channel.send(':x: You need the `DJ` role to pause the music!');
if (!message.member.roles.has(client.global.db.guilds[message.guild.id].djrole)) return message.channel.send(':x: You need the `DJ` role to pause the music!'); } else if (!permissions.has(PermissionFlagsBits.ManageMessages)) return message.channel.send(':x: You need the `MANAGE_MESSAGES` permission to pause the music!');
} else if (!permissions.has('MANAGE_MESSAGES')) return message.channel.send(':x: You need the `MANAGE_MESSAGES` permission to pause the music!');
}
} }
serverQueue.paused = true; serverQueue.paused = true;
serverQueue.connection.dispatcher.pause(); serverQueue.audioPlayer.pause();
return message.channel.send('⏸ Paused the music!'); return message.channel.send('⏸ Paused the music!');
} else return message.channel.send(':x: There is nothing playing.'); } else return message.channel.send(':x: There is nothing playing.');
} }

View File

@ -1,5 +1,6 @@
const YouTube = require("simple-youtube-api"); const YouTube = require("simple-youtube-api");
const he = require('he'); const he = require('he');
const { EmbedBuilder, PermissionFlagsBits } = require("discord.js");
module.exports = { module.exports = {
name: 'play', name: 'play',
@ -8,13 +9,12 @@ module.exports = {
alias: 'p', alias: 'p',
args: true, args: true,
cooldown: 3, cooldown: 3,
onlyDev: false, async execute(message, args, client, prefix) {
async execute(message, args, client, Discord, prefix) { const youtube = new YouTube(client.config.youtube_api_key);
const youtube = new YouTube(client.config.api_key);
const searchString = args.slice(1).join(" "); const searchString = args.slice(1).join(" ");
const url = args[1] ? args[1].replace(/<(.+)>/g, "$1") : ""; const url = args[1] ? args[1].replace(/<(.+)>/g, "$1") : "";
const serverQueue = client.queue.get(message.guild.id); const serverQueue = client.queue.get(message.guild.id);
const voiceChannel = message.member.voiceChannel; const voiceChannel = message.member.voice.channel;
if (!serverQueue) { if (!serverQueue) {
if (!voiceChannel) return message.channel.send(':x: I\'m sorry but you need to be in a voice channel to play music!'); if (!voiceChannel) return message.channel.send(':x: I\'m sorry but you need to be in a voice channel to play music!');
} else { } else {
@ -22,10 +22,10 @@ module.exports = {
} }
if (!args[1]) return message.channel.send(':x: You need to use a link or search for a song!'); if (!args[1]) return message.channel.send(':x: You need to use a link or search for a song!');
const permissions = voiceChannel.permissionsFor(message.client.user); const permissions = voiceChannel.permissionsFor(message.client.user);
if (!permissions.has('CONNECT')) { if (!permissions.has(PermissionFlagsBits.Connect)) {
return message.channel.send(':x: I cannot connect to your voice channel, make sure I have the proper permissions!'); return message.channel.send(':x: I cannot connect to your voice channel, make sure I have the proper permissions!');
} }
if (!permissions.has('SPEAK')) { if (!permissions.has(PermissionFlagsBits.Speak)) {
return message.channel.send(':x: I cannot speak in your voice channel, make sure I have the proper permissions!'); return message.channel.send(':x: I cannot speak in your voice channel, make sure I have the proper permissions!');
} }
if (url.match(/^https?:\/\/(www.youtube.com|youtube.com)\/playlist(.*)$/)) { if (url.match(/^https?:\/\/(www.youtube.com|youtube.com)\/playlist(.*)$/)) {
@ -43,15 +43,16 @@ module.exports = {
try { try {
var videos = await youtube.searchVideos(searchString, 10); var videos = await youtube.searchVideos(searchString, 10);
let index = 0; let index = 0;
const embed = new Discord.RichEmbed() const embed = new EmbedBuilder()
.setTitle("__Song Selection__") .setTitle("__Song Selection__")
.setDescription(`${videos.map(video2 => `**${++index}** ${he.decode(video2.title)} `).join('\n')}`) .setDescription(`${videos.map(video2 => `**${++index}** ${he.decode(video2.title)} `).join('\n')}`)
.setFooter("Please provide a number ranging from 1-10 to select one of the search results.") .setFooter({ text: "Please provide a number ranging from 1-10 to select one of the search results." })
.setColor(client.config.embedColor) .setColor(client.config.embedColor)
message.channel.send(embed); message.channel.send({ embeds: [embed] });
try { try {
var response = await message.channel.awaitMessages(message2 => message2.content > 0 && message2.content < 11 && message2.author === message.author, { var response = await message.channel.awaitMessages({
maxMatches: 1, filter: message2 => message2.content > 0 && message2.content < 11 && message2.author === message.author,
max: 1,
time: 10000, time: 10000,
errors: ['time'] errors: ['time']
}); });

View File

@ -1,5 +1,6 @@
const YouTube = require("simple-youtube-api"); const YouTube = require("simple-youtube-api");
const he = require('he'); const he = require('he');
const { EmbedBuilder, PermissionFlagsBits } = require("discord.js");
module.exports = { module.exports = {
name: 'playlist', name: 'playlist',
@ -7,43 +8,36 @@ module.exports = {
description: 'Save and load queues', description: 'Save and load queues',
alias: 'pl', alias: 'pl',
cooldown: 10, cooldown: 10,
onlyDev: false, async execute(message, args, client, prefix) {
async execute(message, args, client, Discord, prefix) { const embed = new EmbedBuilder()
const embed = new Discord.RichEmbed()
.setTitle('Options for playlist!') .setTitle('Options for playlist!')
.addField('play', 'Play the guild specific queue.', true) .addFields(
.addField('save', 'Save the currently playing queue. Note that this will overwrite the currently saved queue!', true) { name: 'play', value: 'Play the guild specific queue.', inline: true },
.addField('add', 'Add songs to the playlist. Like song selection', true) { name: 'save', value: 'Save the currently playing queue. Note that this will overwrite the currently saved queue!', inline: true },
.addField('remove', 'Remove songs from the playlist.', true) { name: 'add', value: 'Add songs to the playlist. Like song selection', inline: true },
.addField('list', 'Display the playlist.', true) { name: 'remove', value: 'Remove songs from the playlist.', inline: true },
.setFooter(`how to use: ${prefix}playlist <Option> <Optional option>`) { name: 'list', value: 'Display the playlist.', inline: true }
.setAuthor(client.user.username, client.user.displayAvatarURL) )
.setFooter({ text: `how to use: ${prefix}playlist <Option> <Optional option>` })
.setAuthor({ name: client.user.username, iconURL: client.user.avatarURL()})
.setColor(client.config.embedColor) .setColor(client.config.embedColor)
const permissions = message.channel.permissionsFor(message.author); const permissions = message.channel.permissionsFor(message.author);
if (message.author.id !== client.config.devId) { if (client.global.db.guilds[message.guild.id].dj) {
if (client.global.db.guilds[message.guild.id].dj) { if (!message.member.roles.cache.has(client.global.db.guilds[message.guild.id].djrole)) return message.channel.send(':x: You need the `DJ` role to modify or play the playlist!');
if (!message.member.roles.has(client.global.db.guilds[message.guild.id].djrole)) return message.channel.send(':x: You need the `DJ` role to modify or play the playlist!'); } else if (!permissions.has(PermissionFlagsBits.ManageGuild)) return message.channel.send(':x: You need the `MANAGE_SERVER` permission to modify the playlist!');
} else if (!permissions.has('MANAGE_GUILD')) return message.channel.send(':x: You need the `MANAGE_SERVER` permission to modify the playlist!');
}
if (client.global.db.guilds[message.guild.id].premium) { if (client.global.db.guilds[message.guild.id].premium) {
if (args[1]) { if (args[1]) {
const optionName = args[1].toLowerCase(); const optionName = args[1].toLowerCase();
const option = client.playlistCmd.get(optionName) || client.playlistCmd.find(cmd => cmd.aliases && cmd.aliases.includes(optionName)); const option = client.playlistCmd.get(optionName) || client.playlistCmd.find(cmd => cmd.aliases && cmd.aliases.includes(optionName));
if (!option) return message.channel.send(embed); if (!option) return message.channel.send({ embeds: [embed] });
try { try {
option.execute(message, args, client, Discord, prefix); option.execute(message, args, client, prefix);
} catch (error) { } catch (error) {
message.reply(`:x: there was an error trying to execute that option! Please contact support with \`${prefix}bug\`!`); message.reply(`:x: there was an error trying to execute that option!`);
const embed = new Discord.RichEmbed()
.setTitle(`Musix ${error.toString()}`)
.setDescription(error.stack.replace(/at /g, '**at **'))
.setColor(client.config.embedColor);
client.fetchUser(client.config.devId).then(user => user.send(embed)).catch(console.error);
client.channels.get(client.config.debug_channel).send(embed);
console.log(error); console.log(error);
} }
} else { } else {
return message.channel.send(embed); return message.channel.send({ embeds: [embed] });
} }
} else return message.channel.send(":x: This is not a premium guild!"); } else return message.channel.send(":x: This is not a premium guild!");
}, },

View File

@ -1,12 +1,13 @@
const YouTube = require("simple-youtube-api"); const YouTube = require("simple-youtube-api");
const he = require('he'); const he = require('he');
const { EmbedBuilder } = require("discord.js");
module.exports = { module.exports = {
name: 'add', name: 'add',
async execute(message, args, client, Discord, prefix) { async execute(message, args, client, prefix) {
if (client.global.db.playlists[message.guild.id].saved) { if (client.global.db.playlists[message.guild.id].saved) {
const serverQueue = client.queue.get(message.guild.id); const serverQueue = client.queue.get(message.guild.id);
const youtube = new YouTube(client.config.api_key); const youtube = new YouTube(client.config.youtube_api_key);
const searchString = args.slice(2).join(" "); const searchString = args.slice(2).join(" ");
const url = args[2] ? args[2].replace(/<(.+)>/g, "$1") : ""; const url = args[2] ? args[2].replace(/<(.+)>/g, "$1") : "";
if (!args[2]) return message.channel.send(':x: You need to use a link or search for a song!'); if (!args[2]) return message.channel.send(':x: You need to use a link or search for a song!');
@ -16,15 +17,16 @@ module.exports = {
try { try {
var videos = await youtube.searchVideos(searchString, 10); var videos = await youtube.searchVideos(searchString, 10);
let index = 0; let index = 0;
const embed = new Discord.RichEmbed() const embed = new EmbedBuilder()
.setTitle("__Song Selection__") .setTitle("__Song Selection__")
.setDescription(`${videos.map(video2 => `**${++index}** ${he.decode(video2.title)} `).join('\n')}`) .setDescription(`${videos.map(video2 => `**${++index}** ${he.decode(video2.title)} `).join('\n')}`)
.setFooter("Please provide a number ranging from 1-10 to select one of the search results.") .setFooter({ text: "Please provide a number ranging from 1-10 to select one of the search results." })
.setColor("#b50002") .setColor("#b50002")
message.channel.send(embed); message.channel.send({ embeds: [embed] });
try { try {
var response = await message.channel.awaitMessages(message2 => message2.content > 0 && message2.content < 11, { var response = await message.channel.awaitMessages({
maxMatches: 1, filter: message2 => message2.content > 0 && message2.content < 11,
max: 1,
time: 10000, time: 10000,
errors: ['time'] errors: ['time']
}); });
@ -41,11 +43,11 @@ module.exports = {
} }
let song = { let song = {
id: video.id, id: video.id,
title: Discord.Util.escapeMarkdown(video.title), title: video.title,
url: `https://www.youtube.com/watch?v=${video.id}` url: `https://www.youtube.com/watch?v=${video.id}`
} }
client.global.db.playlists[message.guild.id].songs.push(song); client.global.db.playlists[message.guild.id].songs.push(song);
message.channel.send(`:white_check_mark: ${song.title} added to the playlist!`); message.channel.send(`:white_check_mark: ${song.title} added to the playlist!`);
} else return message.channel.send(':x: There is no playlist saved! Start by using the save option!'); } else return message.channel.send(':x: There is no playlist saved! Start by using the save option!');
} }
}; };

View File

@ -1,6 +1,6 @@
module.exports = { module.exports = {
name: 'delete', name: 'delete',
async execute(message, args, client, Discord, prefix) { async execute(message, args, client, prefix) {
client.global.db.playlists[message.guild.id] = { client.global.db.playlists[message.guild.id] = {
songs: [], songs: [],
firstSong: undefined, firstSong: undefined,
@ -8,4 +8,4 @@ module.exports = {
}; };
message.channel.send(':wastebasket: Deleted the playlist.'); message.channel.send(':wastebasket: Deleted the playlist.');
} }
}; };

View File

@ -1,6 +1,8 @@
const { EmbedBuilder } = require("discord.js");
module.exports = { module.exports = {
name: 'list', name: 'list',
async execute(message, args, client, Discord, prefix) { async execute(message, args, client, prefix) {
if (args[2]) { if (args[2]) {
if (isNaN(args[2])) return msg.channel.send(':x: I\'m sorry, But you need to enter a valid __number__.'); if (isNaN(args[2])) return msg.channel.send(':x: I\'m sorry, But you need to enter a valid __number__.');
} }
@ -13,10 +15,10 @@ module.exports = {
for (let i = 0; i < hashs; i++) { for (let i = 0; i < hashs; i++) {
queuemessage = queuemessage.replace('**#**', `**${i + 1}**`); queuemessage = queuemessage.replace('**#**', `**${i + 1}**`);
} }
const embed = new Discord.RichEmbed() const embed = new EmbedBuilder()
.setTitle("__playlist queue__") .setTitle("__playlist queue__")
.setDescription(`${pagetext}\n${queuemessage}`) .setDescription(`${pagetext}\n${queuemessage}`)
.setColor("#b50002") .setColor("#b50002")
return message.channel.send(embed); return message.channel.send({ embeds: [embed] });
} }
}; };

View File

@ -1,14 +1,17 @@
const { PermissionFlagsBits } = require("discord.js");
const { createAudioPlayer, getVoiceConnection, joinVoiceChannel, NoSubscriberBehavior } = require("@discordjs/voice");
module.exports = { module.exports = {
name: 'play', name: 'play',
async execute(message, args, client, Discord, prefix) { async execute(message, args, client, prefix) {
const serverQueue = client.queue.get(message.guild.id); const serverQueue = client.queue.get(message.guild.id);
const voiceChannel = message.member.voiceChannel; const voiceChannel = message.member.voice.channel;
if (!voiceChannel) return message.channel.send(':x: I\'m sorry but you need to be in a voice channel to play music!'); if (!voiceChannel) return message.channel.send(':x: I\'m sorry but you need to be in a voice channel to play music!');
const permissions = voiceChannel.permissionsFor(message.client.user); const permissions = voiceChannel.permissionsFor(message.client.user);
if (!permissions.has('CONNECT')) { if (!permissions.has(PermissionFlagsBits.Connect)) {
return message.channel.send(':x: I cannot connect to your voice channel, make sure I have the proper permissions!'); return message.channel.send(':x: I cannot connect to your voice channel, make sure I have the proper permissions!');
} }
if (!permissions.has('SPEAK')) { if (!permissions.has(PermissionFlagsBits.Speak)) {
return message.channel.send(':x: I cannot speak in your voice channel, make sure I have the proper permissions!'); return message.channel.send(':x: I cannot speak in your voice channel, make sure I have the proper permissions!');
} }
let songs; let songs;
@ -24,8 +27,13 @@ module.exports = {
if (!serverQueue) { if (!serverQueue) {
const construct = { const construct = {
textChannel: message.channel, textChannel: message.channel,
voiceChannel: message.member.voiceChannel, voiceChannel: message.member.voice.channel,
connection: null, connection: null,
audioPlayer: createAudioPlayer({
behaviors: {
noSubscriber: NoSubscriberBehavior.Play,
}
}),
songs: [...songs], songs: [...songs],
volume: client.global.db.guilds[message.guild.id].defaultVolume, volume: client.global.db.guilds[message.guild.id].defaultVolume,
playing: false, playing: false,
@ -38,7 +46,13 @@ module.exports = {
client.queue.set(message.guild.id, construct); client.queue.set(message.guild.id, construct);
message.channel.send(":white_check_mark: Queue set!"); message.channel.send(":white_check_mark: Queue set!");
try { try {
var connection = await message.member.voiceChannel.join(); const connection =
getVoiceConnection(voiceChannel.guild.id) ??
joinVoiceChannel({
channelId: voiceChannel.id,
guildId: voiceChannel.guild.id,
adapterCreator: voiceChannel.guild.voiceAdapterCreator
});
construct.connection = connection; construct.connection = connection;
client.funcs.play(message.guild, construct.songs[0], client, message, 0, false); client.funcs.play(message.guild, construct.songs[0], client, message, 0, false);
} catch (error) { } catch (error) {
@ -46,10 +60,10 @@ module.exports = {
return message.channel.send(`:x: An error occured: ${error}`); return message.channel.send(`:x: An error occured: ${error}`);
} }
} else { } else {
serverQueue.connection.dispatcher.end("queue set"); serverQueue.audioPlayer.stop();
serverQueue.songs = [...client.global.db.playlists[message.guild.id].songs]; serverQueue.songs = [...client.global.db.playlists[message.guild.id].songs];
message.channel.send(":white_check_mark: Queue set!"); message.channel.send(":white_check_mark: Queue set!");
} }
} else return message.channel.send(':x: There is no queue set for this server!') } else return message.channel.send(':x: There is no queue set for this server!')
} }
}; };

View File

@ -1,6 +1,6 @@
module.exports = { module.exports = {
name: 'remove', name: 'remove',
async execute(message, args, client, Discord, prefix) { async execute(message, args, client, prefix) {
if (client.global.db.playlists[message.guild.id].saved) { if (client.global.db.playlists[message.guild.id].saved) {
if (!args[2]) return message.channel.send(':x: Please provide a number on the position of the song that you wan\'t to remove!'); if (!args[2]) return message.channel.send(':x: Please provide a number on the position of the song that you wan\'t to remove!');
const songNum = parseInt(args[2]) - 1; const songNum = parseInt(args[2]) - 1;
@ -10,4 +10,4 @@ module.exports = {
return client.global.db.playlists[message.guild.id].songs.splice(songNum, 1); return client.global.db.playlists[message.guild.id].songs.splice(songNum, 1);
} else return message.channel.send(':x: There is no playlist saved! Start by using the save option!'); } else return message.channel.send(':x: There is no playlist saved! Start by using the save option!');
} }
}; };

View File

@ -1,6 +1,6 @@
module.exports = { module.exports = {
name: 'save', name: 'save',
async execute(message, args, client, Discord, prefix) { async execute(message, args, client, prefix) {
const serverQueue = client.queue.get(message.guild.id); const serverQueue = client.queue.get(message.guild.id);
if (!serverQueue) return message.channel.send(':x: There is nothing playing!'); if (!serverQueue) return message.channel.send(':x: There is nothing playing!');
client.global.db.playlists[message.guild.id] = { client.global.db.playlists[message.guild.id] = {
@ -10,4 +10,4 @@ module.exports = {
}; };
message.channel.send(":white_check_mark: Queue saved!"); message.channel.send(":white_check_mark: Queue saved!");
} }
}; };

View File

@ -1,10 +1,11 @@
const { EmbedBuilder } = require("discord.js");
module.exports = { module.exports = {
name: 'queue', name: 'queue',
description: 'Queue command.', description: 'Queue command.',
alias: 'q', alias: 'q',
cooldown: 5, cooldown: 5,
onlyDev: false, async execute(message, args, client, prefix) {
async execute(message, args, client, Discord, prefix) {
const serverQueue = client.queue.get(message.guild.id); const serverQueue = client.queue.get(message.guild.id);
if (!serverQueue) return message.channel.send(':x: There is nothing playing.'); if (!serverQueue) return message.channel.send(':x: There is nothing playing.');
if (args[1]) { if (args[1]) {
@ -21,18 +22,18 @@ module.exports = {
queuemessage = queuemessage.replace('**#**', `**${i + 1}**`); queuemessage = queuemessage.replace('**#**', `**${i + 1}**`);
} }
if (!serverQueue.looping) { if (!serverQueue.looping) {
const embed = new Discord.RichEmbed() const embed = new EmbedBuilder()
.setTitle("__Song queue__") .setTitle("__Song queue__")
.setDescription(`**Now playing:** ${serverQueue.songs[0].title}🎶\n${pagetext}\n${queuemessage}`) .setDescription(`**Now playing:** ${serverQueue.songs[0].title}🎶\n${pagetext}\n${queuemessage}`)
.setColor(client.config.embedColor) .setColor(client.config.embedColor)
return message.channel.send(embed); return message.channel.send({ embeds: [embed] });
} else { } else {
const embed = new Discord.RichEmbed() const embed = new EmbedBuilder()
.setTitle("__Song queue__") .setTitle("__Song queue__")
.setDescription(`**Now playing:** ${serverQueue.songs[0].title}🎶\n${pagetext}\n${queuemessage}`) .setDescription(`**Now playing:** ${serverQueue.songs[0].title}🎶\n${pagetext}\n${queuemessage}`)
.setFooter('🔁 Currently looping the queue!') .setFooter({ text: '🔁 Currently looping the queue!' })
.setColor(client.config.embedColor) .setColor(client.config.embedColor)
return message.channel.send(embed); return message.channel.send({ embeds: [embed] });
} }
} }
}; };

View File

@ -1,11 +1,12 @@
const { PermissionFlagsBits } = require("discord.js");
module.exports = { module.exports = {
name: 'remove', name: 'remove',
description: 'Remove command.', description: 'Remove command.',
alias: 'rm', alias: 'rm',
cooldown: 5, cooldown: 5,
onlyDev: false, execute(message, args, client, prefix) {
execute(message, args, client, Discord, prefix) { const voiceChannel = message.member.voice.channel;
const { voiceChannel } = message.member;
const serverQueue = client.queue.get(message.guild.id); const serverQueue = client.queue.get(message.guild.id);
const permissions = message.channel.permissionsFor(message.author); const permissions = message.channel.permissionsFor(message.author);
if (!serverQueue) return message.channel.send(':x: There is nothing playing.'); if (!serverQueue) return message.channel.send(':x: There is nothing playing.');
@ -15,14 +16,12 @@ module.exports = {
if (isNaN(pos)) return message.channel.send(':x: You need to enter a number!'); if (isNaN(pos)) return message.channel.send(':x: You need to enter a number!');
if (pos === 0) return message.channel.send(':x: You can not remove the currently playing song!'); if (pos === 0) return message.channel.send(':x: You can not remove the currently playing song!');
if (pos > serverQueue.songs.size) return message.channel.send(`:x: There is only ${serverQueue.songs.size} amount of songs in the queue!`); if (pos > serverQueue.songs.size) return message.channel.send(`:x: There is only ${serverQueue.songs.size} amount of songs in the queue!`);
if (message.author.id !== client.config.devId) { if (voiceChannel !== serverQueue.voiceChannel) return message.channel.send(':x: I\'m sorry but you need to be in the same voice channel as Musix to remove songs!');
if (voiceChannel !== serverQueue.voiceChannel) return message.channel.send(':x: I\'m sorry but you need to be in the same voice channel as Musix to remove songs!'); if (client.global.db.guilds[message.guild.id].dj) {
if (client.global.db.guilds[message.guild.id].dj) { if (serverQueue.songs[pos].author !== message.author) {
if (serverQueue.songs[pos].author !== message.author) { if (!message.member.roles.cache.has(client.global.db.guilds[message.guild.id].djrole)) return message.channel.send(':x: You need the `DJ` role to remove songs queue by others!');
if (!message.member.roles.has(client.global.db.guilds[message.guild.id].djrole)) return message.channel.send(':x: You need the `DJ` role to remove songs queue by others!'); }
} } else if (!permissions.has(PermissionFlagsBits.ManageMessages) && serverQueue.songs[pos].author !== message.author) return message.channel.send(':x: You need the `MANAGE_MESSAGES` permission to remove songs queued by others!');
} else if (!permissions.has('MANAGE_MESSAGES') && serverQueue.songs[pos].author !== message.author) return message.channel.send(':x: You need the `MANAGE_MESSAGES` permission to remove songs queued by others!');
}
message.channel.send(`🗑️ removed \`${serverQueue.songs[pos].title}\` from the queue!`); message.channel.send(`🗑️ removed \`${serverQueue.songs[pos].title}\` from the queue!`);
return serverQueue.songs.splice(pos, 1); return serverQueue.songs.splice(pos, 1);
} }

View File

@ -1,25 +1,24 @@
const { PermissionFlagsBits } = require("discord.js");
module.exports = { module.exports = {
name: 'resume', name: 'resume',
description: 'Resume command.', description: 'Resume command.',
alias: 'resume', alias: 'resume',
cooldown: 5, cooldown: 5,
onlyDev: false, execute(message, args, client, prefix) {
execute(message, args, client, Discord, prefix) {
const serverQueue = client.queue.get(message.guild.id); const serverQueue = client.queue.get(message.guild.id);
const permissions = message.channel.permissionsFor(message.author); const permissions = message.channel.permissionsFor(message.author);
const { voiceChannel } = message.member; const voiceChannel = message.member.voice.channel;
if (!serverQueue) return message.channel.send(':x: There is nothing playing.'); if (!serverQueue) return message.channel.send(':x: There is nothing playing.');
if (serverQueue.playing && serverQueue.paused) { if (serverQueue.playing && serverQueue.paused) {
if (message.author.id !== client.config.devId) { if (voiceChannel !== serverQueue.voiceChannel) return message.channel.send(':x: I\'m sorry but you need to be in the same voice channel as Musix to loop the queue!');
if (voiceChannel !== serverQueue.voiceChannel) return message.channel.send(':x: I\'m sorry but you need to be in the same voice channel as Musix to loop the queue!'); if (client.global.db.guilds[message.guild.id].permissions === true) {
if (client.global.db.guilds[message.guild.id].permissions === true) { if (client.global.db.guilds[message.guild.id].dj) {
if (client.global.db.guilds[message.guild.id].dj) { if (!message.member.roles.cache.has(client.global.db.guilds[message.guild.id].djrole)) return message.channel.send(':x: You need the `DJ` role to resume the music!');
if (!message.member.roles.has(client.global.db.guilds[message.guild.id].djrole)) return message.channel.send(':x: You need the `DJ` role to resume the music!'); } else if (!permissions.has(PermissionFlagsBits.ManageMessages)) return message.channel.send(':x: You need the `MANAGE_MESSAGES` permission to resume the music!');
} else if (!permissions.has('MANAGE_MESSAGES')) return message.channel.send(':x: You need the `MANAGE_MESSAGES` permission to resume the music!');
}
} }
serverQueue.paused = false; serverQueue.paused = false;
serverQueue.connection.dispatcher.resume(); serverQueue.audioPlayer.unpause();
return message.channel.send('▶ Resumed the music!'); return message.channel.send('▶ Resumed the music!');
} }
return message.channel.send(':x: The music is not paused!'); return message.channel.send(':x: The music is not paused!');

View File

@ -1,31 +1,29 @@
const { PermissionFlagsBits } = require("discord.js");
module.exports = { module.exports = {
name: 'seek', name: 'seek',
description: 'seek command.', description: 'Seek music.',
alias: 'seek', alias: 'seek',
cooldown: 10, cooldown: 10,
onlyDev: true, async execute(message, args, client, prefix) {
async execute(message, args, client, Discord, prefix) {
const ytdl = require('ytdl-core'); const ytdl = require('ytdl-core');
const serverQueue = client.queue.get(message.guild.id); const serverQueue = client.queue.get(message.guild.id);
const permissions = message.channel.permissionsFor(message.author); const permissions = message.channel.permissionsFor(message.author);
const { voiceChannel } = message.member; const voiceChannel = message.member.voice.channel;
if (!serverQueue) return message.channel.send(':x: There is nothing playing.'); if (!serverQueue) return message.channel.send(':x: There is nothing playing.');
let data = await Promise.resolve(ytdl.getInfo(serverQueue.songs[0].url)); let data = await Promise.resolve(ytdl.getInfo(serverQueue.songs[0].url));
if (serverQueue.playing) { if (serverQueue.playing) {
if (message.author.id !== client.config.devId) { if (voiceChannel !== serverQueue.voiceChannel) return message.channel.send(':x: I\'m sorry but you need to be in the same voice channel as Musix to seek the song!');
if (voiceChannel !== serverQueue.voiceChannel) return message.channel.send(':x: I\'m sorry but you need to be in the same voice channel as Musix to seek the song!'); if (client.global.db.guilds[message.guild.id].permissions === true) {
if (client.global.db.guilds[message.guild.id].permissions === true) { if (client.global.db.guilds[message.guild.id].dj) {
if (client.global.db.guilds[message.guild.id].dj) { if (!message.member.roles.cache.has(client.global.db.guilds[message.guild.id].djrole)) return message.channel.send(':x: You need the `DJ` role to seek the song!');
if (!message.member.roles.has(client.global.db.guilds[message.guild.id].djrole)) return message.channel.send(':x: You need the `DJ` role to seek the song!'); } else if (!permissions.has(PermissionFlagsBits.ManageMessages)) return message.channel.send(':x: You need the `MANAGE_MESSAGES` permission to seek the song!');
} else if (!permissions.has('MANAGE_MESSAGES')) return message.channel.send(':x: You need the `MANAGE_MESSAGES` permission to seek the song!');
}
} }
if (!args[1]) return message.channel.send(`:x: Correct usage: \`${prefix}seek <seeking point in seconds>\``); if (!args[1]) return message.channel.send(`:x: Correct usage: \`${prefix}seek <seeking point in seconds>\``);
const pos = parseInt(args[1]) const pos = parseInt(args[1])
if (isNaN(pos)) return message.channel.send(':x: I\'m sorry, But you need to enter a valid __number__.'); if (isNaN(pos)) return message.channel.send(':x: I\'m sorry, But you need to enter a valid __number__.');
if (pos < 0) return message.channel.send(':x: The seeking point needs to be a positive number!'); if (pos < 0) return message.channel.send(':x: The seeking point needs to be a positive number!');
if (pos > data.length_seconds) return message.channel.send(`:x: The lenght of this song is ${data.length_seconds} seconds! You can't seek further than that!`); if (pos > data.length_seconds) return message.channel.send(`:x: The lenght of this song is ${data.length_seconds} seconds! You can't seek further than that!`);
serverQueue.connection.dispatcher.end('seek'); serverQueue.audioPlayer.stop();
client.funcs.play(message.guild, serverQueue.songs[0], client, message, pos, false); client.funcs.play(message.guild, serverQueue.songs[0], client, message, pos, false);
} else { } else {
message.channel.send(':x: There is nothing playing!'); message.channel.send(':x: There is nothing playing!');

View File

@ -1,43 +1,39 @@
const { EmbedBuilder, PermissionFlagsBits } = require("discord.js");
module.exports = { module.exports = {
name: 'settings', name: 'settings',
usage: '[setting]', usage: '[setting]',
description: 'Change the settings', description: 'Change the settings',
alias: 'settings', alias: 'settings',
cooldown: 10, cooldown: 10,
onlyDev: false, async execute(message, args, client, prefix) {
async execute(message, args, client, Discord, prefix) { const embed = new EmbedBuilder()
const embed = new Discord.RichEmbed()
.setTitle('Guild settings for Musix') .setTitle('Guild settings for Musix')
.addField('prefix', 'Change the guild specific prefix. (string)', true) .addFields(
.addField('volume', 'Change the default volume that the bot will start playing at. (number)', true) { name: 'prefix', value: 'Change the guild specific prefix. (string)', inline: true},
.addField('permissions', 'Change whether to require permissions to use eg `skip, stop, pause, loop, etc...`', true) { name: 'volume', value: 'Change the default volume that the bot will start playing at. (number)', inline: true },
.addField('setdj', 'Set a DJ role. This will allow chosen users to freely use all Musix commands. This will automatically set the `permissions` settings to true in order for the `DJ` role to have effect!', true) { name: 'permissions', value: 'Change whether to require permissions to use eg `skip, stop, pause, loop, etc...`', inline: true },
.addField('announcesongs', 'Whether to announce songs that start playing or not.') { name: 'setdj', value: 'Set a DJ role. This will allow chosen users to freely use all Musix commands. This will automatically set the `permissions` settings to true in order for the `DJ` role to have effect!', inline: true },
.addField('songselection', 'Will i ask to select a song from the top 10 queries or start playing the first result instantly.') { name: 'announcesongs', value: 'Whether to announce songs that start playing or not.' },
.setFooter(`how to use: ${prefix}settings <Setting name> <value>`) { name: 'songselection', value: 'Will i ask to select a song from the top 10 queries or start playing the first result instantly.' }
.setAuthor(client.user.username, client.user.displayAvatarURL) )
.setFooter({ text: `how to use: ${prefix}settings <Setting name> <value>` })
.setAuthor({ name: client.user.username, iconURL: client.user.avatarURL()})
.setColor(client.embedColor) .setColor(client.embedColor)
const permissions = message.channel.permissionsFor(message.author); const permissions = message.channel.permissionsFor(message.author);
if (message.author.id !== client.config.devId) { if (!permissions.has(PermissionFlagsBits.ManageGuild)) return message.channel.send(':x: You need the `MANAGE_SERVER` permission to change the settings!');
if (!permissions.has('MANAGE_GUILD')) return message.channel.send(':x: You need the `MANAGE_SERVER` permission to change the settings!');
}
if (args[1]) { if (args[1]) {
const optionName = args[1].toLowerCase(); const optionName = args[1].toLowerCase();
const option = client.settingCmd.get(optionName) || client.settingCmd.find(cmd => cmd.aliases && cmd.aliases.includes(optionName)); const option = client.settingCmd.get(optionName) || client.settingCmd.find(cmd => cmd.aliases && cmd.aliases.includes(optionName));
if (!option) return message.channel.send(embed); if (!option) return message.channel.send({ embeds: [embed] });
try { try {
option.execute(message, args, client, Discord, prefix); option.execute(message, args, client, prefix);
} catch (error) { } catch (error) {
message.reply(`:x: there was an error trying to execute that option! Please contact support with \`${prefix}bug\`!`); message.reply(`:x: there was an error trying to execute that option!`);
const embed = new Discord.RichEmbed() console.log(error);
.setTitle(`Musix ${error.toString()}`)
.setDescription(error.stack.replace(/at /g, '**at **'))
.setColor(client.config.embedColor);
client.fetchUser(client.config.devId).then(user => user.send(embed)).catch(console.error);
client.channels.get(client.config.debug_channel).send(embed);
} }
} else { } else {
return message.channel.send(embed); return message.channel.send({ embeds: [embed] });
} }
}, },
}; };

View File

@ -1,6 +1,6 @@
module.exports = { module.exports = {
name: 'announcesongs', name: 'announcesongs',
async execute(message, args, client, Discord, prefix) { async execute(message, args, client, prefix) {
if (client.global.db.guilds[message.guild.id].startPlaying) { if (client.global.db.guilds[message.guild.id].startPlaying) {
client.global.db.guilds[message.guild.id].startPlaying = false; client.global.db.guilds[message.guild.id].startPlaying = false;
return message.channel.send(':white_check_mark: announcesongs now set to `false`!'); return message.channel.send(':white_check_mark: announcesongs now set to `false`!');
@ -9,4 +9,4 @@ module.exports = {
return message.channel.send(':white_check_mark: announcesongs now set to `true`!'); return message.channel.send(':white_check_mark: announcesongs now set to `true`!');
} }
} }
}; };

View File

@ -1,6 +1,6 @@
module.exports = { module.exports = {
name: 'permissions', name: 'permissions',
async execute(message, args, client, Discord, prefix) { async execute(message, args, client, prefix) {
if (!args[2]) return message.channel.send(`🔒 Permission requirement: \`${client.global.db.guilds[message.guild.id].permissions}\``); if (!args[2]) return message.channel.send(`🔒 Permission requirement: \`${client.global.db.guilds[message.guild.id].permissions}\``);
if (args[2] === 'true') { if (args[2] === 'true') {
if (!client.global.db.guilds[message.guild.id].permissions) { if (!client.global.db.guilds[message.guild.id].permissions) {
@ -14,4 +14,4 @@ module.exports = {
} else return message.channel.send(':x: That value is already `false`!'); } else return message.channel.send(':x: That value is already `false`!');
} else return message.channel.send(':x: Please define a boolean! (true/false)'); } else return message.channel.send(':x: Please define a boolean! (true/false)');
} }
}; };

View File

@ -1,8 +1,8 @@
module.exports = { module.exports = {
name: 'prefix', name: 'prefix',
async execute(message, args, client, Discord, prefix) { async execute(message, args, client, prefix) {
if (!args[2]) return message.channel.send(`Current prefix: \`${client.global.db.guilds[message.guild.id].prefix}\``); if (!args[2]) return message.channel.send(`Current prefix: \`${client.global.db.guilds[message.guild.id].prefix}\``);
client.global.db.guilds[message.guild.id].prefix = args[2]; client.global.db.guilds[message.guild.id].prefix = args[2];
message.channel.send(`:white_check_mark: New prefix set to: \`${args[2]}\``); message.channel.send(`:white_check_mark: New prefix set to: \`${args[2]}\``);
} }
}; };

View File

@ -1,6 +1,6 @@
module.exports = { module.exports = {
name: 'reset', name: 'reset',
async execute(message, args, client, Discord, prefix) { async execute(message, args, client, prefix) {
client.global.db.guilds[message.guild.id] = { client.global.db.guilds[message.guild.id] = {
prefix: client.config.prefix, prefix: client.config.prefix,
defaultVolume: 5, defaultVolume: 5,
@ -11,4 +11,4 @@ module.exports = {
}; };
message.channel.send(':white_check_mark: Reset __all__ guild settings!'); message.channel.send(':white_check_mark: Reset __all__ guild settings!');
} }
}; };

View File

@ -1,20 +1,20 @@
const { PermissionFlagsBits } = require("discord.js");
module.exports = { module.exports = {
name: 'setdj', name: 'setdj',
async execute(message, args, client, Discord, prefix) { async execute(message, args, client, prefix) {
if (!client.global.db.guilds[message.guild.id].dj) { if (!client.global.db.guilds[message.guild.id].dj) {
if (!client.global.db.guilds[message.guild.id].permissions) { if (!client.global.db.guilds[message.guild.id].permissions) {
client.global.db.guilds[message.guild.id].permissions = true; client.global.db.guilds[message.guild.id].permissions = true;
} }
if (message.guild.roles.find(x => x.name === "DJ")) { if (message.guild.roles.cache.find(x => x.name === "DJ")) {
client.global.db.guilds[message.guild.id].djrole = message.guild.roles.find(x => x.name === "DJ").id; client.global.db.guilds[message.guild.id].djrole = message.guild.roles.cache.find(x => x.name === "DJ").id;
message.channel.send(':white_check_mark: I found a `DJ` role from this guild! This role is now the DJ role.'); message.channel.send(':white_check_mark: I found a `DJ` role from this guild! This role is now the DJ role.');
client.global.db.guilds[message.guild.id].dj = true; client.global.db.guilds[message.guild.id].dj = true;
} else { } else {
const permissions = message.channel.permissionsFor(message.client.user); const permissions = message.channel.permissionsFor(message.client.user);
if (!permissions.has('MANAGE_ROLES')) return message.channel.send(':x: I cannot create roles (Manage roles), make sure I have the proper permissions! I will need this permission to create a `DJ` role since i did not find one!'); if (!permissions.has(PermissionFlagsBits.ManageRoles)) return message.channel.send(':x: I cannot create roles (Manage roles), make sure I have the proper permissions! I will need this permission to create a `DJ` role since i did not find one!');
message.guild.createRole({ message.guild.createRole({ name: 'DJ' })
name: 'DJ',
})
.then(role => client.global.db.guilds[message.guild.id].djrole = role.id) .then(role => client.global.db.guilds[message.guild.id].djrole = role.id)
.catch(console.error) .catch(console.error)
client.global.db.guilds[message.guild.id].dj = true; client.global.db.guilds[message.guild.id].dj = true;
@ -25,4 +25,4 @@ module.exports = {
message.channel.send(':white_check_mark: `DJ` now set to `false`'); message.channel.send(':white_check_mark: `DJ` now set to `false`');
} }
} }
}; };

View File

@ -1,7 +1,7 @@
module.exports = { module.exports = {
name: 'setpremium', name: 'setpremium',
async execute(message, args, client, Discord, prefix) { async execute(message, args, client, prefix) {
if (message.author.id !== client.config.devId) return; //if (message.author.id !== client.config.devId) return;
if (args[2]) { if (args[2]) {
const guild = client.guilds.get(args[2]); const guild = client.guilds.get(args[2]);
if (!client.global.db.guilds[guild.id].premium) { if (!client.global.db.guilds[guild.id].premium) {
@ -31,4 +31,4 @@ module.exports = {
} }
} }
} }
}; };

View File

@ -1,6 +1,6 @@
module.exports = { module.exports = {
name: 'songselection', name: 'songselection',
async execute(message, args, client, Discord, prefix) { async execute(message, args, client, prefix) {
if (!client.global.db.guilds[message.guild.id].songSelection) { if (!client.global.db.guilds[message.guild.id].songSelection) {
message.channel.send(':white_check_mark: Songselection now set to `true`!'); message.channel.send(':white_check_mark: Songselection now set to `true`!');
client.global.db.guilds[message.guild.id].songSelection = true; client.global.db.guilds[message.guild.id].songSelection = true;
@ -9,4 +9,4 @@ module.exports = {
message.channel.send(':white_check_mark: Songselection now set to `false`'); message.channel.send(':white_check_mark: Songselection now set to `false`');
} }
} }
}; };

View File

@ -1,10 +1,10 @@
module.exports = { module.exports = {
name: 'volume', name: 'volume',
async execute(message, args, client, Discord, prefix) { async execute(message, args, client, prefix) {
if (!args[2]) return message.channel.send(`:speaker: Current default volume is: \`${client.global.db.guilds[message.guild.id].defaultVolume}\``); if (!args[2]) return message.channel.send(`:speaker: Current default volume is: \`${client.global.db.guilds[message.guild.id].defaultVolume}\``);
if (isNaN(args[2])) return message.channel.send(':x: I\'m sorry, But the default volume needs to be a valid __number__.'); if (isNaN(args[2])) return message.channel.send(':x: I\'m sorry, But the default volume needs to be a valid __number__.');
if (args[2].length > 2) return message.channel.send(':x: The default volume must be below `100` for quality and safety resons.'); if (args[2].length > 2) return message.channel.send(':x: The default volume must be below `100` for quality and safety resons.');
client.global.db.guilds[message.guild.id].defaultVolume = args[2]; client.global.db.guilds[message.guild.id].defaultVolume = args[2];
message.channel.send(`:white_check_mark: Default volume set to: \`${args[2]}\``); message.channel.send(`:white_check_mark: Default volume set to: \`${args[2]}\``);
} }
}; };

View File

@ -3,8 +3,7 @@ module.exports = {
description: 'Shuffle command.', description: 'Shuffle command.',
alias: 'shuffle', alias: 'shuffle',
cooldown: 5, cooldown: 5,
onlyDev: false, execute(message, args, client, prefix) {
execute(message, args, client, Discord, prefix) {
const serverQueue = client.queue.get(message.guild.id); const serverQueue = client.queue.get(message.guild.id);
let currentIndex = serverQueue.songs.length, let currentIndex = serverQueue.songs.length,
temporaryValue, temporaryValue,
@ -19,4 +18,4 @@ module.exports = {
serverQueue.songs[randomIndex] = temporaryValue; serverQueue.songs[randomIndex] = temporaryValue;
} }
} }
}; };

View File

@ -1,39 +1,36 @@
const { PermissionFlagsBits } = require("discord.js");
module.exports = { module.exports = {
name: 'skip', name: 'skip',
description: 'Skip command.', description: 'Skip command.',
alias: 's', alias: 's',
cooldown: 5, cooldown: 5,
onlyDev: false, execute(message, args, client, prefix) {
execute(message, args, client, Discord, prefix) { const voiceChannel = message.member.voice.channel;
const { voiceChannel } = message.member;
const serverQueue = client.queue.get(message.guild.id); const serverQueue = client.queue.get(message.guild.id);
const permissions = message.channel.permissionsFor(message.author); const permissions = message.channel.permissionsFor(message.author);
if (!serverQueue) return message.channel.send(':x: There is nothing playing that I could skip for you.'); if (!serverQueue) return message.channel.send(':x: There is nothing playing that I could skip for you.');
if (!serverQueue.playing) return message.channel.send(':x: There is nothing playing that I could skip for you.'); if (!serverQueue.playing) return message.channel.send(':x: There is nothing playing that I could skip for you.');
if (message.author.id !== client.config.devId) { if (voiceChannel !== serverQueue.voiceChannel) return message.channel.send(':x: I\'m sorry but you need to be in the same voice channel as Musix to skip the song!');
if (voiceChannel !== serverQueue.voiceChannel) return message.channel.send(':x: I\'m sorry but you need to be in the same voice channel as Musix to skip the song!'); if (client.global.db.guilds[message.guild.id].permissions === true) {
if (client.global.db.guilds[message.guild.id].permissions === true) { if (!message.member.roles.cache.has(client.global.db.guilds[message.guild.id].djrole) && !permissions.has(PermissionFlagsBits.ManageMessages)) {
if (!message.member.roles.has(client.global.db.guilds[message.guild.id].djrole) && !permissions.has('MANAGE_MESSAGES')) {
return vote(serverQueue, message, client);
} else {
return skipSong(serverQueue, message);
}
} else {
return vote(serverQueue, message, client); return vote(serverQueue, message, client);
} else {
return skipSong(serverQueue, message);
} }
} else { } else {
return skipSong(serverQueue, message); return vote(serverQueue, message, client);
} }
} }
}; };
function skipSong(serverQueue, message) { function skipSong(serverQueue, message) {
message.channel.send(':fast_forward: Skipped the song!'); message.channel.send(':fast_forward: Skipped the song!');
serverQueue.connection.dispatcher.end('skipped'); serverQueue.audioPlayer.stop();
}; };
function vote(serverQueue, message) { function vote(serverQueue, message) {
serverQueue.votesNeeded = Math.floor(message.guild.voiceConnection.channel.members.size / 2); serverQueue.votesNeeded = Math.floor(serverQueue.voiceChannel.members.size / 2);
serverQueue.votesNeeded.toFixed(); serverQueue.votesNeeded.toFixed();
if (message.guild.voiceConnection.channel.members.size > 2) { if (serverQueue.voiceChannel.members.size > 2) {
if (serverQueue.voters.includes(message.member.id)) return message.channel.send(':x: You have already voted to skip!'); if (serverQueue.voters.includes(message.member.id)) return message.channel.send(':x: You have already voted to skip!');
serverQueue.votes++; serverQueue.votes++;
serverQueue.voters.push(message.member.id); serverQueue.voters.push(message.member.id);

View File

@ -1,21 +1,25 @@
const { EmbedBuilder } = require("discord.js");
const { getVoiceConnections } = require("@discordjs/voice");
module.exports = { module.exports = {
name: 'status', name: 'status',
description: 'Status command.', description: 'Status command.',
alias: 'status', alias: 'status',
cooldown: 5, cooldown: 5,
onlyDev: false, execute(message, args, client, prefix) {
execute(message, args, client, Discord, prefix) {
const uptime = client.funcs.msToTime(client.uptime); const uptime = client.funcs.msToTime(client.uptime);
const ping = Math.floor(client.ping * 10) / 10; const ping = Math.floor(client.ws.ping * 10) / 10;
const embed = new Discord.RichEmbed() const embed = new EmbedBuilder()
.setTitle(`Status for ${client.user.username}`) .setTitle(`Status for ${client.user.username}`)
.addField(':signal_strength: Ping', ping, true) .addFields(
.addField(':stopwatch: Uptime', uptime, true) { name: ':signal_strength: Ping', value: ping, inline: true },
.addField(`:play_pause: Currently playing music on`, `${client.voiceConnections.size} guild(s)`, true) { name: ':stopwatch: Uptime', value: uptime, inline: true },
.addField(`💿 Operating system`, process.platform, true) { name: ':play_pause: Currently playing music on', value: `${getVoiceConnections.size} guild(s)`, inline: true },
.setAuthor(client.user.username, client.user.displayAvatarURL) { name: '💿 Operating system', value: process.platform, inline: true }
)
.setAuthor({ name: client.user.username, iconURL: client.user.avatarURL()})
.setColor(client.config.embedColor) .setColor(client.config.embedColor)
return message.channel.send(embed); return message.channel.send({ embeds: [embed] });
} }
}; };

View File

@ -1,26 +1,25 @@
const { PermissionFlagsBits } = require("discord.js");
module.exports = { module.exports = {
name: 'stop', name: 'stop',
description: 'Stop command.', description: 'Stop command.',
alias: 'stop', alias: 'stop',
cooldown: 5, cooldown: 5,
onlyDev: false, execute(message, args, client, prefix) {
execute(message, args, client, Discord, prefix) { const voiceChannel = message.member.voice.channel;
const { voiceChannel } = message.member;
const serverQueue = client.queue.get(message.guild.id); const serverQueue = client.queue.get(message.guild.id);
const permissions = message.channel.permissionsFor(message.author); const permissions = message.channel.permissionsFor(message.author);
if (!serverQueue) return message.channel.send(':x: There is nothing playing that I could stop for you.'); if (!serverQueue) return message.channel.send(':x: There is nothing playing that I could stop for you.');
if (!serverQueue.playing) return message.channel.send(':x: There is nothing playing that I could stop for you.'); if (!serverQueue.playing) return message.channel.send(':x: There is nothing playing that I could stop for you.');
if (message.author.id !== client.config.devId) { if (voiceChannel !== serverQueue.voiceChannel) return message.channel.send(':x: I\'m sorry but you need to be in the same voice channel as Musix to stop the music!');
if (voiceChannel !== serverQueue.voiceChannel) return message.channel.send(':x: I\'m sorry but you need to be in the same voice channel as Musix to stop the music!'); if (client.global.db.guilds[message.guild.id].permissions === true) {
if (client.global.db.guilds[message.guild.id].permissions === true) { if (client.global.db.guilds[message.guild.id].dj) {
if (client.global.db.guilds[message.guild.id].dj) { if (!message.member.roles.cache.has(client.global.db.guilds[message.guild.id].djrole)) return message.channel.send(':x: You need the `DJ` role to stop the music!');
if (!message.member.roles.has(client.global.db.guilds[message.guild.id].djrole)) return message.channel.send(':x: You need the `DJ` role to stop the music!'); } else if (!permissions.has(PermissionFlagsBits.ManageChannels)) return message.channel.send(':x: You need the `MANAGE_CHANNELS` permission to stop the music!');
} else if (!permissions.has('MANAGE_CHANNELS')) return message.channel.send(':x: You need the `MANAGE_CHANNELS` permission to stop the music!');
}
} }
serverQueue.songs = []; serverQueue.songs = [];
serverQueue.looping = false; serverQueue.looping = false;
serverQueue.connection.dispatcher.end('Stopped'); serverQueue.audioPlayer.stop();
message.channel.send(':stop_button: Stopped the music!') message.channel.send(':stop_button: Stopped the music!')
} }
}; };

View File

@ -1,30 +1,29 @@
const { PermissionFlagsBits } = require("discord.js");
module.exports = { module.exports = {
name: 'volume', name: 'volume',
description: 'Volume command.', description: 'Volume command.',
alias: 'volume', alias: 'volume',
cooldown: 5, cooldown: 5,
onlyDev: false,
execute(message, args, client, Discord, prefix) { execute(message, args, client, Discord, prefix) {
const { voiceChannel } = message.member; const voiceChannel = message.member.voice.channel;
const serverQueue = client.queue.get(message.guild.id); const serverQueue = client.queue.get(message.guild.id);
const permissions = message.channel.permissionsFor(message.author); const permissions = message.channel.permissionsFor(message.author);
if (!serverQueue) return message.channel.send(':x: There is nothing playing.'); if (!serverQueue) return message.channel.send(':x: There is nothing playing.');
if (!serverQueue.playing) return message.channel.send(':x: There is nothing playing.'); if (!serverQueue.playing) return message.channel.send(':x: There is nothing playing.');
if (!args[1]) return message.channel.send(`:loud_sound: The current volume is: **${serverQueue.volume}**`); if (!args[1]) return message.channel.send(`:loud_sound: The current volume is: **${serverQueue.volume}**`);
const volume = parseFloat(args[1]); const volume = parseFloat(args[1]);
if (message.author.id !== client.config.devId) { if (!voiceChannel) return message.channel.send(':x: I\'m sorry but you need to be in a voice channel to change the volume!');
if (!voiceChannel) return message.channel.send(':x: I\'m sorry but you need to be in a voice channel to change the volume!'); if (client.global.db.guilds[message.guild.id].permissions === true) {
if (client.global.db.guilds[message.guild.id].permissions === true) { if (client.global.db.guilds[message.guild.id].dj) {
if (client.global.db.guilds[message.guild.id].dj) { if (!message.member.roles.cache.has(client.global.db.guilds[message.guild.id].djrole)) return message.channel.send(':x: You need the `DJ` role to change the volume!');
if (!message.member.roles.has(client.global.db.guilds[message.guild.id].djrole)) return message.channel.send(':x: You need the `DJ` role to change the volume!'); } else if (!permissions.has(PermissionFlagsBits.ManageChannels)) return message.channel.send(':x: You need the `MANAGE_CHANNELS` permission to change the volume!');
} else if (!permissions.has('MANAGE_CHANNELS')) return message.channel.send(':x: You need the `MANAGE_CHANNELS` permission to change the volume!');
}
} }
if (isNaN(volume)) return message.channel.send(':x: I\'m sorry, But you need to enter a valid __number__.'); if (isNaN(volume)) return message.channel.send(':x: I\'m sorry, But you need to enter a valid __number__.');
if (volume > 100) return message.channel.send(':x: The max volume is `100`!'); if (volume > 100) return message.channel.send(':x: The max volume is `100`!');
if (volume < 0) return message.channel.send(':x: The volume needs to be a positive number!'); if (volume < 0) return message.channel.send(':x: The volume needs to be a positive number!');
serverQueue.volume = volume; serverQueue.volume = volume;
serverQueue.connection.dispatcher.setVolume(volume / 5); serverQueue.audioResource.volume.setVolume(volume / 100);
return message.channel.send(`:loud_sound: I set the volume to: **${volume}**`); return message.channel.send(`:loud_sound: I set the volume to: **${volume}**`);
} }
}; };

10
config.js Normal file
View File

@ -0,0 +1,10 @@
module.exports = {
discord_api_token: process.env.DISCORD_API_TOKEN,
firebase: {
serviceAccount: null
//serviceAccount: require('./serviceAccount.json')
},
youtube_api_key: process.env.YOUTUBE_API_KEY,
prefix: process.env.BOT_PREFIX ?? "mx>",
embedColor: "#b50002"
}

View File

@ -1,9 +0,0 @@
module.exports = {
token: process.env.TOKEN,
api_key: process.env.API_KEY,
debug_channel: "634718645188034560",
devId: "360363051792203779",
prefix: ">",
embedColor: "#b50002",
invite: "https://discordapp.com/api/oauth2/authorize?client_id=607266889537945605&permissions=271600640&redirect_uri=https%3A%2F%2Fdiscordapp.com%2Foauth2%2Fauthorize%3Fclient_id%3D607266889537945605%26%3Bscope%3Dbot%26%3Bpermissions%3D0&scope=bot",
}

View File

@ -1,23 +1,25 @@
module.exports = { module.exports = {
name: 'guildcreate', name: 'guildcreate',
async execute(client, guild) { async execute(client, guild) {
client.db.collection('guilds').doc(guild.id).set({ if(client.config.firebase.serviceAccount){
prefix: client.config.prefix, client.db.collection('guilds').doc(guild.id).set({
defaultVolume: 5, prefix: client.config.prefix,
permissions: false, defaultVolume: 50,
premium: false, permissions: false,
dj: false, premium: false,
djrole: null, dj: false,
startPlaying: true djrole: null,
}); startPlaying: true
client.global.db.guilds[guild.id] = { });
prefix: client.config.prefix, client.global.db.guilds[guild.id] = {
defaultVolume: 5, prefix: client.config.prefix,
permissions: false, defaultVolume: 50,
premium: false, permissions: false,
dj: false, premium: false,
djrole: null, dj: false,
startPlaying: true djrole: null,
}; startPlaying: true
};
}
} }
} }

View File

@ -1,6 +1,6 @@
module.exports = { module.exports = {
name: 'message', name: 'message',
async execute(client, message, Discord) { async execute(client, message) {
if (message.author.bot || !message.guild) return; if (message.author.bot || !message.guild) return;
let prefix = client.global.db.guilds[message.guild.id].prefix; let prefix = client.global.db.guilds[message.guild.id].prefix;
const args = message.content.slice(prefix.length).split(' '); const args = message.content.slice(prefix.length).split(' ');
@ -10,7 +10,7 @@ module.exports = {
if (args[1] === 'prefix') return message.channel.send(`My prefix here is: \`${prefix}\`.`); if (args[1] === 'prefix') return message.channel.send(`My prefix here is: \`${prefix}\`.`);
if (args[1] === 'help') { if (args[1] === 'help') {
const command = client.commands.get("help"); const command = client.commands.get("help");
return client.funcs.exe(message, args, client, Discord, prefix, command); return client.funcs.exe(message, args, client, prefix, command);
} }
} }
} }
@ -19,7 +19,6 @@ module.exports = {
const commandName = args[0].toLowerCase(); const commandName = args[0].toLowerCase();
const command = client.commands.get(commandName) || client.commands.find(cmd => cmd.aliases && cmd.aliases.includes(commandName)) || client.commandAliases.get(commandName); const command = client.commands.get(commandName) || client.commands.find(cmd => cmd.aliases && cmd.aliases.includes(commandName)) || client.commandAliases.get(commandName);
if (!command && message.content !== `${prefix}`) return; if (!command && message.content !== `${prefix}`) return;
if (command.onlyDev && message.author.id !== client.config.devId) return message.channel.send(':x: You are not allowed to do that!'); client.funcs.exe(message, args, client, prefix, command);
client.funcs.exe(message, args, client, Discord, prefix, command);
} }
} }

View File

@ -1,41 +1,53 @@
module.exports = { module.exports = {
name: 'ready', name: 'ready',
async execute(client, dbl, Discord) { async execute(client) {
const remoteMusixGuildsData = await client.funcs.dbget('guilds', null, client);
const remoteMusixPlaylistsData = await client.funcs.dbget('playlists', null, client);
remoteMusixGuildsData.forEach(guildData => {
client.global.db.guilds[guildData.id] = guildData.d;
});
remoteMusixPlaylistsData.forEach(guildData => {
client.global.db.playlists[guildData.id] = guildData.d;
});
console.log('- DB Set -');
client.user.setActivity(`@${client.user.username} help | 🎶`, { type: 'LISTENING' }); client.user.setActivity(`@${client.user.username} help | 🎶`, { type: 'LISTENING' });
client.user.setStatus('dnd'); client.user.setStatus('online');
dbl.postStats(client.guilds.size);
console.log('- Activated -'); console.log('- Activated -');
setInterval(async () => {
client.guilds.forEach(guild => { client.guilds.cache.forEach(guild => {
client.db.collection('guilds').doc(guild.id).set({ client.global.db.guilds[guild.id] = {
prefix: client.global.db.guilds[guild.id].prefix, prefix: client.config.prefix,
defaultVolume: client.global.db.guilds[guild.id].defaultVolume, defaultVolume: 50,
permissions: client.global.db.guilds[guild.id].permissions, permissions: false,
premium: client.global.db.guilds[guild.id].premium, premium: false,
dj: client.global.db.guilds[guild.id].dj, dj: false,
djrole: client.global.db.guilds[guild.id].djrole, djrole: null,
startPlaying: client.global.db.guilds[guild.id].startPlaying startPlaying: true
}); };
if (client.global.db.guilds[guild.id].premium) { });
client.db.collection('playlists').doc(guild.id).set({
songs: client.global.db.playlists[guild.id].songs, if(client.config.firebase.serviceAccount){
saved: client.global.db.playlists[guild.id].saved, const remoteMusixGuildsData = await client.funcs.dbget('guilds', null, client);
}); const remoteMusixPlaylistsData = await client.funcs.dbget('playlists', null, client);
} remoteMusixGuildsData.forEach(guildData => {
client.global.db.guilds[guildData.id] = guildData.d;
}); });
dbl.postStats(client.guilds.size); remoteMusixPlaylistsData.forEach(guildData => {
}, 1800000); client.global.db.playlists[guildData.id] = guildData.d;
setInterval(() => { });
client.funcs.ffmpeg(client, Discord); console.log('- DB Set -');
}, 7200000);
setInterval(async () => {
client.guilds.cache.forEach(guild => {
client.db.collection('guilds').doc(guild.id).set({
prefix: client.global.db.guilds[guild.id].prefix,
defaultVolume: client.global.db.guilds[guild.id].defaultVolume,
permissions: client.global.db.guilds[guild.id].permissions,
premium: client.global.db.guilds[guild.id].premium,
dj: client.global.db.guilds[guild.id].dj,
djrole: client.global.db.guilds[guild.id].djrole,
startPlaying: client.global.db.guilds[guild.id].startPlaying
});
if (client.global.db.guilds[guild.id].premium) {
client.db.collection('playlists').doc(guild.id).set({
songs: client.global.db.playlists[guild.id].songs,
saved: client.global.db.playlists[guild.id].saved,
});
}
});
}, 1800000);
}
} }
} }

13
funcs/exe.js Normal file
View File

@ -0,0 +1,13 @@
const { EmbedBuilder, PermissionFlagsBits } = require("discord.js");
module.exports = function (message, args, client, prefix, command) {
const permissions = message.channel.permissionsFor(message.client.user);
if (!permissions.has(PermissionFlagsBits.EmbedLinks)) return message.channel.send(':x: I cannot send embeds (Embed links), make sure I have the proper permissions!');
try {
command.uses++;
command.execute(message, args, client, prefix);
} catch (error) {
message.reply(`:x: there was an error trying to execute that command!`);
console.log(error);
}
};

View File

@ -1,8 +1,9 @@
const { createAudioPlayer, getVoiceConnection, joinVoiceChannel, NoSubscriberBehavior } = require("@discordjs/voice");
module.exports = async function (video, message, voiceChannel, client, playlist = false) { module.exports = async function (video, message, voiceChannel, client, playlist = false) {
const Discord = require('discord.js');
let song = { let song = {
id: video.id, id: video.id,
title: Discord.Util.escapeMarkdown(video.title), title: video.title,
url: `https://www.youtube.com/watch?v=${video.id}`, url: `https://www.youtube.com/watch?v=${video.id}`,
author: message.author author: message.author
} }
@ -12,6 +13,11 @@ module.exports = async function (video, message, voiceChannel, client, playlist
textChannel: message.channel, textChannel: message.channel,
voiceChannel: voiceChannel, voiceChannel: voiceChannel,
connection: null, connection: null,
audioPlayer: createAudioPlayer({
behaviors: {
noSubscriber: NoSubscriberBehavior.Play,
}
}),
songs: [], songs: [],
volume: client.global.db.guilds[message.guild.id].defaultVolume, volume: client.global.db.guilds[message.guild.id].defaultVolume,
playing: false, playing: false,
@ -24,12 +30,18 @@ module.exports = async function (video, message, voiceChannel, client, playlist
construct.songs.push(song); construct.songs.push(song);
client.queue.set(message.guild.id, construct); client.queue.set(message.guild.id, construct);
try { try {
var connection = await voiceChannel.join(); const connection =
getVoiceConnection(voiceChannel.guild.id) ??
joinVoiceChannel({
channelId: voiceChannel.id,
guildId: voiceChannel.guild.id,
adapterCreator: voiceChannel.guild.voiceAdapterCreator
});
construct.connection = connection; construct.connection = connection;
client.funcs.play(message.guild, construct.songs[0], client, message, 0, true); client.funcs.play(message.guild, construct.songs[0], client, message, 0, true);
} catch (error) { } catch (error) {
client.queue.delete(message.guild.id); client.queue.delete(message.guild.id);
client.channels.get(client.config.debug_channel).send("Error with connecting to voice channel: " + error); console.log("Error with connecting to voice channel: " + error);
return message.channel.send(`:x: An error occured: ${error}`); return message.channel.send(`:x: An error occured: ${error}`);
} }
} else { } else {

48
funcs/play.js Normal file
View File

@ -0,0 +1,48 @@
const { EmbedBuilder } = require('discord.js');
const { AudioPlayerStatus, createAudioResource } = require('@discordjs/voice');
const ytdl = require('ytdl-core');
module.exports = async function (guild, song, client, message, seek, play) {
const serverQueue = client.queue.get(guild.id);
if (!song) {
serverQueue.connection.destroy();
client.queue.delete(guild.id);
return;
}
serverQueue.audioPlayer
.on(AudioPlayerStatus.Idle, () => {
serverQueue.playing = false;
serverQueue.audioPlayer.removeAllListeners();
if (serverQueue.looping) {
serverQueue.songs.push(serverQueue.songs[0]);
}
serverQueue.songs.shift();
client.funcs.play(guild, serverQueue.songs[0], client, message);
})
.on('error', (error) => {
console.error(error)
});
const audioResource = createAudioResource(ytdl(song.url, { filter: "audio", highWaterMark: 1 << 25 }),{
inlineVolume: true
});
audioResource.volume.setVolume(serverQueue.volume / 100);
serverQueue.audioPlayer.play(audioResource);
serverQueue.audioResource = audioResource;
serverQueue.connection.subscribe(serverQueue.audioPlayer);
/*.playStream(ytdl(song.url, { filter: "audio", highWaterMark: 1 << 25 }), { seek: seek, bitrate: 1024, passes: 10, volume: 1 })*/
if (client.global.db.guilds[guild.id].startPlaying || play) {
let data = await Promise.resolve(ytdl.getInfo(serverQueue.songs[0].url));
let songtime = (data.length_seconds * 1000).toFixed(0);
const embed = new EmbedBuilder()
.setTitle(`:musical_note: Start playing: **${song.title}**`)
.setDescription(`Song duration: \`${client.funcs.msToTime(songtime)}\``)
.setColor("#b50002")
serverQueue.textChannel.send({ embeds: [embed] });
}
serverQueue.playing = true;
}

View File

@ -1,12 +1,7 @@
const Discord = require('discord.js'); const Discord = require('discord.js');
const MusicClient = require('./Struct/Client'); const MusicClient = require('./Client');
const client = new MusicClient({}); const client = new MusicClient({});
const DBL = require("dblapi.js");
const dbl = new DBL(process.env.DBLTOKEN, client);
const fs = require('fs'); const fs = require('fs');
require('dotenv/config');
client.config = require('./config/config.js');
const commandFiles = fs.readdirSync('./commands/').filter(f => f.endsWith('.js')); const commandFiles = fs.readdirSync('./commands/').filter(f => f.endsWith('.js'));
for (const file of commandFiles) { for (const file of commandFiles) {
@ -37,13 +32,13 @@ for (const file of settingFiles) {
client.on('ready', async () => { client.on('ready', async () => {
const eventName = 'ready'; const eventName = 'ready';
const event = client.events.get(eventName) || client.events.find(ent => ent.aliases && ent.aliases.includes(eventName)); const event = client.events.get(eventName) || client.events.find(ent => ent.aliases && ent.aliases.includes(eventName));
event.execute(client, dbl, Discord); event.execute(client);
}); });
client.on('message', message => { client.on('messageCreate', message => {
const eventName = 'message'; const eventName = 'message';
const event = client.events.get(eventName) || client.events.find(ent => ent.aliases && ent.aliases.includes(eventName)); const event = client.events.get(eventName) || client.events.find(ent => ent.aliases && ent.aliases.includes(eventName));
event.execute(client, message, Discord); event.execute(client, message);
}); });
client.on('guildCreate', async (guild) => { client.on('guildCreate', async (guild) => {
@ -52,7 +47,4 @@ client.on('guildCreate', async (guild) => {
event.execute(client, guild); event.execute(client, guild);
}); });
dbl.on('error', error => { client.login(client.config.discord_api_token).catch(err => { console.log('- Failed To Login -> ' + err); });
console.log(`Error with DBL! ${error}`);
})
client.login(client.config.token).catch(err => { console.log('- Failed To Login -> ' + err); });

3205
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,32 +1,34 @@
{ {
"name": "Musix", "name": "musix-oss",
"version": "2.21.1", "version": "2.22.0",
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"start": "node ." "start": "node index.js",
"start:dev": "nodemon"
}, },
"keywords": [], "keywords": [],
"author": "MatteZ02", "author": "Musix Org",
"license": "MIT", "license": "MIT",
"homepage": "https://https://github.com/MatteZ02/Musix", "homepage": "https://https://github.com/musix-oss/musix",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://https://github.com/MatteZ02/Musix" "url": "https://https://github.com/musix-oss/musix"
}, },
"dependencies": { "dependencies": {
"dblapi.js": "^2.4.1",
"discord.js": "^14.14.1", "discord.js": "^14.14.1",
"@discordjs/voice": "^0.16.1",
"@discordjs/opus": "^0.9.0",
"dotenv": "^16.4.1", "dotenv": "^16.4.1",
"ffmpeg-static": "^5.2.0",
"firebase": "^10.8.0", "firebase": "^10.8.0",
"firebase-admin": "^12.0.0", "firebase-admin": "^12.0.0",
"fs": "0.0.1-security",
"he": "^1.2.0", "he": "^1.2.0",
"ms": "^2.1.3", "ms": "^2.1.3",
"node-opus": "^0.3.3",
"request": "^2.88.2", "request": "^2.88.2",
"simple-youtube-api": "^5.2.1", "simple-youtube-api": "^5.2.1",
"ytdl-core": "^4.11.5" "ytdl-core": "^4.11.5"
},
"devDependencies": {
"nodemon": "^3.0.3"
} }
} }