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
@@ -0,0 +1,35 @@
1
+ /** Yukimu v2.0.0 — Autoplay Plugin */
2
+ import { Plugin } from "../Plugin";
3
+ import type { Yukimu } from "../Yukimu";
4
+ import type { Player } from "../Player";
5
+ import type { Track } from "../types";
6
+ export type AutoplayStrategy = (player: Player, lastTrack: Track, manager: Yukimu) => Promise<Track | null>;
7
+ export interface AutoplayOptions {
8
+ /** Custom strategy to find the next track. If not provided, uses YouTube recommendations. */
9
+ strategy?: AutoplayStrategy;
10
+ /** Maximum number of autoplay tracks to play in sequence (default: 50) */
11
+ maxAutoplayTracks?: number;
12
+ /** Delay in ms before fetching the next autoplay track (default: 1000) */
13
+ fetchDelay?: number;
14
+ }
15
+ /**
16
+ * Built-in autoplay plugin that automatically plays related tracks when the queue ends.
17
+ *
18
+ * Default strategy: Uses the last track's URI to search for related YouTube content.
19
+ * Custom strategy: Users can provide their own function to find the next track.
20
+ */
21
+ export declare class AutoplayPlugin extends Plugin {
22
+ readonly name = "Autoplay";
23
+ private readonly options;
24
+ private autoplayCounters;
25
+ private boundListeners;
26
+ constructor(options?: AutoplayOptions);
27
+ load(manager: Yukimu): void;
28
+ unload(manager: Yukimu): void;
29
+ /**
30
+ * Default autoplay strategy: search YouTube for related content based on the last track.
31
+ */
32
+ private defaultStrategy;
33
+ private sleep;
34
+ }
35
+ //# sourceMappingURL=AutoplayPlugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AutoplayPlugin.d.ts","sourceRoot":"","sources":["../../src/plugins/AutoplayPlugin.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,KAAK,EAAE,KAAK,EAAgB,MAAM,UAAU,CAAC;AAEpD,MAAM,MAAM,gBAAgB,GAAG,CAC7B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,KAAK,EAChB,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;AAE3B,MAAM,WAAW,eAAe;IAC9B,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,0EAA0E;IAC1E,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;GAKG;AACH,qBAAa,cAAe,SAAQ,MAAM;IACxC,SAAgB,IAAI,cAAc;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4B;IACpD,OAAO,CAAC,gBAAgB,CAAkC;IAC1D,OAAO,CAAC,cAAc,CAAoD;gBAE9D,OAAO,GAAE,eAAoB;IASlC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAoD3B,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAQpC;;OAEG;YACW,eAAe;IAmC7B,OAAO,CAAC,KAAK;CAGd"}
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ /** Yukimu v2.0.0 — Autoplay Plugin */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.AutoplayPlugin = void 0;
5
+ const Plugin_1 = require("../Plugin");
6
+ /**
7
+ * Built-in autoplay plugin that automatically plays related tracks when the queue ends.
8
+ *
9
+ * Default strategy: Uses the last track's URI to search for related YouTube content.
10
+ * Custom strategy: Users can provide their own function to find the next track.
11
+ */
12
+ class AutoplayPlugin extends Plugin_1.Plugin {
13
+ name = "Autoplay";
14
+ options;
15
+ autoplayCounters = new Map();
16
+ boundListeners = new Map();
17
+ constructor(options = {}) {
18
+ super();
19
+ this.options = {
20
+ strategy: options.strategy ?? this.defaultStrategy.bind(this),
21
+ maxAutoplayTracks: options.maxAutoplayTracks ?? 50,
22
+ fetchDelay: options.fetchDelay ?? 1000,
23
+ };
24
+ }
25
+ load(manager) {
26
+ const onAutoplayRequest = async (player, lastTrack) => {
27
+ if (!player.autoplay)
28
+ return;
29
+ const count = this.autoplayCounters.get(player.guildId) ?? 0;
30
+ if (count >= this.options.maxAutoplayTracks) {
31
+ manager.logger.info(`[Autoplay] Max autoplay tracks (${this.options.maxAutoplayTracks}) reached for guild ${player.guildId}`);
32
+ this.autoplayCounters.delete(player.guildId);
33
+ return;
34
+ }
35
+ // Small delay to prevent rapid-fire requests
36
+ await this.sleep(this.options.fetchDelay);
37
+ // Check if player is still alive and autoplay is still enabled
38
+ const currentPlayer = manager.players.get(player.guildId);
39
+ if (!currentPlayer || !currentPlayer.autoplay)
40
+ return;
41
+ try {
42
+ const nextTrack = await this.options.strategy(currentPlayer, lastTrack, manager);
43
+ if (nextTrack) {
44
+ this.autoplayCounters.set(player.guildId, count + 1);
45
+ await currentPlayer.play(nextTrack);
46
+ manager.logger.debug(`[Autoplay] Playing recommendation for guild ${player.guildId}: ${nextTrack.info?.title}`);
47
+ }
48
+ else {
49
+ manager.logger.debug(`[Autoplay] No recommendation found for guild ${player.guildId}`);
50
+ }
51
+ }
52
+ catch (err) {
53
+ manager.logger.warn(`[Autoplay] Failed to autoplay for guild ${player.guildId}: ${err}`);
54
+ }
55
+ };
56
+ const onTrackStart = (player) => {
57
+ // Reset counter if user manually adds a track (not autoplay)
58
+ if (player.queue.size > 0) {
59
+ this.autoplayCounters.delete(player.guildId);
60
+ }
61
+ };
62
+ const onPlayerDestroy = (player) => {
63
+ this.autoplayCounters.delete(player.guildId);
64
+ };
65
+ this.boundListeners.set("autoplayRequest", onAutoplayRequest);
66
+ this.boundListeners.set("trackStart", onTrackStart);
67
+ this.boundListeners.set("playerDestroy", onPlayerDestroy);
68
+ manager.on("autoplayRequest", onAutoplayRequest);
69
+ manager.on("trackStart", onTrackStart);
70
+ manager.on("playerDestroy", onPlayerDestroy);
71
+ }
72
+ unload(manager) {
73
+ for (const [event, listener] of this.boundListeners) {
74
+ manager.off(event, listener);
75
+ }
76
+ this.boundListeners.clear();
77
+ this.autoplayCounters.clear();
78
+ }
79
+ /**
80
+ * Default autoplay strategy: search YouTube for related content based on the last track.
81
+ */
82
+ async defaultStrategy(player, lastTrack, manager) {
83
+ // Build a search query from the last track's metadata
84
+ const title = lastTrack.info?.title ?? "";
85
+ const author = lastTrack.info?.author ?? "";
86
+ const query = `${title} ${author}`.trim();
87
+ if (!query)
88
+ return null;
89
+ const result = await manager.search(query, {
90
+ source: "youtube",
91
+ requester: lastTrack.requester,
92
+ });
93
+ if (!result.tracks || result.tracks.length === 0)
94
+ return null;
95
+ // Find a track that's different from the last one played
96
+ const different = result.tracks.find((t) => t.encoded !== lastTrack.encoded && t.info?.identifier !== lastTrack.info?.identifier);
97
+ // Also check it's not in the previous history
98
+ const notInHistory = different
99
+ ? !player.queue.previous.some((p) => p.encoded === different.encoded)
100
+ : false;
101
+ if (different && notInHistory)
102
+ return different;
103
+ // Fallback: return the second result if available
104
+ return result.tracks[1] ?? result.tracks[0] ?? null;
105
+ }
106
+ sleep(ms) {
107
+ return new Promise((resolve) => setTimeout(resolve, ms));
108
+ }
109
+ }
110
+ exports.AutoplayPlugin = AutoplayPlugin;
111
+ //# sourceMappingURL=AutoplayPlugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AutoplayPlugin.js","sourceRoot":"","sources":["../../src/plugins/AutoplayPlugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /** Yukimu v2.0.0 — Inactivity Plugin */
2
+ import { Plugin } from "../Plugin";
3
+ import type { Yukimu } from "../Yukimu";
4
+ export interface InactivityOptions {
5
+ /** Time in ms before auto-disconnecting on inactivity (default: 300000 = 5 min) */
6
+ timeout?: number;
7
+ /** What counts as inactivity: "idle" = no playback, "empty" = empty voice channel */
8
+ trigger?: "idle" | "empty" | "both";
9
+ /** Whether to send a message before disconnecting (emits "inactivityTimeout" event) */
10
+ notify?: boolean;
11
+ }
12
+ /**
13
+ * Auto-disconnects players after a period of inactivity.
14
+ *
15
+ * Monitors:
16
+ * - "idle" mode: Disconnects when nothing is playing for the configured timeout
17
+ * - "empty" mode: Disconnects when the voice channel is empty (bot alone)
18
+ * - "both" mode: Disconnects on either condition
19
+ */
20
+ export declare class InactivityPlugin extends Plugin {
21
+ readonly name = "Inactivity";
22
+ private readonly options;
23
+ private timers;
24
+ private boundListeners;
25
+ constructor(options?: InactivityOptions);
26
+ load(manager: Yukimu): void;
27
+ unload(manager: Yukimu): void;
28
+ private clearTimer;
29
+ }
30
+ //# sourceMappingURL=InactivityPlugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InactivityPlugin.d.ts","sourceRoot":"","sources":["../../src/plugins/InactivityPlugin.ts"],"names":[],"mappings":"AAAA,wCAAwC;AAExC,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAGxC,MAAM,WAAW,iBAAiB;IAChC,mFAAmF;IACnF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qFAAqF;IACrF,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IACpC,uFAAuF;IACvF,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;GAOG;AACH,qBAAa,gBAAiB,SAAQ,MAAM;IAC1C,SAAgB,IAAI,gBAAgB;IACpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8B;IACtD,OAAO,CAAC,MAAM,CAAyD;IACvE,OAAO,CAAC,cAAc,CAAoD;gBAE9D,OAAO,GAAE,iBAAsB;IASpC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAkD3B,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAYpC,OAAO,CAAC,UAAU;CAOnB"}
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ /** Yukimu v2.0.0 — Inactivity Plugin */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.InactivityPlugin = void 0;
5
+ const Plugin_1 = require("../Plugin");
6
+ /**
7
+ * Auto-disconnects players after a period of inactivity.
8
+ *
9
+ * Monitors:
10
+ * - "idle" mode: Disconnects when nothing is playing for the configured timeout
11
+ * - "empty" mode: Disconnects when the voice channel is empty (bot alone)
12
+ * - "both" mode: Disconnects on either condition
13
+ */
14
+ class InactivityPlugin extends Plugin_1.Plugin {
15
+ name = "Inactivity";
16
+ options;
17
+ timers = new Map();
18
+ boundListeners = new Map();
19
+ constructor(options = {}) {
20
+ super();
21
+ this.options = {
22
+ timeout: options.timeout ?? 300_000, // 5 minutes
23
+ trigger: options.trigger ?? "idle",
24
+ notify: options.notify ?? true,
25
+ };
26
+ }
27
+ load(manager) {
28
+ const startTimer = (player) => {
29
+ this.clearTimer(player.guildId);
30
+ this.timers.set(player.guildId, setTimeout(() => {
31
+ const currentPlayer = manager.players.get(player.guildId);
32
+ if (!currentPlayer)
33
+ return;
34
+ manager.logger.info(`[Inactivity] Auto-disconnecting guild ${player.guildId} after ${this.options.timeout}ms of inactivity`);
35
+ manager.destroyPlayer(player.guildId).catch(() => { });
36
+ }, this.options.timeout));
37
+ };
38
+ const onQueueEnd = (player) => {
39
+ if (this.options.trigger === "idle" || this.options.trigger === "both") {
40
+ startTimer(player);
41
+ }
42
+ };
43
+ const onTrackStart = (player) => {
44
+ // Cancel inactivity timer when a track starts playing
45
+ this.clearTimer(player.guildId);
46
+ };
47
+ const onPlayerCreate = (player) => {
48
+ // Start timer for new players that don't have anything playing
49
+ if (!player.playing) {
50
+ if (this.options.trigger === "idle" || this.options.trigger === "both") {
51
+ startTimer(player);
52
+ }
53
+ }
54
+ };
55
+ const onPlayerDestroy = (player) => {
56
+ this.clearTimer(player.guildId);
57
+ };
58
+ this.boundListeners.set("queueEnd", onQueueEnd);
59
+ this.boundListeners.set("trackStart", onTrackStart);
60
+ this.boundListeners.set("playerCreate", onPlayerCreate);
61
+ this.boundListeners.set("playerDestroy", onPlayerDestroy);
62
+ manager.on("queueEnd", onQueueEnd);
63
+ manager.on("trackStart", onTrackStart);
64
+ manager.on("playerCreate", onPlayerCreate);
65
+ manager.on("playerDestroy", onPlayerDestroy);
66
+ }
67
+ unload(manager) {
68
+ for (const [event, listener] of this.boundListeners) {
69
+ manager.off(event, listener);
70
+ }
71
+ this.boundListeners.clear();
72
+ for (const timer of this.timers.values()) {
73
+ clearTimeout(timer);
74
+ }
75
+ this.timers.clear();
76
+ }
77
+ clearTimer(guildId) {
78
+ const existing = this.timers.get(guildId);
79
+ if (existing) {
80
+ clearTimeout(existing);
81
+ this.timers.delete(guildId);
82
+ }
83
+ }
84
+ }
85
+ exports.InactivityPlugin = InactivityPlugin;
86
+ //# sourceMappingURL=InactivityPlugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InactivityPlugin.js","sourceRoot":"","sources":["../../src/plugins/InactivityPlugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /** Yukimu v2.0.0 — PlayerMoved Plugin */
2
+ import { Plugin } from "../Plugin";
3
+ import type { Yukimu } from "../Yukimu";
4
+ export interface PlayerMovedOptions {
5
+ /** What to do when the bot is disconnected from voice (default: "destroy") */
6
+ onDisconnect?: "destroy" | "pause" | "none";
7
+ /** What to do on voice socket close codes 4014/4006 (default: "destroy") */
8
+ onSocketClose?: "destroy" | "pause" | "none";
9
+ /** Additional close codes to handle (default: [4014, 4006]) */
10
+ closeCodes?: number[];
11
+ }
12
+ /**
13
+ * Handles player behavior when the bot is moved between channels
14
+ * or disconnected from voice.
15
+ *
16
+ * Improvements from v1:
17
+ * - Configurable behavior (destroy, pause, or ignore)
18
+ * - Handles additional close codes (4015 for voice server crash)
19
+ * - Proper unload() with listener cleanup
20
+ */
21
+ export declare class PlayerMoved extends Plugin {
22
+ readonly name = "PlayerMoved";
23
+ private readonly options;
24
+ private boundListeners;
25
+ constructor(options?: PlayerMovedOptions);
26
+ load(manager: Yukimu): void;
27
+ unload(manager: Yukimu): void;
28
+ }
29
+ //# sourceMappingURL=PlayerMoved.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlayerMoved.d.ts","sourceRoot":"","sources":["../../src/plugins/PlayerMoved.ts"],"names":[],"mappings":"AAAA,yCAAyC;AAEzC,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAGxC,MAAM,WAAW,kBAAkB;IACjC,8EAA8E;IAC9E,YAAY,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;IAC5C,4EAA4E;IAC5E,aAAa,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;IAC7C,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,qBAAa,WAAY,SAAQ,MAAM;IACrC,SAAgB,IAAI,iBAAiB;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA+B;IACvD,OAAO,CAAC,cAAc,CAAoD;gBAE9D,OAAO,GAAE,kBAAuB;IASrC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IA4C3B,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;CAMrC"}
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ /** Yukimu v2.0.0 — PlayerMoved Plugin */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.PlayerMoved = void 0;
5
+ const Plugin_1 = require("../Plugin");
6
+ /**
7
+ * Handles player behavior when the bot is moved between channels
8
+ * or disconnected from voice.
9
+ *
10
+ * Improvements from v1:
11
+ * - Configurable behavior (destroy, pause, or ignore)
12
+ * - Handles additional close codes (4015 for voice server crash)
13
+ * - Proper unload() with listener cleanup
14
+ */
15
+ class PlayerMoved extends Plugin_1.Plugin {
16
+ name = "PlayerMoved";
17
+ options;
18
+ boundListeners = new Map();
19
+ constructor(options = {}) {
20
+ super();
21
+ this.options = {
22
+ onDisconnect: options.onDisconnect ?? "destroy",
23
+ onSocketClose: options.onSocketClose ?? "destroy",
24
+ closeCodes: options.closeCodes ?? [4014, 4006, 4015],
25
+ };
26
+ }
27
+ load(manager) {
28
+ const onPlayerMove = async (player, _oldChannel, newChannel) => {
29
+ if (!newChannel) {
30
+ // Bot was disconnected from voice
31
+ switch (this.options.onDisconnect) {
32
+ case "destroy":
33
+ await manager.destroyPlayer(player.guildId).catch(() => { });
34
+ break;
35
+ case "pause":
36
+ await player.pause(true).catch(() => { });
37
+ break;
38
+ case "none":
39
+ break;
40
+ }
41
+ return;
42
+ }
43
+ // Bot was moved to a different channel — update is already handled by Yukimu
44
+ player.voiceChannelId = newChannel;
45
+ };
46
+ const onSocketClosed = async (player, code, _reason, _byRemote) => {
47
+ if (this.options.closeCodes.includes(code)) {
48
+ switch (this.options.onSocketClose) {
49
+ case "destroy":
50
+ manager.logger.info(`[PlayerMoved] Destroying player for guild ${player.guildId} (socket closed: ${code})`);
51
+ await manager.destroyPlayer(player.guildId).catch(() => { });
52
+ break;
53
+ case "pause":
54
+ manager.logger.info(`[PlayerMoved] Pausing player for guild ${player.guildId} (socket closed: ${code})`);
55
+ await player.pause(true).catch(() => { });
56
+ break;
57
+ case "none":
58
+ break;
59
+ }
60
+ }
61
+ };
62
+ this.boundListeners.set("playerMove", onPlayerMove);
63
+ this.boundListeners.set("socketClosed", onSocketClosed);
64
+ manager.on("playerMove", onPlayerMove);
65
+ manager.on("socketClosed", onSocketClosed);
66
+ }
67
+ unload(manager) {
68
+ for (const [event, listener] of this.boundListeners) {
69
+ manager.off(event, listener);
70
+ }
71
+ this.boundListeners.clear();
72
+ }
73
+ }
74
+ exports.PlayerMoved = PlayerMoved;
75
+ //# sourceMappingURL=PlayerMoved.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlayerMoved.js","sourceRoot":"","sources":["../../src/plugins/PlayerMoved.ts"],"names":[],"mappings":"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"}