yukimu 2.0.8 → 3.0.0

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.
Files changed (97) hide show
  1. package/dist/BitrateOptimizer.d.ts +52 -0
  2. package/dist/BitrateOptimizer.d.ts.map +1 -0
  3. package/dist/BitrateOptimizer.js +115 -0
  4. package/dist/BitrateOptimizer.js.map +1 -0
  5. package/dist/ConnectionPool.d.ts +84 -0
  6. package/dist/ConnectionPool.d.ts.map +1 -0
  7. package/dist/ConnectionPool.js +203 -0
  8. package/dist/ConnectionPool.js.map +1 -0
  9. package/dist/Constants.d.ts +47 -0
  10. package/dist/Constants.d.ts.map +1 -0
  11. package/dist/Constants.js +170 -0
  12. package/dist/Constants.js.map +1 -0
  13. package/dist/Logger.d.ts +22 -0
  14. package/dist/Logger.d.ts.map +1 -0
  15. package/dist/Logger.js +74 -0
  16. package/dist/Logger.js.map +1 -0
  17. package/dist/Node.d.ts +61 -0
  18. package/dist/Node.d.ts.map +1 -0
  19. package/dist/Node.js +446 -0
  20. package/dist/Node.js.map +1 -0
  21. package/dist/Player.d.ts +143 -0
  22. package/dist/Player.d.ts.map +1 -0
  23. package/dist/Player.js +574 -0
  24. package/dist/Player.js.map +1 -0
  25. package/dist/Plugin.d.ts +25 -0
  26. package/dist/Plugin.d.ts.map +1 -0
  27. package/dist/Plugin.js +15 -0
  28. package/dist/Plugin.js.map +1 -0
  29. package/dist/Queue.d.ts +89 -0
  30. package/dist/Queue.d.ts.map +1 -0
  31. package/dist/Queue.js +188 -0
  32. package/dist/Queue.js.map +1 -0
  33. package/dist/Resolver.d.ts +68 -0
  34. package/dist/Resolver.d.ts.map +1 -0
  35. package/dist/Resolver.js +361 -0
  36. package/dist/Resolver.js.map +1 -0
  37. package/dist/Rest.d.ts +46 -0
  38. package/dist/Rest.d.ts.map +1 -0
  39. package/dist/Rest.js +247 -0
  40. package/dist/Rest.js.map +1 -0
  41. package/dist/TrackCache.d.ts +41 -0
  42. package/dist/TrackCache.d.ts.map +1 -0
  43. package/dist/TrackCache.js +144 -0
  44. package/dist/TrackCache.js.map +1 -0
  45. package/dist/WsQueue.d.ts +41 -0
  46. package/dist/WsQueue.d.ts.map +1 -0
  47. package/dist/WsQueue.js +116 -0
  48. package/dist/WsQueue.js.map +1 -0
  49. package/dist/Yukimu.d.ts +84 -0
  50. package/dist/Yukimu.d.ts.map +1 -0
  51. package/dist/Yukimu.js +290 -0
  52. package/dist/Yukimu.js.map +1 -0
  53. package/dist/connector/Connector.d.ts +34 -0
  54. package/dist/connector/Connector.d.ts.map +1 -0
  55. package/dist/connector/Connector.js +39 -0
  56. package/dist/connector/Connector.js.map +1 -0
  57. package/dist/connector/DiscordJS.d.ts +27 -0
  58. package/dist/connector/DiscordJS.d.ts.map +1 -0
  59. package/dist/connector/DiscordJS.js +69 -0
  60. package/dist/connector/DiscordJS.js.map +1 -0
  61. package/dist/connector/Eris.d.ts +19 -0
  62. package/dist/connector/Eris.d.ts.map +1 -0
  63. package/dist/connector/Eris.js +62 -0
  64. package/dist/connector/Eris.js.map +1 -0
  65. package/dist/connector/Oceanic.d.ts +19 -0
  66. package/dist/connector/Oceanic.d.ts.map +1 -0
  67. package/dist/connector/Oceanic.js +60 -0
  68. package/dist/connector/Oceanic.js.map +1 -0
  69. package/dist/errors/YukimuError.d.ts +51 -0
  70. package/dist/errors/YukimuError.d.ts.map +1 -0
  71. package/dist/errors/YukimuError.js +105 -0
  72. package/dist/errors/YukimuError.js.map +1 -0
  73. package/dist/index.d.ts +29 -0
  74. package/dist/index.d.ts.map +1 -0
  75. package/dist/index.js +70 -0
  76. package/dist/index.js.map +1 -0
  77. package/dist/plugins/AutoResume.d.ts +25 -0
  78. package/dist/plugins/AutoResume.d.ts.map +1 -0
  79. package/dist/plugins/AutoResume.js +132 -0
  80. package/dist/plugins/AutoResume.js.map +1 -0
  81. package/dist/plugins/AutoplayPlugin.d.ts +35 -0
  82. package/dist/plugins/AutoplayPlugin.d.ts.map +1 -0
  83. package/dist/plugins/AutoplayPlugin.js +111 -0
  84. package/dist/plugins/AutoplayPlugin.js.map +1 -0
  85. package/dist/plugins/InactivityPlugin.d.ts +30 -0
  86. package/dist/plugins/InactivityPlugin.d.ts.map +1 -0
  87. package/dist/plugins/InactivityPlugin.js +86 -0
  88. package/dist/plugins/InactivityPlugin.js.map +1 -0
  89. package/dist/plugins/PlayerMoved.d.ts +29 -0
  90. package/dist/plugins/PlayerMoved.d.ts.map +1 -0
  91. package/dist/plugins/PlayerMoved.js +75 -0
  92. package/dist/plugins/PlayerMoved.js.map +1 -0
  93. package/dist/types.d.ts +309 -0
  94. package/dist/types.d.ts.map +1 -0
  95. package/dist/types.js +4 -0
  96. package/dist/types.js.map +1 -0
  97. package/package.json +4 -4
