magmastream 2.9.2-dev.1 → 2.9.2-dev.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/dist/index.d.ts +63 -4
- package/dist/index.js +1 -0
- package/dist/statestorage/JsonQueue.js +273 -171
- package/dist/statestorage/MemoryQueue.js +260 -203
- package/dist/statestorage/RedisQueue.js +396 -203
- package/dist/structures/Enums.js +110 -1
- package/dist/structures/Filters.js +27 -13
- package/dist/structures/MagmastreamError.js +19 -0
- package/dist/structures/Manager.js +345 -219
- package/dist/structures/Node.js +222 -64
- package/dist/structures/Player.js +169 -56
- package/dist/structures/Rest.js +23 -12
- package/dist/structures/Utils.js +66 -65
- package/dist/utils/managerCheck.js +99 -21
- package/dist/utils/nodeCheck.js +59 -34
- package/dist/utils/playerCheck.js +47 -28
- package/package.json +1 -1
package/dist/structures/Node.js
CHANGED
|
@@ -9,6 +9,7 @@ const ws_1 = tslib_1.__importDefault(require("ws"));
|
|
|
9
9
|
const fs_1 = tslib_1.__importDefault(require("fs"));
|
|
10
10
|
const path_1 = tslib_1.__importDefault(require("path"));
|
|
11
11
|
const Enums_1 = require("./Enums");
|
|
12
|
+
const MagmastreamError_1 = require("./MagmastreamError");
|
|
12
13
|
const validSponsorBlocks = Object.values(Enums_1.SponsorBlockSegment).map((v) => v.toLowerCase());
|
|
13
14
|
class Node {
|
|
14
15
|
manager;
|
|
@@ -40,8 +41,12 @@ class Node {
|
|
|
40
41
|
constructor(manager, options) {
|
|
41
42
|
this.manager = manager;
|
|
42
43
|
this.options = options;
|
|
43
|
-
if (!this.manager)
|
|
44
|
-
throw new
|
|
44
|
+
if (!this.manager) {
|
|
45
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
46
|
+
code: Enums_1.MagmaStreamErrorCode.GENERAL_INVALID_MANAGER,
|
|
47
|
+
message: "Manager instance is required.",
|
|
48
|
+
});
|
|
49
|
+
}
|
|
45
50
|
if (this.manager.nodes.has(options.identifier || options.host)) {
|
|
46
51
|
return this.manager.nodes.get(options.identifier || options.host);
|
|
47
52
|
}
|
|
@@ -162,7 +167,11 @@ class Node {
|
|
|
162
167
|
try {
|
|
163
168
|
const sessionIds = JSON.parse(currentRaw);
|
|
164
169
|
if (typeof sessionIds !== "object" || Array.isArray(sessionIds)) {
|
|
165
|
-
throw new
|
|
170
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
171
|
+
code: Enums_1.MagmaStreamErrorCode.NODE_SESSION_IDS_LOAD_FAILED,
|
|
172
|
+
message: "Invalid sessionIds data type from Redis.",
|
|
173
|
+
context: { sessionIds },
|
|
174
|
+
});
|
|
166
175
|
}
|
|
167
176
|
this.sessionIdsMap = new Map(Object.entries(sessionIds));
|
|
168
177
|
const compositeKey = `${this.options.identifier}::${this.manager.options.clusterId}`;
|
|
@@ -199,9 +208,9 @@ class Node {
|
|
|
199
208
|
switch (this.manager.options.stateStorage.type) {
|
|
200
209
|
case Enums_1.StateStorageType.Memory:
|
|
201
210
|
case Enums_1.StateStorageType.JSON: {
|
|
202
|
-
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Updating sessionIds to file: ${this.sessionIdsFilePath}`);
|
|
203
211
|
const compositeKey = `${this.options.identifier}::${this.manager.options.clusterId}`;
|
|
204
212
|
const filePath = this.sessionIdsFilePath;
|
|
213
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Updating sessionIds to file: ${filePath}`);
|
|
205
214
|
let updated = false;
|
|
206
215
|
let retries = 3;
|
|
207
216
|
while (!updated && retries > 0) {
|
|
@@ -227,8 +236,12 @@ class Node {
|
|
|
227
236
|
catch (err) {
|
|
228
237
|
retries--;
|
|
229
238
|
if (retries === 0) {
|
|
230
|
-
|
|
231
|
-
|
|
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
|
+
});
|
|
232
245
|
}
|
|
233
246
|
await new Promise((r) => setTimeout(r, 50));
|
|
234
247
|
}
|
|
@@ -239,27 +252,37 @@ class Node {
|
|
|
239
252
|
const key = `${this.redisPrefix}node:sessionIds`;
|
|
240
253
|
const compositeKey = `${this.options.identifier}::${this.manager.options.clusterId}`;
|
|
241
254
|
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Updating sessionIds in Redis key: ${key}`);
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
255
|
+
let sessionIds = {};
|
|
256
|
+
try {
|
|
257
|
+
const currentRaw = await this.manager.redis.get(key);
|
|
258
|
+
if (currentRaw) {
|
|
246
259
|
sessionIds = JSON.parse(currentRaw);
|
|
247
260
|
if (typeof sessionIds !== "object" || Array.isArray(sessionIds)) {
|
|
248
261
|
throw new Error("Invalid data type in Redis");
|
|
249
262
|
}
|
|
250
263
|
}
|
|
251
|
-
|
|
252
|
-
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE]
|
|
264
|
+
else {
|
|
265
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Redis key not found — creating new sessionIds key.`);
|
|
253
266
|
sessionIds = {};
|
|
254
267
|
}
|
|
255
268
|
}
|
|
256
|
-
|
|
257
|
-
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Redis
|
|
269
|
+
catch (err) {
|
|
270
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Corrupted Redis sessionIds, reinitializing: ${err.message}`);
|
|
258
271
|
sessionIds = {};
|
|
259
272
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
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
|
+
}
|
|
263
286
|
break;
|
|
264
287
|
}
|
|
265
288
|
}
|
|
@@ -371,7 +394,11 @@ class Node {
|
|
|
371
394
|
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Reconnecting node: ${Utils_1.JSONUtils.safe(debugInfo, 2)}`);
|
|
372
395
|
this.reconnectTimeout = setTimeout(async () => {
|
|
373
396
|
if (this.reconnectAttempts >= this.options.maxRetryAttempts) {
|
|
374
|
-
const error = new
|
|
397
|
+
const error = new MagmastreamError_1.MagmaStreamError({
|
|
398
|
+
code: Enums_1.MagmaStreamErrorCode.NODE_RECONNECT_FAILED,
|
|
399
|
+
message: `Unable to reconnect after ${this.options.maxRetryAttempts} attempts.`,
|
|
400
|
+
context: { ...debugInfo },
|
|
401
|
+
});
|
|
375
402
|
this.manager.emit(Enums_1.ManagerEventTypes.NodeError, this, error);
|
|
376
403
|
return await this.destroy();
|
|
377
404
|
}
|
|
@@ -634,7 +661,8 @@ class Node {
|
|
|
634
661
|
const skipFlag = player.get("skipFlag");
|
|
635
662
|
const previous = await player.queue.getPrevious();
|
|
636
663
|
const current = await player.queue.getCurrent();
|
|
637
|
-
|
|
664
|
+
// Only add current to previous if it's not already the newest
|
|
665
|
+
if (!skipFlag && (previous.length === 0 || (previous.at(-1)?.track !== current?.track))) {
|
|
638
666
|
await player.queue.addPrevious(current);
|
|
639
667
|
}
|
|
640
668
|
player.set("skipFlag", false);
|
|
@@ -696,10 +724,10 @@ class Node {
|
|
|
696
724
|
if (!player.isAutoplay || attempt > player.autoplayTries || !(await player.queue.getPrevious()).length)
|
|
697
725
|
return false;
|
|
698
726
|
const PreviousQueue = await player.queue.getPrevious();
|
|
699
|
-
const lastTrack = PreviousQueue
|
|
700
|
-
lastTrack.requester = player.get("Internal_AutoplayUser");
|
|
727
|
+
const lastTrack = PreviousQueue.at(-1); // newest is at tail
|
|
701
728
|
if (!lastTrack)
|
|
702
729
|
return false;
|
|
730
|
+
lastTrack.requester = player.get("Internal_AutoplayUser");
|
|
703
731
|
const tracks = await Utils_1.AutoPlayUtils.getRecommendedTracks(lastTrack);
|
|
704
732
|
const normalize = (str) => str
|
|
705
733
|
.toLowerCase()
|
|
@@ -708,6 +736,7 @@ class Node {
|
|
|
708
736
|
const filteredTracks = tracks.filter((track) => track.identifier !== lastTrack.identifier && track.uri !== lastTrack.uri && normalize(track.title) !== normalize(lastTrack.title));
|
|
709
737
|
if (filteredTracks.length) {
|
|
710
738
|
const randomTrack = filteredTracks[Math.floor(Math.random() * filteredTracks.length)];
|
|
739
|
+
console.log(randomTrack);
|
|
711
740
|
await player.queue.add(randomTrack);
|
|
712
741
|
await player.play();
|
|
713
742
|
return true;
|
|
@@ -838,24 +867,35 @@ class Node {
|
|
|
838
867
|
* @returns {Promise<Lyrics | NodeLinkGetLyrics>} A promise that resolves with the lyrics data.
|
|
839
868
|
*/
|
|
840
869
|
async getLyrics(track, skipTrackSource = false, language) {
|
|
841
|
-
if (!this.connected)
|
|
842
|
-
throw new
|
|
870
|
+
if (!this.connected) {
|
|
871
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
872
|
+
code: Enums_1.MagmaStreamErrorCode.NODE_DISCONNECTED,
|
|
873
|
+
message: `The node is not connected to the lavalink server.`,
|
|
874
|
+
context: { identifier: this.options.identifier },
|
|
875
|
+
});
|
|
876
|
+
}
|
|
843
877
|
if (this.isNodeLink) {
|
|
844
878
|
return (await this.rest.get(`/v4/loadlyrics?encodedTrack=${encodeURIComponent(track.track)}${language ? `&language=${language}` : ""}`));
|
|
845
879
|
}
|
|
846
|
-
|
|
847
|
-
|
|
880
|
+
const requiredPlugins = ["lavalyrics-plugin"];
|
|
881
|
+
for (const plugin of requiredPlugins) {
|
|
882
|
+
if (!this.info.plugins.some((p) => p.name === plugin)) {
|
|
883
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
884
|
+
code: Enums_1.MagmaStreamErrorCode.NODE_PLUGIN_ERROR,
|
|
885
|
+
message: `The plugin "${plugin}" must be present in the lavalink node.`,
|
|
886
|
+
context: { identifier: this.options.identifier },
|
|
887
|
+
});
|
|
888
|
+
}
|
|
848
889
|
}
|
|
849
|
-
if (!this.info.plugins.some((
|
|
850
|
-
throw new
|
|
890
|
+
if (!this.info.plugins.some((p) => p.name === "lavasrc-plugin" || p.name === "java-lyrics-plugin")) {
|
|
891
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
892
|
+
code: Enums_1.MagmaStreamErrorCode.NODE_PLUGIN_ERROR,
|
|
893
|
+
message: `One of the following plugins must also be present in the lavalink node: "lavasrc-plugin" or "java-lyrics-plugin".`,
|
|
894
|
+
context: { identifier: this.options.identifier },
|
|
895
|
+
});
|
|
851
896
|
}
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
provider: null,
|
|
855
|
-
text: null,
|
|
856
|
-
lines: [],
|
|
857
|
-
plugin: [],
|
|
858
|
-
});
|
|
897
|
+
const lyrics = (await this.rest.get(`/v4/lyrics?track=${encodeURIComponent(track.track)}&skipTrackSource=${skipTrackSource}`));
|
|
898
|
+
return lyrics || { source: null, provider: null, text: null, lines: [], plugin: [] };
|
|
859
899
|
}
|
|
860
900
|
/**
|
|
861
901
|
* Subscribes to lyrics for a player.
|
|
@@ -865,17 +905,50 @@ class Node {
|
|
|
865
905
|
* @throws {RangeError} If the node is not connected to the lavalink server or if the java-lyrics-plugin is not available.
|
|
866
906
|
*/
|
|
867
907
|
async lyricsSubscribe(guildId, skipTrackSource = false) {
|
|
868
|
-
if (!this.connected)
|
|
869
|
-
throw new
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
908
|
+
if (!this.connected) {
|
|
909
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
910
|
+
code: Enums_1.MagmaStreamErrorCode.NODE_DISCONNECTED,
|
|
911
|
+
message: `The node is not connected to the lavalink server.`,
|
|
912
|
+
context: { identifier: this.options.identifier },
|
|
913
|
+
});
|
|
914
|
+
}
|
|
915
|
+
if (this.isNodeLink) {
|
|
916
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
917
|
+
code: Enums_1.MagmaStreamErrorCode.NODE_PROTOCOL_ERROR,
|
|
918
|
+
message: `The node is a NodeLink, cannot subscribe to lyrics.`,
|
|
919
|
+
context: { identifier: this.options.identifier },
|
|
920
|
+
});
|
|
921
|
+
}
|
|
922
|
+
const requiredPlugins = ["lavalyrics-plugin"];
|
|
923
|
+
for (const plugin of requiredPlugins) {
|
|
924
|
+
if (!this.info.plugins.some((p) => p.name === plugin)) {
|
|
925
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
926
|
+
code: Enums_1.MagmaStreamErrorCode.NODE_PLUGIN_ERROR,
|
|
927
|
+
message: `The plugin "${plugin}" must be present in the lavalink node.`,
|
|
928
|
+
context: { identifier: this.options.identifier },
|
|
929
|
+
});
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
if (!this.info.plugins.some((p) => p.name === "lavasrc-plugin" || p.name === "java-lyrics-plugin")) {
|
|
933
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
934
|
+
code: Enums_1.MagmaStreamErrorCode.NODE_PLUGIN_ERROR,
|
|
935
|
+
message: `One of the following plugins must also be present in the lavalink node: "lavasrc-plugin" or "java-lyrics-plugin".`,
|
|
936
|
+
context: { identifier: this.options.identifier },
|
|
937
|
+
});
|
|
874
938
|
}
|
|
875
|
-
|
|
876
|
-
|
|
939
|
+
try {
|
|
940
|
+
return await this.rest.post(`/v4/sessions/${this.sessionId}/players/${guildId}/lyrics/subscribe?skipTrackSource=${skipTrackSource}`, {});
|
|
941
|
+
}
|
|
942
|
+
catch (err) {
|
|
943
|
+
throw err instanceof MagmastreamError_1.MagmaStreamError
|
|
944
|
+
? err
|
|
945
|
+
: new MagmastreamError_1.MagmaStreamError({
|
|
946
|
+
code: Enums_1.MagmaStreamErrorCode.NODE_PROTOCOL_ERROR,
|
|
947
|
+
message: "Failed to subscribe to lyrics session.",
|
|
948
|
+
cause: err instanceof Error ? err : undefined,
|
|
949
|
+
context: { identifier: this.options.identifier, guildId, skipTrackSource },
|
|
950
|
+
});
|
|
877
951
|
}
|
|
878
|
-
return await this.rest.post(`/v4/sessions/${this.sessionId}/players/${guildId}/lyrics/subscribe?skipTrackSource=${skipTrackSource}`, {});
|
|
879
952
|
}
|
|
880
953
|
/**
|
|
881
954
|
* Unsubscribes from lyrics for a player.
|
|
@@ -884,14 +957,40 @@ class Node {
|
|
|
884
957
|
* @throws {RangeError} If the node is not connected to the lavalink server or if the java-lyrics-plugin is not available.
|
|
885
958
|
*/
|
|
886
959
|
async lyricsUnsubscribe(guildId) {
|
|
887
|
-
if (!this.connected)
|
|
888
|
-
throw new
|
|
889
|
-
|
|
890
|
-
|
|
960
|
+
if (!this.connected) {
|
|
961
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
962
|
+
code: Enums_1.MagmaStreamErrorCode.NODE_DISCONNECTED,
|
|
963
|
+
message: `The node is not connected to the lavalink server.`,
|
|
964
|
+
context: { identifier: this.options.identifier },
|
|
965
|
+
});
|
|
966
|
+
}
|
|
967
|
+
if (this.isNodeLink) {
|
|
968
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
969
|
+
code: Enums_1.MagmaStreamErrorCode.NODE_PROTOCOL_ERROR,
|
|
970
|
+
message: `The node is a NodeLink, cannot unsubscribe from lyrics.`,
|
|
971
|
+
context: { identifier: this.options.identifier },
|
|
972
|
+
});
|
|
973
|
+
}
|
|
891
974
|
if (!this.info.plugins.some((plugin) => plugin.name === "java-lyrics-plugin")) {
|
|
892
|
-
throw new
|
|
975
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
976
|
+
code: Enums_1.MagmaStreamErrorCode.NODE_PLUGIN_ERROR,
|
|
977
|
+
message: `The plugin "java-lyrics-plugin" must be present in the lavalink node to unsubscribe.`,
|
|
978
|
+
context: { identifier: this.options.identifier },
|
|
979
|
+
});
|
|
980
|
+
}
|
|
981
|
+
try {
|
|
982
|
+
return await this.rest.delete(`/v4/sessions/${this.sessionId}/players/${guildId}/lyrics/subscribe`);
|
|
983
|
+
}
|
|
984
|
+
catch (err) {
|
|
985
|
+
throw err instanceof MagmastreamError_1.MagmaStreamError
|
|
986
|
+
? err
|
|
987
|
+
: new MagmastreamError_1.MagmaStreamError({
|
|
988
|
+
code: Enums_1.MagmaStreamErrorCode.NODE_PROTOCOL_ERROR,
|
|
989
|
+
message: "Failed to unsubscribe from lyrics session.",
|
|
990
|
+
cause: err instanceof Error ? err : undefined,
|
|
991
|
+
context: { identifier: this.options.identifier, guildId },
|
|
992
|
+
});
|
|
893
993
|
}
|
|
894
|
-
return await this.rest.delete(`/v4/sessions/${this.sessionId}/players/${guildId}/lyrics/subscribe`);
|
|
895
994
|
}
|
|
896
995
|
/**
|
|
897
996
|
* Handles the event when a track becomes stuck during playback.
|
|
@@ -1015,9 +1114,26 @@ class Node {
|
|
|
1015
1114
|
* @throws {RangeError} If the sponsorblock-plugin is not available in the Lavalink node.
|
|
1016
1115
|
*/
|
|
1017
1116
|
async getSponsorBlock(player) {
|
|
1018
|
-
if (!this.info.plugins.some((plugin) => plugin.name === "sponsorblock-plugin"))
|
|
1019
|
-
throw new
|
|
1020
|
-
|
|
1117
|
+
if (!this.info.plugins.some((plugin) => plugin.name === "sponsorblock-plugin")) {
|
|
1118
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
1119
|
+
code: Enums_1.MagmaStreamErrorCode.NODE_PLUGIN_ERROR,
|
|
1120
|
+
message: `The plugin "sponsorblock-plugin" must be present in the lavalink node to fetch SponsorBlock data.`,
|
|
1121
|
+
context: { identifier: this.options.identifier, guildId: player.guildId },
|
|
1122
|
+
});
|
|
1123
|
+
}
|
|
1124
|
+
try {
|
|
1125
|
+
return (await this.rest.get(`/v4/sessions/${this.sessionId}/players/${player.guildId}/sponsorblock/categories`));
|
|
1126
|
+
}
|
|
1127
|
+
catch (err) {
|
|
1128
|
+
throw err instanceof MagmastreamError_1.MagmaStreamError
|
|
1129
|
+
? err
|
|
1130
|
+
: new MagmastreamError_1.MagmaStreamError({
|
|
1131
|
+
code: Enums_1.MagmaStreamErrorCode.NODE_PROTOCOL_ERROR,
|
|
1132
|
+
message: "Failed to fetch SponsorBlock segments.",
|
|
1133
|
+
cause: err instanceof Error ? err : undefined,
|
|
1134
|
+
context: { identifier: this.options.identifier, guildId: player.guildId },
|
|
1135
|
+
});
|
|
1136
|
+
}
|
|
1021
1137
|
}
|
|
1022
1138
|
/**
|
|
1023
1139
|
* Sets the sponsorblock segments for a player.
|
|
@@ -1034,14 +1150,40 @@ class Node {
|
|
|
1034
1150
|
* ```
|
|
1035
1151
|
*/
|
|
1036
1152
|
async setSponsorBlock(player, segments = [Enums_1.SponsorBlockSegment.Sponsor, Enums_1.SponsorBlockSegment.SelfPromo]) {
|
|
1037
|
-
if (!this.info.plugins.some((plugin) => plugin.name === "sponsorblock-plugin"))
|
|
1038
|
-
throw new
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1153
|
+
if (!this.info.plugins.some((plugin) => plugin.name === "sponsorblock-plugin")) {
|
|
1154
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
1155
|
+
code: Enums_1.MagmaStreamErrorCode.NODE_PLUGIN_ERROR,
|
|
1156
|
+
message: `The plugin "sponsorblock-plugin" must be present in the lavalink node to set SponsorBlock segments.`,
|
|
1157
|
+
context: { identifier: this.options.identifier, guildId: player.guildId },
|
|
1158
|
+
});
|
|
1159
|
+
}
|
|
1160
|
+
if (!segments.length) {
|
|
1161
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
1162
|
+
code: Enums_1.MagmaStreamErrorCode.NODE_PROTOCOL_ERROR,
|
|
1163
|
+
message: "No segments provided. Did you mean to use 'deleteSponsorBlock'?",
|
|
1164
|
+
context: { identifier: this.options.identifier, guildId: player.guildId },
|
|
1165
|
+
});
|
|
1166
|
+
}
|
|
1167
|
+
if (segments.some((v) => !validSponsorBlocks.includes(v.toLowerCase()))) {
|
|
1168
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
1169
|
+
code: Enums_1.MagmaStreamErrorCode.NODE_PROTOCOL_ERROR,
|
|
1170
|
+
message: `Invalid SponsorBlock segments provided. Valid ones are: ${validSponsorBlocks.map((v) => `'${v}'`).join(", ")}`,
|
|
1171
|
+
context: { identifier: this.options.identifier, guildId: player.guildId, invalidSegments: segments },
|
|
1172
|
+
});
|
|
1173
|
+
}
|
|
1174
|
+
try {
|
|
1175
|
+
await this.rest.put(`/v4/sessions/${this.sessionId}/players/${player.guildId}/sponsorblock/categories`, Utils_1.JSONUtils.safe(segments.map((v) => v.toLowerCase()), 2));
|
|
1176
|
+
}
|
|
1177
|
+
catch (err) {
|
|
1178
|
+
throw err instanceof MagmastreamError_1.MagmaStreamError
|
|
1179
|
+
? err
|
|
1180
|
+
: new MagmastreamError_1.MagmaStreamError({
|
|
1181
|
+
code: Enums_1.MagmaStreamErrorCode.NODE_PROTOCOL_ERROR,
|
|
1182
|
+
message: "Failed to set SponsorBlock segments.",
|
|
1183
|
+
cause: err instanceof Error ? err : undefined,
|
|
1184
|
+
context: { identifier: this.options.identifier, guildId: player.guildId, segments },
|
|
1185
|
+
});
|
|
1186
|
+
}
|
|
1045
1187
|
}
|
|
1046
1188
|
/**
|
|
1047
1189
|
* Deletes the sponsorblock segments for a player.
|
|
@@ -1050,10 +1192,26 @@ class Node {
|
|
|
1050
1192
|
* @throws {RangeError} If the sponsorblock-plugin is not available in the Lavalink node.
|
|
1051
1193
|
*/
|
|
1052
1194
|
async deleteSponsorBlock(player) {
|
|
1053
|
-
if (!this.info.plugins.some((plugin) => plugin.name === "sponsorblock-plugin"))
|
|
1054
|
-
throw new
|
|
1055
|
-
|
|
1056
|
-
|
|
1195
|
+
if (!this.info.plugins.some((plugin) => plugin.name === "sponsorblock-plugin")) {
|
|
1196
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
1197
|
+
code: Enums_1.MagmaStreamErrorCode.NODE_PLUGIN_ERROR,
|
|
1198
|
+
message: `The plugin "sponsorblock-plugin" must be present in the lavalink node to delete SponsorBlock segments.`,
|
|
1199
|
+
context: { identifier: this.options.identifier, guildId: player.guildId },
|
|
1200
|
+
});
|
|
1201
|
+
}
|
|
1202
|
+
try {
|
|
1203
|
+
await this.rest.delete(`/v4/sessions/${this.sessionId}/players/${player.guildId}/sponsorblock/categories`);
|
|
1204
|
+
}
|
|
1205
|
+
catch (err) {
|
|
1206
|
+
throw err instanceof MagmastreamError_1.MagmaStreamError
|
|
1207
|
+
? err
|
|
1208
|
+
: new MagmastreamError_1.MagmaStreamError({
|
|
1209
|
+
code: Enums_1.MagmaStreamErrorCode.NODE_PROTOCOL_ERROR,
|
|
1210
|
+
message: "Failed to delete SponsorBlock segments.",
|
|
1211
|
+
cause: err instanceof Error ? err : undefined,
|
|
1212
|
+
context: { identifier: this.options.identifier, guildId: player.guildId },
|
|
1213
|
+
});
|
|
1214
|
+
}
|
|
1057
1215
|
}
|
|
1058
1216
|
/**
|
|
1059
1217
|
* Creates a README.md or README.txt file in the magmastream directory
|