lavalink-client 2.3.0 → 2.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -0
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/structures/Constants.d.ts +44 -1
- package/dist/cjs/structures/Constants.js +45 -1
- package/dist/cjs/structures/LavalinkManager.js +80 -5
- package/dist/cjs/structures/Node.js +202 -20
- package/dist/cjs/structures/Player.d.ts +0 -1
- package/dist/cjs/structures/Player.js +73 -6
- package/dist/cjs/structures/Queue.js +29 -2
- package/dist/cjs/structures/Types/Manager.d.ts +25 -0
- package/dist/cjs/structures/Types/Queue.d.ts +1 -1
- package/dist/cjs/structures/Utils.js +68 -18
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/structures/Constants.d.ts +44 -1
- package/dist/esm/structures/Constants.js +44 -0
- package/dist/esm/structures/LavalinkManager.js +81 -6
- package/dist/esm/structures/Node.js +203 -21
- package/dist/esm/structures/Player.d.ts +0 -1
- package/dist/esm/structures/Player.js +73 -6
- package/dist/esm/structures/Queue.js +29 -2
- package/dist/esm/structures/Types/Manager.d.ts +25 -0
- package/dist/esm/structures/Types/Queue.d.ts +1 -1
- package/dist/esm/structures/Utils.js +68 -18
- package/dist/types/index.d.ts +1 -0
- package/dist/types/structures/Constants.d.ts +44 -1
- package/dist/types/structures/Player.d.ts +0 -1
- package/dist/types/structures/Types/Manager.d.ts +25 -0
- package/dist/types/structures/Types/Queue.d.ts +1 -1
- package/package.json +1 -1
- package/dist/index.d.ts +0 -10
- package/dist/index.js +0 -13
- package/dist/structures/Filters.d.ts +0 -230
- package/dist/structures/Filters.js +0 -472
- package/dist/structures/LavalinkManager.d.ts +0 -47
- package/dist/structures/LavalinkManager.js +0 -36
- package/dist/structures/LavalinkManagerStatics.d.ts +0 -3
- package/dist/structures/LavalinkManagerStatics.js +0 -76
- package/dist/structures/Node.d.ts +0 -171
- package/dist/structures/Node.js +0 -462
- package/dist/structures/NodeManager.d.ts +0 -58
- package/dist/structures/NodeManager.js +0 -25
- package/dist/structures/Player.d.ts +0 -101
- package/dist/structures/Player.js +0 -232
- package/dist/structures/PlayerManager.d.ts +0 -62
- package/dist/structures/PlayerManager.js +0 -26
- package/dist/structures/Queue.d.ts +0 -93
- package/dist/structures/Queue.js +0 -160
- package/dist/structures/QueueManager.d.ts +0 -77
- package/dist/structures/QueueManager.js +0 -74
- package/dist/structures/Track.d.ts +0 -27
- package/dist/structures/Track.js +0 -2
- package/dist/structures/Utils.d.ts +0 -183
- package/dist/structures/Utils.js +0 -43
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
/// <reference types="node" />
|
|
3
|
-
import WebSocket from "ws";
|
|
4
|
-
import { Dispatcher, Pool } from "undici";
|
|
5
|
-
import { NodeManager } from "./NodeManager";
|
|
6
|
-
import internal from "node:stream";
|
|
7
|
-
import { InvalidLavalinkRestRequest, LavalinkPlayer, PlayerUpdateInfo, RoutePlanner } from "./Utils";
|
|
8
|
-
import { Session } from "node:inspector";
|
|
9
|
-
/** Modifies any outgoing REST requests. */
|
|
10
|
-
export type ModifyRequest = (options: Dispatcher.RequestOptions) => void;
|
|
11
|
-
export interface LavalinkNodeOptions {
|
|
12
|
-
/** The Lavalink Server-Ip / Domain-URL */
|
|
13
|
-
host: string;
|
|
14
|
-
/** The Lavalink Connection Port */
|
|
15
|
-
port: number;
|
|
16
|
-
/** The Lavalink Password / Authorization-Key */
|
|
17
|
-
authorization: string;
|
|
18
|
-
/** Does the Server use ssl (https) */
|
|
19
|
-
secure?: boolean;
|
|
20
|
-
/** Add a Custom ID to the node, for later use */
|
|
21
|
-
id?: string;
|
|
22
|
-
/** Voice Regions of this Node */
|
|
23
|
-
regions?: string[];
|
|
24
|
-
/** Options for the undici http pool used for http requests */
|
|
25
|
-
poolOptions?: Pool.Options;
|
|
26
|
-
/** The retryAmount for the node. */
|
|
27
|
-
retryAmount?: number;
|
|
28
|
-
/** The retryDelay for the node. */
|
|
29
|
-
retryDelay?: number;
|
|
30
|
-
/** Pool Undici Options - requestTimeout */
|
|
31
|
-
requestTimeout?: number;
|
|
32
|
-
}
|
|
33
|
-
export interface MemoryStats {
|
|
34
|
-
/** The free memory of the allocated amount. */
|
|
35
|
-
free: number;
|
|
36
|
-
/** The used memory of the allocated amount. */
|
|
37
|
-
used: number;
|
|
38
|
-
/** The total allocated memory. */
|
|
39
|
-
allocated: number;
|
|
40
|
-
/** The reservable memory. */
|
|
41
|
-
reservable: number;
|
|
42
|
-
}
|
|
43
|
-
export interface CPUStats {
|
|
44
|
-
/** The core amount the host machine has. */
|
|
45
|
-
cores: number;
|
|
46
|
-
/** The system load. */
|
|
47
|
-
systemLoad: number;
|
|
48
|
-
/** The lavalink load. */
|
|
49
|
-
lavalinkLoad: number;
|
|
50
|
-
}
|
|
51
|
-
export interface FrameStats {
|
|
52
|
-
/** The amount of sent frames. */
|
|
53
|
-
sent?: number;
|
|
54
|
-
/** The amount of nulled frames. */
|
|
55
|
-
nulled?: number;
|
|
56
|
-
/** The amount of deficit frames. */
|
|
57
|
-
deficit?: number;
|
|
58
|
-
}
|
|
59
|
-
export interface NodeStats {
|
|
60
|
-
/** The amount of players on the node. */
|
|
61
|
-
players: number;
|
|
62
|
-
/** The amount of playing players on the node. */
|
|
63
|
-
playingPlayers: number;
|
|
64
|
-
/** The uptime for the node. */
|
|
65
|
-
uptime: number;
|
|
66
|
-
/** The memory stats for the node. */
|
|
67
|
-
memory: MemoryStats;
|
|
68
|
-
/** The cpu stats for the node. */
|
|
69
|
-
cpu: CPUStats;
|
|
70
|
-
/** The frame stats for the node. */
|
|
71
|
-
frameStats: FrameStats;
|
|
72
|
-
}
|
|
73
|
-
export interface LavalinkInfo {
|
|
74
|
-
version: VersionObject;
|
|
75
|
-
buildTime: number;
|
|
76
|
-
git: GitObject;
|
|
77
|
-
jvm: string;
|
|
78
|
-
lavaplayer: string;
|
|
79
|
-
sourceManagers: string[];
|
|
80
|
-
filters: string[];
|
|
81
|
-
plugins: PluginObject[];
|
|
82
|
-
}
|
|
83
|
-
export interface VersionObject {
|
|
84
|
-
semver: string;
|
|
85
|
-
major: number;
|
|
86
|
-
minor: number;
|
|
87
|
-
patch: internal;
|
|
88
|
-
preRelease?: string;
|
|
89
|
-
}
|
|
90
|
-
export interface GitObject {
|
|
91
|
-
branch: string;
|
|
92
|
-
commit: string;
|
|
93
|
-
commitTime: string;
|
|
94
|
-
}
|
|
95
|
-
export interface PluginObject {
|
|
96
|
-
name: string;
|
|
97
|
-
version: string;
|
|
98
|
-
}
|
|
99
|
-
export declare class LavalinkNode {
|
|
100
|
-
socket: WebSocket | null;
|
|
101
|
-
rest: Pool;
|
|
102
|
-
options: LavalinkNodeOptions;
|
|
103
|
-
/** The amount of rest calls the node has made. */
|
|
104
|
-
calls: number;
|
|
105
|
-
stats: NodeStats;
|
|
106
|
-
private NodeManager;
|
|
107
|
-
private reconnectTimeout?;
|
|
108
|
-
private reconnectAttempts;
|
|
109
|
-
sessionId?: string | null;
|
|
110
|
-
info: LavalinkInfo | null;
|
|
111
|
-
version: "v4";
|
|
112
|
-
constructor(options: LavalinkNodeOptions, manager: NodeManager);
|
|
113
|
-
/**
|
|
114
|
-
* Makes an API call to the Node
|
|
115
|
-
* @param endpoint The endpoint that we will make the call to
|
|
116
|
-
* @param modify Used to modify the request before being sent
|
|
117
|
-
* @returns The returned data
|
|
118
|
-
*/
|
|
119
|
-
makeRequest(endpoint: string, modify?: ModifyRequest, parseAsText?: boolean): Promise<unknown>;
|
|
120
|
-
updatePlayer(data: PlayerUpdateInfo): Promise<LavalinkPlayer>;
|
|
121
|
-
private syncPlayerData;
|
|
122
|
-
destroyPlayer(guildId: any): Promise<unknown>;
|
|
123
|
-
connect(): void;
|
|
124
|
-
get id(): string;
|
|
125
|
-
destroy(): void;
|
|
126
|
-
/** Returns if connected to the Node. */
|
|
127
|
-
get connected(): boolean;
|
|
128
|
-
get poolAddress(): string;
|
|
129
|
-
private fetchInfo;
|
|
130
|
-
private fetchVersion;
|
|
131
|
-
/**
|
|
132
|
-
* Gets all Players of a Node
|
|
133
|
-
*/
|
|
134
|
-
getPlayers(): Promise<LavalinkPlayer[]>;
|
|
135
|
-
/**
|
|
136
|
-
* Gets specific Player Information
|
|
137
|
-
*/
|
|
138
|
-
getPlayer(guildId: string): Promise<LavalinkPlayer | InvalidLavalinkRestRequest>;
|
|
139
|
-
/**
|
|
140
|
-
* Updates the session with a resuming key and timeout
|
|
141
|
-
* @param resumingKey
|
|
142
|
-
* @param timeout
|
|
143
|
-
*/
|
|
144
|
-
updateSession(resumingKey?: string, timeout?: number): Promise<Session | Record<string, string>>;
|
|
145
|
-
/**
|
|
146
|
-
* Get routplanner Info from Lavalink
|
|
147
|
-
*/
|
|
148
|
-
getRoutePlannerStatus(): Promise<RoutePlanner>;
|
|
149
|
-
/**
|
|
150
|
-
* Release blacklisted IP address into pool of IPs
|
|
151
|
-
* @param address IP address
|
|
152
|
-
*/
|
|
153
|
-
unmarkFailedAddress(address: string): Promise<void>;
|
|
154
|
-
/**
|
|
155
|
-
* Release blacklisted IP address into pool of IPs
|
|
156
|
-
* @param address IP address
|
|
157
|
-
*/
|
|
158
|
-
unmarkAllFailedAddresses(): Promise<void>;
|
|
159
|
-
private reconnect;
|
|
160
|
-
private open;
|
|
161
|
-
private close;
|
|
162
|
-
private error;
|
|
163
|
-
private message;
|
|
164
|
-
private handleEvent;
|
|
165
|
-
private trackStart;
|
|
166
|
-
private trackEnd;
|
|
167
|
-
private queueEnd;
|
|
168
|
-
private trackStuck;
|
|
169
|
-
private trackError;
|
|
170
|
-
private socketClosed;
|
|
171
|
-
}
|
package/dist/structures/Node.js
DELETED
|
@@ -1,462 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.LavalinkNode = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
const ws_1 = tslib_1.__importDefault(require("ws"));
|
|
6
|
-
const undici_1 = require("undici");
|
|
7
|
-
const node_path_1 = require("node:path");
|
|
8
|
-
class LavalinkNode {
|
|
9
|
-
socket = null;
|
|
10
|
-
rest;
|
|
11
|
-
options;
|
|
12
|
-
/** The amount of rest calls the node has made. */
|
|
13
|
-
calls = 0;
|
|
14
|
-
stats;
|
|
15
|
-
NodeManager = null;
|
|
16
|
-
reconnectTimeout;
|
|
17
|
-
reconnectAttempts = 1;
|
|
18
|
-
sessionId = null;
|
|
19
|
-
info = null;
|
|
20
|
-
version;
|
|
21
|
-
constructor(options, manager) {
|
|
22
|
-
if (!this.options.authorization)
|
|
23
|
-
throw new SyntaxError("LavalinkNode requires 'authorization'");
|
|
24
|
-
if (!this.options.host)
|
|
25
|
-
throw new SyntaxError("LavalinkNode requires 'host'");
|
|
26
|
-
if (!this.options.port)
|
|
27
|
-
throw new SyntaxError("LavalinkNode requires 'port'");
|
|
28
|
-
this.options = {
|
|
29
|
-
secure: false,
|
|
30
|
-
retryAmount: 5,
|
|
31
|
-
retryDelay: 30e3,
|
|
32
|
-
requestTimeout: 10e3,
|
|
33
|
-
...options
|
|
34
|
-
};
|
|
35
|
-
this.NodeManager = manager;
|
|
36
|
-
if (this.options.secure && this.options.port !== 443)
|
|
37
|
-
throw new SyntaxError("If secure is true, then the port must be 443");
|
|
38
|
-
this.rest = new undici_1.Pool(this.poolAddress, this.options.poolOptions);
|
|
39
|
-
this.options.regions = (this.options.regions || []).map(a => a.toLowerCase());
|
|
40
|
-
this.stats = {
|
|
41
|
-
players: 0,
|
|
42
|
-
playingPlayers: 0,
|
|
43
|
-
cpu: {
|
|
44
|
-
cores: 0,
|
|
45
|
-
lavalinkLoad: 0,
|
|
46
|
-
systemLoad: 0
|
|
47
|
-
},
|
|
48
|
-
memory: {
|
|
49
|
-
allocated: 0,
|
|
50
|
-
free: 0,
|
|
51
|
-
reservable: 0,
|
|
52
|
-
used: 0,
|
|
53
|
-
},
|
|
54
|
-
uptime: 0,
|
|
55
|
-
frameStats: {
|
|
56
|
-
deficit: 0,
|
|
57
|
-
nulled: 0,
|
|
58
|
-
sent: 0,
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Makes an API call to the Node
|
|
64
|
-
* @param endpoint The endpoint that we will make the call to
|
|
65
|
-
* @param modify Used to modify the request before being sent
|
|
66
|
-
* @returns The returned data
|
|
67
|
-
*/
|
|
68
|
-
async makeRequest(endpoint, modify, parseAsText = false) {
|
|
69
|
-
const options = {
|
|
70
|
-
path: `/${this.version}/${endpoint.replace(/^\//gm, "")}`,
|
|
71
|
-
method: "GET",
|
|
72
|
-
headers: {
|
|
73
|
-
Authorization: this.options.authorization
|
|
74
|
-
},
|
|
75
|
-
headersTimeout: this.options.requestTimeout,
|
|
76
|
-
};
|
|
77
|
-
modify?.(options);
|
|
78
|
-
const url = new URL(`${this.poolAddress}${options.path}`);
|
|
79
|
-
url.searchParams.append("trace", "true");
|
|
80
|
-
options.path = url.toString().replace(this.poolAddress, "");
|
|
81
|
-
const request = await this.rest.request(options);
|
|
82
|
-
this.calls++;
|
|
83
|
-
if (options.method === "DELETE")
|
|
84
|
-
return;
|
|
85
|
-
return parseAsText ? await request.body.text() : await request.body.json();
|
|
86
|
-
}
|
|
87
|
-
async updatePlayer(data) {
|
|
88
|
-
if (!this.sessionId)
|
|
89
|
-
throw new Error("The Lavalink Node is either not ready, or not up to date!");
|
|
90
|
-
this.syncPlayerData(data);
|
|
91
|
-
const res = await this.makeRequest(`/sessions/${this.sessionId}/players/${data.guildId}`, r => {
|
|
92
|
-
r.method = "PATCH";
|
|
93
|
-
r.headers = { Authorization: this.options.authorization, "Content-Type": "application/json" };
|
|
94
|
-
if (data.playerOptions.track)
|
|
95
|
-
delete data.playerOptions.track;
|
|
96
|
-
r.body = JSON.stringify(data.playerOptions);
|
|
97
|
-
if (data.noReplace) {
|
|
98
|
-
const url = new URL(`${this.poolAddress}${r.path}`);
|
|
99
|
-
url.searchParams.append("noReplace", data.noReplace?.toString() || "false");
|
|
100
|
-
r.path = url.toString().replace(this.poolAddress, "");
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
return this.syncPlayerData({}, res), res;
|
|
104
|
-
}
|
|
105
|
-
syncPlayerData(data, res) {
|
|
106
|
-
if (typeof data === "object" && typeof data?.guildId === "string" && typeof data.playerOptions === "object" && Object.keys(data.playerOptions).length > 1) {
|
|
107
|
-
const player = this.NodeManager.LavalinkManager.playerManager.getPlayer(data.guildId);
|
|
108
|
-
if (!player)
|
|
109
|
-
return;
|
|
110
|
-
if (typeof data.playerOptions.paused !== "undefined") {
|
|
111
|
-
player.paused = data.playerOptions.paused;
|
|
112
|
-
player.playing = !data.playerOptions.paused;
|
|
113
|
-
}
|
|
114
|
-
if (typeof data.playerOptions.position !== "undefined")
|
|
115
|
-
player.position = data.playerOptions.position;
|
|
116
|
-
if (typeof data.playerOptions.voice !== "undefined")
|
|
117
|
-
player.voice = data.playerOptions.voice;
|
|
118
|
-
if (typeof data.playerOptions.volume !== "undefined") {
|
|
119
|
-
if (this.NodeManager.LavalinkManager.options.playerOptions.volumeDecrementer) {
|
|
120
|
-
player.volume = data.playerOptions.volume / this.NodeManager.LavalinkManager.options.playerOptions.volumeDecrementer;
|
|
121
|
-
player.lavalinkVolume = data.playerOptions.volume;
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
player.volume = data.playerOptions.volume;
|
|
125
|
-
player.lavalinkVolume = data.playerOptions.volume;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
if (typeof data.playerOptions.filters !== "undefined") {
|
|
129
|
-
const oldFilterTimescale = { ...(player.filterManager.data.timescale || {}) };
|
|
130
|
-
Object.freeze(oldFilterTimescale);
|
|
131
|
-
if (data.playerOptions.filters.timescale)
|
|
132
|
-
player.filterManager.data.timescale = data.playerOptions.filters.timescale;
|
|
133
|
-
if (data.playerOptions.filters.distortion)
|
|
134
|
-
player.filterManager.data.distortion = data.playerOptions.filters.distortion;
|
|
135
|
-
if (data.playerOptions.filters.echo)
|
|
136
|
-
player.filterManager.data.echo = data.playerOptions.filters.echo;
|
|
137
|
-
if (data.playerOptions.filters.vibrato)
|
|
138
|
-
player.filterManager.data.vibrato = data.playerOptions.filters.vibrato;
|
|
139
|
-
if (data.playerOptions.filters.volume)
|
|
140
|
-
player.filterManager.data.volume = data.playerOptions.filters.volume;
|
|
141
|
-
if (data.playerOptions.filters.equalizer)
|
|
142
|
-
player.filterManager.data.equalizer = data.playerOptions.filters.equalizer;
|
|
143
|
-
if (data.playerOptions.filters.karaoke)
|
|
144
|
-
player.filterManager.data.karaoke = data.playerOptions.filters.karaoke;
|
|
145
|
-
if (data.playerOptions.filters.lowPass)
|
|
146
|
-
player.filterManager.data.lowPass = data.playerOptions.filters.lowPass;
|
|
147
|
-
if (data.playerOptions.filters.rotation)
|
|
148
|
-
player.filterManager.data.rotation = data.playerOptions.filters.rotation;
|
|
149
|
-
if (data.playerOptions.filters.tremolo)
|
|
150
|
-
player.filterManager.data.tremolo = data.playerOptions.filters.tremolo;
|
|
151
|
-
player.filterManager.checkFiltersState(oldFilterTimescale);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
// just for res
|
|
155
|
-
if (res?.guildId === "string" && typeof res?.voice !== "undefined") {
|
|
156
|
-
const player = this.NodeManager.LavalinkManager.playerManager.getPlayer(data.guildId);
|
|
157
|
-
if (!player)
|
|
158
|
-
return;
|
|
159
|
-
if (typeof res?.voice?.connected === "boolean" && res.voice.connected === false)
|
|
160
|
-
return player.destroy();
|
|
161
|
-
player.wsPing = res?.voice?.ping || player?.wsPing;
|
|
162
|
-
}
|
|
163
|
-
return true;
|
|
164
|
-
}
|
|
165
|
-
async destroyPlayer(guildId) {
|
|
166
|
-
if (!this.sessionId)
|
|
167
|
-
throw new Error("The Lavalink-Node is either not ready, or not up to date!");
|
|
168
|
-
return await this.makeRequest(`/sessions/${this.sessionId}/players/${guildId}`, r => { r.method = "DELETE"; });
|
|
169
|
-
}
|
|
170
|
-
connect() {
|
|
171
|
-
if (this.connected)
|
|
172
|
-
return;
|
|
173
|
-
const headers = {
|
|
174
|
-
Authorization: this.options.authorization,
|
|
175
|
-
"Num-Shards": String(this.NodeManager.LavalinkManager.options.client.shards || "auto"),
|
|
176
|
-
"User-Id": this.NodeManager.LavalinkManager.options.client.id,
|
|
177
|
-
"User-Name": this.NodeManager.LavalinkManager.options.client.username || "Lavalink-Client",
|
|
178
|
-
};
|
|
179
|
-
this.socket = new ws_1.default(`ws${this.options.secure ? "s" : ""}://${this.options.host}:${this.options.port}/v4/websocket`, { headers });
|
|
180
|
-
this.socket.on("open", this.open.bind(this));
|
|
181
|
-
this.socket.on("close", this.close.bind(this));
|
|
182
|
-
this.socket.on("message", this.message.bind(this));
|
|
183
|
-
this.socket.on("error", this.error.bind(this));
|
|
184
|
-
}
|
|
185
|
-
get id() {
|
|
186
|
-
return this.options.id || this.options.host;
|
|
187
|
-
}
|
|
188
|
-
destroy() {
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
|
-
/** Returns if connected to the Node. */
|
|
192
|
-
get connected() {
|
|
193
|
-
if (!this.socket)
|
|
194
|
-
return false;
|
|
195
|
-
return this.socket.readyState === ws_1.default.OPEN;
|
|
196
|
-
}
|
|
197
|
-
get poolAddress() {
|
|
198
|
-
return `http${this.options.secure ? "s" : ""}://${this.options.host}:${this.options.port}`;
|
|
199
|
-
}
|
|
200
|
-
async fetchInfo() {
|
|
201
|
-
if (!this.sessionId)
|
|
202
|
-
throw new Error("The Lavalink-Node is either not ready, or not up to date!");
|
|
203
|
-
const resInfo = await this.makeRequest(`/info`, r => r.path = `/${this.version}/info`).catch(console.warn) || null;
|
|
204
|
-
return resInfo;
|
|
205
|
-
}
|
|
206
|
-
async fetchVersion() {
|
|
207
|
-
if (!this.sessionId)
|
|
208
|
-
throw new Error("The Lavalink-Node is either not ready, or not up to date!");
|
|
209
|
-
const resInfo = await this.makeRequest(`/version`, r => r.path = "/version", true).catch(console.warn) || null;
|
|
210
|
-
return resInfo;
|
|
211
|
-
}
|
|
212
|
-
/**
|
|
213
|
-
* Gets all Players of a Node
|
|
214
|
-
*/
|
|
215
|
-
async getPlayers() {
|
|
216
|
-
if (!this.sessionId)
|
|
217
|
-
throw new Error("The Lavalink-Node is either not ready, or not up to date!");
|
|
218
|
-
const players = await this.makeRequest(`/sessions/${this.sessionId}/players`);
|
|
219
|
-
if (!Array.isArray(players))
|
|
220
|
-
return [];
|
|
221
|
-
else
|
|
222
|
-
return players;
|
|
223
|
-
}
|
|
224
|
-
/**
|
|
225
|
-
* Gets specific Player Information
|
|
226
|
-
*/
|
|
227
|
-
async getPlayer(guildId) {
|
|
228
|
-
if (!this.sessionId)
|
|
229
|
-
throw new Error("The Lavalink-Node is either not ready, or not up to date!");
|
|
230
|
-
return await this.makeRequest(`/sessions/${this.sessionId}/players/${guildId}`);
|
|
231
|
-
}
|
|
232
|
-
/**
|
|
233
|
-
* Updates the session with a resuming key and timeout
|
|
234
|
-
* @param resumingKey
|
|
235
|
-
* @param timeout
|
|
236
|
-
*/
|
|
237
|
-
async updateSession(resumingKey, timeout) {
|
|
238
|
-
if (!this.sessionId)
|
|
239
|
-
throw new Error("the Lavalink-Node is either not ready, or not up to date!");
|
|
240
|
-
return await this.makeRequest(`/sessions/${this.sessionId}`, r => {
|
|
241
|
-
r.method = "PATCH";
|
|
242
|
-
r.headers = { Authorization: this.options.authorization, 'Content-Type': 'application/json' };
|
|
243
|
-
r.body = JSON.stringify({ resumingKey, timeout });
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
/**
|
|
247
|
-
* Get routplanner Info from Lavalink
|
|
248
|
-
*/
|
|
249
|
-
async getRoutePlannerStatus() {
|
|
250
|
-
if (!this.sessionId)
|
|
251
|
-
throw new Error("the Lavalink-Node is either not ready, or not up to date!");
|
|
252
|
-
return await this.makeRequest(`/routeplanner/status`);
|
|
253
|
-
}
|
|
254
|
-
/**
|
|
255
|
-
* Release blacklisted IP address into pool of IPs
|
|
256
|
-
* @param address IP address
|
|
257
|
-
*/
|
|
258
|
-
async unmarkFailedAddress(address) {
|
|
259
|
-
if (!this.sessionId)
|
|
260
|
-
throw new Error("the Lavalink-Node is either not ready, or not up to date!");
|
|
261
|
-
await this.makeRequest(`/routeplanner/free/address`, r => {
|
|
262
|
-
r.method = "POST";
|
|
263
|
-
r.headers = { Authorization: this.options.authorization, 'Content-Type': 'application/json' };
|
|
264
|
-
r.body = JSON.stringify({ address });
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
|
-
/**
|
|
268
|
-
* Release blacklisted IP address into pool of IPs
|
|
269
|
-
* @param address IP address
|
|
270
|
-
*/
|
|
271
|
-
async unmarkAllFailedAddresses() {
|
|
272
|
-
if (!this.sessionId)
|
|
273
|
-
throw new Error("the Lavalink-Node is either not ready, or not up to date!");
|
|
274
|
-
await this.makeRequest(`/routeplanner/free/all`, r => {
|
|
275
|
-
r.method = "POST";
|
|
276
|
-
r.headers = { Authorization: this.options.authorization, 'Content-Type': 'application/json' };
|
|
277
|
-
});
|
|
278
|
-
}
|
|
279
|
-
reconnect() {
|
|
280
|
-
this.reconnectTimeout = setTimeout(() => {
|
|
281
|
-
if (this.reconnectAttempts >= this.options.retryAmount) {
|
|
282
|
-
const error = new Error(`Unable to connect after ${this.options.retryAmount} attempts.`);
|
|
283
|
-
this.NodeManager.emit("error", this, error);
|
|
284
|
-
return this.destroy();
|
|
285
|
-
}
|
|
286
|
-
this.socket.removeAllListeners();
|
|
287
|
-
this.socket = null;
|
|
288
|
-
this.NodeManager.emit("reconnecting", this);
|
|
289
|
-
this.connect();
|
|
290
|
-
this.reconnectAttempts++;
|
|
291
|
-
}, this.options.retryDelay);
|
|
292
|
-
}
|
|
293
|
-
open() {
|
|
294
|
-
if (this.reconnectTimeout)
|
|
295
|
-
clearTimeout(this.reconnectTimeout);
|
|
296
|
-
this.NodeManager.emit("connect", this);
|
|
297
|
-
setTimeout(() => {
|
|
298
|
-
this.fetchInfo().then(x => this.info = x).catch(() => null).then(() => {
|
|
299
|
-
if (!this.info && ["v3", "v4"].includes(this.version)) {
|
|
300
|
-
const errorString = `Lavalink Node (${this.poolAddress}) does not provide any /${this.version}/info`;
|
|
301
|
-
throw new Error(errorString);
|
|
302
|
-
}
|
|
303
|
-
});
|
|
304
|
-
}, 1500);
|
|
305
|
-
}
|
|
306
|
-
close(code, reason) {
|
|
307
|
-
this.NodeManager.emit("disconnect", this, { code, reason });
|
|
308
|
-
if (code !== 1000 || reason !== "destroy")
|
|
309
|
-
this.reconnect();
|
|
310
|
-
}
|
|
311
|
-
error(error) {
|
|
312
|
-
if (!error)
|
|
313
|
-
return;
|
|
314
|
-
this.NodeManager.emit("error", this, error);
|
|
315
|
-
}
|
|
316
|
-
async message(d) {
|
|
317
|
-
if (Array.isArray(d))
|
|
318
|
-
d = Buffer.concat(d);
|
|
319
|
-
else if (d instanceof ArrayBuffer)
|
|
320
|
-
d = Buffer.from(d);
|
|
321
|
-
const payload = JSON.parse(d.toString());
|
|
322
|
-
if (!payload.op)
|
|
323
|
-
return;
|
|
324
|
-
this.NodeManager.emit("raw", this, payload);
|
|
325
|
-
switch (payload.op) {
|
|
326
|
-
case "stats":
|
|
327
|
-
delete payload.op;
|
|
328
|
-
this.stats = { ...payload };
|
|
329
|
-
break;
|
|
330
|
-
case "playerUpdate":
|
|
331
|
-
const player = this.NodeManager.LavalinkManager.playerManager.getPlayer(payload.guildId);
|
|
332
|
-
if (!player)
|
|
333
|
-
return;
|
|
334
|
-
if (player.get("internal_updateInterval"))
|
|
335
|
-
clearInterval(player.get("internal_updateInterval"));
|
|
336
|
-
player.position = payload.state.position || 0;
|
|
337
|
-
player.set("internal_lastposition", player.position);
|
|
338
|
-
player.connected = payload.state.connected;
|
|
339
|
-
player.wsPing = payload.state.ping >= 0 ? payload.state.ping : player.wsPing <= 0 && player.connected ? null : player.wsPing || 0;
|
|
340
|
-
if (!player.createdTimeStamp && payload.state.time)
|
|
341
|
-
player.createdTimeStamp = payload.sate.time;
|
|
342
|
-
if (typeof this.NodeManager.LavalinkManager.options.playerOptions.clientBasedUpdateInterval === "number" && this.NodeManager.LavalinkManager.options.playerOptions.clientBasedUpdateInterval >= 10) {
|
|
343
|
-
player.set("internal_updateInterval", setInterval(() => {
|
|
344
|
-
player.position += this.NodeManager.LavalinkManager.options.playerOptions.clientBasedUpdateInterval || 250;
|
|
345
|
-
player.set("internal_lastposition", player.position);
|
|
346
|
-
if (player.filterManager.filterUpdatedState >= 1) {
|
|
347
|
-
player.filterManager.filterUpdatedState++;
|
|
348
|
-
const maxMins = 8;
|
|
349
|
-
const currentDuration = player.queue.currentTrack?.info?.duration || 0;
|
|
350
|
-
if (currentDuration <= maxMins * 6e4 || (0, node_path_1.isAbsolute)(player.queue.currentTrack?.info?.uri)) {
|
|
351
|
-
if (player.filterManager.filterUpdatedState >= ((this.NodeManager.LavalinkManager.options.playerOptions.clientBasedUpdateInterval || 250) > 400 ? 2 : 3)) {
|
|
352
|
-
player.filterManager.filterUpdatedState = 0;
|
|
353
|
-
player.seek(player.position);
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
else {
|
|
357
|
-
player.filterManager.filterUpdatedState = 0;
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
}, this.NodeManager.LavalinkManager.options.playerOptions.clientBasedUpdateInterval || 250));
|
|
361
|
-
}
|
|
362
|
-
else {
|
|
363
|
-
if (player.filterManager.filterUpdatedState >= 1) { // if no interval but instafix available, findable via the "filterUpdatedState" property
|
|
364
|
-
const maxMins = 8;
|
|
365
|
-
const currentDuration = player.queue.currentTrack?.info?.duration || 0;
|
|
366
|
-
if (currentDuration <= maxMins * 6e4 || (0, node_path_1.isAbsolute)(player.queue.currentTrack?.info?.uri))
|
|
367
|
-
player.seek(player.position);
|
|
368
|
-
player.filterManager.filterUpdatedState = 0;
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
break;
|
|
372
|
-
case "event":
|
|
373
|
-
this.handleEvent(payload);
|
|
374
|
-
break;
|
|
375
|
-
case "ready": // payload: { resumed: false, sessionId: 'ytva350aevn6n9n8', op: 'ready' }
|
|
376
|
-
this.sessionId = payload.sessionId;
|
|
377
|
-
break;
|
|
378
|
-
default:
|
|
379
|
-
this.NodeManager.emit("error", this, new Error(`Unexpected op "${payload.op}" with data`), payload);
|
|
380
|
-
return;
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
async handleEvent(payload) {
|
|
384
|
-
if (!payload.guildId)
|
|
385
|
-
return;
|
|
386
|
-
const player = this.NodeManager.LavalinkManager.playerManager.getPlayer(payload.guildId);
|
|
387
|
-
if (!player)
|
|
388
|
-
return;
|
|
389
|
-
switch (payload.type) {
|
|
390
|
-
case "TrackStartEvent":
|
|
391
|
-
this.trackStart(player, player.queue.currentTrack, payload);
|
|
392
|
-
break;
|
|
393
|
-
case "TrackEndEvent":
|
|
394
|
-
this.trackEnd(player, player.queue.currentTrack, payload);
|
|
395
|
-
break;
|
|
396
|
-
case "TrackStuckEvent":
|
|
397
|
-
this.trackStuck(player, player.queue.currentTrack, payload);
|
|
398
|
-
break;
|
|
399
|
-
case "TrackExceptionEvent":
|
|
400
|
-
this.trackError(player, player.queue.currentTrack, payload);
|
|
401
|
-
break;
|
|
402
|
-
case "WebSocketClosedEvent":
|
|
403
|
-
this.socketClosed(player, payload);
|
|
404
|
-
break;
|
|
405
|
-
default:
|
|
406
|
-
this.NodeManager.emit("error", this, new Error(`Node#event unknown event '${payload.type}'.`), payload);
|
|
407
|
-
break;
|
|
408
|
-
}
|
|
409
|
-
return;
|
|
410
|
-
}
|
|
411
|
-
trackStart(player, track, payload) {
|
|
412
|
-
player.playing = true;
|
|
413
|
-
player.paused = false;
|
|
414
|
-
return this.NodeManager.LavalinkManager.playerManager.emit("trackStart", player, track, payload);
|
|
415
|
-
}
|
|
416
|
-
async trackEnd(player, track, payload) {
|
|
417
|
-
// If there are no songs in the queue
|
|
418
|
-
if (!player.queue.size && player.repeatMode === "off")
|
|
419
|
-
return this.queueEnd(player, player.queue.currentTrack, payload);
|
|
420
|
-
// If a track was forcibly played
|
|
421
|
-
if (payload.reason === "REPLACED")
|
|
422
|
-
return this.NodeManager.LavalinkManager.playerManager.emit("trackEnd", player, track, payload);
|
|
423
|
-
// If a track had an error while starting
|
|
424
|
-
if (["LOAD_FAILED", "CLEAN_UP"].includes(payload.reason)) {
|
|
425
|
-
await player.queue._trackEnd();
|
|
426
|
-
if (!player.queue.currentTrack)
|
|
427
|
-
return this.queueEnd(player, player.queue.currentTrack, payload);
|
|
428
|
-
this.NodeManager.LavalinkManager.playerManager.emit("trackEnd", player, track, payload);
|
|
429
|
-
return this.NodeManager.LavalinkManager.options.autoSkip && player.play({ track: player.queue.currentTrack });
|
|
430
|
-
}
|
|
431
|
-
// remove tracks from the queue
|
|
432
|
-
if (player.repeatMode !== "track")
|
|
433
|
-
await player.queue._trackEnd(player.repeatMode === "queue");
|
|
434
|
-
// if no track available, end queue
|
|
435
|
-
if (!player.queue.currentTrack)
|
|
436
|
-
return this.queueEnd(player, player.queue.currentTrack, payload);
|
|
437
|
-
// fire event
|
|
438
|
-
this.NodeManager.LavalinkManager.playerManager.emit("trackEnd", player, track, payload);
|
|
439
|
-
// play track if autoSkip is true
|
|
440
|
-
return this.NodeManager.LavalinkManager.options.autoSkip && player.play({ track: player.queue.currentTrack });
|
|
441
|
-
}
|
|
442
|
-
async queueEnd(player, track, payload) {
|
|
443
|
-
player.queue.setCurrent(null);
|
|
444
|
-
player.playing = false;
|
|
445
|
-
return this.NodeManager.LavalinkManager.playerManager.emit("queueEnd", player, track, payload);
|
|
446
|
-
}
|
|
447
|
-
async trackStuck(player, track, payload) {
|
|
448
|
-
this.NodeManager.LavalinkManager.playerManager.emit("trackStuck", player, track, payload);
|
|
449
|
-
// If there are no songs in the queue
|
|
450
|
-
if (!player.queue.size && player.repeatMode === "off")
|
|
451
|
-
return; // this.queueEnd(player, queue, payload);
|
|
452
|
-
// player.stop()
|
|
453
|
-
}
|
|
454
|
-
trackError(player, track, payload) {
|
|
455
|
-
this.NodeManager.LavalinkManager.playerManager.emit("trackError", player, track, payload);
|
|
456
|
-
// player.stop();
|
|
457
|
-
}
|
|
458
|
-
socketClosed(player, payload) {
|
|
459
|
-
return this.NodeManager.LavalinkManager.playerManager.emit("socketClosed", player, payload);
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
exports.LavalinkNode = LavalinkNode;
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import { EventEmitter } from "stream";
|
|
3
|
-
import { LavalinkNode, LavalinkNodeOptions } from "./Node";
|
|
4
|
-
import { LavalinkManager } from "./LavalinkManager";
|
|
5
|
-
interface NodeManagerEvents {
|
|
6
|
-
/**
|
|
7
|
-
* Emitted when a Node is created.
|
|
8
|
-
* @event Manager.nodeManager#create
|
|
9
|
-
*/
|
|
10
|
-
"create": (node: LavalinkNode) => void;
|
|
11
|
-
/**
|
|
12
|
-
* Emitted when a Node is destroyed.
|
|
13
|
-
* @event Manager.nodeManager#destroy
|
|
14
|
-
*/
|
|
15
|
-
"destroy": (node: LavalinkNode) => void;
|
|
16
|
-
/**
|
|
17
|
-
* Emitted when a Node is connected.
|
|
18
|
-
* @event Manager.nodeManager#connect
|
|
19
|
-
*/
|
|
20
|
-
"connect": (node: LavalinkNode) => void;
|
|
21
|
-
/**
|
|
22
|
-
* Emitted when a Node is reconnecting.
|
|
23
|
-
* @event Manager.nodeManager#reconnecting
|
|
24
|
-
*/
|
|
25
|
-
"reconnecting": (node: LavalinkNode) => void;
|
|
26
|
-
/**
|
|
27
|
-
* Emitted when a Node is disconnects.
|
|
28
|
-
* @event Manager.nodeManager#disconnect
|
|
29
|
-
*/
|
|
30
|
-
"disconnect": (node: LavalinkNode, reason: {
|
|
31
|
-
code?: number;
|
|
32
|
-
reason?: string;
|
|
33
|
-
}) => void;
|
|
34
|
-
/**
|
|
35
|
-
* Emitted when a Node is error.
|
|
36
|
-
* @event Manager.nodeManager#error
|
|
37
|
-
*/
|
|
38
|
-
"error": (node: LavalinkNode, error: Error, payload?: unknown) => void;
|
|
39
|
-
/**
|
|
40
|
-
* Emits every single Node event.
|
|
41
|
-
* @event Manager.nodeManager#raw
|
|
42
|
-
*/
|
|
43
|
-
"raw": (node: LavalinkNode, payload: unknown) => void;
|
|
44
|
-
}
|
|
45
|
-
export declare interface NodeManager {
|
|
46
|
-
on<U extends keyof NodeManagerEvents>(event: U, listener: NodeManagerEvents[U]): this;
|
|
47
|
-
emit<U extends keyof NodeManagerEvents>(event: U, ...args: Parameters<NodeManagerEvents[U]>): boolean;
|
|
48
|
-
/** @private */
|
|
49
|
-
LavalinkManager: LavalinkManager;
|
|
50
|
-
}
|
|
51
|
-
export declare class NodeManager extends EventEmitter {
|
|
52
|
-
nodes: Map<string, LavalinkNode>;
|
|
53
|
-
constructor(LavalinkManager: LavalinkManager);
|
|
54
|
-
createNode(options: LavalinkNodeOptions): LavalinkNode;
|
|
55
|
-
get leastUsedNodes(): LavalinkNode[];
|
|
56
|
-
deleteNode(options: LavalinkNodeOptions): void;
|
|
57
|
-
}
|
|
58
|
-
export {};
|