1
0
mirror of https://github.com/musix-org/musix-oss synced 2024-12-22 11:43:17 +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 admin = require('firebase-admin');
const serviceAccount = require('./serviceAccount.json');
require('dotenv/config');
module.exports = class extends Client {
constructor() {
super({
disableEveryone: true,
disabledEvents: ['TYPING_START']
intents: [
"Guilds",
"GuildMessages",
"GuildVoiceStates",
"MessageContent"
],
disableMentions: "everyone",
disabledEvents: ["TYPING_START"]
});
this.commands = new Collection();
@ -26,15 +32,9 @@ module.exports = class extends Client {
this.funcs.handleVideo = require('./funcs/handleVideo.js');
this.funcs.play = require('./funcs/play.js');
this.funcs.msToTime = require('./funcs/msToTime.js');
this.funcs.dbget = require('./funcs/dbget.js');
this.funcs.exe = require('./funcs/exe.js');
this.funcs.ffmpeg = require('./funcs/ffmpeg.js');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
});
this.db = admin.firestore();
this.config = require('./config.js');
this.global = {
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
RUN apk add --virtual .build-deps python3 make g++ gcc git
#Code Dependencies
RUN apk add --virtual .code-deps ffmpeg
WORKDIR /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 = {
name: 'cmduses',
usage: '',
description: 'Command usage statistics',
uses: 0,
async execute(msg, args, client, Discord) {
async execute(msg, args, client) {
const cmduses = [];
client.commands.forEach((value, key) => {
cmduses.push([key, value.uses]);
@ -17,12 +19,12 @@ module.exports = {
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());
});
const embed = new Discord.RichEmbed();
const embed = new EmbedBuilder();
embed
.setTitle('Musix Command Usage During Current Uptime')
.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);
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 = {
name: 'help',
description: 'Help command.',
alias: 'help',
cooldown: 5,
onlyDev: false,
execute(message, args, client, Discord, prefix) {
const embed = new Discord.RichEmbed()
execute(message, args, client, prefix) {
const embed = new EmbedBuilder()
.setTitle(`Commands for ${client.user.username}!`)
.addField(`${prefix}play | ${prefix}p`, 'Play a song.', true)
.addField(`${prefix}skip | ${prefix}s`, 'Skip a song.', true)
.addField(`${prefix}queue | ${prefix}q`, 'Display the queue.', true)
.addField(`${prefix}nowplaying | ${prefix}np`, 'Display what\'s currently playing.', true)
.addField(`${prefix}remove | ${prefix}rm`, 'Remove songs from the queue.', true)
.addField(`${prefix}volume`, 'Change or check the volume.', true)
.addField(`${prefix}pause`, 'Pause the music.', true)
.addField(`${prefix}resume`, 'Resume the music.', true)
.addField(`${prefix}loop`, 'Loop the queue.', true)
.addField(`${prefix}stop`, 'Stop the music, Clear the queue and leave the current voice channel.', true)
.addField(`${prefix}invite`, 'Invite Musix.', true)
.addField(`${prefix}status`, 'See different information for Musix.', true)
.addField(`${prefix}bug`, 'Report a bug.', true)
.addField(`${prefix}settings`, 'Change the guild specific settings.', true)
.addField(`${prefix}help`, 'Display the help.', true)
.setAuthor(message.member.username, message.member.displayAvatarURL)
.addFields(
{ name: `${prefix}play | ${prefix}p`, value: 'Play a song.', inline: true },
{ name: `${prefix}skip | ${prefix}s`, value: 'Skip a song.', inline: true },
{ name: `${prefix}queue | ${prefix}q`, value: 'Display the queue.', inline: true },
{ name: `${prefix}nowplaying | ${prefix}np`, value: 'Display what\'s currently playing.', inline: true },
{ name: `${prefix}remove | ${prefix}rm`, value: 'Remove songs from the queue.', inline: true },
{ name: `${prefix}volume`, value: 'Change or check the volume.', inline: true },
{ name: `${prefix}pause`, value: 'Pause the music.', inline: true },
{ name: `${prefix}resume`, value: 'Resume the music.', inline: true },
{ name: `${prefix}loop`, value: 'Loop the queue.', inline: true },
{ name: `${prefix}seek`, value: 'Seek music.', inline: true },
{ name: `${prefix}stop`, value: 'Stop the music, Clear the queue and leave the current voice channel.', inline: true },
{ name: `${prefix}invite`, value: 'Invite Musix.', inline: true },
{ name: `${prefix}status`, value: 'See different information for Musix.', inline: true },
{ name: `${prefix}settings`, value: 'Change the guild specific settings.', inline: true },
{ name: `${prefix}help`, value: 'Display the help.', inline: true }
)
.setAuthor({ name: client.user.username, iconURL: client.user.avatarURL()})
.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 = {
name: 'invite',
description: 'Invite command.',
alias: 'invite',
cooldown: 5,
onlyDev: false,
execute(message, args, client, Discord, prefix) {
const embed = new Discord.RichEmbed()
execute(message, args, client, prefix) {
const embed = new EmbedBuilder()
.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)
return message.channel.send(embed);
return message.channel.send({ embeds: [embed] });
}
};
};

View File

@ -1,28 +1,27 @@
const { PermissionFlagsBits } = require('discord.js');
module.exports = {
name: 'loop',
description: 'loop command.',
alias: 'loop',
cooldown: 10,
onlyDev: false,
async execute(message, args, client, Discord, prefix) {
async execute(message, args, client, prefix) {
const serverQueue = client.queue.get(message.guild.id);
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 (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 (client.global.db.guilds[message.guild.id].permissions === true) {
if (client.global.db.guilds[message.guild.id].dj) {
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('MANAGE_MESSAGES')) return message.channel.send(':x: You need the `MANAGE_MESSAGES` permission to loop the queue!');
}
}
if (!serverQueue.looping) {
serverQueue.looping = true;
message.channel.send(':repeat: Looping the queue now!');
} else {
serverQueue.looping = false;
message.channel.send(':repeat: No longer looping 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].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!');
} else if (!permissions.has(PermissionFlagsBits.ManageChannels)) return message.channel.send(':x: You need the `MANAGE_MESSAGES` permission to loop the queue!');
}
if (!serverQueue.looping) {
serverQueue.looping = true;
message.channel.send(':repeat: Looping the queue now!');
} else {
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 = {
name: 'nowplaying',
description: 'Now playing command.',
alias: 'np',
cooldown: 5,
onlyDev: false,
async execute(message, args, client, Discord, prefix) {
async execute(message, args, client, prefix) {
const ytdl = require('ytdl-core');
const serverQueue = client.queue.get(message.guild.id);
if (!serverQueue) return message.channel.send(':x: There is nothing playing.');
@ -15,13 +16,12 @@ module.exports = {
let barlength = 30;
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('⎯'); }
const embed = new Discord.RichEmbed()
const embed = new EmbedBuilder()
.setTitle("__Now playing__")
.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)
.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 = {
name: 'pause',
description: 'Pause command.',
alias: 'pause',
cooldown: 5,
onlyDev: false,
execute(message, args, client, Discord, prefix) {
execute(message, args, client, prefix) {
const serverQueue = client.queue.get(message.guild.id);
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.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 (message.author.id !== client.config.devId) {
if (client.global.db.guilds[message.guild.id].permissions === true) {
if (client.global.db.guilds[message.guild.id].dj) {
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('MANAGE_MESSAGES')) return message.channel.send(':x: You need the `MANAGE_MESSAGES` permission to pause the music!');
}
if (client.global.db.guilds[message.guild.id].permissions === true) {
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!');
} else if (!permissions.has(PermissionFlagsBits.ManageMessages)) return message.channel.send(':x: You need the `MANAGE_MESSAGES` permission to pause the music!');
}
serverQueue.paused = true;
serverQueue.connection.dispatcher.pause();
serverQueue.audioPlayer.pause();
return message.channel.send('⏸ Paused the music!');
} else return message.channel.send(':x: There is nothing playing.');
}

View File

@ -1,5 +1,6 @@
const YouTube = require("simple-youtube-api");
const he = require('he');
const { EmbedBuilder, PermissionFlagsBits } = require("discord.js");
module.exports = {
name: 'play',
@ -8,13 +9,12 @@ module.exports = {
alias: 'p',
args: true,
cooldown: 3,
onlyDev: false,
async execute(message, args, client, Discord, prefix) {
const youtube = new YouTube(client.config.api_key);
async execute(message, args, client, prefix) {
const youtube = new YouTube(client.config.youtube_api_key);
const searchString = args.slice(1).join(" ");
const url = args[1] ? args[1].replace(/<(.+)>/g, "$1") : "";
const serverQueue = client.queue.get(message.guild.id);
const voiceChannel = message.member.voiceChannel;
const voiceChannel = message.member.voice.channel;
if (!serverQueue) {
if (!voiceChannel) return message.channel.send(':x: I\'m sorry but you need to be in a voice channel to play music!');
} 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!');
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!');
}
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!');
}
if (url.match(/^https?:\/\/(www.youtube.com|youtube.com)\/playlist(.*)$/)) {
@ -43,15 +43,16 @@ module.exports = {
try {
var videos = await youtube.searchVideos(searchString, 10);
let index = 0;
const embed = new Discord.RichEmbed()
const embed = new EmbedBuilder()
.setTitle("__Song Selection__")
.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)
message.channel.send(embed);
message.channel.send({ embeds: [embed] });
try {
var response = await message.channel.awaitMessages(message2 => message2.content > 0 && message2.content < 11 && message2.author === message.author, {
maxMatches: 1,
var response = await message.channel.awaitMessages({
filter: message2 => message2.content > 0 && message2.content < 11 && message2.author === message.author,
max: 1,
time: 10000,
errors: ['time']
});

View File

@ -1,5 +1,6 @@
const YouTube = require("simple-youtube-api");
const he = require('he');
const { EmbedBuilder, PermissionFlagsBits } = require("discord.js");
module.exports = {
name: 'playlist',
@ -7,43 +8,36 @@ module.exports = {
description: 'Save and load queues',
alias: 'pl',
cooldown: 10,
onlyDev: false,
async execute(message, args, client, Discord, prefix) {
const embed = new Discord.RichEmbed()
async execute(message, args, client, prefix) {
const embed = new EmbedBuilder()
.setTitle('Options for playlist!')
.addField('play', 'Play the guild specific queue.', true)
.addField('save', 'Save the currently playing queue. Note that this will overwrite the currently saved queue!', true)
.addField('add', 'Add songs to the playlist. Like song selection', true)
.addField('remove', 'Remove songs from the playlist.', true)
.addField('list', 'Display the playlist.', true)
.setFooter(`how to use: ${prefix}playlist <Option> <Optional option>`)
.setAuthor(client.user.username, client.user.displayAvatarURL)
.addFields(
{ name: 'play', value: 'Play the guild specific queue.', inline: true },
{ name: 'save', value: 'Save the currently playing queue. Note that this will overwrite the currently saved queue!', inline: true },
{ name: 'add', value: 'Add songs to the playlist. Like song selection', inline: true },
{ name: 'remove', value: 'Remove songs from the playlist.', inline: true },
{ name: 'list', value: 'Display the playlist.', inline: true }
)
.setFooter({ text: `how to use: ${prefix}playlist <Option> <Optional option>` })
.setAuthor({ name: client.user.username, iconURL: client.user.avatarURL()})
.setColor(client.config.embedColor)
const permissions = message.channel.permissionsFor(message.author);
if (message.author.id !== client.config.devId) {
if (client.global.db.guilds[message.guild.id].dj) {
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('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].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!');
} else if (!permissions.has(PermissionFlagsBits.ManageGuild)) 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 (args[1]) {
const optionName = args[1].toLowerCase();
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 {
option.execute(message, args, client, Discord, prefix);
option.execute(message, args, client, prefix);
} catch (error) {
message.reply(`:x: there was an error trying to execute that option! Please contact support with \`${prefix}bug\`!`);
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);
message.reply(`:x: there was an error trying to execute that option!`);
console.log(error);
}
} else {
return message.channel.send(embed);
return message.channel.send({ embeds: [embed] });
}
} 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 he = require('he');
const { EmbedBuilder } = require("discord.js");
module.exports = {
name: 'add',
async execute(message, args, client, Discord, prefix) {
async execute(message, args, client, prefix) {
if (client.global.db.playlists[message.guild.id].saved) {
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 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!');
@ -16,15 +17,16 @@ module.exports = {
try {
var videos = await youtube.searchVideos(searchString, 10);
let index = 0;
const embed = new Discord.RichEmbed()
const embed = new EmbedBuilder()
.setTitle("__Song Selection__")
.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")
message.channel.send(embed);
message.channel.send({ embeds: [embed] });
try {
var response = await message.channel.awaitMessages(message2 => message2.content > 0 && message2.content < 11, {
maxMatches: 1,
var response = await message.channel.awaitMessages({
filter: message2 => message2.content > 0 && message2.content < 11,
max: 1,
time: 10000,
errors: ['time']
});
@ -41,11 +43,11 @@ module.exports = {
}
let song = {
id: video.id,
title: Discord.Util.escapeMarkdown(video.title),
title: video.title,
url: `https://www.youtube.com/watch?v=${video.id}`
}
client.global.db.playlists[message.guild.id].songs.push(song);
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!');
}
};
};

View File

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

View File

@ -1,6 +1,8 @@
const { EmbedBuilder } = require("discord.js");
module.exports = {
name: 'list',
async execute(message, args, client, Discord, prefix) {
async execute(message, args, client, prefix) {
if (args[2]) {
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++) {
queuemessage = queuemessage.replace('**#**', `**${i + 1}**`);
}
const embed = new Discord.RichEmbed()
const embed = new EmbedBuilder()
.setTitle("__playlist queue__")
.setDescription(`${pagetext}\n${queuemessage}`)
.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 = {
name: 'play',
async execute(message, args, client, Discord, prefix) {
async execute(message, args, client, prefix) {
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!');
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!');
}
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!');
}
let songs;
@ -24,8 +27,13 @@ module.exports = {
if (!serverQueue) {
const construct = {
textChannel: message.channel,
voiceChannel: message.member.voiceChannel,
voiceChannel: message.member.voice.channel,
connection: null,
audioPlayer: createAudioPlayer({
behaviors: {
noSubscriber: NoSubscriberBehavior.Play,
}
}),
songs: [...songs],
volume: client.global.db.guilds[message.guild.id].defaultVolume,
playing: false,
@ -38,7 +46,13 @@ module.exports = {
client.queue.set(message.guild.id, construct);
message.channel.send(":white_check_mark: Queue set!");
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;
client.funcs.play(message.guild, construct.songs[0], client, message, 0, false);
} catch (error) {
@ -46,10 +60,10 @@ module.exports = {
return message.channel.send(`:x: An error occured: ${error}`);
}
} else {
serverQueue.connection.dispatcher.end("queue set");
serverQueue.audioPlayer.stop();
serverQueue.songs = [...client.global.db.playlists[message.guild.id].songs];
message.channel.send(":white_check_mark: Queue set!");
}
} else return message.channel.send(':x: There is no queue set for this server!')
}
};
};

View File

@ -1,6 +1,6 @@
module.exports = {
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 (!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;
@ -10,4 +10,4 @@ module.exports = {
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!');
}
};
};

View File

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

View File

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

View File

@ -1,11 +1,12 @@
const { PermissionFlagsBits } = require("discord.js");
module.exports = {
name: 'remove',
description: 'Remove command.',
alias: 'rm',
cooldown: 5,
onlyDev: false,
execute(message, args, client, Discord, prefix) {
const { voiceChannel } = message.member;
execute(message, args, client, prefix) {
const voiceChannel = message.member.voice.channel;
const serverQueue = client.queue.get(message.guild.id);
const permissions = message.channel.permissionsFor(message.author);
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 (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 (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 (client.global.db.guilds[message.guild.id].dj) {
if (serverQueue.songs[pos].author !== message.author) {
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('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!');
}
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 (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!');
}
} 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!');
message.channel.send(`🗑️ removed \`${serverQueue.songs[pos].title}\` from the queue!`);
return serverQueue.songs.splice(pos, 1);
}

View File

@ -1,25 +1,24 @@
const { PermissionFlagsBits } = require("discord.js");
module.exports = {
name: 'resume',
description: 'Resume command.',
alias: 'resume',
cooldown: 5,
onlyDev: false,
execute(message, args, client, Discord, prefix) {
execute(message, args, client, prefix) {
const serverQueue = client.queue.get(message.guild.id);
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.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 (client.global.db.guilds[message.guild.id].permissions === true) {
if (client.global.db.guilds[message.guild.id].dj) {
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('MANAGE_MESSAGES')) return message.channel.send(':x: You need the `MANAGE_MESSAGES` permission to resume 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 loop the queue!');
if (client.global.db.guilds[message.guild.id].permissions === true) {
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!');
} else if (!permissions.has(PermissionFlagsBits.ManageMessages)) return message.channel.send(':x: You need the `MANAGE_MESSAGES` permission to resume the music!');
}
serverQueue.paused = false;
serverQueue.connection.dispatcher.resume();
serverQueue.audioPlayer.unpause();
return message.channel.send('▶ Resumed the music!');
}
return message.channel.send(':x: The music is not paused!');

View File

@ -1,31 +1,29 @@
const { PermissionFlagsBits } = require("discord.js");
module.exports = {
name: 'seek',
description: 'seek command.',
description: 'Seek music.',
alias: 'seek',
cooldown: 10,
onlyDev: true,
async execute(message, args, client, Discord, prefix) {
async execute(message, args, client, prefix) {
const ytdl = require('ytdl-core');
const serverQueue = client.queue.get(message.guild.id);
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.');
let data = await Promise.resolve(ytdl.getInfo(serverQueue.songs[0].url));
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 (client.global.db.guilds[message.guild.id].permissions === true) {
if (client.global.db.guilds[message.guild.id].dj) {
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('MANAGE_MESSAGES')) return message.channel.send(':x: You need the `MANAGE_MESSAGES` permission 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].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!');
} else if (!permissions.has(PermissionFlagsBits.ManageMessages)) 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>\``);
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 (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!`);
serverQueue.connection.dispatcher.end('seek');
serverQueue.audioPlayer.stop();
client.funcs.play(message.guild, serverQueue.songs[0], client, message, pos, false);
} else {
message.channel.send(':x: There is nothing playing!');

View File

@ -1,43 +1,39 @@
const { EmbedBuilder, PermissionFlagsBits } = require("discord.js");
module.exports = {
name: 'settings',
usage: '[setting]',
description: 'Change the settings',
alias: 'settings',
cooldown: 10,
onlyDev: false,
async execute(message, args, client, Discord, prefix) {
const embed = new Discord.RichEmbed()
async execute(message, args, client, prefix) {
const embed = new EmbedBuilder()
.setTitle('Guild settings for Musix')
.addField('prefix', 'Change the guild specific prefix. (string)', true)
.addField('volume', 'Change the default volume that the bot will start playing at. (number)', true)
.addField('permissions', 'Change whether to require permissions to use eg `skip, stop, pause, loop, etc...`', 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)
.addField('announcesongs', 'Whether to announce songs that start playing or not.')
.addField('songselection', 'Will i ask to select a song from the top 10 queries or start playing the first result instantly.')
.setFooter(`how to use: ${prefix}settings <Setting name> <value>`)
.setAuthor(client.user.username, client.user.displayAvatarURL)
.addFields(
{ name: 'prefix', value: 'Change the guild specific prefix. (string)', inline: true},
{ name: 'volume', value: 'Change the default volume that the bot will start playing at. (number)', inline: true },
{ name: 'permissions', value: 'Change whether to require permissions to use eg `skip, stop, pause, loop, etc...`', inline: true },
{ 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 },
{ name: 'announcesongs', value: 'Whether to announce songs that start playing or not.' },
{ name: 'songselection', value: 'Will i ask to select a song from the top 10 queries or start playing the first result instantly.' }
)
.setFooter({ text: `how to use: ${prefix}settings <Setting name> <value>` })
.setAuthor({ name: client.user.username, iconURL: client.user.avatarURL()})
.setColor(client.embedColor)
const permissions = message.channel.permissionsFor(message.author);
if (message.author.id !== client.config.devId) {
if (!permissions.has('MANAGE_GUILD')) return message.channel.send(':x: You need the `MANAGE_SERVER` permission to change the settings!');
}
if (!permissions.has(PermissionFlagsBits.ManageGuild)) return message.channel.send(':x: You need the `MANAGE_SERVER` permission to change the settings!');
if (args[1]) {
const optionName = args[1].toLowerCase();
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 {
option.execute(message, args, client, Discord, prefix);
option.execute(message, args, client, prefix);
} catch (error) {
message.reply(`:x: there was an error trying to execute that option! Please contact support with \`${prefix}bug\`!`);
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);
message.reply(`:x: there was an error trying to execute that option!`);
console.log(error);
}
} else {
return message.channel.send(embed);
return message.channel.send({ embeds: [embed] });
}
},
};

View File

@ -1,6 +1,6 @@
module.exports = {
name: 'announcesongs',
async execute(message, args, client, Discord, prefix) {
async execute(message, args, client, prefix) {
if (client.global.db.guilds[message.guild.id].startPlaying) {
client.global.db.guilds[message.guild.id].startPlaying = 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`!');
}
}
};
};

View File

@ -1,6 +1,6 @@
module.exports = {
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] === 'true') {
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: Please define a boolean! (true/false)');
}
};
};

View File

@ -1,8 +1,8 @@
module.exports = {
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}\``);
client.global.db.guilds[message.guild.id].prefix = args[2];
message.channel.send(`:white_check_mark: New prefix set to: \`${args[2]}\``);
}
};
};

View File

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

View File

@ -1,20 +1,20 @@
const { PermissionFlagsBits } = require("discord.js");
module.exports = {
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].permissions) {
client.global.db.guilds[message.guild.id].permissions = true;
}
if (message.guild.roles.find(x => x.name === "DJ")) {
client.global.db.guilds[message.guild.id].djrole = message.guild.roles.find(x => x.name === "DJ").id;
if (message.guild.roles.cache.find(x => x.name === "DJ")) {
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.');
client.global.db.guilds[message.guild.id].dj = true;
} else {
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!');
message.guild.createRole({
name: 'DJ',
})
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({ name: 'DJ' })
.then(role => client.global.db.guilds[message.guild.id].djrole = role.id)
.catch(console.error)
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`');
}
}
};
};

View File

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

View File

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

View File

@ -1,10 +1,10 @@
module.exports = {
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 (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.');
client.global.db.guilds[message.guild.id].defaultVolume = 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.',
alias: 'shuffle',
cooldown: 5,
onlyDev: false,
execute(message, args, client, Discord, prefix) {
execute(message, args, client, prefix) {
const serverQueue = client.queue.get(message.guild.id);
let currentIndex = serverQueue.songs.length,
temporaryValue,
@ -19,4 +18,4 @@ module.exports = {
serverQueue.songs[randomIndex] = temporaryValue;
}
}
};
};

View File

@ -1,39 +1,36 @@
const { PermissionFlagsBits } = require("discord.js");
module.exports = {
name: 'skip',
description: 'Skip command.',
alias: 's',
cooldown: 5,
onlyDev: false,
execute(message, args, client, Discord, prefix) {
const { voiceChannel } = message.member;
execute(message, args, client, prefix) {
const voiceChannel = message.member.voice.channel;
const serverQueue = client.queue.get(message.guild.id);
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.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 (client.global.db.guilds[message.guild.id].permissions === true) {
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 {
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 (!message.member.roles.cache.has(client.global.db.guilds[message.guild.id].djrole) && !permissions.has(PermissionFlagsBits.ManageMessages)) {
return vote(serverQueue, message, client);
} else {
return skipSong(serverQueue, message);
}
} else {
return skipSong(serverQueue, message);
return vote(serverQueue, message, client);
}
}
};
function skipSong(serverQueue, message) {
message.channel.send(':fast_forward: Skipped the song!');
serverQueue.connection.dispatcher.end('skipped');
serverQueue.audioPlayer.stop();
};
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();
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!');
serverQueue.votes++;
serverQueue.voters.push(message.member.id);

View File

@ -1,21 +1,25 @@
const { EmbedBuilder } = require("discord.js");
const { getVoiceConnections } = require("@discordjs/voice");
module.exports = {
name: 'status',
description: 'Status command.',
alias: 'status',
cooldown: 5,
onlyDev: false,
execute(message, args, client, Discord, prefix) {
execute(message, args, client, prefix) {
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}`)
.addField(':signal_strength: Ping', ping, true)
.addField(':stopwatch: Uptime', uptime, true)
.addField(`:play_pause: Currently playing music on`, `${client.voiceConnections.size} guild(s)`, true)
.addField(`💿 Operating system`, process.platform, true)
.setAuthor(client.user.username, client.user.displayAvatarURL)
.addFields(
{ name: ':signal_strength: Ping', value: ping, inline: true },
{ name: ':stopwatch: Uptime', value: uptime, inline: true },
{ name: ':play_pause: Currently playing music on', value: `${getVoiceConnections.size} guild(s)`, inline: true },
{ name: '💿 Operating system', value: process.platform, inline: true }
)
.setAuthor({ name: client.user.username, iconURL: client.user.avatarURL()})
.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 = {
name: 'stop',
description: 'Stop command.',
alias: 'stop',
cooldown: 5,
onlyDev: false,
execute(message, args, client, Discord, prefix) {
const { voiceChannel } = message.member;
execute(message, args, client, prefix) {
const voiceChannel = message.member.voice.channel;
const serverQueue = client.queue.get(message.guild.id);
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.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 (client.global.db.guilds[message.guild.id].permissions === true) {
if (client.global.db.guilds[message.guild.id].dj) {
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('MANAGE_CHANNELS')) return message.channel.send(':x: You need the `MANAGE_CHANNELS` permission 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].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!');
} else if (!permissions.has(PermissionFlagsBits.ManageChannels)) return message.channel.send(':x: You need the `MANAGE_CHANNELS` permission to stop the music!');
}
serverQueue.songs = [];
serverQueue.looping = false;
serverQueue.connection.dispatcher.end('Stopped');
serverQueue.audioPlayer.stop();
message.channel.send(':stop_button: Stopped the music!')
}
};

View File

@ -1,30 +1,29 @@
const { PermissionFlagsBits } = require("discord.js");
module.exports = {
name: 'volume',
description: 'Volume command.',
alias: 'volume',
cooldown: 5,
onlyDev: false,
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 permissions = message.channel.permissionsFor(message.author);
if (!serverQueue) 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}**`);
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 (client.global.db.guilds[message.guild.id].permissions === true) {
if (client.global.db.guilds[message.guild.id].dj) {
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('MANAGE_CHANNELS')) return message.channel.send(':x: You need the `MANAGE_CHANNELS` permission 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].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!');
} else if (!permissions.has(PermissionFlagsBits.ManageChannels)) 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 (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!');
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}**`);
}
};

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 = {
name: 'guildcreate',
async execute(client, guild) {
client.db.collection('guilds').doc(guild.id).set({
prefix: client.config.prefix,
defaultVolume: 5,
permissions: false,
premium: false,
dj: false,
djrole: null,
startPlaying: true
});
client.global.db.guilds[guild.id] = {
prefix: client.config.prefix,
defaultVolume: 5,
permissions: false,
premium: false,
dj: false,
djrole: null,
startPlaying: true
};
if(client.config.firebase.serviceAccount){
client.db.collection('guilds').doc(guild.id).set({
prefix: client.config.prefix,
defaultVolume: 50,
permissions: false,
premium: false,
dj: false,
djrole: null,
startPlaying: true
});
client.global.db.guilds[guild.id] = {
prefix: client.config.prefix,
defaultVolume: 50,
permissions: false,
premium: false,
dj: false,
djrole: null,
startPlaying: true
};
}
}
}

View File

@ -1,6 +1,6 @@
module.exports = {
name: 'message',
async execute(client, message, Discord) {
async execute(client, message) {
if (message.author.bot || !message.guild) return;
let prefix = client.global.db.guilds[message.guild.id].prefix;
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] === '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 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.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, Discord, prefix, command);
client.funcs.exe(message, args, client, prefix, command);
}
}

View File

@ -1,41 +1,53 @@
module.exports = {
name: 'ready',
async execute(client, dbl, Discord) {
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 -');
async execute(client) {
client.user.setActivity(`@${client.user.username} help | 🎶`, { type: 'LISTENING' });
client.user.setStatus('dnd');
dbl.postStats(client.guilds.size);
client.user.setStatus('online');
console.log('- Activated -');
setInterval(async () => {
client.guilds.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,
});
}
client.guilds.cache.forEach(guild => {
client.global.db.guilds[guild.id] = {
prefix: client.config.prefix,
defaultVolume: 50,
permissions: false,
premium: false,
dj: false,
djrole: null,
startPlaying: true
};
});
if(client.config.firebase.serviceAccount){
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);
}, 1800000);
setInterval(() => {
client.funcs.ffmpeg(client, Discord);
}, 7200000);
remoteMusixPlaylistsData.forEach(guildData => {
client.global.db.playlists[guildData.id] = guildData.d;
});
console.log('- DB Set -');
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) {
const Discord = require('discord.js');
let song = {
id: video.id,
title: Discord.Util.escapeMarkdown(video.title),
title: video.title,
url: `https://www.youtube.com/watch?v=${video.id}`,
author: message.author
}
@ -12,6 +13,11 @@ module.exports = async function (video, message, voiceChannel, client, playlist
textChannel: message.channel,
voiceChannel: voiceChannel,
connection: null,
audioPlayer: createAudioPlayer({
behaviors: {
noSubscriber: NoSubscriberBehavior.Play,
}
}),
songs: [],
volume: client.global.db.guilds[message.guild.id].defaultVolume,
playing: false,
@ -24,12 +30,18 @@ module.exports = async function (video, message, voiceChannel, client, playlist
construct.songs.push(song);
client.queue.set(message.guild.id, construct);
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;
client.funcs.play(message.guild, construct.songs[0], client, message, 0, true);
} catch (error) {
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}`);
}
} 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 MusicClient = require('./Struct/Client');
const MusicClient = require('./Client');
const client = new MusicClient({});
const DBL = require("dblapi.js");
const dbl = new DBL(process.env.DBLTOKEN, client);
const fs = require('fs');
require('dotenv/config');
client.config = require('./config/config.js');
const commandFiles = fs.readdirSync('./commands/').filter(f => f.endsWith('.js'));
for (const file of commandFiles) {
@ -37,13 +32,13 @@ for (const file of settingFiles) {
client.on('ready', async () => {
const eventName = 'ready';
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 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) => {
@ -52,7 +47,4 @@ client.on('guildCreate', async (guild) => {
event.execute(client, guild);
});
dbl.on('error', error => {
console.log(`Error with DBL! ${error}`);
})
client.login(client.config.token).catch(err => { console.log('- Failed To Login -> ' + err); });
client.login(client.config.discord_api_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",
"version": "2.21.1",
"name": "musix-oss",
"version": "2.22.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node ."
"start": "node index.js",
"start:dev": "nodemon"
},
"keywords": [],
"author": "MatteZ02",
"author": "Musix Org",
"license": "MIT",
"homepage": "https://https://github.com/MatteZ02/Musix",
"homepage": "https://https://github.com/musix-oss/musix",
"repository": {
"type": "git",
"url": "https://https://github.com/MatteZ02/Musix"
"url": "https://https://github.com/musix-oss/musix"
},
"dependencies": {
"dblapi.js": "^2.4.1",
"discord.js": "^14.14.1",
"@discordjs/voice": "^0.16.1",
"@discordjs/opus": "^0.9.0",
"dotenv": "^16.4.1",
"ffmpeg-static": "^5.2.0",
"firebase": "^10.8.0",
"firebase-admin": "^12.0.0",
"fs": "0.0.1-security",
"he": "^1.2.0",
"ms": "^2.1.3",
"node-opus": "^0.3.3",
"request": "^2.88.2",
"simple-youtube-api": "^5.2.1",
"ytdl-core": "^4.11.5"
},
"devDependencies": {
"nodemon": "^3.0.3"
}
}