2021-04-04 05:42:15 +00:00
|
|
|
import { VoiceServerUpdateData } from '../gateway/handlers/mod.ts'
|
|
|
|
import { VoiceStateOptions } from '../gateway/mod.ts'
|
|
|
|
import { Client } from '../client/mod.ts'
|
2020-12-20 09:11:37 +00:00
|
|
|
import {
|
|
|
|
GuildVoiceChannelPayload,
|
|
|
|
ModifyVoiceChannelOption,
|
2021-03-19 15:39:14 +00:00
|
|
|
ModifyVoiceChannelPayload
|
2020-12-20 09:11:37 +00:00
|
|
|
} from '../types/channel.ts'
|
|
|
|
import { CHANNEL } from '../types/endpoint.ts'
|
2021-03-19 15:39:14 +00:00
|
|
|
import { GuildChannel } from './channel.ts'
|
2020-11-08 07:57:24 +00:00
|
|
|
import { Guild } from './guild.ts'
|
2020-12-05 08:56:43 +00:00
|
|
|
import { VoiceState } from './voiceState.ts'
|
2021-03-30 17:18:24 +00:00
|
|
|
import { GuildChannelVoiceStatesManager } from '../managers/guildChannelVoiceStates.ts'
|
2021-03-31 02:05:21 +00:00
|
|
|
import { User } from './user.ts'
|
|
|
|
import { Member } from './member.ts'
|
2020-10-23 16:11:00 +00:00
|
|
|
|
2021-02-06 13:55:45 +00:00
|
|
|
export interface VoiceServerData extends VoiceServerUpdateData {
|
|
|
|
sessionID: string
|
|
|
|
}
|
|
|
|
|
2021-03-19 15:39:14 +00:00
|
|
|
export class VoiceChannel extends GuildChannel {
|
2020-10-23 16:11:00 +00:00
|
|
|
bitrate: string
|
|
|
|
userLimit: number
|
2021-03-30 17:18:24 +00:00
|
|
|
voiceStates = new GuildChannelVoiceStatesManager(
|
|
|
|
this.client,
|
|
|
|
this.guild.voiceStates,
|
|
|
|
this
|
|
|
|
)
|
2020-10-23 16:11:00 +00:00
|
|
|
|
2020-12-02 12:29:52 +00:00
|
|
|
constructor(client: Client, data: GuildVoiceChannelPayload, guild: Guild) {
|
2021-03-19 15:39:14 +00:00
|
|
|
super(client, data, guild)
|
2020-10-23 16:11:00 +00:00
|
|
|
this.bitrate = data.bitrate
|
|
|
|
this.userLimit = data.user_limit
|
2020-10-29 14:43:27 +00:00
|
|
|
}
|
|
|
|
|
2021-02-06 13:55:45 +00:00
|
|
|
/** Join the Voice Channel */
|
|
|
|
async join(
|
|
|
|
options?: VoiceStateOptions & { onlyJoin?: boolean }
|
|
|
|
): Promise<VoiceServerUpdateData> {
|
2020-12-05 08:56:43 +00:00
|
|
|
return await new Promise((resolve, reject) => {
|
2021-02-06 13:55:45 +00:00
|
|
|
let vcdata: VoiceServerData
|
|
|
|
let sessionID: string
|
2020-12-05 08:56:43 +00:00
|
|
|
let done = 0
|
|
|
|
|
|
|
|
const onVoiceStateAdd = (state: VoiceState): void => {
|
|
|
|
if (state.user.id !== this.client.user?.id) return
|
|
|
|
if (state.channel?.id !== this.id) return
|
2021-01-20 10:05:15 +00:00
|
|
|
this.client.off('voiceStateAdd', onVoiceStateAdd)
|
2020-12-05 08:56:43 +00:00
|
|
|
done++
|
2021-02-06 13:55:45 +00:00
|
|
|
sessionID = state.sessionID
|
|
|
|
if (done >= 2) {
|
|
|
|
vcdata.sessionID = sessionID
|
|
|
|
if (options?.onlyJoin !== true) {
|
|
|
|
}
|
|
|
|
resolve(vcdata)
|
|
|
|
}
|
2020-12-05 08:56:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const onVoiceServerUpdate = (data: VoiceServerUpdateData): void => {
|
|
|
|
if (data.guild.id !== this.guild.id) return
|
2021-02-06 13:55:45 +00:00
|
|
|
vcdata = (data as unknown) as VoiceServerData
|
2021-01-20 10:05:15 +00:00
|
|
|
this.client.off('voiceServerUpdate', onVoiceServerUpdate)
|
2020-12-05 08:56:43 +00:00
|
|
|
done++
|
2021-02-06 13:55:45 +00:00
|
|
|
if (done >= 2) {
|
|
|
|
vcdata.sessionID = sessionID
|
|
|
|
resolve(vcdata)
|
|
|
|
}
|
2020-12-05 08:56:43 +00:00
|
|
|
}
|
|
|
|
|
2021-01-24 16:46:10 +00:00
|
|
|
this.client.shards
|
|
|
|
.get(this.guild.shardID)
|
|
|
|
?.updateVoiceState(this.guild.id, this.id, options)
|
2020-12-05 08:56:43 +00:00
|
|
|
|
|
|
|
this.client.on('voiceStateAdd', onVoiceStateAdd)
|
|
|
|
this.client.on('voiceServerUpdate', onVoiceServerUpdate)
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
if (done < 2) {
|
2021-01-20 10:05:15 +00:00
|
|
|
this.client.off('voiceServerUpdate', onVoiceServerUpdate)
|
|
|
|
this.client.off('voiceStateAdd', onVoiceStateAdd)
|
2020-12-05 08:56:43 +00:00
|
|
|
reject(
|
|
|
|
new Error(
|
|
|
|
"Connection timed out - couldn't connect to Voice Channel"
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}, 1000 * 60)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-02-06 13:55:45 +00:00
|
|
|
/** Leave the Voice Channel */
|
2020-12-05 08:56:43 +00:00
|
|
|
leave(): void {
|
2021-01-24 16:46:10 +00:00
|
|
|
this.client.shards
|
|
|
|
.get(this.guild.shardID)
|
|
|
|
?.updateVoiceState(this.guild.id, undefined)
|
2020-12-05 08:56:43 +00:00
|
|
|
}
|
|
|
|
|
2020-12-03 05:28:20 +00:00
|
|
|
readFromData(data: GuildVoiceChannelPayload): void {
|
2020-10-29 14:43:27 +00:00
|
|
|
super.readFromData(data)
|
|
|
|
this.bitrate = data.bitrate ?? this.bitrate
|
|
|
|
this.userLimit = data.user_limit ?? this.userLimit
|
2020-10-23 16:11:00 +00:00
|
|
|
}
|
2020-12-20 09:11:37 +00:00
|
|
|
|
|
|
|
async edit(options?: ModifyVoiceChannelOption): Promise<VoiceChannel> {
|
|
|
|
const body: ModifyVoiceChannelPayload = {
|
|
|
|
name: options?.name,
|
|
|
|
position: options?.position,
|
|
|
|
permission_overwrites: options?.permissionOverwrites,
|
|
|
|
parent_id: options?.parentID,
|
|
|
|
bitrate: options?.bitrate,
|
|
|
|
user_limit: options?.userLimit
|
|
|
|
}
|
|
|
|
|
|
|
|
const resp = await this.client.rest.patch(CHANNEL(this.id), body)
|
|
|
|
|
|
|
|
return new VoiceChannel(this.client, resp, this.guild)
|
|
|
|
}
|
2021-03-31 02:05:21 +00:00
|
|
|
|
|
|
|
async disconnectMember(
|
|
|
|
member: User | Member | string
|
|
|
|
): Promise<Member | undefined> {
|
|
|
|
const memberID = typeof member === 'string' ? member : member.id
|
|
|
|
const memberVoiceState = await this.voiceStates.get(memberID)
|
|
|
|
|
|
|
|
return memberVoiceState?.disconnect()
|
|
|
|
}
|
|
|
|
|
|
|
|
async disconnectAll(): Promise<Member[]> {
|
|
|
|
const members: Member[] = []
|
|
|
|
for await (const memberVoiceState of this.voiceStates) {
|
|
|
|
const member = await memberVoiceState.disconnect()
|
|
|
|
if (member !== undefined) {
|
|
|
|
members.push(member)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return members
|
|
|
|
}
|
2020-10-23 16:11:00 +00:00
|
|
|
}
|