diff options
| author | Alee14 <Alee14498@gmail.com> | 2017-07-28 16:20:27 -0400 |
|---|---|---|
| committer | Alee14 <Alee14498@gmail.com> | 2017-07-28 16:20:27 -0400 |
| commit | d35e0862e6b60fe3c4f823371627359f3ce3e68b (patch) | |
| tree | d98b788eb1abf0a8814207b993b4e22efe711deb /node_modules/discord.js/src/client/voice | |
| parent | 20993df62e7e38ed43428aafa5981afc3543bdea (diff) | |
| download | AleeBot-d35e0862e6b60fe3c4f823371627359f3ce3e68b.tar.gz AleeBot-d35e0862e6b60fe3c4f823371627359f3ce3e68b.tar.bz2 AleeBot-d35e0862e6b60fe3c4f823371627359f3ce3e68b.zip | |
Removing node modules (go get them yourself :P)
Diffstat (limited to 'node_modules/discord.js/src/client/voice')
18 files changed, 0 insertions, 1825 deletions
diff --git a/node_modules/discord.js/src/client/voice/ClientVoiceManager.js b/node_modules/discord.js/src/client/voice/ClientVoiceManager.js deleted file mode 100644 index ea83745..0000000 --- a/node_modules/discord.js/src/client/voice/ClientVoiceManager.js +++ /dev/null @@ -1,245 +0,0 @@ -const Collection = require('../../util/Collection'); -const mergeDefault = require('../../util/MergeDefault'); -const Constants = require('../../util/Constants'); -const VoiceConnection = require('./VoiceConnection'); -const EventEmitter = require('events').EventEmitter; - -/** - * Manages all the voice stuff for the Client - * @private - */ -class ClientVoiceManager { - constructor(client) { - /** - * The client that instantiated this voice manager - * @type {Client} - */ - this.client = client; - - /** - * A collection mapping connection IDs to the Connection objects - * @type {Collection<string, VoiceConnection>} - */ - this.connections = new Collection(); - - /** - * Pending connection attempts, maps guild ID to VoiceChannel - * @type {Collection<string, VoiceChannel>} - */ - this.pending = new Collection(); - - this.client.on('self.voiceServer', this.onVoiceServer.bind(this)); - this.client.on('self.voiceStateUpdate', this.onVoiceStateUpdate.bind(this)); - } - - onVoiceServer(data) { - if (this.pending.has(data.guild_id)) this.pending.get(data.guild_id).setTokenAndEndpoint(data.token, data.endpoint); - } - - onVoiceStateUpdate(data) { - if (this.pending.has(data.guild_id)) this.pending.get(data.guild_id).setSessionID(data.session_id); - } - - /** - * Sends a request to the main gateway to join a voice channel - * @param {VoiceChannel} channel The channel to join - * @param {Object} [options] The options to provide - */ - sendVoiceStateUpdate(channel, options = {}) { - if (!this.client.user) throw new Error('Unable to join because there is no client user.'); - if (!channel.permissionsFor) { - throw new Error('Channel does not support permissionsFor; is it really a voice channel?'); - } - const permissions = channel.permissionsFor(this.client.user); - if (!permissions) { - throw new Error('There is no permission set for the client user in this channel - are they part of the guild?'); - } - if (!permissions.hasPermission('CONNECT')) { - throw new Error('You do not have permission to join this voice channel.'); - } - - options = mergeDefault({ - guild_id: channel.guild.id, - channel_id: channel.id, - self_mute: false, - self_deaf: false, - }, options); - - this.client.ws.send({ - op: Constants.OPCodes.VOICE_STATE_UPDATE, - d: options, - }); - } - - /** - * Sets up a request to join a voice channel - * @param {VoiceChannel} channel The voice channel to join - * @returns {Promise<VoiceConnection>} - */ - joinChannel(channel) { - return new Promise((resolve, reject) => { - if (this.pending.get(channel.guild.id)) throw new Error('Already connecting to this guild\'s voice server.'); - if (!channel.joinable) throw new Error('You do not have permission to join this voice channel.'); - - const existingConnection = this.connections.get(channel.guild.id); - if (existingConnection) { - if (existingConnection.channel.id !== channel.id) { - this.sendVoiceStateUpdate(channel); - this.connections.get(channel.guild.id).channel = channel; - } - resolve(existingConnection); - return; - } - - const pendingConnection = new PendingVoiceConnection(this, channel); - this.pending.set(channel.guild.id, pendingConnection); - - pendingConnection.on('fail', reason => { - this.pending.delete(channel.guild.id); - reject(reason); - }); - - pendingConnection.on('pass', voiceConnection => { - this.pending.delete(channel.guild.id); - this.connections.set(channel.guild.id, voiceConnection); - voiceConnection.once('ready', () => resolve(voiceConnection)); - voiceConnection.once('error', reject); - voiceConnection.once('disconnect', () => this.connections.delete(channel.guild.id)); - }); - }); - } -} - -/** - * Represents a Pending Voice Connection - * @private - */ -class PendingVoiceConnection extends EventEmitter { - constructor(voiceManager, channel) { - super(); - - /** - * The ClientVoiceManager that instantiated this pending connection - * @type {ClientVoiceManager} - */ - this.voiceManager = voiceManager; - - /** - * The channel that this pending voice connection will attempt to join - * @type {VoiceChannel} - */ - this.channel = channel; - - /** - * The timeout that will be invoked after 15 seconds signifying a failure to connect - * @type {Timeout} - */ - this.deathTimer = this.voiceManager.client.setTimeout( - () => this.fail(new Error('Connection not established within 15 seconds.')), 15000); - - /** - * An object containing data required to connect to the voice servers with - * @type {Object} - */ - this.data = {}; - - this.sendVoiceStateUpdate(); - } - - checkReady() { - if (this.data.token && this.data.endpoint && this.data.session_id) { - this.pass(); - return true; - } else { - return false; - } - } - - /** - * Set the token and endpoint required to connect to the the voice servers - * @param {string} token the token - * @param {string} endpoint the endpoint - * @returns {void} - */ - setTokenAndEndpoint(token, endpoint) { - if (!token) { - this.fail(new Error('Token not provided from voice server packet.')); - return; - } - if (!endpoint) { - this.fail(new Error('Endpoint not provided from voice server packet.')); - return; - } - if (this.data.token) { - this.fail(new Error('There is already a registered token for this connection.')); - return; - } - if (this.data.endpoint) { - this.fail(new Error('There is already a registered endpoint for this connection.')); - return; - } - - endpoint = endpoint.match(/([^:]*)/)[0]; - - if (!endpoint) { - this.fail(new Error('Failed to find an endpoint.')); - return; - } - - this.data.token = token; - this.data.endpoint = endpoint; - - this.checkReady(); - } - - /** - * Sets the Session ID for the connection - * @param {string} sessionID the session ID - */ - setSessionID(sessionID) { - if (!sessionID) { - this.fail(new Error('Session ID not supplied.')); - return; - } - if (this.data.session_id) { - this.fail(new Error('There is already a registered session ID for this connection.')); - return; - } - this.data.session_id = sessionID; - - this.checkReady(); - } - - clean() { - clearInterval(this.deathTimer); - this.emit('fail', new Error('Clean-up triggered :fourTriggered:')); - } - - pass() { - clearInterval(this.deathTimer); - this.emit('pass', this.upgrade()); - } - - fail(reason) { - this.emit('fail', reason); - this.clean(); - } - - sendVoiceStateUpdate() { - try { - this.voiceManager.sendVoiceStateUpdate(this.channel); - } catch (error) { - this.fail(error); - } - } - - /** - * Upgrades this Pending Connection to a full Voice Connection - * @returns {VoiceConnection} - */ - upgrade() { - return new VoiceConnection(this); - } -} - -module.exports = ClientVoiceManager; diff --git a/node_modules/discord.js/src/client/voice/VoiceConnection.js b/node_modules/discord.js/src/client/voice/VoiceConnection.js deleted file mode 100644 index ac44ff8..0000000 --- a/node_modules/discord.js/src/client/voice/VoiceConnection.js +++ /dev/null @@ -1,276 +0,0 @@ -const VoiceWebSocket = require('./VoiceWebSocket'); -const VoiceUDP = require('./VoiceUDPClient'); -const Constants = require('../../util/Constants'); -const AudioPlayer = require('./player/AudioPlayer'); -const VoiceReceiver = require('./receiver/VoiceReceiver'); -const EventEmitter = require('events').EventEmitter; -const fs = require('fs'); - -/** - * Represents a connection to a voice channel in Discord. - * ```js - * // obtained using: - * voiceChannel.join().then(connection => { - * - * }); - * ``` - * @extends {EventEmitter} - */ -class VoiceConnection extends EventEmitter { - constructor(pendingConnection) { - super(); - - /** - * The Voice Manager that instantiated this connection - * @type {ClientVoiceManager} - */ - this.voiceManager = pendingConnection.voiceManager; - - /** - * The voice channel this connection is currently serving - * @type {VoiceChannel} - */ - this.channel = pendingConnection.channel; - - /** - * Whether we're currently transmitting audio - * @type {boolean} - */ - this.speaking = false; - - /** - * An array of Voice Receivers that have been created for this connection - * @type {VoiceReceiver[]} - */ - this.receivers = []; - - /** - * The authentication data needed to connect to the voice server - * @type {Object} - * @private - */ - this.authentication = pendingConnection.data; - - /** - * The audio player for this voice connection - * @type {AudioPlayer} - */ - this.player = new AudioPlayer(this); - - this.player.on('debug', m => { - /** - * Debug info from the connection - * @event VoiceConnection#debug - * @param {string} message the debug message - */ - this.emit('debug', `audio player - ${m}`); - }); - - this.player.on('error', e => { - /** - * Warning info from the connection - * @event VoiceConnection#warn - * @param {string|Error} warning the warning - */ - this.emit('warn', e); - this.player.cleanup(); - }); - - /** - * Map SSRC to speaking values - * @type {Map<number, boolean>} - * @private - */ - this.ssrcMap = new Map(); - - /** - * Whether this connection is ready - * @type {boolean} - * @private - */ - this.ready = false; - - /** - * Object that wraps contains the `ws` and `udp` sockets of this voice connection - * @type {Object} - * @private - */ - this.sockets = {}; - this.connect(); - } - - /** - * Sets whether the voice connection should display as "speaking" or not - * @param {boolean} value whether or not to speak - * @private - */ - setSpeaking(value) { - if (this.speaking === value) return; - this.speaking = value; - this.sockets.ws.sendPacket({ - op: Constants.VoiceOPCodes.SPEAKING, - d: { - speaking: true, - delay: 0, - }, - }).catch(e => { - this.emit('debug', e); - }); - } - - /** - * Disconnect the voice connection, causing a disconnect and closing event to be emitted. - */ - disconnect() { - this.emit('closing'); - this.voiceManager.client.ws.send({ - op: Constants.OPCodes.VOICE_STATE_UPDATE, - d: { - guild_id: this.channel.guild.id, - channel_id: null, - self_mute: false, - self_deaf: false, - }, - }); - /** - * Emitted when the voice connection disconnects - * @event VoiceConnection#disconnect - */ - this.emit('disconnect'); - } - - /** - * Connect the voice connection - * @private - */ - connect() { - if (this.sockets.ws) throw new Error('There is already an existing WebSocket connection.'); - if (this.sockets.udp) throw new Error('There is already an existing UDP connection.'); - this.sockets.ws = new VoiceWebSocket(this); - this.sockets.udp = new VoiceUDP(this); - this.sockets.ws.on('error', e => this.emit('error', e)); - this.sockets.udp.on('error', e => this.emit('error', e)); - this.sockets.ws.once('ready', d => { - this.authentication.port = d.port; - this.authentication.ssrc = d.ssrc; - /** - * Emitted whenever the connection encounters an error. - * @event VoiceConnection#error - * @param {Error} error the encountered error - */ - this.sockets.udp.findEndpointAddress() - .then(address => { - this.sockets.udp.createUDPSocket(address); - }, e => this.emit('error', e)); - }); - this.sockets.ws.once('sessionDescription', (mode, secret) => { - this.authentication.encryptionMode = mode; - this.authentication.secretKey = secret; - /** - * Emitted once the connection is ready, when a promise to join a voice channel resolves, - * the connection will already be ready. - * @event VoiceConnection#ready - */ - this.emit('ready'); - this.ready = true; - }); - this.sockets.ws.on('speaking', data => { - const guild = this.channel.guild; - const user = this.voiceManager.client.users.get(data.user_id); - this.ssrcMap.set(+data.ssrc, user); - if (!data.speaking) { - for (const receiver of this.receivers) { - const opusStream = receiver.opusStreams.get(user.id); - const pcmStream = receiver.pcmStreams.get(user.id); - if (opusStream) { - opusStream.push(null); - opusStream.open = false; - receiver.opusStreams.delete(user.id); - } - if (pcmStream) { - pcmStream.push(null); - pcmStream.open = false; - receiver.pcmStreams.delete(user.id); - } - } - } - /** - * Emitted whenever a user starts/stops speaking - * @event VoiceConnection#speaking - * @param {User} user The user that has started/stopped speaking - * @param {boolean} speaking Whether or not the user is speaking - */ - if (this.ready) this.emit('speaking', user, data.speaking); - guild._memberSpeakUpdate(data.user_id, data.speaking); - }); - } - - /** - * Options that can be passed to stream-playing methods: - * @typedef {Object} StreamOptions - * @property {number} [seek=0] The time to seek to - * @property {number} [volume=1] The volume to play at - * @property {number} [passes=1] How many times to send the voice packet to reduce packet loss - */ - - /** - * Play the given file in the voice connection. - * @param {string} file The path to the file - * @param {StreamOptions} [options] Options for playing the stream - * @returns {StreamDispatcher} - * @example - * // play files natively - * voiceChannel.join() - * .then(connection => { - * const dispatcher = connection.playFile('C:/Users/Discord/Desktop/music.mp3'); - * }) - * .catch(console.error); - */ - playFile(file, options) { - return this.playStream(fs.createReadStream(file), options); - } - - /** - * Plays and converts an audio stream in the voice connection. - * @param {ReadableStream} stream The audio stream to play - * @param {StreamOptions} [options] Options for playing the stream - * @returns {StreamDispatcher} - * @example - * // play streams using ytdl-core - * const ytdl = require('ytdl-core'); - * const streamOptions = { seek: 0, volume: 1 }; - * voiceChannel.join() - * .then(connection => { - * const stream = ytdl('https://www.youtube.com/watch?v=XAWgeLF9EVQ', {filter : 'audioonly'}); - * const dispatcher = connection.playStream(stream, streamOptions); - * }) - * .catch(console.error); - */ - playStream(stream, { seek = 0, volume = 1, passes = 1 } = {}) { - const options = { seek, volume, passes }; - return this.player.playUnknownStream(stream, options); - } - - /** - * Plays a stream of 16-bit signed stereo PCM at 48KHz. - * @param {ReadableStream} stream The audio stream to play. - * @param {StreamOptions} [options] Options for playing the stream - * @returns {StreamDispatcher} - */ - playConvertedStream(stream, { seek = 0, volume = 1, passes = 1 } = {}) { - const options = { seek, volume, passes }; - return this.player.playPCMStream(stream, null, options); - } - - /** - * Creates a VoiceReceiver so you can start listening to voice data. It's recommended to only create one of these. - * @returns {VoiceReceiver} - */ - createReceiver() { - const receiver = new VoiceReceiver(this); - this.receivers.push(receiver); - return receiver; - } -} - -module.exports = VoiceConnection; diff --git a/node_modules/discord.js/src/client/voice/VoiceUDPClient.js b/node_modules/discord.js/src/client/voice/VoiceUDPClient.js deleted file mode 100644 index b7b0c0c..0000000 --- a/node_modules/discord.js/src/client/voice/VoiceUDPClient.js +++ /dev/null @@ -1,145 +0,0 @@ -const udp = require('dgram'); -const dns = require('dns'); -const Constants = require('../../util/Constants'); -const EventEmitter = require('events').EventEmitter; - -/** - * Represents a UDP Client for a Voice Connection - * @extends {EventEmitter} - * @private - */ -class VoiceConnectionUDPClient extends EventEmitter { - constructor(voiceConnection) { - super(); - - /** - * The voice connection that this UDP client serves - * @type {VoiceConnection} - */ - this.voiceConnection = voiceConnection; - - /** - * The UDP socket - * @type {?Socket} - */ - this.socket = null; - - /** - * The address of the discord voice server - * @type {?string} - */ - this.discordAddress = null; - - /** - * The local IP address - * @type {?string} - */ - this.localAddress = null; - - /** - * The local port - * @type {?string} - */ - this.localPort = null; - - this.voiceConnection.on('closing', this.shutdown.bind(this)); - } - - shutdown() { - if (this.socket) { - try { - this.socket.close(); - } catch (e) { - return; - } - this.socket = null; - } - } - - /** - * The port of the discord voice server - * @type {number} - * @readonly - */ - get discordPort() { - return this.voiceConnection.authentication.port; - } - - /** - * Tries to resolve the voice server endpoint to an address - * @returns {Promise<string>} - */ - findEndpointAddress() { - return new Promise((resolve, reject) => { - dns.lookup(this.voiceConnection.authentication.endpoint, (error, address) => { - if (error) { - reject(error); - return; - } - this.discordAddress = address; - resolve(address); - }); - }); - } - - /** - * Send a packet to the UDP client - * @param {Object} packet the packet to send - * @returns {Promise<Object>} - */ - send(packet) { - return new Promise((resolve, reject) => { - if (!this.socket) throw new Error('Tried to send a UDP packet, but there is no socket available.'); - if (!this.discordAddress || !this.discordPort) throw new Error('Malformed UDP address or port.'); - this.socket.send(packet, 0, packet.length, this.discordPort, this.discordAddress, error => { - if (error) reject(error); else resolve(packet); - }); - }); - } - - createUDPSocket(address) { - this.discordAddress = address; - const socket = this.socket = udp.createSocket('udp4'); - - socket.once('message', message => { - const packet = parseLocalPacket(message); - if (packet.error) { - this.emit('error', packet.error); - return; - } - - this.localAddress = packet.address; - this.localPort = packet.port; - - this.voiceConnection.sockets.ws.sendPacket({ - op: Constants.VoiceOPCodes.SELECT_PROTOCOL, - d: { - protocol: 'udp', - data: { - address: packet.address, - port: packet.port, - mode: 'xsalsa20_poly1305', - }, - }, - }); - }); - - const blankMessage = new Buffer(70); - blankMessage.writeUIntBE(this.voiceConnection.authentication.ssrc, 0, 4); - this.send(blankMessage); - } -} - -function parseLocalPacket(message) { - try { - const packet = new Buffer(message); - let address = ''; - for (let i = 4; i < packet.indexOf(0, i); i++) address += String.fromCharCode(packet[i]); - const port = parseInt(packet.readUIntLE(packet.length - 2, 2).toString(10), 10); - return { address, port }; - } catch (error) { - return { error }; - } -} - -module.exports = VoiceConnectionUDPClient; diff --git a/node_modules/discord.js/src/client/voice/VoiceWebSocket.js b/node_modules/discord.js/src/client/voice/VoiceWebSocket.js deleted file mode 100644 index bafa5dd..0000000 --- a/node_modules/discord.js/src/client/voice/VoiceWebSocket.js +++ /dev/null @@ -1,249 +0,0 @@ -const Constants = require('../../util/Constants'); -const SecretKey = require('./util/SecretKey'); -const EventEmitter = require('events').EventEmitter; - -let WebSocket; -try { - WebSocket = require('uws'); -} catch (err) { - WebSocket = require('ws'); -} - -/** - * Represents a Voice Connection's WebSocket - * @extends {EventEmitter} - * @private - */ -class VoiceWebSocket extends EventEmitter { - constructor(voiceConnection) { - super(); - - /** - * The Voice Connection that this WebSocket serves - * @type {VoiceConnection} - */ - this.voiceConnection = voiceConnection; - - /** - * How many connection attempts have been made - * @type {number} - */ - this.attempts = 0; - - this.connect(); - this.dead = false; - this.voiceConnection.on('closing', this.shutdown.bind(this)); - } - - shutdown() { - this.dead = true; - this.reset(); - } - - /** - * The client of this voice websocket - * @type {Client} - * @readonly - */ - get client() { - return this.voiceConnection.voiceManager.client; - } - - /** - * Resets the current WebSocket - */ - reset() { - if (this.ws) { - if (this.ws.readyState !== WebSocket.CLOSED) this.ws.close(); - this.ws = null; - } - this.clearHeartbeat(); - } - - /** - * Starts connecting to the Voice WebSocket Server. - */ - connect() { - if (this.dead) return; - if (this.ws) this.reset(); - if (this.attempts > 5) { - this.emit('error', new Error(`Too many connection attempts (${this.attempts}).`)); - return; - } - - this.attempts++; - - /** - * The actual WebSocket used to connect to the Voice WebSocket Server. - * @type {WebSocket} - */ - this.ws = new WebSocket(`wss://${this.voiceConnection.authentication.endpoint}`); - this.ws.onopen = this.onOpen.bind(this); - this.ws.onmessage = this.onMessage.bind(this); - this.ws.onclose = this.onClose.bind(this); - this.ws.onerror = this.onError.bind(this); - } - - /** - * Sends data to the WebSocket if it is open. - * @param {string} data the data to send to the WebSocket - * @returns {Promise<string>} - */ - send(data) { - return new Promise((resolve, reject) => { - if (!this.ws || this.ws.readyState !== WebSocket.OPEN) { - throw new Error(`Voice websocket not open to send ${data}.`); - } - this.ws.send(data, null, error => { - if (error) reject(error); else resolve(data); - }); - }); - } - - /** - * JSON.stringify's a packet and then sends it to the WebSocket Server. - * @param {Object} packet the packet to send - * @returns {Promise<string>} - */ - sendPacket(packet) { - try { - packet = JSON.stringify(packet); - } catch (error) { - return Promise.reject(error); - } - return this.send(packet); - } - - /** - * Called whenever the WebSocket opens - */ - onOpen() { - this.sendPacket({ - op: Constants.OPCodes.DISPATCH, - d: { - server_id: this.voiceConnection.channel.guild.id, - user_id: this.client.user.id, - token: this.voiceConnection.authentication.token, - session_id: this.voiceConnection.authentication.session_id, - }, - }).catch(() => { - this.emit('error', new Error('Tried to send join packet, but the WebSocket is not open.')); - }); - } - - /** - * Called whenever a message is received from the WebSocket - * @param {MessageEvent} event the message event that was received - * @returns {void} - */ - onMessage(event) { - try { - return this.onPacket(JSON.parse(event.data)); - } catch (error) { - return this.onError(error); - } - } - - /** - * Called whenever the connection to the WebSocket Server is lost - */ - onClose() { - if (!this.dead) this.client.setTimeout(this.connect.bind(this), this.attempts * 1000); - } - - /** - * Called whenever an error occurs with the WebSocket. - * @param {Error} error the error that occurred - */ - onError(error) { - this.emit('error', error); - } - - /** - * Called whenever a valid packet is received from the WebSocket - * @param {Object} packet the received packet - */ - onPacket(packet) { - switch (packet.op) { - case Constants.VoiceOPCodes.READY: - this.setHeartbeat(packet.d.heartbeat_interval); - /** - * Emitted once the voice websocket receives the ready packet - * @param {Object} packet the received packet - * @event VoiceWebSocket#ready - */ - this.emit('ready', packet.d); - break; - case Constants.VoiceOPCodes.SESSION_DESCRIPTION: - /** - * Emitted once the Voice Websocket receives a description of this voice session - * @param {string} encryptionMode the type of encryption being used - * @param {SecretKey} secretKey the secret key used for encryption - * @event VoiceWebSocket#sessionDescription - */ - this.emit('sessionDescription', packet.d.mode, new SecretKey(packet.d.secret_key)); - break; - case Constants.VoiceOPCodes.SPEAKING: - /** - * Emitted whenever a speaking packet is received - * @param {Object} data - * @event VoiceWebSocket#speaking - */ - this.emit('speaking', packet.d); - break; - default: - /** - * Emitted when an unhandled packet is received - * @param {Object} packet - * @event VoiceWebSocket#unknownPacket - */ - this.emit('unknownPacket', packet); - break; - } - } - - /** - * Sets an interval at which to send a heartbeat packet to the WebSocket - * @param {number} interval the interval at which to send a heartbeat packet - */ - setHeartbeat(interval) { - if (!interval || isNaN(interval)) { - this.onError(new Error('Tried to set voice heartbeat but no valid interval was specified.')); - return; - } - if (this.heartbeatInterval) { - /** - * Emitted whenver the voice websocket encounters a non-fatal error - * @param {string} warn the warning - * @event VoiceWebSocket#warn - */ - this.emit('warn', 'A voice heartbeat interval is being overwritten'); - clearInterval(this.heartbeatInterval); - } - this.heartbeatInterval = this.client.setInterval(this.sendHeartbeat.bind(this), interval); - } - - /** - * Clears a heartbeat interval, if one exists - */ - clearHeartbeat() { - if (!this.heartbeatInterval) { - this.emit('warn', 'Tried to clear a heartbeat interval that does not exist'); - return; - } - clearInterval(this.heartbeatInterval); - this.heartbeatInterval = null; - } - - /** - * Sends a heartbeat packet - */ - sendHeartbeat() { - this.sendPacket({ op: Constants.VoiceOPCodes.HEARTBEAT, d: null }).catch(() => { - this.emit('warn', 'Tried to send heartbeat, but connection is not open'); - this.clearHeartbeat(); - }); - } -} - -module.exports = VoiceWebSocket; diff --git a/node_modules/discord.js/src/client/voice/dispatcher/StreamDispatcher.js b/node_modules/discord.js/src/client/voice/dispatcher/StreamDispatcher.js deleted file mode 100644 index e08a365..0000000 --- a/node_modules/discord.js/src/client/voice/dispatcher/StreamDispatcher.js +++ /dev/null @@ -1,307 +0,0 @@ -const EventEmitter = require('events').EventEmitter; -const NaCl = require('tweetnacl'); - -const nonce = new Buffer(24); -nonce.fill(0); - -/** - * The class that sends voice packet data to the voice connection. - * ```js - * // obtained using: - * voiceChannel.join().then(connection => { - * // you can play a file or a stream here: - * const dispatcher = connection.playFile('./file.mp3'); - * }); - * ``` - * @extends {EventEmitter} - */ -class StreamDispatcher extends EventEmitter { - constructor(player, stream, sd, streamOptions) { - super(); - this.player = player; - this.stream = stream; - this.streamingData = { - channels: 2, - count: 0, - sequence: sd.sequence, - timestamp: sd.timestamp, - pausedTime: 0, - }; - this._startStreaming(); - this._triggered = false; - this._volume = streamOptions.volume; - - /** - * How many passes the dispatcher should take when sending packets to reduce packet loss. Values over 5 - * aren't recommended, as it means you are using 5x more bandwidth. You _can_ edit this at runtime. - * @type {number} - */ - this.passes = streamOptions.passes || 1; - - /** - * Whether playing is paused - * @type {boolean} - */ - this.paused = false; - - this.setVolume(streamOptions.volume || 1); - } - - /** - * How long the stream dispatcher has been "speaking" for - * @type {number} - * @readonly - */ - get time() { - return this.streamingData.count * (this.streamingData.length || 0); - } - - /** - * The total time, taking into account pauses and skips, that the dispatcher has been streaming for - * @type {number} - * @readonly - */ - get totalStreamTime() { - return this.time + this.streamingData.pausedTime; - } - - /** - * The volume of the stream, relative to the stream's input volume - * @type {number} - * @readonly - */ - get volume() { - return this._volume; - } - - /** - * Sets the volume relative to the input stream - i.e. 1 is normal, 0.5 is half, 2 is double. - * @param {number} volume The volume that you want to set - */ - setVolume(volume) { - this._volume = volume; - } - - /** - * Set the volume in decibels - * @param {number} db The decibels - */ - setVolumeDecibels(db) { - this._volume = Math.pow(10, db / 20); - } - - /** - * Set the volume so that a perceived value of 0.5 is half the perceived volume etc. - * @param {number} value The value for the volume - */ - setVolumeLogarithmic(value) { - this._volume = Math.pow(value, 1.660964); - } - - /** - * Stops sending voice packets to the voice connection (stream may still progress however) - */ - pause() { - this._setPaused(true); - } - - /** - * Resumes sending voice packets to the voice connection (may be further on in the stream than when paused) - */ - resume() { - this._setPaused(false); - } - - /** - * Stops the current stream permanently and emits an `end` event. - * @param {string} [reason='user'] An optional reason for stopping the dispatcher. - */ - end(reason = 'user') { - this._triggerTerminalState('end', reason); - } - - _setSpeaking(value) { - this.speaking = value; - /** - * Emitted when the dispatcher starts/stops speaking - * @event StreamDispatcher#speaking - * @param {boolean} value Whether or not the dispatcher is speaking - */ - this.emit('speaking', value); - } - - _sendBuffer(buffer, sequence, timestamp) { - let repeats = this.passes; - const packet = this._createPacket(sequence, timestamp, this.player.opusEncoder.encode(buffer)); - while (repeats--) { - this.player.voiceConnection.sockets.udp.send(packet) - .catch(e => this.emit('debug', `Failed to send a packet ${e}`)); - } - } - - _createPacket(sequence, timestamp, buffer) { - const packetBuffer = new Buffer(buffer.length + 28); - packetBuffer.fill(0); - packetBuffer[0] = 0x80; - packetBuffer[1] = 0x78; - - packetBuffer.writeUIntBE(sequence, 2, 2); - packetBuffer.writeUIntBE(timestamp, 4, 4); - packetBuffer.writeUIntBE(this.player.voiceConnection.authentication.ssrc, 8, 4); - - packetBuffer.copy(nonce, 0, 0, 12); - buffer = NaCl.secretbox(buffer, nonce, this.player.voiceConnection.authentication.secretKey.key); - - for (let i = 0; i < buffer.length; i++) packetBuffer[i + 12] = buffer[i]; - - return packetBuffer; - } - - _applyVolume(buffer) { - if (this._volume === 1) return buffer; - - const out = new Buffer(buffer.length); - for (let i = 0; i < buffer.length; i += 2) { - if (i >= buffer.length - 1) break; - const uint = Math.min(32767, Math.max(-32767, Math.floor(this._volume * buffer.readInt16LE(i)))); - out.writeInt16LE(uint, i); - } - - return out; - } - - _send() { - try { - if (this._triggered) { - this._setSpeaking(false); - return; - } - - const data = this.streamingData; - - if (data.missed >= 5) { - this._triggerTerminalState('end', 'Stream is not generating quickly enough.'); - return; - } - - if (this.paused) { - // data.timestamp = data.timestamp + 4294967295 ? data.timestamp + 960 : 0; - data.pausedTime += data.length * 10; - this.player.voiceConnection.voiceManager.client.setTimeout(() => this._send(), data.length * 10); - return; - } - - this._setSpeaking(true); - - if (!data.startTime) { - /** - * Emitted once the dispatcher starts streaming - * @event StreamDispatcher#start - */ - this.emit('start'); - data.startTime = Date.now(); - } - - const bufferLength = 1920 * data.channels; - let buffer = this.stream.read(bufferLength); - if (!buffer) { - data.missed++; - data.pausedTime += data.length * 10; - this.player.voiceConnection.voiceManager.client.setTimeout(() => this._send(), data.length * 10); - return; - } - - data.missed = 0; - - if (buffer.length !== bufferLength) { - const newBuffer = new Buffer(bufferLength).fill(0); - buffer.copy(newBuffer); - buffer = newBuffer; - } - - buffer = this._applyVolume(buffer); - - data.count++; - data.sequence = (data.sequence + 1) < 65536 ? data.sequence + 1 : 0; - data.timestamp = data.timestamp + 4294967295 ? data.timestamp + 960 : 0; - - this._sendBuffer(buffer, data.sequence, data.timestamp); - - const nextTime = data.length + (data.startTime + data.pausedTime + (data.count * data.length) - Date.now()); - this.player.voiceConnection.voiceManager.client.setTimeout(() => this._send(), nextTime); - } catch (e) { - this._triggerTerminalState('error', e); - } - } - - _triggerEnd(reason) { - /** - * Emitted once the stream has ended. Attach a `once` listener to this. - * @event StreamDispatcher#end - * @param {string} reason The reason for the end of the dispatcher. If it ended because it reached the end of the - * stream, this would be `stream`. If you invoke `.end()` without specifying a reason, this would be `user`. - */ - this.emit('end', reason); - } - - _triggerError(err) { - this.emit('end'); - /** - * Emitted once the stream has encountered an error. Attach a `once` listener to this. Also emits `end`. - * @event StreamDispatcher#error - * @param {Error} err The encountered error - */ - this.emit('error', err); - } - - _triggerTerminalState(state, err) { - if (this._triggered) return; - /** - * Emitted when the stream wants to give debug information. - * @event StreamDispatcher#debug - * @param {string} information The debug information - */ - this.emit('debug', `Triggered terminal state ${state} - stream is now dead`); - this._triggered = true; - this._setSpeaking(false); - switch (state) { - case 'end': - this._triggerEnd(err); - break; - case 'error': - this._triggerError(err); - break; - default: - this.emit('error', 'Unknown trigger state'); - break; - } - } - - _startStreaming() { - if (!this.stream) { - this.emit('error', 'No stream'); - return; - } - - this.stream.on('end', err => this._triggerTerminalState('end', err || 'stream')); - this.stream.on('error', err => this._triggerTerminalState('error', err)); - - const data = this.streamingData; - data.length = 20; - data.missed = 0; - - this.stream.once('readable', () => this._send()); - } - - _setPaused(paused) { - if (paused) { - this.paused = true; - this._setSpeaking(false); - } else { - this.paused = false; - this._setSpeaking(true); - } - } -} - -module.exports = StreamDispatcher; diff --git a/node_modules/discord.js/src/client/voice/opus/BaseOpusEngine.js b/node_modules/discord.js/src/client/voice/opus/BaseOpusEngine.js deleted file mode 100644 index 6c3ba6e..0000000 --- a/node_modules/discord.js/src/client/voice/opus/BaseOpusEngine.js +++ /dev/null @@ -1,15 +0,0 @@ -class BaseOpus { - constructor(player) { - this.player = player; - } - - encode(buffer) { - return buffer; - } - - decode(buffer) { - return buffer; - } -} - -module.exports = BaseOpus; diff --git a/node_modules/discord.js/src/client/voice/opus/NodeOpusEngine.js b/node_modules/discord.js/src/client/voice/opus/NodeOpusEngine.js deleted file mode 100644 index 10f287b..0000000 --- a/node_modules/discord.js/src/client/voice/opus/NodeOpusEngine.js +++ /dev/null @@ -1,27 +0,0 @@ -const OpusEngine = require('./BaseOpusEngine'); - -let opus; - -class NodeOpusEngine extends OpusEngine { - constructor(player) { - super(player); - try { - opus = require('node-opus'); - } catch (err) { - throw err; - } - this.encoder = new opus.OpusEncoder(48000, 2); - } - - encode(buffer) { - super.encode(buffer); - return this.encoder.encode(buffer, 1920); - } - - decode(buffer) { - super.decode(buffer); - return this.encoder.decode(buffer, 1920); - } -} - -module.exports = NodeOpusEngine; diff --git a/node_modules/discord.js/src/client/voice/opus/OpusEngineList.js b/node_modules/discord.js/src/client/voice/opus/OpusEngineList.js deleted file mode 100644 index ffd512a..0000000 --- a/node_modules/discord.js/src/client/voice/opus/OpusEngineList.js +++ /dev/null @@ -1,24 +0,0 @@ -const list = [ - require('./NodeOpusEngine'), - require('./OpusScriptEngine'), -]; - -function fetch(Encoder) { - try { - return new Encoder(); - } catch (err) { - return null; - } -} - -exports.add = encoder => { - list.push(encoder); -}; - -exports.fetch = () => { - for (const encoder of list) { - const fetched = fetch(encoder); - if (fetched) return fetched; - } - throw new Error('Couldn\'t find an Opus engine.'); -}; diff --git a/node_modules/discord.js/src/client/voice/opus/OpusScriptEngine.js b/node_modules/discord.js/src/client/voice/opus/OpusScriptEngine.js deleted file mode 100644 index 33b4ff5..0000000 --- a/node_modules/discord.js/src/client/voice/opus/OpusScriptEngine.js +++ /dev/null @@ -1,27 +0,0 @@ -const OpusEngine = require('./BaseOpusEngine'); - -let OpusScript; - -class NodeOpusEngine extends OpusEngine { - constructor(player) { - super(player); - try { - OpusScript = require('opusscript'); - } catch (err) { - throw err; - } - this.encoder = new OpusScript(48000, 2); - } - - encode(buffer) { - super.encode(buffer); - return this.encoder.encode(buffer, 960); - } - - decode(buffer) { - super.decode(buffer); - return this.encoder.decode(buffer); - } -} - -module.exports = NodeOpusEngine; diff --git a/node_modules/discord.js/src/client/voice/pcm/ConverterEngine.js b/node_modules/discord.js/src/client/voice/pcm/ConverterEngine.js deleted file mode 100644 index 6b7502f..0000000 --- a/node_modules/discord.js/src/client/voice/pcm/ConverterEngine.js +++ /dev/null @@ -1,14 +0,0 @@ -const EventEmitter = require('events').EventEmitter; - -class ConverterEngine extends EventEmitter { - constructor(player) { - super(); - this.player = player; - } - - createConvertStream() { - return; - } -} - -module.exports = ConverterEngine; diff --git a/node_modules/discord.js/src/client/voice/pcm/ConverterEngineList.js b/node_modules/discord.js/src/client/voice/pcm/ConverterEngineList.js deleted file mode 100644 index 56d430e..0000000 --- a/node_modules/discord.js/src/client/voice/pcm/ConverterEngineList.js +++ /dev/null @@ -1 +0,0 @@ -exports.fetch = () => require('./FfmpegConverterEngine'); diff --git a/node_modules/discord.js/src/client/voice/pcm/FfmpegConverterEngine.js b/node_modules/discord.js/src/client/voice/pcm/FfmpegConverterEngine.js deleted file mode 100644 index 8fb725b..0000000 --- a/node_modules/discord.js/src/client/voice/pcm/FfmpegConverterEngine.js +++ /dev/null @@ -1,86 +0,0 @@ -const ConverterEngine = require('./ConverterEngine'); -const ChildProcess = require('child_process'); -const EventEmitter = require('events').EventEmitter; - -class PCMConversionProcess extends EventEmitter { - constructor(process) { - super(); - this.process = process; - this.input = null; - this.process.on('error', e => this.emit('error', e)); - } - - setInput(stream) { - this.input = stream; - stream.pipe(this.process.stdin, { end: false }); - this.input.on('error', e => this.emit('error', e)); - this.process.stdin.on('error', e => this.emit('error', e)); - } - - destroy() { - this.emit('debug', 'destroying a ffmpeg process:'); - if (this.input && this.input.unpipe && this.process.stdin) { - this.input.unpipe(this.process.stdin); - this.emit('unpiped the user input stream from the process input stream'); - } - if (this.process.stdin) { - this.process.stdin.end(); - this.emit('ended the process stdin'); - } - if (this.process.stdin.destroy) { - this.process.stdin.destroy(); - this.emit('destroyed the process stdin'); - } - if (this.process.kill) { - this.process.kill(); - this.emit('killed the process'); - } - } - -} - -class FfmpegConverterEngine extends ConverterEngine { - constructor(player) { - super(player); - this.command = chooseCommand(); - } - - handleError(encoder, err) { - if (encoder.destroy) encoder.destroy(); - this.emit('error', err); - } - - createConvertStream(seek = 0) { - super.createConvertStream(); - const encoder = ChildProcess.spawn(this.command, [ - '-analyzeduration', '0', - '-loglevel', '0', - '-i', '-', - '-f', 's16le', - '-ar', '48000', - '-ac', '2', - '-ss', String(seek), - 'pipe:1', - ], { stdio: ['pipe', 'pipe', 'ignore'] }); - return new PCMConversionProcess(encoder); - } -} - -function chooseCommand() { - for (const cmd of [ - 'ffmpeg', - 'avconv', - './ffmpeg', - './avconv', - 'node_modules\\ffmpeg-binaries\\bin\\ffmpeg', - 'node_modules/ffmpeg-binaries/bin/ffmpeg', - ]) { - if (!ChildProcess.spawnSync(cmd, ['-h']).error) return cmd; - } - throw new Error( - 'FFMPEG was not found on your system, so audio cannot be played. ' + - 'Please make sure FFMPEG is installed and in your PATH.' - ); -} - -module.exports = FfmpegConverterEngine; diff --git a/node_modules/discord.js/src/client/voice/player/AudioPlayer.js b/node_modules/discord.js/src/client/voice/player/AudioPlayer.js deleted file mode 100644 index 96c6c24..0000000 --- a/node_modules/discord.js/src/client/voice/player/AudioPlayer.js +++ /dev/null @@ -1,80 +0,0 @@ -const PCMConverters = require('../pcm/ConverterEngineList'); -const OpusEncoders = require('../opus/OpusEngineList'); -const EventEmitter = require('events').EventEmitter; -const StreamDispatcher = require('../dispatcher/StreamDispatcher'); - -/** - * Represents the Audio Player of a Voice Connection - * @extends {EventEmitter} - * @private - */ -class AudioPlayer extends EventEmitter { - constructor(voiceConnection) { - super(); - /** - * The voice connection the player belongs to - * @type {VoiceConnection} - */ - this.voiceConnection = voiceConnection; - this.audioToPCM = new (PCMConverters.fetch())(); - this.opusEncoder = OpusEncoders.fetch(); - this.currentConverter = null; - /** - * The current stream dispatcher, if a stream is being played - * @type {StreamDispatcher} - */ - this.dispatcher = null; - this.audioToPCM.on('error', e => this.emit('error', e)); - this.streamingData = { - channels: 2, - count: 0, - sequence: 0, - timestamp: 0, - pausedTime: 0, - }; - this.voiceConnection.on('closing', () => this.cleanup(null, 'voice connection closing')); - } - - playUnknownStream(stream, { seek = 0, volume = 1, passes = 1 } = {}) { - const options = { seek, volume, passes }; - stream.on('end', () => { - this.emit('debug', 'Input stream to converter has ended'); - }); - stream.on('error', e => this.emit('error', e)); - const conversionProcess = this.audioToPCM.createConvertStream(options.seek); - conversionProcess.on('error', e => this.emit('error', e)); - conversionProcess.setInput(stream); - return this.playPCMStream(conversionProcess.process.stdout, conversionProcess, options); - } - - cleanup(checkStream, reason) { - // cleanup is a lot less aggressive than v9 because it doesn't try to kill every single stream it is aware of - this.emit('debug', `Clean up triggered due to ${reason}`); - const filter = checkStream && this.dispatcher && this.dispatcher.stream === checkStream; - if (this.currentConverter && (checkStream ? filter : true)) { - this.currentConverter.destroy(); - this.currentConverter = null; - } - } - - playPCMStream(stream, converter, { seek = 0, volume = 1, passes = 1 } = {}) { - const options = { seek, volume, passes }; - stream.on('end', () => this.emit('debug', 'PCM input stream ended')); - this.cleanup(null, 'outstanding play stream'); - this.currentConverter = converter; - if (this.dispatcher) { - this.streamingData = this.dispatcher.streamingData; - } - stream.on('error', e => this.emit('error', e)); - const dispatcher = new StreamDispatcher(this, stream, this.streamingData, options); - dispatcher.on('error', e => this.emit('error', e)); - dispatcher.on('end', () => this.cleanup(dispatcher.stream, 'dispatcher ended')); - dispatcher.on('speaking', value => this.voiceConnection.setSpeaking(value)); - this.dispatcher = dispatcher; - dispatcher.on('debug', m => this.emit('debug', `Stream dispatch - ${m}`)); - return dispatcher; - } - -} - -module.exports = AudioPlayer; diff --git a/node_modules/discord.js/src/client/voice/player/BasePlayer.js b/node_modules/discord.js/src/client/voice/player/BasePlayer.js deleted file mode 100644 index d5285cd..0000000 --- a/node_modules/discord.js/src/client/voice/player/BasePlayer.js +++ /dev/null @@ -1,121 +0,0 @@ -const OpusEngines = require('../opus/OpusEngineList'); -const ConverterEngines = require('../pcm/ConverterEngineList'); -const Constants = require('../../../util/Constants'); -const StreamDispatcher = require('../dispatcher/StreamDispatcher'); -const EventEmitter = require('events').EventEmitter; - -class VoiceConnectionPlayer extends EventEmitter { - constructor(connection) { - super(); - this.connection = connection; - this.opusEncoder = OpusEngines.fetch(); - const Engine = ConverterEngines.fetch(); - this.converterEngine = new Engine(this); - this.converterEngine.on('error', err => { - this._shutdown(); - this.emit('error', err); - }); - this.speaking = false; - this.processMap = new Map(); - this.dispatcher = null; - this._streamingData = { - sequence: 0, - timestamp: 0, - }; - } - - convertStream(stream, { seek = 0, volume = 1, passes = 1 } = {}) { - const options = { seek, volume, passes }; - const encoder = this.converterEngine.createConvertStream(options.seek); - const pipe = stream.pipe(encoder.stdin, { end: false }); - pipe.on('unpipe', () => { - this.killStream(encoder.stdout); - pipe.destroy(); - }); - this.processMap.set(encoder.stdout, { - pcmConverter: encoder, - inputStream: stream, - }); - return encoder.stdout; - } - - _shutdown() { - this.speaking = false; - if (this.dispatcher) this.dispatcher._triggerTerminalState('end', 'ended by parent player shutdown'); - for (const stream of this.processMap.keys()) this.killStream(stream); - } - - killStream(stream) { - const streams = this.processMap.get(stream); - this._streamingData = this.dispatcher.streamingData; - this.emit(Constants.Events.DEBUG, 'Cleaning up player after audio stream ended or encountered an error'); - - const dummyHandler = () => null; - - if (streams) { - this.processMap.delete(stream); - if (streams.inputStream && streams.pcmConverter) { - try { - streams.inputStream.once('error', dummyHandler); - streams.pcmConverter.once('error', dummyHandler); - streams.pcmConverter.stdin.once('error', dummyHandler); - streams.pcmConverter.stdout.once('error', dummyHandler); - if (streams.inputStream.unpipe) { - streams.inputStream.unpipe(streams.pcmConverter.stdin); - this.emit(Constants.Events.DEBUG, '- Unpiped input stream'); - } else if (streams.inputStream.destroy) { - streams.inputStream.destroy(); - this.emit(Constants.Events.DEBUG, '- Couldn\'t unpipe input stream, so destroyed input stream'); - } - if (streams.pcmConverter.stdin) { - streams.pcmConverter.stdin.end(); - this.emit(Constants.Events.DEBUG, '- Ended input stream to PCM converter'); - } - if (streams.pcmConverter && streams.pcmConverter.kill) { - streams.pcmConverter.kill('SIGINT'); - this.emit(Constants.Events.DEBUG, '- Killed the PCM converter'); - } - } catch (err) { - // if an error happened make sure the pcm converter is killed anyway - try { - if (streams.pcmConverter && streams.pcmConverter.kill) { - streams.pcmConverter.kill('SIGINT'); - this.emit(Constants.Events.DEBUG, '- Killed the PCM converter after previous error (abnormal)'); - } - } catch (e) { - return e; - } - return err; - } - } - } - return null; - } - - setSpeaking(value) { - if (this.speaking === value) return; - this.speaking = value; - this.connection.websocket.send({ - op: Constants.VoiceOPCodes.SPEAKING, - d: { - speaking: true, - delay: 0, - }, - }).catch(e => { - this.emit('debug', e); - }); - } - - playPCMStream(pcmStream, { seek = 0, volume = 1, passes = 1 } = {}) { - const options = { seek, volume, passes }; - const dispatcher = new StreamDispatcher(this, pcmStream, this._streamingData, options); - dispatcher.on('speaking', value => this.setSpeaking(value)); - dispatcher.on('end', () => this.killStream(pcmStream)); - dispatcher.on('error', () => this.killStream(pcmStream)); - dispatcher.setVolume(options.volume); - this.dispatcher = dispatcher; - return dispatcher; - } -} - -module.exports = VoiceConnectionPlayer; diff --git a/node_modules/discord.js/src/client/voice/player/DefaultPlayer.js b/node_modules/discord.js/src/client/voice/player/DefaultPlayer.js deleted file mode 100644 index b465e8c..0000000 --- a/node_modules/discord.js/src/client/voice/player/DefaultPlayer.js +++ /dev/null @@ -1,19 +0,0 @@ -const BasePlayer = require('./BasePlayer'); -const fs = require('fs'); - -class DefaultPlayer extends BasePlayer { - playFile(file, { seek = 0, volume = 1 } = {}) { - const options = { seek: seek, volume: volume }; - return this.playStream(fs.createReadStream(file), options); - } - - playStream(stream, { seek = 0, volume = 1, passes = 1 } = {}) { - this._shutdown(); - const options = { seek, volume, passes }; - const pcmStream = this.convertStream(stream, options); - const dispatcher = this.playPCMStream(pcmStream, options); - return dispatcher; - } -} - -module.exports = DefaultPlayer; diff --git a/node_modules/discord.js/src/client/voice/receiver/VoiceReadable.js b/node_modules/discord.js/src/client/voice/receiver/VoiceReadable.js deleted file mode 100644 index 50ace27..0000000 --- a/node_modules/discord.js/src/client/voice/receiver/VoiceReadable.js +++ /dev/null @@ -1,19 +0,0 @@ -const Readable = require('stream').Readable; - -class VoiceReadable extends Readable { - constructor() { - super(); - this._packets = []; - this.open = true; - } - - _read() { - return; - } - - _push(d) { - if (this.open) this.push(d); - } -} - -module.exports = VoiceReadable; diff --git a/node_modules/discord.js/src/client/voice/receiver/VoiceReceiver.js b/node_modules/discord.js/src/client/voice/receiver/VoiceReceiver.js deleted file mode 100644 index bc9156f..0000000 --- a/node_modules/discord.js/src/client/voice/receiver/VoiceReceiver.js +++ /dev/null @@ -1,154 +0,0 @@ -const EventEmitter = require('events').EventEmitter; -const NaCl = require('tweetnacl'); -const Readable = require('./VoiceReadable'); - -const nonce = new Buffer(24); -nonce.fill(0); - -/** - * Receives voice data from a voice connection. - * ```js - * // obtained using: - * voiceChannel.join().then(connection => { - * const receiver = connection.createReceiver(); - * }); - * ``` - * @extends {EventEmitter} - */ -class VoiceReceiver extends EventEmitter { - constructor(connection) { - super(); - /* - need a queue because we don't get the ssrc of the user speaking until after the first few packets, - so we queue up unknown SSRCs until they become known, then empty the queue. - */ - this.queues = new Map(); - this.pcmStreams = new Map(); - this.opusStreams = new Map(); - - /** - * Whether or not this receiver has been destroyed. - * @type {boolean} - */ - this.destroyed = false; - - /** - * The VoiceConnection that instantiated this - * @type {VoiceConnection} - */ - this.voiceConnection = connection; - - this._listener = msg => { - const ssrc = +msg.readUInt32BE(8).toString(10); - const user = this.voiceConnection.ssrcMap.get(ssrc); - if (!user) { - if (!this.queues.has(ssrc)) this.queues.set(ssrc, []); - this.queues.get(ssrc).push(msg); - } else { - if (this.queues.get(ssrc)) { - this.queues.get(ssrc).push(msg); - this.queues.get(ssrc).map(m => this.handlePacket(m, user)); - this.queues.delete(ssrc); - return; - } - this.handlePacket(msg, user); - } - }; - this.voiceConnection.sockets.udp.socket.on('message', this._listener); - } - - /** - * If this VoiceReceiver has been destroyed, running `recreate()` will recreate the listener. - * This avoids you having to create a new receiver. - * <info>Any streams that you had prior to destroying the receiver will not be recreated.</info> - */ - recreate() { - if (!this.destroyed) return; - this.voiceConnection.sockets.udp.socket.on('message', this._listener); - this.destroyed = false; - return; - } - - /** - * Destroy this VoiceReceiver, also ending any streams that it may be controlling. - */ - destroy() { - this.voiceConnection.sockets.udp.socket.removeListener('message', this._listener); - for (const stream of this.pcmStreams) { - stream[1]._push(null); - this.pcmStreams.delete(stream[0]); - } - for (const stream of this.opusStreams) { - stream[1]._push(null); - this.opusStreams.delete(stream[0]); - } - this.destroyed = true; - } - - /** - * Creates a readable stream for a user that provides opus data while the user is speaking. When the user - * stops speaking, the stream is destroyed. - * @param {UserResolvable} user The user to create the stream for - * @returns {ReadableStream} - */ - createOpusStream(user) { - user = this.voiceConnection.voiceManager.client.resolver.resolveUser(user); - if (!user) throw new Error('Couldn\'t resolve the user to create Opus stream.'); - if (this.opusStreams.get(user.id)) throw new Error('There is already an existing stream for that user.'); - const stream = new Readable(); - this.opusStreams.set(user.id, stream); - return stream; - } - - /** - * Creates a readable stream for a user that provides PCM data while the user is speaking. When the user - * stops speaking, the stream is destroyed. The stream is 32-bit signed stereo PCM at 48KHz. - * @param {UserResolvable} user The user to create the stream for - * @returns {ReadableStream} - */ - createPCMStream(user) { - user = this.voiceConnection.voiceManager.client.resolver.resolveUser(user); - if (!user) throw new Error('Couldn\'t resolve the user to create PCM stream.'); - if (this.pcmStreams.get(user.id)) throw new Error('There is already an existing stream for that user.'); - const stream = new Readable(); - this.pcmStreams.set(user.id, stream); - return stream; - } - - handlePacket(msg, user) { - msg.copy(nonce, 0, 0, 12); - let data = NaCl.secretbox.open(msg.slice(12), nonce, this.voiceConnection.authentication.secretKey.key); - if (!data) { - /** - * Emitted whenever a voice packet cannot be decrypted - * @event VoiceReceiver#warn - * @param {string} message The warning message - */ - this.emit('warn', 'Failed to decrypt voice packet'); - return; - } - data = new Buffer(data); - if (this.opusStreams.get(user.id)) this.opusStreams.get(user.id)._push(data); - /** - * Emitted whenever voice data is received from the voice connection. This is _always_ emitted (unlike PCM). - * @event VoiceReceiver#opus - * @param {User} user The user that is sending the buffer (is speaking) - * @param {Buffer} buffer The opus buffer - */ - this.emit('opus', user, data); - if (this.listenerCount('pcm') > 0 || this.pcmStreams.size > 0) { - /** - * Emits decoded voice data when it's received. For performance reasons, the decoding will only - * happen if there is at least one `pcm` listener on this receiver. - * @event VoiceReceiver#pcm - * @param {User} user The user that is sending the buffer (is speaking) - * @param {Buffer} buffer The decoded buffer - */ - const pcm = this.voiceConnection.player.opusEncoder.decode(data); - if (this.pcmStreams.get(user.id)) this.pcmStreams.get(user.id)._push(pcm); - this.emit('pcm', user, pcm); - } - } -} - -module.exports = VoiceReceiver; diff --git a/node_modules/discord.js/src/client/voice/util/SecretKey.js b/node_modules/discord.js/src/client/voice/util/SecretKey.js deleted file mode 100644 index 508a1ba..0000000 --- a/node_modules/discord.js/src/client/voice/util/SecretKey.js +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Represents a Secret Key used in encryption over voice - * @private - */ -class SecretKey { - constructor(key) { - /** - * The key used for encryption - * @type {Uint8Array} - */ - this.key = new Uint8Array(new ArrayBuffer(key.length)); - for (const index in key) this.key[index] = key[index]; - } -} - -module.exports = SecretKey; |
