149 lines
5.4 KiB
JavaScript
149 lines
5.4 KiB
JavaScript
|
"use strict";
|
||
|
|
||
|
const Base = require("../structures/Base");
|
||
|
const Collection = require("../util/Collection");
|
||
|
|
||
|
class VoiceConnectionManager extends Collection {
|
||
|
constructor(vcObject) {
|
||
|
super(vcObject || require("./VoiceConnection"));
|
||
|
this.pendingGuilds = {};
|
||
|
}
|
||
|
|
||
|
join(guildID, channelID, options) {
|
||
|
const connection = this.get(guildID);
|
||
|
if(connection && connection.ws) {
|
||
|
connection.switchChannel(channelID);
|
||
|
if(connection.ready) {
|
||
|
return Promise.resolve(connection);
|
||
|
} else {
|
||
|
return new Promise((res, rej) => {
|
||
|
const disconnectHandler = () => {
|
||
|
connection.removeListener("ready", readyHandler);
|
||
|
connection.removeListener("error", errorHandler);
|
||
|
rej(new Error("Disconnected"));
|
||
|
};
|
||
|
const readyHandler = () => {
|
||
|
connection.removeListener("disconnect", disconnectHandler);
|
||
|
connection.removeListener("error", errorHandler);
|
||
|
res(connection);
|
||
|
};
|
||
|
const errorHandler = (err) => {
|
||
|
connection.removeListener("disconnect", disconnectHandler);
|
||
|
connection.removeListener("ready", readyHandler);
|
||
|
connection.disconnect();
|
||
|
rej(err);
|
||
|
};
|
||
|
connection.once("ready", readyHandler).once("disconnect", disconnectHandler).once("error", errorHandler);
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
return new Promise((res, rej) => {
|
||
|
this.pendingGuilds[guildID] = {
|
||
|
channelID: channelID,
|
||
|
options: options || {},
|
||
|
res: res,
|
||
|
rej: rej,
|
||
|
timeout: setTimeout(() => {
|
||
|
delete this.pendingGuilds[guildID];
|
||
|
rej(new Error("Voice connection timeout"));
|
||
|
}, 10000)
|
||
|
};
|
||
|
});
|
||
|
}
|
||
|
|
||
|
leave(guildID) {
|
||
|
const connection = this.get(guildID);
|
||
|
if(!connection) {
|
||
|
return;
|
||
|
}
|
||
|
connection.disconnect();
|
||
|
connection._destroy();
|
||
|
this.remove(connection);
|
||
|
}
|
||
|
|
||
|
switch(guildID, channelID) {
|
||
|
const connection = this.get(guildID);
|
||
|
if(!connection) {
|
||
|
return;
|
||
|
}
|
||
|
connection.switch(channelID);
|
||
|
}
|
||
|
|
||
|
voiceServerUpdate(data) {
|
||
|
if(this.pendingGuilds[data.guild_id] && this.pendingGuilds[data.guild_id].timeout) {
|
||
|
clearTimeout(this.pendingGuilds[data.guild_id].timeout);
|
||
|
this.pendingGuilds[data.guild_id].timeout = null;
|
||
|
}
|
||
|
let connection = this.get(data.guild_id);
|
||
|
if(!connection) {
|
||
|
if(!this.pendingGuilds[data.guild_id]) {
|
||
|
return;
|
||
|
}
|
||
|
connection = this.add(new this.baseObject(data.guild_id, {
|
||
|
shard: data.shard,
|
||
|
opusOnly: this.pendingGuilds[data.guild_id].options.opusOnly,
|
||
|
shared: this.pendingGuilds[data.guild_id].options.shared
|
||
|
}));
|
||
|
}
|
||
|
connection.connect({
|
||
|
channel_id: (this.pendingGuilds[data.guild_id] || connection).channelID,
|
||
|
endpoint: data.endpoint,
|
||
|
token: data.token,
|
||
|
session_id: data.session_id,
|
||
|
user_id: data.user_id
|
||
|
});
|
||
|
if(!this.pendingGuilds[data.guild_id] || this.pendingGuilds[data.guild_id].waiting) {
|
||
|
return;
|
||
|
}
|
||
|
this.pendingGuilds[data.guild_id].waiting = true;
|
||
|
const disconnectHandler = () => {
|
||
|
connection = this.get(data.guild_id);
|
||
|
if(connection) {
|
||
|
connection.removeListener("ready", readyHandler);
|
||
|
connection.removeListener("error", errorHandler);
|
||
|
}
|
||
|
if(this.pendingGuilds[data.guild_id]) {
|
||
|
this.pendingGuilds[data.guild_id].rej(new Error("Disconnected"));
|
||
|
delete this.pendingGuilds[data.guild_id];
|
||
|
}
|
||
|
};
|
||
|
const readyHandler = () => {
|
||
|
connection = this.get(data.guild_id);
|
||
|
if(connection) {
|
||
|
connection.removeListener("disconnect", disconnectHandler);
|
||
|
connection.removeListener("error", errorHandler);
|
||
|
}
|
||
|
if(this.pendingGuilds[data.guild_id]) {
|
||
|
this.pendingGuilds[data.guild_id].res(connection);
|
||
|
delete this.pendingGuilds[data.guild_id];
|
||
|
}
|
||
|
};
|
||
|
const errorHandler = (err) => {
|
||
|
connection = this.get(data.guild_id);
|
||
|
if(connection) {
|
||
|
connection.removeListener("disconnect", disconnectHandler);
|
||
|
connection.removeListener("ready", readyHandler);
|
||
|
connection.disconnect();
|
||
|
}
|
||
|
if(this.pendingGuilds[data.guild_id]) {
|
||
|
this.pendingGuilds[data.guild_id].rej(err);
|
||
|
delete this.pendingGuilds[data.guild_id];
|
||
|
}
|
||
|
};
|
||
|
connection.once("ready", readyHandler).once("disconnect", disconnectHandler).once("error", errorHandler);
|
||
|
}
|
||
|
|
||
|
toString() {
|
||
|
return "[VoiceConnectionManager]";
|
||
|
}
|
||
|
|
||
|
toJSON(props = []) {
|
||
|
return Base.prototype.toJSON.call(this, [
|
||
|
"pendingGuilds",
|
||
|
...props
|
||
|
]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
module.exports = VoiceConnectionManager;
|