poru 3.2.0 → 3.3.2
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 +2 -0
- package/package.json +6 -2
- package/src/Node.js +11 -18
- package/src/Player.js +30 -37
- package/src/Poru.js +8 -17
- package/src/guild/Track.js +4 -6
- package/src/platform/Spotify.js +16 -16
- package/tsconfig.json +16 -0
- package/typings/index.d.ts +323 -0
package/README.md
CHANGED
|
@@ -38,10 +38,12 @@ yarn add poru
|
|
|
38
38
|
To use you need a configured [Lavalink](https://github.com/Frederikam/Lavalink) instance.
|
|
39
39
|
|
|
40
40
|
- Stable client
|
|
41
|
+
- support typescript
|
|
41
42
|
- 100% Compatible with Lavalink
|
|
42
43
|
- Object-oriented
|
|
43
44
|
- 100% Customizable
|
|
44
45
|
- Easy to setup
|
|
46
|
+
- Inbuilt Queue System
|
|
45
47
|
- Inbuilt support for spotify,apple music and deezer
|
|
46
48
|
## Implementation
|
|
47
49
|
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "poru",
|
|
3
|
-
"version": "3.2
|
|
3
|
+
"version": "3.3.2",
|
|
4
4
|
"description": "A stable and powerfull lavalink client around node.js",
|
|
5
5
|
"main": "index.js",
|
|
6
|
+
"typings": "./typings/index.d.ts",
|
|
6
7
|
"scripts": {
|
|
7
8
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
9
|
},
|
|
@@ -34,5 +35,8 @@
|
|
|
34
35
|
"deezer",
|
|
35
36
|
"discordjs",
|
|
36
37
|
"eris"
|
|
37
|
-
]
|
|
38
|
+
],
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/node": "^18.7.18"
|
|
41
|
+
}
|
|
38
42
|
}
|
package/src/Node.js
CHANGED
|
@@ -12,7 +12,7 @@ class Node {
|
|
|
12
12
|
this.url = `${this.secure ? "wss" : "ws"}://${this.host}:${this.port}/`;
|
|
13
13
|
this.ws = null;
|
|
14
14
|
this.reconnectTimeout = node.reconnectTimeout || 5000;
|
|
15
|
-
this.reconnectTries = node.reconnectTries|| 5;
|
|
15
|
+
this.reconnectTries = node.reconnectTries || 5;
|
|
16
16
|
this.reconnectAttempt = null;
|
|
17
17
|
this.attempt = 0;
|
|
18
18
|
this.resumeKey = node.resumeKey || null;
|
|
@@ -63,7 +63,6 @@ class Node {
|
|
|
63
63
|
this.isConnected = false;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
|
|
67
66
|
destroy() {
|
|
68
67
|
if (!this.isConnected) return;
|
|
69
68
|
|
|
@@ -80,11 +79,11 @@ class Node {
|
|
|
80
79
|
|
|
81
80
|
reconnect() {
|
|
82
81
|
this.reconnectAttempt = setTimeout(() => {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
A
|
|
82
|
+
if (this.attempt > this.reconnectTries) {
|
|
83
|
+
throw new Error(
|
|
84
|
+
`[Poru Websocket] Unable to connect with ${this.name} node after ${this.reconnectTries} tries`
|
|
85
|
+
);
|
|
86
|
+
A;
|
|
88
87
|
}
|
|
89
88
|
this.isConnected = false;
|
|
90
89
|
this.ws.removeAllListeners();
|
|
@@ -92,7 +91,6 @@ A
|
|
|
92
91
|
this.manager.emit("nodeReconnect", this);
|
|
93
92
|
this.connect();
|
|
94
93
|
this.attempt++;
|
|
95
|
-
|
|
96
94
|
}, this.reconnectTimeout);
|
|
97
95
|
}
|
|
98
96
|
|
|
@@ -119,7 +117,6 @@ A
|
|
|
119
117
|
return penalties;
|
|
120
118
|
}
|
|
121
119
|
|
|
122
|
-
|
|
123
120
|
#open() {
|
|
124
121
|
if (this.reconnectAttempt) {
|
|
125
122
|
clearTimeout(this.reconnectAttempt);
|
|
@@ -156,8 +153,6 @@ A
|
|
|
156
153
|
}
|
|
157
154
|
}
|
|
158
155
|
|
|
159
|
-
|
|
160
|
-
|
|
161
156
|
#message(payload) {
|
|
162
157
|
const packet = JSON.parse(payload);
|
|
163
158
|
if (!packet.op) return;
|
|
@@ -173,10 +168,9 @@ A
|
|
|
173
168
|
this.name,
|
|
174
169
|
`[Web Socket] Lavalink Node Update : ${packet.op} `
|
|
175
170
|
);
|
|
176
|
-
|
|
171
|
+
}
|
|
177
172
|
|
|
178
173
|
#close(event) {
|
|
179
|
-
|
|
180
174
|
this.disconnect();
|
|
181
175
|
this.manager.emit("nodeDisconnect", this, event);
|
|
182
176
|
this.manager.emit(
|
|
@@ -190,18 +184,17 @@ A
|
|
|
190
184
|
}
|
|
191
185
|
|
|
192
186
|
#error(event) {
|
|
193
|
-
|
|
187
|
+
if (!event) return "Unknown event";
|
|
194
188
|
|
|
195
189
|
this.manager.emit(
|
|
196
190
|
"debug",
|
|
197
191
|
this.name,
|
|
198
|
-
`[Web Socket] Connection for Lavalink node has error code: ${
|
|
192
|
+
`[Web Socket] Connection for Lavalink node has error code: ${
|
|
193
|
+
event.code || event
|
|
194
|
+
}`
|
|
199
195
|
);
|
|
200
196
|
this.manager.emit("nodeError", this, event);
|
|
201
197
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
198
|
}
|
|
205
199
|
|
|
206
|
-
|
|
207
200
|
module.exports = Node;
|
package/src/Player.js
CHANGED
|
@@ -33,6 +33,8 @@ class Player extends EventEmitter {
|
|
|
33
33
|
|
|
34
34
|
this.volume = 100;
|
|
35
35
|
|
|
36
|
+
this.ping = 0;
|
|
37
|
+
|
|
36
38
|
this.currentTrack = null;
|
|
37
39
|
|
|
38
40
|
this.previousTrack = null;
|
|
@@ -42,9 +44,9 @@ class Player extends EventEmitter {
|
|
|
42
44
|
this.on("event", (data) => this.lavalinkEvent(data).bind(this)());
|
|
43
45
|
this.on("playerUpdate", (packet) => {
|
|
44
46
|
(this.isConnected = packet.state.connected),
|
|
45
|
-
(this.position = packet.state.position)
|
|
47
|
+
(this.position = packet.state.position),
|
|
48
|
+
(this.ping = packet.state.ping);
|
|
46
49
|
this.manager.emit("playerUpdate", this, packet);
|
|
47
|
-
|
|
48
50
|
});
|
|
49
51
|
|
|
50
52
|
this.manager.emit("playerCreate", this);
|
|
@@ -53,7 +55,6 @@ class Player extends EventEmitter {
|
|
|
53
55
|
this.guildId,
|
|
54
56
|
`[Poru Player] SuccessFully player created`
|
|
55
57
|
);
|
|
56
|
-
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
async play(options = {}) {
|
|
@@ -82,7 +83,6 @@ class Player extends EventEmitter {
|
|
|
82
83
|
`[Poru Player] Track :\n ${this.currentTrack.info.title} is started to playing`
|
|
83
84
|
);
|
|
84
85
|
|
|
85
|
-
|
|
86
86
|
return this;
|
|
87
87
|
}
|
|
88
88
|
|
|
@@ -136,37 +136,34 @@ class Player extends EventEmitter {
|
|
|
136
136
|
return this;
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
+
setLoop(mode) {
|
|
140
|
+
if (!mode)
|
|
141
|
+
throw new Error(
|
|
142
|
+
`[Poru Player] You must have to provide loop mode as argument of setLoop`
|
|
143
|
+
);
|
|
139
144
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
145
|
+
if (!["NONE", "TRACK", "QUEUE"].includes(mode))
|
|
146
|
+
throw new Error(
|
|
147
|
+
`[Poru Player] setLoop arguments are NONE,TRACK AND QUEUE`
|
|
148
|
+
);
|
|
143
149
|
|
|
144
|
-
|
|
150
|
+
switch (mode) {
|
|
151
|
+
case "NONE": {
|
|
152
|
+
this.loop = "NONE";
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
case "TRACK": {
|
|
156
|
+
this.loop = "TRACK";
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
case "QUEUE": {
|
|
160
|
+
this.loop = "QUEUE";
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
145
164
|
|
|
146
|
-
|
|
147
|
-
case "NONE":
|
|
148
|
-
{
|
|
149
|
-
this.loop = "NONE";
|
|
150
|
-
break;
|
|
151
|
-
}
|
|
152
|
-
case "TRACK":
|
|
153
|
-
{
|
|
154
|
-
this.loop = "TRACK";
|
|
155
|
-
break;
|
|
156
|
-
}
|
|
157
|
-
case "QUEUE":
|
|
158
|
-
{
|
|
159
|
-
this.loop ="QUEUE";
|
|
160
|
-
break;
|
|
165
|
+
return this;
|
|
161
166
|
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
return this;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
167
|
|
|
171
168
|
setTextChannel(channel) {
|
|
172
169
|
if (typeof channel !== "string")
|
|
@@ -176,16 +173,14 @@ switch(mode){
|
|
|
176
173
|
}
|
|
177
174
|
|
|
178
175
|
setVoiceChannel(channel) {
|
|
179
|
-
|
|
180
176
|
if (typeof channel !== "string")
|
|
181
177
|
throw new RangeError("Channel must be a string.");
|
|
182
|
-
|
|
178
|
+
|
|
183
179
|
this.voiceChannel = channel;
|
|
184
180
|
return this;
|
|
185
181
|
}
|
|
186
182
|
|
|
187
183
|
connect(options = this) {
|
|
188
|
-
|
|
189
184
|
let { guildId, voiceChannel, deaf, mute } = options;
|
|
190
185
|
this.send(
|
|
191
186
|
{
|
|
@@ -196,14 +191,13 @@ switch(mode){
|
|
|
196
191
|
},
|
|
197
192
|
true
|
|
198
193
|
);
|
|
199
|
-
|
|
194
|
+
|
|
200
195
|
this.isConnected = true;
|
|
201
196
|
this.manager.emit(
|
|
202
197
|
"debug",
|
|
203
198
|
this.guildID,
|
|
204
199
|
`[Poru Player] Player has been connected`
|
|
205
200
|
);
|
|
206
|
-
|
|
207
201
|
}
|
|
208
202
|
|
|
209
203
|
updateSession(data) {
|
|
@@ -261,7 +255,6 @@ switch(mode){
|
|
|
261
255
|
this.manager.players.delete(this.guildId);
|
|
262
256
|
}
|
|
263
257
|
|
|
264
|
-
|
|
265
258
|
restart() {
|
|
266
259
|
this.filters.updateFilters();
|
|
267
260
|
if (this.currentTrack) {
|
package/src/Poru.js
CHANGED
|
@@ -40,7 +40,7 @@ class Poru extends EventEmitter {
|
|
|
40
40
|
const guild = client.guilds.cache.get(data.d.guild_id);
|
|
41
41
|
if (guild) guild.shard.send(data);
|
|
42
42
|
};
|
|
43
|
-
|
|
43
|
+
|
|
44
44
|
client.on("raw", async (packet) => {
|
|
45
45
|
await this.packetUpdate(packet);
|
|
46
46
|
});
|
|
@@ -99,16 +99,14 @@ class Poru extends EventEmitter {
|
|
|
99
99
|
return node;
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
|
|
103
102
|
checkConnection(options) {
|
|
104
|
-
|
|
105
103
|
let { guildId, voiceChannel, textChannel, shardId } = options;
|
|
106
104
|
if (!guildId)
|
|
107
105
|
throw new Error(`[Poru Connection] you have to Provide guildId`);
|
|
108
106
|
if (!voiceChannel)
|
|
109
107
|
throw new Error(`[Poru Connection] you have to Provide voiceChannel`);
|
|
110
108
|
if (!textChannel)
|
|
111
|
-
throw new Error(`[Poru Connection] you have to Provide
|
|
109
|
+
throw new Error(`[Poru Connection] you have to Provide textChannel`);
|
|
112
110
|
// if(shardId == null) throw new Error(`[Poru Connection] You must have to Provide shardId`);
|
|
113
111
|
|
|
114
112
|
if (typeof guildId !== "string")
|
|
@@ -124,10 +122,7 @@ class Poru extends EventEmitter {
|
|
|
124
122
|
// if(typeof shardId !=="number") throw new Error(`[Poru Connection] shardId must be provided as a number`);
|
|
125
123
|
}
|
|
126
124
|
|
|
127
|
-
|
|
128
|
-
|
|
129
125
|
createConnection(options) {
|
|
130
|
-
|
|
131
126
|
this.checkConnection(options);
|
|
132
127
|
const player = this.players.get(options.guildId);
|
|
133
128
|
if (player) return player;
|
|
@@ -146,9 +141,6 @@ class Poru extends EventEmitter {
|
|
|
146
141
|
this.players.get(guildId)?.destroy();
|
|
147
142
|
}
|
|
148
143
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
144
|
#createPlayer(node, options) {
|
|
153
145
|
if (this.players.has(options.guildId))
|
|
154
146
|
return this.players.get(options.guildId);
|
|
@@ -159,7 +151,6 @@ class Poru extends EventEmitter {
|
|
|
159
151
|
return player;
|
|
160
152
|
}
|
|
161
153
|
|
|
162
|
-
|
|
163
154
|
setServersUpdate(data) {
|
|
164
155
|
let guild = data.guild_id;
|
|
165
156
|
this.voiceServers.set(guild, data);
|
|
@@ -200,7 +191,8 @@ class Poru extends EventEmitter {
|
|
|
200
191
|
}
|
|
201
192
|
|
|
202
193
|
packetUpdate(packet) {
|
|
203
|
-
if (!["VOICE_STATE_UPDATE", "VOICE_SERVER_UPDATE"].includes(packet.t))
|
|
194
|
+
if (!["VOICE_STATE_UPDATE", "VOICE_SERVER_UPDATE"].includes(packet.t))
|
|
195
|
+
return;
|
|
204
196
|
const player = this.players.get(packet.d.guild_id);
|
|
205
197
|
if (!player) return;
|
|
206
198
|
|
|
@@ -212,21 +204,19 @@ class Poru extends EventEmitter {
|
|
|
212
204
|
}
|
|
213
205
|
}
|
|
214
206
|
|
|
215
|
-
|
|
216
|
-
|
|
217
207
|
async resolve(query, source) {
|
|
218
208
|
const node = this.leastUsedNodes[0];
|
|
219
209
|
if (!node) throw new Error("No nodes are available.");
|
|
220
210
|
const regex = /^https?:\/\//;
|
|
221
211
|
|
|
222
212
|
if (regex.test(query)) {
|
|
223
|
-
return this.fetchURL(node, query
|
|
213
|
+
return this.fetchURL(node, query);
|
|
224
214
|
} else {
|
|
225
215
|
return this.fetchTrack(node, query, source);
|
|
226
216
|
}
|
|
227
217
|
}
|
|
228
218
|
|
|
229
|
-
async fetchURL(node, track
|
|
219
|
+
async fetchURL(node, track) {
|
|
230
220
|
if (this.spotify.check(track)) {
|
|
231
221
|
return await this.spotify.resolve(track);
|
|
232
222
|
} else if (this.apple.check(track)) {
|
|
@@ -278,7 +268,8 @@ class Poru extends EventEmitter {
|
|
|
278
268
|
|
|
279
269
|
#fetch(node, endpoint, param) {
|
|
280
270
|
return fetch(
|
|
281
|
-
`http${node.secure ? "s" : ""}://${node.host}:${
|
|
271
|
+
`http${node.secure ? "s" : ""}://${node.host}:${
|
|
272
|
+
node.port
|
|
282
273
|
}/${endpoint}?${param}`,
|
|
283
274
|
{
|
|
284
275
|
headers: {
|
package/src/guild/Track.js
CHANGED
|
@@ -11,9 +11,7 @@ class Track {
|
|
|
11
11
|
sourceName: data.info.sourceName,
|
|
12
12
|
title: data.info.title,
|
|
13
13
|
uri: data.info.uri,
|
|
14
|
-
image:
|
|
15
|
-
`https://i.ytimg.com/vi/${data.info.identifier}/maxresdefault.jpg` ||
|
|
16
|
-
null,
|
|
14
|
+
image: `https://i.ytimg.com/vi/${data.info.identifier}/1.jpg` || null,
|
|
17
15
|
};
|
|
18
16
|
}
|
|
19
17
|
|
|
@@ -41,7 +39,7 @@ class Track {
|
|
|
41
39
|
);
|
|
42
40
|
if (officialAudio) {
|
|
43
41
|
this.info.identifier = officialAudio.info.identifier;
|
|
44
|
-
this.image = `https://i.ytimg.com/vi/${this.info.identifier}/
|
|
42
|
+
this.image = `https://i.ytimg.com/vi/${this.info.identifier}/1.jpg`;
|
|
45
43
|
this.track = officialAudio.track;
|
|
46
44
|
return this;
|
|
47
45
|
}
|
|
@@ -54,13 +52,13 @@ class Track {
|
|
|
54
52
|
);
|
|
55
53
|
if (sameDuration) {
|
|
56
54
|
this.info.identifier = sameDuration.info.identifier;
|
|
57
|
-
this.image = `https://i.ytimg.com/vi/${this.info.identifier}/
|
|
55
|
+
this.image = `https://i.ytimg.com/vi/${this.info.identifier}/1.jpg`;
|
|
58
56
|
this.track = sameDuration.track;
|
|
59
57
|
return this;
|
|
60
58
|
}
|
|
61
59
|
}
|
|
62
60
|
this.info.identifier = result.tracks[0].info.identifier;
|
|
63
|
-
this.image = `https://i.ytimg.com/vi/${this.info.identifier}/
|
|
61
|
+
this.image = `https://i.ytimg.com/vi/${this.info.identifier}/1.jpg`;
|
|
64
62
|
this.track = result.tracks[0].track;
|
|
65
63
|
return this;
|
|
66
64
|
}
|
package/src/platform/Spotify.js
CHANGED
|
@@ -15,7 +15,7 @@ class Spotify {
|
|
|
15
15
|
artistLimit: manager.options.artistLimit,
|
|
16
16
|
searchMarket: manager.options.searchMarket,
|
|
17
17
|
clientID: manager.options.clientID || null,
|
|
18
|
-
clientSecret: manager.options.clientSecret || null
|
|
18
|
+
clientSecret: manager.options.clientSecret || null,
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
this.authorization = Buffer.from(
|
|
@@ -50,19 +50,21 @@ class Spotify {
|
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
|
|
54
53
|
async requestToken() {
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
if (!this.options.clientID && !this.options.clientSecret)
|
|
55
|
+
return this.requestAnonymousToken();
|
|
57
56
|
|
|
58
57
|
try {
|
|
59
|
-
const data = await fetch(
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
58
|
+
const data = await fetch(
|
|
59
|
+
"https://accounts.spotify.com/api/token?grant_type=client_credentials",
|
|
60
|
+
{
|
|
61
|
+
method: "POST",
|
|
62
|
+
headers: {
|
|
63
|
+
Authorization: `Basic ${this.authorization}`,
|
|
64
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
65
|
+
},
|
|
66
|
+
}
|
|
67
|
+
);
|
|
66
68
|
|
|
67
69
|
const body = await data.json();
|
|
68
70
|
|
|
@@ -70,13 +72,11 @@ class Spotify {
|
|
|
70
72
|
this.interval = body.expires_in * 1000;
|
|
71
73
|
} catch (e) {
|
|
72
74
|
if (e.status === 400) {
|
|
73
|
-
throw new Error(
|
|
75
|
+
throw new Error("Invalid Spotify client.");
|
|
74
76
|
}
|
|
75
77
|
}
|
|
76
78
|
}
|
|
77
79
|
|
|
78
|
-
|
|
79
|
-
|
|
80
80
|
async renew() {
|
|
81
81
|
if (Date.now() >= this.interval) {
|
|
82
82
|
await this.requestToken();
|
|
@@ -217,13 +217,13 @@ class Spotify {
|
|
|
217
217
|
}
|
|
218
218
|
}
|
|
219
219
|
|
|
220
|
-
|
|
221
220
|
async fetch(query) {
|
|
222
221
|
try {
|
|
223
222
|
if (this.check(query)) return this.resolve(query);
|
|
224
223
|
|
|
225
224
|
const data = await this.requestData(
|
|
226
|
-
`/search/?q="${query}"&type=artist,album,track&market=${
|
|
225
|
+
`/search/?q="${query}"&type=artist,album,track&market=${
|
|
226
|
+
this.options.searchMarket ?? "US"
|
|
227
227
|
}`
|
|
228
228
|
);
|
|
229
229
|
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"lib": ["ESNext"],
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"moduleResolution": "node",
|
|
6
|
+
"target": "ESNext",
|
|
7
|
+
"sourceMap": true,
|
|
8
|
+
"esModuleInterop": true,
|
|
9
|
+
"experimentalDecorators": true,
|
|
10
|
+
"emitDecoratorMetadata": true,
|
|
11
|
+
"allowSyntheticDefaultImports": true,
|
|
12
|
+
"skipLibCheck": true,
|
|
13
|
+
"skipDefaultLibCheck": true,
|
|
14
|
+
"declaration": true,
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import { EventEmitter } from "node:events";
|
|
2
|
+
|
|
3
|
+
export interface PlaylistInfo {
|
|
4
|
+
name: string;
|
|
5
|
+
selectedTrack: number;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface ResolveResponse {
|
|
9
|
+
loadType:
|
|
10
|
+
| "TRACK_LOADED"
|
|
11
|
+
| "PLAYLIST_LOADED"
|
|
12
|
+
| "SEARCH_RESULT"
|
|
13
|
+
| "NO_MATCHES"
|
|
14
|
+
| "LOAD_FAILED";
|
|
15
|
+
tracks: Track[];
|
|
16
|
+
playlistInfo: PlaylistInfo;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class Track {
|
|
20
|
+
constructor(data: string): this;
|
|
21
|
+
track: string;
|
|
22
|
+
info: {
|
|
23
|
+
identifier: string;
|
|
24
|
+
isSeekable: boolean;
|
|
25
|
+
author: string;
|
|
26
|
+
length: number;
|
|
27
|
+
isStream: boolean;
|
|
28
|
+
sourceName: string;
|
|
29
|
+
title: string;
|
|
30
|
+
uri: string;
|
|
31
|
+
requester?: object | string | null;
|
|
32
|
+
image: string | null;
|
|
33
|
+
};
|
|
34
|
+
resolve: (manager: Poru) => Promise<ResolveResponse>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export class Queue extends Array<Track> {
|
|
38
|
+
constructor(...args: any[]): this;
|
|
39
|
+
get size(): number;
|
|
40
|
+
first: () => Track;
|
|
41
|
+
add: (track: Track) => Queue;
|
|
42
|
+
remove: (index: number) => Queue;
|
|
43
|
+
clear: () => Queue;
|
|
44
|
+
shuffle: () => void;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface FiltersOptions {
|
|
48
|
+
_8d?: boolean;
|
|
49
|
+
bassboost?: number;
|
|
50
|
+
equalizer?: {
|
|
51
|
+
band: number;
|
|
52
|
+
gain: number;
|
|
53
|
+
}[];
|
|
54
|
+
karaoke?: boolean;
|
|
55
|
+
timescale?: boolean;
|
|
56
|
+
tremolo?: boolean;
|
|
57
|
+
vibrato?: boolean;
|
|
58
|
+
rotation?: boolean;
|
|
59
|
+
distortion?: boolean;
|
|
60
|
+
channelMix?: boolean;
|
|
61
|
+
lowPass?: boolean;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export class Filters {
|
|
65
|
+
constructor(player: Player, options: FiltersOptions): this;
|
|
66
|
+
_8d: boolean | null;
|
|
67
|
+
bassboost: number | null;
|
|
68
|
+
player: Player;
|
|
69
|
+
node: Node;
|
|
70
|
+
equalizer: { bands: number; gain: number }[] | null;
|
|
71
|
+
karaoke: boolean | null;
|
|
72
|
+
timescale: boolean | null;
|
|
73
|
+
tremolo: boolean | null;
|
|
74
|
+
vibrato: boolean | null;
|
|
75
|
+
rotation: boolean | null;
|
|
76
|
+
distortion: boolean | null;
|
|
77
|
+
channelMix: boolean | null;
|
|
78
|
+
lowPass: boolean | null;
|
|
79
|
+
|
|
80
|
+
setEqualizer: (bands: number, gain: number) => void;
|
|
81
|
+
setKaraoke: (value: boolean) => Filters;
|
|
82
|
+
setTimescale: (value: boolean) => Filters;
|
|
83
|
+
setTremolo: (value: boolean) => Filters;
|
|
84
|
+
setVibrato: (value: boolean) => Filters;
|
|
85
|
+
setRotation: (value: boolean) => Filters;
|
|
86
|
+
setDistortion: (value: boolean) => Filters;
|
|
87
|
+
setChannelMix: (value: boolean) => Filters;
|
|
88
|
+
setLowPass: (value: boolean) => Filters;
|
|
89
|
+
setFilters: (options: any) => Filters;
|
|
90
|
+
clearFilters: () => Filters;
|
|
91
|
+
setNightcore: (value: boolean) => boolean;
|
|
92
|
+
setSlowmode: (value: boolean) => void;
|
|
93
|
+
setVaporwave: (value: boolean) => void;
|
|
94
|
+
set8D: (value: boolean) => void;
|
|
95
|
+
setBassboost: (value: number) => void;
|
|
96
|
+
updateFilters: () => void;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface NodeStats {
|
|
100
|
+
players: number;
|
|
101
|
+
playingPlayers: number;
|
|
102
|
+
uptime: number;
|
|
103
|
+
memory: {
|
|
104
|
+
free: number;
|
|
105
|
+
used: number;
|
|
106
|
+
allocated: number;
|
|
107
|
+
reservable: number;
|
|
108
|
+
};
|
|
109
|
+
cpu: {
|
|
110
|
+
cores: number;
|
|
111
|
+
systemLoad: number;
|
|
112
|
+
lavalinkLoad: number;
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export interface NodeOptions {
|
|
117
|
+
name?: string;
|
|
118
|
+
host?: string;
|
|
119
|
+
port?: number;
|
|
120
|
+
password?: string;
|
|
121
|
+
secure?: boolean;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export interface PoruOptions {
|
|
125
|
+
reconnectTimeout?: number;
|
|
126
|
+
reconnectTries?: number;
|
|
127
|
+
resumeKey?: string;
|
|
128
|
+
resumeTimeout?: number;
|
|
129
|
+
defaultPlatform?: string;
|
|
130
|
+
playlistLimit?: number;
|
|
131
|
+
albumLimit?: number;
|
|
132
|
+
artistLimit?: number;
|
|
133
|
+
searchMarket?: string;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export class Node implements INode {
|
|
137
|
+
constructor(manager: Poru, options: NodeOptions, node: PoruOptions): this;
|
|
138
|
+
name: string | null;
|
|
139
|
+
host: string;
|
|
140
|
+
port: number;
|
|
141
|
+
password: string;
|
|
142
|
+
secure: boolean;
|
|
143
|
+
manager: Poru;
|
|
144
|
+
url: string;
|
|
145
|
+
reconnectTimeout: number;
|
|
146
|
+
reconnectTries: number;
|
|
147
|
+
reconnectAttempt: boolean;
|
|
148
|
+
attempt: number;
|
|
149
|
+
resumeKey: string | null;
|
|
150
|
+
resumeTimeout: string;
|
|
151
|
+
reconnects: number;
|
|
152
|
+
isConnected: boolean;
|
|
153
|
+
destroyed: boolean | null;
|
|
154
|
+
stats: NodeStats;
|
|
155
|
+
connect: () => void;
|
|
156
|
+
disconnect: () => void;
|
|
157
|
+
destroy: () => void;
|
|
158
|
+
reconnect: () => void;
|
|
159
|
+
send: (payload: any) => void;
|
|
160
|
+
get penalties(): number;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
interface PoruEvents {
|
|
164
|
+
nodeConnect: (node: Node) => void;
|
|
165
|
+
nodeClose: (node: Node) => void;
|
|
166
|
+
nodeError: (node: Node, event: any) => void;
|
|
167
|
+
trackStart: (player: Player, track: Track, payload: LavalinkEvents) => void;
|
|
168
|
+
playerUpdate: (
|
|
169
|
+
player: Player,
|
|
170
|
+
data: {
|
|
171
|
+
op: "playerUpdate";
|
|
172
|
+
guildId: string;
|
|
173
|
+
state: {
|
|
174
|
+
time: number;
|
|
175
|
+
position: number;
|
|
176
|
+
connected: boolean;
|
|
177
|
+
ping: number;
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
) => void;
|
|
181
|
+
trackEnd: (player: Player, track: Track, payload: LavalinkEvents) => void;
|
|
182
|
+
trackError: (player: Player, track: Track, payload: LavalinkEvents) => void;
|
|
183
|
+
socketClosed: (
|
|
184
|
+
player: Player,
|
|
185
|
+
data: {
|
|
186
|
+
op: "event";
|
|
187
|
+
type: "WebSocketClosedEvent";
|
|
188
|
+
guildId: string;
|
|
189
|
+
code: number;
|
|
190
|
+
reason: string;
|
|
191
|
+
byRemote: boolean;
|
|
192
|
+
}
|
|
193
|
+
) => void;
|
|
194
|
+
queueEnd: (player: Player, track: Track, payload: LavalinkEvents) => void;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export class Poru extends EventEmitter {
|
|
198
|
+
constructor(client: any, nodes: NodeOptions[], options?: PoruOptions): this;
|
|
199
|
+
on<U extends keyof PoruEvents>(event: U, listener: PoruEvents[U]): this;
|
|
200
|
+
emit<U extends keyof PoruEvents>(
|
|
201
|
+
event: U,
|
|
202
|
+
...args: Parameters<PoruEvents[U]>
|
|
203
|
+
): boolean;
|
|
204
|
+
|
|
205
|
+
client: any;
|
|
206
|
+
_nodes: Node[];
|
|
207
|
+
nodes: Map<string, Node>;
|
|
208
|
+
players: Map<string, Player>;
|
|
209
|
+
voiceStates: Map<string, any>;
|
|
210
|
+
voiceServers: Map<string, any>;
|
|
211
|
+
isReady: boolean;
|
|
212
|
+
user: string | null;
|
|
213
|
+
options: PoruOptions;
|
|
214
|
+
sendData: null;
|
|
215
|
+
version: string;
|
|
216
|
+
spotify: any;
|
|
217
|
+
apple: any;
|
|
218
|
+
deezer: any;
|
|
219
|
+
init: (client: any) => void;
|
|
220
|
+
addNode: (options: NodeOptions) => Node;
|
|
221
|
+
removeNode: (name: string) => void;
|
|
222
|
+
get leastUsedNodes(): Node[];
|
|
223
|
+
getNode: (name: "best" | string) => Node;
|
|
224
|
+
checkConnection: (options: {
|
|
225
|
+
guildId: string;
|
|
226
|
+
voiceChannel: string;
|
|
227
|
+
textChannel: string;
|
|
228
|
+
}) => void;
|
|
229
|
+
createConnection: (options: {
|
|
230
|
+
guildId: string;
|
|
231
|
+
voiceChannel: string;
|
|
232
|
+
textChannel?: string;
|
|
233
|
+
deaf?: boolean;
|
|
234
|
+
mute?: boolean;
|
|
235
|
+
}) => Player;
|
|
236
|
+
removeConnection: (guildId: string) => void;
|
|
237
|
+
setServersUpdate: (data: { guild_id: string }) => boolean;
|
|
238
|
+
setStateUpdate: (data: {
|
|
239
|
+
user_id?: string;
|
|
240
|
+
channel_id?: string;
|
|
241
|
+
guild_id: string;
|
|
242
|
+
}) => void;
|
|
243
|
+
packetUpdate: (packet: {
|
|
244
|
+
t: string;
|
|
245
|
+
d: {
|
|
246
|
+
guild_id: string;
|
|
247
|
+
};
|
|
248
|
+
}) => void;
|
|
249
|
+
resolve: (query: string, source?: string) => Promise<ResolveResponse>;
|
|
250
|
+
fetchURL: (node: Node, track: Track) => Promise<ResolveResponse>;
|
|
251
|
+
fetchTrack: (
|
|
252
|
+
node: Node,
|
|
253
|
+
query: string,
|
|
254
|
+
source?: string
|
|
255
|
+
) => Promise<ResolveResponse>;
|
|
256
|
+
decodeTrack: (track: Track) => Promise<Track>;
|
|
257
|
+
get: (identifier: string) => Player;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export type PlayerLoopModes = "NONE" | "TRACK" | "QUEUE";
|
|
261
|
+
export type LavalinkEvents =
|
|
262
|
+
| "TrackStartEvent"
|
|
263
|
+
| "TrackEndEvent"
|
|
264
|
+
| "TrackExceptionEvent"
|
|
265
|
+
| "TrackStuckEvent"
|
|
266
|
+
| "WebSocketClosedEvent";
|
|
267
|
+
|
|
268
|
+
export interface PlayerOptions {
|
|
269
|
+
guildId: string;
|
|
270
|
+
voiceChannel:
|
|
271
|
+
| {
|
|
272
|
+
id: string;
|
|
273
|
+
}
|
|
274
|
+
| string;
|
|
275
|
+
textChannel?: string;
|
|
276
|
+
mute?: boolean;
|
|
277
|
+
deaf?: boolean;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export class Player extends EventEmitter {
|
|
281
|
+
constructor(manager: Poru, node: Node, options: PlayerOptions): this;
|
|
282
|
+
manager: Poru;
|
|
283
|
+
queue: Queue;
|
|
284
|
+
node: Node;
|
|
285
|
+
options: PlayerOptions;
|
|
286
|
+
filters: Filters;
|
|
287
|
+
guildId: string;
|
|
288
|
+
voiceChannel: string;
|
|
289
|
+
textChannel: string;
|
|
290
|
+
isConnected: boolean;
|
|
291
|
+
isPlaying: boolean;
|
|
292
|
+
isPaused: boolean;
|
|
293
|
+
loop: PlayerLoopModes;
|
|
294
|
+
position: number;
|
|
295
|
+
ping: number;
|
|
296
|
+
volume: number;
|
|
297
|
+
currentTrack: Track | null;
|
|
298
|
+
previousTracks: Track;
|
|
299
|
+
voiceUpdateState: any;
|
|
300
|
+
|
|
301
|
+
play: (options?: { noReplace?: boolean }) => Promise<Player>;
|
|
302
|
+
stop: () => Player;
|
|
303
|
+
pause: (pause: boolean) => Player;
|
|
304
|
+
seekTo: (position: number) => Promise<Player>;
|
|
305
|
+
setVolume: (volume: number) => Player;
|
|
306
|
+
setLoop: (mode: PlayerLoopModes) => Player;
|
|
307
|
+
setTextChannel: (channel: string) => Player;
|
|
308
|
+
setVoiceChannel: (channel: string) => Player;
|
|
309
|
+
connect: (options: {
|
|
310
|
+
guildId: string;
|
|
311
|
+
voiceChannel: string;
|
|
312
|
+
deaf: boolean;
|
|
313
|
+
mute: boolean;
|
|
314
|
+
}) => void;
|
|
315
|
+
updateSession: (data: any) => Player;
|
|
316
|
+
reconnect: () => Player;
|
|
317
|
+
disconnect: () => Player;
|
|
318
|
+
destroy: () => void;
|
|
319
|
+
restart: () => void;
|
|
320
|
+
autoplay: (option: boolean) => void;
|
|
321
|
+
send: (payload: any) => void;
|
|
322
|
+
lavalinkEvent: (data: LavalinkEvents) => void;
|
|
323
|
+
}
|