harmony/src/structures/guildVoiceChannel.ts

111 lines
3.3 KiB
TypeScript
Raw Normal View History

import { VoiceServerUpdateData } from '../gateway/handlers/index.ts'
import { VoiceStateOptions } from '../gateway/index.ts'
import { Client } from '../models/client.ts'
2020-12-20 09:11:37 +00:00
import {
GuildVoiceChannelPayload,
ModifyVoiceChannelOption,
ModifyVoiceChannelPayload
2020-12-20 09:11:37 +00:00
} from '../types/channel.ts'
import { CHANNEL } from '../types/endpoint.ts'
import { GuildChannel } from './channel.ts'
2020-11-08 07:57:24 +00:00
import { Guild } from './guild.ts'
import { VoiceState } from './voiceState.ts'
2021-02-06 13:55:45 +00:00
export interface VoiceServerData extends VoiceServerUpdateData {
sessionID: string
}
export class VoiceChannel extends GuildChannel {
bitrate: string
userLimit: number
2020-12-02 12:29:52 +00:00
constructor(client: Client, data: GuildVoiceChannelPayload, guild: Guild) {
super(client, data, guild)
this.bitrate = data.bitrate
this.userLimit = data.user_limit
}
2021-02-06 13:55:45 +00:00
/** Join the Voice Channel */
async join(
options?: VoiceStateOptions & { onlyJoin?: boolean }
): Promise<VoiceServerUpdateData> {
return await new Promise((resolve, reject) => {
2021-02-06 13:55:45 +00:00
let vcdata: VoiceServerData
let sessionID: string
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)
done++
2021-02-06 13:55:45 +00:00
sessionID = state.sessionID
if (done >= 2) {
vcdata.sessionID = sessionID
if (options?.onlyJoin !== true) {
}
resolve(vcdata)
}
}
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)
done++
2021-02-06 13:55:45 +00:00
if (done >= 2) {
vcdata.sessionID = sessionID
resolve(vcdata)
}
}
2021-01-24 16:46:10 +00:00
this.client.shards
.get(this.guild.shardID)
?.updateVoiceState(this.guild.id, this.id, options)
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)
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 */
leave(): void {
2021-01-24 16:46:10 +00:00
this.client.shards
.get(this.guild.shardID)
?.updateVoiceState(this.guild.id, undefined)
}
2020-12-03 05:28:20 +00:00
readFromData(data: GuildVoiceChannelPayload): void {
super.readFromData(data)
this.bitrate = data.bitrate ?? this.bitrate
this.userLimit = data.user_limit ?? this.userLimit
}
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)
}
}