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