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
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { AutoPlayPlatform, TrackPartial } from "./Enums";
|
|
2
|
+
import { Manager } from "./Manager";
|
|
3
|
+
import { AnyUser, ErrorOrEmptySearchResult, Extendable, LavalinkResponse, SearchResult, SerializedPlayerState, Track, TrackData } from "./Types";
|
|
4
|
+
import { Player } from "./Player";
|
|
5
|
+
export declare abstract class TrackUtils {
|
|
6
|
+
static trackPartial: TrackPartial[] | null;
|
|
7
|
+
private static manager;
|
|
8
|
+
/**
|
|
9
|
+
* Initializes the TrackUtils class with the given manager.
|
|
10
|
+
* @param manager The manager instance to use.
|
|
11
|
+
* @hidden
|
|
12
|
+
*/
|
|
13
|
+
static init(manager: Manager): void;
|
|
14
|
+
/**
|
|
15
|
+
* Sets the partial properties for the Track class. If a Track has some of its properties removed by the partial,
|
|
16
|
+
* it will be considered a partial Track.
|
|
17
|
+
* @param {TrackPartial} partial The array of string property names to remove from the Track class.
|
|
18
|
+
*/
|
|
19
|
+
static setTrackPartial(partial: TrackPartial[]): void;
|
|
20
|
+
/**
|
|
21
|
+
* Checks if the provided argument is a valid Track.
|
|
22
|
+
* @param value The value to check.
|
|
23
|
+
* @returns {boolean} Whether the provided argument is a valid Track.
|
|
24
|
+
*/
|
|
25
|
+
static isTrack(track: unknown): track is Track;
|
|
26
|
+
/**
|
|
27
|
+
* Checks if the provided argument is a valid Track array.
|
|
28
|
+
* @param value The value to check.
|
|
29
|
+
* @returns {boolean} Whether the provided argument is a valid Track array.
|
|
30
|
+
*/
|
|
31
|
+
static isTrackArray(value: unknown): value is Track[];
|
|
32
|
+
/**
|
|
33
|
+
* Checks if the provided argument is a valid Track or Track array.
|
|
34
|
+
* @param value The value to check.
|
|
35
|
+
* @returns {boolean} Whether the provided argument is a valid Track or Track array.
|
|
36
|
+
*/
|
|
37
|
+
static validate(value: unknown): value is Track | Track[];
|
|
38
|
+
/**
|
|
39
|
+
* Builds a Track from the raw data from Lavalink and a optional requester.
|
|
40
|
+
* @param data The raw data from Lavalink to build the Track from.
|
|
41
|
+
* @param requester The user who requested the track, if any.
|
|
42
|
+
* @param isAutoPlay Whether the track is autoplayed. Defaults to false.
|
|
43
|
+
* @returns The built Track.
|
|
44
|
+
*/
|
|
45
|
+
static build<T = AnyUser>(data: TrackData, requester?: T, isAutoplay?: boolean): Track;
|
|
46
|
+
/**
|
|
47
|
+
* Validates a search result.
|
|
48
|
+
* @param result The search result to validate.
|
|
49
|
+
* @returns Whether the search result is valid.
|
|
50
|
+
*/
|
|
51
|
+
static isErrorOrEmptySearchResult(result: SearchResult): result is ErrorOrEmptySearchResult;
|
|
52
|
+
/**
|
|
53
|
+
* Revives a track.
|
|
54
|
+
* @param track The track to revive.
|
|
55
|
+
* @returns The revived track.
|
|
56
|
+
*/
|
|
57
|
+
static revive(track: Track): Track;
|
|
58
|
+
}
|
|
59
|
+
export declare abstract class AutoPlayUtils {
|
|
60
|
+
private static manager;
|
|
61
|
+
/**
|
|
62
|
+
* Initializes the AutoPlayUtils class with the given manager.
|
|
63
|
+
* @param manager The manager instance to use.
|
|
64
|
+
* @hidden
|
|
65
|
+
*/
|
|
66
|
+
static init(manager: Manager): Promise<void>;
|
|
67
|
+
/**
|
|
68
|
+
* Gets recommended tracks for the given track.
|
|
69
|
+
* @param track The track to get recommended tracks for.
|
|
70
|
+
* @returns An array of recommended tracks.
|
|
71
|
+
*/
|
|
72
|
+
static getRecommendedTracks(track: Track): Promise<Track[]>;
|
|
73
|
+
/**
|
|
74
|
+
* Gets recommended tracks from Last.fm for the given track.
|
|
75
|
+
* @param track The track to get recommended tracks for.
|
|
76
|
+
* @param apiKey The API key for Last.fm.
|
|
77
|
+
* @returns An array of recommended tracks.
|
|
78
|
+
*/
|
|
79
|
+
static getRecommendedTracksFromLastFm(track: Track, apiKey: string): Promise<Track[]>;
|
|
80
|
+
/**
|
|
81
|
+
* Gets recommended tracks from the given source.
|
|
82
|
+
* @param track The track to get recommended tracks for.
|
|
83
|
+
* @param platform The source to get recommended tracks from.
|
|
84
|
+
* @returns An array of recommended tracks.
|
|
85
|
+
*/
|
|
86
|
+
static getRecommendedTracksFromSource(track: Track, platform: AutoPlayPlatform): Promise<Track[]>;
|
|
87
|
+
/**
|
|
88
|
+
* Searches for a track using the manager and returns resolved tracks.
|
|
89
|
+
* @param query The search query (artist - title).
|
|
90
|
+
* @param requester The requester who initiated the search.
|
|
91
|
+
* @returns An array of resolved tracks, or an empty array if not found or error occurred.
|
|
92
|
+
*/
|
|
93
|
+
private static resolveTracksFromQuery;
|
|
94
|
+
/**
|
|
95
|
+
* Resolves the first available track from a search query using the specified source.
|
|
96
|
+
* Useful for normalizing tracks that lack platform-specific metadata or URIs.
|
|
97
|
+
*
|
|
98
|
+
* @param query - The search query string (usually "Artist - Title").
|
|
99
|
+
* @param source - The search platform to use (e.g., Spotify, Deezer, YouTube).
|
|
100
|
+
* @param requester - The requester object, used for context or attribution.
|
|
101
|
+
* @returns A single resolved {@link Track} object if found, or `null` if the search fails or returns no results.
|
|
102
|
+
*/
|
|
103
|
+
private static resolveFirstTrackFromQuery;
|
|
104
|
+
private static isPlaylistRawData;
|
|
105
|
+
private static isTrackData;
|
|
106
|
+
private static isTrackDataArray;
|
|
107
|
+
static buildTracksFromResponse<T>(recommendedResult: LavalinkResponse, requester?: T): Track[];
|
|
108
|
+
}
|
|
109
|
+
export declare abstract class PlayerUtils {
|
|
110
|
+
private static manager;
|
|
111
|
+
/**
|
|
112
|
+
* Initializes the PlayerUtils class with the given manager.
|
|
113
|
+
* @param manager The manager instance to use.
|
|
114
|
+
* @hidden
|
|
115
|
+
*/
|
|
116
|
+
static init(manager: Manager): void;
|
|
117
|
+
/**
|
|
118
|
+
* Serializes a Player instance to avoid circular references.
|
|
119
|
+
* @param player The Player instance to serialize
|
|
120
|
+
* @returns The serialized Player instance
|
|
121
|
+
*/
|
|
122
|
+
static serializePlayer(player: Player): Promise<SerializedPlayerState> | null;
|
|
123
|
+
/**
|
|
124
|
+
* Gets the base directory for player data.
|
|
125
|
+
*/
|
|
126
|
+
static getPlayersBaseDir(): string;
|
|
127
|
+
/**
|
|
128
|
+
* Gets the path to the player's directory.
|
|
129
|
+
*/
|
|
130
|
+
static getGuildDir(guildId: string): string;
|
|
131
|
+
/**
|
|
132
|
+
* Gets the path to the player's state file.
|
|
133
|
+
*/
|
|
134
|
+
static getPlayerStatePath(guildId: string): string;
|
|
135
|
+
/**
|
|
136
|
+
* Gets the path to the player's current track file.
|
|
137
|
+
*/
|
|
138
|
+
static getPlayerCurrentPath(guildId: string): string;
|
|
139
|
+
/**
|
|
140
|
+
* Gets the path to the player's queue file.
|
|
141
|
+
*/
|
|
142
|
+
static getPlayerQueuePath(guildId: string): string;
|
|
143
|
+
/**
|
|
144
|
+
* Gets the path to the player's previous tracks file.
|
|
145
|
+
*/
|
|
146
|
+
static getPlayerPreviousPath(guildId: string): string;
|
|
147
|
+
/**
|
|
148
|
+
* Gets the Redis key for player storage.
|
|
149
|
+
*/
|
|
150
|
+
static getRedisKey(): string;
|
|
151
|
+
}
|
|
152
|
+
/** Gets or extends structures to extend the built in, or already extended, classes to add more functionality. */
|
|
153
|
+
export declare abstract class Structure {
|
|
154
|
+
/**
|
|
155
|
+
* Extends a class.
|
|
156
|
+
* @param name
|
|
157
|
+
* @param extender
|
|
158
|
+
*/
|
|
159
|
+
static extend<K extends keyof Extendable, T extends Extendable[K]>(name: K, extender: (target: Extendable[K]) => T): T;
|
|
160
|
+
/**
|
|
161
|
+
* Get a structure from available structures by name.
|
|
162
|
+
* @param name
|
|
163
|
+
*/
|
|
164
|
+
static get<K extends keyof Extendable>(name: K): Extendable[K];
|
|
165
|
+
}
|
|
166
|
+
export declare abstract class JSONUtils {
|
|
167
|
+
static safe<T>(obj: T, space?: number): string;
|
|
168
|
+
static serializeTrack(track: Track): string;
|
|
169
|
+
}
|
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,25 +56,30 @@ 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.
|
|
@@ -544,8 +544,7 @@ class AutoPlayUtils {
|
|
|
544
544
|
return typeof data === "object" && data !== null && "encoded" in data && "info" in data;
|
|
545
545
|
}
|
|
546
546
|
static isTrackDataArray(data) {
|
|
547
|
-
return (Array.isArray(data) &&
|
|
548
|
-
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"));
|
|
549
548
|
}
|
|
550
549
|
static buildTracksFromResponse(recommendedResult, requester) {
|
|
551
550
|
if (!recommendedResult)
|
|
@@ -624,64 +623,129 @@ class PlayerUtils {
|
|
|
624
623
|
* @returns The serialized Player instance
|
|
625
624
|
*/
|
|
626
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
|
+
};
|
|
627
653
|
try {
|
|
628
|
-
const current = await player.queue.getCurrent();
|
|
629
|
-
const
|
|
630
|
-
|
|
631
|
-
const serializeTrack = (track) => ({
|
|
632
|
-
...track,
|
|
633
|
-
requester: track.requester ? { id: track.requester.id, username: track.requester.username } : null,
|
|
634
|
-
});
|
|
635
|
-
const safeNode = player.node
|
|
636
|
-
? JSON.parse(JSON.stringify(player.node, (key, value) => {
|
|
637
|
-
if (key === "rest" || key === "players" || key === "shards" || key === "manager")
|
|
638
|
-
return undefined;
|
|
639
|
-
return value;
|
|
640
|
-
}))
|
|
641
|
-
: null;
|
|
642
|
-
return JSON.parse(JSON.stringify(player, (key, value) => {
|
|
643
|
-
if (key === "manager")
|
|
654
|
+
const [current, tracks, previous] = await Promise.all([player.queue.getCurrent(), player.queue.getTracks(), player.queue.getPrevious()]);
|
|
655
|
+
const serializeTrack = (track) => {
|
|
656
|
+
if (!track || !track.identifier)
|
|
644
657
|
return null;
|
|
645
|
-
|
|
646
|
-
return safeNode;
|
|
647
|
-
if (key === "filters") {
|
|
658
|
+
try {
|
|
648
659
|
return {
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
rotation: value?.rotation ?? null,
|
|
653
|
-
timescale: value?.timescale ?? null,
|
|
654
|
-
vibrato: value?.vibrato ?? null,
|
|
655
|
-
reverb: value?.reverb ?? null,
|
|
656
|
-
volume: value?.volume ?? 1.0,
|
|
657
|
-
bassBoostlevel: value?.bassBoostlevel ?? null,
|
|
658
|
-
filterStatus: value?.filtersStatus ? { ...value.filtersStatus } : {},
|
|
660
|
+
...track,
|
|
661
|
+
requester: track.requester ? { id: track.requester.id, username: track.requester.username } : null,
|
|
662
|
+
displayThumbnail: undefined,
|
|
659
663
|
};
|
|
660
664
|
}
|
|
661
|
-
|
|
662
|
-
return
|
|
663
|
-
current: current ? serializeTrack(current) : null,
|
|
664
|
-
tracks: tracks.map(serializeTrack),
|
|
665
|
-
previous: previous.map(serializeTrack),
|
|
666
|
-
};
|
|
665
|
+
catch {
|
|
666
|
+
return null;
|
|
667
667
|
}
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
668
|
+
};
|
|
669
|
+
const safeCurrent = current ? serializeTrack(current) : null;
|
|
670
|
+
const safeTracks = tracks.map(serializeTrack).filter((t) => t !== null);
|
|
671
|
+
const safePrevious = previous.map(serializeTrack).filter((t) => t !== null);
|
|
672
|
+
let safeNode = null;
|
|
673
|
+
if (player.node) {
|
|
674
|
+
try {
|
|
675
|
+
safeNode = JSON.parse(JSON.stringify(player.node, (key, value) => {
|
|
676
|
+
if (["rest", "players", "shards", "manager"].includes(key))
|
|
677
|
+
return undefined;
|
|
678
|
+
if (isNonSerializable(value))
|
|
679
|
+
return undefined;
|
|
680
|
+
return value;
|
|
681
|
+
}));
|
|
682
|
+
}
|
|
683
|
+
catch {
|
|
684
|
+
safeNode = null;
|
|
673
685
|
}
|
|
674
|
-
|
|
675
|
-
|
|
686
|
+
}
|
|
687
|
+
const serializableData = player.getSerializableData();
|
|
688
|
+
const nowPlayingMessage = serializableData.nowPlayingMessage;
|
|
689
|
+
delete serializableData.nowPlayingMessage;
|
|
690
|
+
const snapshot = {
|
|
691
|
+
clusterId: player.clusterId,
|
|
692
|
+
options: player.options,
|
|
693
|
+
voiceState: player.voiceState,
|
|
694
|
+
guildId: player.guildId,
|
|
695
|
+
voiceChannelId: player.voiceChannelId ?? null,
|
|
696
|
+
textChannelId: player.textChannelId ?? null,
|
|
697
|
+
volume: player.volume,
|
|
698
|
+
paused: player.paused,
|
|
699
|
+
playing: player.playing,
|
|
700
|
+
position: player.position,
|
|
701
|
+
trackRepeat: player.trackRepeat,
|
|
702
|
+
queueRepeat: player.queueRepeat,
|
|
703
|
+
dynamicRepeat: player.dynamicRepeat,
|
|
704
|
+
node: safeNode,
|
|
705
|
+
queue: {
|
|
706
|
+
current: safeCurrent,
|
|
707
|
+
tracks: safeTracks,
|
|
708
|
+
previous: safePrevious,
|
|
709
|
+
},
|
|
710
|
+
filters: player.filters
|
|
711
|
+
? {
|
|
712
|
+
distortion: player.filters.distortion ?? null,
|
|
713
|
+
equalizer: player.filters.equalizer ?? [],
|
|
714
|
+
karaoke: player.filters.karaoke ?? null,
|
|
715
|
+
rotation: player.filters.rotation ?? null,
|
|
716
|
+
timescale: player.filters.timescale ?? null,
|
|
717
|
+
vibrato: player.filters.vibrato ?? null,
|
|
718
|
+
reverb: player.filters.reverb ?? null,
|
|
719
|
+
volume: player.filters.volume ?? 1.0,
|
|
720
|
+
bassBoostlevel: player.filters.bassBoostlevel ?? null,
|
|
721
|
+
filterStatus: { ...player.filters.filtersStatus },
|
|
722
|
+
}
|
|
723
|
+
: null,
|
|
724
|
+
data: {
|
|
725
|
+
...safeSerialize(serializableData),
|
|
726
|
+
nowPlayingMessage: nowPlayingMessage
|
|
727
|
+
? {
|
|
728
|
+
id: String(nowPlayingMessage.id),
|
|
729
|
+
channelId: nowPlayingMessage.channelId,
|
|
730
|
+
guildId: nowPlayingMessage.guildId,
|
|
731
|
+
}
|
|
732
|
+
: null,
|
|
733
|
+
},
|
|
734
|
+
};
|
|
735
|
+
// Sanity check
|
|
736
|
+
JSON.stringify(snapshot);
|
|
737
|
+
return snapshot;
|
|
676
738
|
}
|
|
677
739
|
catch (err) {
|
|
678
|
-
|
|
740
|
+
const error = err instanceof MagmastreamError_1.MagmaStreamError
|
|
679
741
|
? err
|
|
680
742
|
: new MagmastreamError_1.MagmaStreamError({
|
|
681
|
-
code: Enums_1.MagmaStreamErrorCode.
|
|
682
|
-
message: `An error occurred while
|
|
743
|
+
code: Enums_1.MagmaStreamErrorCode.UTILS_PLAYER_SERIALIZE_FAILED,
|
|
744
|
+
message: `An error occurred while serializing player: ${err instanceof Error ? err.message : String(err)}`,
|
|
683
745
|
cause: err instanceof Error ? err : undefined,
|
|
684
746
|
});
|
|
747
|
+
console.error(error);
|
|
748
|
+
return null;
|
|
685
749
|
}
|
|
686
750
|
}
|
|
687
751
|
/**
|
|
@@ -720,6 +784,16 @@ class PlayerUtils {
|
|
|
720
784
|
static getPlayerPreviousPath(guildId) {
|
|
721
785
|
return path_1.default.join(this.getGuildDir(guildId), "previous.json");
|
|
722
786
|
}
|
|
787
|
+
/**
|
|
788
|
+
* Gets the Redis key for player storage.
|
|
789
|
+
*/
|
|
790
|
+
static getRedisKey() {
|
|
791
|
+
const cfg = this.manager.options.stateStorage.redisConfig;
|
|
792
|
+
// Default prefix
|
|
793
|
+
let prefix = (cfg.prefix ?? "magmastream:").trim();
|
|
794
|
+
prefix = prefix.replace(/:+$/g, "") + ":";
|
|
795
|
+
return prefix;
|
|
796
|
+
}
|
|
723
797
|
}
|
|
724
798
|
exports.PlayerUtils = PlayerUtils;
|
|
725
799
|
/** Gets or extends structures to extend the built in, or already extended, classes to add more functionality. */
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Represents an equalizer band. */
|
|
2
|
+
export interface Band {
|
|
3
|
+
/** The index of the equalizer band (0-12). */
|
|
4
|
+
band: number;
|
|
5
|
+
/** The gain value of the equalizer band (in decibels). */
|
|
6
|
+
gain: number;
|
|
7
|
+
}
|
|
8
|
+
export declare const bassBoostEqualizer: Band[];
|
|
9
|
+
export declare const softEqualizer: Band[];
|
|
10
|
+
export declare const tvEqualizer: Band[];
|
|
11
|
+
export declare const trebleBassEqualizer: Band[];
|
|
12
|
+
export declare const vaporwaveEqualizer: Band[];
|
|
13
|
+
export declare const popEqualizer: Band[];
|
|
14
|
+
export declare const electronicEqualizer: Band[];
|
|
15
|
+
export declare const radioEqualizer: Band[];
|
|
16
|
+
export declare const demonEqualizer: Band[];
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ManagerOptions } from "../structures/Types";
|
|
2
|
+
/**
|
|
3
|
+
* Validates the provided ManagerOptions object.
|
|
4
|
+
* @param options - The options to validate.
|
|
5
|
+
* @throws {MagmaStreamError} Throws if any required option is missing or invalid.
|
|
6
|
+
*/
|
|
7
|
+
export default function managerCheck(options: ManagerOptions): void;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { NodeOptions } from "../structures/Types";
|
|
2
|
+
/**
|
|
3
|
+
* Validates the provided NodeOptions object.
|
|
4
|
+
* @param options - The options to validate.
|
|
5
|
+
* @throws {MagmaStreamError} Throws if any required option is missing or invalid.
|
|
6
|
+
*/
|
|
7
|
+
export default function nodeCheck(options: NodeOptions): void;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { PlayerOptions } from "../structures/Types";
|
|
2
|
+
/**
|
|
3
|
+
* Validates the provided PlayerOptions object.
|
|
4
|
+
* @param options - The options to validate.
|
|
5
|
+
* @throws {MagmaStreamError} Throws if any required option is missing or invalid.
|
|
6
|
+
*/
|
|
7
|
+
export default function playerCheck(options: PlayerOptions): void;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Manager as BaseManager } from "../structures/Manager";
|
|
2
|
+
import type { GatewayVoiceStateUpdate } from "discord-api-types/v10";
|
|
3
|
+
import { Client, Guild, User } from "discord.js";
|
|
4
|
+
import { AnyUser, ManagerOptions } from "../structures/Types";
|
|
5
|
+
export * from "../index";
|
|
6
|
+
/**
|
|
7
|
+
* Discord.js wrapper for Magmastream.
|
|
8
|
+
*/
|
|
9
|
+
export declare class DiscordJSManager extends BaseManager {
|
|
10
|
+
readonly client: Client;
|
|
11
|
+
constructor(client: Client, options?: ManagerOptions);
|
|
12
|
+
protected send(packet: GatewayVoiceStateUpdate): void;
|
|
13
|
+
resolveUser(user: AnyUser | string): Promise<User | AnyUser>;
|
|
14
|
+
resolveGuild(guildId: string): Guild | null;
|
|
15
|
+
}
|
|
@@ -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;
|
|
@@ -51,5 +60,11 @@ class DiscordJSManager extends Manager_1.Manager {
|
|
|
51
60
|
return { id, username: typeof user === "string" ? undefined : user.username };
|
|
52
61
|
}
|
|
53
62
|
}
|
|
63
|
+
resolveGuild(guildId) {
|
|
64
|
+
const cached = this.client.guilds.cache.get(guildId);
|
|
65
|
+
if (cached)
|
|
66
|
+
return cached;
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
54
69
|
}
|
|
55
70
|
exports.DiscordJSManager = DiscordJSManager;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { GatewayVoiceStateUpdate } from "discord-api-types/v10";
|
|
2
|
+
import { Manager as BaseManager } from "../structures/Manager";
|
|
3
|
+
import { Bot, User } from "@discordeno/bot";
|
|
4
|
+
import { AnyGuild, AnyUser, ManagerOptions } from "../structures/Types";
|
|
5
|
+
export * from "../index";
|
|
6
|
+
/**
|
|
7
|
+
* Discordeno wrapper for Magmastream.
|
|
8
|
+
*/
|
|
9
|
+
export declare class DiscordenoManager extends BaseManager {
|
|
10
|
+
readonly client: Bot;
|
|
11
|
+
constructor(client: Bot, options?: ManagerOptions);
|
|
12
|
+
protected send(packet: GatewayVoiceStateUpdate): void;
|
|
13
|
+
/**
|
|
14
|
+
* Resolve a user by ID or partial info.
|
|
15
|
+
* Uses user-provided cache getter if available, otherwise falls back to minimal info.
|
|
16
|
+
*/
|
|
17
|
+
resolveUser(user: AnyUser | string): Promise<User | AnyUser>;
|
|
18
|
+
resolveGuild(guildId: string): AnyGuild;
|
|
19
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
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
|
+
resolveGuild(guildId) {
|
|
73
|
+
// Try user-provided cache getter
|
|
74
|
+
return this.getGuildFromCache(guildId);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
exports.DiscordenoManager = DiscordenoManager;
|