magmastream 2.9.3-dev.2 → 2.9.3-dev.20
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 +168 -101
- package/dist/index.js +1 -1
- package/dist/statestorage/JsonQueue.js +28 -4
- package/dist/statestorage/MemoryQueue.js +51 -36
- package/dist/statestorage/RedisQueue.js +30 -9
- package/dist/structures/Enums.js +6 -0
- package/dist/structures/Filters.js +5 -4
- package/dist/structures/Manager.js +62 -48
- package/dist/structures/Node.js +91 -145
- package/dist/structures/Player.js +31 -124
- package/dist/structures/Rest.js +41 -21
- package/dist/structures/Utils.js +139 -77
- package/dist/wrappers/discord.js.js +13 -4
- package/dist/wrappers/discordeno.js +73 -0
- package/dist/wrappers/eris.js +14 -3
- package/dist/wrappers/oceanic.js +16 -4
- package/dist/wrappers/seyfert.js +19 -1
- package/package.json +30 -23
- package/dist/wrappers/detritus.js +0 -52
package/dist/structures/Utils.js
CHANGED
|
@@ -9,9 +9,11 @@ const Enums_1 = require("./Enums");
|
|
|
9
9
|
const path_1 = tslib_1.__importDefault(require("path"));
|
|
10
10
|
const safe_stable_stringify_1 = tslib_1.__importDefault(require("safe-stable-stringify"));
|
|
11
11
|
const MagmastreamError_1 = require("./MagmastreamError");
|
|
12
|
+
// import { isPlainObject } from "lodash";
|
|
12
13
|
// import playwright from "playwright";
|
|
13
14
|
/** @hidden */
|
|
14
15
|
const SIZES = ["0", "1", "2", "3", "default", "mqdefault", "hqdefault", "maxresdefault"];
|
|
16
|
+
const REQUIRED_TRACK_KEYS = ["track", "title", "uri"];
|
|
15
17
|
class TrackUtils {
|
|
16
18
|
static trackPartial = null;
|
|
17
19
|
static manager;
|
|
@@ -39,19 +41,12 @@ class TrackUtils {
|
|
|
39
41
|
const defaultProperties = [
|
|
40
42
|
Enums_1.TrackPartial.Track,
|
|
41
43
|
Enums_1.TrackPartial.Title,
|
|
42
|
-
Enums_1.TrackPartial.Identifier,
|
|
43
44
|
Enums_1.TrackPartial.Author,
|
|
44
45
|
Enums_1.TrackPartial.Duration,
|
|
45
|
-
Enums_1.TrackPartial.Isrc,
|
|
46
|
-
Enums_1.TrackPartial.IsSeekable,
|
|
47
|
-
Enums_1.TrackPartial.IsStream,
|
|
48
46
|
Enums_1.TrackPartial.Uri,
|
|
49
|
-
Enums_1.TrackPartial.ArtworkUrl,
|
|
50
47
|
Enums_1.TrackPartial.SourceName,
|
|
51
|
-
Enums_1.TrackPartial.
|
|
48
|
+
Enums_1.TrackPartial.ArtworkUrl,
|
|
52
49
|
Enums_1.TrackPartial.Requester,
|
|
53
|
-
Enums_1.TrackPartial.PluginInfo,
|
|
54
|
-
Enums_1.TrackPartial.CustomData,
|
|
55
50
|
];
|
|
56
51
|
/** The array of property names that will be removed from the Track class */
|
|
57
52
|
this.trackPartial = Array.from(new Set([...defaultProperties, ...partial]));
|
|
@@ -61,33 +56,39 @@ class TrackUtils {
|
|
|
61
56
|
}
|
|
62
57
|
/**
|
|
63
58
|
* Checks if the provided argument is a valid Track.
|
|
64
|
-
*
|
|
65
|
-
* @param trackOrTracks The Track or array of Tracks to check.
|
|
59
|
+
* @param value The value to check.
|
|
66
60
|
* @returns {boolean} Whether the provided argument is a valid Track.
|
|
67
61
|
*/
|
|
68
|
-
static
|
|
69
|
-
if (typeof
|
|
62
|
+
static isTrack(track) {
|
|
63
|
+
if (typeof track !== "object" || track === null)
|
|
70
64
|
return false;
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
65
|
+
const t = track;
|
|
66
|
+
return REQUIRED_TRACK_KEYS.every((key) => typeof t[key] === "string");
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Checks if the provided argument is a valid Track array.
|
|
70
|
+
* @param value The value to check.
|
|
71
|
+
* @returns {boolean} Whether the provided argument is a valid Track array.
|
|
72
|
+
*/
|
|
73
|
+
static isTrackArray(value) {
|
|
74
|
+
return Array.isArray(value) && value.every(this.isTrack);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Checks if the provided argument is a valid Track or Track array.
|
|
78
|
+
* @param value The value to check.
|
|
79
|
+
* @returns {boolean} Whether the provided argument is a valid Track or Track array.
|
|
80
|
+
*/
|
|
81
|
+
static validate(value) {
|
|
82
|
+
return this.isTrack(value) || this.isTrackArray(value);
|
|
83
83
|
}
|
|
84
84
|
/**
|
|
85
85
|
* Builds a Track from the raw data from Lavalink and a optional requester.
|
|
86
86
|
* @param data The raw data from Lavalink to build the Track from.
|
|
87
87
|
* @param requester The user who requested the track, if any.
|
|
88
|
+
* @param isAutoPlay Whether the track is autoplayed. Defaults to false.
|
|
88
89
|
* @returns The built Track.
|
|
89
90
|
*/
|
|
90
|
-
static build(data, requester) {
|
|
91
|
+
static build(data, requester, isAutoplay = false) {
|
|
91
92
|
if (typeof data === "undefined") {
|
|
92
93
|
throw new MagmastreamError_1.MagmaStreamError({
|
|
93
94
|
code: Enums_1.MagmaStreamErrorCode.UTILS_TRACK_BUILD_FAILED,
|
|
@@ -138,6 +139,7 @@ class TrackUtils {
|
|
|
138
139
|
requester: requester,
|
|
139
140
|
pluginInfo: data.pluginInfo,
|
|
140
141
|
customData: {},
|
|
142
|
+
isAutoplay: isAutoplay,
|
|
141
143
|
};
|
|
142
144
|
track.displayThumbnail = track.displayThumbnail.bind(track);
|
|
143
145
|
if (this.trackPartial) {
|
|
@@ -542,8 +544,7 @@ class AutoPlayUtils {
|
|
|
542
544
|
return typeof data === "object" && data !== null && "encoded" in data && "info" in data;
|
|
543
545
|
}
|
|
544
546
|
static isTrackDataArray(data) {
|
|
545
|
-
return (Array.isArray(data) &&
|
|
546
|
-
data.every((track) => typeof track === "object" && track !== null && "encoded" in track && "info" in track && typeof track.encoded === "string"));
|
|
547
|
+
return (Array.isArray(data) && data.every((track) => typeof track === "object" && track !== null && "encoded" in track && "info" in track && typeof track.encoded === "string"));
|
|
547
548
|
}
|
|
548
549
|
static buildTracksFromResponse(recommendedResult, requester) {
|
|
549
550
|
if (!recommendedResult)
|
|
@@ -560,7 +561,7 @@ class AutoPlayUtils {
|
|
|
560
561
|
context: { recommendedResult },
|
|
561
562
|
});
|
|
562
563
|
}
|
|
563
|
-
return [TrackUtils.build(data, requester)];
|
|
564
|
+
return [TrackUtils.build(data, requester, true)];
|
|
564
565
|
}
|
|
565
566
|
case Enums_1.LoadTypes.Short:
|
|
566
567
|
case Enums_1.LoadTypes.Search: {
|
|
@@ -572,7 +573,7 @@ class AutoPlayUtils {
|
|
|
572
573
|
context: { recommendedResult },
|
|
573
574
|
});
|
|
574
575
|
}
|
|
575
|
-
return data.map((d) => TrackUtils.build(d, requester));
|
|
576
|
+
return data.map((d) => TrackUtils.build(d, requester, true));
|
|
576
577
|
}
|
|
577
578
|
case Enums_1.LoadTypes.Album:
|
|
578
579
|
case Enums_1.LoadTypes.Artist:
|
|
@@ -582,7 +583,7 @@ class AutoPlayUtils {
|
|
|
582
583
|
case Enums_1.LoadTypes.Playlist: {
|
|
583
584
|
const data = recommendedResult.data;
|
|
584
585
|
if (this.isPlaylistRawData(data)) {
|
|
585
|
-
return data.tracks.map((d) => TrackUtils.build(d, requester));
|
|
586
|
+
return data.tracks.map((d) => TrackUtils.build(d, requester, true));
|
|
586
587
|
}
|
|
587
588
|
throw new MagmastreamError_1.MagmaStreamError({
|
|
588
589
|
code: Enums_1.MagmaStreamErrorCode.UTILS_AUTOPLAY_BUILD_FAILED,
|
|
@@ -622,71 +623,121 @@ class PlayerUtils {
|
|
|
622
623
|
* @returns The serialized Player instance
|
|
623
624
|
*/
|
|
624
625
|
static async serializePlayer(player) {
|
|
626
|
+
const isNonSerializable = (value) => {
|
|
627
|
+
if (typeof value === "function" || typeof value === "symbol")
|
|
628
|
+
return true;
|
|
629
|
+
if (typeof value === "object" && value !== null) {
|
|
630
|
+
const ctorName = value.constructor?.name ?? "";
|
|
631
|
+
return (value instanceof Map ||
|
|
632
|
+
value instanceof Set ||
|
|
633
|
+
value instanceof WeakMap ||
|
|
634
|
+
value instanceof WeakSet ||
|
|
635
|
+
ctorName === "Timeout" ||
|
|
636
|
+
ctorName === "Socket" ||
|
|
637
|
+
ctorName === "TLSSocket" ||
|
|
638
|
+
ctorName === "EventEmitter");
|
|
639
|
+
}
|
|
640
|
+
return false;
|
|
641
|
+
};
|
|
642
|
+
const safeSerialize = (obj) => {
|
|
643
|
+
if (!obj || typeof obj !== "object")
|
|
644
|
+
return obj;
|
|
645
|
+
const result = {};
|
|
646
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
647
|
+
if (!isNonSerializable(v)) {
|
|
648
|
+
result[k] = v;
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
return result;
|
|
652
|
+
};
|
|
625
653
|
try {
|
|
626
|
-
const current = await player.queue.getCurrent();
|
|
627
|
-
const
|
|
628
|
-
|
|
629
|
-
const serializeTrack = (track) => ({
|
|
630
|
-
...track,
|
|
631
|
-
requester: track.requester ? { id: track.requester.id, username: track.requester.username } : null,
|
|
632
|
-
});
|
|
633
|
-
const safeNode = player.node
|
|
634
|
-
? JSON.parse(JSON.stringify(player.node, (key, value) => {
|
|
635
|
-
if (key === "rest" || key === "players" || key === "shards" || key === "manager")
|
|
636
|
-
return undefined;
|
|
637
|
-
return value;
|
|
638
|
-
}))
|
|
639
|
-
: null;
|
|
640
|
-
return JSON.parse(JSON.stringify(player, (key, value) => {
|
|
641
|
-
if (key === "manager")
|
|
642
|
-
return null;
|
|
643
|
-
if (key === "node")
|
|
644
|
-
return safeNode;
|
|
645
|
-
if (key === "filters") {
|
|
654
|
+
const [current, tracks, previous] = await Promise.all([player.queue.getCurrent(), player.queue.getTracks(), player.queue.getPrevious()]);
|
|
655
|
+
const serializeTrack = (track) => {
|
|
656
|
+
try {
|
|
646
657
|
return {
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
karaoke: value?.karaoke ?? null,
|
|
650
|
-
rotation: value?.rotation ?? null,
|
|
651
|
-
timescale: value?.timescale ?? null,
|
|
652
|
-
vibrato: value?.vibrato ?? null,
|
|
653
|
-
reverb: value?.reverb ?? null,
|
|
654
|
-
volume: value?.volume ?? 1.0,
|
|
655
|
-
bassBoostlevel: value?.bassBoostlevel ?? null,
|
|
656
|
-
filterStatus: value?.filtersStatus ? { ...value.filtersStatus } : {},
|
|
658
|
+
...track,
|
|
659
|
+
requester: track.requester ? { id: track.requester.id, username: track.requester.username } : null,
|
|
657
660
|
};
|
|
658
661
|
}
|
|
659
|
-
|
|
660
|
-
return
|
|
661
|
-
current: current ? serializeTrack(current) : null,
|
|
662
|
-
tracks: tracks.map(serializeTrack),
|
|
663
|
-
previous: previous.map(serializeTrack),
|
|
664
|
-
};
|
|
662
|
+
catch {
|
|
663
|
+
return null;
|
|
665
664
|
}
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
665
|
+
};
|
|
666
|
+
const safeCurrent = current ? serializeTrack(current) : null;
|
|
667
|
+
const safeTracks = tracks.map(serializeTrack).filter((t) => t !== null);
|
|
668
|
+
const safePrevious = previous.map(serializeTrack).filter((t) => t !== null);
|
|
669
|
+
let safeNode = null;
|
|
670
|
+
if (player.node) {
|
|
671
|
+
try {
|
|
672
|
+
safeNode = JSON.parse(JSON.stringify(player.node, (key, value) => {
|
|
673
|
+
if (["rest", "players", "shards", "manager"].includes(key))
|
|
674
|
+
return undefined;
|
|
675
|
+
if (isNonSerializable(value))
|
|
676
|
+
return undefined;
|
|
677
|
+
return value;
|
|
678
|
+
}));
|
|
671
679
|
}
|
|
672
|
-
|
|
673
|
-
|
|
680
|
+
catch {
|
|
681
|
+
safeNode = null;
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
const snapshot = {
|
|
685
|
+
options: player.options,
|
|
686
|
+
voiceState: player.voiceState,
|
|
687
|
+
clusterId: player.clusterId,
|
|
688
|
+
guildId: player.guildId,
|
|
689
|
+
voiceChannelId: player.voiceChannelId ?? null,
|
|
690
|
+
textChannelId: player.textChannelId ?? null,
|
|
691
|
+
volume: player.volume,
|
|
692
|
+
paused: player.paused,
|
|
693
|
+
playing: player.playing,
|
|
694
|
+
position: player.position,
|
|
695
|
+
trackRepeat: player.trackRepeat,
|
|
696
|
+
queueRepeat: player.queueRepeat,
|
|
697
|
+
dynamicRepeat: player.dynamicRepeat,
|
|
698
|
+
node: safeNode,
|
|
699
|
+
queue: {
|
|
700
|
+
current: safeCurrent,
|
|
701
|
+
tracks: safeTracks,
|
|
702
|
+
previous: safePrevious,
|
|
703
|
+
},
|
|
704
|
+
filters: player.filters
|
|
705
|
+
? {
|
|
706
|
+
distortion: player.filters.distortion ?? null,
|
|
707
|
+
equalizer: player.filters.equalizer ?? [],
|
|
708
|
+
karaoke: player.filters.karaoke ?? null,
|
|
709
|
+
rotation: player.filters.rotation ?? null,
|
|
710
|
+
timescale: player.filters.timescale ?? null,
|
|
711
|
+
vibrato: player.filters.vibrato ?? null,
|
|
712
|
+
reverb: player.filters.reverb ?? null,
|
|
713
|
+
volume: player.filters.volume ?? 1.0,
|
|
714
|
+
bassBoostlevel: player.filters.bassBoostlevel ?? null,
|
|
715
|
+
filterStatus: { ...player.filters.filtersStatus },
|
|
716
|
+
}
|
|
717
|
+
: null,
|
|
718
|
+
data: safeSerialize(player.getSerializableData()),
|
|
719
|
+
};
|
|
720
|
+
// Sanity check
|
|
721
|
+
JSON.stringify(snapshot);
|
|
722
|
+
return snapshot;
|
|
674
723
|
}
|
|
675
724
|
catch (err) {
|
|
676
|
-
|
|
725
|
+
const error = err instanceof MagmastreamError_1.MagmaStreamError
|
|
677
726
|
? err
|
|
678
727
|
: new MagmastreamError_1.MagmaStreamError({
|
|
679
|
-
code: Enums_1.MagmaStreamErrorCode.
|
|
680
|
-
message: `An error occurred while
|
|
728
|
+
code: Enums_1.MagmaStreamErrorCode.UTILS_PLAYER_SERIALIZE_FAILED,
|
|
729
|
+
message: `An error occurred while serializing player: ${err instanceof Error ? err.message : String(err)}`,
|
|
681
730
|
cause: err instanceof Error ? err : undefined,
|
|
682
731
|
});
|
|
732
|
+
console.error(error);
|
|
733
|
+
return null;
|
|
683
734
|
}
|
|
684
735
|
}
|
|
685
736
|
/**
|
|
686
737
|
* Gets the base directory for player data.
|
|
687
738
|
*/
|
|
688
739
|
static getPlayersBaseDir() {
|
|
689
|
-
return path_1.default.join(process.cwd(), "magmastream", "sessionData", "players");
|
|
740
|
+
return path_1.default.join(process.cwd(), "magmastream", "sessionData", "cluster", String(this.manager.options.clusterId), "players");
|
|
690
741
|
}
|
|
691
742
|
/**
|
|
692
743
|
* Gets the path to the player's directory.
|
|
@@ -718,6 +769,17 @@ class PlayerUtils {
|
|
|
718
769
|
static getPlayerPreviousPath(guildId) {
|
|
719
770
|
return path_1.default.join(this.getGuildDir(guildId), "previous.json");
|
|
720
771
|
}
|
|
772
|
+
/**
|
|
773
|
+
* Gets the Redis key for player storage.
|
|
774
|
+
*/
|
|
775
|
+
static getRedisKey() {
|
|
776
|
+
const cfg = this.manager.options.stateStorage.redisConfig;
|
|
777
|
+
// Default prefix
|
|
778
|
+
let prefix = (cfg.prefix ?? "magmastream:").trim();
|
|
779
|
+
prefix = prefix.replace(/:+$/g, "") + ":";
|
|
780
|
+
const clusterId = String(this.manager.options.clusterId ?? 0).trim() || "0";
|
|
781
|
+
return `${prefix}cluster:${clusterId}:`;
|
|
782
|
+
}
|
|
721
783
|
}
|
|
722
784
|
exports.PlayerUtils = PlayerUtils;
|
|
723
785
|
/** Gets or extends structures to extend the built in, or already extended, classes to add more functionality. */
|
|
@@ -4,7 +4,10 @@ exports.DiscordJSManager = void 0;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const Manager_1 = require("../structures/Manager");
|
|
6
6
|
const discord_js_1 = require("discord.js");
|
|
7
|
-
const
|
|
7
|
+
const discord_js_2 = require("discord.js");
|
|
8
|
+
const MagmastreamError_1 = require("../structures/MagmastreamError");
|
|
9
|
+
const Enums_1 = require("../structures/Enums");
|
|
10
|
+
const [major, minor] = discord_js_2.version.split(".").map(Number);
|
|
8
11
|
tslib_1.__exportStar(require("../index"), exports);
|
|
9
12
|
/**
|
|
10
13
|
* Discord.js wrapper for Magmastream.
|
|
@@ -14,6 +17,12 @@ class DiscordJSManager extends Manager_1.Manager {
|
|
|
14
17
|
constructor(client, options) {
|
|
15
18
|
super(options);
|
|
16
19
|
this.client = client;
|
|
20
|
+
if (!this.client.options.intents.has(discord_js_1.GatewayIntentBits.GuildVoiceStates)) {
|
|
21
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
22
|
+
code: Enums_1.MagmaStreamErrorCode.INTENT_MISSING,
|
|
23
|
+
message: "[Custom Wrapper] Your Discord.js client must have the GuildVoiceStates intent enabled.",
|
|
24
|
+
});
|
|
25
|
+
}
|
|
17
26
|
const attachReadyHandler = () => {
|
|
18
27
|
const handler = () => {
|
|
19
28
|
if (!this.options.clientId)
|
|
@@ -21,11 +30,11 @@ class DiscordJSManager extends Manager_1.Manager {
|
|
|
21
30
|
};
|
|
22
31
|
// Only attach clientReady if Discord.js >= 14.22.0
|
|
23
32
|
if (major > 14 || (major === 14 && minor >= 22)) {
|
|
24
|
-
client.once("clientReady", handler);
|
|
33
|
+
this.client.once("clientReady", handler);
|
|
25
34
|
}
|
|
26
35
|
// Only attach ready if Discord.js < 14.22.0
|
|
27
36
|
if (major < 14 || (major === 14 && minor < 22)) {
|
|
28
|
-
client.once("ready", handler);
|
|
37
|
+
this.client.once("ready", handler);
|
|
29
38
|
}
|
|
30
39
|
};
|
|
31
40
|
attachReadyHandler();
|
|
@@ -39,7 +48,7 @@ class DiscordJSManager extends Manager_1.Manager {
|
|
|
39
48
|
guild.shard.send(packet);
|
|
40
49
|
}
|
|
41
50
|
async resolveUser(user) {
|
|
42
|
-
const id = typeof user === "string" ? user : user.id;
|
|
51
|
+
const id = typeof user === "string" ? user : String(user.id);
|
|
43
52
|
const cached = this.client.users.cache.get(id);
|
|
44
53
|
if (cached)
|
|
45
54
|
return cached;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DiscordenoManager = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const Manager_1 = require("../structures/Manager");
|
|
6
|
+
const bot_1 = require("@discordeno/bot");
|
|
7
|
+
const Enums_1 = require("../structures/Enums");
|
|
8
|
+
const MagmastreamError_1 = require("../structures/MagmastreamError");
|
|
9
|
+
tslib_1.__exportStar(require("../index"), exports);
|
|
10
|
+
/**
|
|
11
|
+
* Discordeno wrapper for Magmastream.
|
|
12
|
+
*/
|
|
13
|
+
class DiscordenoManager extends Manager_1.Manager {
|
|
14
|
+
client;
|
|
15
|
+
constructor(client, options) {
|
|
16
|
+
super(options);
|
|
17
|
+
this.client = client;
|
|
18
|
+
// Ensure GuildVoiceStates intent is enabled
|
|
19
|
+
const intents = this.client.gateway.intents;
|
|
20
|
+
if (!(intents & bot_1.GatewayIntents.GuildVoiceStates)) {
|
|
21
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
22
|
+
code: Enums_1.MagmaStreamErrorCode.INTENT_MISSING,
|
|
23
|
+
message: "[Custom Wrapper] Your Discordeno client must have the GuildVoiceStates intent enabled.",
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
// Chain READY event
|
|
27
|
+
const oldReady = this.client.handlers.READY;
|
|
28
|
+
this.client.handlers.READY = (bot, payload, shardId) => {
|
|
29
|
+
if (oldReady)
|
|
30
|
+
oldReady(bot, payload, shardId);
|
|
31
|
+
if (!this.options?.clientId)
|
|
32
|
+
this.options.clientId = this.client.applicationId.toString();
|
|
33
|
+
};
|
|
34
|
+
// Chain VOICE_STATE_UPDATE event
|
|
35
|
+
const oldVoiceState = this.client.handlers.VOICE_STATE_UPDATE;
|
|
36
|
+
this.client.handlers.VOICE_STATE_UPDATE = (bot, payload, shardId) => {
|
|
37
|
+
if (oldVoiceState)
|
|
38
|
+
oldVoiceState(bot, payload, shardId);
|
|
39
|
+
this.updateVoiceState(payload);
|
|
40
|
+
};
|
|
41
|
+
// Chain VOICE_SERVER_UPDATE event
|
|
42
|
+
const oldVoiceServer = this.client.handlers.VOICE_SERVER_UPDATE;
|
|
43
|
+
this.client.handlers.VOICE_SERVER_UPDATE = (bot, payload, shardId) => {
|
|
44
|
+
if (oldVoiceServer)
|
|
45
|
+
oldVoiceServer(bot, payload, shardId);
|
|
46
|
+
this.updateVoiceState(payload);
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
// Send voice state updates to the guild shard
|
|
50
|
+
send(packet) {
|
|
51
|
+
this.client.gateway.sendPayload(this.client.gateway.calculateShardId(packet.d.guild_id), {
|
|
52
|
+
op: bot_1.GatewayOpcodes.VoiceStateUpdate,
|
|
53
|
+
d: packet.d,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Resolve a user by ID or partial info.
|
|
58
|
+
* Uses user-provided cache getter if available, otherwise falls back to minimal info.
|
|
59
|
+
*/
|
|
60
|
+
async resolveUser(user) {
|
|
61
|
+
const id = typeof user === "string" ? user : String(user.id);
|
|
62
|
+
// Try user-provided cache getter
|
|
63
|
+
const cached = this.getUserFromCache(id);
|
|
64
|
+
if (cached)
|
|
65
|
+
return cached;
|
|
66
|
+
// Fallback: return minimal info
|
|
67
|
+
return {
|
|
68
|
+
id,
|
|
69
|
+
username: typeof user === "string" ? undefined : user.username,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
exports.DiscordenoManager = DiscordenoManager;
|
package/dist/wrappers/eris.js
CHANGED
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ErisManager = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
+
const v10_1 = require("discord-api-types/v10");
|
|
5
6
|
const Manager_1 = require("../structures/Manager");
|
|
7
|
+
const Enums_1 = require("../structures/Enums");
|
|
8
|
+
const MagmastreamError_1 = require("../structures/MagmastreamError");
|
|
6
9
|
tslib_1.__exportStar(require("../index"), exports);
|
|
7
10
|
/**
|
|
8
11
|
* Eris wrapper for Magmastream.
|
|
@@ -12,11 +15,19 @@ class ErisManager extends Manager_1.Manager {
|
|
|
12
15
|
constructor(client, options) {
|
|
13
16
|
super(options);
|
|
14
17
|
this.client = client;
|
|
15
|
-
|
|
18
|
+
const intents = this.client.options.intents;
|
|
19
|
+
const hasGuildVoiceStates = typeof intents === "number" ? (intents & v10_1.GatewayIntentBits.GuildVoiceStates) === v10_1.GatewayIntentBits.GuildVoiceStates : intents.includes("guildVoiceStates");
|
|
20
|
+
if (!hasGuildVoiceStates) {
|
|
21
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
22
|
+
code: Enums_1.MagmaStreamErrorCode.INTENT_MISSING,
|
|
23
|
+
message: "[Custom Wrapper] Your Eris client must have the guildVoiceStates intent enabled.",
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
this.client.once("ready", () => {
|
|
16
27
|
if (!this.options.clientId)
|
|
17
28
|
this.options.clientId = client.user.id;
|
|
18
29
|
});
|
|
19
|
-
client.on("rawWS", async (packet) => {
|
|
30
|
+
this.client.on("rawWS", async (packet) => {
|
|
20
31
|
await this.updateVoiceState(packet);
|
|
21
32
|
});
|
|
22
33
|
}
|
|
@@ -26,7 +37,7 @@ class ErisManager extends Manager_1.Manager {
|
|
|
26
37
|
guild.shard.sendWS(packet.op, packet.d);
|
|
27
38
|
}
|
|
28
39
|
async resolveUser(user) {
|
|
29
|
-
const id = typeof user === "string" ? user : user.id;
|
|
40
|
+
const id = typeof user === "string" ? user : String(user.id);
|
|
30
41
|
const cached = this.client.users.get(id);
|
|
31
42
|
if (cached)
|
|
32
43
|
return cached;
|
package/dist/wrappers/oceanic.js
CHANGED
|
@@ -3,6 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.OceanicManager = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const Manager_1 = require("../structures/Manager");
|
|
6
|
+
const oceanic_js_1 = require("oceanic.js");
|
|
7
|
+
const Enums_1 = require("../structures/Enums");
|
|
8
|
+
const MagmastreamError_1 = require("../structures/MagmastreamError");
|
|
6
9
|
tslib_1.__exportStar(require("../index"), exports);
|
|
7
10
|
/**
|
|
8
11
|
* Oceanic wrapper for Magmastream.
|
|
@@ -12,11 +15,20 @@ class OceanicManager extends Manager_1.Manager {
|
|
|
12
15
|
constructor(client, options) {
|
|
13
16
|
super(options);
|
|
14
17
|
this.client = client;
|
|
15
|
-
|
|
18
|
+
const intents = this.client.shards.options.intents;
|
|
19
|
+
const { Intents } = oceanic_js_1.Constants;
|
|
20
|
+
const hasGuildVoiceStates = typeof intents === "number" ? (intents & Intents.GUILD_VOICE_STATES) === Intents.GUILD_VOICE_STATES : intents.includes("GUILD_VOICE_STATES");
|
|
21
|
+
if (!hasGuildVoiceStates) {
|
|
22
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
23
|
+
code: Enums_1.MagmaStreamErrorCode.INTENT_MISSING,
|
|
24
|
+
message: "[Custom Wrapper] Your Oceanic client must have the GUILD_VOICE_STATES intent enabled.",
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
this.client.once("ready", () => {
|
|
16
28
|
if (!this.options.clientId)
|
|
17
|
-
this.options.clientId = client.user.id;
|
|
29
|
+
this.options.clientId = this.client.user.id;
|
|
18
30
|
});
|
|
19
|
-
client.on("packet", async (packet) => {
|
|
31
|
+
this.client.on("packet", async (packet) => {
|
|
20
32
|
await this.updateVoiceState(packet);
|
|
21
33
|
});
|
|
22
34
|
}
|
|
@@ -26,7 +38,7 @@ class OceanicManager extends Manager_1.Manager {
|
|
|
26
38
|
guild.shard.send(packet.op, packet.d);
|
|
27
39
|
}
|
|
28
40
|
async resolveUser(user) {
|
|
29
|
-
const id = typeof user === "string" ? user : user.id;
|
|
41
|
+
const id = typeof user === "string" ? user : String(user.id);
|
|
30
42
|
const cached = this.client.users.get(id);
|
|
31
43
|
if (cached)
|
|
32
44
|
return cached;
|
package/dist/wrappers/seyfert.js
CHANGED
|
@@ -4,7 +4,10 @@ exports.SeyfertManager = void 0;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const Manager_1 = require("../structures/Manager");
|
|
6
6
|
const seyfert_1 = require("seyfert");
|
|
7
|
+
const types_1 = require("seyfert/lib/types");
|
|
7
8
|
const common_1 = require("seyfert/lib/common");
|
|
9
|
+
const MagmastreamError_1 = require("../structures/MagmastreamError");
|
|
10
|
+
const Enums_1 = require("../structures/Enums");
|
|
8
11
|
tslib_1.__exportStar(require("../index"), exports);
|
|
9
12
|
/**
|
|
10
13
|
* Seyfert wrapper for Magmastream.
|
|
@@ -36,6 +39,21 @@ class SeyfertManager extends Manager_1.Manager {
|
|
|
36
39
|
constructor(client, options) {
|
|
37
40
|
super(options);
|
|
38
41
|
this.client = client;
|
|
42
|
+
this.client
|
|
43
|
+
.getRC()
|
|
44
|
+
.then((rc) => {
|
|
45
|
+
if (!(rc.intents & types_1.GatewayIntentBits.GuildVoiceStates)) {
|
|
46
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
47
|
+
code: Enums_1.MagmaStreamErrorCode.INTENT_MISSING,
|
|
48
|
+
message: "[Custom Wrapper] Your Seyfert client must have the GuildVoiceStates intent enabled.",
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
})
|
|
52
|
+
.catch((error) => {
|
|
53
|
+
queueMicrotask(() => {
|
|
54
|
+
throw error;
|
|
55
|
+
});
|
|
56
|
+
});
|
|
39
57
|
}
|
|
40
58
|
send(packet) {
|
|
41
59
|
if (this.client instanceof seyfert_1.Client) {
|
|
@@ -46,7 +64,7 @@ class SeyfertManager extends Manager_1.Manager {
|
|
|
46
64
|
}
|
|
47
65
|
}
|
|
48
66
|
async resolveUser(user) {
|
|
49
|
-
const id = typeof user === "string" ? user : user.id;
|
|
67
|
+
const id = typeof user === "string" ? user : String(user.id);
|
|
50
68
|
const cached = this.client.cache.users?.get(id);
|
|
51
69
|
if (cached)
|
|
52
70
|
return cached;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "magmastream",
|
|
3
|
-
"version": "2.9.3-dev.
|
|
3
|
+
"version": "2.9.3-dev.20",
|
|
4
4
|
"description": "A user-friendly Lavalink client designed for NodeJS.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -10,45 +10,51 @@
|
|
|
10
10
|
"scripts": {
|
|
11
11
|
"build": "tsc",
|
|
12
12
|
"types": "rtb --dist dist",
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
13
|
+
"format": "prettier --write .",
|
|
14
|
+
"format:check": "prettier --check .",
|
|
15
|
+
"lint": "eslint \"src/**/*.{ts,js}\"",
|
|
16
|
+
"lint:fix": "eslint --fix \"src/**/*.{ts,js}\"",
|
|
17
|
+
"ci": "run-s format:check lint build types",
|
|
18
|
+
"release:dev": "npm run format && npm run lint:fix && npm run ci && npm version prerelease --preid=dev && git push && npm publish --tag dev"
|
|
17
19
|
},
|
|
18
20
|
"devDependencies": {
|
|
19
21
|
"@favware/rollup-type-bundler": "^4.0.0",
|
|
20
|
-
"@types/jsdom": "^
|
|
21
|
-
"@types/lodash": "^4.17.
|
|
22
|
-
"@types/node": "^
|
|
22
|
+
"@types/jsdom": "^27.0.0",
|
|
23
|
+
"@types/lodash": "^4.17.24",
|
|
24
|
+
"@types/node": "^25.3.0",
|
|
23
25
|
"@types/ws": "^8.18.1",
|
|
24
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
25
|
-
"@typescript-eslint/parser": "^8.
|
|
26
|
-
"eslint": "^
|
|
26
|
+
"@typescript-eslint/eslint-plugin": "^8.56.0",
|
|
27
|
+
"@typescript-eslint/parser": "^8.56.0",
|
|
28
|
+
"eslint": "^10.0.1",
|
|
27
29
|
"npm-run-all": "^4.1.5",
|
|
28
|
-
"
|
|
30
|
+
"prettier": "^3.8.1",
|
|
31
|
+
"typedoc": "^0.28.17",
|
|
29
32
|
"typedoc-plugin-no-inherit": "^1.6.1",
|
|
30
|
-
"typescript": "^5.
|
|
33
|
+
"typescript": "^5.9.3"
|
|
31
34
|
},
|
|
32
35
|
"dependencies": {
|
|
33
36
|
"@discordjs/collection": "^2.1.1",
|
|
34
|
-
"axios": "^1.
|
|
37
|
+
"axios": "^1.13.5",
|
|
35
38
|
"events": "^3.3.0",
|
|
36
|
-
"ioredis": "^5.
|
|
37
|
-
"jsdom": "^
|
|
38
|
-
"lodash": "^4.17.
|
|
39
|
+
"ioredis": "^5.9.3",
|
|
40
|
+
"jsdom": "^28.1.0",
|
|
41
|
+
"lodash": "^4.17.23",
|
|
39
42
|
"safe-stable-stringify": "^2.5.0",
|
|
40
43
|
"tslib": "^2.8.1",
|
|
41
|
-
"ws": "^8.
|
|
44
|
+
"ws": "^8.19.0"
|
|
42
45
|
},
|
|
43
46
|
"optionalDependencies": {
|
|
44
|
-
"detritus-client": "0.16.x",
|
|
45
47
|
"discord.js": "14.x",
|
|
48
|
+
"discordeno": "21.x",
|
|
46
49
|
"eris": "0.18.x",
|
|
47
|
-
"oceanic.js": "1.
|
|
48
|
-
"seyfert": "
|
|
50
|
+
"oceanic.js": "^1.13.0",
|
|
51
|
+
"seyfert": "4.x"
|
|
52
|
+
},
|
|
53
|
+
"overrides": {
|
|
54
|
+
"undici": "^6.23.0"
|
|
49
55
|
},
|
|
50
56
|
"engines": {
|
|
51
|
-
"node": ">=
|
|
57
|
+
"node": ">=20.19.0"
|
|
52
58
|
},
|
|
53
59
|
"eslintConfig": {
|
|
54
60
|
"root": true,
|
|
@@ -92,7 +98,8 @@
|
|
|
92
98
|
"magmastream"
|
|
93
99
|
],
|
|
94
100
|
"repository": {
|
|
95
|
-
"
|
|
101
|
+
"type": "git",
|
|
102
|
+
"url": "git+https://gitryx.com/MagmaStream/magmastream.git#main"
|
|
96
103
|
},
|
|
97
104
|
"homepage": "https://docs.magmastream.com",
|
|
98
105
|
"author": "Abel Purnwasy",
|