Replace Lavalink wrapper, migrate to pnpm, add ko-fi sponsor link
This commit is contained in:
parent
cefafba8fb
commit
10becff3a0
19 changed files with 2768 additions and 8025 deletions
1
.github/FUNDING.yml
vendored
1
.github/FUNDING.yml
vendored
|
@ -1 +1,2 @@
|
|||
patreon: TheEssem
|
||||
ko_fi: TheEssem
|
12
.github/workflows/build.yml
vendored
12
.github/workflows/build.yml
vendored
|
@ -17,10 +17,12 @@ jobs:
|
|||
uses: actions/checkout@v1
|
||||
- name: Setup Node.js environment
|
||||
uses: actions/setup-node@v2.1.2
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v2.2.2
|
||||
- name: Install dependencies
|
||||
run: sudo apt install libvips-dev libmagick++-dev
|
||||
- name: Build
|
||||
run: npm install --legacy-peer-deps && npm run build
|
||||
run: pnpm install && npm run build
|
||||
|
||||
win32:
|
||||
runs-on: windows-latest
|
||||
|
@ -29,10 +31,12 @@ jobs:
|
|||
uses: actions/checkout@v1
|
||||
- name: Setup Node.js environment
|
||||
uses: actions/setup-node@v2.1.2
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v2.2.2
|
||||
- name: Install dependencies
|
||||
run: choco install imagemagick -PackageParameters InstallDevelopmentHeaders=true
|
||||
- name: Build
|
||||
run: npm install --legacy-peer-deps && npm run build
|
||||
run: pnpm install && npm run build
|
||||
|
||||
darwin:
|
||||
runs-on: macos-latest
|
||||
|
@ -41,7 +45,9 @@ jobs:
|
|||
uses: actions/checkout@v1
|
||||
- name: Setup Node.js environment
|
||||
uses: actions/setup-node@v2.1.2
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v2.2.2
|
||||
- name: Install dependencies
|
||||
run: brew install imagemagick vips
|
||||
- name: Build
|
||||
run: npm install --legacy-peer-deps && npm run build
|
||||
run: pnpm install && npm run build
|
||||
|
|
17
.github/workflows/codeql-analysis.yml
vendored
17
.github/workflows/codeql-analysis.yml
vendored
|
@ -52,8 +52,6 @@ jobs:
|
|||
#scope: # optional
|
||||
# Used to pull node distributions from node-versions. Since there's a default, this is typically not supplied by the user.
|
||||
#token: # optional, default is ${{ github.token }}
|
||||
|
||||
- run: sudo apt install libvips-dev libmagick++-dev
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
|
@ -65,20 +63,5 @@ jobs:
|
|||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
#- name: Autobuild
|
||||
# uses: github/codeql-action/autobuild@v1
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# npm install --legacy-peer-deps
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
|
|
|
@ -20,10 +20,8 @@ class AvatarCommand extends Command {
|
|||
return self.dynamicAvatarURL(null, 512);
|
||||
}
|
||||
} else if (this.args.join(" ") !== "" && this.channel.guild) {
|
||||
console.log(member);
|
||||
const searched = await this.channel.guild.searchMembers(this.args.join(" "));
|
||||
if (searched.length === 0) return self.dynamicAvatarURL(null, 512);
|
||||
console.log(searched);
|
||||
const user = await this.client.getRESTUser(searched[0].user.id);
|
||||
return user ? user.dynamicAvatarURL(null, 512) : self.dynamicAvatarURL(null, 512);
|
||||
} else {
|
||||
|
|
|
@ -6,7 +6,7 @@ class CaptionTwoCommand extends ImageCommand {
|
|||
params(url) {
|
||||
const newArgs = this.options.text ?? this.args.filter(item => !item.includes(url)).join(" ");
|
||||
return {
|
||||
caption: newArgs && newArgs.trim() ? newArgs.replaceAll("&", "&").replaceAll(">", ">").replaceAll("<", "<").replaceAll("\"", """).replaceAll("'", "'").replaceAll("%", "%").replaceAll("\\n", "\n") : words.sort(() => 0.5 - Math.random()).slice(0, Math.floor(Math.random() * words.length + 1)).join(" "),
|
||||
caption: newArgs && newArgs.trim() ? newArgs.replaceAll("&", "&").replaceAll(">", ">").replaceAll("<", "<").replaceAll("\"", """).replaceAll("'", "'").replaceAll("\\n", "\n") : words.sort(() => 0.5 - Math.random()).slice(0, Math.floor(Math.random() * words.length + 1)).join(" "),
|
||||
top: !!this.specialArgs.top,
|
||||
font: this.specialArgs.font && allowedFonts.includes(this.specialArgs.font.toLowerCase()) ? this.specialArgs.font.toLowerCase() : "helvetica"
|
||||
};
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { Rest } from "lavacord";
|
||||
import format from "format-duration";
|
||||
import MusicCommand from "../../classes/musicCommand.js";
|
||||
|
||||
|
@ -9,8 +8,8 @@ class NowPlayingCommand extends MusicCommand {
|
|||
if (!this.channel.guild.members.get(this.client.user.id).voiceState.channelID) return "I'm not in a voice channel!";
|
||||
const player = this.connection.player;
|
||||
if (!player) return "I'm not playing anything!";
|
||||
const track = await Rest.decode(player.node, player.track);
|
||||
const parts = Math.floor((player.state.position / track.length) * 10);
|
||||
const track = await player.node.rest.decode(player.track);
|
||||
const parts = Math.floor((player.position / track.length) * 10);
|
||||
return {
|
||||
embeds: [{
|
||||
color: 16711680,
|
||||
|
@ -32,7 +31,7 @@ class NowPlayingCommand extends MusicCommand {
|
|||
},
|
||||
{
|
||||
name: `${"▬".repeat(parts)}🔘${"▬".repeat(10 - parts)}`,
|
||||
value: `${format(player.state.position)}/${track.isStream ? "∞" : format(track.length)}`
|
||||
value: `${format(player.position)}/${track.isStream ? "∞" : format(track.length)}`
|
||||
}]
|
||||
}]
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//import { Rest } from "lavacord";
|
||||
import fetch from "node-fetch";
|
||||
import format from "format-duration";
|
||||
import { nodes } from "../../utils/soundplayer.js";
|
||||
import paginator from "../../utils/pagination/pagination.js";
|
||||
import MusicCommand from "../../classes/musicCommand.js";
|
||||
|
||||
|
@ -11,8 +11,8 @@ class QueueCommand extends MusicCommand {
|
|||
if (!this.channel.guild.members.get(this.client.user.id).voiceState.channelID) return "I'm not in a voice channel!";
|
||||
if (!this.channel.permissionsOf(this.client.user.id).has("embedLinks")) return "I don't have the `Embed Links` permission!";
|
||||
const player = this.connection;
|
||||
//const tracks = await Rest.decode(player.player.node, queue);
|
||||
const tracks = await fetch(`http://${player.player.node.host}:${player.player.node.port}/decodetracks`, { method: "POST", body: JSON.stringify(this.queue), headers: { Authorization: player.player.node.password, "Content-Type": "application/json" } }).then(res => res.json());
|
||||
const node = nodes.filter((val) => { return val.name === player.player.node.name })[0];
|
||||
const tracks = await fetch(`http://${node.url}/decodetracks`, { method: "POST", body: JSON.stringify(this.queue), headers: { Authorization: node.auth, "Content-Type": "application/json" } }).then(res => res.json());
|
||||
const trackList = [];
|
||||
const firstTrack = tracks.shift();
|
||||
for (const [i, track] of tracks.entries()) {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { Rest } from "lavacord";
|
||||
import { queues } from "../../utils/soundplayer.js";
|
||||
import MusicCommand from "../../classes/musicCommand.js";
|
||||
|
||||
|
@ -11,7 +10,8 @@ class RemoveCommand extends MusicCommand {
|
|||
const pos = parseInt(this.options.position ?? this.args[0]);
|
||||
if (isNaN(pos) || pos > this.queue.length || pos < 1) return "That's not a valid position!";
|
||||
const removed = this.queue.splice(pos, 1);
|
||||
const track = await Rest.decode(this.connection.player.node, removed[0]);
|
||||
if (removed.length === 0) return "That's not a valid position!";
|
||||
const track = await this.connection.player.node.rest.decode(removed[0]);
|
||||
queues.set(this.channel.guild.id, this.queue);
|
||||
return `🔊 The song \`${track.title ? track.title : "(blank)"}\` has been removed from the queue.`;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { Rest } from "lavacord";
|
||||
import MusicCommand from "../../classes/musicCommand.js";
|
||||
|
||||
class SeekCommand extends MusicCommand {
|
||||
|
@ -8,11 +7,11 @@ class SeekCommand extends MusicCommand {
|
|||
if (!this.channel.guild.members.get(this.client.user.id).voiceState.channelID) return "I'm not in a voice channel!";
|
||||
if (this.connection.host !== this.author.id) return "Only the current voice session host can seek the music!";
|
||||
const player = this.connection.player;
|
||||
const track = await Rest.decode(player.node, player.track);
|
||||
const track = await player.node.rest.decode(player.track);
|
||||
if (!track.isSeekable) return "This track isn't seekable!";
|
||||
const seconds = parseFloat(this.options.position ?? this.args[0]);
|
||||
if (isNaN(seconds) || (seconds * 1000) > track.length || (seconds * 1000) < 0) return "That's not a valid position!";
|
||||
await player.seek(seconds * 1000);
|
||||
player.seekTo(seconds * 1000);
|
||||
return `🔊 Seeked track to ${seconds} second(s).`;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ class SkipCommand extends MusicCommand {
|
|||
max: votes.max
|
||||
};
|
||||
if (votes.count + 1 === votes.max) {
|
||||
await player.player.stop(this.channel.guild.id);
|
||||
await player.player.stopTrack(this.channel.guild.id);
|
||||
skipVotes.set(this.channel.guild.id, { count: 0, ids: [], max: Math.min(3, player.voiceChannel.voiceMembers.filter((i) => i.id !== this.client.user.id && !i.bot).length) });
|
||||
if (this.type === "application") return "🔊 The current song has been skipped.";
|
||||
} else {
|
||||
|
@ -24,7 +24,7 @@ class SkipCommand extends MusicCommand {
|
|||
return `🔊 Voted to skip song (${votes.count + 1}/${votes.max} people have voted).`;
|
||||
}
|
||||
} else {
|
||||
await player.player.stop(this.channel.guild.id);
|
||||
await player.player.stopTrack();
|
||||
if (this.type === "application") return "🔊 The current song has been skipped.";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,13 +7,12 @@ class StopCommand extends MusicCommand {
|
|||
if (!this.member.voiceState.channelID) return "You need to be in a voice channel first!";
|
||||
if (!this.channel.guild.members.get(this.client.user.id).voiceState.channelID) return "I'm not in a voice channel!";
|
||||
if (!this.connection) {
|
||||
await manager.leave(this.channel.guild.id);
|
||||
await manager.getNode().leaveChannel(this.channel.guild.id);
|
||||
return "🔊 The current voice channel session has ended.";
|
||||
}
|
||||
if (this.connection.host !== this.author.id && !this.member.permissions.has("manageChannels")) return "Only the current voice session host can stop the music!";
|
||||
await manager.leave(this.channel.guild.id);
|
||||
const connection = this.connection.player;
|
||||
await connection.destroy();
|
||||
connection.node.leaveChannel(this.channel.guild.id);
|
||||
players.delete(this.channel.guild.id);
|
||||
queues.delete(this.channel.guild.id);
|
||||
return "🔊 The current voice channel session has ended.";
|
||||
|
|
|
@ -7,7 +7,7 @@ class ToggleCommand extends MusicCommand {
|
|||
if (!this.channel.guild.members.get(this.client.user.id).voiceState.channelID) return "I'm not in a voice channel!";
|
||||
if (this.connection.host !== this.author.id && !this.member.permissions.has("manageChannels")) return "Only the current voice session host can pause/resume the music!";
|
||||
const player = this.connection.player;
|
||||
await player.pause(!player.paused ? true : false);
|
||||
player.setPaused(!player.paused ? true : false);
|
||||
return `🔊 The player has been ${player.paused ? "paused" : "resumed"}.`;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
import { manager } from "../utils/soundplayer.js";
|
||||
|
||||
// run when a raw packet is sent, used for sending data to lavalink
|
||||
export default async (client, cluster, worker, ipc, packet) => {
|
||||
if (!manager) return;
|
||||
switch (packet.t) {
|
||||
case "VOICE_SERVER_UPDATE":
|
||||
await manager.voiceServerUpdate(packet.d);
|
||||
break;
|
||||
case "VOICE_STATE_UPDATE":
|
||||
await manager.voiceStateUpdate(packet.d);
|
||||
break;
|
||||
case "GUILD_CREATE":
|
||||
for (const state of packet.d.voice_states) await manager.voiceStateUpdate({ ...state, guild_id: packet.d.id });
|
||||
break;
|
||||
}
|
||||
};
|
7920
package-lock.json
generated
7920
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -33,15 +33,16 @@
|
|||
"file-type": "^17.1.1",
|
||||
"format-duration": "^2.0.0",
|
||||
"jsqr": "^1.3.1",
|
||||
"lavacord": "^1.1.9",
|
||||
"node-addon-api": "^5.0.0",
|
||||
"node-emoji": "^1.10.0",
|
||||
"node-fetch": "^3.2.0",
|
||||
"qrcode": "^1.4.4",
|
||||
"sharp": "^0.30.6",
|
||||
"shoukaku": "^3.1.0",
|
||||
"winston": "^3.3.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.18.5",
|
||||
"@babel/eslint-parser": "^7.13.8",
|
||||
"@babel/eslint-plugin": "^7.13.0",
|
||||
"@babel/plugin-proposal-class-properties": "^7.13.0",
|
||||
|
|
2685
pnpm-lock.yaml
Normal file
2685
pnpm-lock.yaml
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"lava": [
|
||||
{ "id": "1", "host": "localhost", "port": 2333, "password": "youshallnotpass", "local": true }
|
||||
{ "name": "localhost", "url": "localhost:2333", "auth": "youshallnotpass", "local": true }
|
||||
],
|
||||
"image": [
|
||||
{ "server": "localhost", "auth": "verycoolpass100", "tls": false }
|
||||
|
|
4
shard.js
4
shard.js
|
@ -10,7 +10,7 @@ import { log, error } from "./utils/logger.js";
|
|||
// initialize command loader
|
||||
import { load, update } from "./utils/handler.js";
|
||||
// lavalink stuff
|
||||
import { checkStatus, connect, status, connected } from "./utils/soundplayer.js";
|
||||
import { checkStatus, connect, reload, status, connected, manager } from "./utils/soundplayer.js";
|
||||
// database stuff
|
||||
import database from "./utils/database.js";
|
||||
// command collections
|
||||
|
@ -83,7 +83,7 @@ class Shard extends BaseClusterWorker {
|
|||
this.ipc.register("soundreload", async () => {
|
||||
const soundStatus = await checkStatus();
|
||||
if (!soundStatus) {
|
||||
const length = await connect(this.bot);
|
||||
const length = reload();
|
||||
return this.ipc.broadcast("soundReloadSuccess", { length });
|
||||
} else {
|
||||
return this.ipc.broadcast("soundReloadFail");
|
||||
|
|
|
@ -2,15 +2,14 @@ import * as logger from "./logger.js";
|
|||
import fetch from "node-fetch";
|
||||
import fs from "fs";
|
||||
import format from "format-duration";
|
||||
import { Manager, Rest } from "lavacord";
|
||||
|
||||
let nodes;
|
||||
import { Shoukaku, Connectors } from "shoukaku";
|
||||
|
||||
export const players = new Map();
|
||||
export const queues = new Map();
|
||||
export const skipVotes = new Map();
|
||||
|
||||
export let manager;
|
||||
export let nodes;
|
||||
export let status = false;
|
||||
export let connected = false;
|
||||
|
||||
|
@ -20,7 +19,7 @@ export async function checkStatus() {
|
|||
const newNodes = [];
|
||||
for (const node of nodes) {
|
||||
try {
|
||||
const response = await fetch(`http://${node.host}:${node.port}/version`, { headers: { Authorization: node.password } }).then(res => res.text());
|
||||
const response = await fetch(`http://${node.url}/version`, { headers: { Authorization: node.auth } }).then(res => res.text());
|
||||
if (response) newNodes.push(node);
|
||||
} catch {
|
||||
logger.error(`Failed to get status of Lavalink node ${node.host}.`);
|
||||
|
@ -32,22 +31,31 @@ export async function checkStatus() {
|
|||
}
|
||||
|
||||
export async function connect(client) {
|
||||
manager = new Manager(nodes, {
|
||||
user: client.user.id,
|
||||
shards: client.shards.size || 1,
|
||||
send: (packet) => {
|
||||
const guild = client.guilds.get(packet.d.guild_id);
|
||||
if (!guild) return;
|
||||
return guild.shard.sendWS(packet.op, packet.d);
|
||||
}
|
||||
});
|
||||
const { length } = await manager.connect();
|
||||
logger.log(`Successfully connected to ${length} Lavalink node(s).`);
|
||||
connected = true;
|
||||
manager.on("error", (error, node) => {
|
||||
manager = new Shoukaku(new Connectors.Eris(client), nodes);
|
||||
client.emit("ready"); // workaround
|
||||
manager.on("error", (node, error) => {
|
||||
logger.error(`An error occurred on Lavalink node ${node}: ${error}`);
|
||||
});
|
||||
return length;
|
||||
manager.once("ready", (name) => {
|
||||
logger.log(`Successfully connected to ${manager.nodes.size} Lavalink node(s).`);
|
||||
connected = true;
|
||||
});
|
||||
}
|
||||
|
||||
export function reload() {
|
||||
const activeNodes = manager.nodes;
|
||||
const names = nodes.map((a) => a.name);
|
||||
for (const name in activeNodes) {
|
||||
if (!names.includes(name)) {
|
||||
manager.removeNode(name);
|
||||
}
|
||||
}
|
||||
for (const node of nodes) {
|
||||
if (!activeNodes.has(node.name)) {
|
||||
manager.addNode(node);
|
||||
}
|
||||
}
|
||||
return manager.nodes.size;
|
||||
}
|
||||
|
||||
export async function play(client, sound, options, music = false) {
|
||||
|
@ -58,41 +66,44 @@ export async function play(client, sound, options, music = false) {
|
|||
const voiceChannel = options.channel.guild.channels.get(options.member.voiceState.channelID);
|
||||
if (!voiceChannel.permissionsOf(client.user.id).has("voiceConnect")) return "I don't have permission to join this voice channel!";
|
||||
const player = players.get(options.channel.guild.id);
|
||||
if (!music && manager.voiceStates.has(options.channel.guild.id) && (player && player.type === "music")) return "I can't play a sound effect while playing music!";
|
||||
let node = manager.idealNodes[0];
|
||||
if (!music && manager.players().has(options.channel.guild.id) && (player && player.type === "music")) return "I can't play a sound effect while playing music!";
|
||||
let node = manager.getNode();
|
||||
if (!node) {
|
||||
const status = await checkStatus();
|
||||
if (!status) {
|
||||
await connect(client);
|
||||
node = manager.idealNodes[0];
|
||||
node = manager.getNode();
|
||||
}
|
||||
}
|
||||
if (!music && !nodes.filter(obj => obj.host === node.host)[0].local) {
|
||||
if (!music && !nodes.filter(obj => obj.name === node.name)[0].local) {
|
||||
sound = sound.replace(/\.\//, "https://raw.githubusercontent.com/esmBot/esmBot/master/");
|
||||
}
|
||||
let tracks, playlistInfo;
|
||||
let response;
|
||||
try {
|
||||
({ tracks, playlistInfo } = await Rest.load(node, sound));
|
||||
response = await node.rest.resolve(sound);
|
||||
if (!response) return "🔊 I couldn't get a response from the audio server.";
|
||||
if (response.loadType === "NO_MATCHES" || response.loadType === "LOAD_FAILED") return "I couldn't find that song!";
|
||||
} catch {
|
||||
return "🔊 Hmmm, seems that all of the audio servers are down. Try again in a bit.";
|
||||
}
|
||||
const oldQueue = queues.get(voiceChannel.guild.id);
|
||||
if (!tracks || tracks.length === 0) return "I couldn't find that song!";
|
||||
if (!response.tracks || response.tracks.length === 0) return "I couldn't find that song!";
|
||||
if (music) {
|
||||
const sortedTracks = tracks.map((val) => { return val.track; });
|
||||
const playlistTracks = playlistInfo.selectedTrack ? sortedTracks : [sortedTracks[0]];
|
||||
const sortedTracks = response.tracks.map((val) => { return val.track; });
|
||||
const playlistTracks = response.playlistInfo.selectedTrack ? sortedTracks : [sortedTracks[0]];
|
||||
queues.set(voiceChannel.guild.id, oldQueue ? [...oldQueue, ...playlistTracks] : playlistTracks);
|
||||
}
|
||||
const connection = await manager.join({
|
||||
guild: voiceChannel.guild.id,
|
||||
channel: voiceChannel.id,
|
||||
node: node.id
|
||||
}, { selfdeaf: true });
|
||||
const connection = player && player.player ? player.player : await node.joinChannel({
|
||||
guildId: voiceChannel.guild.id,
|
||||
channelId: voiceChannel.id,
|
||||
shardId: voiceChannel.guild.shard.id,
|
||||
deaf: true
|
||||
});
|
||||
|
||||
if (oldQueue && oldQueue.length !== 0 && music) {
|
||||
return `Your ${playlistInfo.name ? "playlist" : "tune"} \`${playlistInfo.name ? playlistInfo.name.trim() : (tracks[0].info.title !== "" ? tracks[0].info.title.trim() : "(blank)")}\` has been added to the queue!`;
|
||||
return `Your ${response.playlistInfo.name ? "playlist" : "tune"} \`${response.playlistInfo.name ? response.playlistInfo.name.trim() : (response.tracks[0].info.title !== "" ? response.tracks[0].info.title.trim() : "(blank)")}\` has been added to the queue!`;
|
||||
} else {
|
||||
nextSong(client, options, connection, tracks[0].track, tracks[0].info, music, voiceChannel, player ? player.host : options.member.id, player ? player.loop : false, player ? player.shuffle : false);
|
||||
nextSong(client, options, connection, response.tracks[0].track, response.tracks[0].info, music, voiceChannel, player ? player.host : options.member.id, player ? player.loop : false, player ? player.shuffle : false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -151,9 +162,9 @@ export async function nextSong(client, options, connection, track, info, music,
|
|||
}
|
||||
connection.removeAllListeners("error");
|
||||
connection.removeAllListeners("end");
|
||||
await connection.play(track);
|
||||
connection.playTrack({ track });
|
||||
players.set(voiceChannel.guild.id, { player: connection, type: music ? "music" : "sound", host: host, voiceChannel: voiceChannel, originalChannel: options.channel, loop: loop, shuffle: shuffle, playMessage: playingMessage });
|
||||
connection.once("error", async (error) => {
|
||||
connection.once("exception", async (exception) => {
|
||||
try {
|
||||
if (playingMessage.channel.messages.has(playingMessage.id)) await playingMessage.delete();
|
||||
const playMessage = players.get(voiceChannel.guild.id).playMessage;
|
||||
|
@ -162,16 +173,15 @@ export async function nextSong(client, options, connection, track, info, music,
|
|||
// no-op
|
||||
}
|
||||
try {
|
||||
await manager.leave(voiceChannel.guild.id);
|
||||
await connection.destroy();
|
||||
connection.node.leaveChannel(voiceChannel.guild.id);
|
||||
} catch {
|
||||
// no-op
|
||||
}
|
||||
connection.removeAllListeners("end");
|
||||
players.delete(voiceChannel.guild.id);
|
||||
queues.delete(voiceChannel.guild.id);
|
||||
logger.error(error);
|
||||
const content = `🔊 Looks like there was an error regarding sound playback:\n\`\`\`${error.type}: ${error.error}\`\`\``;
|
||||
logger.error(exception.error);
|
||||
const content = `🔊 Looks like there was an error regarding sound playback:\n\`\`\`${exception.type}: ${exception.error}\`\`\``;
|
||||
if (options.type === "classic") {
|
||||
await client.createMessage(options.channel.id, content);
|
||||
} else {
|
||||
|
@ -203,7 +213,7 @@ export async function nextSong(client, options, connection, track, info, music,
|
|||
}
|
||||
queues.set(voiceChannel.guild.id, newQueue);
|
||||
if (newQueue.length !== 0) {
|
||||
const newTrack = await Rest.decode(connection.node, newQueue[0]);
|
||||
const newTrack = await connection.node.rest.decode(newQueue[0]);
|
||||
nextSong(client, options, connection, newQueue[0], newTrack, music, voiceChannel, host, player.loop, player.shuffle, track);
|
||||
try {
|
||||
if (newQueue[0] !== track && playingMessage.channel.messages.has(playingMessage.id)) await playingMessage.delete();
|
||||
|
@ -212,8 +222,7 @@ export async function nextSong(client, options, connection, track, info, music,
|
|||
// no-op
|
||||
}
|
||||
} else if (process.env.STAYVC !== "true") {
|
||||
await manager.leave(voiceChannel.guild.id);
|
||||
await connection.destroy();
|
||||
connection.node.leaveChannel(voiceChannel.guild.id);
|
||||
players.delete(voiceChannel.guild.id);
|
||||
queues.delete(voiceChannel.guild.id);
|
||||
skipVotes.delete(voiceChannel.guild.id);
|
||||
|
|
Loading…
Reference in a new issue