magmastream 2.9.3-dev.3 → 2.9.3-dev.30
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/dist/config/blockedWords.d.ts +1 -0
- package/dist/index.d.ts +19 -3687
- package/dist/index.js +1 -1
- package/dist/statestorage/JsonQueue.d.ts +173 -0
- package/dist/statestorage/JsonQueue.js +32 -4
- package/dist/statestorage/MemoryQueue.d.ts +154 -0
- package/dist/statestorage/MemoryQueue.js +56 -36
- package/dist/statestorage/RedisQueue.d.ts +178 -0
- package/dist/statestorage/RedisQueue.js +29 -7
- package/dist/structures/Enums.d.ts +310 -0
- package/dist/structures/Enums.js +6 -0
- package/dist/structures/Filters.d.ts +352 -0
- package/dist/structures/Filters.js +5 -4
- package/dist/structures/MagmastreamError.d.ts +14 -0
- package/dist/structures/Manager.d.ts +259 -0
- package/dist/structures/Manager.js +297 -555
- package/dist/structures/Node.d.ts +390 -0
- package/dist/structures/Node.js +98 -143
- package/dist/structures/Player.d.ts +347 -0
- package/dist/structures/Player.js +53 -127
- package/dist/structures/Plugin.d.ts +23 -0
- package/dist/structures/Rest.d.ts +93 -0
- package/dist/structures/Rest.js +41 -21
- package/dist/structures/Types.d.ts +1315 -0
- package/dist/structures/Utils.d.ts +169 -0
- package/dist/structures/Utils.js +145 -71
- package/dist/utils/filtersEqualizers.d.ts +16 -0
- package/dist/utils/managerCheck.d.ts +7 -0
- package/dist/utils/nodeCheck.d.ts +7 -0
- package/dist/utils/playerCheck.d.ts +7 -0
- package/dist/wrappers/discord.js.d.ts +15 -0
- package/dist/wrappers/discord.js.js +19 -4
- package/dist/wrappers/discordeno.d.ts +19 -0
- package/dist/wrappers/discordeno.js +77 -0
- package/dist/wrappers/eris.d.ts +15 -0
- package/dist/wrappers/eris.js +20 -3
- package/dist/wrappers/oceanic.d.ts +15 -0
- package/dist/wrappers/oceanic.js +22 -4
- package/dist/wrappers/seyfert.d.ts +37 -0
- package/dist/wrappers/seyfert.js +25 -1
- package/package.json +106 -98
- package/dist/wrappers/detritus.js +0 -52
package/dist/structures/Node.js
CHANGED
|
@@ -31,7 +31,6 @@ class Node {
|
|
|
31
31
|
reconnectTimeout;
|
|
32
32
|
reconnectAttempts = 1;
|
|
33
33
|
redisPrefix;
|
|
34
|
-
sessionIdsFilePath;
|
|
35
34
|
sessionIdsMap = new Map();
|
|
36
35
|
/**
|
|
37
36
|
* Creates an instance of Node.
|
|
@@ -97,18 +96,10 @@ class Node {
|
|
|
97
96
|
switch (this.manager.options.stateStorage.type) {
|
|
98
97
|
case Enums_1.StateStorageType.Memory:
|
|
99
98
|
case Enums_1.StateStorageType.JSON:
|
|
100
|
-
this.sessionIdsFilePath = path_1.default.join(process.cwd(), "magmastream", "sessionData", "sessionIds.json");
|
|
101
|
-
const configDir = path_1.default.dirname(this.sessionIdsFilePath);
|
|
102
|
-
if (!fs_1.default.existsSync(configDir)) {
|
|
103
|
-
fs_1.default.mkdirSync(configDir, { recursive: true });
|
|
104
|
-
}
|
|
105
|
-
this.createSessionIdsFile();
|
|
106
99
|
this.createReadmeFile();
|
|
107
100
|
break;
|
|
108
101
|
case Enums_1.StateStorageType.Redis:
|
|
109
|
-
this.redisPrefix =
|
|
110
|
-
? this.manager.options.stateStorage.redisConfig.prefix
|
|
111
|
-
: this.manager.options.stateStorage.redisConfig.prefix ?? "magmastream:";
|
|
102
|
+
this.redisPrefix = Utils_1.PlayerUtils.getRedisKey();
|
|
112
103
|
break;
|
|
113
104
|
}
|
|
114
105
|
}
|
|
@@ -125,16 +116,19 @@ class Node {
|
|
|
125
116
|
get address() {
|
|
126
117
|
return `${this.options.host}:${this.options.port}`;
|
|
127
118
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
119
|
+
getCompositeKey() {
|
|
120
|
+
return `${this.options.identifier}::${this.manager.options.clusterId}`;
|
|
121
|
+
}
|
|
122
|
+
getRedisSessionIdsKey() {
|
|
123
|
+
return `${this.redisPrefix}node:sessionIds`;
|
|
124
|
+
}
|
|
125
|
+
getNodeSessionsDir() {
|
|
126
|
+
return path_1.default.join(process.cwd(), "magmastream", "sessionData", "nodeSessions");
|
|
127
|
+
}
|
|
128
|
+
getNodeSessionPath() {
|
|
129
|
+
const safeId = String(this.options.identifier).replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
130
|
+
const clusterId = String(this.manager.options.clusterId ?? 0);
|
|
131
|
+
return path_1.default.join(this.getNodeSessionsDir(), `${safeId}__${clusterId}.txt`);
|
|
138
132
|
}
|
|
139
133
|
/**
|
|
140
134
|
* Loads session IDs from the sessionIds.json file if it exists.
|
|
@@ -148,49 +142,43 @@ class Node {
|
|
|
148
142
|
switch (this.manager.options.stateStorage.type) {
|
|
149
143
|
case Enums_1.StateStorageType.Memory:
|
|
150
144
|
case Enums_1.StateStorageType.JSON: {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
145
|
+
const dir = this.getNodeSessionsDir();
|
|
146
|
+
const filePath = this.getNodeSessionPath();
|
|
147
|
+
if (!fs_1.default.existsSync(dir))
|
|
148
|
+
fs_1.default.mkdirSync(dir, { recursive: true });
|
|
149
|
+
if (!fs_1.default.existsSync(filePath)) {
|
|
150
|
+
this.sessionId = null;
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
try {
|
|
154
|
+
const raw = fs_1.default.readFileSync(filePath, "utf-8").trim();
|
|
155
|
+
this.sessionId = raw.length ? raw : null;
|
|
156
|
+
if (this.sessionId)
|
|
157
|
+
this.sessionIdsMap.set(this.getCompositeKey(), this.sessionId);
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
this.sessionId = null;
|
|
159
161
|
}
|
|
160
162
|
break;
|
|
161
163
|
}
|
|
162
|
-
case Enums_1.StateStorageType.Redis:
|
|
163
|
-
const key =
|
|
164
|
-
this.
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
message: "Invalid sessionIds data type from Redis.",
|
|
173
|
-
context: { sessionIds },
|
|
174
|
-
});
|
|
175
|
-
}
|
|
176
|
-
this.sessionIdsMap = new Map(Object.entries(sessionIds));
|
|
177
|
-
const compositeKey = `${this.options.identifier}::${this.manager.options.clusterId}`;
|
|
178
|
-
if (this.sessionIdsMap.has(compositeKey)) {
|
|
179
|
-
this.sessionId = this.sessionIdsMap.get(compositeKey) || null;
|
|
180
|
-
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Restored sessionId for ${compositeKey}: ${this.sessionId}`);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
catch (err) {
|
|
184
|
-
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Failed to parse Redis sessionIds: ${err.message}`);
|
|
185
|
-
this.sessionIdsMap = new Map();
|
|
164
|
+
case Enums_1.StateStorageType.Redis: {
|
|
165
|
+
const key = this.getRedisSessionIdsKey();
|
|
166
|
+
const compositeKey = this.getCompositeKey();
|
|
167
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Loading sessionId from Redis hash: ${key} field: ${compositeKey}`);
|
|
168
|
+
try {
|
|
169
|
+
const sid = await this.manager.redis.hget(key, compositeKey);
|
|
170
|
+
this.sessionId = sid ?? null;
|
|
171
|
+
if (this.sessionId) {
|
|
172
|
+
this.sessionIdsMap.set(compositeKey, this.sessionId);
|
|
173
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Restored sessionId for ${compositeKey}: ${this.sessionId}`);
|
|
186
174
|
}
|
|
187
175
|
}
|
|
188
|
-
|
|
189
|
-
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE]
|
|
190
|
-
|
|
191
|
-
this.sessionIdsMap = new Map();
|
|
176
|
+
catch (err) {
|
|
177
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Failed to load sessionId from Redis hash: ${err.message}`);
|
|
178
|
+
this.sessionId = null;
|
|
192
179
|
}
|
|
193
180
|
break;
|
|
181
|
+
}
|
|
194
182
|
}
|
|
195
183
|
}
|
|
196
184
|
/**
|
|
@@ -207,84 +195,53 @@ class Node {
|
|
|
207
195
|
async updateSessionId() {
|
|
208
196
|
switch (this.manager.options.stateStorage.type) {
|
|
209
197
|
case Enums_1.StateStorageType.Memory:
|
|
210
|
-
case Enums_1.StateStorageType.JSON:
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
this.
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
fs_1.default.writeFileSync(tmpPath, Utils_1.JSONUtils.safe(fileData, 2), "utf-8");
|
|
232
|
-
fs_1.default.renameSync(tmpPath, filePath);
|
|
233
|
-
this.sessionIdsMap = new Map(Object.entries(fileData));
|
|
234
|
-
updated = true;
|
|
235
|
-
}
|
|
236
|
-
catch (err) {
|
|
237
|
-
retries--;
|
|
238
|
-
if (retries === 0) {
|
|
239
|
-
throw new MagmastreamError_1.MagmaStreamError({
|
|
240
|
-
code: Enums_1.MagmaStreamErrorCode.NODE_SESSION_IDS_UPDATE_FAILED,
|
|
241
|
-
message: `Failed to update sessionIds after retries.`,
|
|
242
|
-
cause: err instanceof Error ? err : undefined,
|
|
243
|
-
context: { filePath, compositeKey, storage: "file" },
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
await new Promise((r) => setTimeout(r, 50));
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
break;
|
|
198
|
+
case Enums_1.StateStorageType.JSON:
|
|
199
|
+
return this.updateSessionIdFile();
|
|
200
|
+
case Enums_1.StateStorageType.Redis:
|
|
201
|
+
return this.updateSessionIdRedis();
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
async updateSessionIdFile() {
|
|
205
|
+
const dir = this.getNodeSessionsDir();
|
|
206
|
+
const filePath = this.getNodeSessionPath();
|
|
207
|
+
const tmpPath = `${filePath}.tmp`;
|
|
208
|
+
if (!fs_1.default.existsSync(dir))
|
|
209
|
+
fs_1.default.mkdirSync(dir, { recursive: true });
|
|
210
|
+
if (this.sessionId) {
|
|
211
|
+
fs_1.default.writeFileSync(tmpPath, this.sessionId, "utf-8");
|
|
212
|
+
fs_1.default.renameSync(tmpPath, filePath);
|
|
213
|
+
this.sessionIdsMap.set(this.getCompositeKey(), this.sessionId);
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
try {
|
|
217
|
+
if (fs_1.default.existsSync(filePath))
|
|
218
|
+
fs_1.default.unlinkSync(filePath);
|
|
250
219
|
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
}
|
|
264
|
-
else {
|
|
265
|
-
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Redis key not found — creating new sessionIds key.`);
|
|
266
|
-
sessionIds = {};
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
catch (err) {
|
|
270
|
-
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Corrupted Redis sessionIds, reinitializing: ${err.message}`);
|
|
271
|
-
sessionIds = {};
|
|
272
|
-
}
|
|
273
|
-
try {
|
|
274
|
-
sessionIds[compositeKey] = this.sessionId;
|
|
275
|
-
this.sessionIdsMap = new Map(Object.entries(sessionIds));
|
|
276
|
-
await this.manager.redis.set(key, Utils_1.JSONUtils.safe(sessionIds));
|
|
277
|
-
}
|
|
278
|
-
catch (err) {
|
|
279
|
-
throw new MagmastreamError_1.MagmaStreamError({
|
|
280
|
-
code: Enums_1.MagmaStreamErrorCode.NODE_SESSION_IDS_UPDATE_FAILED,
|
|
281
|
-
message: `Failed to update sessionIds in Redis.`,
|
|
282
|
-
cause: err instanceof Error ? err : undefined,
|
|
283
|
-
context: { key, compositeKey, storage: "redis" },
|
|
284
|
-
});
|
|
285
|
-
}
|
|
286
|
-
break;
|
|
220
|
+
catch { }
|
|
221
|
+
this.sessionIdsMap.delete(this.getCompositeKey());
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
async updateSessionIdRedis() {
|
|
225
|
+
const key = this.getRedisSessionIdsKey();
|
|
226
|
+
const compositeKey = this.getCompositeKey();
|
|
227
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Updating sessionId in Redis hash: ${key} field: ${compositeKey}`);
|
|
228
|
+
try {
|
|
229
|
+
if (this.sessionId) {
|
|
230
|
+
await this.manager.redis.hset(key, compositeKey, this.sessionId);
|
|
231
|
+
this.sessionIdsMap.set(compositeKey, this.sessionId);
|
|
287
232
|
}
|
|
233
|
+
else {
|
|
234
|
+
await this.manager.redis.hdel(key, compositeKey);
|
|
235
|
+
this.sessionIdsMap.delete(compositeKey);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
catch (err) {
|
|
239
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
240
|
+
code: Enums_1.MagmaStreamErrorCode.NODE_SESSION_IDS_UPDATE_FAILED,
|
|
241
|
+
message: "Failed to update sessionId in Redis hash.",
|
|
242
|
+
cause: err instanceof Error ? err : undefined,
|
|
243
|
+
context: { key, compositeKey, storage: "redis-hash" },
|
|
244
|
+
});
|
|
288
245
|
}
|
|
289
246
|
}
|
|
290
247
|
/**
|
|
@@ -305,12 +262,7 @@ class Node {
|
|
|
305
262
|
"User-Id": this.manager.options.clientId,
|
|
306
263
|
"Client-Name": this.manager.options.clientName,
|
|
307
264
|
};
|
|
308
|
-
|
|
309
|
-
if (this.sessionId) {
|
|
310
|
-
headers["Session-Id"] = this.sessionId;
|
|
311
|
-
}
|
|
312
|
-
else if (this.options.enableSessionResumeOption && this.sessionIdsMap.has(compositeKey)) {
|
|
313
|
-
this.sessionId = this.sessionIdsMap.get(compositeKey) || null;
|
|
265
|
+
if (typeof this.sessionId === "string" && this.sessionId.length > 0) {
|
|
314
266
|
headers["Session-Id"] = this.sessionId;
|
|
315
267
|
}
|
|
316
268
|
this.socket = new ws_1.default(`ws${this.options.useSSL ? "s" : ""}://${this.address}/v4/websocket`, { headers });
|
|
@@ -356,9 +308,7 @@ class Node {
|
|
|
356
308
|
// Automove all players connected to that node
|
|
357
309
|
const players = this.manager.players.filter((p) => p.node == this);
|
|
358
310
|
if (players.size) {
|
|
359
|
-
|
|
360
|
-
await player.autoMoveNode();
|
|
361
|
-
}
|
|
311
|
+
await Promise.all(Array.from(players.values(), (player) => player.autoMoveNode()));
|
|
362
312
|
}
|
|
363
313
|
this.socket.close(1000, "destroy");
|
|
364
314
|
this.socket.removeAllListeners();
|
|
@@ -537,10 +487,11 @@ class Node {
|
|
|
537
487
|
case "ready":
|
|
538
488
|
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Node message: ${Utils_1.JSONUtils.safe(payload, 2)}`);
|
|
539
489
|
this.rest.setSessionId(payload.sessionId);
|
|
490
|
+
const hadPreviousSession = this.sessionId && this.sessionId !== payload.sessionId;
|
|
540
491
|
this.sessionId = payload.sessionId;
|
|
541
492
|
await this.updateSessionId();
|
|
542
493
|
this.info = await this.fetchInfo();
|
|
543
|
-
if (payload.resumed) {
|
|
494
|
+
if (payload.resumed || !hadPreviousSession) {
|
|
544
495
|
await this.manager.loadPlayerStates(this.options.identifier);
|
|
545
496
|
}
|
|
546
497
|
if (this.options.enableSessionResumeOption) {
|
|
@@ -1222,8 +1173,12 @@ class Node {
|
|
|
1222
1173
|
* @private
|
|
1223
1174
|
*/
|
|
1224
1175
|
createReadmeFile() {
|
|
1225
|
-
const
|
|
1176
|
+
const baseDir = path_1.default.join(process.cwd(), "magmastream");
|
|
1177
|
+
const readmeFilePath = path_1.default.join(baseDir, "README.md");
|
|
1226
1178
|
const message = "Please do NOT delete the magmastream/ folder as it is used to store player data for autoresume etc.";
|
|
1179
|
+
if (!fs_1.default.existsSync(baseDir)) {
|
|
1180
|
+
fs_1.default.mkdirSync(baseDir, { recursive: true });
|
|
1181
|
+
}
|
|
1227
1182
|
if (!fs_1.default.existsSync(readmeFilePath)) {
|
|
1228
1183
|
fs_1.default.writeFileSync(readmeFilePath, message, "utf-8");
|
|
1229
1184
|
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Created README file at: ${readmeFilePath}`);
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
import { Filters } from "./Filters";
|
|
2
|
+
import { Manager } from "./Manager";
|
|
3
|
+
import { Node } from "./Node";
|
|
4
|
+
import { AnyMessage, IQueue, Lyrics, PlayerOptions, PlayOptions, SearchQuery, SearchResult, Track, VoiceState } from "./Types";
|
|
5
|
+
import { SponsorBlockSegment, StateTypes } from "./Enums";
|
|
6
|
+
import { WebSocket } from "ws";
|
|
7
|
+
export declare class Player {
|
|
8
|
+
options: PlayerOptions;
|
|
9
|
+
/** The Queue for the Player. */
|
|
10
|
+
queue: IQueue;
|
|
11
|
+
/** The filters applied to the audio. */
|
|
12
|
+
filters: Filters;
|
|
13
|
+
/** Whether the queue repeats the track. */
|
|
14
|
+
trackRepeat: boolean;
|
|
15
|
+
/** Whether the queue repeats the queue. */
|
|
16
|
+
queueRepeat: boolean;
|
|
17
|
+
/**Whether the queue repeats and shuffles after each song. */
|
|
18
|
+
dynamicRepeat: boolean;
|
|
19
|
+
/** The time the player is in the track. */
|
|
20
|
+
position: number;
|
|
21
|
+
/** Whether the player is playing. */
|
|
22
|
+
playing: boolean;
|
|
23
|
+
/** Whether the player is paused. */
|
|
24
|
+
paused: boolean;
|
|
25
|
+
/** The volume for the player */
|
|
26
|
+
volume: number;
|
|
27
|
+
/** The Node for the Player. */
|
|
28
|
+
node: Node;
|
|
29
|
+
/** The guild ID for the player. */
|
|
30
|
+
guildId: string;
|
|
31
|
+
/** The voice channel for the player. */
|
|
32
|
+
voiceChannelId: string | null;
|
|
33
|
+
/** The text channel for the player. */
|
|
34
|
+
textChannelId: string | null;
|
|
35
|
+
/**The now playing message. */
|
|
36
|
+
nowPlayingMessage?: AnyMessage;
|
|
37
|
+
/** The current state of the player. */
|
|
38
|
+
state: StateTypes;
|
|
39
|
+
/** The equalizer bands array. */
|
|
40
|
+
bands: number[];
|
|
41
|
+
/** The voice state object from Discord. */
|
|
42
|
+
voiceState: VoiceState;
|
|
43
|
+
/** The Manager. */
|
|
44
|
+
manager: Manager;
|
|
45
|
+
/** The autoplay state of the player. */
|
|
46
|
+
isAutoplay: boolean;
|
|
47
|
+
/** The number of times to try autoplay before emitting queueEnd. */
|
|
48
|
+
autoplayTries: number;
|
|
49
|
+
/** The cluster ID for the player. */
|
|
50
|
+
clusterId: number;
|
|
51
|
+
private readonly data;
|
|
52
|
+
private dynamicLoopInterval;
|
|
53
|
+
dynamicRepeatIntervalMs: number | null;
|
|
54
|
+
private static _manager;
|
|
55
|
+
/** Should only be used when the node is a NodeLink */
|
|
56
|
+
protected voiceReceiverWsClient: WebSocket | null;
|
|
57
|
+
protected isConnectToVoiceReceiver: boolean;
|
|
58
|
+
protected voiceReceiverReconnectTimeout: NodeJS.Timeout | null;
|
|
59
|
+
protected voiceReceiverAttempt: number;
|
|
60
|
+
protected voiceReceiverReconnectTries: number;
|
|
61
|
+
/**
|
|
62
|
+
* Creates a new player, returns one if it already exists.
|
|
63
|
+
* @param options The player options.
|
|
64
|
+
* @see https://docs.magmastream.com/main/introduction/getting-started
|
|
65
|
+
*/
|
|
66
|
+
constructor(options: PlayerOptions);
|
|
67
|
+
/**
|
|
68
|
+
* Initializes the static properties of the Player class.
|
|
69
|
+
* @hidden
|
|
70
|
+
* @param manager The Manager to use.
|
|
71
|
+
*/
|
|
72
|
+
static init(manager: Manager): void;
|
|
73
|
+
/**
|
|
74
|
+
* Set custom data.
|
|
75
|
+
* @param key - The key to set the data for.
|
|
76
|
+
* @param value - The value to set the data to.
|
|
77
|
+
*/
|
|
78
|
+
set(key: string, value: unknown): void;
|
|
79
|
+
/**
|
|
80
|
+
* Retrieves custom data associated with a given key.
|
|
81
|
+
* @template T - The expected type of the data.
|
|
82
|
+
* @param {string} key - The key to retrieve the data for.
|
|
83
|
+
* @returns {T} - The data associated with the key, cast to the specified type.
|
|
84
|
+
*/
|
|
85
|
+
get<T>(key: string): T;
|
|
86
|
+
/**
|
|
87
|
+
* Same as Manager#search() but a shortcut on the player itself.
|
|
88
|
+
* @param query
|
|
89
|
+
* @param requester
|
|
90
|
+
*/
|
|
91
|
+
search<T = unknown>(query: string | SearchQuery, requester?: T): Promise<SearchResult>;
|
|
92
|
+
/**
|
|
93
|
+
* Connects the player to the voice channel.
|
|
94
|
+
* @throws {RangeError} If no voice channel has been set.
|
|
95
|
+
* @returns {void}
|
|
96
|
+
*/
|
|
97
|
+
connect(): void;
|
|
98
|
+
/**
|
|
99
|
+
* Disconnects the player from the voice channel.
|
|
100
|
+
* @returns {this} The player instance.
|
|
101
|
+
*/
|
|
102
|
+
disconnect(): Promise<this>;
|
|
103
|
+
/**
|
|
104
|
+
* Destroys the player and clears the queue.
|
|
105
|
+
* @param {boolean} disconnect - Whether to disconnect the player from the voice channel.
|
|
106
|
+
* @returns {Promise<boolean>} - Whether the player was successfully destroyed.
|
|
107
|
+
* @emits {PlayerDestroy} - Emitted when the player is destroyed.
|
|
108
|
+
* @emits {PlayerStateUpdate} - Emitted when the player state is updated.
|
|
109
|
+
*/
|
|
110
|
+
destroy(disconnect?: boolean): Promise<boolean>;
|
|
111
|
+
/**
|
|
112
|
+
* Sets the player voice channel.
|
|
113
|
+
* @param {string} channel - The new voice channel ID.
|
|
114
|
+
* @returns {this} - The player instance.
|
|
115
|
+
* @throws {TypeError} If the channel parameter is not a string.
|
|
116
|
+
*/
|
|
117
|
+
setVoiceChannelId(channel: string): this;
|
|
118
|
+
/**
|
|
119
|
+
* Sets the player text channel.
|
|
120
|
+
*
|
|
121
|
+
* This method updates the text channel associated with the player. It also
|
|
122
|
+
* emits a player state update event indicating the change in the channel.
|
|
123
|
+
*
|
|
124
|
+
* @param {string} channel - The new text channel ID.
|
|
125
|
+
* @returns {this} - The player instance for method chaining.
|
|
126
|
+
* @throws {TypeError} If the channel parameter is not a string.
|
|
127
|
+
*/
|
|
128
|
+
setTextChannelId(channel: string): this;
|
|
129
|
+
/**
|
|
130
|
+
* Sets the now playing message.
|
|
131
|
+
*
|
|
132
|
+
* @param message - The message of the now playing message.
|
|
133
|
+
* @returns The now playing message.
|
|
134
|
+
*/
|
|
135
|
+
setNowPlayingMessage(message: AnyMessage): AnyMessage;
|
|
136
|
+
/**
|
|
137
|
+
* Plays the next track.
|
|
138
|
+
*
|
|
139
|
+
* If a track is provided, it will be played. Otherwise, the next track in the queue will be played.
|
|
140
|
+
* If the queue is not empty, but the current track has not finished yet, it will be replaced with the provided track.
|
|
141
|
+
*
|
|
142
|
+
* @param {object} [optionsOrTrack] - The track to play or the options to play with.
|
|
143
|
+
* @param {object} [playOptions] - The options to play with.
|
|
144
|
+
*
|
|
145
|
+
* @returns {Promise<void>}
|
|
146
|
+
*/
|
|
147
|
+
play(): Promise<Player>;
|
|
148
|
+
play(track: Track): Promise<Player>;
|
|
149
|
+
play(options: PlayOptions): Promise<Player>;
|
|
150
|
+
play(track: Track, options: PlayOptions): Promise<Player>;
|
|
151
|
+
/**
|
|
152
|
+
* Sets the autoplay-state of the player.
|
|
153
|
+
*
|
|
154
|
+
* Autoplay is a feature that makes the player play a recommended
|
|
155
|
+
* track when the current track ends.
|
|
156
|
+
*
|
|
157
|
+
* @param {boolean} autoplayState - Whether or not autoplay should be enabled.
|
|
158
|
+
* @param {object} AutoplayUser - The user-object that should be used as the bot-user.
|
|
159
|
+
* @param {number} [tries=3] - The number of times the player should try to find a
|
|
160
|
+
* recommended track if the first one doesn't work.
|
|
161
|
+
* @returns {this} - The player instance.
|
|
162
|
+
*/
|
|
163
|
+
setAutoplay<T = unknown>(autoplayState: boolean, AutoplayUser?: T, tries?: number): this;
|
|
164
|
+
/**
|
|
165
|
+
* Gets recommended tracks and returns an array of tracks.
|
|
166
|
+
* @param {Track} track - The track to find recommendations for.
|
|
167
|
+
* @returns {Promise<Track[]>} - Array of recommended tracks.
|
|
168
|
+
*/
|
|
169
|
+
getRecommendedTracks(track: Track): Promise<Track[]>;
|
|
170
|
+
/**
|
|
171
|
+
* Sets the volume of the player.
|
|
172
|
+
* @param {number} volume - The new volume. Must be between 0 and 500 when using filter mode (100 = 100%).
|
|
173
|
+
* @returns {Promise<Player>} - The updated player.
|
|
174
|
+
* @throws {TypeError} If the volume is not a number.
|
|
175
|
+
* @throws {RangeError} If the volume is not between 0 and 500 when using filter mode (100 = 100%).
|
|
176
|
+
* @emits {PlayerStateUpdate} - Emitted when the volume is changed.
|
|
177
|
+
* @example
|
|
178
|
+
* player.setVolume(50);
|
|
179
|
+
*/
|
|
180
|
+
setVolume(volume: number): Promise<this>;
|
|
181
|
+
/**
|
|
182
|
+
* Sets the sponsorblock for the player. This will set the sponsorblock segments for the player to the given segments.
|
|
183
|
+
* @param {SponsorBlockSegment[]} segments - The sponsorblock segments to set. Defaults to `[SponsorBlockSegment.Sponsor, SponsorBlockSegment.SelfPromo]` if not provided.
|
|
184
|
+
* @returns {Promise<void>} The promise is resolved when the operation is complete.
|
|
185
|
+
*/
|
|
186
|
+
setSponsorBlock(segments?: SponsorBlockSegment[]): Promise<void>;
|
|
187
|
+
/**
|
|
188
|
+
* Gets the sponsorblock for the player.
|
|
189
|
+
* @returns {Promise<SponsorBlockSegment[]>} The sponsorblock segments.
|
|
190
|
+
*/
|
|
191
|
+
getSponsorBlock(): Promise<SponsorBlockSegment[]>;
|
|
192
|
+
/**
|
|
193
|
+
* Deletes the sponsorblock for the player. This will remove all sponsorblock segments that have been set for the player.
|
|
194
|
+
* @returns {Promise<void>}
|
|
195
|
+
*/
|
|
196
|
+
deleteSponsorBlock(): Promise<void>;
|
|
197
|
+
/**
|
|
198
|
+
* Sets the track repeat mode.
|
|
199
|
+
* When track repeat is enabled, the current track will replay after it ends.
|
|
200
|
+
* Disables queueRepeat and dynamicRepeat modes if enabled.
|
|
201
|
+
*
|
|
202
|
+
* @param repeat - A boolean indicating whether to enable track repeat.
|
|
203
|
+
* @returns {this} - The player instance.
|
|
204
|
+
* @throws {TypeError} If the repeat parameter is not a boolean.
|
|
205
|
+
*/
|
|
206
|
+
setTrackRepeat(repeat: boolean): this;
|
|
207
|
+
/**
|
|
208
|
+
* Sets the queue repeat.
|
|
209
|
+
* @param repeat Whether to repeat the queue or not
|
|
210
|
+
* @returns {this} - The player instance.
|
|
211
|
+
* @throws {TypeError} If the repeat parameter is not a boolean
|
|
212
|
+
*/
|
|
213
|
+
setQueueRepeat(repeat: boolean): this;
|
|
214
|
+
/**
|
|
215
|
+
* Sets the queue to repeat and shuffles the queue after each song.
|
|
216
|
+
* @param repeat "true" or "false".
|
|
217
|
+
* @param ms After how many milliseconds to trigger dynamic repeat.
|
|
218
|
+
* @returns {this} - The player instance.
|
|
219
|
+
* @throws {TypeError} If the repeat parameter is not a boolean.
|
|
220
|
+
* @throws {RangeError} If the queue size is less than or equal to 1.
|
|
221
|
+
*/
|
|
222
|
+
setDynamicRepeat(repeat: boolean, ms: number): Promise<this>;
|
|
223
|
+
/**
|
|
224
|
+
* Restarts the currently playing track from the beginning.
|
|
225
|
+
* If there is no track playing, it will play the next track in the queue.
|
|
226
|
+
* @returns {Promise<Player>} The current instance of the Player class for method chaining.
|
|
227
|
+
*/
|
|
228
|
+
restart(): Promise<Player>;
|
|
229
|
+
/**
|
|
230
|
+
* Stops the player and optionally removes tracks from the queue.
|
|
231
|
+
* @param {number} [amount] The amount of tracks to remove from the queue. If not provided, removes the current track if it exists.
|
|
232
|
+
* @returns {Promise<this>} - The player instance.
|
|
233
|
+
* @throws {RangeError} If the amount is greater than the queue length.
|
|
234
|
+
*/
|
|
235
|
+
stop(amount?: number): Promise<this>;
|
|
236
|
+
/**
|
|
237
|
+
* Skips the current track.
|
|
238
|
+
* @returns {this} - The player instance.
|
|
239
|
+
* @throws {Error} If there are no tracks in the queue.
|
|
240
|
+
* @emits {PlayerStateUpdate} - With {@link PlayerStateEventTypes.TrackChange} as the change type.
|
|
241
|
+
*/
|
|
242
|
+
pause(pause: boolean): Promise<this>;
|
|
243
|
+
/**
|
|
244
|
+
* Skips to the previous track in the queue.
|
|
245
|
+
* @returns {this} - The player instance.
|
|
246
|
+
* @throws {Error} If there are no previous tracks in the queue.
|
|
247
|
+
* @emits {PlayerStateUpdate} - With {@link PlayerStateEventTypes.TrackChange} as the change type.
|
|
248
|
+
*/
|
|
249
|
+
previous(addBackToQueue?: boolean): Promise<this>;
|
|
250
|
+
/**
|
|
251
|
+
* Seeks to a given position in the currently playing track.
|
|
252
|
+
* @param position - The position in milliseconds to seek to.
|
|
253
|
+
* @returns {this} - The player instance.
|
|
254
|
+
* @throws {Error} If the position is invalid.
|
|
255
|
+
* @emits {PlayerStateUpdate} - With {@link PlayerStateEventTypes.TrackChange} as the change type.
|
|
256
|
+
*/
|
|
257
|
+
seek(position: number): Promise<this>;
|
|
258
|
+
/**
|
|
259
|
+
* Returns the current repeat state of the player.
|
|
260
|
+
* @param player The player to get the repeat state from.
|
|
261
|
+
* @returns The repeat state of the player, or null if it is not repeating.
|
|
262
|
+
*/
|
|
263
|
+
private getRepeatState;
|
|
264
|
+
/**
|
|
265
|
+
* Automatically moves the player to a usable node.
|
|
266
|
+
* @returns {Promise<Player | void>} - The player instance or void if not moved.
|
|
267
|
+
*/
|
|
268
|
+
autoMoveNode(): Promise<Player | void>;
|
|
269
|
+
/**
|
|
270
|
+
* Moves the player to another node.
|
|
271
|
+
* @param {string} identifier - The identifier of the node to move to.
|
|
272
|
+
* @returns {Promise<Player>} - The player instance after being moved.
|
|
273
|
+
*/
|
|
274
|
+
moveNode(identifier: string): Promise<Player>;
|
|
275
|
+
/**
|
|
276
|
+
* Retrieves the data associated with the player.
|
|
277
|
+
* @returns {Record<string, unknown>} - The data associated with the player.
|
|
278
|
+
*/
|
|
279
|
+
getData(): Record<string, unknown>;
|
|
280
|
+
/**
|
|
281
|
+
* Retrieves the dynamic loop interval of the player.
|
|
282
|
+
* @returns {NodeJS.Timeout | null} - The dynamic loop interval of the player.
|
|
283
|
+
*/
|
|
284
|
+
getDynamicLoopIntervalPublic(): NodeJS.Timeout | null;
|
|
285
|
+
/**
|
|
286
|
+
* Retrieves the data associated with the player.
|
|
287
|
+
* @returns {Record<string, unknown>} - The data associated with the player.
|
|
288
|
+
*/
|
|
289
|
+
getSerializableData(): Record<string, unknown>;
|
|
290
|
+
/**
|
|
291
|
+
* Retrieves the current lyrics for the playing track.
|
|
292
|
+
* @param skipTrackSource - Indicates whether to skip the track source when fetching lyrics.
|
|
293
|
+
* @returns {Promise<Lyrics>} - The lyrics of the current track.
|
|
294
|
+
*/
|
|
295
|
+
getCurrentLyrics(skipTrackSource?: boolean): Promise<Lyrics>;
|
|
296
|
+
/**
|
|
297
|
+
* Sets up the voice receiver for the player.
|
|
298
|
+
* @returns {Promise<void>} - A promise that resolves when the voice receiver is set up.
|
|
299
|
+
* @throws {Error} - If the node is not a NodeLink.
|
|
300
|
+
*/
|
|
301
|
+
setupVoiceReceiver(): Promise<void>;
|
|
302
|
+
/**
|
|
303
|
+
* Removes the voice receiver for the player.
|
|
304
|
+
* @returns {Promise<void>} - A promise that resolves when the voice receiver is removed.
|
|
305
|
+
* @throws {Error} - If the node is not a NodeLink.
|
|
306
|
+
*/
|
|
307
|
+
removeVoiceReceiver(): Promise<void>;
|
|
308
|
+
/**
|
|
309
|
+
* Closes the voice receiver for the player.
|
|
310
|
+
* @param {number} code - The code to close the voice receiver with.
|
|
311
|
+
* @param {string} reason - The reason to close the voice receiver with.
|
|
312
|
+
* @returns {Promise<void>} - A promise that resolves when the voice receiver is closed.
|
|
313
|
+
*/
|
|
314
|
+
private closeVoiceReceiver;
|
|
315
|
+
/**
|
|
316
|
+
* Reconnects the voice receiver for the player.
|
|
317
|
+
* @returns {Promise<void>} - A promise that resolves when the voice receiver is reconnected.
|
|
318
|
+
*/
|
|
319
|
+
private reconnectVoiceReceiver;
|
|
320
|
+
/**
|
|
321
|
+
* Disconnects the voice receiver for the player.
|
|
322
|
+
* @returns {Promise<void>} - A promise that resolves when the voice receiver is disconnected.
|
|
323
|
+
*/
|
|
324
|
+
private disconnectVoiceReceiver;
|
|
325
|
+
/**
|
|
326
|
+
* Opens the voice receiver for the player.
|
|
327
|
+
* @returns {Promise<void>} - A promise that resolves when the voice receiver is opened.
|
|
328
|
+
*/
|
|
329
|
+
private openVoiceReceiver;
|
|
330
|
+
/**
|
|
331
|
+
* Handles a voice receiver message.
|
|
332
|
+
* @param {string} payload - The payload to handle.
|
|
333
|
+
* @returns {Promise<void>} - A promise that resolves when the voice receiver message is handled.
|
|
334
|
+
*/
|
|
335
|
+
private onVoiceReceiverMessage;
|
|
336
|
+
/**
|
|
337
|
+
* Handles a voice receiver error.
|
|
338
|
+
* @param {Error} error - The error to handle.
|
|
339
|
+
* @returns {Promise<void>} - A promise that resolves when the voice receiver error is handled.
|
|
340
|
+
*/
|
|
341
|
+
private onVoiceReceiverError;
|
|
342
|
+
/**
|
|
343
|
+
* Updates the voice state for the player.
|
|
344
|
+
* @returns {Promise<void>} - A promise that resolves when the voice state is updated.
|
|
345
|
+
*/
|
|
346
|
+
updateVoice(): Promise<void>;
|
|
347
|
+
}
|