diff --git a/src/client/Client.js b/src/client/Client.js index b1dc15573..10272aeee 100644 --- a/src/client/Client.js +++ b/src/client/Client.js @@ -144,12 +144,6 @@ class Client extends BaseClient { */ this.readyAt = null; - /** - * Active voice broadcasts that have been created - * @type {VoiceBroadcast[]} - */ - this.broadcasts = []; - if (this.options.messageSweepInterval > 0) { this.setInterval(this.sweepMessages.bind(this), this.options.messageSweepInterval * 1000); } @@ -196,16 +190,6 @@ class Client extends BaseClient { return this.readyAt ? Date.now() - this.readyAt : null; } - /** - * Creates a voice broadcast. - * @returns {VoiceBroadcast} - */ - createVoiceBroadcast() { - const broadcast = new VoiceBroadcast(this); - this.broadcasts.push(broadcast); - return broadcast; - } - /** * Logs the client in, establishing a websocket connection to Discord. * @param {string} token Token of the account to log in with @@ -390,7 +374,6 @@ class Client extends BaseClient { toJSON() { return super.toJSON({ readyAt: false, - broadcasts: false, presences: false, }); } diff --git a/src/client/voice/ClientVoiceManager.js b/src/client/voice/ClientVoiceManager.js index 466b6d664..ba1e2a253 100644 --- a/src/client/voice/ClientVoiceManager.js +++ b/src/client/voice/ClientVoiceManager.js @@ -3,10 +3,11 @@ const Collection = require('../../util/Collection'); const { VoiceStatus } = require('../../util/Constants'); const VoiceConnection = require('./VoiceConnection'); +const VoiceBroadcast = require('./VoiceBroadcast'); const { Error } = require('../../errors'); /** - * Manages all the voice stuff for the client. + * Manages voice connections for the client * @private */ class ClientVoiceManager { @@ -22,6 +23,22 @@ class ClientVoiceManager { * @type {Collection} */ this.connections = new Collection(); + + /** + * Active voice broadcasts that have been created + * @type {VoiceBroadcast[]} + */ + this.broadcasts = []; + } + + /** + * Creates a voice broadcast. + * @returns {VoiceBroadcast} + */ + createVoiceBroadcast() { + const broadcast = new VoiceBroadcast(this); + this.broadcasts.push(broadcast); + return broadcast; } onVoiceServer({ guild_id, token, endpoint }) { @@ -46,6 +63,7 @@ class ClientVoiceManager { * Sets up a request to join a voice channel. * @param {VoiceChannel} channel The voice channel to join * @returns {Promise} + * @private */ joinChannel(channel) { return new Promise((resolve, reject) => { diff --git a/src/client/voice/VoiceBroadcast.js b/src/client/voice/VoiceBroadcast.js index 870798dd8..6cb2bcd14 100644 --- a/src/client/voice/VoiceBroadcast.js +++ b/src/client/voice/VoiceBroadcast.js @@ -2,7 +2,7 @@ const EventEmitter = require('events'); const BroadcastAudioPlayer = require('./player/BroadcastAudioPlayer'); -const DispatcherSet = require('./util/DispatcherSet'); +const { Events } = require('../../util/Constants'); const PlayInterface = require('./util/PlayInterface'); /** @@ -29,9 +29,9 @@ class VoiceBroadcast extends EventEmitter { this.client = client; /** * The dispatchers playing this broadcast - * @type {Set} + * @type {StreamDispatcher[]} */ - this.dispatchers = new DispatcherSet(this); + this.dispatchers = []; this.player = new BroadcastAudioPlayer(this); } @@ -60,6 +60,35 @@ class VoiceBroadcast extends EventEmitter { * @returns {BroadcastDispatcher} */ play() { return null; } + + add(dispatcher) { + const index = this.dispatchers.indexOf(dispatcher); + if (index === -1) { + /** + * Emitted whenever a stream dispatcher subscribes to the broadcast. + * @event VoiceBroadcast#subscribe + * @param {StreamDispatcher} dispatcher The subscribed dispatcher + */ + this.broadcast.emit(Events.VOICE_BROADCAST_SUBSCRIBE, dispatcher); + return true; + } else { + return false; + } + } + + delete(dispatcher) { + const index = this.dispatchers.indexOf(dispatcher); + if (index !== -1) { + /** + * Emitted whenever a stream dispatcher unsubscribes to the broadcast. + * @event VoiceBroadcast#unsubscribe + * @param {StreamDispatcher} dispatcher The unsubscribed dispatcher + */ + this.broadcast.emit(Events.VOICE_BROADCAST_UNSUBSCRIBE, dispatcher); + return true; + } + return false; + } } PlayInterface.applyToClass(VoiceBroadcast); diff --git a/src/client/voice/dispatcher/StreamDispatcher.js b/src/client/voice/dispatcher/StreamDispatcher.js index 71e6e1611..340e40c5d 100644 --- a/src/client/voice/dispatcher/StreamDispatcher.js +++ b/src/client/voice/dispatcher/StreamDispatcher.js @@ -122,7 +122,7 @@ class StreamDispatcher extends Writable { _cleanup() { if (this.player.dispatcher === this) this.player.dispatcher = null; const { streams } = this; - if (streams.broadcast) streams.broadcast.dispatchers.delete(this); + if (streams.broadcast) streams.broadcast.delete(this); if (streams.opus) streams.opus.destroy(); if (streams.ffmpeg) streams.ffmpeg.destroy(); } diff --git a/src/client/voice/player/AudioPlayer.js b/src/client/voice/player/AudioPlayer.js index 3ce94d815..6f719a730 100644 --- a/src/client/voice/player/AudioPlayer.js +++ b/src/client/voice/player/AudioPlayer.js @@ -19,7 +19,7 @@ class AudioPlayer extends BasePlayer { playBroadcast(broadcast, options) { const dispatcher = this.createDispatcher(options, { broadcast }); - broadcast.dispatchers.add(dispatcher); + broadcast.add(dispatcher); return dispatcher; } }