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

Voice receive broken for reconnected voice connections #359

Closed
Yahweasel opened this issue Feb 4, 2018 · 3 comments
Closed

Voice receive broken for reconnected voice connections #359

Yahweasel opened this issue Feb 4, 2018 · 3 comments

Comments

@Yahweasel
Copy link

If you connect to a voice channel in a guild, disconnect, then connect to a voice channel again (same or different), the second fails to receive any data, although showing all signs of connecting successfully. Example code:

const fs = require("fs");
const Eris = require("eris");
const config = JSON.parse(fs.readFileSync("config.json", "utf8"));
const client = new Eris(config.token);

var counter = 0;

function session(connection) {
    const sessionNum = ++counter;
    console.log("Starting session " + sessionNum);
    const opus = connection.receive("opus");
    opus.on("data", ()=>{
        console.log(sessionNum);
    });
    connection.on("disconnect", ()=>{
        console.log("Ending session " + sessionNum);
    });
}

client.on("messageCreate", (msg) => {
    if (msg.content === "join") {
        if (msg.member && msg.channel.guild && msg.member.voiceState.channelID) {
            var channel = msg.channel.guild.channels.get(msg.member.voiceState.channelID);
            if (!channel) return;
            channel.join({opusOnly:true}).then(session).catch(console.error);
        }
    } else if (msg.content === "leave") {
        if (msg.channel.guild) {
            var vc = client.voiceConnections.get(msg.channel.guild.id);
            if (!vc) return;
            vc.disconnect(); // Should channel.leave() instead, but this is what I have :)
        }
    }
});

client.connect();

Expected output:

Starting session 1
1
1
...
Ending session 1
Starting session 2
2
2
...
Ending session 2

Actual output:

Starting session 1
1
1
...
Ending session 1
Starting session 2
Ending session 2

Note that I somewhat naughtily used the undocumented VoiceConnection.disconnect function instead of VoiceChannel.leave, but the result is the same either way, it was just easier in this example :)

@Yahweasel
Copy link
Author

OK, never mind, the bug is SLIGHTLY weirder than I'd realized, as the actual output is:

Starting session 1
1
1
...
Ending session 1
Starting session 2
Ending session 1
Ending session 2

i.e., the disconnect event fires into the PREVIOUS session's callback. I assume the VoiceConnection is being reused, but it appears to be reused in a nonworking way.

@Yahweasel
Copy link
Author

Behold, the world's cheekiest (and thus best) workaround:

const fs = require("fs");
const Eris = require("eris");
const config = JSON.parse(fs.readFileSync("config.json", "utf8"));
const client = new Eris(config.token);

var counter = 0;

function session(connection, guild) {
    const sessionNum = ++counter;
    console.log("Starting session " + sessionNum);
    const opus = connection.receive("opus");
    opus.on("data", ()=>{
        console.log(sessionNum);
    });
    connection.on("disconnect", ()=>{
        console.log("Ending session " + sessionNum);
        client.voiceConnections.delete(guild.id);
    });
}

client.on("messageCreate", (msg) => {
    if (msg.content === "join") {
        if (msg.member && msg.channel.guild && msg.member.voiceState.channelID) {
            var channel = msg.channel.guild.channels.get(msg.member.voiceState.channelID);
            if (!channel) return;
            channel.join({opusOnly:true})
                .then((connection)=>{session(connection,msg.channel.guild);})
                .catch(console.error);
        }
    } else if (msg.content === "leave") {
        if (msg.channel.guild) {
            var me = msg.channel.guild.members.get(client.user.id);
            if (!me) return;
            var cid = me.voiceState.channelID;
            if (!cid) return;
            var channel = msg.channel.guild.channels.get(cid);
            if (!channel) return;
            channel.leave();
            /*
            var vc = client.voiceConnections.get(msg.channel.guild.id);
            if (!vc) return;
            vc.disconnect();
            */
        }
    }
});

client.connect();

So, yes, it has something to do with mis-reusing the voice connection. Presumably any existing VoiceConnection should universally be scrapped if you're doing a fresh join.

@abalabahaha abalabahaha changed the title Only first voice connection per guild works Voice receive broken for reconnected voice connections Feb 25, 2018
@abalabahaha
Copy link
Owner

Something on your end appears to have swallowed a rather useful error stacktrace

TypeError: this.receiveStreamOpus.destroy is not a function
    at VoiceConnection._destroy (/home/abal/Documents/eris/lib/voice/VoiceConnection.js:170:36)
    at Map.leave (/home/abal/Documents/eris/lib/voice/VoiceConnectionManager.js:113:20)
    at Client.leaveVoiceChannel (/home/abal/Documents/eris/lib/Client.js:289:31)

nandub added a commit to nandub/eris that referenced this issue Mar 14, 2018
* upstream/master:
  0.8.5
  Add option to manually offset ratelimiter
  Add Eris.VERSION (abalabahaha#364)
  Avoid negative average latency (fix abalabahaha#365)
  Code/docs tidying
  Check for missing msg.author in CommandClient (fix abalabahaha#362)
  Fix voice receive stream cleanup (fix abalabahaha#359)
  Fix Spotify presence update caching (abalabahaha#363)
  Update editStatus docs (abalabahaha#361)
  Expose userID for CommandClient reaction buttons
  Expose activity and application properties in Message
  Fix user caching for ban events
nandub added a commit to nandub/eris that referenced this issue Mar 14, 2018
* upstream/master:
  0.8.5
  Add option to manually offset ratelimiter
  Add Eris.VERSION (abalabahaha#364)
  Avoid negative average latency (fix abalabahaha#365)
  Code/docs tidying
  Check for missing msg.author in CommandClient (fix abalabahaha#362)
  Fix voice receive stream cleanup (fix abalabahaha#359)
  Fix Spotify presence update caching (abalabahaha#363)
  Update editStatus docs (abalabahaha#361)
  Expose userID for CommandClient reaction buttons
  Expose activity and application properties in Message
  Fix user caching for ban events
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants