diff options
Diffstat (limited to 'src')
34 files changed, 2180 insertions, 0 deletions
diff --git a/src/app.js b/src/app.js new file mode 100644 index 0000000..fca1bad --- /dev/null +++ b/src/app.js @@ -0,0 +1,7 @@ +const { ShardingManager } = require('discord.js'); +const config = require('./config.json'); +const manager = new ShardingManager('./dist/bot.js', { token: config['secret'] }); +//const manager = new ShardingManager('./bot.js', { token: config['secret'] }); + +manager.spawn(); +manager.on('shardCreate', shard => console.log(`Launched shard: ${shard.id}`)); diff --git a/src/bot.ts b/src/bot.ts new file mode 100644 index 0000000..cf90dfc --- /dev/null +++ b/src/bot.ts @@ -0,0 +1,71 @@ +import config from './config.json'; +import { CommandoClient } from 'discord.js-commando'; +import path from 'path'; +import { Structures } from 'discord.js'; +import emoji from 'emoji-random'; +Structures.extend('Guild', Guild => { + class MusicGuild extends Guild { + musicData: { queue: never[]; isPlaying: boolean; volume: number; songDispatcher: null; }; + constructor(client, data) { + super(client, data); + this.musicData = { + queue: [], + isPlaying: false, + volume: 1, + songDispatcher: null + }; + } + } + return MusicGuild; +}); + +const client = new CommandoClient({ + commandPrefix: 'uwu!', + owner: '217348698294714370' +}); + +client.registry + .registerDefaultTypes() + .registerGroups([ + ['fun', 'Fun Command Group'], + ['moderation', 'Moderation Command Group'], + ['utility', 'Utility Command Group'], + ['voice', 'Voice Command Group'] + ]) + .registerDefaultGroups() + .registerDefaultCommands({ + help: true + }) + .registerCommandsIn(path.join(__dirname, 'commands')); + +client.once('ready', () => { + console.log(`Started bot: ${client.user.tag} (ID: ${client.user.id})\nCurrently running on ${client.guilds.cache.size} server(s).`); + client.user.setActivity('uwu!help | v5.0.0', { + type: 'WATCHING' + }); +}); + +client.on('error', console.error); +//client.on('debug', console.debug); + +client.on('message', async msg => { + var msgContent = msg.content.toLowerCase(); + function prefixCheck() { + if (msgContent.startsWith('uwu!')) { + return true; + } + } + if (prefixCheck()) { + if (msg.channel.type == 'dm') { + console.log(msg.author.tag, 'says', msgContent, 'in a DM'); + } else { + console.log(msg.member.user.tag, 'says', msgContent, 'in #' + msg.channel.name); + } + } + + if (msg.mentions.everyone) { + msg.react(emoji.random()); + } +}); + +client.login(config['secret']);
\ No newline at end of file diff --git a/src/commands/fun/8ball.js b/src/commands/fun/8ball.js new file mode 100644 index 0000000..6be4f01 --- /dev/null +++ b/src/commands/fun/8ball.js @@ -0,0 +1,38 @@ +const { Command } = require('discord.js-commando'); +const { MessageEmbed } = require('discord.js'); + +module.exports = class EightBallFun extends Command { + constructor(client) { + super(client, { + name: '8ball', + aliases: [ + '8b', + '9b', + '9ball', + '7b', + '7ball' + ], + group: 'fun', + memberName: '8ball', + description: 'Shake the 8ball for a fortune.', + throttling: { + usages: 5, + duration: 30 + }, + examples: ['uwu!8ball', 'uwu!8b'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + clientPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'] + }); + } + run(msg) { + var r = ['Yes~ uwu', 'No.', 'Yes!', 'No!', 'What, no.', 'Yes.', 'Maybe.', 'Perhaps.', 'Try again.', 'I\'m not sure.']; + var s = r[Math.floor(Math.random() * r.length)]; + + let embed = new MessageEmbed() + + .setAuthor('The 8-ball says', 'https://upload.wikimedia.org/wikipedia/commons/thumb/f/fd/8-Ball_Pool.svg/500px-8-Ball_Pool.svg.png') + .setDescription('`' + s + '`'); + + msg.channel.send(embed); + } +};
\ No newline at end of file diff --git a/src/commands/fun/emoji.js b/src/commands/fun/emoji.js new file mode 100644 index 0000000..ca633b9 --- /dev/null +++ b/src/commands/fun/emoji.js @@ -0,0 +1,24 @@ +const emoji = require('emoji-random'); +const { Command } = require('discord.js-commando'); + +module.exports = class EmojiFun extends Command { + constructor(client) { + super(client, { + name: 'emoji', + aliases: ['moji'], + group: 'fun', + memberName: 'emoji', + description: 'Gives you a random emoji.' + emoji.random(), + throttling: { + usages: 5, + duration: 30 + }, + examples: ['uwu!emoji', 'uwu!moji'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + clientPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'] + }); + } + run(msg) { + msg.reply(emoji.random()); + } +};
\ No newline at end of file diff --git a/src/commands/fun/gay.js b/src/commands/fun/gay.js new file mode 100644 index 0000000..ec78ee3 --- /dev/null +++ b/src/commands/fun/gay.js @@ -0,0 +1,34 @@ +const { Command } = require('discord.js-commando'); + +module.exports = class GayFun extends Command { + constructor(client) { + super(client, { + name: 'gay', + aliases: [ + 'gayamount', + 'gayrange', + 'gayrate' + ], + group: 'fun', + memberName: 'gay', + description: 'Tells you your gay-ness amount.', + examples: [ + 'uwu!gay', + 'uwu!gayamount', + 'uwu!gayrange', + 'uwu!gayrate' + ], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + clientPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'] + }); + } + run(msg) { + var gayAmount = Math.floor((Math.random() * 100) + 1); + var gayAmountDecimal = Math.floor((Math.random() * 100) + 1); + + msg.reply('Scanning..').then(scanningMsg => { + scanningMsg.delete() + msg.reply('Your gay-ness amount is **' + gayAmount + '.' + gayAmountDecimal + '%**. 🏳️🌈'); + }); + } +};
\ No newline at end of file diff --git a/src/commands/fun/quote.js b/src/commands/fun/quote.js new file mode 100644 index 0000000..4a19a31 --- /dev/null +++ b/src/commands/fun/quote.js @@ -0,0 +1,40 @@ +const atquotes = require('at-quotes'); +const { Command } = require('discord.js-commando'); +const emoji = require('emoji-random'); + +module.exports = class QuoteFun extends Command { + constructor(client) { + super(client, { + name: 'quote', + aliases: ['quotes'], + group: 'fun', + memberName: 'quote', + description: 'Gives you a random quote from Adventure Time.', + throttling: { + usages: 5, + duration: 30 + }, + examples: ['s5n!quote', 's5n!quote finn'], + args: [ + { + key: 'atCharacter', + prompt: 'Would you like a specific character? (Finn, Jake, Ice King, No)', + type: 'string' + } + ], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + clientPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'] + }); + } + run(msg, { atCharacter }) { + if (!atCharacter || atCharacter == 'no' || atCharacter == 'n') { + msg.reply(atquotes.getQuote() + ' ' + emoji.random()); + } else if (atCharacter == 'finn' || atCharacter == 'f') { + msg.reply(atquotes.getFinnQuote() + ' ' + emoji.random()); + } else if (atCharacter == 'jake' || atCharacter == 'j') { + msg.reply(atquotes.getJakeQuote() + ' ' + emoji.random()); + } else if (atCharacter == 'ice king' || atCharacter == 'ik') { + msg.reply(atquotes.getIceKingQuote() + ' ' + emoji.random()); + } + } +};
\ No newline at end of file diff --git a/src/commands/fun/respect.js b/src/commands/fun/respect.js new file mode 100644 index 0000000..50d185b --- /dev/null +++ b/src/commands/fun/respect.js @@ -0,0 +1,23 @@ +const { Command } = require('discord.js-commando'); + +module.exports = class RespectFun extends Command { + constructor(client) { + super(client, { + name: 'respect', + aliases: ['f'], + group: 'fun', + memberName: 'respect', + description: 'Press F to pay respects.', + examples: ['uwu!respect', 'uwu!f'], + guildOnly: true, + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + clientPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'] + }); + } + run(msg) { + msg.channel.send('Press F to pay respects.').then(m => { + m.react('🇫'); + msg.delete(); + }); + } +};
\ No newline at end of file diff --git a/src/commands/fun/say.js b/src/commands/fun/say.js new file mode 100644 index 0000000..667bb49 --- /dev/null +++ b/src/commands/fun/say.js @@ -0,0 +1,31 @@ +const { Command } = require('discord.js-commando'); + +module.exports = class SayFun extends Command { + constructor(client) { + super(client, { + name: 'say', + group: 'fun', + memberName: 'say', + description: 'Allows you to speak as the bot.', + guildOnly: true, + args: [ + { + key: 'say', + prompt: 'What would you like to send?', + type: 'string' + } + ], + examples: ['uwu!say hi'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + clientPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'] + }); + } + run(msg, { say }) { + if (msg.member.hasPermission('KICK_MEMBERS')) { + msg.channel.send(say); + msg.delete(); + } else { + msg.reply('Insufficent perms. ' + emoji.random()); + } + } +};
\ No newline at end of file diff --git a/src/commands/fun/uwufy.ts b/src/commands/fun/uwufy.ts new file mode 100644 index 0000000..9e40078 --- /dev/null +++ b/src/commands/fun/uwufy.ts @@ -0,0 +1,31 @@ +import { Message } from "discord.js"; +import { Command } from 'discord.js-commando'; + +module.exports = class UwufyFun extends Command { + constructor(client) { + super(client, { + name: 'uwufy', + aliases: ['uwu', 'owofy', 'owo'], + group: 'fun', + memberName: 'uwufy', + description: 'Uwufys anything you send.', + args: [ + { + key: 'userMsg', + prompt: 'What would you like to uwufy?', + type: 'string' + } + ], + examples: ['uwu!say please uwufy this'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + clientPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + }); + } + run(msg: Message, { userMsg }) { + var m = userMsg; + var u1 = m.replace('r', 'w'); + var u2 = u1.replace('l', 'w'); + msg.reply(u2); + msg.delete(); + } +};
\ No newline at end of file diff --git a/src/commands/utility/btc.ts b/src/commands/utility/btc.ts new file mode 100644 index 0000000..2845194 --- /dev/null +++ b/src/commands/utility/btc.ts @@ -0,0 +1,36 @@ +import { Command } from 'discord.js-commando'; +import emoji from 'emoji-random'; +import btc from 'btc-value'; +btc.setApiKey('a43419ce-fc59-4951-8af9-20c5e36ef73f'); + +module.exports = class BTCUtility extends Command { + constructor(client) { + super(client, { + name: 'btc', + aliases: ['bitcoin', 'crypto'], + group: 'utility', + memberName: 'btc', + description: 'Allows you to check current Bitcoin price.', + args: [ + { + key: 'currencyName', + prompt: 'What currency could you like to see it in? (USD, AUD, CAD)', + type: 'string' + } + ], + examples: [ + 'uwu!bitcoin aud', + 'uwu!crypto cad', + 'uwu!btc usd' + ], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + clientPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'] + }); + } + run(msg: Message, { currencyName }) { + currencyName = currencyName.toUpperCase(); + btc({ isDecimal: true, currencyCode: currencyName }).then(value => { + msg.reply('The current price of *Bitcoin* in **' + currencyName + '** is **' + value + '**. ' + emoji.random()); + }); + } +};
\ No newline at end of file diff --git a/src/commands/utility/btcchange.js b/src/commands/utility/btcchange.js new file mode 100644 index 0000000..474a3ee --- /dev/null +++ b/src/commands/utility/btcchange.js @@ -0,0 +1,47 @@ +const { Command } = require('discord.js-commando'); +const btc = require('btc-value'); +btc.setApiKey('a43419ce-fc59-4951-8af9-20c5e36ef73f'); + +module.exports = class BTCChangeUtility extends Command { + constructor(client) { + super(client, { + name: 'btcchange', + aliases: ['bitcoinchange', 'cryptochange', 'btcc'], + group: 'utility', + memberName: 'btcchange', + description: 'Allows you to check the fluctuation in Bitcoin prices within a specified amount of time.', + args: [ + { + key: 'timeAmount', + prompt: 'What time range do you want to check the fluction amount in? (day, hour, week)', + type: 'string' + } + ], + examples: [ + 'uwu!btcchange day', + 'uwu!bitcoinchange hour', + 'uwu!cryptochange week', + 'uwu!btcc day' + ], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + clientPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'] + }); + } + run(msg, { timeAmount }) { + if (timeAmount == 'day') { + btc.getPercentageChangeLastDay().then(percentage => { + msg.reply('The fluction amount of *Bitcoin* in the last **' + timeAmount + '** is **' + percentage + '%**. ' + emoji.random()); + }); + } else if (timeAmount == 'hour') { + btc.getPercentageChangeLastHour().then(percentage => { + msg.reply('The fluction amount of *Bitcoin* in the last **' + timeAmount + '** is **' + percentage + '%**. ' + emoji.random()); + }); + } else if (timeAmount == 'week') { + btc.getPercentageChangeLastWeek().then(percentage => { + msg.reply('The fluction amount of *Bitcoin* in the last **' + timeAmount + '** is **' + percentage + '%**. ' + emoji.random()); + }); + } else { + msg.reply('*' + timeAmount + '* is not a valid range. ' + emoji.random()); + } + } +};
\ No newline at end of file diff --git a/src/commands/utility/clear.js b/src/commands/utility/clear.js new file mode 100644 index 0000000..6871cca --- /dev/null +++ b/src/commands/utility/clear.js @@ -0,0 +1,72 @@ +const { Command } = require('discord.js-commando'); +const emoji = require('emoji-random'); + +module.exports = class ClearUtility extends Command { + constructor(client) { + super(client, { + name: 'clear', + aliases: ['delete', 'del', 'c', 'd'], + group: 'utility', + memberName: 'clear', + description: 'Clears a specified amount of messages.', + guildOnly: true, + args: [ + { + key: 'deleteAmount', + prompt: 'How many messages would you like to delete?', + type: 'integer' + } + ], + examples: [ + 'uwu!clear 23', + 'uwu!delete 75', + 'uwu!del 32', + 'uwu!c 45', + 'uwu!d 84' + ], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY', 'MANAGE_MESSAGES'], + clientPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY', 'MANAGE_MESSAGES'] + }); + } + async run(msg, { deleteAmount }) { + if (msg.member.hasPermission('MANAGE_MESSAGES')) { + if (!deleteAmount) { + msg.reply('You haven\'t specified an amount of messages which should be deleted. ' + emoji.random()).then(deleteNotificationMessage => { + deleteNotificationMessage.delete({ timeout: 1000 }); + }); + } else if (isNaN(deleteAmount)) { + msg.reply('The amount parameter isn\'t a number. ' + emoji.random()).then(deleteNotificationMessage => { + deleteNotificationMessage.delete({ timeout: 1000 }); + }); + } else if (deleteAmount > 100) { + msg.reply('You can\'t delete more than 100 messages at once. ' + emoji.random()).then(deleteNotificationMessage => { + deleteNotificationMessage.delete({ timeout: 1000 }); + }); + } else if (deleteAmount < 1) { + msg.reply('You have to delete at least 1 message. ' + emoji.random()).then(deleteNotificationMessage => { + deleteNotificationMessage.delete({ timeout: 1000 }); + }); + } + /*else if (msg.createdTimestamp > 1209600) { + msg.reply('due to discord rules, bots can only bulk delete messages that are under 14 days old :(') + } */ + else { + var clearAmount = deleteAmount + 1; + // It took me so long to figure out why this was not really working. It would delete but an insane amount at a time. + // I realized that because it was getting parsed as a string, it would just add 1 to it so if I tried to delete 1 + // message, it would delete 11 lol. Fixed by parsing as integer THEN adding one. 02:30 2020/04/03/2020 + + await msg.channel.messages.fetch({ + limit: clearAmount + }).then(messages => { // I am on v11 discord.js + msg.channel.bulkDelete(messages); + }); + msg.reply('It\'s been deleted ~uwu ' + emoji.random()).then(deleteNotificationMessage => { + deleteNotificationMessage.delete({ timeout: 1000 }); + }); + } + } else { + msg.reply('Insufficent perms. ' + emoji.random()); + } + } +};
\ No newline at end of file diff --git a/src/commands/utility/membercount.js b/src/commands/utility/membercount.js new file mode 100644 index 0000000..1178236 --- /dev/null +++ b/src/commands/utility/membercount.js @@ -0,0 +1,29 @@ +const { Command } = require('discord.js-commando'); +const emoji = require('emoji-random'); + +module.exports = class MemberCountUtility extends Command { + constructor(client) { + super(client, { + name: 'membercount', + aliases: ['memberc', 'mcount', 'mc'], + group: 'utility', + memberName: 'membercount', + description: 'Tells you how many members are in the current server.', + throttling: { + usages: 5, + duration: 30 + }, + examples: [ + 'uwu!membercount', + 'uwu!memberc', + 'uwu!mcount', + 'uwu!mc' + ], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + clientPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'] + }); + } + run(msg) { + msg.reply(`There are **${msg.guild.memberCount}** members in **${msg.guild.name}**. ` + emoji.random()); + } +};
\ No newline at end of file diff --git a/src/commands/utility/server.js b/src/commands/utility/server.js new file mode 100644 index 0000000..58555fa --- /dev/null +++ b/src/commands/utility/server.js @@ -0,0 +1,54 @@ +const { Command } = require('discord.js-commando'); +const { MessageEmbed } = require('discord.js'); + +module.exports = class ServerUtility extends Command { + constructor(client) { + super(client, { + name: 'server', + aliases: [ + 'serverinfo', + 'si', + 'server-info', + 'serverstats', + 'server-stats' + ], + group: 'utility', + memberName: 'server', + description: 'Gives you information about the current server.', + throttling: { + usages: 2, + duration: 60 + }, + guildOnly: true, + examples: [ + 'uwu!server', + 'uwu!serverinfo', + 'uwu!server-info', + 'uwu!serverstats', + 'uwu!server-stats', + 'uwu!si' + ], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + clientPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'] + }); + } + run(msg) { + var o = msg.guild.members.cache.filter(m => m.presence.status === 'online').size; + + let embed = new MessageEmbed() + + .setAuthor(`${msg.guild.name} - ${msg.guild.id}`, `${msg.guild.iconURL()}`, `https://discordapp.com/channels/${msg.guild.id}/${msg.guild.id}`) + .setDescription(`Here\'s all the information on \`${msg.guild.name}\``) + .setThumbnail(`${msg.guild.iconURL()}`) + .addField('Owner', `${msg.guild.owner}`, false) + .addField(`Members [${msg.guild.memberCount}]`, `${o} members are online.`, true) + .addField('Region', `${msg.guild.region}`, true) + .addField('Text channels', `${msg.guild.channels.filter(c => c.type === 'text').size}`, true) + .addField('Voice channels', `${msg.guild.channels.filter(c => c.type === 'voice').size}`, true) + .addField('Guild created', `${msg.guild.createdAt}`, false) + .addField(`${this.client.user.username} joined`, `${msg.guild.members.get('699473263998271489').joinedAt}`) + .setColor(0xFFCC4D); + + msg.channel.send(embed); + } +};
\ No newline at end of file diff --git a/src/commands/utility/servers.ts b/src/commands/utility/servers.ts new file mode 100644 index 0000000..1b3ce0f --- /dev/null +++ b/src/commands/utility/servers.ts @@ -0,0 +1,28 @@ +import { Command } from 'discord.js-commando'; +import { MessageEmbed, Message } from 'discord.js'; +import emoji from 'emoji-random'; + +module.exports = class ServersUtility extends Command { + constructor(client) { + super(client, { + name: 'servers', + aliases: ['servercount', 'scount', 'serverc'], + group: 'utility', + memberName: 'servers', + description: 'Tells you the amount of servers uwufy is in.', + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + clientPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'] + }); + } + run(msg: Message) { + msg.channel.send('Please wait..').then(m => { + m.edit(`** **`); + + let emb = new MessageEmbed() + .setDescription(`Currently running on 31${this.client.guilds.cache.size} server(s). ` + emoji.random()) + .setColor(0xFFCC4D) + + msg.channel.send(emb); + }); + } +};
\ No newline at end of file diff --git a/src/commands/utility/uptime.ts b/src/commands/utility/uptime.ts new file mode 100644 index 0000000..eebd031 --- /dev/null +++ b/src/commands/utility/uptime.ts @@ -0,0 +1,40 @@ +import { Command } from 'discord.js-commando'; +import { duration as _duration } from 'moment'; +import 'moment-duration-format'; +// @ts-ignore +import emoji from 'emoji-random'; +import { MessageEmbed, Message } from 'discord.js'; + +export default class UptimeUtility extends Command { + constructor(client) { + super(client, { + name: 'uptime', + aliases: ['ut'], + group: 'utility', + memberName: 'uptime', + description: 'Tells you how long the bot has been online.', + throttling: { + usages: 5, + duration: 30 + }, + examples: [ + 'uwu!uptime', + 'uwu!ut' + ], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + clientPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'] + }); + } + run(msg: Message) { + const duration = _duration(this.client.uptime).format(" D [days], H [hrs], m [mins], s [secs]"); + msg.channel.send('Please wait..').then(m => { + m.edit(`** **`); + + let emb = new MessageEmbed() + .setDescription('uwufier has been up for ' + duration + '. ' + emoji.random()) + .setColor(0xFFCC4D) + + msg.channel.send(emb); + }); + } +}
\ No newline at end of file diff --git a/src/commands/voice/abee.ts b/src/commands/voice/abee.ts new file mode 100644 index 0000000..939b575 --- /dev/null +++ b/src/commands/voice/abee.ts @@ -0,0 +1,199 @@ +import ytdl from 'ytdl-core'; +import { Command } from 'discord.js-commando'; +import { MessageEmbed, Message } from 'discord.js'; +import Youtube from 'simple-youtube-api'; +//const { youtubeAPI } = require('../../config.json'); +import config from '../../config.json'; +const youtube = new Youtube(config['yt-api-key']); +import emoji from 'emoji-random'; + +module.exports = class ABeeVoice extends Command { + constructor(client) { + super(client, { + name: 'abee', + aliases: ['a-bee'], + group: 'voice', + memberName: 'abee', + description: 'A bee 🐝', + guildOnly: true, + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + examples: ['uwu!abee', 'uwu!a-bee'], + }); + } + async run(msg: Message) { + const voiceChannel = msg.member.voice.channel; + if (!voiceChannel) return msg.say('Please join a channel and try again. ' + emoji.random()); + + const id = 'lvdnhWhQBdo'; + const video = await youtube.getVideoByID(id).catch(function () { + return msg.say( + 'There was a problem getting the video you provided. ' + emoji.random() + ); + }); + // // can be uncommented if you don't want the bot to play live streams + // if (video.raw.snippet.liveBroadcastContent === 'live') { + // return msg.say("I don't support live streams!"); + // } + // // can be uncommented if you don't want the bot to play videos longer than 1 hour + // if (video.duration.hours !== 0) { + // return msg.say('I cannot play videos longer than 1 hour'); + // } + // // can be uncommented if you want to limit the queue + // if (msg.guild.musicData.queue.length > 10) { + // return msg.say( + // 'There are too many songs in the queue already, skip or wait a bit' + // ); + // } + msg.guild.musicData.queue.push( + this.constructSongObj(video, voiceChannel) + ); + if ( + msg.guild.musicData.isPlaying == false || + typeof msg.guild.musicData.isPlaying == 'undefined' + ) { + msg.guild.musicData.isPlaying = true; + return this.playSong(msg.guild.musicData.queue, msg); + } else if (msg.guild.musicData.isPlaying == true) { + return msg.say(`${video.title} added to queue. ` + emoji.random()); + } + + var that = this; + msg.channel + .awaitMessages( + function (msg) { + return (msg.content > 0 && msg.content < 6) || msg.content === 'exit'; + }, { + max: 1, + time: 60000, + errors: ['time'] + } + ) + .then(function (response) { + const videoIndex = parseInt(response.first().content); + if (response.first().content === 'exit') return songEmbed.delete(); + youtube + .getVideoByID(videos[videoIndex - 1].id) + .then(function (video) { + // // can be uncommented if you don't want the bot to play live streams + // if (video.raw.snippet.liveBroadcastContent === 'live') { + // songEmbed.delete(); + // return msg.say("I don't support live streams!"); + // } + + // // can be uncommented if you don't want the bot to play videos longer than 1 hour + // if (video.duration.hours !== 0) { + // songEmbed.delete(); + // return msg.say('I cannot play videos longer than 1 hour'); + // } + + // // can be uncommented if you don't want to limit the queue + // if (msg.guild.musicData.queue.length > 10) { + // songEmbed.delete(); + // return msg.say( + // 'There are too many songs in the queue already, skip or wait a bit' + // ); + // } + msg.guild.musicData.queue.push( + that.constructSongObj(video, voiceChannel) + ); + if (msg.guild.musicData.isPlaying == false) { + msg.guild.musicData.isPlaying = true; + if (songEmbed) { + songEmbed.delete(); + } + that.playSong(msg.guild.musicData.queue, msg); + } else if (msg.guild.musicData.isPlaying == true) { + if (songEmbed) { + songEmbed.delete(); + } + return msg.say(`${video.title} added to queue. ` + emoji.random()); + } + }) + .catch(function () { + if (songEmbed) { + songEmbed.delete(); + } + return msg.say( + 'An error has occured when trying to get the video ID from YouTube. ' + emoji.random() + ); + }); + }); + } + playSong(queue, msg) { + const classThis = this; // use classThis instead of 'this' because of lexical scope below + queue[0].voiceChannel + .join() + .then(function (connection) { + const dispatcher = connection + .play( + ytdl(queue[0].url, { + quality: 'highestaudio', + highWaterMark: 1024 * 1024 * 10 + }) + ) + .on('start', function () { + msg.guild.musicData.songDispatcher = dispatcher; + const volume = 100 / 100; + msg.guild.musicData.volume = volume; + dispatcher.setVolume(msg.guild.musicData.volume); + const videoEmbed = new MessageEmbed() + .setThumbnail(queue[0].thumbnail) + .setColor(0xF97DAE) + .addField('Now playing:', queue[0].title) + .addField('Duration:', queue[0].duration); + if (queue[1]) videoEmbed.addField('Next song:', queue[1].title); + msg.say(videoEmbed); + msg.guild.musicData.nowPlaying = queue[0]; + return queue.shift(); + }) + .on('finish', function () { + if (queue.length >= 1) { + return classThis.playSong(queue, msg); + } else { + msg.guild.musicData.isPlaying = false; + msg.guild.musicData.nowPlaying = null; + msg.guild.musicData.songDispatcher = null; + return msg.guild.me.voice.channel.leave(); + } + }) + .on('error', function (e) { + msg.say('Can\'t play song. ' + emoji.random()); + console.error(e); + msg.guild.musicData.queue.length = 0; + msg.guild.musicData.isPlaying = false; + msg.guild.musicData.nowPlaying = null; + msg.guild.musicData.songDispatcher = null; + return msg.guild.me.voice.channel.leave(); + }); + }) + .catch(function (e) { + console.error(e); + return msg.guild.me.voice.channel.leave(); + }); + } + constructSongObj(video, voiceChannel) { + let duration = this.formatDuration(video.duration); + if (duration == '00:00') duration = 'Live Stream'; + return { + url: `https://www.youtube.com/watch?v=${video.raw.id}`, + title: video.title, + duration, + thumbnail: video.thumbnails.high.url, + voiceChannel + }; + } + // prettier-ignore + formatDuration(durationObj) { + const duration = `${durationObj.hours ? (durationObj.hours + ':') : ''}${ + durationObj.minutes ? durationObj.minutes : '00' + }:${ + (durationObj.seconds < 10) + ? ('0' + durationObj.seconds) + : (durationObj.seconds + ? durationObj.seconds + : '00') + }`; + return duration; + } +};
\ No newline at end of file diff --git a/src/commands/voice/itemshop.ts b/src/commands/voice/itemshop.ts new file mode 100644 index 0000000..f8c0b2b --- /dev/null +++ b/src/commands/voice/itemshop.ts @@ -0,0 +1,209 @@ +import ytdl from 'ytdl-core'; +import { Command } from 'discord.js-commando'; +import { MessageEmbed, Message } from 'discord.js'; +import Youtube from 'simple-youtube-api'; +//const { youtubeAPI } = require('../../config.json'); +import config from '../../config.json'; +const youtube = new Youtube(config['yt-api-key']); +import emoji from 'emoji-random'; + +module.exports = class ABeeVoice extends Command { + constructor(client) { + super(client, { + name: 'itemshop', + aliases: ['item-shop'], + group: 'voice', + memberName: 'itemshop', + description: 'Use code \'Frozen\' in the Fortnite item shop.', + guildOnly: true, + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + examples: ['uwu!itemshop', 'uwu!item-shop'] + }); + } + async run(msg: Message) { + const voiceChannel = msg.member.voice.channel; + if (!voiceChannel) return msg.say('Please join a channel and try again. ' + emoji.random()); + + const id = 'pBiI1hTwU7E'; + const video = await youtube.getVideoByID(id).catch(function () { + return msg.say( + 'There was a problem getting the video you provided. ' + emoji.random() + ); + }); + // // can be uncommented if you don't want the bot to play live streams + // if (video.raw.snippet.liveBroadcastContent === 'live') { + // return msg.say("I don't support live streams!"); + // } + // // can be uncommented if you don't want the bot to play videos longer than 1 hour + // if (video.duration.hours !== 0) { + // return msg.say('I cannot play videos longer than 1 hour'); + // } + // // can be uncommented if you want to limit the queue + // if (msg.guild.musicData.queue.length > 10) { + // return msg.say( + // 'There are too many songs in the queue already, skip or wait a bit' + // ); + // } + msg.guild.musicData.queue.push( + this.constructSongObj(video, voiceChannel) + ); + if ( + msg.guild.musicData.isPlaying == false || + typeof msg.guild.musicData.isPlaying == 'undefined' + ) { + msg.guild.musicData.isPlaying = true; + return this.playSong(msg.guild.musicData.queue, msg); + } else if (msg.guild.musicData.isPlaying == true) { + return msg.say(`${video.title} added to queue. ` + emoji.random()); + } + + var that = this; + msg.channel + .awaitMessages( + function (msg) { + return (msg.content > 0 && msg.content < 6) || msg.content === 'exit'; + }, { + max: 1, + time: 60000, + errors: ['time'] + } + ) + .then(function (response) { + const videoIndex = parseInt(response.first().content); + if (response.first().content === 'exit') return songEmbed.delete(); + youtube + .getVideoByID(videos[videoIndex - 1].id) + .then(function (video) { + // // can be uncommented if you don't want the bot to play live streams + // if (video.raw.snippet.liveBroadcastContent === 'live') { + // songEmbed.delete(); + // return msg.say("I don't support live streams!"); + // } + + // // can be uncommented if you don't want the bot to play videos longer than 1 hour + // if (video.duration.hours !== 0) { + // songEmbed.delete(); + // return msg.say('I cannot play videos longer than 1 hour'); + // } + + // // can be uncommented if you don't want to limit the queue + // if (msg.guild.musicData.queue.length > 10) { + // songEmbed.delete(); + // return msg.say( + // 'There are too many songs in the queue already, skip or wait a bit' + // ); + // } + msg.guild.musicData.queue.push( + that.constructSongObj(video, voiceChannel) + ); + if (msg.guild.musicData.isPlaying == false) { + msg.guild.musicData.isPlaying = true; + if (songEmbed) { + songEmbed.delete(); + } + that.playSong(msg.guild.musicData.queue, msg); + } else if (msg.guild.musicData.isPlaying == true) { + if (songEmbed) { + songEmbed.delete(); + } + msg.say(`${video.title} added to queue. ` + emoji.random()); + return; + } + }) + .catch(function () { + if (songEmbed) { + songEmbed.delete(); + } + return msg.say( + 'An error has occured when trying to get the video ID from Youtube.' + emoji.random() + ); + }); + }); + } + playSong(queue, msg) { + const classThis = this; // use classThis instead of 'this' because of lexical scope below + queue[0].voiceChannel + .join() + .then(function (connection) { + const dispatcher = connection + .play( + ytdl(queue[0].url, { + quality: 'highestaudio', + highWaterMark: 1024 * 1024 * 10 + }) + + ) + .on('start', function () { + msg.guild.musicData.songDispatcher = dispatcher; + const volume = 100 / 100; + msg.guild.musicData.volume = volume; + dispatcher.setVolume(msg.guild.musicData.volume); + const videoEmbed = new MessageEmbed() + .setThumbnail(queue[0].thumbnail) + .setColor(0xF97DAE) + .addField('Now playing:', queue[0].title) + .addField('Duration:', queue[0].duration); + if (queue[1]) videoEmbed.addField('Next song:', queue[1].title); + msg.say(videoEmbed); + msg.guild.musicData.nowPlaying = queue[0]; + return queue.shift(); + }) + .on('finish', function () { + if (queue.length >= 1) { + return classThis.playSong(queue, msg); + } else { + msg.guild.musicData.isPlaying = false; + msg.guild.musicData.nowPlaying = null; + msg.guild.musicData.songDispatcher = null; + return msg.guild.me.voice.channel.leave(); + } + }) + .on('error', function (e) { + msg.say('Can\'t play song. ' + emoji.random()); + console.error(e); + msg.guild.musicData.queue.length = 0; + msg.guild.musicData.isPlaying = false; + msg.guild.musicData.nowPlaying = null; + msg.guild.musicData.songDispatcher = null; + return msg.guild.me.voice.channel.leave(); + }); + function timeCheck() { + if (dispatcher.streamTime >= 6000) { + msg.guild.musicData.isPlaying = false; + msg.guild.musicData.nowPlaying = null; + msg.guild.musicData.songDispatcher = null; + } + } + setInterval(timeCheck, 500); + }) + .catch(function (e) { + console.error(e); + return msg.guild.me.voice.channel.leave(); + }); + } + constructSongObj(video, voiceChannel) { + let duration = this.formatDuration(video.duration); + if (duration == '00:00') duration = 'Live Stream'; + return { + url: `https://www.youtube.com/watch?v=${video.raw.id}`, + title: video.title, + duration, + thumbnail: video.thumbnails.high.url, + voiceChannel + }; + } + // prettier-ignore + formatDuration(durationObj) { + const duration = `${durationObj.hours ? (durationObj.hours + ':') : ''}${ + durationObj.minutes ? durationObj.minutes : '00' + }:${ + (durationObj.seconds < 10) + ? ('0' + durationObj.seconds) + : (durationObj.seconds + ? durationObj.seconds + : '00') + }`; + return duration; + } +};
\ No newline at end of file diff --git a/src/commands/voice/join.js b/src/commands/voice/join.js new file mode 100644 index 0000000..4410e4c --- /dev/null +++ b/src/commands/voice/join.js @@ -0,0 +1,31 @@ +const { Command } = require('discord.js-commando'); +const emoji = require('emoji-random'); + +module.exports = class JoinVoice extends Command { + constructor(client) { + super(client, { + name: 'join', + group: 'voice', + memberName: 'join', + description: 'Joins your current voice channel.', + throttling: { + usages: 2, + duration: 5 + }, + guildOnly: true, + examples: ['uwu!join'], + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + }); + } + run(msg) { + if (msg.guild.musicData.isPlaying == false && msg.member.voice.channel) { + msg.member.voice.channel.join(); + msg.reply('Succesfully joined voice channel. ' + emoji.random()); + } else if (msg.guild.musicData.isPlaying == false) { + msg.reply('I\'m already in voice channel. ' + emoji.random()); + } else if (!msg.member.voice.channel) { + msg.reply('Please join a channel and try again. ' + emoji.random()); + } + } +};
\ No newline at end of file diff --git a/src/commands/voice/leave.js b/src/commands/voice/leave.js new file mode 100644 index 0000000..4c25e62 --- /dev/null +++ b/src/commands/voice/leave.js @@ -0,0 +1,34 @@ +const { Command } = require('discord.js-commando'); +const emoji = require('emoji-random'); + +module.exports = class LeaveVoice extends Command { + constructor(client) { + super(client, { + name: 'leave', + aliases: ['end', 'stop'], + group: 'voice', + memberName: 'leave', + description: 'Leaves voice channel and stops currently playing audio.', + guildOnly: true, + examples: ['uwu!leave', 'uwu!end', 'uwu!stop'], + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + }); + } + run(msg) { + var voiceChannel = msg.member.voice.channel; + if (!voiceChannel) return msg.reply('Please join a channel and try again. ' + emoji.random()); + + if ( + typeof msg.guild.musicData.songDispatcher == 'undefined' || + msg.guild.musicData.songDispatcher == null + ) { + return msg.reply('There isn\'t any audio playing right now. ' + emoji.random()); + } + if (!msg.guild.musicData.queue) + return msg.say('There aren\'t any songs in the current queue. ' + emoji.random()); + msg.guild.musicData.songDispatcher.end(); + msg.guild.musicData.queue.length = 0; + return; + } +};
\ No newline at end of file diff --git a/src/commands/voice/loop.js b/src/commands/voice/loop.js new file mode 100644 index 0000000..05c0e99 --- /dev/null +++ b/src/commands/voice/loop.js @@ -0,0 +1,34 @@ +const { Command } = require('discord.js-commando'); +const emoji = require('emoji-random'); + +module.exports = class LoopVoice extends Command { + constructor(client) { + super(client, { + name: 'loop', + aliases: ['repeat'], + group: 'voice', + memberName: 'loop', + description: 'Loops currently playing audio.', + guildOnly: true, + examples: ['uwu!loop', 'uwu!repeat'], + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + }); + } + run(msg) { + var voiceChannel = msg.member.voice.channel; + if (!voiceChannel) return msg.reply('Please join a channel and try again. ' + emoji.random()); + + if ( + typeof msg.guild.musicData.songDispatcher == 'undefined' || + msg.guild.musicData.songDispatcher == null + ) { + return msg.reply('There isn\'t any audio playing right now. ' + emoji.random()); + } + msg.channel.send( + `${msg.guild.musicData.nowPlaying.title} added to queue. ` + emoji.random() + ); + msg.guild.musicData.queue.unshift(msg.guild.musicData.nowPlaying); + return; + } +};
\ No newline at end of file diff --git a/src/commands/voice/minecraft.ts b/src/commands/voice/minecraft.ts new file mode 100644 index 0000000..cad7c06 --- /dev/null +++ b/src/commands/voice/minecraft.ts @@ -0,0 +1,204 @@ +import ytdl from 'ytdl-core'; +import { Command } from 'discord.js-commando'; +import { MessageEmbed } from 'discord.js'; +import Youtube from 'simple-youtube-api'; +//const { youtubeAPI } = require('../../config.json'); +import config from '../../config.json'; +const youtube = new Youtube(config['yt-api-key']); +import emoji from 'emoji-random'; + +module.exports = class MinecraftVoice extends Command { + constructor(client) { + super(client, { + name: 'minecraft', + aliases: ['minecraftsountrack', 'minecraft-soundtrack', 'mcs', 'mc-s'], + group: 'voice', + memberName: 'minecraft', + description: 'Plays the Minecraft soundtrack.', + guildOnly: true, + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + examples: [ + 'uwu!minecraft', + 'uwu!minecraftsountrack', + 'uwu!minecraft-soundtrack', + 'uwu!mcs', + 'uwu!mc-s' + ] + }); + } + async run(msg) { + const voiceChannel = msg.member.voice.channel; + if (!voiceChannel) return msg.say('Join a channel and try again. ' + emoji.random()); + + const playlist = await youtube.getPlaylist('https://www.youtube.com/watch?v=05UM-i4PuOY&list=PLxOTV5xn7n1i2HcKtRBthP2loWjrBGAIY').catch(function () { + return msg.say('There was a problem getting the soundtrack. ' + emoji.random()); + }); + // remove the 10 if you removed the queue limit conditions below + const videosObj = await playlist.getVideos(24).catch(function () { + return msg.say( + 'There was a problem getting the soundtrack. ' + emoji.random() + ); + }); + for (let i = 0; i < videosObj.length; i++) { + const video = await videosObj[i].fetch(); + // this can be uncommented if you choose to limit the queue + // if (msg.guild.musicData.queue.length < 10) { + // + msg.guild.musicData.queue.push( + this.constructSongObj(video, voiceChannel) + ); + // } else { + // return msg.say( + // `I can't play the full playlist because there will be more than 10 songs in queue` + // ); + // } + } + if (msg.guild.musicData.isPlaying == false) { + msg.guild.musicData.isPlaying = true; + return this.playSong(msg.guild.musicData.queue, msg); + } else if (msg.guild.musicData.isPlaying == true) { + return msg.say( + 'Now playing the Minecraft soundtrack. ' + emoji.random() + ); + } + + var that = this; + msg.channel + .awaitMessages( + function (msg) { + return (msg.content > 0 && msg.content < 6) || msg.content === 'exit'; + }, { + max: 1, + time: 60000, + errors: ['time'] + } + ) + .then(function (response) { + const videoIndex = parseInt(response.first().content); + if (response.first().content === 'exit') return songEmbed.delete(); + youtube + .getVideoByID(videos[videoIndex - 1].id) + .then(function (video) { + // // can be uncommented if you don't want the bot to play live streams + // if (video.raw.snippet.liveBroadcastContent === 'live') { + // songEmbed.delete(); + // return msg.say("I don't support live streams!"); + // } + + // // can be uncommented if you don't want the bot to play videos longer than 1 hour + // if (video.duration.hours !== 0) { + // songEmbed.delete(); + // return msg.say('I cannot play videos longer than 1 hour'); + // } + + // // can be uncommented if you don't want to limit the queue + // if (msg.guild.musicData.queue.length > 10) { + // songEmbed.delete(); + // return msg.say( + // 'There are too many songs in the queue already, skip or wait a bit' + // ); + // } + msg.guild.musicData.queue.push( + that.constructSongObj(video, voiceChannel) + ); + if (msg.guild.musicData.isPlaying == false) { + msg.guild.musicData.isPlaying = true; + if (songEmbed) { + songEmbed.delete(); + } + that.playSong(msg.guild.musicData.queue, msg); + } else if (msg.guild.musicData.isPlaying == true) { + if (songEmbed) { + songEmbed.delete(); + } + return msg.say('Now playing the Minecraft soundtrack. ' + emoji.random()); + } + }) + .catch(function () { + if (songEmbed) { + songEmbed.delete(); + } + return msg.say( + 'An error has occured when trying to get the video ID from YouTube. ' + emoji.random() + ); + }); + }); + } + playSong(queue, msg) { + const classThis = this; // use classThis instead of 'this' because of lexical scope below + queue[0].voiceChannel + .join() + .then(function (connection) { + const dispatcher = connection + .play( + ytdl(queue[0].url, { + quality: 'highestaudio', + highWaterMark: 1024 * 1024 * 10 + }) + ) + .on('start', function () { + msg.guild.musicData.songDispatcher = dispatcher; + const volume = 100 / 100; + msg.guild.musicData.volume = volume; + dispatcher.setVolume(msg.guild.musicData.volume); + const videoEmbed = new MessageEmbed() + .setThumbnail(queue[0].thumbnail) + .setColor(0xFFCC4D) + .addField('Now Playing:', queue[0].title) + .addField('Duration:', queue[0].duration); + if (queue[1]) videoEmbed.addField('Next Song:', queue[1].title); + msg.say(videoEmbed); + msg.guild.musicData.nowPlaying = queue[0]; + return queue.shift(); + }) + .on('finish', function () { + if (queue.length >= 1) { + return classThis.playSong(queue, msg); + } else { + msg.guild.musicData.isPlaying = false; + msg.guild.musicData.nowPlaying = null; + msg.guild.musicData.songDispatcher = null; + return msg.guild.me.voice.channel.leave(); + } + }) + .on('error', function (e) { + msg.say('Can\'t play soundtrack. ' + emoji.random()); + console.error(e); + msg.guild.musicData.queue.length = 0; + msg.guild.musicData.isPlaying = false; + msg.guild.musicData.nowPlaying = null; + msg.guild.musicData.songDispatcher = null; + return msg.guild.me.voice.channel.leave(); + }); + }) + .catch(function (e) { + console.error(e); + return msg.guild.me.voice.channel.leave(); + }); + } + constructSongObj(video, voiceChannel) { + let duration = this.formatDuration(video.duration); + if (duration == '00:00') duration = 'Live Stream'; + return { + url: `https://www.youtube.com/watch?v=${video.raw.id}`, + title: video.title, + duration, + thumbnail: video.thumbnails.high.url, + voiceChannel + }; + } + // prettier-ignore + formatDuration(durationObj) { + const duration = `${durationObj.hours ? (durationObj.hours + ':') : ''}${ + durationObj.minutes ? durationObj.minutes : '00' + }:${ + (durationObj.seconds < 10) + ? ('0' + durationObj.seconds) + : (durationObj.seconds + ? durationObj.seconds + : '00') + }`; + return duration; + } +};
\ No newline at end of file diff --git a/src/commands/voice/pause.js b/src/commands/voice/pause.js new file mode 100644 index 0000000..6ab6fb0 --- /dev/null +++ b/src/commands/voice/pause.js @@ -0,0 +1,32 @@ +const { Command } = require('discord.js-commando'); +const emoji = require('emoji-random'); + +module.exports = class PauseVoice extends Command { + constructor(client) { + super(client, { + name: 'pause', + group: 'voice', + memberName: 'pause', + description: 'Pauses audio of previously playing.', + guildOnly: true, + examples: ['uwu!pause'], + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + }); + } + run(msg) { + var voiceChannel = msg.member.voice.channel; + if (!voiceChannel) return msg.reply('Please join a channel and try again. ' + emoji.random()); + + if ( + typeof msg.guild.musicData.songDispatcher == 'undefined' || + msg.guild.musicData.songDispatcher == null + ) { + return msg.reply('There isn\'t any audio playing right now. ' + emoji.random()); + } + + msg.say('Song paused :pause_button:'); + + msg.guild.musicData.songDispatcher.pause(); + } +};
\ No newline at end of file diff --git a/src/commands/voice/play.ts b/src/commands/voice/play.ts new file mode 100644 index 0000000..61cf5d4 --- /dev/null +++ b/src/commands/voice/play.ts @@ -0,0 +1,292 @@ +import ytdl from 'ytdl-core'; +import { Command } from 'discord.js-commando'; +import { MessageEmbed, Message } from 'discord.js'; +import Youtube from 'simple-youtube-api'; +//const { youtubeAPI } = require('../../config.json'); +import config from '../../config.json'; +const youtube = new Youtube(config['yt-api-key']); +import emoji from 'emoji-random'; + +module.exports = class PlayVoice extends Command { + constructor(client) { + super(client, { + name: 'play', + group: 'voice', + memberName: 'play', + description: 'Play the audio of a YouTube video in a voice channel.', + guildOnly: true, + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + args: [ + { + key: 'query', + prompt: 'What song would you like to hear?', + type: 'string', + validate: function (query) { + return query.length > 0 && query.length < 200; + } + } + ], + examples: [ + 'uwu!play https://www.youtube.com/watch?v=dQw4w9WgXcQ', + 'uwu!play despacito' + ] + }); + } + async run(msg: Message, { query }) { + const voiceChannel = msg.member.voice.channel; + if (!voiceChannel) return msg.say('Please join a channel and try again. ' + emoji.random()); + + if ( + // if the user entered yt playlist url + query.match( + /^(?!.*\?.*\bv=)https:\/\/www\.youtube\.com\/.*\?.*\blist=.*$/ + ) + ) { + const playlist = await youtube.getPlaylist(query).catch(function () { + return msg.say('Playlist is either private or it does not exist. ' + emoji.random()); + }); + // remove the 10 if you removed the queue limit conditions below + const videosObj = await playlist.getVideos(10).catch(function () { + return msg.say( + 'There was a problem getting one or more of the videos in the playlist. ' + emoji.random() + ); + }); + for (let i = 0; i < videosObj.length; i++) { + const video = await videosObj[i].fetch(); + // this can be uncommented if you choose to limit the queue + // if (msg.guild.musicData.queue.length < 10) { + // + msg.guild.musicData.queue.push( + this.constructSongObj(video, voiceChannel) + ); + // } else { + // return msg.say( + // `I can't play the full playlist because there will be more than 10 songs in queue` + // ); + // } + } + if (msg.guild.musicData.isPlaying == false) { + msg.guild.musicData.isPlaying = true; + return this.playSong(msg.guild.musicData.queue, msg); + } else if (msg.guild.musicData.isPlaying == true) { + return msg.say( + `Playlist - :musical_note: ${playlist.title} :musical_note: has been added to queue. ` + emoji.random() + ); + } + } + + // This if statement checks if the user entered a youtube url, it can be any kind of youtube url + if (query.match(/^(http(s)?:\/\/)?((w){3}.)?youtu(be|.be)?(\.com)?\/.+/)) { + query = query + .replace(/(>|<)/gi, '') + .split(/(vi\/|v=|\/v\/|youtu\.be\/|\/embed\/)/); + const id = query[2].split(/[^0-9a-z_\-]/i)[0]; + const video = await youtube.getVideoByID(id).catch(function () { + return msg.say( + 'There was a problem getting the video you provided. ' + emoji.random() + ); + }); + // // can be uncommented if you don't want the bot to play live streams + // if (video.raw.snippet.liveBroadcastContent === 'live') { + // return msg.say("I don't support live streams!"); + // } + // // can be uncommented if you don't want the bot to play videos longer than 1 hour + // if (video.duration.hours !== 0) { + // return msg.say('I cannot play videos longer than 1 hour'); + // } + // // can be uncommented if you want to limit the queue + // if (msg.guild.musicData.queue.length > 10) { + // return msg.say( + // 'There are too many songs in the queue already, skip or wait a bit' + // ); + // } + msg.guild.musicData.queue.push( + this.constructSongObj(video, voiceChannel) + ); + if ( + msg.guild.musicData.isPlaying == false || + typeof msg.guild.musicData.isPlaying == 'undefined' + ) { + msg.guild.musicData.isPlaying = true; + return this.playSong(msg.guild.musicData.queue, msg); + } else if (msg.guild.musicData.isPlaying == true) { + return msg.say(`${video.title} added to queue. ` + emoji.random()); + } + } + + // if user provided a song/video name + const videos = await youtube.searchVideos(query, 5).catch(function () { + return msg.say( + 'There was a problem searching the video you requested. ' + emoji.random() + ); + }); + if (videos.length < 5) { + return msg.say( + `There was some trouble finding what you were looking for, please try again or be more specific. ` + emoji.random() + ); + } + const vidNameArr = []; + for (let i = 0; i < videos.length; i++) { + vidNameArr.push(`${i + 1}: ${videos[i].title}`); + } + vidNameArr.push('exit'); + const embed = new MessageEmbed() + .setColor(0xFFCC4D) + .setTitle('Please choose a song (1 to 5) ' + emoji.random()) + .addField(``, '**Song #**' + vidNameArr[0]) + .addField(``, '**Song #**' + vidNameArr[1]) + .addField(``, '**Song #**' + vidNameArr[2]) + .addField(``, '**Song #**' + vidNameArr[3]) + .addField(``, '**Song #**' + vidNameArr[4]) + .addField(``, '**Exit selection**: ' + 'exit'); + var songEmbed = await msg.channel.send({ + embed + }); + var that = this; + msg.channel + .awaitMessages( + function (msg) { + return (msg.content > 0 && msg.content < 6) || msg.content === 'exit'; + }, { + max: 1, + time: 60000, + errors: ['time'] + } + ) + .then(function (response) { + const videoIndex = parseInt(response.first().content); + if (response.first().content === 'exit') return songEmbed.delete(); + youtube + .getVideoByID(videos[videoIndex - 1].id) + .then(function (video) { + // // can be uncommented if you don't want the bot to play live streams + // if (video.raw.snippet.liveBroadcastContent === 'live') { + // songEmbed.delete(); + // return msg.say("I don't support live streams!"); + // } + + // // can be uncommented if you don't want the bot to play videos longer than 1 hour + // if (video.duration.hours !== 0) { + // songEmbed.delete(); + // return msg.say('I cannot play videos longer than 1 hour'); + // } + + // // can be uncommented if you don't want to limit the queue + // if (msg.guild.musicData.queue.length > 10) { + // songEmbed.delete(); + // return msg.say( + // 'There are too many songs in the queue already, skip or wait a bit' + // ); + // } + msg.guild.musicData.queue.push( + that.constructSongObj(video, voiceChannel) + ); + if (msg.guild.musicData.isPlaying == false) { + msg.guild.musicData.isPlaying = true; + if (songEmbed) { + songEmbed.delete(); + } + that.playSong(msg.guild.musicData.queue, msg); + } else if (msg.guild.musicData.isPlaying == true) { + if (songEmbed) { + songEmbed.delete(); + } + return msg.say(`${video.title} added to queue. ` + emoji.random()); + } + }) + .catch(function () { + if (songEmbed) { + songEmbed.delete(); + } + return msg.say( + 'An error has occured when trying to get the video ID from YouTube. ' + emoji.random() + ); + }); + }) + .catch(function () { + if (songEmbed) { + songEmbed.delete(); + } + return msg.say( + 'Try again and enter a number between 1 and 5 or exit. ' + emoji.random() + ); + }); + } + playSong(queue, msg) { + const classThis = this; // use classThis instead of 'this' because of lexical scope below + queue[0].voiceChannel + .join() + .then(function (connection) { + const dispatcher = connection + .play( + ytdl(queue[0].url, { + quality: 'highestaudio', + highWaterMark: 1024 * 1024 * 10 + }) + ) + .on('start', function () { + msg.guild.musicData.songDispatcher = dispatcher; + const volume = 100 / 100; + msg.guild.musicData.volume = volume; + dispatcher.setVolume(msg.guild.musicData.volume); + const videoEmbed = new MessageEmbed() + .setThumbnail(queue[0].thumbnail) + .setColor(0xFFCC4D) + .addField('Now playing:', queue[0].title) + .addField('Duration:', queue[0].duration); + if (queue[1]) videoEmbed.addField('Next song:', queue[1].title); + msg.say(videoEmbed); + msg.guild.musicData.nowPlaying = queue[0]; + return queue.shift(); + }) + .on('finish', function () { + if (queue.length >= 1) { + return classThis.playSong(queue, msg); + } else { + msg.guild.musicData.isPlaying = false; + msg.guild.musicData.nowPlaying = null; + msg.guild.musicData.songDispatcher = null; + return msg.guild.me.voice.channel.leave(); + } + }) + .on('error', function (e) { + msg.say('Can\'t play song. ' + emoji.random()); + console.error(e); + msg.guild.musicData.queue.length = 0; + msg.guild.musicData.isPlaying = false; + msg.guild.musicData.nowPlaying = null; + msg.guild.musicData.songDispatcher = null; + return msg.guild.me.voice.channel.leave(); + }); + }) + .catch(function (e) { + console.error(e); + return msg.guild.me.voice.channel.leave(); + }); + } + constructSongObj(video, voiceChannel) { + let duration = this.formatDuration(video.duration); + if (duration == '00:00') duration = 'Live Stream'; + return { + url: `https://www.youtube.com/watch?v=${video.raw.id}`, + title: video.title, + duration, + thumbnail: video.thumbnails.high.url, + voiceChannel + }; + } + // prettier-ignore + formatDuration(durationObj) { + const duration = `${durationObj.hours ? (durationObj.hours + ':') : ''}${ + durationObj.minutes ? durationObj.minutes : '00' + }:${ + (durationObj.seconds < 10) + ? ('0' + durationObj.seconds) + : (durationObj.seconds + ? durationObj.seconds + : '00') + }`; + return duration; + } +};
\ No newline at end of file diff --git a/src/commands/voice/psycho.ts b/src/commands/voice/psycho.ts new file mode 100644 index 0000000..827c00a --- /dev/null +++ b/src/commands/voice/psycho.ts @@ -0,0 +1,198 @@ +import ytdl from 'ytdl-core'; +import { Command } from 'discord.js-commando'; +import { MessageEmbed, Message } from 'discord.js'; +import Youtube from 'simple-youtube-api'; +//const { youtubeAPI } = require('../../config.json'); +import config from '../../config.json'; +const youtube = new Youtube(config['yt-api-key']); +import emoji from 'emoji-random'; + +module.exports = class PsychoVoice extends Command { + constructor(client) { + super(client, { + name: 'psycho', + group: 'voice', + memberName: 'psycho', + description: 'Plays Psycho by Mase.', + guildOnly: true, + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + examples: ['uwu!psycho'] + }); + } + async run(msg: Message, { query }) { + const voiceChannel = msg.member.voice.channel; + if (!voiceChannel) return msg.say('Please join a channel and try again. ' + emoji.random()); + + const id = 'fnd_HSmAODs'; + const video = await youtube.getVideoByID(id).catch(function () { + return msg.say( + 'There was a problem getting the video you provided. ' + emoji.random() + ); + }); + // // can be uncommented if you don't want the bot to play live streams + // if (video.raw.snippet.liveBroadcastContent === 'live') { + // return msg.say("I don't support live streams!"); + // } + // // can be uncommented if you don't want the bot to play videos longer than 1 hour + // if (video.duration.hours !== 0) { + // return msg.say('I cannot play videos longer than 1 hour'); + // } + // // can be uncommented if you want to limit the queue + // if (msg.guild.musicData.queue.length > 10) { + // return msg.say( + // 'There are too many songs in the queue already, skip or wait a bit' + // ); + // } + msg.guild.musicData.queue.push( + this.constructSongObj(video, voiceChannel) + ); + if ( + msg.guild.musicData.isPlaying == false || + typeof msg.guild.musicData.isPlaying == 'undefined' + ) { + msg.guild.musicData.isPlaying = true; + return this.playSong(msg.guild.musicData.queue, msg); + } else if (msg.guild.musicData.isPlaying == true) { + return msg.say(`${video.title} added to queue. ` + emoji.random()); + } + + var that = this; + msg.channel + .awaitMessages( + function (msg) { + return (msg.content > 0 && msg.content < 6) || msg.content === 'exit'; + }, { + max: 1, + time: 60000, + errors: ['time'] + } + ) + .then(function (response) { + const videoIndex = parseInt(response.first().content); + if (response.first().content === 'exit') return songEmbed.delete(); + youtube + .getVideoByID(videos[videoIndex - 1].id) + .then(function (video) { + // // can be uncommented if you don't want the bot to play live streams + // if (video.raw.snippet.liveBroadcastContent === 'live') { + // songEmbed.delete(); + // return msg.say("I don't support live streams!"); + // } + + // // can be uncommented if you don't want the bot to play videos longer than 1 hour + // if (video.duration.hours !== 0) { + // songEmbed.delete(); + // return msg.say('I cannot play videos longer than 1 hour'); + // } + + // // can be uncommented if you don't want to limit the queue + // if (msg.guild.musicData.queue.length > 10) { + // songEmbed.delete(); + // return msg.say( + // 'There are too many songs in the queue already, skip or wait a bit' + // ); + // } + msg.guild.musicData.queue.push( + that.constructSongObj(video, voiceChannel) + ); + if (msg.guild.musicData.isPlaying == false) { + msg.guild.musicData.isPlaying = true; + if (songEmbed) { + songEmbed.delete(); + } + that.playSong(msg.guild.musicData.queue, msg); + } else if (msg.guild.musicData.isPlaying == true) { + if (songEmbed) { + songEmbed.delete(); + } + return msg.say(`${video.title} added to queue. ` + emoji.random()); + } + }) + .catch(function () { + if (songEmbed) { + songEmbed.delete(); + } + return msg.say( + 'An error has occured when trying to get the video ID from YouTube. ' + emoji.random() + ); + }); + }); + } + playSong(queue, msg) { + const classThis = this; // use classThis instead of 'this' because of lexical scope below + queue[0].voiceChannel + .join() + .then(function (connection) { + const dispatcher = connection + .play( + ytdl(queue[0].url, { + quality: 'highestaudio', + highWaterMark: 1024 * 1024 * 10 + }) + ) + .on('start', function () { + msg.guild.musicData.songDispatcher = dispatcher; + const volume = 100 / 100; + msg.guild.musicData.volume = volume; + dispatcher.setVolume(msg.guild.musicData.volume); + const videoEmbed = new MessageEmbed() + .setThumbnail(queue[0].thumbnail) + .setColor(0xFFCC4D) + .addField('Now playing:', queue[0].title) + .addField('Duration:', queue[0].duration); + if (queue[1]) videoEmbed.addField('Next song:', queue[1].title); + msg.say(videoEmbed); + msg.guild.musicData.nowPlaying = queue[0]; + return queue.shift(); + }) + .on('finish', function () { + if (queue.length >= 1) { + return classThis.playSong(queue, msg); + } else { + msg.guild.musicData.isPlaying = false; + msg.guild.musicData.nowPlaying = null; + msg.guild.musicData.songDispatcher = null; + return msg.guild.me.voice.channel.leave(); + } + }) + .on('error', function (e) { + msg.say('Can\'t play song ' + emoji.random()); + console.error(e); + msg.guild.musicData.queue.length = 0; + msg.guild.musicData.isPlaying = false; + msg.guild.musicData.nowPlaying = null; + msg.guild.musicData.songDispatcher = null; + return msg.guild.me.voice.channel.leave(); + }); + }) + .catch(function (e) { + console.error(e); + return msg.guild.me.voice.channel.leave(); + }); + } + constructSongObj(video, voiceChannel) { + let duration = this.formatDuration(video.duration); + if (duration == '00:00') duration = 'Live Stream'; + return { + url: `https://www.youtube.com/watch?v=${video.raw.id}`, + title: video.title, + duration, + thumbnail: video.thumbnails.high.url, + voiceChannel + }; + } + // prettier-ignore + formatDuration(durationObj) { + const duration = `${durationObj.hours ? (durationObj.hours + ':') : ''}${ + durationObj.minutes ? durationObj.minutes : '00' + }:${ + (durationObj.seconds < 10) + ? ('0' + durationObj.seconds) + : (durationObj.seconds + ? durationObj.seconds + : '00') + }`; + return duration; + } +};
\ No newline at end of file diff --git a/src/commands/voice/queue.js b/src/commands/voice/queue.js new file mode 100644 index 0000000..59fce1a --- /dev/null +++ b/src/commands/voice/queue.js @@ -0,0 +1,51 @@ +const { Command } = require('discord.js-commando'); +const { MessageEmbed } = require('discord.js'); +const emoji = require('emoji-random'); + +module.exports = class QueueVoice extends Command { + constructor(client) { + super(client, { + name: 'queue', + aliases: [ + 'q', + 'song-list', + 'next-songs', + 'songlist', + 'nextsongs', + 'nextsong', + 'next-song' + ], + group: 'voice', + memberName: 'queue', + description: 'Displays the current queue.', + guildOnly: true, + examples: [ + 'uwu!queue', + 'uwu!q', + 'uwu!songlist', + 'uwu!song-list', + 'uwu!nextsong', + 'uwu!next-song', + 'uwu!nextsongs', + 'uwu!next-songs' + ], + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + }); + } + run(msg) { + if (msg.guild.musicData.queue.length == 0) + return msg.say('There aren\'t any songs in the current queue. ' + emoji.random()); + const titleArray = []; + msg.guild.musicData.queue.map(obj => { + titleArray.push(obj.title); + }); + let queueEmbed = new MessageEmbed() + .setColor(0xFFCC4D) + .setTitle('Music Queue ' + emoji.random()); + for (let i = 0; i < titleArray.length; i++) { + queueEmbed.addField(``, `**${i + 1}**: ` + `${titleArray[i]}`); + } + return msg.say(queueEmbed); + } +};
\ No newline at end of file diff --git a/src/commands/voice/remove.js b/src/commands/voice/remove.js new file mode 100644 index 0000000..34a30de --- /dev/null +++ b/src/commands/voice/remove.js @@ -0,0 +1,41 @@ +const { Command } = require('discord.js-commando'); +const emoji = require('emoji-random'); + +module.exports = class RemoveVoice extends Command { + constructor(client) { + super(client, { + name: 'remove', + group: 'voice', + memberName: 'remove', + description: 'Removes a song from the current queue.', + guildOnly: true, + args: [ + { + key: 'songNumber', + prompt: 'What song would you like to remove from the current queue?', + type: 'integer' + } + ], + examples: ['uwu!remove 2'], + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + }); + } + run(msg, { songNumber }) { + if (songNumber < 1 && songNumber >= msg.guild.musicData.queue.length) { + return msg.reply('Please enter a valid song. ' + emoji.random()); + } + var voiceChannel = msg.member.voice.channel; + if (!voiceChannel) return msg.reply('Please join a channel and try again. ' + emoji.random()); + + if ( + typeof msg.guild.musicData.songDispatcher == 'undefined' || + msg.guild.musicData.songDispatcher == null + ) { + return msg.reply('There isn\'t any audio playing right now. ' + emoji.random()); + } + + msg.guild.musicData.queue.splice(songNumber - 1, 1); + return msg.say(`Removed song **#${songNumber}** from current queue. ` + emoji.random()); + } +};
\ No newline at end of file diff --git a/src/commands/voice/resume.js b/src/commands/voice/resume.js new file mode 100644 index 0000000..1b28b28 --- /dev/null +++ b/src/commands/voice/resume.js @@ -0,0 +1,32 @@ +const { Command } = require('discord.js-commando'); +const emoji = require('emoji-random'); + +module.exports = class ResumeVoice extends Command { + constructor(client) { + super(client, { + name: 'resume', + group: 'voice', + memberName: 'resume', + description: 'Resumes audio of previously paused.', + guildOnly: true, + examples: ['uwu!resume'], + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + }); + } + run(msg) { + var voiceChannel = msg.member.voice.channel; + if (!voiceChannel) return msg.reply('Please join a channel and try again. ') + emoji.random(); + + if ( + typeof msg.guild.musicData.songDispatcher == 'undefined' || + msg.guild.musicData.songDispatcher == null + ) { + return msg.reply('There isn\'t any audio playing right now. ' + emoji.random()); + } + + msg.say('Song resumed :play_pause:'); + + msg.guild.musicData.songDispatcher.resume(); + } +};
\ No newline at end of file diff --git a/src/commands/voice/shuffle.js b/src/commands/voice/shuffle.js new file mode 100644 index 0000000..3183f87 --- /dev/null +++ b/src/commands/voice/shuffle.js @@ -0,0 +1,53 @@ +const { Command } = require('discord.js-commando'); +const { MessageEmbed } = require('discord.js'); +const emoji = require('emoji-random'); + +module.exports = class ShuffleVoice extends Command { + constructor(client) { + super(client, { + name: 'shuffle', + group: 'voice', + memberName: 'shuffle', + description: 'Shuffles the current queue.', + guildOnly: true, + examples: ['uwu!shuffle'], + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + }); + } + run(msg) { + var voiceChannel = msg.member.voice.channel; + if (!voiceChannel) return msg.reply('Please join channel and try again. ' + emoji.random()); + + if ( + typeof msg.guild.musicData.songDispatcher == 'undefined' || + msg.guild.musicData.songDispatcher == null + ) { + return msg.reply('There isn\'t any audio playing right now. ' + emoji.random()); + } + + if (msg.guild.musicData.queue.length < 1) + return msg.say('There aren\'t any songs in the current queue. ' + emoji.random()); + + shuffleQueue(msg.guild.musicData.queue); + + const titleArray = []; + msg.guild.musicData.queue.map(obj => { + titleArray.push(obj.title); + }); + var queueEmbed = new MessageEmbed() + .setColor(0xF97DAE) + .setTitle('New Music Queue ' + emoji.random()); + for (let i = 0; i < titleArray.length; i++) { + queueEmbed.addField(`${i + 1}:`, `${titleArray[i]}`); + } + return msg.say(queueEmbed); + } +}; + +function shuffleQueue(queue) { + for (let i = queue.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [queue[i], queue[j]] = [queue[j], queue[i]]; + } +}
\ No newline at end of file diff --git a/src/commands/voice/skip.js b/src/commands/voice/skip.js new file mode 100644 index 0000000..8638291 --- /dev/null +++ b/src/commands/voice/skip.js @@ -0,0 +1,29 @@ +const { Command } = require('discord.js-commando'); +const emoji = require('emoji-random'); + +module.exports = class SkipVoice extends Command { + constructor(client) { + super(client, { + name: 'skip', + group: 'voice', + memberName: 'skip', + description: 'Skips one song ahead in the current queue.', + guildOnly: true, + examples: ['uwu!skip'], + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + }); + } + run(msg) { + const voiceChannel = msg.member.voice.channel; + if (!voiceChannel) return msg.reply('Please join a channel and try again. ' + emoji.random()); + + if ( + typeof msg.guild.musicData.songDispatcher == 'undefined' || + msg.guild.musicData.songDispatcher == null + ) { + return msg.reply('There isn\'t any audio playing right now. ' + emoji.random()); + } + msg.guild.musicData.songDispatcher.end(); + } +};
\ No newline at end of file diff --git a/src/commands/voice/skipall.js b/src/commands/voice/skipall.js new file mode 100644 index 0000000..e981f46 --- /dev/null +++ b/src/commands/voice/skipall.js @@ -0,0 +1,44 @@ +const { Command } = require('discord.js-commando'); +const emoji = require('emoji-random'); + +module.exports = class SkipAllVoice extends Command { + constructor(client) { + super(client, { + name: 'skipall', + aliases: [ + 'endqueue', + 'endq', + 'skipqueue', + 'skipq' + ], + group: 'voice', + memberName: 'skipall', + description: 'Removes all the songs from current queue.', + guildOnly: true, + examples: [ + 'uwu!endqueue', + 'uwu!endq', + 'uwu!skipqueue', + 'uwu!skipq' + ], + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + }); + } + run(msg) { + var voiceChannel = msg.member.voice.channel; + if (!voiceChannel) return msg.reply('Please join a channel and try again. ' + emoji.random()); + + if ( + typeof msg.guild.musicData.songDispatcher == 'undefined' || + msg.guild.musicData.songDispatcher == null + ) { + return msg.reply('There isn\'t any audio playing right now. ' + emoji.random()); + } + if (!msg.guild.musicData.queue) + return msg.say('There aren\'t any songs in the current queue. ' + emoji.random()); + msg.guild.musicData.songDispatcher.end(); + msg.guild.musicData.queue.length = 0; // clear queue + return; + } +};
\ No newline at end of file diff --git a/src/commands/voice/skipto.js b/src/commands/voice/skipto.js new file mode 100644 index 0000000..f43d56c --- /dev/null +++ b/src/commands/voice/skipto.js @@ -0,0 +1,43 @@ +const { Command } = require('discord.js-commando'); +const emoji = require('emoji-random'); + +module.exports = class SkipToVoice extends Command { + constructor(client) { + super(client, { + name: 'skipto', + group: 'voice', + memberName: 'skipto', + description: 'Skip to a certain song in the current queue.', + guildOnly: true, + args: [{ + key: 'songNumber', + prompt: 'What song would you like to skip to in the current queue?', + type: 'integer' + }], + examples: ['uwu!skipto 5'], + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + }); + } + run(msg, { songNumber }) { + if (songNumber < 1 && songNumber >= msg.guild.musicData.queue.length) { + return msg.reply('Please enter a valid song. ' + emoji.random()); + } + var voiceChannel = msg.member.voice.channel; + if (!voiceChannel) return msg.reply('Please join channel and try again. ' + emoji.random()); + + if ( + typeof msg.guild.musicData.songDispatcher == 'undefined' || + msg.guild.musicData.songDispatcher == null + ) { + return msg.reply('There isn\'t any audio playing right now. ' + emoji.random()); + } + + if (msg.guild.musicData.queue < 1) + return msg.reply('There aren\'t any songs in the current queue. ' + emoji.random()); + + msg.guild.musicData.queue.splice(0, songNumber - 1); + msg.guild.musicData.songDispatcher.end(); + return; + } +};
\ No newline at end of file diff --git a/src/commands/voice/volume.js b/src/commands/voice/volume.js new file mode 100644 index 0000000..96a6de3 --- /dev/null +++ b/src/commands/voice/volume.js @@ -0,0 +1,45 @@ +const { Command } = require('discord.js-commando'); +const emoji = require('emoji-random'); + +module.exports = class VolumeVoice extends Command { + constructor(client) { + super(client, { + name: 'volume', + aliases: ['vol'], + group: 'voice', + memberName: 'volume', + description: 'Changes volume of any currentaly playing audio.', + guildOnly: true, + args: [ + { + key: 'wantedVol', + prompt: 'What would volume you like? (1 to 200)', + type: 'integer', + validate: wantedVol => wantedVol >= 1 && wantedVol <= 200 + } + ], + examples: [ + 'uwu!volume 20', + 'uwu!vol 50' + ], + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + }); + } + run(msg, { wantedVol }) { + var voiceChannel = msg.member.voice.channel; + if (!voiceChannel) return msg.reply('Please join a channel and try again. ' + emoji.random()); + + if ( + typeof msg.guild.musicData.songDispatcher == 'undefined' || + msg.guild.musicData.songDispatcher == null + ) { + return msg.reply('There isn\'t any audio playing right now. ' + emoji.random()); + } + + const volume = wantedVol / 100; + msg.guild.musicData.volume = volume; + msg.guild.musicData.songDispatcher.setVolume(volume); + msg.reply(`Volume is now: **${wantedVol}%**. ` + emoji.random()); + } +};
\ No newline at end of file diff --git a/src/config.json b/src/config.json new file mode 100644 index 0000000..16bac59 --- /dev/null +++ b/src/config.json @@ -0,0 +1,4 @@ +{ + "secret":"Njk5NDczMjYzOTk4MjcxNDg5.XpU5oQ.btZuxVudhNllSQY6CxrXXtMJm9A", + "yt-api-key":"AIzaSyCeG1lQAeInv4vjFv_eTL9IFAFNdQC9Nk8" +}
\ No newline at end of file |