1
0
mirror of https://github.com/musix-org/musix-oss synced 2025-07-06 19:00:50 +00:00

162 Commits
v2 ... v1.3.0

Author SHA1 Message Date
bb6e1d28b9 Bumb Version 2024-02-09 08:04:20 +02:00
3dd931282e Merge branch 'master' into v1 2024-02-09 07:56:25 +02:00
ea19532261 Update README.md 2024-02-09 07:40:04 +02:00
c424c93330 Replace forgotten older prefix 2024-02-09 07:25:29 +02:00
a527f84c29 Fix code to work on this decade 2024-02-09 07:22:35 +02:00
cd0fc2beff Use nodemon in development 2024-02-09 01:03:02 +02:00
53241c9062 Package Name Update 2024-02-09 00:15:48 +02:00
bd1042f2ee Licensing Changes 2024-02-09 00:15:25 +02:00
dffe362648 Dependencies Update 2024-02-09 00:13:58 +02:00
d33ffc042a Merge branch 'master' into v1 2024-02-09 00:09:19 +02:00
35739461ba Merge branch 'master' into v1 2024-02-09 00:06:27 +02:00
440c7fe99e Merge pull request #1 from musix-org/dependabot/npm_and_yarn/v1/discord.js-14.14.1
Bump discord.js from 11.6.4 to 14.14.1
2024-02-09 00:02:54 +02:00
e75e6b4785 Bump discord.js from 11.6.4 to 14.14.1
Bumps [discord.js](https://github.com/discordjs/discord.js/tree/HEAD/packages/discord.js) from 11.6.4 to 14.14.1.
- [Release notes](https://github.com/discordjs/discord.js/releases)
- [Changelog](https://github.com/discordjs/discord.js/blob/main/packages/discord.js/CHANGELOG.md)
- [Commits](https://github.com/discordjs/discord.js/commits/14.14.1/packages/discord.js)

---
updated-dependencies:
- dependency-name: discord.js
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-08 22:02:47 +00:00
5479359f9a Merge pull request #2 from musix-org/dependabot/npm_and_yarn/v1/opusscript-0.1.1
Bump opusscript from 0.0.6 to 0.1.1
2024-02-09 00:01:49 +02:00
8a959de014 Merge pull request #4 from musix-org/dependabot/npm_and_yarn/v1/ytdl-core-4.11.5
Bump ytdl-core from 0.29.7 to 4.11.5
2024-02-09 00:01:40 +02:00
26841615a0 Bump opusscript from 0.0.6 to 0.1.1
Bumps [opusscript](https://github.com/abalabahaha/opusscript) from 0.0.6 to 0.1.1.
- [Release notes](https://github.com/abalabahaha/opusscript/releases)
- [Commits](https://github.com/abalabahaha/opusscript/compare/0.0.6...0.1.1)

---
updated-dependencies:
- dependency-name: opusscript
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-08 21:54:19 +00:00
3889c69eb3 Merge pull request #3 from musix-org/dependabot/npm_and_yarn/v1/ms-2.1.3
Bump ms from 2.1.2 to 2.1.3
2024-02-08 23:53:17 +02:00
5a87b39d09 Bump ytdl-core from 0.29.7 to 4.11.5
Bumps [ytdl-core](https://github.com/fent/node-ytdl-core) from 0.29.7 to 4.11.5.
- [Release notes](https://github.com/fent/node-ytdl-core/releases)
- [Commits](https://github.com/fent/node-ytdl-core/compare/v0.29.7...v4.11.5)

---
updated-dependencies:
- dependency-name: ytdl-core
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-08 21:52:19 +00:00
57aa500ee7 Bump ms from 2.1.2 to 2.1.3
Bumps [ms](https://github.com/vercel/ms) from 2.1.2 to 2.1.3.
- [Release notes](https://github.com/vercel/ms/releases)
- [Commits](https://github.com/vercel/ms/compare/2.1.2...2.1.3)

---
updated-dependencies:
- dependency-name: ms
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-08 21:52:12 +00:00
f23f819a3c Merge branch 'master' into v1 2024-02-08 23:28:12 +02:00
a58152a896 Merge remote-tracking branch 'musix-v1/master' into v1 2024-02-08 17:14:41 +02:00
2042a72b39 Merge pull request #3 from Musix-Development/dependabot/npm_and_yarn/ws-6.2.2
Bump ws from 6.2.1 to 6.2.2
2021-07-01 02:35:18 +03:00
b2fd69a6bd Bump ws from 6.2.1 to 6.2.2
Bumps [ws](https://github.com/websockets/ws) from 6.2.1 to 6.2.2.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/commits)

---
updated-dependencies:
- dependency-name: ws
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-06 16:26:57 +00:00
66332da136 Merge pull request #2 from Musix-Development/dependabot/npm_and_yarn/node-fetch-2.6.1
Bump node-fetch from 2.6.0 to 2.6.1
2021-03-28 18:34:16 +03:00
0d1c00fd53 Bump node-fetch from 2.6.0 to 2.6.1
Bumps [node-fetch](https://github.com/bitinn/node-fetch) from 2.6.0 to 2.6.1.
- [Release notes](https://github.com/bitinn/node-fetch/releases)
- [Changelog](https://github.com/node-fetch/node-fetch/blob/master/docs/CHANGELOG.md)
- [Commits](https://github.com/bitinn/node-fetch/compare/v2.6.0...v2.6.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-27 12:41:31 +00:00
2b6db0e070 Update README.md 2020-07-19 13:34:37 +03:00
6b49a56f71 Update README.md 2020-07-19 13:31:33 +03:00
1c74df8e4e Fixes and updates after 9 months. 2020-04-29 11:59:31 +03:00
c5d5b049f3 Removed node_modules 2020-04-29 11:54:39 +03:00
47cd3e1539 Update index.js 2019-07-31 17:36:48 +03:00
4abc7ff3df Update index.js 2019-07-31 17:22:36 +03:00
e039afb074 Update index.js 2019-07-31 15:03:33 +03:00
fac41faf9e Update index.js 2019-07-31 10:04:41 +03:00
1d36a9d285 Update index.js 2019-07-31 09:57:34 +03:00
c0651f1ba1 Update index.js 2019-07-31 09:55:31 +03:00
53f9b2bb72 Update index.js 2019-07-30 17:36:15 +03:00
b31669bd9f Update index.js 2019-07-30 17:18:37 +03:00
aac527787e Update index.js 2019-07-30 17:14:23 +03:00
3c8e6ae403 Update index.js 2019-07-30 16:48:27 +03:00
4fb86fade4 Update index.js 2019-07-30 16:46:35 +03:00
ed5702c964 Update index.js 2019-07-30 16:44:41 +03:00
493df7e240 Update index.js 2019-07-30 16:34:58 +03:00
91098e2973 Update index.js 2019-07-30 16:31:28 +03:00
ee5a55de50 Update index.js 2019-07-30 16:29:36 +03:00
8af2a345d0 Update index.js 2019-07-30 16:25:51 +03:00
b30d497658 Update index.js 2019-07-30 16:20:00 +03:00
07534038d3 Update index.js 2019-07-30 16:18:23 +03:00
0e0d90c859 Update index.js 2019-07-30 16:16:04 +03:00
5bde5f2a02 Update index.js 2019-07-30 16:15:33 +03:00
668b6de332 Update index.js 2019-07-30 16:10:29 +03:00
d65d5aae9e Update index.js 2019-07-30 16:02:25 +03:00
f64f5dba92 Update index.js 2019-07-30 15:55:28 +03:00
d9e7d8d3ad Update index.js 2019-07-30 10:13:04 +03:00
47548f66d0 Update index.js 2019-07-30 08:12:37 +03:00
13b1a320ff Update index.js 2019-07-30 08:01:29 +03:00
0e39d7f210 Update index.js 2019-07-29 17:56:30 +03:00
2ee9414b90 Update index.js 2019-07-25 16:58:02 +03:00
c5ca2ec569 Update index.js 2019-07-25 16:47:22 +03:00
b4818b6ca4 Update index.js 2019-07-25 16:43:47 +03:00
b55e4f25ce Update index.js 2019-07-23 18:06:48 +03:00
cb10d308a0 Update index.js 2019-07-23 09:30:56 +03:00
f7d19118e9 Update index.js 2019-07-22 20:47:41 +03:00
1eded156f7 Update index.js 2019-07-19 12:20:22 +03:00
337bfe3a87 Update index.js 2019-07-19 11:09:38 +03:00
77b1c5fcd3 Update index.js 2019-07-19 10:42:38 +03:00
c0daa44536 Update index.js 2019-07-19 10:19:00 +03:00
8b821c5bb1 Update index.js 2019-07-18 20:33:04 +03:00
02e69b9398 Update index.js 2019-07-18 20:32:20 +03:00
e3b3178a5f Update index.js 2019-07-18 20:29:54 +03:00
41dc95cf1b Update index.js 2019-07-18 20:28:56 +03:00
c43698aa17 Update index.js 2019-07-18 20:23:19 +03:00
397ad03821 Update index.js 2019-07-18 20:19:28 +03:00
477707c341 Update index.js 2019-07-18 20:16:43 +03:00
de81037f05 Update index.js 2019-07-18 19:36:36 +03:00
9a6941aedf Update index.js 2019-07-12 09:52:00 +03:00
85b5a1b26c Update index.js 2019-07-12 09:47:28 +03:00
dd4e240925 Update index.js 2019-07-12 09:35:00 +03:00
730ce0dc1c Update index.js 2019-07-11 13:16:19 +03:00
1d224327bf Update index.js 2019-07-10 14:18:20 +03:00
4680497b0e Update index.js 2019-07-10 14:17:13 +03:00
adb964cef0 Update index.js 2019-07-10 14:05:38 +03:00
49d9b04d05 Update index.js 2019-07-10 14:03:02 +03:00
ac55c4ec9f Update index.js 2019-07-10 13:13:24 +03:00
ad3a5c751d Update index.js 2019-07-10 13:11:50 +03:00
6a1d049938 Update index.js 2019-07-10 13:01:42 +03:00
3dea69bfec Update index.js 2019-07-09 12:17:33 +03:00
c6a15eb1a0 Update index.js 2019-07-09 12:16:11 +03:00
ca99bb7f9c Update index.js 2019-06-20 07:26:09 -07:00
5400f0d14f Update index.js 2019-06-18 20:58:36 +03:00
02d6d42173 Update index.js 2019-06-18 18:24:11 +03:00
fdb012be2d Update index.js 2019-06-18 18:23:45 +03:00
4c013f2df7 Update index.js 2019-06-18 18:23:20 +03:00
1b36d9b7f5 Update index.js 2019-06-18 18:22:29 +03:00
33d3907512 Update index.js 2019-06-18 18:03:01 +03:00
2e2f7c2e9a Update index.js 2019-06-18 17:59:58 +03:00
04662353f2 Update index.js 2019-06-18 10:54:46 +03:00
6646f7c118 Update index.js 2019-06-18 10:53:04 +03:00
ed6710eacb Update index.js 2019-06-18 10:25:11 +03:00
41b8199958 Update index.js 2019-06-18 10:19:05 +03:00
43a2f99cb0 Update index.js 2019-06-18 10:15:56 +03:00
e37beacaf3 Update index.js 2019-06-16 21:00:04 +03:00
0f2a622a84 Update index.js 2019-06-16 17:57:55 +03:00
fd30344bd8 Update index.js 2019-06-16 17:08:35 +03:00
b966010a37 Update index.js 2019-06-16 17:04:37 +03:00
20938dd9b9 Update index.js 2019-06-16 16:28:54 +03:00
728ea82a7d Update index.js 2019-06-16 16:25:12 +03:00
99e5c6903d Update index.js 2019-06-16 16:05:38 +03:00
2a0d3aab24 Update index.js 2019-06-16 16:03:14 +03:00
b8dc88ed85 Update index.js 2019-06-13 10:43:06 +03:00
4a85a7e842 Update index.js 2019-06-13 10:41:53 +03:00
ee4829ca28 Update index.js 2019-06-13 10:38:45 +03:00
1b2a6fd7e3 Update index.js 2019-06-13 10:36:34 +03:00
36e1ea30bd Update index.js 2019-06-12 13:21:36 +03:00
a40248bc4a Ytdl-core update 2019-06-12 12:26:54 +03:00
2a308321ae Update index.js 2019-06-10 21:24:21 +03:00
38197d8ce9 Update index.js 2019-06-10 21:22:50 +03:00
1e645020cc Update index.js 2019-06-10 08:38:23 +03:00
2771302154 Update index.js 2019-06-10 08:37:21 +03:00
c065136b8a Update index.js 2019-06-10 08:32:29 +03:00
735dec1949 Update index.js 2019-06-10 08:29:29 +03:00
eb8774b289 Update index.js 2019-06-09 22:49:44 +03:00
b66a3b73d7 Update index.js 2019-06-09 22:42:05 +03:00
81eda3780d Update index.js 2019-06-09 22:37:54 +03:00
fc9d955a68 Update index.js 2019-06-09 22:33:55 +03:00
54a8d3174d Update index.js 2019-06-09 22:31:08 +03:00
1f0180cf13 Update index.js 2019-06-06 07:50:21 +03:00
6af5b45823 Update index.js 2019-06-06 07:46:44 +03:00
b0eac04971 Update index.js 2019-06-06 07:43:43 +03:00
bfb105808d Update index.js 2019-06-06 07:42:53 +03:00
a33fcd9c40 Update index.js 2019-06-06 07:38:59 +03:00
6b70f6599d Update index.js 2019-06-05 20:10:54 +03:00
ca15b1361e Update index.js 2019-06-05 20:07:54 +03:00
33e87d8774 Update index.js 2019-06-05 16:39:01 +03:00
eb039662f1 Update index.js 2019-06-05 16:32:20 +03:00
9e7d75927b Update index.js 2019-06-05 16:29:58 +03:00
7e6a6a03ef Update index.js 2019-06-03 16:21:23 +03:00
04314762cc Update index.js 2019-06-01 09:23:23 +03:00
b8416bac27 Update index.js 2019-05-31 21:43:07 +03:00
bd3008c072 Update index.js 2019-05-31 21:38:53 +03:00
43b71ddb69 Update index.js 2019-05-31 21:34:54 +03:00
936befb259 Update index.js 2019-05-31 21:32:55 +03:00
551007caee Update index.js 2019-05-31 21:32:05 +03:00
23f5cdfce3 Update index.js 2019-05-31 16:05:35 +03:00
eb40a640d2 Update index.js 2019-05-31 16:05:05 +03:00
f7274b1ce9 Update index.js 2019-05-31 16:01:59 +03:00
c703f244a1 Update index.js 2019-05-31 15:59:26 +03:00
9aa5dc7769 Update index.js 2019-05-31 15:57:17 +03:00
60db516870 Update index.js 2019-05-30 21:14:31 +03:00
e5df70d320 Update index.js 2019-05-30 21:05:16 +03:00
bc636ce416 Update index.js 2019-05-30 20:24:40 +03:00
e24b4f0899 Update index.js 2019-05-30 16:58:34 +03:00
aef0d98225 Update index.js 2019-05-30 16:55:40 +03:00
97ee60c9a2 Update index.js 2019-05-30 16:50:56 +03:00
46ca9b4f25 Update index.js 2019-05-30 16:46:31 +03:00
61de1c2041 Update index.js 2019-05-30 14:08:30 +03:00
7ebcec8eed Update index.js 2019-05-30 14:05:47 +03:00
3bf7adf902 Update index.js 2019-05-30 14:04:07 +03:00
13ba629479 Update index.js 2019-05-30 13:22:58 +03:00
2aaf8ba525 Update index.js 2019-05-30 13:21:56 +03:00
c525181752 fix 2019-05-30 12:10:19 +03:00
5eb0264906 fix 2019-05-30 12:06:47 +03:00
cbdffcf19c Start 2019-05-30 12:01:25 +03:00
49 changed files with 655 additions and 3376 deletions

3
.env_example Normal file
View File

@ -0,0 +1,3 @@
DISCORD_API_TOKEN=
BOT_PREFIX=
YOUTUBE_API_KEY=

View File

@ -1,23 +0,0 @@
name: Dependabot Auto-Merge
on:
pull_request_target:
branches:
- v1
- v2
- v3
permissions:
pull-requests: write
contents: write
jobs:
dependabot:
name: Dependabot Auto-Merge
runs-on: ubuntu-latest
if: ${{ github.actor == 'dependabot[bot]' }}
steps:
- name: Enable auto-merge for Dependabot PRs
run: gh pr merge --auto --merge "$PR_URL"
env:
PR_URL: ${{ github.event.pull_request.html_url }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

3
.gitignore vendored
View File

@ -1,4 +1 @@
.env
.vscode
node_modules
serviceAccount.json

View File

@ -1,58 +0,0 @@
const { Client, Collection } = require('discord.js');
const admin = require('firebase-admin');
require('dotenv/config');
module.exports = class extends Client {
constructor() {
super({
intents: [
"Guilds",
"GuildMessages",
"GuildVoiceStates",
"MessageContent"
],
disableMentions: "everyone",
disabledEvents: ["TYPING_START"]
});
this.commands = new Collection();
this.commandAliases = new Collection();
this.playlistCmd = new Collection();
this.settingCmd = new Collection();
this.events = new Collection();
this.queue = new Map();
this.funcs = {};
this.funcs.handleVideo = require('./funcs/handleVideo.js');
this.funcs.play = require('./funcs/play.js');
this.funcs.msToTime = require('./funcs/msToTime.js');
this.funcs.exe = require('./funcs/exe.js');
this.config = require('./config.js');
this.global = {
db: {
guilds: {},
playlists: {},
},
};
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;
}
}
};

1
Procfile Normal file
View File

@ -0,0 +1 @@
worker: node index.js

View File

@ -1,21 +1 @@
# Musix-V2
THIS VERSION OF MUSIX IS NO LONGER SUPPORTED!
## Discord music bot
Second version of Musix discord music bot.
Made with discord.js V11
NOTE! THIS BOT CANNOT BE USED AFTER OCTOBER 4TH 2020! This is due to new rules for bots by discord.
## Installation
npm install (idk how yarn works)
Some modules are outdated to updating is recommended!
## Usage
You will need you own .env file and serviceAccount.json for database!
# Musix OSS - V1

View File

@ -1,32 +0,0 @@
const { EmbedBuilder } = require("discord.js");
module.exports = {
name: 'help',
description: 'Help command.',
alias: 'help',
cooldown: 5,
execute(message, args, client, prefix) {
const embed = new EmbedBuilder()
.setTitle(`Commands for ${client.user.username}!`)
.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({ embeds: [embed] });
}
};

View File

@ -1,15 +0,0 @@
const { EmbedBuilder } = require("discord.js");
module.exports = {
name: 'invite',
description: 'Invite command.',
alias: 'invite',
cooldown: 5,
execute(message, args, client, prefix) {
const embed = new EmbedBuilder()
.setTitle(`Invite ${client.user.username} to your Discord server!`)
.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({ embeds: [embed] });
}
};

View File

@ -1,27 +0,0 @@
const { PermissionFlagsBits } = require('discord.js');
module.exports = {
name: 'loop',
description: 'loop command.',
alias: 'loop',
cooldown: 10,
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.voice.channel;
if (!serverQueue) return message.channel.send(':x: There is nothing playing.');
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,27 +0,0 @@
const { EmbedBuilder } = require('discord.js');
module.exports = {
name: 'nowplaying',
description: 'Now playing command.',
alias: 'np',
cooldown: 5,
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.');
if (!serverQueue.playing) return message.channel.send(':x: There is nothing playing.');
let data = await Promise.resolve(ytdl.getInfo(serverQueue.songs[0].url));
let songtime = (data.length_seconds * 1000).toFixed(0);
let completed = (serverQueue.connection.dispatcher.time).toFixed(0);
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 EmbedBuilder()
.setTitle("__Now playing__")
.setDescription(`🎶**Now playing:** ${serverQueue.songs[0].title}\n${array.join('')} | \`${client.funcs.msToTime(completed)} / ${client.funcs.msToTime(songtime)}\``)
.setFooter({ text: `Queued by ${serverQueue.songs[0].author.tag}` })
.setURL(serverQueue.songs[0].url)
.setColor(client.config.embedColor)
return message.channel.send({ embeds: [embed] });
}
};

View File

@ -1,25 +0,0 @@
const { PermissionFlagsBits } = require('discord.js');
module.exports = {
name: 'pause',
description: 'Pause command.',
alias: 'pause',
cooldown: 5,
execute(message, args, client, prefix) {
const serverQueue = client.queue.get(message.guild.id);
const permissions = message.channel.permissionsFor(message.author);
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 (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.audioPlayer.pause();
return message.channel.send('⏸ Paused the music!');
} else return message.channel.send(':x: There is nothing playing.');
}
};

View File

@ -1,86 +0,0 @@
const YouTube = require("simple-youtube-api");
const he = require('he');
const { EmbedBuilder, PermissionFlagsBits } = require("discord.js");
module.exports = {
name: 'play',
description: 'Play command.',
usage: '[song name]',
alias: 'p',
args: true,
cooldown: 3,
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.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 {
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 play music!');
}
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(PermissionFlagsBits.Connect)) {
return message.channel.send(':x: I cannot connect to your voice channel, make sure I have the proper permissions!');
}
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(.*)$/)) {
const playlist = await youtube.getPlaylist(url);
const videos = await playlist.getVideos();
for (const video of Object.values(videos)) {
const video2 = await youtube.getVideoByID(video.id);
await client.funcs.handleVideo(video2, message, voiceChannel, client, true);
}
return message.channel.send(`:white_check_mark: Playlist: **${playlist.title}** has been added to the queue!`);
} else if (client.global.db.guilds[message.guild.id].songSelection) {
try {
var video = await youtube.getVideo(url);
} catch (error) {
try {
var videos = await youtube.searchVideos(searchString, 10);
let index = 0;
const embed = new EmbedBuilder()
.setTitle("__Song Selection__")
.setDescription(`${videos.map(video2 => `**${++index}** ${he.decode(video2.title)} `).join('\n')}`)
.setFooter({ text: "Please provide a number ranging from 1-10 to select one of the search results." })
.setColor(client.config.embedColor)
message.channel.send({ embeds: [embed] });
try {
var response = await message.channel.awaitMessages({
filter: message2 => message2.content > 0 && message2.content < 11 && message2.author === message.author,
max: 1,
time: 10000,
errors: ['time']
});
} catch (err) {
console.error(err);
return message.channel.send(':x: Cancelling video selection');
}
const videoIndex = parseInt(response.first().content);
var video = await youtube.getVideoByID(videos[videoIndex - 1].id);
} catch (err) {
console.error(err);
return message.channel.send(':x: I could not obtain any search results!');
}
}
return client.funcs.handleVideo(video, message, voiceChannel, client, false);
} else {
try {
var video = await youtube.getVideo(url);
} catch (error) {
try {
var videos = await youtube.searchVideos(searchString, 1);
var video = await youtube.getVideoByID(videos[0].id);
} catch (err) {
console.error(err);
return message.channel.send(':x: I could not obtain any search results!');
}
}
return client.funcs.handleVideo(video, message, voiceChannel, client, false);
}
}
};

View File

@ -1,44 +0,0 @@
const YouTube = require("simple-youtube-api");
const he = require('he');
const { EmbedBuilder, PermissionFlagsBits } = require("discord.js");
module.exports = {
name: 'playlist',
usage: '[option]',
description: 'Save and load queues',
alias: 'pl',
cooldown: 10,
async execute(message, args, client, prefix) {
const embed = new EmbedBuilder()
.setTitle('Options for playlist!')
.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 (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({ embeds: [embed] });
try {
option.execute(message, args, client, prefix);
} catch (error) {
message.reply(`:x: there was an error trying to execute that option!`);
console.log(error);
}
} else {
return message.channel.send({ embeds: [embed] });
}
} else return message.channel.send(":x: This is not a premium guild!");
},
};

View File

@ -1,53 +0,0 @@
const YouTube = require("simple-youtube-api");
const he = require('he');
const { EmbedBuilder } = require("discord.js");
module.exports = {
name: 'add',
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.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!');
try {
var video = await youtube.getVideo(url);
} catch (error) {
try {
var videos = await youtube.searchVideos(searchString, 10);
let index = 0;
const embed = new EmbedBuilder()
.setTitle("__Song Selection__")
.setDescription(`${videos.map(video2 => `**${++index}** ${he.decode(video2.title)} `).join('\n')}`)
.setFooter({ text: "Please provide a number ranging from 1-10 to select one of the search results." })
.setColor("#b50002")
message.channel.send({ embeds: [embed] });
try {
var response = await message.channel.awaitMessages({
filter: message2 => message2.content > 0 && message2.content < 11,
max: 1,
time: 10000,
errors: ['time']
});
} catch (err) {
console.error(err);
return message.channel.send(':x: Cancelling video selection');
}
const videoIndex = parseInt(response.first().content);
var video = await youtube.getVideoByID(videos[videoIndex - 1].id);
} catch (err) {
console.error(err);
return message.channel.send(':x: I could not obtain any search results!');
}
}
let song = {
id: video.id,
title: he.decode(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,11 +0,0 @@
module.exports = {
name: 'delete',
async execute(message, args, client, prefix) {
client.global.db.playlists[message.guild.id] = {
songs: [],
firstSong: undefined,
saved: false,
};
message.channel.send(':wastebasket: Deleted the playlist.');
}
};

View File

@ -1,24 +0,0 @@
const { EmbedBuilder } = require("discord.js");
module.exports = {
name: 'list',
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__.');
}
let page = parseInt(args[2]);
if (!page) page = 1;
let pagetext = `:page_facing_up: Page: ${page} :page_facing_up:`
let queuesongs = client.global.db.playlists[message.guild.id].songs.slice((page - 1) * 20, page * 20);
let queuemessage = `${queuesongs.map(song => `**#** ${song.title}`).join('\n')}`
const hashs = queuemessage.split('**#**').length;
for (let i = 0; i < hashs; i++) {
queuemessage = queuemessage.replace('**#**', `**${i + 1}**`);
}
const embed = new EmbedBuilder()
.setTitle("__playlist queue__")
.setDescription(`${pagetext}\n${queuemessage}`)
.setColor("#b50002")
return message.channel.send({ embeds: [embed] });
}
};

View File

@ -1,69 +0,0 @@
const { PermissionFlagsBits } = require("discord.js");
const { createAudioPlayer, getVoiceConnection, joinVoiceChannel, NoSubscriberBehavior } = require("@discordjs/voice");
module.exports = {
name: 'play',
async execute(message, args, client, prefix) {
const serverQueue = client.queue.get(message.guild.id);
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(PermissionFlagsBits.Connect)) {
return message.channel.send(':x: I cannot connect to your voice channel, make sure I have the proper permissions!');
}
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;
if (!voiceChannel) return message.channel.send(':x: I\'m sorry but you need to be in a voice channel to play music!');
if (args[2]) {
if (client.global.db.guilds[args[2]].premium && client.global.db.playlists[args[2]].saved) {
songs = client.global.db.playlists[args[2]].songs;
} else return message.channel.send(':x: There is no queue saved for this guild!')
} else {
songs = client.global.db.playlists[message.guild.id].songs;
}
if (client.global.db.playlists[message.guild.id].saved) {
if (!serverQueue) {
const construct = {
textChannel: message.channel,
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,
looping: false,
paused: false,
votes: 0,
voters: [],
votesNeeded: null
};
client.queue.set(message.guild.id, construct);
message.channel.send(":white_check_mark: Queue set!");
try {
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) {
client.queue.delete(message.guild.id);
return message.channel.send(`:x: An error occured: ${error}`);
}
} else {
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,13 +0,0 @@
module.exports = {
name: 'remove',
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;
if (isNaN(songNum)) return message.channel.send(':x: You need to enter a __number__!');
if (parseInt(songNum) > client.global.db.playlists[message.guild.id].songs.size) return message.channel.send(`:x: There is only ${serverQueue.songs.size} amount of songs in the queue!`);
message.channel.send(`🗑️ removed \`${client.global.db.playlists[message.guild.id].songs[songNum].title}\` from the playlist!`);
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,13 +0,0 @@
module.exports = {
name: 'save',
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] = {
songs: serverQueue.songs,
firstSong: serverQueue.songs[0],
saved: true,
};
message.channel.send(":white_check_mark: Queue saved!");
}
};

View File

@ -1,39 +0,0 @@
const { EmbedBuilder } = require("discord.js");
module.exports = {
name: 'queue',
description: 'Queue command.',
alias: 'q',
cooldown: 5,
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]) {
if (isNaN(args[1])) return msg.channel.send(':x: I\'m sorry, But you need to enter a valid __number__.');
}
let page = parseInt(args[1]);
if (!page) page = 1;
let pagetext = `:page_facing_up: Page: ${page} :page_facing_up:`
if (page === 1) pagetext = ':arrow_down: Next in queue :arrow_down:'
let queuesongs = serverQueue.songs.slice((page - 1) * 20 + 1, page * 20 + 1);
let queuemessage = `${queuesongs.map(song => `**#** ${song.title}`).join('\n')}`
const hashs = queuemessage.split('**#**').length;
for (let i = 0; i < hashs; i++) {
queuemessage = queuemessage.replace('**#**', `**${i + 1}**`);
}
if (!serverQueue.looping) {
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({ embeds: [embed] });
} else {
const embed = new EmbedBuilder()
.setTitle("__Song queue__")
.setDescription(`**Now playing:** ${serverQueue.songs[0].title}🎶\n${pagetext}\n${queuemessage}`)
.setFooter({ text: '🔁 Currently looping the queue!' })
.setColor(client.config.embedColor)
return message.channel.send({ embeds: [embed] });
}
}
};

View File

@ -1,28 +0,0 @@
const { PermissionFlagsBits } = require("discord.js");
module.exports = {
name: 'remove',
description: 'Remove command.',
alias: 'rm',
cooldown: 5,
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.');
if (!serverQueue.playing) return message.channel.send(':x: There is nothing playing');
if (!args[1]) return message.channel.send(':x: Please provide a song position in queue for me to remove!');
const pos = parseInt(args[1]);
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 (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,26 +0,0 @@
const { PermissionFlagsBits } = require("discord.js");
module.exports = {
name: 'resume',
description: 'Resume command.',
alias: 'resume',
cooldown: 5,
execute(message, args, client, prefix) {
const serverQueue = client.queue.get(message.guild.id);
const permissions = message.channel.permissionsFor(message.author);
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 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.audioPlayer.unpause();
return message.channel.send('▶ Resumed the music!');
}
return message.channel.send(':x: The music is not paused!');
}
};

View File

@ -1,32 +0,0 @@
const { PermissionFlagsBits } = require("discord.js");
module.exports = {
name: 'seek',
description: 'Seek music.',
alias: 'seek',
cooldown: 10,
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.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 (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.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,39 +0,0 @@
const { EmbedBuilder, PermissionFlagsBits } = require("discord.js");
module.exports = {
name: 'settings',
usage: '[setting]',
description: 'Change the settings',
alias: 'settings',
cooldown: 10,
async execute(message, args, client, prefix) {
const embed = new EmbedBuilder()
.setTitle('Guild settings for Musix')
.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 <name> <value>` })
.setAuthor({ name: client.user.username, iconURL: client.user.avatarURL() })
.setColor(client.config.embedColor)
const permissions = message.channel.permissionsFor(message.author);
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({ embeds: [embed] });
try {
option.execute(message, args, client, prefix);
} catch (error) {
message.reply(`:x: there was an error trying to execute that option!`);
console.log(error);
}
} else {
return message.channel.send({ embeds: [embed] });
}
},
};

View File

@ -1,12 +0,0 @@
module.exports = {
name: 'announcesongs',
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`!');
} else {
client.global.db.guilds[message.guild.id].startPlaying = true;
return message.channel.send(':white_check_mark: announcesongs now set to `true`!');
}
}
};

View File

@ -1,17 +0,0 @@
module.exports = {
name: 'permissions',
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) {
client.global.db.guilds[message.guild.id].permissions = true;
message.channel.send(`:white_check_mark: Permissions requirement now set to: \`true\``);
} else return message.channel.send(':x: That value is already `true`!');
} else if (args[2] === 'false') {
if (client.global.db.guilds[message.guild.id].permissions) {
client.global.db.guilds[message.guild.id].permissions = false;
message.channel.send(`:white_check_mark: Permissions requirement now set to: \`false\``);
} 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 +0,0 @@
module.exports = {
name: '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,14 +0,0 @@
module.exports = {
name: 'reset',
async execute(message, args, client, prefix) {
client.global.db.guilds[message.guild.id] = {
prefix: client.config.prefix,
defaultVolume: 5,
permissions: false,
premium: false,
dj: false,
djrole: null
};
message.channel.send(':white_check_mark: Reset __all__ guild settings!');
}
};

View File

@ -1,28 +0,0 @@
const { PermissionFlagsBits } = require("discord.js");
module.exports = {
name: 'setdj',
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.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(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;
message.channel.send(':white_check_mark: I did not find a role `DJ` so i have created one for you!');
}
} else {
client.global.db.guilds[message.guild.id].dj = false;
message.channel.send(':white_check_mark: `DJ` now set to `false`');
}
}
};

View File

@ -1,34 +0,0 @@
module.exports = {
name: 'setpremium',
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) {
client.global.db.playlists[guild.id] = {
songs: [],
firstSong: undefined,
saved: false,
};
client.global.db.guilds[guild.id].premium = true;
message.channel.send(`:white_check_mark: Guild ${guild.name} | ${guild.id} is now premium! :tada:`)
} else {
client.global.db.guilds[guild.id].premium = false;
message.channel.send(`:white_check_mark: Guild ${guild.name} | ${guild.id} is no longer premium!`)
}
} else {
if (!client.global.db.guilds[message.guild.id].premium) {
client.global.db.playlists[message.guild.id] = {
songs: [],
firstSong: undefined,
saved: false,
};
client.global.db.guilds[message.guild.id].premium = true;
message.channel.send(':white_check_mark: This guild is now premium! :tada:')
} else {
client.global.db.guilds[message.guild.id].premium = false;
message.channel.send(":white_check_mark: This guild is no longer premium!")
}
}
}
};

View File

@ -1,12 +0,0 @@
module.exports = {
name: 'songselection',
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;
} else {
client.global.db.guilds[message.guild.id].songSelection = false;
message.channel.send(':white_check_mark: Songselection now set to `false`');
}
}
};

View File

@ -1,10 +0,0 @@
module.exports = {
name: 'volume',
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

@ -1,21 +0,0 @@
module.exports = {
name: 'Shuffle',
description: 'Shuffle command.',
alias: 'shuffle',
cooldown: 5,
execute(message, args, client, prefix) {
const serverQueue = client.queue.get(message.guild.id);
let currentIndex = serverQueue.songs.length,
temporaryValue,
randomIndex;
while (0 !== currentIndex) {
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
temporaryValue = serverQueue.songs[currentIndex];
serverQueue.songs[currentIndex] = serverQueue.songs[randomIndex];
serverQueue.songs[randomIndex] = temporaryValue;
}
}
};

View File

@ -1,46 +0,0 @@
const { PermissionFlagsBits } = require("discord.js");
module.exports = {
name: 'skip',
description: 'Skip command.',
alias: 's',
cooldown: 5,
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 (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 vote(serverQueue, message, client);
}
}
};
function skipSong(serverQueue, message) {
message.channel.send(':fast_forward: Skipped the song!');
serverQueue.audioPlayer.stop();
};
function vote(serverQueue, message) {
serverQueue.votesNeeded = Math.floor(serverQueue.voiceChannel.members.size / 2);
serverQueue.votesNeeded.toFixed();
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);
if (serverQueue.votes >= serverQueue.votesNeeded) {
serverQueue.voters = [];
serverQueue.votes = 0;
serverQueue.votesNeeded = null;
return skipSong(serverQueue, message);
} else return message.channel.send(`:x: Not enough votes! ${serverQueue.votes} / ${serverQueue.votesNeeded}!`);
} else {
return skipSong(serverQueue, message);
}
};

View File

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

View File

@ -1,25 +0,0 @@
const { PermissionFlagsBits } = require("discord.js");
module.exports = {
name: 'stop',
description: 'Stop command.',
alias: 'stop',
cooldown: 5,
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 (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.audioPlayer.stop();
message.channel.send(':stop_button: Stopped the music!')
}
};

View File

@ -1,29 +0,0 @@
const { PermissionFlagsBits } = require("discord.js");
module.exports = {
name: 'volume',
description: 'Volume command.',
alias: 'volume',
cooldown: 5,
execute(message, args, client, Discord, 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.');
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 (!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.audioResource.volume.setVolume(volume / 100);
return message.channel.send(`:loud_sound: I set the volume to: **${volume}**`);
}
};

View File

@ -1,10 +0,0 @@
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,25 +0,0 @@
module.exports = {
name: 'guildcreate',
async execute(client, guild) {
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,24 +0,0 @@
module.exports = {
name: 'message',
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(' ');
if (message.mentions.users.first()) {
if (message.mentions.users.first().id === client.user.id) {
if (!args[1]) return;
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, prefix, command);
}
}
}
if (!message.content.startsWith(prefix)) return;
if (!args[0]) return;
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;
client.funcs.exe(message, args, client, prefix, command);
}
}

View File

@ -1,53 +0,0 @@
module.exports = {
name: 'ready',
async execute(client) {
client.user.setActivity(`@${client.user.username} help | 🎶`, { type: 'LISTENING' });
client.user.setStatus('online');
console.log('- Activated -');
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;
});
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);
}
}
}

View File

@ -1,22 +0,0 @@
module.exports = async function (collection, doc, client) {
if (doc) {
let d = await client.db.collection(collection).doc(doc).get().catch(err => {
console.log('Error getting document', err);
return 'error';
});
return d.data();
} else {
let d = await client.db.collection(collection).get().catch(err => {
console.log('Error getting document', err);
return 'error';
});
let finalD = [];
d.forEach(doc => {
finalD.push({
id: doc.id,
d: doc.data(),
});
});
return finalD;
}
};

View File

@ -1,13 +0,0 @@
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,53 +0,0 @@
const { createAudioPlayer, getVoiceConnection, joinVoiceChannel, NoSubscriberBehavior } = require("@discordjs/voice");
module.exports = async function (video, message, voiceChannel, client, playlist = false) {
let song = {
id: video.id,
title: he.decode(video.title),
url: `https://www.youtube.com/watch?v=${video.id}`,
author: message.author
}
const serverQueue = client.queue.get(message.guild.id);
if (!serverQueue) {
const construct = {
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,
paused: false,
looping: false,
votes: 0,
voters: [],
votesNeeded: null
};
construct.songs.push(song);
client.queue.set(message.guild.id, construct);
try {
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);
console.log("Error with connecting to voice channel: " + error);
return message.channel.send(`:x: An error occured: ${error}`);
}
} else {
serverQueue.songs.push(song);
if (playlist) return undefined;
return message.channel.send(`:white_check_mark: **${song.title}** has been added to the queue!`);
}
return undefined;
}

View File

@ -1,11 +0,0 @@
module.exports = function msToTime(duration) {
var seconds = Math.floor((duration / 1000) % 60),
minutes = Math.floor((duration / (1000 * 60)) % 60),
hours = Math.floor((duration / (1000 * 60 * 60)) % 24);
hours = (hours < 10) ? "0" + hours : hours;
minutes = (minutes < 10) ? "0" + minutes : minutes;
seconds = (seconds < 10) ? "0" + seconds : seconds;
return `${hours}:${minutes}:${seconds}`;
}

View File

@ -1,48 +0,0 @@
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;
}

430
index.js
View File

@ -1,50 +1,400 @@
const { AudioPlayerStatus, createAudioPlayer, createAudioResource, getVoiceConnection, joinVoiceChannel, NoSubscriberBehavior } = require('@discordjs/voice');
const { Client, ActivityType, PermissionFlagsBits } = require('discord.js');
const Discord = require('discord.js');
const MusicClient = require('./Client');
const client = new MusicClient({});
const fs = require('fs');
const YouTube = require('simple-youtube-api')
const ytdl = require('ytdl-core');
const PREFIX = (process.env.BOT_PREFIX ?? "mx>");
const client = new Client({
intents: [
"Guilds",
"GuildMessages",
"GuildVoiceStates",
"MessageContent"
],
disableMentions: 'everyone'
});
const youtube = new YouTube(process.env.YOUTUBE_API_KEY);
const queue = new Map();
client.login(process.env.DISCORD_API_TOKEN);
client.on('ready', () => {
client.user.setActivity(`${PREFIX}help`, { type: ActivityType.Listening })
client.user.setStatus('online');
});
client.on('messageCreate', async msg => {
if (!msg.guild || msg.author.bot) return;
if (msg.content.startsWith(`${PREFIX}`)) {
if (msg.content === `${PREFIX}ping`) {
msg.channel.send(`My current Ping: **${Math.floor(client.ws.ping * 10) / 10} ms**.`);
return;
}
if (msg.content === `${PREFIX}help`) {
const embed = new Discord.EmbedBuilder()
.setTitle('Commands for ' + client.user.username + '!')
.addFields(
{ name: '```' + `${PREFIX}` + 'play | ' + `${PREFIX}` + 'p```', value: 'Play a song.', inline: true },
{ name: '```' + `${PREFIX}` + 'queue | ' + `${PREFIX}` + 'q```', value: 'Display the queue.', inline: true },
{ name: '```' + `${PREFIX}` + 'nowplaying | ' + `${PREFIX}` + 'np```', value: 'Display whats currently playing.', 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}` + 'stop```', value: 'Stop the music, Clear the queue and leave the current voice channel.', inline: true },
{ name: '```' + `${PREFIX}` + 'skip | ' + `${PREFIX}` + 's```', value: 'Skip a song.', inline: true },
{ name: '```' + `${PREFIX}` + 'invite```', value: 'Invite ' + client.user.username + '.', inline: true },
{ name: '```' + `${PREFIX}` + 'ping```', value: 'See the current ping for ' + client.user.username, inline: true },
{ name: '```' + `${PREFIX}` + 'info```', value: 'Display info and instructions.', inline: true },
{ name: '```' + `${PREFIX}` + 'help```', value: 'Display the help.', inline: true }
)
.setAuthor({ name: client.user.username, iconURL: client.user.avatarURL() })
.setColor('#b50002');
msg.channel.send({ embeds: [embed] });
return undefined;
}
if (msg.content === `${PREFIX}info`) {
var line = '**>-----------------------------------------------------------------------<**';
var dj = msg.guild.roles.cache.find(x => x.name === 'DJ') ? true : false;
const embed = new Discord.EmbedBuilder()
.setTitle('**' + client.user.username + ' instructions and info**:')
.addFields(
{ name: 'If your current guild has a role called \'DJ\' you will need it to use music commands! If your current guild doesn\'t have a role called \'DJ\' everyone can use music commands!', value:'DJ role existance: ' + dj, inline: true },
{ name: 'If you encounter any errors with ' + client.user.username + ' please report about them on the offical ' + client.user.username + ' support server!', value: 'https://discord.gg/rvHuJtB', inline: true },
{ name: `On errors you can do ${PREFIX}stop to reset the queue and try again!`, value: line, inline: true },
{ name: 'Current Ping in milliseconds', value: `${Math.floor(client.ws.ping * 10) / 10} ms`, inline: true },
{ name: 'Be careful with the Volume command! Volume is not recommended to be put over 3 with user volume at 100%!', value: 'Volume will reset to 1 always when a new song begins!', inline: true }
)
.setAuthor({ name: client.user.username, iconURL: client.user.avatarURL() })
.setColor('#b50002');
msg.channel.send({ embeds: [embed] });
return undefined;
}
if (msg.content === `${PREFIX}invite`) {
msg.channel.send('Invite me with:' + '\n' + 'https://discord.com/oauth2/authorize?client_id=' + client.user.id + '&permissions=2184465408&scope=applications.commands+bot');
return undefined;
}
if (msg.member.guild.roles.cache.find(x => x.name === 'DJ')) {
if (msg.member.roles.cache.find(x => x.name === 'DJ')) {
const args = msg.content.split(' ');
const searchString = args.slice(1).join(' ');
const url = args[1] ? args[1].replace(/<(.+)>/g, '$1') : '';
const serverQueue = queue.get(msg.guild.id);
const commandFiles = fs.readdirSync('./commands/').filter(f => f.endsWith('.js'));
for (const file of commandFiles) {
const command = require(`./commands/${file}`);
command.uses = 0;
client.commands.set(command.name, command);
client.commandAliases.set(command.alias, command);
}
let command = msg.content.toLowerCase().split(' ')[0];
command = command.slice(PREFIX.length);
const eventFiles = fs.readdirSync('./events/').filter(f => f.endsWith('.js'));
for (const file of eventFiles) {
const event = require(`./events/${file}`);
client.events.set(event.name, event);
}
if (command === 'play' || command === 'p') {
if (!args[1]) return msg.channel.send(':x: I\'m sorry but you didn\'t specify a song');
const voiceChannel = msg.member.voice.channel;
if (!voiceChannel) return msg.channel.send(':x: I\'m sorry but you need to be in a voice channel to play music!');
const permissions = voiceChannel.permissionsFor(msg.client.user);
if (!permissions.has(PermissionFlagsBits.Connect)) {
return msg.channel.send(':x: I cannot connect to your voice channel, make sure I have the proper permissions!');
}
if (!permissions.has(PermissionFlagsBits.Speak)) {
return msg.channel.send(':x: I cannot speak in this voice channel, make sure I have the proper permissions!');
}
if (url.match(/^https?:\/\/(www.youtube.com|youtube.com)\/playlist(.*)$/)) {
const playlist = await youtube.getPlaylist(url);
const videos = await playlist.getVideos();
for (const video of Object.values(videos)) {
const video2 = await youtube.getVideoByID(video.id);
await handleVideo(video2, msg, voiceChannel, true);
}
return msg.channel.send(`:white_check_mark: Playlist: **${playlist.title}** has been added to the queue!`);
} else {
try {
var video = await youtube.getVideo(url);
} catch (error) {
try {
var videos = await youtube.searchVideos(searchString, 10);
let index = 0;
msg.channel.send(`
__**Song selection:**__
${videos.map(video2 => `**${++index} -** ${video2.title}`).join('\n')}
Please provide a value to select one of the search results ranging from 1-10.
`);
const playlistFiles = fs.readdirSync('./commands/playlist/').filter(f => f.endsWith('.js'));
for (const file of playlistFiles) {
const option = require(`./commands/playlist/${file}`);
client.playlistCmd.set(option.name, option);
}
try {
var response = await msg.channel.awaitMessages({
filter: msg2 => msg2.content > 0 && msg2.content < 11,
max: 1,
time: 10000,
errors: ['time']
});
} catch (err) {
return msg.channel.send(':x: Cancelling song selection.');
}
const videoIndex = parseInt(response.first().content);
const settingFiles = fs.readdirSync('./commands/settings/').filter(f => f.endsWith('.js'));
for (const file of settingFiles) {
const option = require(`./commands/settings/${file}`);
client.settingCmd.set(option.name, option);
}
var video = await youtube.getVideoByID(videos[videoIndex - 1].id);
} catch (err) {
return msg.channel.send(':x: I could not obtain any search results.');
}
}
return handleVideo(video, msg, voiceChannel);
}
} else if (command === 'skip' || command === 's') {
if (!msg.member.voice.channel) return msg.channel.send(':x: You are not in a voice channel!');
if (!serverQueue) return msg.channel.send(':x: There is nothing playing that I could skip for you.');
if (!serverQueue.songs[1]) return msg.channel.send(':x: Theres nothing to skip to!')
serverQueue.audioPlayer.stop();
return;
} else if (command === 'stop') {
if (!msg.member.voice.channel) return msg.channel.send(':x: You are not in a voice channel!');
if (!serverQueue) return msg.channel.send(':x: There is nothing playing that I could stop for you.');
serverQueue.songs = [];
serverQueue.audioPlayer.stop();
return;
} else if (command === 'volume') {
if (!msg.member.voice.channel) return msg.channel.send(':x: You are not in a voice channel!');
if (!serverQueue) return msg.channel.send(':x: There is nothing playing.');
if (!args[1]) return msg.channel.send(`The current volume is: **${serverQueue.volume}** :speaker:`);
if (isNaN(args[1])) {
return msg.channel.send(':x: I\'m sorry, But you need to enter a valid __number__.')
}
serverQueue.volume = args[1];
serverQueue.audioResource.volume.setVolume(args[1] / 100);
return msg.channel.send(`I set the volume to: **${args[1]}** 🔊`);
} else if (command === 'np' || command === 'nowplaying') {
if (!serverQueue) return msg.channel.send(':x: There is nothing playing.');
return msg.channel.send(`:musical_note: Now playing: **${serverQueue.songs[0].title}**`);
} else if (command === "queue" || command === 'q') {
if (!serverQueue)
return msg.channel.send(":x: There is nothing in the queue.");
var queuemessage = `__**Song queue:**__
${serverQueue.songs.map(song => `**-** ${song.title}`).join("\n")}
**Now playing:** ${serverQueue.songs[0].title} :musical_note: `;
if (queuemessage.length > 2000) {
return msg.channel.send(":x: The queue has too many songs in it to show all in this channel. Try again after a few songs.");
}
return msg.channel.send(queuemessage);
} else if (command === 'pause') {
if (serverQueue && serverQueue.playing) {
serverQueue.playing = false;
serverQueue.audioPlayer.pause();
return msg.channel.send(':pause_button: Paused the music for you!');
}
return msg.channel.send(':x: There is nothing playing.');
} else if (command === 'resume') {
if (serverQueue && !serverQueue.playing) {
serverQueue.playing = true;
serverQueue.audioPlayer.unpause();
return msg.channel.send(':play_pause: Resumed the music for you!');
}
return msg.channel.send(':x: There is nothing playing.');
}
if (msg.content === `${PREFIX}`) return;
msg.channel.send(`:x: Unknown command! Type ${PREFIX}help for the list of commands!`)
return;
}
if (msg.content === `${PREFIX}`) return;
var coms = [`${PREFIX}play`, `${PREFIX}queue`, `${PREFIX}np`, `${PREFIX}volume`, `${PREFIX}pause`, `${PREFIX}resume`, `${PREFIX}stop`, `${PREFIX}skip`, `${PREFIX}ping`, `${PREFIX}q`, `${PREFIX}nowplaying`, `${PREFIX}p`, `${PREFIX}s`];
for (var i = 0; i < coms.length; i++) {
if (msg.content.includes(coms[i])) {
if (!msg.member.roles.cache.find(x => x.name === 'DJ')) {
msg.channel.send(':x: i\'m sorry but you need to have the \'DJ\' role to use music commands!')
return;
}
}
}
msg.channel.send(`:x: Unknown command! Type ${PREFIX}help for the list of commands!`)
return;
} else {
const args = msg.content.split(' ');
const searchString = args.slice(1).join(' ');
const url = args[1] ? args[1].replace(/<(.+)>/g, '$1') : '';
const serverQueue = queue.get(msg.guild.id);
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);
let command = msg.content.toLowerCase().split(' ')[0];
command = command.slice(PREFIX.length)
if (command === 'play' || command === 'p') {
if (!args[1]) return msg.channel.send(':x: I think you forgot what you wanted to play!');
const voiceChannel = msg.member.voice.channel;
if (!voiceChannel) return msg.channel.send(':x: I\'m sorry but you need to be in a voice channel to play music!');
const permissions = voiceChannel.permissionsFor(msg.client.user);
if (!permissions.has(PermissionFlagsBits.Connect)) {
return msg.channel.send(':x: I cannot connect to your voice channel, make sure I have the proper permissions!');
}
if (!permissions.has(PermissionFlagsBits.Speak)) {
return msg.channel.send(':x: I cannot speak in this voice channel, make sure I have the proper permissions!');
}
if (url.match(/^https?:\/\/(www.youtube.com|youtube.com)\/playlist(.*)$/)) {
const playlist = await youtube.getPlaylist(url);
const videos = await playlist.getVideos();
for (const video of Object.values(videos)) {
const video2 = await youtube.getVideoByID(video.id); // eslint-disable-line no-await-in-loop
await handleVideo(video2, msg, voiceChannel, true); // eslint-disable-line no-await-in-loop
}
return msg.channel.send(`:white_check_mark: Playlist: **${playlist.title}** has been added to the queue!`);
} else {
try {
var video = await youtube.getVideo(url);
} catch (error) {
try {
var videos = await youtube.searchVideos(searchString, 10);
let index = 0;
msg.channel.send(`
__**Song selection:**__
${videos.map(video2 => `**${++index} -** ${video2.title}`).join('\n')}
Please provide a value to select one of the search results ranging from 1-10.
`);
// eslint-disable-next-line max-depth
try {
var response = await msg.channel.awaitMessages(msg2 => msg2.content > 0 && msg2.content < 11, {
maxMatches: 1,
time: 10000,
errors: ['time']
});
} catch (err) {
return msg.channel.send(':x: No or invalid value entered, cancelling video selection.');
}
const videoIndex = parseInt(response.first().content);
var video = await youtube.getVideoByID(videos[videoIndex - 1].id);
} catch (err) {
console.error(err);
return msg.channel.send(':x: I could not obtain any search results.');
}
}
return handleVideo(video, msg, voiceChannel);
}
} else if (command === 'skip' || command === 's') {
if (!msg.member.voice.channel) return msg.channel.send(':x: You are not in a voice channel!');
if (!serverQueue) return msg.channel.send(':x: There is nothing playing that I could skip for you.');
msg.channel.send('Skipped :thumbsup:')
serverQueue.audioPlayer.stop();
return undefined;
} else if (command === 'stop') {
if (!msg.member.voice.channel) return msg.channel.send(':x: You are not in a voice channel!');
if (!serverQueue) return msg.channel.send(':x: There is nothing playing that I could stop for you.');
msg.channel.send('Stopped the music! :stop_button:')
serverQueue.songs = [];
serverQueue.audioPlayer.stop();
return undefined;
} else if (command === 'volume') {
if (!msg.member.voice.channel) return msg.channel.send(':x: You are not in a voice channel!');
if (!serverQueue) return msg.channel.send(':x: There is nothing playing.');
if (!args[1]) return msg.channel.send(`The current volume is: **${serverQueue.volume}** :speaker:`);
if (isNaN(args[1])) {
return msg.channel.send(':x: I\'m sorry, But you need to enter a valid __number__.')
}
serverQueue.volume = args[1];
serverQueue.audioResource.volume.setVolume(args[1] / 100);
return msg.channel.send(`I set the volume to: **${args[1]}** 🔊`);
} else if (command === 'np' || command === 'nowplaying') {
if (!serverQueue) return msg.channel.send(':x: There is nothing playing.');
return msg.channel.send(`:musical_note: Now playing: **${serverQueue.songs[0].title}**`);
} else if (command === "queue" || command === 'q') {
if (!serverQueue)
return msg.channel.send(":x: There is nothing in the queue.");
var queuemessage = `__**Song queue:**__
${serverQueue.songs.map(song => `**-** ${song.title}`).join("\n")}
**Now playing:** ${serverQueue.songs[0].title} :musical_note: `;
if (queuemessage.length < 2000) {
return msg.channel.send(":x: The queue has too many songs in it to show all in this channel. Try again after a few songs");
}
return msg.channel.send(queuemessage);
} else if (command === 'pause') {
if (serverQueue && serverQueue.playing) {
serverQueue.playing = false;
serverQueue.audioPlayer.pause();
return msg.channel.send(':pause_button: Paused the music for you!');
}
return msg.channel.send(':x: There is nothing playing.');
} else if (command === 'resume') {
if (serverQueue && !serverQueue.playing) {
serverQueue.playing = true;
serverQueue.audioPlayer.unpause();
return msg.channel.send(':play_pause: Resumed the music for you!');
}
return msg.channel.send(':x: There is nothing playing.');
}
}
if (msg.content === `${PREFIX}`) {
return;
}
msg.channel.send(`:x: Unknown command! Type ${PREFIX}help for the list of commands!`)
return;
}
});
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);
});
async function handleVideo(video, msg, voiceChannel, playlist = false) {
const serverQueue = queue.get(msg.guild.id);
const song = {
id: video.id,
title: video.title,
url: `https://www.youtube.com/watch?v=${video.id}`
};
if (!serverQueue) {
const queueConstruct = {
textChannel: msg.channel,
voiceChannel: voiceChannel,
connection: null,
audioPlayer: createAudioPlayer({
behaviors: {
noSubscriber: NoSubscriberBehavior.Play,
}
}),
audioResource: null,
songs: [],
volume: 50,
playing: true
};
client.on('guildCreate', async (guild) => {
const eventName = 'guildcreate';
const event = client.events.get(eventName) || client.events.find(ent => ent.aliases && ent.aliases.includes(eventName));
event.execute(client, guild);
});
queue.set(msg.guild.id, queueConstruct);
client.login(client.config.discord_api_token).catch(err => { console.log('- Failed To Login -> ' + err); });
queueConstruct.songs.push(song);
try {
const connection =
getVoiceConnection(voiceChannel.guild.id) ??
joinVoiceChannel({
channelId: voiceChannel.id,
guildId: voiceChannel.guild.id,
adapterCreator: voiceChannel.guild.voiceAdapterCreator
});
queueConstruct.connection = connection;
play(msg.guild, queueConstruct.songs[0]);
} catch (error) {
console.error(`I could not join the voice channel: ${error}`);
queue.delete(msg.guild.id);
return msg.channel.send(`:x: I could not join the voice channel: ${error}`);
}
} else {
serverQueue.songs.push(song);
if (playlist) return undefined;
else return msg.channel.send(`:white_check_mark: **${song.title}** has been added to the queue!`);
}
return undefined;
}
function play(guild, song) {
const serverQueue = queue.get(guild.id);
if (!song) {
serverQueue.connection.destroy();
queue.delete(guild.id);
return;
}
serverQueue.audioPlayer
.on(AudioPlayerStatus.Idle, () => {
serverQueue.songs.shift();
serverQueue.audioPlayer.removeAllListeners();
play(guild, serverQueue.songs[0]);
})
.on('error', (error) => {
console.error(error)
});
const audioResource = createAudioResource(ytdl(song.url, { quality: `highestaudio`, filter: 'audioonly' }),{
inlineVolume: true
});
audioResource.volume.setVolume(serverQueue.volume / 100);
serverQueue.audioPlayer.play(audioResource);
serverQueue.audioResource = audioResource;
serverQueue.connection.subscribe(serverQueue.audioPlayer);
serverQueue.textChannel.send(`:musical_note: Start playing: **${song.title}**`);
}

2324
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,34 +1,26 @@
{
"name": "musix-oss",
"version": "2.22.0",
"version": "1.3.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node index.js",
"start:dev": "nodemon"
"start:dev": "nodemon",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "Musix Org",
"author": "",
"license": "MIT",
"homepage": "https://https://github.com/musix-oss/musix",
"repository": {
"type": "git",
"url": "https://https://github.com/musix-oss/musix"
},
"dependencies": {
"discord.js": "^14.21.0",
"@discordjs/voice": "^0.18.0",
"@discordjs/opus": "^0.10.0",
"dotenv": "^17.0.1",
"firebase": "^11.10.0",
"firebase-admin": "^13.4.0",
"he": "^1.2.0",
"discord.js": "^14.14.1",
"@discordjs/voice": "^0.16.1",
"@discordjs/opus": "^0.9.0",
"ms": "^2.1.3",
"request": "^2.88.2",
"simple-youtube-api": "^5.2.1",
"ytdl-core": "^4.11.5"
},
"devDependencies": {
"nodemon": "^3.1.10"
"nodemon": "^3.0.3"
}
}