Compare commits

...

4 commits

7 changed files with 52 additions and 19 deletions

View file

@ -1,6 +1,6 @@
{ {
"name": "discord.js", "name": "discord.js",
"version": "12.5.0", "version": "12.5.1",
"description": "A powerful library for interacting with the Discord API", "description": "A powerful library for interacting with the Discord API",
"main": "./src/index", "main": "./src/index",
"types": "./typings/index.d.ts", "types": "./typings/index.d.ts",

View file

@ -473,7 +473,11 @@ class VoiceConnection extends EventEmitter {
} }
onStartSpeaking({ user_id, ssrc, speaking }) { onStartSpeaking({ user_id, ssrc, speaking }) {
this.ssrcMap.set(+ssrc, { userID: user_id, speaking: speaking }); this.ssrcMap.set(+ssrc, {
...(this.ssrcMap.get(+ssrc) || {}),
userID: user_id,
speaking: speaking,
});
} }
/** /**

View file

@ -189,7 +189,11 @@ class VoiceWebSocket extends EventEmitter {
this.emit('sessionDescription', packet.d); this.emit('sessionDescription', packet.d);
break; break;
case VoiceOPCodes.CLIENT_CONNECT: case VoiceOPCodes.CLIENT_CONNECT:
this.connection.ssrcMap.set(+packet.d.audio_ssrc, { userID: packet.d.user_id, speaking: 0 }); this.connection.ssrcMap.set(+packet.d.audio_ssrc, {
userID: packet.d.user_id,
speaking: 0,
hasVideo: Boolean(packet.d.video_ssrc),
});
break; break;
case VoiceOPCodes.CLIENT_DISCONNECT: case VoiceOPCodes.CLIENT_DISCONNECT:
const streamInfo = this.connection.receiver && this.connection.receiver.packets.streams.get(packet.d.user_id); const streamInfo = this.connection.receiver && this.connection.receiver.packets.streams.get(packet.d.user_id);

View file

@ -1,7 +1,9 @@
'use strict'; 'use strict';
const EventEmitter = require('events'); const EventEmitter = require('events');
const Speaking = require('../../../util/Speaking');
const secretbox = require('../util/Secretbox'); const secretbox = require('../util/Secretbox');
const { SILENCE_FRAME } = require('../util/Silence');
// The delay between packets when a user is considered to have stopped speaking // The delay between packets when a user is considered to have stopped speaking
// https://github.com/discordjs/discord.js/issues/3524#issuecomment-540373200 // https://github.com/discordjs/discord.js/issues/3524#issuecomment-540373200
@ -84,12 +86,30 @@ class PacketHandler extends EventEmitter {
const userStat = this.connection.ssrcMap.get(ssrc); const userStat = this.connection.ssrcMap.get(ssrc);
if (!userStat) return; if (!userStat) return;
let opusPacket;
const streamInfo = this.streams.get(userStat.userID);
// If the user is in video, we need to check if the packet is just silence
if (userStat.hasVideo) {
opusPacket = this.parseBuffer(buffer);
if (opusPacket instanceof Error) {
// Only emit an error if we were actively receiving packets from this user
if (streamInfo) {
this.emit('error', opusPacket);
return;
}
}
if (SILENCE_FRAME.equals(opusPacket)) {
// If this is a silence frame, pretend we never received it
return;
}
}
let speakingTimeout = this.speakingTimeouts.get(ssrc); let speakingTimeout = this.speakingTimeouts.get(ssrc);
if (typeof speakingTimeout === 'undefined') { if (typeof speakingTimeout === 'undefined') {
// Ensure at least the speaking bit is set. // Ensure at least the speaking bit is set.
// As the object is by reference, it's only needed once per client re-connect. // As the object is by reference, it's only needed once per client re-connect.
if (userStat.speaking === 0) { if (userStat.speaking === 0) {
userStat.speaking = 1; userStat.speaking = Speaking.FLAGS.SPEAKING;
} }
this.connection.onSpeaking({ user_id: userStat.userID, ssrc: ssrc, speaking: userStat.speaking }); this.connection.onSpeaking({ user_id: userStat.userID, ssrc: ssrc, speaking: userStat.speaking });
speakingTimeout = this.receiver.connection.client.setTimeout(() => { speakingTimeout = this.receiver.connection.client.setTimeout(() => {
@ -106,15 +126,17 @@ class PacketHandler extends EventEmitter {
speakingTimeout.refresh(); speakingTimeout.refresh();
} }
let stream = this.streams.get(userStat.userID); if (streamInfo) {
if (!stream) return; const { stream } = streamInfo;
stream = stream.stream; if (!opusPacket) {
const opusPacket = this.parseBuffer(buffer); opusPacket = this.parseBuffer(buffer);
if (opusPacket instanceof Error) { if (opusPacket instanceof Error) {
this.emit('error', opusPacket); this.emit('error', opusPacket);
return; return;
}
}
stream.push(opusPacket);
} }
stream.push(opusPacket);
} }
} }

View file

@ -10,4 +10,6 @@ class Silence extends Readable {
} }
} }
Silence.SILENCE_FRAME = SILENCE_FRAME;
module.exports = Silence; module.exports = Silence;

View file

@ -198,8 +198,9 @@ class GuildTemplate extends Base {
* @readonly * @readonly
*/ */
get guild() { get guild() {
return this.client.guilds.get(this.guildID) || null; return this.client.guilds.cache.get(this.guildID) || null;
} }
/** /**
* The URL of this template * The URL of this template
* @type {string} * @type {string}

View file

@ -28,12 +28,6 @@ class MessageReaction {
*/ */
this.message = message; this.message = message;
/**
* Whether the client has given this reaction
* @type {boolean}
*/
this.me = data.me;
/** /**
* A manager of the users that have given this reaction * A manager of the users that have given this reaction
* @type {ReactionUserManager} * @type {ReactionUserManager}
@ -54,6 +48,12 @@ class MessageReaction {
*/ */
this.count = data.count; this.count = data.count;
} }
/**
* Whether the client has given this reaction
* @type {boolean}
*/
this.me = data.me;
} }
/** /**