lavalink-client 1.0.4 → 1.0.6
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 +33 -98
- package/dist/cjs/structures/LavalinkManager.d.ts +19 -14
- package/dist/cjs/structures/LavalinkManager.js +3 -14
- package/dist/cjs/structures/Node.d.ts +3 -3
- package/dist/cjs/structures/Node.js +16 -11
- package/dist/cjs/structures/NodeManager.d.ts +1 -12
- package/dist/cjs/structures/NodeManager.js +53 -60
- package/dist/cjs/structures/Player.d.ts +4 -4
- package/dist/cjs/structures/Player.js +20 -7
- package/dist/cjs/structures/Queue.d.ts +9 -9
- package/dist/cjs/structures/Queue.js +24 -23
- package/dist/cjs/structures/Track.d.ts +14 -3
- package/dist/cjs/structures/Utils.d.ts +20 -5
- package/dist/cjs/structures/Utils.js +135 -15
- package/dist/esm/structures/LavalinkManager.d.ts +19 -14
- package/dist/esm/structures/LavalinkManager.js +3 -14
- package/dist/esm/structures/Node.d.ts +3 -3
- package/dist/esm/structures/Node.js +16 -11
- package/dist/esm/structures/NodeManager.d.ts +1 -12
- package/dist/esm/structures/NodeManager.js +53 -60
- package/dist/esm/structures/Player.d.ts +4 -4
- package/dist/esm/structures/Player.js +20 -7
- package/dist/esm/structures/Queue.d.ts +9 -9
- package/dist/esm/structures/Queue.js +25 -24
- package/dist/esm/structures/Track.d.ts +14 -3
- package/dist/esm/structures/Utils.d.ts +20 -5
- package/dist/esm/structures/Utils.js +135 -15
- package/dist/types/structures/LavalinkManager.d.ts +19 -14
- package/dist/types/structures/Node.d.ts +3 -3
- package/dist/types/structures/NodeManager.d.ts +1 -12
- package/dist/types/structures/Player.d.ts +4 -4
- package/dist/types/structures/Queue.d.ts +9 -9
- package/dist/types/structures/Track.d.ts +14 -3
- package/dist/types/structures/Utils.d.ts +20 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,17 +1,43 @@
|
|
|
1
|
-
#
|
|
2
|
-
Easy and advanced lavalink client. Use it with lavalink plugins as well as latest lavalink versions
|
|
1
|
+
# Lavalink Client
|
|
2
|
+
Easy and advanced lavalink client. Use it with lavalink plugins as well as latest lavalink versions.
|
|
3
3
|
|
|
4
4
|
# Install
|
|
5
5
|
|
|
6
6
|
Latest stable Version: (currently, unreleased)
|
|
7
|
-
|
|
7
|
+
|
|
8
|
+
<details><summary>👉 via NPM</summary>
|
|
9
|
+
|
|
10
|
+
```bash
|
|
8
11
|
npm install --save lavalink-client
|
|
9
12
|
```
|
|
13
|
+
|
|
14
|
+
|
|
10
15
|
Dev Version: (Current)
|
|
11
|
-
|
|
16
|
+
|
|
17
|
+
```bash
|
|
12
18
|
npm install tomato6966/lavalink-client
|
|
13
19
|
```
|
|
14
20
|
|
|
21
|
+
</details>
|
|
22
|
+
|
|
23
|
+
<details><summary>👉 via YARN</summary>
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
yarn add lavalink-client
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Dev Version: (Current)
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
yarn add tomato6966/lavalink-client
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
</details>
|
|
36
|
+
|
|
37
|
+
# Documentation
|
|
38
|
+
|
|
39
|
+
Check out the [Documentation](https://lc4.gitbook.io/lavalink-client) for **Examples**, and **__detailled__ Docs**, and to figure out **how to get started**. *note: it's not fully done yet (see the docs)*
|
|
40
|
+
|
|
15
41
|
# Features
|
|
16
42
|
|
|
17
43
|
- 💯 Lavalink v4 Supported only (with Lavalink Plugins)
|
|
@@ -21,6 +47,8 @@ npm install tomato6966/lavalink-client
|
|
|
21
47
|
|
|
22
48
|
- ✨ Choose able queue stores (maps, collections, redis, databases, ...)
|
|
23
49
|
- You can create your own queueStore, thus make it easy to sync queues accross multiple connections (e.g. dashboard-bot)
|
|
50
|
+
- Automated Queue Sync methods
|
|
51
|
+
- Automated unresolveable Tracks (save the queries as Partial Track Objects -> Fetch the tracks only once they are gonna play)
|
|
24
52
|
|
|
25
53
|
- 😍 Included Filter & Equalizer Management
|
|
26
54
|
|
|
@@ -41,98 +69,5 @@ npm install tomato6966/lavalink-client
|
|
|
41
69
|
- Destroys the player on channeldelete
|
|
42
70
|
- Pauses / resumes the player if it get's muted / unmuted (server-wide) [soon]
|
|
43
71
|
- ...
|
|
44
|
-
- 😁 Much much more!
|
|
45
|
-
|
|
46
|
-
# Documentation
|
|
47
|
-
|
|
48
|
-
*soon*
|
|
49
|
-
|
|
50
|
-
# How to Use
|
|
51
|
-
|
|
52
|
-
1. Import the Manager
|
|
53
|
-
|
|
54
|
-
```ts
|
|
55
|
-
import { LavalinkManager } from "lavalink-client"; // Modular JS / Typescript
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
```js
|
|
59
|
-
const { LavalinkManager } = require("lavalink-client"); // Common Js
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
2. create the Manager
|
|
63
|
-
|
|
64
|
-
```ts
|
|
65
|
-
// Suggest it to extend it to the bot Client
|
|
66
|
-
client.lavalink = new LavalinkManager({
|
|
67
|
-
nodes: [
|
|
68
|
-
{
|
|
69
|
-
authorization: "youshallnotpass",
|
|
70
|
-
host: "localhost",
|
|
71
|
-
port: 2333,
|
|
72
|
-
id: "testnode",
|
|
73
|
-
requestTimeout: 10000,
|
|
74
|
-
}
|
|
75
|
-
],
|
|
76
|
-
sendToShard: (guildId, payload) => client.guilds.cache.get(guildId)?.shard?.send(payload),
|
|
77
|
-
autoSkip: true,
|
|
78
|
-
client: {
|
|
79
|
-
id: envConfig.clientId,
|
|
80
|
-
username: "TESTBOT",
|
|
81
|
-
shards: "auto"
|
|
82
|
-
},
|
|
83
|
-
playerOptions: {
|
|
84
|
-
applyVolumeAsFilter: false,
|
|
85
|
-
clientBasedUpdateInterval: 50,
|
|
86
|
-
defaultSearchPlatform: "dzsearch",
|
|
87
|
-
volumeDecrementer: 0.7
|
|
88
|
-
},
|
|
89
|
-
queueOptions: {
|
|
90
|
-
maxPreviousTracks: 5
|
|
91
|
-
},
|
|
92
|
-
// queueStore: new myCustomStore(client.redis), // OPTIONAL! 'class myCustomStore extends DefaultQueueStore' --> for custom queue stores, e.g. redis, etc. | default is lavalink-client#MiniMap
|
|
93
|
-
// queueChangesWatcher: new myCustomWatcher(), // OPTIONAL! 'class myCustomWatcher extends QueueChangesWatcher' --> for queue action logs!
|
|
94
|
-
});
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
3. **VERY IMPORTANT!** - Register Voice State updates + initialize the Manager
|
|
98
|
-
|
|
99
|
-
```ts
|
|
100
|
-
client.on("raw", d => client.lavalink.sendRawData(d)); // for voice state updates!
|
|
101
|
-
client.on("ready", async () => {
|
|
102
|
-
console.log("Discord Bot is ready to be Used!");
|
|
103
|
-
// user.id is required, user.shards (not), user.username (not, but recommended for lavalink stats!)
|
|
104
|
-
await client.lavalink.init({ ...client.user!, shards: "auto" });
|
|
105
|
-
});
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
4. **Use it!**
|
|
109
|
-
|
|
110
|
-
```ts
|
|
111
|
-
// create player
|
|
112
|
-
const player = await client.lavalink.createPlayer({
|
|
113
|
-
guildId: guild.id, voiceChannelId: voice.id, textChannelId: text.id, // in what guild + channel(s)
|
|
114
|
-
selfDeaf: true, selfMute: false, volume: 100 // configuration(s)
|
|
115
|
-
});
|
|
116
|
-
// connect the player to it's vc
|
|
117
|
-
await player.connect();
|
|
118
|
-
|
|
119
|
-
const res = await player.search({
|
|
120
|
-
query: `Elton John`, // source: `soundcloud`,
|
|
121
|
-
}, client.user); // search a query (query-search, url search, identifier search, etc.)
|
|
122
|
-
|
|
123
|
-
await player.queue.add(res.tracks); // add 1 track, or an array of tracks
|
|
124
|
-
await player.play(); // you can provide specific track, or let the manager choose the track from the queue!
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
## Example (typescript)
|
|
128
|
-
|
|
129
|
-
Can be found in the [`/testBot`](https://github.com/Tomato6966/lavalink-client/blob/main/testBot/README.md) Directory
|
|
130
|
-
|
|
131
|
-
It contains the following features:
|
|
132
72
|
|
|
133
|
-
-
|
|
134
|
-
- Example Use for `Queue Changes Watcher Logger`
|
|
135
|
-
- Example Use for `Filters`, `Audio Output`, `equalizers`
|
|
136
|
-
- How to make an easy, yet advanced `Slash Commands Only Bot`
|
|
137
|
-
- `Slim Memory Usage`
|
|
138
|
-
- `All lavalink-client events` displayments
|
|
73
|
+
- 😁 Much much more!
|
|
@@ -5,14 +5,15 @@ import { QueueSaverOptions } from "./Queue";
|
|
|
5
5
|
import { GuildShardPayload, LavalinkSearchPlatform, ManagerUitls, MiniMap, SearchPlatform, TrackEndEvent, TrackExceptionEvent, TrackStartEvent, TrackStuckEvent, VoicePacket, VoiceServer, VoiceState, WebSocketClosedEvent } from "./Utils";
|
|
6
6
|
import { LavalinkNodeOptions } from "./Node";
|
|
7
7
|
import { DestroyReasonsType, Player, PlayerOptions } from "./Player";
|
|
8
|
-
import { Track } from "./Track";
|
|
8
|
+
import { Track, UnresolvedTrack } from "./Track";
|
|
9
9
|
export interface LavalinkManager {
|
|
10
10
|
nodeManager: NodeManager;
|
|
11
11
|
utils: ManagerUitls;
|
|
12
12
|
}
|
|
13
13
|
export interface BotClientOptions {
|
|
14
|
-
|
|
14
|
+
/** Bot Client Id */
|
|
15
15
|
id: string;
|
|
16
|
+
/** Bot Client Username */
|
|
16
17
|
username?: string;
|
|
17
18
|
/** So users can pass entire objects / classes */
|
|
18
19
|
[x: string | number | symbol | undefined]: any;
|
|
@@ -40,6 +41,7 @@ export interface LavalinkPlayerOptions {
|
|
|
40
41
|
autoPlayFunction?: (player: Player, lastPlayedTrack: Track) => Promise<void>;
|
|
41
42
|
destroyAfterMs?: number;
|
|
42
43
|
};
|
|
44
|
+
useUnresolvedData?: boolean;
|
|
43
45
|
}
|
|
44
46
|
export interface ManagerOptions {
|
|
45
47
|
nodes: LavalinkNodeOptions[];
|
|
@@ -47,40 +49,38 @@ export interface ManagerOptions {
|
|
|
47
49
|
client?: BotClientOptions;
|
|
48
50
|
playerOptions?: LavalinkPlayerOptions;
|
|
49
51
|
autoSkip?: boolean;
|
|
50
|
-
defaultLeastUsedNodeSortType?: "memory" | "calls" | "players";
|
|
51
|
-
defaultLeastLoadNodeSortType?: "cpu" | "memory";
|
|
52
52
|
/** @async */
|
|
53
53
|
sendToShard: (guildId: string, payload: GuildShardPayload) => void;
|
|
54
54
|
}
|
|
55
55
|
interface LavalinkManagerEvents {
|
|
56
56
|
/**
|
|
57
57
|
* Emitted when a Track started playing.
|
|
58
|
-
* @event Manager
|
|
58
|
+
* @event Manager#trackStart
|
|
59
59
|
*/
|
|
60
60
|
"trackStart": (player: Player, track: Track, payload: TrackStartEvent) => void;
|
|
61
61
|
/**
|
|
62
62
|
* Emitted when a Track finished.
|
|
63
|
-
* @event Manager
|
|
63
|
+
* @event Manager#trackEnd
|
|
64
64
|
*/
|
|
65
65
|
"trackEnd": (player: Player, track: Track, payload: TrackEndEvent) => void;
|
|
66
66
|
/**
|
|
67
67
|
* Emitted when a Track got stuck while playing.
|
|
68
|
-
* @event Manager
|
|
68
|
+
* @event Manager#trackStuck
|
|
69
69
|
*/
|
|
70
70
|
"trackStuck": (player: Player, track: Track, payload: TrackStuckEvent) => void;
|
|
71
71
|
/**
|
|
72
72
|
* Emitted when a Track errored.
|
|
73
|
-
* @event Manager
|
|
73
|
+
* @event Manager#trackError
|
|
74
74
|
*/
|
|
75
|
-
"trackError": (player: Player, track: Track, payload: TrackExceptionEvent) => void;
|
|
75
|
+
"trackError": (player: Player, track: Track | UnresolvedTrack, payload: TrackExceptionEvent) => void;
|
|
76
76
|
/**
|
|
77
77
|
* Emitted when the Playing finished and no more tracks in the queue.
|
|
78
|
-
* @event Manager
|
|
78
|
+
* @event Manager#queueEnd
|
|
79
79
|
*/
|
|
80
80
|
"queueEnd": (player: Player, track: Track, payload: TrackEndEvent | TrackStuckEvent | TrackExceptionEvent) => void;
|
|
81
81
|
/**
|
|
82
82
|
* Emitted when a Player is created.
|
|
83
|
-
* @event Manager
|
|
83
|
+
* @event Manager#playerCreate
|
|
84
84
|
*/
|
|
85
85
|
"playerCreate": (player: Player) => void;
|
|
86
86
|
/**
|
|
@@ -90,19 +90,24 @@ interface LavalinkManagerEvents {
|
|
|
90
90
|
"playerMove": (player: Player, oldVoiceChannelId: string, newVoiceChannelId: string) => void;
|
|
91
91
|
/**
|
|
92
92
|
* Emitted when a Player is disconnected from a channel.
|
|
93
|
-
* @event Manager
|
|
93
|
+
* @event Manager#playerDisconnect
|
|
94
94
|
*/
|
|
95
95
|
"playerDisconnect": (player: Player, voiceChannelId: string) => void;
|
|
96
96
|
/**
|
|
97
97
|
* Emitted when a Node-Socket got closed for a specific Player.
|
|
98
|
-
* @event Manager
|
|
98
|
+
* @event Manager#playerSocketClosed
|
|
99
99
|
*/
|
|
100
100
|
"playerSocketClosed": (player: Player, payload: WebSocketClosedEvent) => void;
|
|
101
101
|
/**
|
|
102
102
|
* Emitted when a Player get's destroyed
|
|
103
|
-
* @event Manager
|
|
103
|
+
* @event Manager#playerDestroy
|
|
104
104
|
*/
|
|
105
105
|
"playerDestroy": (player: Player, destroyReason?: DestroyReasonsType) => void;
|
|
106
|
+
/**
|
|
107
|
+
* Always emits when the player (on lavalink side) got updated
|
|
108
|
+
* @event Manager#playerUpdate
|
|
109
|
+
*/
|
|
110
|
+
"playerUpdate": (player: Player) => void;
|
|
106
111
|
}
|
|
107
112
|
export interface LavalinkManager {
|
|
108
113
|
options: ManagerOptions;
|
|
@@ -45,10 +45,6 @@ class LavalinkManager extends events_1.EventEmitter {
|
|
|
45
45
|
};
|
|
46
46
|
if (!this.options.autoSkip)
|
|
47
47
|
this.options.autoSkip = true;
|
|
48
|
-
if (!this.options.defaultLeastLoadNodeSortType)
|
|
49
|
-
this.options.defaultLeastLoadNodeSortType = "memory";
|
|
50
|
-
if (!this.options.defaultLeastUsedNodeSortType)
|
|
51
|
-
this.options.defaultLeastUsedNodeSortType = "players";
|
|
52
48
|
if (!this.options.playerOptions.defaultSearchPlatform)
|
|
53
49
|
this.options.playerOptions.defaultSearchPlatform = "ytsearch";
|
|
54
50
|
// default queue options
|
|
@@ -66,13 +62,9 @@ class LavalinkManager extends events_1.EventEmitter {
|
|
|
66
62
|
if (typeof options.sendToShard !== "function")
|
|
67
63
|
throw new SyntaxError("ManagerOption.sendToShard was not provided, which is required!");
|
|
68
64
|
// only check in .init()
|
|
69
|
-
// if(typeof options.client !== "object" || typeof options.client.id !== "string") throw new SyntaxError("ManagerOption.client = { id: string, username?:string
|
|
65
|
+
// if(typeof options.client !== "object" || typeof options.client.id !== "string") throw new SyntaxError("ManagerOption.client = { id: string, username?:string } was not provided, which is required");
|
|
70
66
|
if (options.autoSkip && typeof options.autoSkip !== "boolean")
|
|
71
67
|
throw new SyntaxError("ManagerOption.autoSkip must be either false | true aka boolean");
|
|
72
|
-
if (options.defaultLeastLoadNodeSortType && !["memory", "cpu"].includes(options.defaultLeastLoadNodeSortType))
|
|
73
|
-
throw new SyntaxError("ManagerOption.defaultLeastLoadNodeSortType must be 'memory' | 'cpu'");
|
|
74
|
-
if (options.defaultLeastUsedNodeSortType && !["memory", "players", "calls"].includes(options.defaultLeastUsedNodeSortType))
|
|
75
|
-
throw new SyntaxError("ManagerOption.defaultLeastLoadNodeSortType must be 'memory' | 'calls' | 'players'");
|
|
76
68
|
if (!options.nodes || !Array.isArray(options.nodes) || !options.nodes.every(node => this.utils.isNodeOptions(node)))
|
|
77
69
|
throw new SyntaxError("ManagerOption.nodes must be an Array of NodeOptions and is required of at least 1 Node");
|
|
78
70
|
/* QUEUE STORE */
|
|
@@ -157,9 +149,7 @@ class LavalinkManager extends events_1.EventEmitter {
|
|
|
157
149
|
* @param data
|
|
158
150
|
*/
|
|
159
151
|
async sendRawData(data) {
|
|
160
|
-
if (!this.initiated)
|
|
161
|
-
return;
|
|
162
|
-
if (!("t" in data))
|
|
152
|
+
if (!this.initiated || !("t" in data))
|
|
163
153
|
return;
|
|
164
154
|
// for channel Delete
|
|
165
155
|
if ("CHANNEL_DELETE" === data.t) {
|
|
@@ -167,9 +157,8 @@ class LavalinkManager extends events_1.EventEmitter {
|
|
|
167
157
|
if (!update.guild_id)
|
|
168
158
|
return;
|
|
169
159
|
const player = this.getPlayer(update.guild_id);
|
|
170
|
-
if (player.voiceChannelId === update.id)
|
|
160
|
+
if (player && player.voiceChannelId === update.id)
|
|
171
161
|
return player.destroy(Player_1.DestroyReasons.ChannelDeleted);
|
|
172
|
-
}
|
|
173
162
|
}
|
|
174
163
|
// for voice updates
|
|
175
164
|
if (["VOICE_STATE_UPDATE", "VOICE_SERVER_UPDATE"].includes(data.t)) {
|
|
@@ -4,7 +4,7 @@ import { NodeManager } from "./NodeManager";
|
|
|
4
4
|
import internal from "stream";
|
|
5
5
|
import { InvalidLavalinkRestRequest, LavalinkPlayer, PlayerUpdateInfo, RoutePlanner, Session, Base64 } from "./Utils";
|
|
6
6
|
import { DestroyReasonsType } from "./Player";
|
|
7
|
-
import {
|
|
7
|
+
import { Track } from "./Track";
|
|
8
8
|
/** Modifies any outgoing REST requests. */
|
|
9
9
|
export type ModifyRequest = (options: Dispatcher.RequestOptions) => void;
|
|
10
10
|
export interface LavalinkNodeOptions {
|
|
@@ -185,13 +185,13 @@ export declare class LavalinkNode {
|
|
|
185
185
|
* @param encoded
|
|
186
186
|
* @returns
|
|
187
187
|
*/
|
|
188
|
-
singleTrack: (encoded: Base64) => Promise<
|
|
188
|
+
singleTrack: (encoded: Base64, requester: unknown) => Promise<Track>;
|
|
189
189
|
/**
|
|
190
190
|
*
|
|
191
191
|
* @param encodeds Decodes multiple tracks into their info
|
|
192
192
|
* @returns
|
|
193
193
|
*/
|
|
194
|
-
multipleTracks: (encodeds: Base64[]) => Promise<
|
|
194
|
+
multipleTracks: (encodeds: Base64[], requester: unknown) => Promise<Track[]>;
|
|
195
195
|
};
|
|
196
196
|
/**
|
|
197
197
|
* Request Lavalink statistics.
|
|
@@ -137,9 +137,8 @@ class LavalinkNode {
|
|
|
137
137
|
return;
|
|
138
138
|
const headers = {
|
|
139
139
|
Authorization: this.options.authorization,
|
|
140
|
-
"Num-Shards": String(this.NodeManager.LavalinkManager.options.client.shards || "auto"),
|
|
141
140
|
"User-Id": this.NodeManager.LavalinkManager.options.client.id,
|
|
142
|
-
"
|
|
141
|
+
"Client-Name": this.NodeManager.LavalinkManager.options.client.username || "Lavalink-Client",
|
|
143
142
|
};
|
|
144
143
|
if (typeof this.options.sessionId === "string" || typeof sessionId === "string") {
|
|
145
144
|
headers["Session-Id"] = this.options.sessionId || sessionId;
|
|
@@ -228,25 +227,27 @@ class LavalinkNode {
|
|
|
228
227
|
* @param encoded
|
|
229
228
|
* @returns
|
|
230
229
|
*/
|
|
231
|
-
singleTrack: async (encoded) => {
|
|
230
|
+
singleTrack: async (encoded, requester) => {
|
|
232
231
|
if (!encoded)
|
|
233
232
|
throw new SyntaxError("No encoded (Base64 string) was provided");
|
|
234
|
-
return
|
|
233
|
+
// return the decoded + builded track
|
|
234
|
+
return this.NodeManager.LavalinkManager.utils.buildTrack(await this.request(`/decodetrack?encodedTrack=${encoded}`), requester);
|
|
235
235
|
},
|
|
236
236
|
/**
|
|
237
237
|
*
|
|
238
238
|
* @param encodeds Decodes multiple tracks into their info
|
|
239
239
|
* @returns
|
|
240
240
|
*/
|
|
241
|
-
multipleTracks: async (encodeds) => {
|
|
241
|
+
multipleTracks: async (encodeds, requester) => {
|
|
242
242
|
if (!Array.isArray(encodeds) || !encodeds.every(v => typeof v === "string" && v.length > 1))
|
|
243
243
|
throw new SyntaxError("You need to provide encodeds, which is an array of base64 strings");
|
|
244
|
+
// return the decoded + builded tracks
|
|
244
245
|
return await this.request(`/decodetracks`, r => {
|
|
245
246
|
r.method = "POST";
|
|
246
247
|
r.body = JSON.stringify(encodeds);
|
|
247
248
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
248
249
|
r.headers["Content-Type"] = "application/json";
|
|
249
|
-
});
|
|
250
|
+
}).then((r) => r.map(track => this.NodeManager.LavalinkManager.utils.buildTrack(track, requester)));
|
|
250
251
|
}
|
|
251
252
|
};
|
|
252
253
|
/**
|
|
@@ -477,6 +478,7 @@ class LavalinkNode {
|
|
|
477
478
|
player.filterManager.filterUpdatedState = 0;
|
|
478
479
|
}
|
|
479
480
|
}
|
|
481
|
+
this.NodeManager.LavalinkManager.emit("playerUpdate", player);
|
|
480
482
|
break;
|
|
481
483
|
case "event":
|
|
482
484
|
this.handleEvent(payload);
|
|
@@ -523,6 +525,7 @@ class LavalinkNode {
|
|
|
523
525
|
return this.NodeManager.LavalinkManager.emit("trackStart", player, track, payload);
|
|
524
526
|
}
|
|
525
527
|
async trackEnd(player, track, payload) {
|
|
528
|
+
console.log(payload.reason);
|
|
526
529
|
// If there are no songs in the queue
|
|
527
530
|
if (!player.queue.tracks.length && player.repeatMode === "off")
|
|
528
531
|
return this.queueEnd(player, track, payload);
|
|
@@ -531,7 +534,7 @@ class LavalinkNode {
|
|
|
531
534
|
return this.NodeManager.LavalinkManager.emit("trackEnd", player, track, payload);
|
|
532
535
|
// If a track had an error while starting
|
|
533
536
|
if (["loadFailed", "cleanup"].includes(payload.reason)) {
|
|
534
|
-
await (0, Utils_1.queueTrackEnd)(player
|
|
537
|
+
await (0, Utils_1.queueTrackEnd)(player);
|
|
535
538
|
// if no track available, end queue
|
|
536
539
|
if (!player.queue.current)
|
|
537
540
|
return this.queueEnd(player, track, payload);
|
|
@@ -542,7 +545,7 @@ class LavalinkNode {
|
|
|
542
545
|
}
|
|
543
546
|
// remove tracks from the queue
|
|
544
547
|
if (player.repeatMode !== "track")
|
|
545
|
-
await (0, Utils_1.queueTrackEnd)(player
|
|
548
|
+
await (0, Utils_1.queueTrackEnd)(player);
|
|
546
549
|
// if no track available, end queue
|
|
547
550
|
if (!player.queue.current)
|
|
548
551
|
return this.queueEnd(player, track, payload);
|
|
@@ -552,15 +555,17 @@ class LavalinkNode {
|
|
|
552
555
|
return this.NodeManager.LavalinkManager.options.autoSkip && player.play({ noReplace: true });
|
|
553
556
|
}
|
|
554
557
|
async queueEnd(player, track, payload) {
|
|
558
|
+
// add previous track to the queue!
|
|
555
559
|
player.queue.current = null;
|
|
556
560
|
player.playing = false;
|
|
557
561
|
if (typeof this.NodeManager.LavalinkManager.options?.playerOptions?.onEmptyQueue?.autoPlayFunction === "function") {
|
|
558
562
|
await this.NodeManager.LavalinkManager.options?.playerOptions?.onEmptyQueue?.autoPlayFunction(player, track);
|
|
559
563
|
if (player.queue.tracks.length > 0)
|
|
560
|
-
await (0, Utils_1.queueTrackEnd)(player
|
|
564
|
+
await (0, Utils_1.queueTrackEnd)(player);
|
|
561
565
|
if (player.queue.current)
|
|
562
566
|
return player.play({ noReplace: true, paused: false });
|
|
563
567
|
}
|
|
568
|
+
player.queue.previous.unshift(track);
|
|
564
569
|
if (payload?.reason !== "stopped") {
|
|
565
570
|
await player.queue.utils.save();
|
|
566
571
|
}
|
|
@@ -585,7 +590,7 @@ class LavalinkNode {
|
|
|
585
590
|
if (!player.queue.tracks.length && player.repeatMode === "off")
|
|
586
591
|
return;
|
|
587
592
|
// remove the current track, and enqueue the next one
|
|
588
|
-
await (0, Utils_1.queueTrackEnd)(player
|
|
593
|
+
await (0, Utils_1.queueTrackEnd)(player);
|
|
589
594
|
// if no track available, end queue
|
|
590
595
|
if (!player.queue.current)
|
|
591
596
|
return this.queueEnd(player, track, payload);
|
|
@@ -595,7 +600,7 @@ class LavalinkNode {
|
|
|
595
600
|
async trackError(player, track, payload) {
|
|
596
601
|
this.NodeManager.LavalinkManager.emit("trackError", player, track, payload);
|
|
597
602
|
// remove the current track, and enqueue the next one
|
|
598
|
-
await (0, Utils_1.queueTrackEnd)(player
|
|
603
|
+
await (0, Utils_1.queueTrackEnd)(player);
|
|
599
604
|
// if no track available, end queue
|
|
600
605
|
if (!player.queue.current)
|
|
601
606
|
return this.queueEnd(player, track, payload);
|
|
@@ -55,18 +55,7 @@ export declare class NodeManager extends EventEmitter {
|
|
|
55
55
|
nodes: MiniMap<string, LavalinkNode>;
|
|
56
56
|
constructor(LavalinkManager: LavalinkManager);
|
|
57
57
|
createNode(options: LavalinkNodeOptions): LavalinkNode;
|
|
58
|
-
|
|
59
|
-
/** Returns the least used Nodes sorted by amount of calls. */
|
|
60
|
-
private get leastUsedNodesCalls();
|
|
61
|
-
/** Returns the least used Nodes sorted by amount of players. */
|
|
62
|
-
private get leastUsedNodesPlayers();
|
|
63
|
-
/** Returns the least used Nodes sorted by amount of memory usage. */
|
|
64
|
-
private get leastUsedNodesMemory();
|
|
65
|
-
/** Returns the least system load Nodes. */
|
|
66
|
-
get leastLoadNodes(): LavalinkNode[];
|
|
67
|
-
get leastLoadNodesMemory(): LavalinkNode[];
|
|
68
|
-
/** Returns the least system load Nodes. */
|
|
69
|
-
get leastLoadNodesCpu(): LavalinkNode[];
|
|
58
|
+
leastUsedNodes(sortType?: "memory" | "cpuLavalink" | "cpuSystem" | "calls" | "playingPlayers" | "players"): LavalinkNode[];
|
|
70
59
|
deleteNode(node: LavalinkNodeIdentifier | LavalinkNode): void;
|
|
71
60
|
}
|
|
72
61
|
export {};
|
|
@@ -20,68 +20,61 @@ class NodeManager extends stream_1.EventEmitter {
|
|
|
20
20
|
this.nodes.set(newNode.id, newNode);
|
|
21
21
|
return newNode;
|
|
22
22
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
? (a.stats.cpu.systemLoad / a.stats.cpu.cores) * 100
|
|
76
|
-
: 0;
|
|
77
|
-
const bload = b.stats.cpu
|
|
78
|
-
? (b.stats.cpu.systemLoad / b.stats.cpu.cores) * 100
|
|
79
|
-
: 0;
|
|
80
|
-
return aload - bload;
|
|
81
|
-
});
|
|
23
|
+
leastUsedNodes(sortType = "players") {
|
|
24
|
+
switch (sortType) {
|
|
25
|
+
case "memory":
|
|
26
|
+
{
|
|
27
|
+
return [...this.nodes.values()]
|
|
28
|
+
.filter((node) => node.connected)
|
|
29
|
+
.sort((a, b) => (a.stats?.memory?.used || 0) - (b.stats?.memory?.used || 0)); // sort after memor
|
|
30
|
+
}
|
|
31
|
+
break;
|
|
32
|
+
case "cpuLavalink":
|
|
33
|
+
{
|
|
34
|
+
return [...this.nodes.values()]
|
|
35
|
+
.filter((node) => node.connected)
|
|
36
|
+
.sort((a, b) => (a.stats?.cpu?.lavalinkLoad || 0) - (b.stats?.cpu?.lavalinkLoad || 0)); // sort after memor
|
|
37
|
+
}
|
|
38
|
+
break;
|
|
39
|
+
case "cpuSystem":
|
|
40
|
+
{
|
|
41
|
+
return [...this.nodes.values()]
|
|
42
|
+
.filter((node) => node.connected)
|
|
43
|
+
.sort((a, b) => (a.stats?.cpu?.systemLoad || 0) - (b.stats?.cpu?.systemLoad || 0)); // sort after memor
|
|
44
|
+
}
|
|
45
|
+
break;
|
|
46
|
+
case "calls":
|
|
47
|
+
{
|
|
48
|
+
return [...this.nodes.values()]
|
|
49
|
+
.filter((node) => node.connected)
|
|
50
|
+
.sort((a, b) => a.calls - b.calls); // client sided sorting
|
|
51
|
+
}
|
|
52
|
+
break;
|
|
53
|
+
case "playingPlayers":
|
|
54
|
+
{
|
|
55
|
+
return [...this.nodes.values()]
|
|
56
|
+
.filter((node) => node.connected)
|
|
57
|
+
.sort((a, b) => (a.stats?.playingPlayers || 0) - (b.stats?.playingPlayers || 0));
|
|
58
|
+
}
|
|
59
|
+
break;
|
|
60
|
+
case "players":
|
|
61
|
+
{
|
|
62
|
+
return [...this.nodes.values()]
|
|
63
|
+
.filter((node) => node.connected)
|
|
64
|
+
.sort((a, b) => (a.stats?.players || 0) - (b.stats?.players || 0));
|
|
65
|
+
}
|
|
66
|
+
break;
|
|
67
|
+
default:
|
|
68
|
+
{
|
|
69
|
+
return [...this.nodes.values()]
|
|
70
|
+
.filter((node) => node.connected)
|
|
71
|
+
.sort((a, b) => (a.stats?.players || 0) - (b.stats?.players || 0));
|
|
72
|
+
}
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
82
75
|
}
|
|
83
76
|
deleteNode(node) {
|
|
84
|
-
const decodeNode = typeof node === "string" ? this.nodes.get(node) : node || this.leastUsedNodes[0];
|
|
77
|
+
const decodeNode = typeof node === "string" ? this.nodes.get(node) : node || this.leastUsedNodes()[0];
|
|
85
78
|
if (!decodeNode)
|
|
86
79
|
throw new Error("Node was not found");
|
|
87
80
|
decodeNode.destroy(Player_1.DestroyReasons.NodeDeleted);
|
|
@@ -110,7 +110,7 @@ export declare class Player {
|
|
|
110
110
|
* Play the next track from the queue / a specific track, with playoptions for Lavalink
|
|
111
111
|
* @param options
|
|
112
112
|
*/
|
|
113
|
-
play(options?: Partial<PlayOptions>):
|
|
113
|
+
play(options?: Partial<PlayOptions>): any;
|
|
114
114
|
/**
|
|
115
115
|
* Set the Volume for the Player
|
|
116
116
|
* @param volume The Volume in percent
|
|
@@ -143,12 +143,12 @@ export declare class Player {
|
|
|
143
143
|
* Set the Repeatmode of the Player
|
|
144
144
|
* @param repeatMode
|
|
145
145
|
*/
|
|
146
|
-
setRepeatMode(repeatMode: RepeatMode): Promise<
|
|
146
|
+
setRepeatMode(repeatMode: RepeatMode): Promise<RepeatMode>;
|
|
147
147
|
/**
|
|
148
148
|
* Skip the current song, or a specific amount of songs
|
|
149
149
|
* @param amount provide the index of the next track to skip to
|
|
150
150
|
*/
|
|
151
|
-
skip(skipTo?: number): Promise<
|
|
151
|
+
skip(skipTo?: number): Promise<any>;
|
|
152
152
|
/**
|
|
153
153
|
* Connects the Player to the Voice Channel
|
|
154
154
|
* @returns
|
|
@@ -172,6 +172,7 @@ export declare class Player {
|
|
|
172
172
|
/** Converts the Player including Queue to a Json state */
|
|
173
173
|
toJSON(): {
|
|
174
174
|
guildId: string;
|
|
175
|
+
options: PlayerOptions;
|
|
175
176
|
voiceChannelId: string;
|
|
176
177
|
textChannelId: string;
|
|
177
178
|
position: number;
|
|
@@ -184,7 +185,6 @@ export declare class Player {
|
|
|
184
185
|
createdTimeStamp: number;
|
|
185
186
|
filters: {};
|
|
186
187
|
equalizer: import("./Filters").EQBand[];
|
|
187
|
-
queue: import("./Queue").StoredQueue;
|
|
188
188
|
nodeId: string;
|
|
189
189
|
};
|
|
190
190
|
}
|