1
0
mirror of https://github.com/musix-org/musix-oss synced 2025-06-18 05:26:00 +00:00

Update V3.2.0

This commit is contained in:
MatteZ02
2020-04-19 20:00:16 +03:00
parent ce214a827f
commit ec07bdb5a3
33 changed files with 2319 additions and 659 deletions

View File

@ -1,60 +1,66 @@
const { Client, Collection } = require('discord.js');
const admin = require('firebase-admin');
const serviceAccount = require('./config/serviceAccount.json');
const fs = require('fs');
const path = require('path');
const events = require('../events/events.ts');
const { Client, Collection } = require("discord.js");
const admin = require("firebase-admin");
const serviceAccount = require("./config/serviceAccount.json");
const fs = require("fs");
const path = require("path");
const events = require("../events/events.ts");
module.exports = class extends Client {
constructor() {
super({
disableEveryone: true,
disabledEvents: ['TYPING_START']
});
constructor() {
super({
disableEveryone: true,
disabledEvents: ["TYPING_START"],
});
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
});
this.commands = new Collection();
this.commandAliases = new Collection();
this.settingCmd = new Collection();
this.queue = new Map();
this.funcs = {};
this.dispatcher = {};
this.config = require('./config/config.ts');
this.messages = require('./config/messages.ts');
this.db = admin.firestore();
this.db.FieldValue = require('firebase-admin').firestore.FieldValue;
this.dispatcher.finish = require('../events/dispatcherEvents/finish.ts');
this.dispatcher.error = require('../events/dispatcherEvents/error.ts');
this.global = {
db: {
guilds: {},
},
};
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
});
this.commands = new Collection();
this.commandAliases = new Collection();
this.settingCmd = new Collection();
this.queue = new Map();
this.funcs = {};
this.dispatcher = {};
this.config = require("../../config/config.ts");
this.messages = require("./config/messages.ts");
this.db = admin.firestore();
this.db.FieldValue = require("firebase-admin").firestore.FieldValue;
this.dispatcher.finish = require("../events/dispatcherEvents/finish.ts");
this.dispatcher.error = require("../events/dispatcherEvents/error.ts");
this.global = {
db: {
guilds: {},
},
};
fs.readdirSync(path.join(__dirname, 'funcs')).forEach(filename => {
this.funcs[filename.slice(0, -3)] = require(`./funcs/${filename}`);
});
fs.readdirSync(path.join(__dirname, "funcs")).forEach((filename) => {
this.funcs[filename.slice(0, -3)] = require(`./funcs/${filename}`);
});
const commandFiles = fs.readdirSync(path.join(path.dirname(__dirname), 'commands')).filter(f => f.endsWith('.ts'));
for (const file of commandFiles) {
const command = require(`../commands/${file}`);
command.uses = 0;
this.commands.set(command.name, command);
this.commandAliases.set(command.alias, command);
}
const settingFiles = fs.readdirSync(path.join(path.dirname(__dirname), 'commands/settings')).filter(f => f.endsWith('.ts'));
for (const file of settingFiles) {
const option = require(`../commands/settings/${file}`);
this.settingCmd.set(option.name, option);
}
if (this.config.devMode) {
this.config.token = this.config.devToken;
}
events(this);
this.login(this.config.token).catch(err => console.log('Failed to login: ' + err));
const commandFiles = fs
.readdirSync(path.join(path.dirname(__dirname), "commands"))
.filter((f) => f.endsWith(".ts"));
for (const file of commandFiles) {
const command = require(`../commands/${file}`);
command.uses = 0;
this.commands.set(command.name, command);
this.commandAliases.set(command.alias, command);
}
const settingFiles = fs
.readdirSync(path.join(path.dirname(__dirname), "commands/settings"))
.filter((f) => f.endsWith(".ts"));
for (const file of settingFiles) {
const option = require(`../commands/settings/${file}`);
this.settingCmd.set(option.name, option);
}
if (this.config.devMode) {
this.config.token = this.config.devToken;
}
events(this);
this.login(this.config.token).catch((err) =>
console.log("Failed to login: " + err)
);
}
};

