buddy

node MVC discord bot
Log | Files | Refs | README

ClientVoiceManager.js (3283B)


      1 'use strict';
      2 
      3 const VoiceBroadcast = require('./VoiceBroadcast');
      4 const VoiceConnection = require('./VoiceConnection');
      5 const { Error } = require('../../errors');
      6 const Collection = require('../../util/Collection');
      7 
      8 /**
      9  * Manages voice connections for the client
     10  */
     11 class ClientVoiceManager {
     12   constructor(client) {
     13     /**
     14      * The client that instantiated this voice manager
     15      * @type {Client}
     16      * @readonly
     17      * @name ClientVoiceManager#client
     18      */
     19     Object.defineProperty(this, 'client', { value: client });
     20 
     21     /**
     22      * A collection mapping connection IDs to the Connection objects
     23      * @type {Collection<Snowflake, VoiceConnection>}
     24      */
     25     this.connections = new Collection();
     26 
     27     /**
     28      * Active voice broadcasts that have been created
     29      * @type {VoiceBroadcast[]}
     30      */
     31     this.broadcasts = [];
     32   }
     33 
     34   /**
     35    * Creates a voice broadcast.
     36    * @returns {VoiceBroadcast}
     37    */
     38   createBroadcast() {
     39     const broadcast = new VoiceBroadcast(this.client);
     40     this.broadcasts.push(broadcast);
     41     return broadcast;
     42   }
     43 
     44   onVoiceServer({ guild_id, token, endpoint }) {
     45     this.client.emit('debug', `[VOICE] voiceServer guild: ${guild_id} token: ${token} endpoint: ${endpoint}`);
     46     const connection = this.connections.get(guild_id);
     47     if (connection) connection.setTokenAndEndpoint(token, endpoint);
     48   }
     49 
     50   onVoiceStateUpdate({ guild_id, session_id, channel_id }) {
     51     const connection = this.connections.get(guild_id);
     52     this.client.emit('debug', `[VOICE] connection? ${!!connection}, ${guild_id} ${session_id} ${channel_id}`);
     53     if (!connection) return;
     54     if (!channel_id) {
     55       connection._disconnect();
     56       this.connections.delete(guild_id);
     57       return;
     58     }
     59     connection.channel = this.client.channels.cache.get(channel_id);
     60     connection.setSessionID(session_id);
     61   }
     62 
     63   /**
     64    * Sets up a request to join a voice channel.
     65    * @param {VoiceChannel} channel The voice channel to join
     66    * @returns {Promise<VoiceConnection>}
     67    * @private
     68    */
     69   joinChannel(channel) {
     70     return new Promise((resolve, reject) => {
     71       if (!channel.joinable) {
     72         throw new Error('VOICE_JOIN_CHANNEL', channel.full);
     73       }
     74 
     75       let connection = this.connections.get(channel.guild.id);
     76 
     77       if (connection) {
     78         if (connection.channel.id !== channel.id) {
     79           this.connections.get(channel.guild.id).updateChannel(channel);
     80         }
     81         resolve(connection);
     82         return;
     83       } else {
     84         connection = new VoiceConnection(this, channel);
     85         connection.on('debug', msg =>
     86           this.client.emit('debug', `[VOICE (${channel.guild.id}:${connection.status})]: ${msg}`),
     87         );
     88         connection.authenticate();
     89         this.connections.set(channel.guild.id, connection);
     90       }
     91 
     92       connection.once('failed', reason => {
     93         this.connections.delete(channel.guild.id);
     94         reject(reason);
     95       });
     96 
     97       connection.on('error', reject);
     98 
     99       connection.once('authenticated', () => {
    100         connection.once('ready', () => {
    101           resolve(connection);
    102           connection.removeListener('error', reject);
    103         });
    104         connection.once('disconnect', () => this.connections.delete(channel.guild.id));
    105       });
    106     });
    107   }
    108 }
    109 
    110 module.exports = ClientVoiceManager;