eris-discordbot-template/node_modules/eris/lib/voice/VoiceConnectionManager.js
2023-11-29 18:23:54 +03:00

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;