View File

@ -1,32 +0,0 @@
require("dotenv/config");
module.exports = {
token: process.env.TOKEN,
devToken: process.env.DEVTOKEN,
dblKey: process.env.DBLKEY,
api_key: process.env.GOOGLE_API_KEY,
testServer: "489111553321336832",
primary_test_channel: "617633098296721409",
secondary_test_channel: "570531724002328577",
devId: "360363051792203779",
embedColor: "#b50002",
invite:
"https://discordapp.com/oauth2/authorize?client_id=607266889537945605&permissions=3427328&scope=bot",
supportServer: "https://discord.gg/rvHuJtB",
devMode: false,
api: false,
saveDB: true,
respawn: true,
shards: 10,
shardDelay: 10000,
spawnTimeout: 60000,
respawnDelay: 1000,
prefix: ">",
devPrefix: "-",
defaultVolume: 5,
permissions: false,
dj: false,
djrole: null,
startPlaying: true,
bass: 1,
};

View File

@ -9,15 +9,27 @@ module.exports = {
announceSongsTrue:
emojis.green_check_mark + "announcesongs now set to `true`!",
bassApplied:
emojis.volumeHigh +
"The bass level **%BASS%** will be applied when the next song starts playing!",
emojis.volumeHigh + "The bass level **%BASS%** has been applied!",
bassFalse: emojis.green_check_mark + "Bass is now false!",
bassLevel: emojis.green_check_mark + "Bass level is now",
blacklistTitle: "Currently blacklisted channels:",
blackListedVC:
emojis.redx +
"Your voiceChannel is blacklisted! Please choose another channel!",
boolean: emojis.redx + "Please define a boolean! (true/false)",
cancellingVideoSelection: emojis.redx + "Cancelling video selection",
cantSkipToCurrent:
emojis.redx + "You can't skip to the song currently playing!",
channelAdded:
emojis.green_check_mark + "Channel %CHANNEL% added to the blacklist!",
channelAlreadyBlackListed:
emojis.redx + "That channel is already blacklisted!",
channelFull: emojis.redx + "Your voice channel is full!",
channelNotBlackListed:
emojis.redx + "That channel is not blacklisted or does not exist!",
channelRemoved:
emojis.green_check_mark +
"Channel %CHANNEL% has been removed from the blacklist!",
cmdUsesFooter: "These statistics are from the current uptime.",
cmdUsesTitle: "Musix Command Usage During Current Uptime",
correctUsage: emojis.redx + "correct usage: ",
@ -38,6 +50,8 @@ module.exports = {
devMode:
emojis.redx +
"Dev mode has been turned on! Commands are only available to developer(s)!",
disableNigthCore:
emojis.redx + "Please disable nigthCore in order to use this command!",
dispatcherError: "Error with the dispatcher: ",
djFalse: emojis.green_check_mark + "`DJ` now set to `false`",
djRoleCreated:
@ -56,24 +70,34 @@ module.exports = {
errorExeOpt:
emojis.redx + "there was an error trying to execute that option!",
evalTitle: "Evaluation Command",
failedToLoad: emojis.redx + "Songs failed to load: ",
helpCmdFooter: "Command Alias:",
helpFooter:
'"%PREFIX%help <command>" to see more information about a command.',
helpTitle: "help",
idOrMentionChannel:
emojis.redx + "Please provide a channel id or mention a channel!",
inviteTitle: "Invite Musix to your Discord server!",
joined: emojis.green_check_mark + "Joined",
joinSupport: "Join the musix support server: ",
loadingSongs: emojis.loading + "Loading song(s)",
looping: emojis.repeat + "Looping the queue now!",
loopingSong: emojis.repeatSong + "Looping **%TITLE%** now!",
lyricsTitle: "Lyrics",
lyricsUsage: emojis.redx + "Provide a song to search for!",
maxBass: emojis.redx + "The max bass is `100`!",
maxVolume: emojis.redx + "The max volume is `100`!",
mentionChannel: emojis.redx + "Please mention a channel!",
musicCommandsDisabled:
emojis.redx +
"This channels has been blacklisted! Music commands cannot be used here!",
nigthCoreApplied:
emojis.green_check_mark +
"NigthCore is now **%BOOLEAN%** this will be applied when the next song starts playing!",
noDj: emojis.redx + "You need the `DJ` role to use this command!",
noLooping: emojis.repeat + "No longer looping the queue!",
noLoopingSong: emojis.repeatSong + "No longer looping the song!",
noMorePremium: ":cry: Guild %GUILD% is no longer premium!",
noPerms: emojis.redx + `You need the %PERMS% permission to use this command!`,
noPermsConnect:
emojis.redx +
@ -95,8 +119,10 @@ module.exports = {
"I cannot use external emojis, make sure I have the proper permissions!",
noQuery: emojis.redx + "you need to use a link or search for a song!",
noResults: emojis.redx + "I could not obtain any search results!",
noResultsLyrics: emojis.redx + "I could not obtain any results!",
noServerQueue: emojis.redx + "There is nothing playing!",
noSongs: emojis.redx + "That song does not exist!",
notPremium: emojis.redx + "This is not a premium guild!",
nowPlayingDesc: emojis.notes + "**Now playing:**",
notAllowed: emojis.redx + "You are not allowed to do that!",
notEnoughVotes: emojis.redx + "Not enough votes!",
@ -105,6 +131,8 @@ module.exports = {
emojis.redx +
"I'm sorry but you need to be in a voice channel to play music!",
nowPlaying: "__Now playing__",
nowPremium: ":tada: Guild %GUILD% is now premium!",
onlyDev: emojis.redx + "This command is only available for dev(s)!",
paused: emojis.pause + "Paused the music!",
permission: "🔒 Permission requirement:",
permissionsFalse: emojis.redx + "That value is already `false`!",
@ -122,6 +150,7 @@ module.exports = {
prefixHere: "My prefix here is: ",
prefixMaxLength: "The prefix must be shorter or equal to 5 letters!",
prefixSet: emojis.green_check_mark + "New prefix set to:",
premiumUsage: emojis.redx + "`settings premium <guild id>`",
provideANumber:
"Please provide a number ranging from 1-10 to select one of the search results.",
provideASong:
@ -151,6 +180,9 @@ module.exports = {
"Whether to announce songs that start playing or not.",
settingsBass: "bass",
settingsBassDesc: "Change the default bass level.",
settingsBlacklist: "blacklist",
settingsBlacklistDesc:
"Blacklist channels that you wan't to block music commands to be executed on or block the bot from joining certain voiceChannels.",
settingsFooter: "how to use: %PREFIX%settings <Setting name> <value>",
settingsPermissions: "permissions",
settingsPermissionsDesc:

View File

@ -1,7 +1,7 @@
module.exports = {
ytdlOptions: { filter: "audio", highWaterMark: 1 << 20, volume: false },
ytdlOptions: { filter: "audio", highWaterMark: 1 << 25, volume: false },
options: {
seek: 0,
seek: null,
bitrate: 1024,
volume: 1,
type: "converted",

View File

@ -1,27 +1,34 @@
module.exports = function (client, msg, command) {
const queue = client.queue.get(msg.guild.id);
const permissions = msg.channel.permissionsFor(msg.author);
if (!queue || !queue.playing) {
msg.channel.send(client.messages.noServerQueue);
return false;
const queue = client.queue.get(msg.guild.id);
const permissions = msg.channel.permissionsFor(msg.author);
if (!queue || !queue.playing) {
msg.channel.send(client.messages.noServerQueue);
return false;
}
if (msg.author.id !== client.config.devId) {
if (msg.member.voice.channel !== queue.voiceChannel) {
msg.channel.send(client.messages.wrongVoiceChannel);
return false;
}
if (msg.author.id !== client.config.devId) {
if (msg.member.voice.channel !== queue.voiceChannel) {
msg.channel.send(client.messages.wrongVoiceChannel);
return false;
}
if (client.global.db.guilds[msg.guild.id].permissions === true) {
if (client.global.db.guilds[msg.guild.id].dj) {
if (!msg.member.roles.cache.has(client.global.db.guilds[msg.guild.id].djrole)) {
msg.channel.send(client.messages.noDj);
return false;
} else return true;
} else if (!permissions.has(command.permission)) {
let message
message = client.messages.noPerms.replace("%PERMS%", command.permissions);
msg.channel.send(message);
return false;
} else return true;
if (client.global.db.guilds[msg.guild.id].permissions === true) {
if (client.global.db.guilds[msg.guild.id].dj) {
if (
!msg.member.roles.cache.has(
client.global.db.guilds[msg.guild.id].djrole
)
) {
msg.channel.send(client.messages.noDj);
return false;
} else return true;
} else if (!permissions.has(command.permission)) {
let message;
message = client.messages.noPerms.replace(
"%PERMS%",
command.permissions
);
msg.channel.send(message);
return false;
} else return true;
} else return true;
} else return true;
};

View File

@ -1,11 +1,22 @@
module.exports = async function (client) {
client.guilds.cache.forEach(guild => {
if (client.global.db.guilds[guild.id].prefix === undefined) client.global.db.guilds[guild.id].prefix = client.config.prefix;
if (client.global.db.guilds[guild.id].defaultVolume === undefined) client.global.db.guilds[guild.id].defaultVolume = client.config.defaultVolume;
if (client.global.db.guilds[guild.id].permissions === undefined) client.global.db.guilds[guild.id].permissions = client.config.permissions;
if (client.global.db.guilds[guild.id].dj === undefined) client.global.db.guilds[guild.id].dj = client.config.dj;
if (client.global.db.guilds[guild.id].djrole === undefined) client.global.db.guilds[guild.id].djrole = client.config.djrole;
if (client.global.db.guilds[guild.id].startPlaying === undefined) client.global.db.guilds[guild.id].startPlaying = client.config.startPlaying;
if (client.global.db.guilds[guild.id].bass === undefined) client.global.db.guilds[guild.id].bass = client.config.bass;
});
};
client.guilds.cache.forEach((guild) => {
if (client.global.db.guilds[guild.id].prefix === undefined)
client.global.db.guilds[guild.id].prefix = client.config.prefix;
if (client.global.db.guilds[guild.id].defaultVolume === undefined)
client.global.db.guilds[guild.id].defaultVolume =
client.config.defaultVolume;
if (client.global.db.guilds[guild.id].permissions === undefined)
client.global.db.guilds[guild.id].permissions = client.config.permissions;
if (client.global.db.guilds[guild.id].dj === undefined)
client.global.db.guilds[guild.id].dj = client.config.dj;
if (client.global.db.guilds[guild.id].djrole === undefined)
client.global.db.guilds[guild.id].djrole = client.config.djrole;
if (client.global.db.guilds[guild.id].startPlaying === undefined)
client.global.db.guilds[guild.id].startPlaying =
client.config.startPlaying;
if (client.global.db.guilds[guild.id].bass === undefined)
client.global.db.guilds[guild.id].bass = client.config.bass;
if (client.global.db.guilds[guild.id].blacklsit === undefined)
client.global.db.guilds[guild.id].blacklist = [];
});
};

12
src/struct/funcs/end.ts Normal file
View File

@ -0,0 +1,12 @@
module.exports = async function (client, msg, pos, command) {
const seek = parseInt(pos);
const queue = client.queue.get(msg.guild.id);
if (command.name === "seek") {
queue.time = pos * 1000;
} else {
queue.time = queue.connection.dispatcher.streamTime + queue.time;
}
queue.connection.dispatcher.end();
queue.endReason = "seek";
client.funcs.play(msg.guild, queue.songs[0], client, seek, false);
};

View File

@ -1,19 +1,28 @@
module.exports = function (msg, args, client, Discord, command) {
const permissions = msg.channel.permissionsFor(msg.client.user);
if (!permissions.has('EMBED_LINKS')) return msg.channel.send(client.messages.noPermsEmbed);
if (!permissions.has('USE_EXTERNAL_EMOJIS')) return msg.channel.send(client.noPermsUseExternalEmojis);
try {
command.uses++;
command.execute(msg, args, client, Discord, command);
} catch (error) {
const date = new Date();
msg.reply(client.messages.errorExe);
const embed = new Discord.MessageEmbed()
.setTitle(`Musix ${error.toString()}`)
.setDescription(error.stack.replace(/at /g, '**at **'))
.setFooter(`guild: ${msg.guild.id} (${msg.guild.name}), user: ${msg.member.id} (${msg.member.displayName}), channel: ${msg.channel.id} (${msg.channel.name}), date: ${date}, Shard: ${client.shard.ids}`)
.setColor('#b50002');
client.users.cache.get(client.devId).send(embed);
console.error(error);
}
const permissions = msg.channel.permissionsFor(msg.client.user);
if (!permissions.has("EMBED_LINKS"))
return msg.channel.send(client.messages.noPermsEmbed);
if (!permissions.has("USE_EXTERNAL_EMOJIS"))
return msg.channel.send(client.noPermsUseExternalEmojis);
if (
command.category === "music" &&
client.global.db.guilds[msg.guild.id].blacklist.includes(msg.channel.id)
)
return msg.channel.send(client.messages.musicCommandsDisabled);
try {
command.uses++;
command.execute(msg, args, client, Discord, command);
} catch (error) {
const date = new Date();
msg.reply(client.messages.errorExe);
const embed = new Discord.MessageEmbed()
.setTitle(`Musix ${error.toString()}`)
.setDescription(error.stack.replace(/at /g, "**at **"))
.setFooter(
`guild: ${msg.guild.id} (${msg.guild.name}), user: ${msg.member.id} (${msg.member.displayName}), channel: ${msg.channel.id} (${msg.channel.name}), date: ${date}, Shard: ${client.shard.ids}`
)
.setColor("#b50002");
client.users.cache.get(client.config.devId).send(embed);
console.error(error);
}
};

View File

@ -1,15 +1,17 @@
module.exports = async function (
video,
resource,
msg,
voiceChannel,
client,
playlist = false
playlist,
type
) {
const Discord = require("discord.js");
const song = {
title: Discord.Util.escapeMarkdown(video.title),
url: video.url,
title: Discord.Util.escapeMarkdown(resource.title),
url: resource.url,
author: msg.author,
type: type,
};
const queue = client.queue.get(msg.guild.id);
@ -24,12 +26,12 @@ module.exports = async function (
}
const construct = {
textChannel: null,
voiceChannel: null,
textChannel: msg.channel,
voiceChannel: voiceChannel,
connection: null,
songs: [],
volume: null,
bass: null,
volume: client.global.db.guilds[msg.guild.id].defaultVolume,
bass: client.global.db.guilds[msg.guild.id].bass,
nigthCore: false,
playing: false,
paused: false,
@ -42,11 +44,6 @@ module.exports = async function (
endReason: null,
};
construct.textChannel = msg.channel;
construct.voiceChannel = voiceChannel;
construct.volume = client.global.db.guilds[msg.guild.id].defaultVolume;
construct.bass = client.global.db.guilds[msg.guild.id].bass;
construct.songs.push(song);
client.queue.set(msg.guild.id, construct);

View File

@ -1,10 +1,9 @@
module.exports = async function (guild, song, client, seek, play) {
const { Readable: ReadableStream } = require("stream");
const Discord = require("discord.js");
const ytdl = require("ytdl-core");
const streamConfig = require("../config/streamConfig.ts");
const getThumb = require("video-thumbnail-url");
const prism = require("prism-media");
const queue = client.queue.get(guild.id);
if (!song) {
queue.voiceChannel.leave();
@ -14,6 +13,9 @@ module.exports = async function (guild, song, client, seek, play) {
streamConfig.options.seek = seek;
let input = song.url;
if (song.type === "ytdl") input = ytdl(song.url, streamConfig.ytdlOptions);
const ffmpegArgs = [
"-analyzeduration",
"0",
@ -28,38 +30,43 @@ module.exports = async function (guild, song, client, seek, play) {
"-af",
`bass=g=${queue.bass}`,
];
client.funcs.sleep(500);
if (queue.nigthCore) {
ffmpegArgs.push("-af");
ffmpegArgs.push("asetrate=52920");
}
const transcoder = new prism.FFmpeg({ args: ffmpegArgs });
const isStream = input instanceof ReadableStream;
const args = isStream ? ffmpegArgs.slice() : ["-i", input, ...ffmpegArgs];
args.unshift("-ss", String(seek));
const transcoder = new prism.FFmpeg({ args: args });
const stream = input.pipe(transcoder);
const dispatcher = queue.connection
.play(
ytdl(song.url, streamConfig.ytdlOptions).pipe(transcoder),
streamConfig.options
)
.play(stream, streamConfig.options)
.on("finish", () => {
client.dispatcher.finish(client, queue.endReason, guild);
})
.on("start", () => {
queue.endReason = null;
dispatcher.player.streamingData.pausedTime = 0;
})
.on("error", (error) => {
client.dispatcher.error(client, error, guild);
});
dispatcher.setVolume(queue.volume / 10);
if (client.global.db.guilds[guild.id].startPlaying || play) {
if ((client.global.db.guilds[guild.id].startPlaying && play) || play) {
if (song.type !== "ytdl") return;
const data = await Promise.resolve(ytdl.getInfo(queue.songs[0].url));
const songtime = (data.length_seconds * 1000).toFixed(0);
const thumbnail = getThumb(queue.songs[0].url);
const embed = new Discord.MessageEmbed()
.setTitle(`${client.messages.startPlaying}**${song.title}**`)
.setDescription(
`Song duration: \`${client.funcs.msToTime(songtime, "hh:mm:ss")}\``
)
.setThumbnail(thumbnail._rejectionHandler0)
.setColor(client.config.embedColor);
queue.textChannel.send(embed);
}

View File

@ -1,16 +1,18 @@
module.exports = async function (client) {
if (client.config.saveDB && !client.config.devMode) {
//console.log('DB saved');
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,
dj: client.global.db.guilds[guild.id].dj,
djrole: client.global.db.guilds[guild.id].djrole,
startPlaying: client.global.db.guilds[guild.id].startPlaying,
bass: client.global.db.guilds[guild.id].bass,
});
});
}
}
if (client.config.saveDB && !client.config.devMode) {
//console.log('DB saved');
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,
dj: client.global.db.guilds[guild.id].dj,
djrole: client.global.db.guilds[guild.id].djrole,
startPlaying: client.global.db.guilds[guild.id].startPlaying,
bass: client.global.db.guilds[guild.id].bass,
blacklist: client.global.db.guilds[guild.id].blacklist,
premium: client.global.db.guilds[guild.id].premium,
});
});
}
};

View File

@ -0,0 +1,3 @@
module.exports = function (milliseconds) {
return new Promise((resolve) => setTimeout(resolve, milliseconds));
};