package/dist/Player.js ADDED
@@ -0,0 +1,574 @@
1
+ "use strict";
2
+ /** Yukimu v2.0.0 — Player with State Safety & Bitrate Optimization */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.Player = void 0;
5
+ const Queue_1 = require("./Queue");
6
+ const BitrateOptimizer_1 = require("./BitrateOptimizer");
7
+ const Constants_1 = require("./Constants");
8
+ const YukimuError_1 = require("./errors/YukimuError");
9
+ /**
10
+ * Represents an audio player for a specific Discord guild.
11
+ *
12
+ * Critical fixes from v1:
13
+ * 1. play() — only sets playing=true AFTER the REST call succeeds
14
+ * 2. pause() — paused tracks are still "playing" from Lavalink's perspective
15
+ * 3. moveToNode() — properly re-sends voice state to the new node
16
+ * 4. sendVoicePayload() — deferred until connector is ready (safe for startup)
17
+ * 5. Proper cleanup in destroy() — all state, timers, and references
18
+ * 6. Input validation on filter values
19
+ * 7. Boost-tier-aware audio optimization
20
+ */
21
+ class Player {
22
+ manager;
23
+ node;
24
+ queue;
25
+ guildId;
26
+ voiceChannelId;
27
+ textChannelId;
28
+ state = Constants_1.PlayerState.DISCONNECTED;
29
+ playing = false;
30
+ paused = false;
31
+ position = 0;
32
+ ping = -1;
33
+ lastUpdated = Date.now();
34
+ volume;
35
+ loop = "none";
36
+ autoplay = false;
37
+ sessionId = null;
38
+ voiceToken = null;
39
+ voiceEndpoint = null;
40
+ selfDeaf;
41
+ selfMute;
42
+ filters = {};
43
+ data = new Map();
44
+ /** @internal Deferred resolver for voice connection readiness */
45
+ _connectionResolve = null;
46
+ constructor(manager, node, options) {
47
+ this.manager = manager;
48
+ this.node = node;
49
+ this.queue = new Queue_1.Queue();
50
+ this.guildId = options.guildId;
51
+ this.voiceChannelId = options.voiceChannelId;
52
+ this.textChannelId = options.textChannelId;
53
+ this.volume = options.volume ?? 100;
54
+ this.selfDeaf = options.selfDeaf ?? true;
55
+ this.selfMute = options.selfMute ?? false;
56
+ // Send the voice state update to Discord (join the channel)
57
+ // This is safe — connector.sendPayload handles missing guilds gracefully
58
+ this.sendVoicePayload(options.voiceChannelId, this.selfDeaf, this.selfMute);
59
+ this.state = Constants_1.PlayerState.CONNECTING;
60
+ }
61
+ // ─── Getters ────────────────────────────────────────────────────────────
62
+ get connected() {
63
+ return this.state === Constants_1.PlayerState.CONNECTED;
64
+ }
65
+ /**
66
+ * Estimated real-time position accounting for time since last update.
67
+ * Returns the actual position (capped at track length).
68
+ */
69
+ get realPosition() {
70
+ if (!this.playing || this.paused)
71
+ return this.position;
72
+ const trackLength = this.queue.current?.info?.length ?? Infinity;
73
+ return Math.min(this.position + (Date.now() - this.lastUpdated), trackLength);
74
+ }
75
+ /**
76
+ * Get the current boost tier of the guild this player is in.
77
+ */
78
+ get boostTier() {
79
+ return this.manager.connector.getGuildBoostTier(this.guildId);
80
+ }
81
+ // ─── Voice ──────────────────────────────────────────────────────────────
82
+ sendVoicePayload(channelId, selfDeaf, selfMute) {
83
+ this.manager.connector.sendPayload(this.guildId, {
84
+ op: 4,
85
+ d: {
86
+ guild_id: this.guildId,
87
+ channel_id: channelId,
88
+ self_deaf: selfDeaf,
89
+ self_mute: selfMute,
90
+ },
91
+ });
92
+ }
93
+ /**
94
+ * Check if we have all voice connection data and send it to Lavalink.
95
+ */
96
+ checkVoiceReady() {
97
+ if (!this.sessionId || !this.voiceToken || !this.voiceEndpoint)
98
+ return;
99
+ const voiceState = {
100
+ token: this.voiceToken,
101
+ endpoint: this.voiceEndpoint,
102
+ sessionId: this.sessionId,
103
+ channelId: this.voiceChannelId,
104
+ };
105
+ if (this.node.version === 4) {
106
+ this.node.rest.updatePlayer(this.guildId, { voice: voiceState }).catch((err) => {
107
+ this.manager.logger.error(`Failed to send voice update for guild ${this.guildId}: ${err}`);
108
+ });
109
+ }
110
+ else {
111
+ this.node.send({
112
+ op: "voiceUpdate",
113
+ guildId: this.guildId,
114
+ sessionId: this.sessionId,
115
+ event: {
116
+ token: this.voiceToken,
117
+ guild_id: this.guildId,
118
+ endpoint: this.voiceEndpoint,
119
+ },
120
+ }).catch((err) => {
121
+ this.manager.logger.error(`Failed to send voice update for guild ${this.guildId}: ${err}`);
122
+ });
123
+ }
124
+ this.state = Constants_1.PlayerState.CONNECTED;
125
+ // Resolve any pending waitForConnection() call
126
+ if (this._connectionResolve) {
127
+ this._connectionResolve();
128
+ this._connectionResolve = null;
129
+ }
130
+ }
131
+ // ─── Playback ───────────────────────────────────────────────────────────
132
+ /**
133
+ * Play a track. If no track is provided, plays the current queue track.
134
+ *
135
+ * FIX: Only sets `playing = true` after the REST call succeeds.
136
+ * In v1, state was set before the REST call, causing ghost playing state on failure.
137
+ */
138
+ async play(track, options) {
139
+ const toPlay = track ?? this.queue.current;
140
+ if (!toPlay) {
141
+ throw new YukimuError_1.PlayerError("No track to play", YukimuError_1.ErrorCode.PLAYER_NO_TRACK);
142
+ }
143
+ this.queue.current = toPlay;
144
+ // Wait for voice connection before sending play command.
145
+ // Without this, Lavalink silently queues the play until voice connects,
146
+ // causing a 3-4 second perceived delay.
147
+ if (this.state !== Constants_1.PlayerState.CONNECTED) {
148
+ await this.waitForConnection(5000);
149
+ }
150
+ if (this.node.version === 4) {
151
+ // Bundle voice state with the play command when available,
152
+ // so Lavalink gets both in a single request (eliminates round-trip)
153
+ const payload = {
154
+ track: { encoded: toPlay.encoded },
155
+ volume: this.volume,
156
+ ...(options?.startTime !== undefined && { position: options.startTime }),
157
+ ...(options?.endTime !== undefined && { endTime: options.endTime }),
158
+ };
159
+ // Include voice state if we have it — lets Lavalink start immediately
160
+ if (this.voiceToken && this.voiceEndpoint && this.sessionId) {
161
+ payload.voice = {
162
+ token: this.voiceToken,
163
+ endpoint: this.voiceEndpoint,
164
+ sessionId: this.sessionId,
165
+ };
166
+ }
167
+ await this.node.rest.updatePlayer(this.guildId, payload, options?.noReplace ?? false);
168
+ }
169
+ else {
170
+ await this.node.send({
171
+ op: "play",
172
+ guildId: this.guildId,
173
+ track: toPlay.encoded,
174
+ volume: String(this.volume),
175
+ ...(options?.startTime !== undefined && { startTime: String(options.startTime) }),
176
+ ...(options?.endTime !== undefined && { endTime: String(options.endTime) }),
177
+ });
178
+ }
179
+ // Only update state AFTER the call succeeds
180
+ this.playing = true;
181
+ this.paused = false;
182
+ this.lastUpdated = Date.now();
183
+ }
184
+ /**
185
+ * Wait for voice connection to be ready.
186
+ * Resolves immediately if already connected, otherwise waits up to timeoutMs.
187
+ * Does NOT reject on timeout — play() will proceed anyway and let Lavalink handle it.
188
+ */
189
+ waitForConnection(timeoutMs) {
190
+ if (this.state === Constants_1.PlayerState.CONNECTED)
191
+ return Promise.resolve();
192
+ return new Promise((resolve) => {
193
+ this._connectionResolve = resolve;
194
+ const timer = setTimeout(() => {
195
+ this._connectionResolve = null;
196
+ this.manager.logger.debug(`Voice connection wait timed out for guild ${this.guildId} after ${timeoutMs}ms, proceeding with play`);
197
+ resolve();
198
+ }, timeoutMs);
199
+ // Don't keep process alive for this timer
200
+ if (timer.unref)
201
+ timer.unref();
202
+ });
203
+ }
204
+ /**
205
+ * Pause or unpause playback.
206
+ *
207
+ * FIX: `playing` now reflects "has an active track" independently of pause state.
208
+ * A paused player is still "playing" (it has an active track, just paused).
209
+ */
210
+ async pause(state = true) {
211
+ if (this.node.version === 4) {
212
+ await this.node.rest.updatePlayer(this.guildId, { paused: state });
213
+ }
214
+ else {
215
+ await this.node.send({ op: "pause", guildId: this.guildId, pause: state });
216
+ }
217
+ this.paused = state;
218
+ // `playing` stays true — the track is still loaded, just paused
219
+ }
220
+ async resume() {
221
+ return this.pause(false);
222
+ }
223
+ async stop() {
224
+ if (this.node.version === 4) {
225
+ await this.node.rest.updatePlayer(this.guildId, { track: { encoded: null } });
226
+ }
227
+ else {
228
+ await this.node.send({ op: "stop", guildId: this.guildId });
229
+ }
230
+ this.playing = false;
231
+ this.paused = false;
232
+ this.position = 0;
233
+ this.queue.current = null;
234
+ }
235
+ async skip() {
236
+ const next = this.queue.next();
237
+ if (next) {
238
+ await this.play(next);
239
+ }
240
+ else {
241
+ await this.stop();
242
+ this.manager.emit("queueEnd", this);
243
+ }
244
+ return next;
245
+ }
246
+ /**
247
+ * Play the previous track (from history).
248
+ * @returns The previous track, or null if no history exists
249
+ */
250
+ async previous() {
251
+ const prev = this.queue.previous[0];
252
+ if (!prev)
253
+ return null;
254
+ // Move current back to front of queue
255
+ if (this.queue.current) {
256
+ this.queue.add(this.queue.current, 0);
257
+ }
258
+ // Remove from previous history
259
+ this.queue.previous.shift();
260
+ await this.play(prev);
261
+ return prev;
262
+ }
263
+ /**
264
+ * Restart the currently playing track from the beginning.
265
+ */
266
+ async replay() {
267
+ if (!this.queue.current) {
268
+ throw new YukimuError_1.PlayerError("No track to replay", YukimuError_1.ErrorCode.PLAYER_NO_TRACK);
269
+ }
270
+ await this.play(this.queue.current, { startTime: 0 });
271
+ }
272
+ async seek(position) {
273
+ if (!this.queue.current?.info?.isSeekable) {
274
+ throw new YukimuError_1.PlayerError("Current track is not seekable", YukimuError_1.ErrorCode.PLAYER_NOT_SEEKABLE);
275
+ }
276
+ if (position < 0)
277
+ position = 0;
278
+ if (this.node.version === 4) {
279
+ await this.node.rest.updatePlayer(this.guildId, { position });
280
+ }
281
+ else {
282
+ await this.node.send({ op: "seek", guildId: this.guildId, position });
283
+ }
284
+ this.position = position;
285
+ this.lastUpdated = Date.now();
286
+ }
287
+ // ─── Volume ─────────────────────────────────────────────────────────────
288
+ async setVolume(volume) {
289
+ if (typeof volume !== "number" || isNaN(volume)) {
290
+ throw new YukimuError_1.PlayerError("Volume must be a number", YukimuError_1.ErrorCode.PLAYER_INVALID_VOLUME);
291
+ }
292
+ volume = Math.floor(Math.max(0, Math.min(1000, volume)));
293
+ if (this.node.version === 4) {
294
+ await this.node.rest.updatePlayer(this.guildId, { volume });
295
+ }
296
+ else {
297
+ await this.node.send({ op: "volume", guildId: this.guildId, volume });
298
+ }
299
+ this.volume = volume;
300
+ }
301
+ // ─── Filters ────────────────────────────────────────────────────────────
302
+ async setFilters(filters) {
303
+ this.filters = { ...this.filters, ...filters };
304
+ if (this.node.version === 4) {
305
+ await this.node.rest.updatePlayer(this.guildId, { filters: this.filters });
306
+ }
307
+ else {
308
+ // v3: equalizer is sent separately
309
+ if (filters.equalizer) {
310
+ await this.node.send({ op: "equalizer", guildId: this.guildId, bands: filters.equalizer });
311
+ }
312
+ const rest = { ...filters };
313
+ delete rest.equalizer;
314
+ if (Object.keys(rest).length > 0) {
315
+ await this.node.send({ op: "filters", guildId: this.guildId, ...rest });
316
+ }
317
+ }
318
+ }
319
+ async clearFilters() {
320
+ this.filters = {};
321
+ if (this.node.version === 4) {
322
+ await this.node.rest.updatePlayer(this.guildId, { filters: {} });
323
+ }
324
+ else {
325
+ await this.node.send({ op: "filters", guildId: this.guildId });
326
+ }
327
+ }
328
+ // ─── Filter Presets ─────────────────────────────────────────────────────
329
+ async setBassBoost(level) {
330
+ const tier = this.boostTier;
331
+ if (level === "off") {
332
+ await this.setFilters({ equalizer: BitrateOptimizer_1.BitrateOptimizer.getFlatEQ() });
333
+ return;
334
+ }
335
+ // Scale bass based on boost tier to prevent clipping
336
+ const scales = { low: 0.3, medium: 0.5, high: 0.75, extreme: 1.0 };
337
+ const scale = scales[level] ?? 0.5;
338
+ const tierScale = tier >= 2 ? 1.0 : tier === 1 ? 0.8 : 0.6;
339
+ const effectiveScale = scale * tierScale;
340
+ const eq = [
341
+ { band: 0, gain: 0.6 * effectiveScale },
342
+ { band: 1, gain: 0.5 * effectiveScale },
343
+ { band: 2, gain: 0.4 * effectiveScale },
344
+ { band: 3, gain: 0.25 * effectiveScale },
345
+ { band: 4, gain: 0.1 * effectiveScale },
346
+ { band: 5, gain: -0.05 * effectiveScale },
347
+ ...Array.from({ length: 9 }, (_, i) => ({ band: i + 6, gain: 0 })),
348
+ ];
349
+ await this.setFilters({ equalizer: eq });
350
+ }
351
+ async setNightcore(enabled) {
352
+ await this.setFilters({
353
+ timescale: enabled ? { speed: 1.2, pitch: 1.2, rate: 1.0 } : {},
354
+ });
355
+ }
356
+ async setVaporwave(enabled) {
357
+ await this.setFilters({
358
+ timescale: enabled ? { speed: 0.8, pitch: 0.8, rate: 1.0 } : {},
359
+ });
360
+ }
361
+ async set8D(enabled) {
362
+ await this.setFilters({
363
+ rotation: enabled ? { rotationHz: 0.2 } : {},
364
+ });
365
+ }
366
+ async setKaraoke(enabled) {
367
+ await this.setFilters({
368
+ karaoke: enabled
369
+ ? { level: 1.0, monoLevel: 1.0, filterBand: 220.0, filterWidth: 100.0 }
370
+ : {},
371
+ });
372
+ }
373
+ async setTremolo(enabled, frequency = 2.0, depth = 0.5) {
374
+ if (enabled) {
375
+ if (frequency <= 0 || frequency > 14) {
376
+ throw new YukimuError_1.PlayerError("Tremolo frequency must be between 0 and 14", YukimuError_1.ErrorCode.PLAYER_INVALID_FILTER);
377
+ }
378
+ if (depth <= 0 || depth > 1) {
379
+ throw new YukimuError_1.PlayerError("Tremolo depth must be between 0 and 1", YukimuError_1.ErrorCode.PLAYER_INVALID_FILTER);
380
+ }
381
+ }
382
+ await this.setFilters({ tremolo: enabled ? { frequency, depth } : {} });
383
+ }
384
+ async setVibrato(enabled, frequency = 2.0, depth = 0.5) {
385
+ if (enabled) {
386
+ if (frequency <= 0 || frequency > 14) {
387
+ throw new YukimuError_1.PlayerError("Vibrato frequency must be between 0 and 14", YukimuError_1.ErrorCode.PLAYER_INVALID_FILTER);
388
+ }
389
+ if (depth <= 0 || depth > 1) {
390
+ throw new YukimuError_1.PlayerError("Vibrato depth must be between 0 and 1", YukimuError_1.ErrorCode.PLAYER_INVALID_FILTER);
391
+ }
392
+ }
393
+ await this.setFilters({ vibrato: enabled ? { frequency, depth } : {} });
394
+ }
395
+ async setLowPass(enabled, smoothing = 20.0) {
396
+ if (enabled && smoothing <= 0) {
397
+ throw new YukimuError_1.PlayerError("LowPass smoothing must be greater than 0", YukimuError_1.ErrorCode.PLAYER_INVALID_FILTER);
398
+ }
399
+ await this.setFilters({ lowPass: enabled ? { smoothing } : {} });
400
+ }
401
+ /** Set playback speed (1.0 = normal, 2.0 = double speed) */
402
+ async setSpeed(speed) {
403
+ if (speed <= 0 || speed > 10) {
404
+ throw new YukimuError_1.PlayerError("Speed must be between 0 and 10", YukimuError_1.ErrorCode.PLAYER_INVALID_FILTER);
405
+ }
406
+ const existing = (this.filters.timescale ?? {});
407
+ await this.setFilters({
408
+ timescale: { ...existing, speed },
409
+ });
410
+ }
411
+ /** Set playback pitch (1.0 = normal) */
412
+ async setPitch(pitch) {
413
+ if (pitch <= 0 || pitch > 10) {
414
+ throw new YukimuError_1.PlayerError("Pitch must be between 0 and 10", YukimuError_1.ErrorCode.PLAYER_INVALID_FILTER);
415
+ }
416
+ const existing = (this.filters.timescale ?? {});
417
+ await this.setFilters({
418
+ timescale: { ...existing, pitch },
419
+ });
420
+ }
421
+ // ─── Queue Shortcuts ───────────────────────────────────────────────────
422
+ /**
423
+ * Add track(s) to the queue. If nothing is currently playing, plays immediately.
424
+ */
425
+ async add(tracks, requester) {
426
+ const arr = Array.isArray(tracks) ? [...tracks] : [tracks];
427
+ if (requester) {
428
+ for (const t of arr) {
429
+ t["requester"] = requester;
430
+ }
431
+ }
432
+ if (!this.queue.current && arr.length > 0) {
433
+ const first = arr.shift();
434
+ if (arr.length > 0)
435
+ this.queue.add(arr);
436
+ await this.play(first);
437
+ }
438
+ else {
439
+ this.queue.add(arr);
440
+ }
441
+ }
442
+ setLoop(mode) {
443
+ this.loop = mode;
444
+ }
445
+ setAutoplay(enabled) {
446
+ this.autoplay = enabled;
447
+ }
448
+ // ─── Node Movement ─────────────────────────────────────────────────────
449
+ /**
450
+ * Move this player to a different Lavalink node.
451
+ *
452
+ * FIX: Now properly re-sends the voice state to the new node.
453
+ * In v1, the new node didn't know about the voice connection.
454
+ */
455
+ async moveToNode(node) {
456
+ if (this.node === node)
457
+ return;
458
+ const oldNode = this.node;
459
+ this.node = node;
460
+ // Clean up on old node
461
+ await oldNode.rest.destroyPlayer(this.guildId).catch(() => { });
462
+ // Re-send voice state to new node
463
+ this.checkVoiceReady();
464
+ // Resume playback on new node
465
+ if (this.queue.current) {
466
+ await this.play(this.queue.current, { startTime: this.realPosition });
467
+ }
468
+ // Re-apply filters and volume
469
+ if (Object.keys(this.filters).length > 0) {
470
+ await this.setFilters(this.filters).catch(() => { });
471
+ }
472
+ if (this.volume !== 100) {
473
+ await this.setVolume(this.volume).catch(() => { });
474
+ }
475
+ }
476
+ /** Move the bot to a different voice channel */
477
+ async move(channelId) {
478
+ this.voiceChannelId = channelId;
479
+ this.sendVoicePayload(channelId, this.selfDeaf, this.selfMute);
480
+ }
481
+ // ─── Audio Quality ──────────────────────────────────────────────────────
482
+ /**
483
+ * Apply optimal audio settings based on the guild's boost tier.
484
+ * Automatically adjusts EQ and filters for best clarity at the available bitrate.
485
+ */
486
+ async applyOptimalQuality() {
487
+ const tier = this.boostTier;
488
+ const filters = BitrateOptimizer_1.BitrateOptimizer.getOptimalFilters(tier);
489
+ await this.setFilters(filters);
490
+ this.manager.logger.debug(`Applied optimal quality for guild ${this.guildId} (boost tier ${tier}, max ${BitrateOptimizer_1.BitrateOptimizer.getMaxBitrate(tier)}kbps)`);
491
+ }
492
+ /** Maximum audio quality — crystal clear, enhanced bass & treble */
493
+ async setHighQuality() {
494
+ const tier = this.boostTier;
495
+ const scale = tier >= 2 ? 1.0 : tier === 1 ? 0.8 : 0.6;
496
+ await this.setFilters({
497
+ equalizer: [
498
+ { band: 0, gain: 0.25 * scale },
499
+ { band: 1, gain: 0.20 * scale },
500
+ { band: 2, gain: 0.15 * scale },
501
+ { band: 3, gain: 0.05 * scale },
502
+ { band: 4, gain: 0.0 },
503
+ { band: 5, gain: 0.0 },
504
+ { band: 6, gain: 0.0 },
505
+ { band: 7, gain: 0.05 * scale },
506
+ { band: 8, gain: 0.10 * scale },
507
+ { band: 9, gain: 0.15 * scale },
508
+ { band: 10, gain: 0.15 * scale },
509
+ { band: 11, gain: 0.10 * scale },
510
+ { band: 12, gain: 0.05 * scale },
511
+ { band: 13, gain: 0.0 },
512
+ { band: 14, gain: 0.0 },
513
+ ],
514
+ lowPass: tier >= 2 ? { smoothing: 5.0 } : {},
515
+ });
516
+ }
517
+ /** Studio quality — flat, neutral, most accurate */
518
+ async setStudioQuality() {
519
+ await this.clearFilters();
520
+ await this.setFilters({
521
+ equalizer: BitrateOptimizer_1.BitrateOptimizer.getFlatEQ(),
522
+ });
523
+ }
524
+ /** Concert hall effect — scaled for boost tier */
525
+ async setConcertHall() {
526
+ const tier = this.boostTier;
527
+ const scale = tier >= 2 ? 1.0 : 0.6;
528
+ await this.setFilters({
529
+ equalizer: [
530
+ { band: 0, gain: 0.1 * scale },
531
+ { band: 1, gain: 0.1 * scale },
532
+ { band: 2, gain: 0.05 * scale },
533
+ { band: 3, gain: 0.0 },
534
+ { band: 4, gain: -0.05 * scale },
535
+ { band: 5, gain: 0.0 },
536
+ { band: 6, gain: 0.05 * scale },
537
+ { band: 7, gain: 0.1 * scale },
538
+ { band: 8, gain: 0.1 * scale },
539
+ { band: 9, gain: 0.05 * scale },
540
+ { band: 10, gain: 0.0 },
541
+ { band: 11, gain: 0.0 },
542
+ { band: 12, gain: 0.0 },
543
+ { band: 13, gain: 0.0 },
544
+ { band: 14, gain: 0.0 },
545
+ ],
546
+ rotation: { rotationHz: 0.05 },
547
+ });
548
+ }
549
+ // ─── Lifecycle ──────────────────────────────────────────────────────────
550
+ /**
551
+ * Destroy this player and clean up all resources.
552
+ */
553
+ async destroy() {
554
+ this.state = Constants_1.PlayerState.DISCONNECTING;
555
+ // Leave voice channel
556
+ this.sendVoicePayload(null, false, false);
557
+ // Destroy on Lavalink
558
+ await this.node.rest.destroyPlayer(this.guildId).catch(() => { });
559
+ // Clean up all state
560
+ this.playing = false;
561
+ this.paused = false;
562
+ this.position = 0;
563
+ this.queue.clear();
564
+ this.data.clear();
565
+ this.filters = {};
566
+ this.sessionId = null;
567
+ this.voiceToken = null;
568
+ this.voiceEndpoint = null;
569
+ this.voiceChannelId = null;
570
+ this.state = Constants_1.PlayerState.DISCONNECTED;
571
+ }
572
+ }
573
+ exports.Player = Player;
574
+ //# sourceMappingURL=Player.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Player.js","sourceRoot":"","sources":["../src/Player.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /** Yukimu v2.0.0 — Plugin Base Class */
2
+ import type { Yukimu } from "./Yukimu";
3
+ /**
4
+ * Base class for Yukimu plugins.
5
+ *
6
+ * Plugins extend Yukimu's functionality by hooking into events.
7
+ * Every plugin must implement `name` and `load()`.
8
+ * Plugins should also implement `unload()` to clean up listeners/timers.
9
+ */
10
+ export declare abstract class Plugin {
11
+ /** Unique name identifying this plugin */
12
+ abstract readonly name: string;
13
+ /**
14
+ * Called when the plugin is loaded into the Yukimu manager.
15
+ * Use this to register event listeners and initialize state.
16
+ */
17
+ abstract load(manager: Yukimu): void;
18
+ /**
19
+ * Called when the plugin is unloaded.
20
+ * Clean up all event listeners, timers, and state here.
21
+ * Failure to implement this will cause memory leaks.
22
+ */
23
+ unload?(manager: Yukimu): void;
24
+ }
25
+ //# sourceMappingURL=Plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Plugin.d.ts","sourceRoot":"","sources":["../src/Plugin.ts"],"names":[],"mappings":"AAAA,wCAAwC;AAExC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEvC;;;;;;GAMG;AACH,8BAAsB,MAAM;IAC1B,0CAA0C;IAC1C,kBAAyB,IAAI,EAAE,MAAM,CAAC;IAEtC;;;OAGG;aACa,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAE3C;;;;OAIG;IACI,MAAM,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;CACtC"}
package/dist/Plugin.js ADDED
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ /** Yukimu v2.0.0 — Plugin Base Class */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.Plugin = void 0;
5
+ /**
6
+ * Base class for Yukimu plugins.
7
+ *
8
+ * Plugins extend Yukimu's functionality by hooking into events.
9
+ * Every plugin must implement `name` and `load()`.
10
+ * Plugins should also implement `unload()` to clean up listeners/timers.
11
+ */
12
+ class Plugin {
13
+ }
14
+ exports.Plugin = Plugin;
15
+ //# sourceMappingURL=Plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Plugin.js","sourceRoot":"","sources":["../src/Plugin.ts"],"names":[],"mappings":";AAAA,wCAAwC;;;AAIxC;;;;;;GAMG;AACH,MAAsB,MAAM;CAgB3B;AAhBD,wBAgBC"}