update lot of things

This commit is contained in:
Snowflake107 2021-06-17 19:07:03 +05:45
parent 38db664871
commit 4ed330958c
10 changed files with 71 additions and 46 deletions

View file

@ -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();

View file

@ -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",

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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>}

View file

@ -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;
}
}

View file

@ -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;
}
}
});

View file

@ -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";

View file

@ -47,6 +47,10 @@ class Util {
return null;
}
}
static wait(time: number) {
return new Promise((r) => setTimeout(r, time).unref());
}
}
export { Util };

View file

@ -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"