magmastream 2.9.3-dev.20 → 2.9.3-dev.22
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 +32 -13
- package/dist/structures/Manager.js +27 -106
- package/dist/structures/Node.js +2 -4
- package/dist/structures/Player.js +1 -1
- package/dist/structures/Utils.js +2 -3
- package/dist/wrappers/discord.js.js +6 -0
- package/dist/wrappers/eris.js +6 -0
- package/dist/wrappers/oceanic.js +6 -0
- package/dist/wrappers/seyfert.js +6 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Collection } from '@discordjs/collection';
|
|
2
2
|
import { GatewayVoiceStateUpdate } from 'discord-api-types/v10';
|
|
3
3
|
import { EventEmitter } from 'events';
|
|
4
|
-
import { User, ClientUser, Message, Client } from 'discord.js';
|
|
5
|
-
import { User as User$1, Message as Message$1, Client as Client$2 } from 'oceanic.js';
|
|
6
|
-
import { User as User$2, Message as Message$2, Bot } from '@discordeno/bot';
|
|
7
|
-
import { User as User$3, Message as Message$3, Client as Client$1 } from 'eris';
|
|
8
|
-
import { User as User$4, ClientUser as ClientUser$1, Message as Message$4, Client as Client$3, WorkerClient } from 'seyfert';
|
|
4
|
+
import { User, ClientUser, Guild, Message, Client } from 'discord.js';
|
|
5
|
+
import { User as User$1, Guild as Guild$1, Message as Message$1, Client as Client$2 } from 'oceanic.js';
|
|
6
|
+
import { User as User$2, Guild as Guild$2, Message as Message$2, Bot } from '@discordeno/bot';
|
|
7
|
+
import { User as User$3, Guild as Guild$3, Message as Message$3, Client as Client$1 } from 'eris';
|
|
8
|
+
import { User as User$4, ClientUser as ClientUser$1, Guild as Guild$4, Message as Message$4, Client as Client$3, WorkerClient } from 'seyfert';
|
|
9
9
|
import WebSocket$1, { WebSocket } from 'ws';
|
|
10
10
|
import { Redis } from 'ioredis';
|
|
11
11
|
|
|
@@ -859,7 +859,7 @@ declare abstract class Plugin {
|
|
|
859
859
|
interface ManagerOptions {
|
|
860
860
|
/** The state storage options.
|
|
861
861
|
*
|
|
862
|
-
* @default { type: StateStorageType.Collection,
|
|
862
|
+
* @default { type: StateStorageType.Collection, deleteDestroyedPlayers: true }
|
|
863
863
|
*/
|
|
864
864
|
stateStorage?: StateStorageOptions;
|
|
865
865
|
/** Enable priority mode over least player count or load balancing?
|
|
@@ -925,8 +925,18 @@ interface ManagerOptions {
|
|
|
925
925
|
* Optional user cache getter.
|
|
926
926
|
* When resolving a user from a partial ID, this function will be called first.
|
|
927
927
|
* Should return the full user object if cached, or undefined if not.
|
|
928
|
+
* @param id The ID of the user to get.
|
|
929
|
+
* @returns The user object if cached, or undefined if not.
|
|
928
930
|
*/
|
|
929
931
|
getUser?: (id: string) => AnyUser | undefined;
|
|
932
|
+
/**
|
|
933
|
+
* Optional guild cache getter.
|
|
934
|
+
* When resolving a guild from a partial ID, this function will be called first.
|
|
935
|
+
* Should return the full guild object if cached, or undefined if not.
|
|
936
|
+
* @param id The ID of the guild to get.
|
|
937
|
+
* @returns The guild object if cached, or undefined if not.
|
|
938
|
+
*/
|
|
939
|
+
getGuild?: (id: string) => AnyGuild | undefined;
|
|
930
940
|
}
|
|
931
941
|
/**
|
|
932
942
|
* State Storage Options
|
|
@@ -935,7 +945,7 @@ interface StateStorageOptions {
|
|
|
935
945
|
type: StateStorageType;
|
|
936
946
|
redisConfig?: RedisConfig;
|
|
937
947
|
jsonConfig?: JsonConfig;
|
|
938
|
-
|
|
948
|
+
deleteDestroyedPlayers?: boolean;
|
|
939
949
|
}
|
|
940
950
|
/**
|
|
941
951
|
* Node Options
|
|
@@ -1013,6 +1023,10 @@ interface PortableMessage {
|
|
|
1013
1023
|
* Any message
|
|
1014
1024
|
*/
|
|
1015
1025
|
type AnyMessage = PortableMessage | Message | Message$1 | Message$2 | Message$3 | Message$4;
|
|
1026
|
+
/**
|
|
1027
|
+
* Any guild
|
|
1028
|
+
*/
|
|
1029
|
+
type AnyGuild = Guild | Guild$1 | Guild$2 | Guild$3 | Guild$4<"cached">;
|
|
1016
1030
|
/**
|
|
1017
1031
|
* Discord Packet
|
|
1018
1032
|
*/
|
|
@@ -2913,6 +2927,7 @@ declare class Manager extends EventEmitter {
|
|
|
2913
2927
|
redis?: Redis;
|
|
2914
2928
|
private _send;
|
|
2915
2929
|
private _getUser?;
|
|
2930
|
+
private _getGuild?;
|
|
2916
2931
|
private loadedPlugins;
|
|
2917
2932
|
/**
|
|
2918
2933
|
* Initiates the Manager class.
|
|
@@ -3086,11 +3101,6 @@ declare class Manager extends EventEmitter {
|
|
|
3086
3101
|
* @emits {playerDisconnect} - Emits a player disconnect event if the channel ID is null.
|
|
3087
3102
|
*/
|
|
3088
3103
|
private handleVoiceStateUpdate;
|
|
3089
|
-
/**
|
|
3090
|
-
* Cleans up inactive players by removing their state files from the file system.
|
|
3091
|
-
* This is done to prevent stale state files from accumulating on the file system.
|
|
3092
|
-
*/
|
|
3093
|
-
cleanupInactivePlayers(): Promise<void>;
|
|
3094
3104
|
/**
|
|
3095
3105
|
* Cleans up an inactive player by removing its state data.
|
|
3096
3106
|
* This is done to prevent stale state data from accumulating.
|
|
@@ -3142,6 +3152,11 @@ declare class Manager extends EventEmitter {
|
|
|
3142
3152
|
* Can be overridden by wrapper managers to return wrapper-specific User classes.
|
|
3143
3153
|
*/
|
|
3144
3154
|
resolveUser(user: AnyUser | string): Promise<AnyUser>;
|
|
3155
|
+
/**
|
|
3156
|
+
* Resolves a Guild ID to a real guild object.
|
|
3157
|
+
* Can be overridden by wrapper managers to return wrapper-specific Guild classes.
|
|
3158
|
+
*/
|
|
3159
|
+
resolveGuild(guildId: string): AnyGuild;
|
|
3145
3160
|
}
|
|
3146
3161
|
|
|
3147
3162
|
declare class Filters {
|
|
@@ -3693,6 +3708,7 @@ declare class DiscordJSManager extends Manager {
|
|
|
3693
3708
|
constructor(client: Client, options?: ManagerOptions);
|
|
3694
3709
|
protected send(packet: GatewayVoiceStateUpdate): void;
|
|
3695
3710
|
resolveUser(user: AnyUser | string): Promise<User | AnyUser>;
|
|
3711
|
+
resolveGuild(guildId: string): Guild | null;
|
|
3696
3712
|
}
|
|
3697
3713
|
|
|
3698
3714
|
/**
|
|
@@ -3703,6 +3719,7 @@ declare class ErisManager extends Manager {
|
|
|
3703
3719
|
constructor(client: Client$1, options?: ManagerOptions);
|
|
3704
3720
|
protected send(packet: GatewayVoiceStateUpdate): void;
|
|
3705
3721
|
resolveUser(user: AnyUser | string): Promise<User$3 | AnyUser>;
|
|
3722
|
+
resolveGuild(guildId: string): Guild$3;
|
|
3706
3723
|
}
|
|
3707
3724
|
|
|
3708
3725
|
/**
|
|
@@ -3713,6 +3730,7 @@ declare class OceanicManager extends Manager {
|
|
|
3713
3730
|
constructor(client: Client$2, options?: ManagerOptions);
|
|
3714
3731
|
protected send(packet: GatewayVoiceStateUpdate): void;
|
|
3715
3732
|
resolveUser(user: AnyUser | string): Promise<User$1 | AnyUser>;
|
|
3733
|
+
resolveGuild(guildId: string): Guild$1;
|
|
3716
3734
|
}
|
|
3717
3735
|
|
|
3718
3736
|
/**
|
|
@@ -3745,7 +3763,8 @@ declare class SeyfertManager extends Manager {
|
|
|
3745
3763
|
constructor(client: Client$3 | WorkerClient, options?: ManagerOptions);
|
|
3746
3764
|
protected send(packet: GatewayVoiceStateUpdate): void;
|
|
3747
3765
|
resolveUser(user: AnyUser | string): Promise<User$4 | AnyUser>;
|
|
3766
|
+
resolveGuild(guildId: string): Guild$4<"cached">;
|
|
3748
3767
|
}
|
|
3749
3768
|
|
|
3750
3769
|
export { AutoPlayPlatform, AutoPlayUtils, AvailableFilters, DiscordJSManager, DiscordenoManager, ErisManager, Filters, JSONUtils, JsonQueue, LoadTypes, MagmaStreamError, MagmaStreamErrorCode, MagmaStreamErrorNumbers, Manager, ManagerEventTypes, MemoryQueue, Node, OceanicManager, Player, PlayerStateEventTypes, PlayerUtils, Plugin, RedisQueue, Rest, SearchPlatform, SeverityTypes, SeyfertManager, SponsorBlockSegment, StateStorageType, StateTypes, Structure, TrackEndReasonTypes, TrackPartial, TrackSourceTypes, TrackUtils, UseNodeOptions };
|
|
3751
|
-
export type { AlbumSearchResult, AnyMessage, AnyUser, ArtistSearchResult, CPUStats, DiscordPacket, DistortionOptions, EndSpeakingEventVoiceReceiver, EndSpeakingEventVoiceReceiverData, EqualizerBand, ErrorOrEmptySearchResult, Exception, Extendable, FrameStats, IQueue, JsonConfig, KaraokeOptions, LavaPlayer, LavalinkInfo, LavalinkResponse, LavalinkVoiceStateResponse, LavalinkVoiceStateUpdate, LoadType, Lyrics, LyricsEvent, LyricsEventType, LyricsFoundEvent, LyricsLine, LyricsLineEvent, LyricsNotFoundEvent, ManagerEvents, ManagerInitOptions, ManagerOptions, MemoryStats, NodeLinkGetLyrics, NodeLinkGetLyricsEmpty, NodeLinkGetLyricsError, NodeLinkGetLyricsMultiple, NodeLinkGetLyricsSingle, NodeMessage, NodeOptions, NodeStats, PlayOptions, PlayerEvent, PlayerEventType, PlayerEvents, PlayerOptions, PlayerStateUpdateEvent, PlayerUpdateVoiceState, PlaylistData, PlaylistInfoData, PlaylistRawData, PlaylistSearchResult, PodcastSearchResult, PortableMessage, PortableUser, RedisConfig, RestPlayOptions, ReverbOptions, RotationOptions, SearchQuery, SearchResult, SearchSearchResult, Severity, ShortSearchResult, ShowSearchResult, Sizes, SponsorBlockChapterStarted, SponsorBlockChaptersLoaded, SponsorBlockSegmentEventType, SponsorBlockSegmentEvents, SponsorBlockSegmentSkipped, SponsorBlockSegmentsLoaded, StartSpeakingEventVoiceReceiver, StartSpeakingEventVoiceReceiverData, StateStorageOptions, StationSearchResult, TimescaleOptions, Track, TrackData, TrackDataInfo, TrackEndEvent, TrackEndReason, TrackExceptionEvent, TrackPluginInfo, TrackSearchResult, TrackSourceName, TrackStartEvent, TrackStuckEvent, UseNodeOption, VibratoOptions, VoicePacket, VoiceReceiverEvent, VoiceServer, VoiceServerUpdate, VoiceState, WebSocketClosedEvent };
|
|
3770
|
+
export type { AlbumSearchResult, AnyGuild, AnyMessage, AnyUser, ArtistSearchResult, CPUStats, DiscordPacket, DistortionOptions, EndSpeakingEventVoiceReceiver, EndSpeakingEventVoiceReceiverData, EqualizerBand, ErrorOrEmptySearchResult, Exception, Extendable, FrameStats, IQueue, JsonConfig, KaraokeOptions, LavaPlayer, LavalinkInfo, LavalinkResponse, LavalinkVoiceStateResponse, LavalinkVoiceStateUpdate, LoadType, Lyrics, LyricsEvent, LyricsEventType, LyricsFoundEvent, LyricsLine, LyricsLineEvent, LyricsNotFoundEvent, ManagerEvents, ManagerInitOptions, ManagerOptions, MemoryStats, NodeLinkGetLyrics, NodeLinkGetLyricsEmpty, NodeLinkGetLyricsError, NodeLinkGetLyricsMultiple, NodeLinkGetLyricsSingle, NodeMessage, NodeOptions, NodeStats, PlayOptions, PlayerEvent, PlayerEventType, PlayerEvents, PlayerOptions, PlayerStateUpdateEvent, PlayerUpdateVoiceState, PlaylistData, PlaylistInfoData, PlaylistRawData, PlaylistSearchResult, PodcastSearchResult, PortableMessage, PortableUser, RedisConfig, RestPlayOptions, ReverbOptions, RotationOptions, SearchQuery, SearchResult, SearchSearchResult, Severity, ShortSearchResult, ShowSearchResult, Sizes, SponsorBlockChapterStarted, SponsorBlockChaptersLoaded, SponsorBlockSegmentEventType, SponsorBlockSegmentEvents, SponsorBlockSegmentSkipped, SponsorBlockSegmentsLoaded, StartSpeakingEventVoiceReceiver, StartSpeakingEventVoiceReceiverData, StateStorageOptions, StationSearchResult, TimescaleOptions, Track, TrackData, TrackDataInfo, TrackEndEvent, TrackEndReason, TrackExceptionEvent, TrackPluginInfo, TrackSearchResult, TrackSourceName, TrackStartEvent, TrackStuckEvent, UseNodeOption, VibratoOptions, VoicePacket, VoiceReceiverEvent, VoiceServer, VoiceServerUpdate, VoiceState, WebSocketClosedEvent };
|
|
@@ -29,6 +29,7 @@ class Manager extends events_1.EventEmitter {
|
|
|
29
29
|
redis;
|
|
30
30
|
_send;
|
|
31
31
|
_getUser;
|
|
32
|
+
_getGuild;
|
|
32
33
|
loadedPlugins = new Set();
|
|
33
34
|
/**
|
|
34
35
|
* Initiates the Manager class.
|
|
@@ -64,6 +65,8 @@ class Manager extends events_1.EventEmitter {
|
|
|
64
65
|
this._send = options.send;
|
|
65
66
|
if (options.getUser && !this._getUser)
|
|
66
67
|
this._getUser = options.getUser;
|
|
68
|
+
if (options.getGuild && !this._getGuild)
|
|
69
|
+
this._getGuild = options.getGuild;
|
|
67
70
|
this.options = {
|
|
68
71
|
...options,
|
|
69
72
|
enabledPlugins: options.enabledPlugins ?? [],
|
|
@@ -89,7 +92,7 @@ class Manager extends events_1.EventEmitter {
|
|
|
89
92
|
stateStorage: {
|
|
90
93
|
...options.stateStorage,
|
|
91
94
|
type: options.stateStorage?.type ?? Enums_1.StateStorageType.Memory,
|
|
92
|
-
|
|
95
|
+
deleteDestroyedPlayers: options.stateStorage?.deleteDestroyedPlayers ?? true,
|
|
93
96
|
},
|
|
94
97
|
autoPlaySearchPlatforms: options.autoPlaySearchPlatforms ?? [Enums_1.AutoPlayPlatform.YouTube],
|
|
95
98
|
send: this._send,
|
|
@@ -533,10 +536,11 @@ class Manager extends events_1.EventEmitter {
|
|
|
533
536
|
await promises_1.default.access(stateFilePath);
|
|
534
537
|
const rawData = await promises_1.default.readFile(stateFilePath, "utf-8");
|
|
535
538
|
const state = JSON.parse(rawData);
|
|
536
|
-
if (state.clusterId !== this.options.clusterId)
|
|
537
|
-
continue;
|
|
538
539
|
if (!state.guildId || state.node?.options?.identifier !== nodeId)
|
|
539
540
|
continue;
|
|
541
|
+
const hasGuild = this.resolveGuild(state.guildId);
|
|
542
|
+
if (!hasGuild)
|
|
543
|
+
continue;
|
|
540
544
|
const lavaPlayer = await node.rest.getPlayer(state.guildId);
|
|
541
545
|
if (!lavaPlayer) {
|
|
542
546
|
await this.destroy(state.guildId);
|
|
@@ -686,31 +690,18 @@ class Manager extends events_1.EventEmitter {
|
|
|
686
690
|
filterActions[filter](true);
|
|
687
691
|
}
|
|
688
692
|
}
|
|
689
|
-
|
|
690
|
-
await this.sleep(1000);
|
|
691
|
-
}
|
|
692
|
-
catch (error) {
|
|
693
|
-
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Error processing player state for guild ${guildId}: ${error}`);
|
|
694
|
-
continue;
|
|
695
|
-
}
|
|
696
|
-
}
|
|
697
|
-
// Cleanup old player state files from guild directories whose nodeId matches
|
|
698
|
-
for (const dirent of guildDirs) {
|
|
699
|
-
if (!dirent.isDirectory())
|
|
700
|
-
continue;
|
|
701
|
-
const guildId = dirent.name;
|
|
702
|
-
const stateFilePath = Utils_1.PlayerUtils.getPlayerStatePath(guildId);
|
|
703
|
-
try {
|
|
704
|
-
await promises_1.default.access(stateFilePath);
|
|
705
|
-
const data = await promises_1.default.readFile(stateFilePath, "utf-8");
|
|
706
|
-
const state = JSON.parse(data);
|
|
707
|
-
if (state && typeof state === "object" && state.node?.options?.identifier === nodeId) {
|
|
693
|
+
try {
|
|
708
694
|
await promises_1.default.rm(Utils_1.PlayerUtils.getPlayerStatePath(guildId), { force: true });
|
|
709
695
|
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Deleted player state folder for guild ${guildId}`);
|
|
710
696
|
}
|
|
697
|
+
catch (error) {
|
|
698
|
+
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Error deleting player state for guild ${guildId}: ${error}`);
|
|
699
|
+
}
|
|
700
|
+
this.emit(Enums_1.ManagerEventTypes.PlayerRestored, player, node);
|
|
701
|
+
await this.sleep(1000);
|
|
711
702
|
}
|
|
712
703
|
catch (error) {
|
|
713
|
-
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Error
|
|
704
|
+
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Error processing player state for guild ${guildId}: ${error}`);
|
|
714
705
|
continue;
|
|
715
706
|
}
|
|
716
707
|
}
|
|
@@ -732,11 +723,14 @@ class Manager extends events_1.EventEmitter {
|
|
|
732
723
|
if (!data)
|
|
733
724
|
continue;
|
|
734
725
|
const state = JSON.parse(data);
|
|
735
|
-
if (!state || typeof state !== "object"
|
|
726
|
+
if (!state || typeof state !== "object")
|
|
736
727
|
continue;
|
|
737
728
|
const guildId = key.split(":").pop();
|
|
738
729
|
if (!guildId || state.node.options.identifier !== nodeId)
|
|
739
730
|
continue;
|
|
731
|
+
const hasGuild = this.resolveGuild(guildId);
|
|
732
|
+
if (!hasGuild)
|
|
733
|
+
continue;
|
|
740
734
|
const lavaPlayer = await node.rest.getPlayer(state.guildId);
|
|
741
735
|
if (!lavaPlayer) {
|
|
742
736
|
await this.destroy(guildId);
|
|
@@ -955,8 +949,6 @@ class Manager extends events_1.EventEmitter {
|
|
|
955
949
|
}
|
|
956
950
|
});
|
|
957
951
|
await Promise.allSettled(savePromises);
|
|
958
|
-
if (this.options.stateStorage.deleteInactivePlayers)
|
|
959
|
-
await this.cleanupInactivePlayers();
|
|
960
952
|
setTimeout(() => {
|
|
961
953
|
console.warn("\x1b[32m%s\x1b[0m", "MAGMASTREAM INFO: Shutting down complete, exiting...");
|
|
962
954
|
process.exit(0);
|
|
@@ -1130,86 +1122,6 @@ class Manager extends events_1.EventEmitter {
|
|
|
1130
1122
|
data: { voice: { token, endpoint, sessionId: update.session_id, channelId: update.channel_id } },
|
|
1131
1123
|
});
|
|
1132
1124
|
}
|
|
1133
|
-
/**
|
|
1134
|
-
* Cleans up inactive players by removing their state files from the file system.
|
|
1135
|
-
* This is done to prevent stale state files from accumulating on the file system.
|
|
1136
|
-
*/
|
|
1137
|
-
async cleanupInactivePlayers() {
|
|
1138
|
-
switch (this.options.stateStorage.type) {
|
|
1139
|
-
case Enums_1.StateStorageType.JSON:
|
|
1140
|
-
{
|
|
1141
|
-
const playersBaseDir = Utils_1.PlayerUtils.getPlayersBaseDir();
|
|
1142
|
-
try {
|
|
1143
|
-
await promises_1.default.mkdir(playersBaseDir, { recursive: true });
|
|
1144
|
-
const activeGuildIds = new Set(this.players.keys());
|
|
1145
|
-
// Cleanup inactive guild directories inside playersBaseDir
|
|
1146
|
-
const guildDirs = await promises_1.default.readdir(playersBaseDir, { withFileTypes: true });
|
|
1147
|
-
for (const dirent of guildDirs) {
|
|
1148
|
-
if (!dirent.isDirectory())
|
|
1149
|
-
continue;
|
|
1150
|
-
const guildId = dirent.name;
|
|
1151
|
-
if (!activeGuildIds.has(guildId)) {
|
|
1152
|
-
const guildPath = Utils_1.PlayerUtils.getGuildDir(guildId);
|
|
1153
|
-
await promises_1.default.rm(guildPath, { recursive: true, force: true });
|
|
1154
|
-
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Deleted inactive player data folder: ${guildId}`);
|
|
1155
|
-
}
|
|
1156
|
-
}
|
|
1157
|
-
}
|
|
1158
|
-
catch (err) {
|
|
1159
|
-
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Error cleaning up inactive JSON players: ${err}`);
|
|
1160
|
-
const error = err instanceof MagmastreamError_1.MagmaStreamError
|
|
1161
|
-
? err
|
|
1162
|
-
: new MagmastreamError_1.MagmaStreamError({
|
|
1163
|
-
code: Enums_1.MagmaStreamErrorCode.MANAGER_CLEANUP_INACTIVE_PLAYERS_FAILED,
|
|
1164
|
-
message: "Error cleaning up inactive players.",
|
|
1165
|
-
cause: err,
|
|
1166
|
-
context: { stage: "CLEANUP_INACTIVE_PLAYERS" },
|
|
1167
|
-
});
|
|
1168
|
-
console.error(error);
|
|
1169
|
-
}
|
|
1170
|
-
}
|
|
1171
|
-
break;
|
|
1172
|
-
case Enums_1.StateStorageType.Redis:
|
|
1173
|
-
{
|
|
1174
|
-
const prefix = Utils_1.PlayerUtils.getRedisKey();
|
|
1175
|
-
const pattern = `${prefix}queue:*:current`;
|
|
1176
|
-
try {
|
|
1177
|
-
const stream = this.redis.scanStream({
|
|
1178
|
-
match: pattern,
|
|
1179
|
-
count: 100,
|
|
1180
|
-
});
|
|
1181
|
-
for await (const keys of stream) {
|
|
1182
|
-
for (const key of keys) {
|
|
1183
|
-
// Extract guildId from queue key
|
|
1184
|
-
const match = key.match(new RegExp(`^${prefix}queue:(.+):current$`));
|
|
1185
|
-
if (!match)
|
|
1186
|
-
continue;
|
|
1187
|
-
const guildId = match[1];
|
|
1188
|
-
// If player is not active in memory, clean up all keys
|
|
1189
|
-
if (!this.players.has(guildId)) {
|
|
1190
|
-
await this.redis.del(`${prefix}playerstore:${guildId}`, `${prefix}queue:${guildId}:current`, `${prefix}queue:${guildId}:tracks`, `${prefix}queue:${guildId}:previous`);
|
|
1191
|
-
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Cleaned inactive Redis player data: ${guildId}`);
|
|
1192
|
-
}
|
|
1193
|
-
}
|
|
1194
|
-
}
|
|
1195
|
-
}
|
|
1196
|
-
catch (err) {
|
|
1197
|
-
const error = err instanceof MagmastreamError_1.MagmaStreamError
|
|
1198
|
-
? err
|
|
1199
|
-
: new MagmastreamError_1.MagmaStreamError({
|
|
1200
|
-
code: Enums_1.MagmaStreamErrorCode.MANAGER_SHUTDOWN_FAILED,
|
|
1201
|
-
message: "Error saving player state.",
|
|
1202
|
-
cause: err,
|
|
1203
|
-
context: { stage: "CLEANUP_INACTIVE_PLAYERS" },
|
|
1204
|
-
});
|
|
1205
|
-
console.error(error);
|
|
1206
|
-
}
|
|
1207
|
-
}
|
|
1208
|
-
break;
|
|
1209
|
-
default:
|
|
1210
|
-
break;
|
|
1211
|
-
}
|
|
1212
|
-
}
|
|
1213
1125
|
/**
|
|
1214
1126
|
* Cleans up an inactive player by removing its state data.
|
|
1215
1127
|
* This is done to prevent stale state data from accumulating.
|
|
@@ -1468,5 +1380,14 @@ class Manager extends events_1.EventEmitter {
|
|
|
1468
1380
|
return { id: user }; // fallback by ID only
|
|
1469
1381
|
return user; // default: just return the portable user
|
|
1470
1382
|
}
|
|
1383
|
+
/**
|
|
1384
|
+
* Resolves a Guild ID to a real guild object.
|
|
1385
|
+
* Can be overridden by wrapper managers to return wrapper-specific Guild classes.
|
|
1386
|
+
*/
|
|
1387
|
+
resolveGuild(guildId) {
|
|
1388
|
+
if (!guildId)
|
|
1389
|
+
return null;
|
|
1390
|
+
return this._getGuild?.(guildId);
|
|
1391
|
+
}
|
|
1471
1392
|
}
|
|
1472
1393
|
exports.Manager = Manager;
|
package/dist/structures/Node.js
CHANGED
|
@@ -99,9 +99,7 @@ class Node {
|
|
|
99
99
|
this.createReadmeFile();
|
|
100
100
|
break;
|
|
101
101
|
case Enums_1.StateStorageType.Redis:
|
|
102
|
-
this.redisPrefix =
|
|
103
|
-
? this.manager.options.stateStorage.redisConfig.prefix
|
|
104
|
-
: (this.manager.options.stateStorage.redisConfig.prefix ?? "magmastream:");
|
|
102
|
+
this.redisPrefix = Utils_1.PlayerUtils.getRedisKey();
|
|
105
103
|
break;
|
|
106
104
|
}
|
|
107
105
|
}
|
|
@@ -125,7 +123,7 @@ class Node {
|
|
|
125
123
|
return `${this.redisPrefix}node:sessionIds`;
|
|
126
124
|
}
|
|
127
125
|
getNodeSessionsDir() {
|
|
128
|
-
return path_1.default.join(process.cwd(), "magmastream", "sessionData", "
|
|
126
|
+
return path_1.default.join(process.cwd(), "magmastream", "sessionData", "nodeSessions");
|
|
129
127
|
}
|
|
130
128
|
getNodeSessionPath() {
|
|
131
129
|
const safeId = String(this.options.identifier).replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
@@ -281,7 +281,7 @@ class Player {
|
|
|
281
281
|
this.nowPlayingMessage = undefined;
|
|
282
282
|
this.manager.emit(Enums_1.ManagerEventTypes.PlayerDestroy, this);
|
|
283
283
|
const deleted = this.manager.players.delete(this.guildId);
|
|
284
|
-
if (this.manager.options.stateStorage.
|
|
284
|
+
if (this.manager.options.stateStorage.deleteDestroyedPlayers) {
|
|
285
285
|
await this.manager.cleanupInactivePlayer(this.guildId);
|
|
286
286
|
}
|
|
287
287
|
return deleted;
|
package/dist/structures/Utils.js
CHANGED
|
@@ -737,7 +737,7 @@ class PlayerUtils {
|
|
|
737
737
|
* Gets the base directory for player data.
|
|
738
738
|
*/
|
|
739
739
|
static getPlayersBaseDir() {
|
|
740
|
-
return path_1.default.join(process.cwd(), "magmastream", "sessionData", "
|
|
740
|
+
return path_1.default.join(process.cwd(), "magmastream", "sessionData", "players");
|
|
741
741
|
}
|
|
742
742
|
/**
|
|
743
743
|
* Gets the path to the player's directory.
|
|
@@ -777,8 +777,7 @@ class PlayerUtils {
|
|
|
777
777
|
// Default prefix
|
|
778
778
|
let prefix = (cfg.prefix ?? "magmastream:").trim();
|
|
779
779
|
prefix = prefix.replace(/:+$/g, "") + ":";
|
|
780
|
-
|
|
781
|
-
return `${prefix}cluster:${clusterId}:`;
|
|
780
|
+
return prefix;
|
|
782
781
|
}
|
|
783
782
|
}
|
|
784
783
|
exports.PlayerUtils = PlayerUtils;
|
|
@@ -60,5 +60,11 @@ class DiscordJSManager extends Manager_1.Manager {
|
|
|
60
60
|
return { id, username: typeof user === "string" ? undefined : user.username };
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
|
+
resolveGuild(guildId) {
|
|
64
|
+
const cached = this.client.guilds.cache.get(guildId);
|
|
65
|
+
if (cached)
|
|
66
|
+
return cached;
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
63
69
|
}
|
|
64
70
|
exports.DiscordJSManager = DiscordJSManager;
|
package/dist/wrappers/eris.js
CHANGED
|
@@ -46,5 +46,11 @@ class ErisManager extends Manager_1.Manager {
|
|
|
46
46
|
username: typeof user === "string" ? undefined : user.username,
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
|
+
resolveGuild(guildId) {
|
|
50
|
+
const cached = this.client.guilds.get(guildId);
|
|
51
|
+
if (cached)
|
|
52
|
+
return cached;
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
49
55
|
}
|
|
50
56
|
exports.ErisManager = ErisManager;
|
package/dist/wrappers/oceanic.js
CHANGED
|
@@ -47,5 +47,11 @@ class OceanicManager extends Manager_1.Manager {
|
|
|
47
47
|
username: typeof user === "string" ? undefined : user.username,
|
|
48
48
|
};
|
|
49
49
|
}
|
|
50
|
+
resolveGuild(guildId) {
|
|
51
|
+
const cached = this.client.guilds.get(guildId);
|
|
52
|
+
if (cached)
|
|
53
|
+
return cached;
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
50
56
|
}
|
|
51
57
|
exports.OceanicManager = OceanicManager;
|
package/dist/wrappers/seyfert.js
CHANGED
|
@@ -75,5 +75,11 @@ class SeyfertManager extends Manager_1.Manager {
|
|
|
75
75
|
return { id, username: typeof user === "string" ? undefined : user.username };
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
|
+
resolveGuild(guildId) {
|
|
79
|
+
const cached = this.client.cache.guilds?.get(guildId);
|
|
80
|
+
if (cached)
|
|
81
|
+
return cached;
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
78
84
|
}
|
|
79
85
|
exports.SeyfertManager = SeyfertManager;
|