update lot of things
This commit is contained in:
parent
38db664871
commit
4ed330958c
10 changed files with 71 additions and 46 deletions
|
@ -1,7 +1,6 @@
|
|||
import { Client, GuildMember, Message, TextChannel } from "discord.js";
|
||||
import { Player, Queue, Track } from "../src/index";
|
||||
import { QueryType, QueueRepeatMode } from "../src/types/types";
|
||||
import { Client, GuildMember, TextChannel } from "discord.js";
|
||||
import { config } from "./config";
|
||||
import { Player, Queue, QueryType, QueueRepeatMode } from "../src/index";
|
||||
// use this in prod.
|
||||
// import { Player, Queue } from "discord-player";
|
||||
|
||||
|
@ -23,10 +22,6 @@ client.on("warn", console.warn);
|
|||
const player = new Player(client);
|
||||
|
||||
player.on("error", console.error);
|
||||
player.on("debug", (queue, message) => {
|
||||
console.log(`DEBUG :: ${queue.guild.name}`);
|
||||
console.log(message);
|
||||
});
|
||||
|
||||
player.on("trackStart", (queue, track) => {
|
||||
const guildQueue = queue as Queue<TextChannel>;
|
||||
|
@ -48,6 +43,11 @@ player.on("channelEmpty", (queue) => {
|
|||
guildQueue.metadata.send("❌ | Nobody is in the voice channel, leaving...");
|
||||
});
|
||||
|
||||
player.on("queueEnd", (queue) => {
|
||||
const guildQueue = queue as Queue<TextChannel>;
|
||||
guildQueue.metadata.send("✅ | Queue finished!");
|
||||
});
|
||||
|
||||
client.on("message", async (message) => {
|
||||
if (message.author.bot || !message.guild) return;
|
||||
if (!client.application?.owner) await client.application?.fetch();
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
},
|
||||
"homepage": "https://discord-player.js.org",
|
||||
"dependencies": {
|
||||
"@discordjs/voice": "^0.4.0",
|
||||
"@discordjs/voice": "^0.5.0",
|
||||
"discord-ytdl-core": "^5.0.3",
|
||||
"soundcloud-scraper": "^5.0.0",
|
||||
"spotify-url-info": "^2.2.3",
|
||||
|
@ -68,7 +68,7 @@
|
|||
"@types/node": "^15.12.2",
|
||||
"@types/ws": "^7.4.4",
|
||||
"discord-api-types": "^0.18.1",
|
||||
"discord.js": "^13.0.0-dev.02693bc02f45980d8165820a103220f0027b96b7",
|
||||
"discord.js": "^13.0.0-dev.a3cbcca13da1af416c219bd64a0a6e84bb87a057",
|
||||
"discord.js-docgen": "discordjs/docgen#ts-patch",
|
||||
"jsdoc-babel": "^0.5.0",
|
||||
"prettier": "^2.3.1",
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Collection, Guild, Snowflake, VoiceState } from "discord.js";
|
||||
import { Client, Collection, Guild, GuildResolvable, Snowflake, VoiceState } from "discord.js";
|
||||
import { TypedEmitter as EventEmitter } from "tiny-typed-emitter";
|
||||
import { Queue } from "./Structures/Queue";
|
||||
import { VoiceUtils } from "./VoiceInterface/VoiceUtils";
|
||||
|
@ -88,11 +88,13 @@ class DiscordPlayer extends EventEmitter<PlayerEvents> {
|
|||
|
||||
/**
|
||||
* Creates a queue for a guild if not available, else returns existing queue
|
||||
* @param {Discord.Guild} guild The guild
|
||||
* @param {GuildResolvable} guild The guild
|
||||
* @param {PlayerOptions} queueInitOptions Queue init options
|
||||
* @returns {Queue}
|
||||
*/
|
||||
createQueue<T = unknown>(guild: Guild, queueInitOptions?: PlayerOptions & { metadata?: T }): Queue<T> {
|
||||
createQueue<T = unknown>(guild: GuildResolvable, queueInitOptions?: PlayerOptions & { metadata?: T }): Queue<T> {
|
||||
guild = this.client.guilds.resolve(guild);
|
||||
if (!guild) throw new Error("Unknown Guild");
|
||||
if (this.queues.has(guild.id)) return this.queues.get(guild.id) as Queue<T>;
|
||||
|
||||
const _meta = queueInitOptions.metadata;
|
||||
|
@ -107,25 +109,29 @@ class DiscordPlayer extends EventEmitter<PlayerEvents> {
|
|||
|
||||
/**
|
||||
* Returns the queue if available
|
||||
* @param {Discord.Snowflake} guild The guild id
|
||||
* @param {GuildResolvable} guild The guild id
|
||||
* @returns {Queue}
|
||||
*/
|
||||
getQueue<T = unknown>(guild: Snowflake) {
|
||||
return this.queues.get(guild) as Queue<T>;
|
||||
getQueue<T = unknown>(guild: GuildResolvable) {
|
||||
guild = this.client.guilds.resolve(guild);
|
||||
if (!guild) throw new Error("Unknown Guild");
|
||||
return this.queues.get(guild.id) as Queue<T>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a queue and returns deleted queue object
|
||||
* @param {Discord.Snowflake} guild The guild id to remove
|
||||
* @param {GuildResolvable} guild The guild id to remove
|
||||
* @returns {Queue}
|
||||
*/
|
||||
deleteQueue<T = unknown>(guild: Snowflake) {
|
||||
deleteQueue<T = unknown>(guild: GuildResolvable) {
|
||||
guild = this.client.guilds.resolve(guild);
|
||||
if (!guild) throw new Error("Unknown Guild");
|
||||
const prev = this.getQueue<T>(guild);
|
||||
|
||||
try {
|
||||
prev.destroy();
|
||||
} catch {}
|
||||
this.queues.delete(guild);
|
||||
this.queues.delete(guild.id);
|
||||
|
||||
return prev;
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ class Playlist {
|
|||
tracks: [] as TrackJSON[]
|
||||
};
|
||||
|
||||
if (withTracks) payload.tracks = this.tracks.map((m) => m.toJSON());
|
||||
if (withTracks) payload.tracks = this.tracks.map((m) => m.toJSON(true));
|
||||
|
||||
return payload as PlaylistJSON;
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ class Queue<T = unknown> {
|
|||
useSafeSearch: false,
|
||||
disableAutoRegister: false,
|
||||
fetchBeforeQueued: false,
|
||||
initialVolume: 100
|
||||
initialVolume: 50
|
||||
} as PlayerOptions,
|
||||
options
|
||||
);
|
||||
|
@ -195,6 +195,13 @@ class Queue<T = unknown> {
|
|||
return this.connection.volume;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alternative volume setter
|
||||
*/
|
||||
set volume(amount: number) {
|
||||
this.setVolume(amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays previous track
|
||||
* @returns {Promise<void>}
|
||||
|
|
|
@ -155,7 +155,7 @@ class Track {
|
|||
* Raw JSON representation of this track
|
||||
* @returns {object}
|
||||
*/
|
||||
toJSON() {
|
||||
toJSON(hidePlaylist?: boolean) {
|
||||
return {
|
||||
title: this.title,
|
||||
description: this.description,
|
||||
|
@ -166,7 +166,7 @@ class Track {
|
|||
durationMS: this.durationMS,
|
||||
views: this.views,
|
||||
requestedBy: this.requestedBy.id,
|
||||
playlist: this.playlist?.toJSON(false) ?? null
|
||||
playlist: hidePlaylist ? null : this.playlist?.toJSON(false) ?? null
|
||||
} as TrackJSON;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,12 +8,14 @@ import {
|
|||
entersState,
|
||||
StreamType,
|
||||
VoiceConnection,
|
||||
VoiceConnectionStatus
|
||||
VoiceConnectionStatus,
|
||||
VoiceConnectionDisconnectReason
|
||||
} from "@discordjs/voice";
|
||||
import { StageChannel, VoiceChannel } from "discord.js";
|
||||
import { Duplex, Readable } from "stream";
|
||||
import { TypedEmitter as EventEmitter } from "tiny-typed-emitter";
|
||||
import Track from "../Structures/Track";
|
||||
import { Util } from "../utils/Util";
|
||||
|
||||
export interface VoiceEvents {
|
||||
error: (error: AudioPlayerError) => any;
|
||||
|
@ -26,8 +28,8 @@ class BasicStreamDispatcher extends EventEmitter<VoiceEvents> {
|
|||
public readonly voiceConnection: VoiceConnection;
|
||||
public readonly audioPlayer: AudioPlayer;
|
||||
public readonly channel: VoiceChannel | StageChannel;
|
||||
public connectPromise?: Promise<void>;
|
||||
public audioResource?: AudioResource<Track>;
|
||||
private readyLock: boolean = false;
|
||||
|
||||
constructor(connection: VoiceConnection, channel: VoiceChannel | StageChannel) {
|
||||
super();
|
||||
|
@ -36,26 +38,31 @@ class BasicStreamDispatcher extends EventEmitter<VoiceEvents> {
|
|||
this.audioPlayer = createAudioPlayer();
|
||||
this.channel = channel;
|
||||
|
||||
this.voiceConnection.on("stateChange", (_, newState) => {
|
||||
this.voiceConnection.on("stateChange", async (_, newState) => {
|
||||
if (newState.status === VoiceConnectionStatus.Disconnected) {
|
||||
if (this.voiceConnection.reconnectAttempts < 5) {
|
||||
setTimeout(() => {
|
||||
if (this.voiceConnection.state.status === VoiceConnectionStatus.Disconnected) {
|
||||
this.voiceConnection.reconnect();
|
||||
if (newState.reason === VoiceConnectionDisconnectReason.WebSocketClose && newState.closeCode === 4014) {
|
||||
try {
|
||||
await entersState(this.voiceConnection, VoiceConnectionStatus.Connecting, 5000);
|
||||
} catch {
|
||||
this.voiceConnection.destroy();
|
||||
}
|
||||
}, (this.voiceConnection.reconnectAttempts + 1) * 5000).unref();
|
||||
} else if (this.voiceConnection.rejoinAttempts < 5) {
|
||||
await Util.wait((this.voiceConnection.rejoinAttempts + 1) * 5000);
|
||||
this.voiceConnection.rejoin();
|
||||
} else {
|
||||
this.voiceConnection.destroy();
|
||||
}
|
||||
} else if (newState.status === VoiceConnectionStatus.Destroyed) {
|
||||
this.end();
|
||||
} else if (!this.connectPromise && (newState.status === VoiceConnectionStatus.Connecting || newState.status === VoiceConnectionStatus.Signalling)) {
|
||||
this.connectPromise = entersState(this.voiceConnection, VoiceConnectionStatus.Ready, 20000)
|
||||
.then(() => undefined)
|
||||
.catch(() => {
|
||||
} else if (!this.readyLock && (newState.status === VoiceConnectionStatus.Connecting || newState.status === VoiceConnectionStatus.Signalling)) {
|
||||
this.readyLock = true;
|
||||
try {
|
||||
await entersState(this.voiceConnection, VoiceConnectionStatus.Ready, 20000);
|
||||
} catch {
|
||||
if (this.voiceConnection.state.status !== VoiceConnectionStatus.Destroyed) this.voiceConnection.destroy();
|
||||
})
|
||||
.finally(() => (this.connectPromise = undefined));
|
||||
} finally {
|
||||
this.readyLock = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -6,3 +6,4 @@ export { Queue } from "./Structures/Queue";
|
|||
export { Track } from "./Structures/Track";
|
||||
export { VoiceUtils } from "./VoiceInterface/VoiceUtils";
|
||||
export { VoiceEvents, StreamDispatcher } from "./VoiceInterface/BasicStreamDispatcher";
|
||||
export * from "./types/types";
|
||||
|
|
|
@ -47,6 +47,10 @@ class Util {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static wait(time: number) {
|
||||
return new Promise((r) => setTimeout(r, time).unref());
|
||||
}
|
||||
}
|
||||
|
||||
export { Util };
|
||||
|
|
16
yarn.lock
16
yarn.lock
|
@ -1108,10 +1108,10 @@
|
|||
"@discordjs/node-pre-gyp" "^0.4.0"
|
||||
node-addon-api "^3.2.1"
|
||||
|
||||
"@discordjs/voice@^0.4.0":
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@discordjs/voice/-/voice-0.4.0.tgz#d5e19f3ee08de2f869e7d057bfff93138fcaf69e"
|
||||
integrity sha512-2GDs+QOCX525rp4yOzqu8RneTUDGdtyExnJMgXHSwCxmPQDWAMVd3dUiCNqLaCEjsQTMhDGEiThpuSDh6r49KQ==
|
||||
"@discordjs/voice@^0.5.0":
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@discordjs/voice/-/voice-0.5.0.tgz#238d6f8c1dc7e30ff781edb08fb0540bca5aa23d"
|
||||
integrity sha512-YPfY8ium1lExmRETz+vC4d3gGvHhGvWQMWLTOkNBoUkN6VyEpO/RVrL5EI+0qUefKAWwv2Gus/c7QM1xhAUwow==
|
||||
dependencies:
|
||||
"@types/ws" "^7.4.4"
|
||||
discord-api-types "^0.18.1"
|
||||
|
@ -2007,10 +2007,10 @@ discord.js-docgen@discordjs/docgen#ts-patch:
|
|||
tsubaki "^1.3.2"
|
||||
yargs "^14.0.0"
|
||||
|
||||
discord.js@^13.0.0-dev.02693bc02f45980d8165820a103220f0027b96b7:
|
||||
version "13.0.0-dev.02693bc02f45980d8165820a103220f0027b96b7"
|
||||
resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-13.0.0-dev.02693bc02f45980d8165820a103220f0027b96b7.tgz#5baa6c758b970a1e6175d06373d4ab33eb6a4164"
|
||||
integrity sha512-nzbmF5MLSjpdr8DS7SpC9q291NQ8XkHlledM4lz+uFJ4YgnMmTpi6e0FgF7v2kpTJPqTsXDRY3rWBv6Dat+08A==
|
||||
discord.js@^13.0.0-dev.a3cbcca13da1af416c219bd64a0a6e84bb87a057:
|
||||
version "13.0.0-dev.a3cbcca13da1af416c219bd64a0a6e84bb87a057"
|
||||
resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-13.0.0-dev.a3cbcca13da1af416c219bd64a0a6e84bb87a057.tgz#7358b44985b2423f1fdb1a9c259d26de74d662f7"
|
||||
integrity sha512-9EFBA08VUt9hIZzgQ1IcNv3/EwLvo4N9RikEzv/qNYjRvonnKi70tp0dpChduM8GFxgqrcTEa2mZJGfuumBBHA==
|
||||
dependencies:
|
||||
"@discordjs/collection" "^0.1.6"
|
||||
"@discordjs/form-data" "^3.0.1"
|
||||
|
|
Loading…
Reference in a new issue