Adding tons of stuff
This commit is contained in:
parent
738d11854c
commit
244349054b
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
This file is ignored by the bot's command loader because of the underscore at the start of the file name. The purpose of this file is for developers to get a headstart on implementing their own commands.
|
||||
The purpose of this file is for developers to get a headstart on implementing their own commands.
|
||||
Developers, remember to insert all three exports; these are required. Your command won't load if any of these are missing.
|
||||
*/
|
||||
|
|
@ -1,236 +1,30 @@
|
|||
const ytdl = require("ytdl-core-discord");
|
||||
|
||||
async function play(connection, message) {
|
||||
var server = client.servers[message.guild.id];
|
||||
|
||||
server.dispatcher = connection.play(await ytdl(server.queue[0]), {filter: "audioonly"}, {type: opus});
|
||||
|
||||
server.queue.shift();
|
||||
|
||||
server.dispatcher.on("end", function() {
|
||||
if(server.queue[0]) play(connection, message);
|
||||
else connection.disconnect();
|
||||
});
|
||||
}
|
||||
const fetch = require("node-fetch");
|
||||
const { URLSearchParams } = require("url");
|
||||
|
||||
exports.run = async (client, message, args, level) => {
|
||||
if(!args[0]) return message.reply("please provide a valid URL.");
|
||||
if(!message.member.voice.channel) return message.reply("you must be in a voice channel to use this command.");
|
||||
if (!message.member || !message.member.voice.channel) return message.reply("you must be in a voice channel to use this command.");
|
||||
|
||||
if(!client.servers[message.guild.id]) client.servers[message.guild.id] = {
|
||||
queue: []
|
||||
};
|
||||
|
||||
var server = client.servers[message.guild.id];
|
||||
const track = args.join(" ");
|
||||
const [song] = await getSongs(`ytsearch: ${track}`);
|
||||
if (!song) return message.reply("no songs were found in your query; try again or be more specific.");
|
||||
|
||||
server.queue.push(args[0]);
|
||||
const player = await client.player.join({
|
||||
guild: message.guild.id,
|
||||
channel: message.member.voice.channel.id,
|
||||
host: client.player.nodes.first().host
|
||||
}, { selfdeaf: true });
|
||||
|
||||
if(!message.guild.voiceConnection) message.member.voice.channel.join().then(function(connection) {
|
||||
play(connection, message);
|
||||
if (!player) return message.reply("I couldn't join the voice channel.");
|
||||
|
||||
player.play(song.track);
|
||||
|
||||
player.once("error", console.error);
|
||||
player.once("end", async data => {
|
||||
if (data.reason === "REPLACED") return;
|
||||
message.channel.send("Song has ended.");
|
||||
await client.player.leave(message.guild.id);
|
||||
});
|
||||
|
||||
/*
|
||||
const queue = client.queue;
|
||||
const serverQueue = client.queue.get(message.guild.id);
|
||||
|
||||
const voiceChannel = message.member.voiceChannel;
|
||||
if(!voiceChannel) return message.reply("you need to be in a voice channel to use this command!");
|
||||
|
||||
const permissions = voiceChannel.permissionsFor(client.user);
|
||||
if(!permissions.has("CONNECT") || !permissions.has("SPEAK")) return message.reply("I don't have the valid permissions to connect and speak in the channel you're in!");
|
||||
|
||||
const songInfo = await ytdl.getInfo(args[0]);
|
||||
const song = {
|
||||
title: songInfo.title,
|
||||
url: songInfo.video_url
|
||||
};
|
||||
|
||||
if(!serverQueue) {
|
||||
const queueConstruct = {
|
||||
textChannel: message.channel,
|
||||
voiceChannel: voiceChannel,
|
||||
connection: null,
|
||||
songs: [],
|
||||
volume: 5,
|
||||
playing: true
|
||||
};
|
||||
|
||||
queue.set(message.guild.id, queueConstruct);
|
||||
queueConstruct.songs.push(song);
|
||||
|
||||
try {
|
||||
var connection = await voiceChannel.join();
|
||||
queueConstruct.connection = connection;
|
||||
this.play(message, queueConstruct.songs[0]);
|
||||
} catch(err) {
|
||||
client.logger.error(err);
|
||||
queue.delete(message.guild.id);
|
||||
return message.channel.send(`Uh oh! Looks like I hit a snag. Here's the error that Node picked up: \`${err}\``);
|
||||
}
|
||||
} else {
|
||||
serverQueue.songs.push(song);
|
||||
return message.channel.send(`**${song.title}** has been added to the queue!`);
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
const query = args[0];
|
||||
|
||||
var voiceChannel = message.author.voiceChannel;
|
||||
if (!voiceChannel) return message.reply("you need to be in a voice channel to use this command!");
|
||||
|
||||
if(query.match(/^(?!.*\?.*\bv=)https:\/\/www\.youtube\.com\/.*\?.*\blist=.*%/)) {
|
||||
try {
|
||||
const playlist = await youtube.getPlaylist(query);
|
||||
const videosObj = await playlist.getVideos();
|
||||
|
||||
for (let i = 0; i < videosObj.length; i++) {
|
||||
const video = await videosObj[i].fetch();
|
||||
|
||||
const url = `https://www.youtube.com/watch?v=${video.raw.id}`;
|
||||
const title = video.raw.snippet.title;
|
||||
let duration = this.formatDuration(video.duration);
|
||||
const thumbnail = video.thumbnails.high.url;
|
||||
if (duration == "00:00") duration = "Live Stream";
|
||||
|
||||
const song = {
|
||||
url,
|
||||
title,
|
||||
duration,
|
||||
thumbnail,
|
||||
voiceChannel
|
||||
};
|
||||
|
||||
message.guild.musicData.push(song);
|
||||
}
|
||||
if(message.guild.musicData.isPlaying == false) {
|
||||
message.guild.musicData.isPlaying == true;
|
||||
return this.playSong(message.guild.musicData.queue, message);
|
||||
} else if (message.guild.musicData.isPlaying == true) {
|
||||
return message.channel.send(`Playlist - :musical_note: ${playlist.title} :musical_note: has been added to the queue.`);
|
||||
}
|
||||
} catch (err) {
|
||||
client.logger.error(err);
|
||||
return message.reply("that playlist is either private or doesn't exist!");
|
||||
}
|
||||
}
|
||||
if(query.match(/^(http(s)?:\/\/)?((w){3}.)?youtu(be|.be)?(\.com)?\/.+/)) {
|
||||
const url = query;
|
||||
try {
|
||||
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);
|
||||
const title = video.title;
|
||||
let duration = this.formatDuration(video.duration);
|
||||
const thumbnail = video.thumbnails.high.url;
|
||||
if(duration == "00:00") duration = "Live Stream";
|
||||
const song = {
|
||||
url,
|
||||
title,
|
||||
duration,
|
||||
thumbnail,
|
||||
voiceChannel
|
||||
};
|
||||
message.guild.musicData.queue.push(song);
|
||||
if(message.guild.musicData.isPlaying == false || typeof message.guild.musicData.isPlaying == "undefined") {
|
||||
message.guild.musicData.isPlaying = true;
|
||||
return this.playSong(message.guild.musicData.queue, message);
|
||||
} else if(message.guild.musicData.isPlaying == true) {
|
||||
return message.channel.send(`${song.title} has been added to the queue.`);
|
||||
}
|
||||
} catch (err) {
|
||||
client.logger.error(err);
|
||||
return message.channel.send("Uh oh! Looks like I hit a snag. Ask a bot administrator to check the console.");
|
||||
}
|
||||
}
|
||||
try {
|
||||
const videos = await youtube.searchVideos(query, 5);
|
||||
if(videos.length < 5) {
|
||||
return message.reply("it seems I had some trouble finding what you requested. Please try again or be more specific.");
|
||||
}
|
||||
const vidNameArr = [];
|
||||
for(let i = 0; i < videos.length; i++) {
|
||||
vidNameArr.push(`${i + 1}: ${videos[i].title}`);
|
||||
}
|
||||
vidNameArr.push("exit");
|
||||
|
||||
const embed = new client.embed("Top 5 songs found", "Please select a song from the list below.", [
|
||||
{
|
||||
name: "**__Song 1__**",
|
||||
value: vidNameArr[0]
|
||||
}
|
||||
{
|
||||
name: "**__Song 2__**",
|
||||
value: vidNameArr[1]
|
||||
}
|
||||
{
|
||||
name: "**__Song 3__**",
|
||||
value: vidNameArr[2]
|
||||
}
|
||||
{
|
||||
name: "**__Song 4__**",
|
||||
value: vidNameArr[3]
|
||||
}
|
||||
{
|
||||
name: "**__Song 5__**",
|
||||
value: vidNameArr[4]
|
||||
}
|
||||
],
|
||||
{
|
||||
author: message.author.tag,
|
||||
authorIcon: message.author.avatarURL
|
||||
});
|
||||
var songEmbed = await message.channel.send({ embed });
|
||||
|
||||
try {
|
||||
var response = await message.channel.awaitMessages(
|
||||
msg => (msg.content > 0 && msg.content < 6) || msg.content === "exit",
|
||||
{
|
||||
max: 1,
|
||||
maxProcessed: 1,
|
||||
time: 20000,
|
||||
errors: ["time"]
|
||||
}
|
||||
);
|
||||
|
||||
var videoIndex = parseInt(response.first().content)
|
||||
} catch (err) {
|
||||
client.logger.error(err);
|
||||
songEmbed.delete();
|
||||
return message.reply("Please try again, and enter a valid number from 1 to 5.\n*(Hint: you can exit this menu by responding with \`exit\`)*");
|
||||
}
|
||||
const url = `https://www.youtube.com/watch?v=${video.raw.id}`;
|
||||
const title = video.title;
|
||||
let duration = this.formatDuration(video.duration);
|
||||
const thumbnail = video.thumbnails.high.url;
|
||||
if(duration == "00:00") duration = "Live Stream";
|
||||
const song = {
|
||||
url,
|
||||
title,
|
||||
duration,
|
||||
thumbnail,
|
||||
voiceChannel
|
||||
};
|
||||
|
||||
message.guild.musicData.queue.push(song);
|
||||
|
||||
if(message.guild.musicData.isPlaying == false) {
|
||||
message.guild.musicData.isPlaying = true;
|
||||
songEmbed.delete();
|
||||
this.playSong(message.guild.musicData.queue, message);
|
||||
} else if(message.guild.musicData.isPlaying == true) {
|
||||
songEmbed.delete();
|
||||
return message.channel.send(`${song.title} has been added to queue.`);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
if (songEmbed) {
|
||||
songEmbed.delete();
|
||||
}
|
||||
return message.channel.send("Something went wrong playing one of the songs, is its source private?");
|
||||
}
|
||||
*/
|
||||
return message.reply(`Now playing: **${song.info.title}** by *${song.info.author}*`);
|
||||
};
|
||||
|
||||
exports.conf = {
|
||||
|
@ -247,96 +41,17 @@ exports.help = {
|
|||
usage: "play [url]"
|
||||
};
|
||||
|
||||
/*
|
||||
function play(message, song) {
|
||||
const queue = client.queue;
|
||||
const guild = message.guild;
|
||||
const serverQueue = queue.get(message.guild.id);
|
||||
function getSongs(search) {
|
||||
const node = client.player.nodes.first();
|
||||
|
||||
if (!song) {
|
||||
serverQueue.voiceChannel.leave();
|
||||
queue.delete(guild.id);
|
||||
return;
|
||||
}
|
||||
const params = new URLSearchParams();
|
||||
params.append("identifier", search);
|
||||
|
||||
const dispatcher = serverQueue.connection
|
||||
.playStream(ytdl(song.url, { fliter: "audioonly" }))
|
||||
.on("end", () => {
|
||||
console.log("Music ended!");
|
||||
serverQueue.songs.shift();
|
||||
this.play(message, serverQueue.songs[0]);
|
||||
})
|
||||
.on("error", error => {
|
||||
console.error(error);
|
||||
});
|
||||
dispatcher.setVolumeLogarithmic(serverQueue.volume / 5);
|
||||
};
|
||||
*/
|
||||
|
||||
/*
|
||||
function playSong(queue, message) {
|
||||
let voiceChannel;
|
||||
queue[0].voiceChannel
|
||||
.join()
|
||||
.then(connection => {
|
||||
const dispatcher = connection
|
||||
.play(
|
||||
ytdl(queue[0].url, {
|
||||
quality: "highestaudio",
|
||||
highWaterMark: 1024 * 1024 * 10
|
||||
})
|
||||
)
|
||||
.on("start", () => {
|
||||
message.guild.musicData.songDispatcher = dispatcher;
|
||||
voiceChannel = queue[0].voiceChannel;
|
||||
|
||||
const videoEmbed = client.embed("", "", [
|
||||
{
|
||||
name: "**__Now Playing__**",
|
||||
value: queue[0].title
|
||||
},
|
||||
{
|
||||
name: "**__Duration__**",
|
||||
value: queue[0].duration
|
||||
}
|
||||
],
|
||||
{
|
||||
thumbnail: queue[0].thumbnail
|
||||
});
|
||||
if (queue[1]) videoEmbed.addField("Next Up:", queue[1].title);
|
||||
message.channel.send(videoEmbed);
|
||||
return queue.shift();
|
||||
})
|
||||
.on("finish", () => {
|
||||
if (queue.length >= 1) {
|
||||
return this.playSong(queue, message);
|
||||
} else {
|
||||
message.guild.musicData.isPlaying = false;
|
||||
return voiceChannel.leave();
|
||||
}
|
||||
})
|
||||
.on("error", e => {
|
||||
message.channel.send("I couldn't play that song!");
|
||||
console.error(e);
|
||||
return voiceChannel.leave();
|
||||
});
|
||||
})
|
||||
.catch(e => {
|
||||
console.error(e);
|
||||
return voiceChannel.leave();
|
||||
});
|
||||
}
|
||||
|
||||
function 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;
|
||||
}
|
||||
*/
|
||||
return fetch(`http://${node.host}:${node.port}/loadtracks?${params.toString()}`, { headers: { Authorization: node.password } })
|
||||
.then(res => res.json())
|
||||
.then(data => data.tracks)
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
return null;
|
||||
});
|
||||
}
|
|
@ -1,6 +1,28 @@
|
|||
const { PlayerManager, Player } = require("discord.js-lavalink");
|
||||
|
||||
module.exports = async client => {
|
||||
client.player = new PlayerManager(client, client.config.nodes, {
|
||||
user: client.user.id,
|
||||
shards: 0,
|
||||
Player: ExamplePlayer
|
||||
});
|
||||
|
||||
client.logger.log(`Looks like I'm ready! My tag is ${client.user.tag}, and I'm ready to serve ${client.users.cache.some(user => !user.bot).size} users in ${client.guilds.cache.size} ${client.guilds.cache.size > 1 ? "servers" : "server"}.`, "ready");
|
||||
|
||||
client.user.setActivity(`${client.users.cache.filter(user => !user.bot).size} humans | ${client.settings.get("default").prefix}help`, {type: "WATCHING"});
|
||||
client.user.setStatus("online");
|
||||
};
|
||||
|
||||
class ExamplePlayer extends Player {
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
|
||||
this.textChannel = null;
|
||||
|
||||
this.on("end", async data => {
|
||||
if (data.reason === "REPLACED" || data.reason === "STOPPED") return;
|
||||
await client.player.leave(this.id);
|
||||
await this.textChannel.send("Song has ended...");
|
||||
}).on("error", console.error);
|
||||
}
|
||||
}
|
67
index.js
67
index.js
|
@ -5,6 +5,10 @@ const { Structures } = require("discord.js");
|
|||
|
||||
const { promisify } = require("util");
|
||||
const readdir = promisify(require("fs").readdir);
|
||||
|
||||
const { readdirSync } = require("fs");
|
||||
const { sep } = require("path");
|
||||
|
||||
const Enmap = require("enmap");
|
||||
const path = require("path");
|
||||
|
||||
|
@ -17,47 +21,30 @@ client.commands = new Enmap();
|
|||
client.aliases = new Enmap();
|
||||
client.settings = new Enmap({name: "settings"});
|
||||
|
||||
/*
|
||||
Structures.extend("Guild", Guild => {
|
||||
class MusicGuild extends Guild {
|
||||
constructor(client, data) {
|
||||
super(client, data);
|
||||
this.musicData = {
|
||||
queue: [],
|
||||
isPlaying: false,
|
||||
songDispatcher: null
|
||||
};
|
||||
}
|
||||
}
|
||||
return MusicGuild;
|
||||
});
|
||||
*/
|
||||
|
||||
async function crawl(directory, filesArray) {
|
||||
const dirs = await readdir(directory, {
|
||||
withFileTypes: true
|
||||
});
|
||||
|
||||
for (let i = 0; i < dirs.length; i++) {
|
||||
const currentDir = dirs[i];
|
||||
const newPath = path.join(directory, currentDir.name);
|
||||
if (currentDir.isDirectory()) {
|
||||
await crawl(newPath, filesArray);
|
||||
}
|
||||
else {
|
||||
filesArray.push(newPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const init = async () => {
|
||||
let cmdFiles = []
|
||||
await crawl("commands",cmdFiles);
|
||||
client.logger.log(`Loading a total of ${cmdFiles.length} commands.`);
|
||||
cmdFiles.forEach(f => {
|
||||
if (!f.endsWith(".js") || f.startsWith("commands\\_")) return;
|
||||
const response = client.loadCommand(f);
|
||||
if (response) console.log(response);
|
||||
const dir = "./commands";
|
||||
|
||||
readdirSync(dir).forEach(dirs => {
|
||||
const commands = readdirSync(`${dir}${sep}${dirs}${sep}`).filter(files => files.endsWith(".js"));
|
||||
|
||||
for (const file of commands) {
|
||||
const pull = require(`${dir}/${dirs}/${file}`);
|
||||
if (pull.help && typeof (pull.help.name) === "string" && typeof (pull.help.category) === "string") {
|
||||
if (client.commands.get(pull.help.name)) return console.warn(`Two or more commands have the same name ${pull.help.name}.`);
|
||||
client.commands.set(pull.help.name, pull);
|
||||
client.logger.log(`Loaded command ${pull.help.name}.`);
|
||||
} else {
|
||||
client.logger.error(`Error loading command in ${dir}${dirs}. You're probably missing its help and configuration brackets.`);
|
||||
continue;
|
||||
}
|
||||
if (pull.help.aliases && typeof (pull.help.aliases) === "object") {
|
||||
pull.help.aliases.forEach(alias => {
|
||||
if (client.aliases.get(alias)) return client.logger.warn(`Two commands or more commands have the same aliases ${alias}`);
|
||||
client.aliases.set(alias, pull.help.name);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
const evtFiles = await readdir("./events/");
|
||||
|
|
|
@ -52,10 +52,10 @@ module.exports = (client) => {
|
|||
const messages = await modlog.fetchMessages({limit:5});
|
||||
|
||||
const log = messages.filter(m => m.author.id === client.user.id &&
|
||||
m.embeds[0] &&
|
||||
m.embeds[0].type === 'rich' &&
|
||||
m.embeds[0].footer &&
|
||||
m.embeds[0].footer.text.startsWith('Case')
|
||||
m.embeds[0] &&
|
||||
m.embeds[0].type === 'rich' &&
|
||||
m.embeds[0].footer &&
|
||||
m.embeds[0].footer.text.startsWith('Case')
|
||||
).first();
|
||||
|
||||
if (!log) return 1;
|
||||
|
@ -346,11 +346,13 @@ module.exports = (client) => {
|
|||
client.quoteRegex = input => `${input}`.replace(/[.?*+^$[\]\\(){}|-]/g, '\\$&');
|
||||
|
||||
client.fetchURL = (url, options = {}) => {
|
||||
options.headers = options.headers ? { ...options.headers, "User-Agent": client.user } : { "User-Agent": client.user };
|
||||
return fetch(url, options, options.type || "json").catch(error => {
|
||||
client.Logger.error(error);
|
||||
});
|
||||
}
|
||||
options.headers = options.headers ? { ...options.headers, "User-Agent": client.user } : { "User-Agent": client.user };
|
||||
return fetch(url, options, options.type || "json").catch(error => {
|
||||
client.Logger.error(error);
|
||||
});
|
||||
}
|
||||
|
||||
client.servers = {};
|
||||
client.nodes = [
|
||||
{ host: "localhost", port: 2333, password: "youshallnotpass" }
|
||||
];
|
||||
}
|
||||
|
|
|
@ -45,6 +45,11 @@
|
|||
"color-convert": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"async-limiter": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
|
||||
"integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
|
@ -224,6 +229,24 @@
|
|||
"ws": "^7.2.0"
|
||||
}
|
||||
},
|
||||
"discord.js-lavalink": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/discord.js-lavalink/-/discord.js-lavalink-2.2.3.tgz",
|
||||
"integrity": "sha512-HR7LJ8EhJ3iVeRmfjBOdvBA5/eO25ncbnZOn12x0Sj/JVFd0h5ClGi6w4giWPrnw8fDvCVxKl7+c0Y/6tLgBDQ==",
|
||||
"requires": {
|
||||
"ws": "^6.1.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"ws": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
|
||||
"integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==",
|
||||
"requires": {
|
||||
"async-limiter": "~1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"dom-serializer": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz",
|
||||
|
@ -590,6 +613,11 @@
|
|||
"resolved": "https://registry.npmjs.org/moment-duration-format/-/moment-duration-format-2.3.2.tgz",
|
||||
"integrity": "sha512-cBMXjSW+fjOb4tyaVHuaVE/A5TqkukDWiOfxxAjY+PEqmmBQlLwn+8OzwPiG3brouXKY5Un4pBjAeB6UToXHaQ=="
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"mute-stream": {
|
||||
"version": "0.0.7",
|
||||
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
|
||||
|
|
|
@ -27,11 +27,13 @@
|
|||
"dateformat": "^3.0.3",
|
||||
"discord-emoji": "^1.1.1",
|
||||
"discord.js": "github:discordjs/discord.js",
|
||||
"discord.js-lavalink": "^2.2.3",
|
||||
"enmap": "^5.0.0",
|
||||
"inquirer": "^6.3.1",
|
||||
"math-expression-evaluator": "^1.2.17",
|
||||
"moment": "^2.24.0",
|
||||
"moment-duration-format": "^2.3.2",
|
||||
"ms": "^2.1.2",
|
||||
"node-fetch": "^2.6.0",
|
||||
"opusscript": "0.0.7",
|
||||
"recrawl": "^2.0.0",
|
||||
|
|
Loading…
Reference in New Issue