diff --git a/assets/audio/fart2.ogg b/assets/audio/fart2.ogg new file mode 100644 index 0000000..1893fb5 Binary files /dev/null and b/assets/audio/fart2.ogg differ diff --git a/commands/general/reload.js b/commands/general/reload.js index 4b80916..ae94f17 100644 --- a/commands/general/reload.js +++ b/commands/general/reload.js @@ -15,7 +15,7 @@ class ReloadCommand extends Command { this.ipc.register("reloadFail", (message) => { this.ipc.unregister("reloadSuccess"); this.ipc.unregister("reloadFail"); - resolve(message); + resolve(message.msg.result); }); }); } diff --git a/commands/music/loop.js b/commands/music/loop.js index f1681cd..b8deeb6 100644 --- a/commands/music/loop.js +++ b/commands/music/loop.js @@ -6,7 +6,7 @@ class LoopCommand extends MusicCommand { if (!this.message.channel.guild) return "This command only works in servers!"; if (!this.message.member.voiceState.channelID) return "You need to be in a voice channel first!"; if (!this.message.channel.guild.members.get(this.client.user.id).voiceState.channelID) return "I'm not in a voice channel!"; - if (this.connection.host !== this.message.author.id) return "Only the current voice session host can loop the music!"; + if (this.connection.host !== this.message.author.id && !this.message.member.permissions.has("manageChannels")) return "Only the current voice session host can loop the music!"; const object = this.connection; object.loop = !object.loop; players.set(this.message.channel.guild.id, object); diff --git a/commands/music/pause.js b/commands/music/pause.js index 5fef5e3..a86556c 100644 --- a/commands/music/pause.js +++ b/commands/music/pause.js @@ -5,7 +5,7 @@ class PauseCommand extends MusicCommand { if (!this.message.channel.guild) return "This command only works in servers!"; if (!this.message.member.voiceState.channelID) return "You need to be in a voice channel first!"; if (!this.message.channel.guild.members.get(this.client.user.id).voiceState.channelID) return "I'm not in a voice channel!"; - if (this.connection.host !== this.message.author.id) return "Only the current voice session host can pause/resume the music!"; + if (this.connection.host !== this.message.author.id && !this.message.member.permissions.has("manageChannels")) return "Only the current voice session host can pause/resume the music!"; const player = this.connection.player; player.pause(!player.paused ? true : false); return `🔊 The player has been ${!player.paused ? "paused" : "resumed"}.`; diff --git a/commands/music/shuffle.js b/commands/music/shuffle.js new file mode 100644 index 0000000..a1f73e3 --- /dev/null +++ b/commands/music/shuffle.js @@ -0,0 +1,20 @@ +import { players } from "../../utils/soundplayer.js"; +import MusicCommand from "../../classes/musicCommand.js"; + +class ShuffleCommand extends MusicCommand { + async run() { + if (!this.message.channel.guild) return "This command only works in servers!"; + if (!this.message.member.voiceState.channelID) return "You need to be in a voice channel first!"; + if (!this.message.channel.guild.members.get(this.client.user.id).voiceState.channelID) return "I'm not in a voice channel!"; + if (this.connection.host !== this.message.author.id) return "Only the current voice session host can shuffle the music!"; + const object = this.connection; + object.shuffle = !object.shuffle; + players.set(this.message.channel.guild.id, object); + return object.shuffle ? "🔊 The player is now shuffling." : "🔊 The player is no longer shuffling."; + } + + static description = "Shuffles the music"; + static aliases = ["toggleshuffle"]; +} + +export default ShuffleCommand; \ No newline at end of file diff --git a/commands/music/stop.js b/commands/music/stop.js index 98d64a9..e72f5f8 100644 --- a/commands/music/stop.js +++ b/commands/music/stop.js @@ -6,7 +6,7 @@ class StopCommand extends MusicCommand { if (!this.message.channel.guild) return "This command only works in servers!"; if (!this.message.member.voiceState.channelID) return "You need to be in a voice channel first!"; if (!this.message.channel.guild.members.get(this.client.user.id).voiceState.channelID) return "I'm not in a voice channel!"; - if (this.connection.host !== this.message.author.id) return "Only the current voice session host can stop the music!"; + if (this.connection.host !== this.message.author.id && !this.message.member.permissions.has("manageChannels")) return "Only the current voice session host can stop the music!"; manager.leave(this.message.channel.guild.id); const connection = this.connection.player; connection.destroy(); diff --git a/commands/soundboard/fartreverb.js b/commands/soundboard/fartreverb.js new file mode 100644 index 0000000..15a2fb2 --- /dev/null +++ b/commands/soundboard/fartreverb.js @@ -0,0 +1,14 @@ +// shoutouts to dairyorange, you're a real one +import { play } from "../../utils/soundplayer.js"; +import MusicCommand from "../../classes/musicCommand.js"; + +class FartReverbCommand extends MusicCommand { + async run() { + return await play(this.client, "./assets/audio/fart2.ogg", this.message); + } + + static description = "Plays a fart sound effect with extra reverb"; + static aliases = ["fart2"]; +} + +export default FartReverbCommand; \ No newline at end of file diff --git a/events/voiceChannelLeave.js b/events/voiceChannelLeave.js index 933a483..07d3b2c 100644 --- a/events/voiceChannelLeave.js +++ b/events/voiceChannelLeave.js @@ -13,7 +13,7 @@ export default async (client, cluster, worker, ipc, member, oldChannel) => { awaitRejoin.on("end", (rejoined, member) => { if (rejoined) { connection.player.pause(false); - players.set(connection.voiceChannel.guild.id, { player: connection.player, type: connection.type, host: member.id, voiceChannel: connection.voiceChannel, originalChannel: connection.originalChannel }); + players.set(connection.voiceChannel.guild.id, { player: connection.player, type: connection.type, host: member.id, voiceChannel: connection.voiceChannel, originalChannel: connection.originalChannel, loop: connection.loop, shuffle: connection.shuffle, playMessage: connection.playMessage }); waitMessage.edit(`🔊 ${member.mention} is the new voice channel host.`); } else { if (waitMessage.channel.messages.get(waitMessage.id)) waitMessage.delete(); @@ -45,7 +45,7 @@ export default async (client, cluster, worker, ipc, member, oldChannel) => { client.createMessage(connection.originalChannel.id, "🔊 The current voice channel session has ended."); } else { const randomMember = random(members); - players.set(connection.voiceChannel.guild.id, { player: connection.player, type: connection.type, host: randomMember.id, voiceChannel: connection.voiceChannel, originalChannel: connection.originalChannel }); + players.set(connection.voiceChannel.guild.id, { player: connection.player, type: connection.type, host: randomMember.id, voiceChannel: connection.voiceChannel, originalChannel: connection.originalChannel, loop: connection.loop, shuffle: connection.shuffle, playMessage: connection.playMessage }); waitMessage.edit(`🔊 ${randomMember.mention} is the new voice channel host.`); } } diff --git a/shard.js b/shard.js index 448519d..e3fd894 100644 --- a/shard.js +++ b/shard.js @@ -64,7 +64,9 @@ class Shard extends BaseClusterWorker { } this.ipc.register("reload", async (message) => { - const result = await load(paths.get(message.msg)); + const path = paths.get(message.msg); + if (!path) return this.ipc.broadcast("reloadFail", { result: "I couldn't find that command!" }); + const result = await load(path, await checkStatus()); if (result) return this.ipc.broadcast("reloadFail", { result }); return this.ipc.broadcast("reloadSuccess"); }); diff --git a/utils/soundplayer.js b/utils/soundplayer.js index 5592a5f..e6cb8af 100644 --- a/utils/soundplayer.js +++ b/utils/soundplayer.js @@ -80,12 +80,12 @@ export async function play(client, sound, message, music = false) { if (oldQueue && music) { return `Your ${playlistInfo.name ? "playlist" : "tune"} \`${playlistInfo.name ? playlistInfo.name : (tracks[0].info.title !== "" ? tracks[0].info.title : "(blank)")}\` has been added to the queue!`; } else { - nextSong(client, message, connection, tracks[0].track, tracks[0].info, music, voiceChannel, player ? player.loop : false); + nextSong(client, message, connection, tracks[0].track, tracks[0].info, music, voiceChannel, player ? player.loop : false, player ? player.shuffle : false); return; } } -export async function nextSong(client, message, connection, track, info, music, voiceChannel, loop = false, lastTrack = null) { +export async function nextSong(client, message, connection, track, info, music, voiceChannel, loop = false, shuffle = false, lastTrack = null) { skipVotes.delete(voiceChannel.guild.id); const parts = Math.floor((0 / info.length) * 10); let playingMessage; @@ -131,7 +131,7 @@ export async function nextSong(client, message, connection, track, info, music, connection.removeAllListeners("end"); await connection.play(track); await connection.volume(75); - players.set(voiceChannel.guild.id, { player: connection, type: music ? "music" : "sound", host: message.author.id, voiceChannel: voiceChannel, originalChannel: message.channel, loop: loop, playMessage: playingMessage }); + players.set(voiceChannel.guild.id, { player: connection, type: music ? "music" : "sound", host: message.author.id, voiceChannel: voiceChannel, originalChannel: message.channel, loop: loop, shuffle: shuffle, playMessage: playingMessage }); connection.once("error", (error) => { if (playingMessage.channel.messages.get(playingMessage.id)) playingMessage.delete(); const playMessage = players.get(voiceChannel.guild.id).playMessage; @@ -145,10 +145,18 @@ export async function nextSong(client, message, connection, track, info, music, }); connection.on("end", async (data) => { if (data.reason === "REPLACED") return; - const queue = queues.get(voiceChannel.guild.id); + let queue = queues.get(voiceChannel.guild.id); const player = players.get(voiceChannel.guild.id); let newQueue; - if (player && player.loop) { + if (player && player.shuffle) { + if (player.loop) { + queue.push(queue.shift()); + } else { + queue = queue.slice(1); + } + queue.unshift(queue.splice(Math.floor(Math.random() * queue.length), 1)[0]); + newQueue = queue; + } else if (player && player.loop) { queue.push(queue.shift()); newQueue = queue; } else { @@ -170,7 +178,7 @@ export async function nextSong(client, message, connection, track, info, music, } } else { const newTrack = await Rest.decode(connection.node, newQueue[0]); - nextSong(client, message, connection, newQueue[0], newTrack, music, voiceChannel, player.loop, track); + nextSong(client, message, connection, newQueue[0], newTrack, music, voiceChannel, player.loop, player.shuffle, track); try { if (newQueue[0] !== track && playingMessage.channel.messages.get(playingMessage.id)) await playingMessage.delete(); if (newQueue[0] !== track && player.playMessage.channel.messages.get(player.playMessage.id)) await player.playMessage.delete();