Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Start/Stop speaking events on UDP packets #3578

Merged
merged 10 commits into from Dec 6, 2019
@@ -38,7 +38,7 @@ discord.js is a powerful [Node.js](https://nodejs.org) module that allows you to
- 100% coverage of the Discord API

## Installation
**Node.js 10.0.0 or newer is required.**
**Node.js 10.2.0 or newer is required.**

This comment has been minimized.

Copy link
@PyroTechniac

PyroTechniac Nov 15, 2019

Contributor

This shouldn't change until an official announcement is made about a version bump

Unless @iCrawl is okay with this I should mention

This comment has been minimized.

Copy link
@sillyfrog

sillyfrog Nov 15, 2019

Author Contributor

Thanks for the feedback! :)

I'll wait for confirmation from @iCrawl , however this change does rely on v10.2 because of the use of refresh(). Let me know the best way to approach things if we can't bump the version (maybe even a note to say this feature requires v10.2?).

Cheers.

Ignore any warnings about unmet peer dependencies, as they're all optional.

Without voice support: `npm install discordjs/discord.js`
@@ -422,7 +422,7 @@ class VoiceConnection extends EventEmitter {
udp.on('error', err => this.emit('error', err));
ws.on('ready', this.onReady.bind(this));
ws.on('sessionDescription', this.onSessionDescription.bind(this));
ws.on('speaking', this.onSpeaking.bind(this));
ws.on('startSpeaking', this.onStartSpeaking.bind(this));

this.sockets.ws.connect();
}
@@ -465,16 +465,19 @@ class VoiceConnection extends EventEmitter {
});
}

onStartSpeaking({ user_id, ssrc, speaking }) {
this.ssrcMap.set(+ssrc, { userID: user_id, speaking: speaking });
}

/**
* Invoked when a speaking event is received.
* @param {Object} data The received data
* @private
*/
onSpeaking({ user_id, ssrc, speaking }) {
onSpeaking({ user_id, speaking }) {
speaking = new Speaking(speaking).freeze();
const guild = this.channel.guild;
const user = this.client.users.get(user_id);
this.ssrcMap.set(+ssrc, user_id);
const old = this._speaking.get(user_id);
this._speaking.set(user_id, speaking);
/**
@@ -504,7 +507,7 @@ class VoiceConnection extends EventEmitter {
}
}

play() {} // eslint-disable-line no-empty-function
play() { } // eslint-disable-line no-empty-function
This conversation was marked as resolved by sillyfrog

This comment has been minimized.

Copy link
@PyroTechniac

PyroTechniac Nov 14, 2019

Contributor
Suggested change
play() { } // eslint-disable-line no-empty-function
play() {} // eslint-disable-line no-empty-function

Nit: formatting should stay the same as it's like that throughout d.js

This comment has been minimized.

Copy link
@sillyfrog

sillyfrog Nov 14, 2019

Author Contributor

Aggg, that's VSCode (I'm just using the default setup), fixed (x2)

}

PlayInterface.applyToClass(VoiceConnection);
@@ -201,9 +201,9 @@ class VoiceWebSocket extends EventEmitter {
/**
* Emitted whenever a speaking packet is received.
* @param {Object} data
* @event VoiceWebSocket#speaking
* @event VoiceWebSocket#startSpeaking
*/
this.emit('speaking', packet.d);
this.emit('startSpeaking', packet.d);
break;
default:
/**
@@ -3,6 +3,10 @@
const secretbox = require('../util/Secretbox');
const EventEmitter = require('events');

// The delay between packets when a user is considered to have stopped speaking
// https://github.com/discordjs/discord.js/issues/3524#issuecomment-540373200
const DISCORD_SPEAKING_DELAY = 250;

class Readable extends require('stream').Readable { _read() {} } // eslint-disable-line no-empty-function

class PacketHandler extends EventEmitter {
@@ -11,6 +15,7 @@ class PacketHandler extends EventEmitter {
this.nonce = Buffer.alloc(24);
this.receiver = receiver;
this.streams = new Map();
this.speakingTimeouts = new Map();
}

get connection() {
@@ -72,13 +77,29 @@ class PacketHandler extends EventEmitter {
return packet;
}

userFromSSRC(ssrc) { return this.connection.client.users.get(this.connection.ssrcMap.get(ssrc)); }

push(buffer) {
const ssrc = buffer.readUInt32BE(8);
const user = this.userFromSSRC(ssrc);
if (!user) return;
let stream = this.streams.get(user.id);
const userStat = this.connection.ssrcMap.get(ssrc);
if (!userStat) return;

let speakingTimeout = this.speakingTimeouts.get(ssrc);
if (typeof speakingTimeout === 'undefined') {
this.connection.onSpeaking({ user_id: userStat.userID, ssrc: ssrc, speaking: userStat.speaking });
speakingTimeout = this.receiver.connection.client.setTimeout(() => {
try {
this.connection.onSpeaking({ user_id: userStat.userID, ssrc: ssrc, speaking: 0 });
this.receiver.connection.client.clearTimeout(speakingTimeout);
this.speakingTimeouts.delete(ssrc);
} catch (ex) {
// Connection already closed, ignore
}
}, DISCORD_SPEAKING_DELAY);
this.speakingTimeouts.set(ssrc, speakingTimeout);
} else {
speakingTimeout.refresh();
}

let stream = this.streams.get(userStat.userID);
if (!stream) return;
stream = stream.stream;
const opusPacket = this.parseBuffer(buffer);
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.