From b7955fea06d6c84ad4a93aa48509aae5b13ef16a Mon Sep 17 00:00:00 2001 From: Mogyuchi Date: Sun, 21 May 2023 09:15:08 +0900 Subject: [PATCH] =?UTF-8?q?=E5=8F=AF=E8=83=BD=E3=81=AA=E5=A0=B4=E5=90=88?= =?UTF-8?q?=E3=80=81=E5=88=A5=E3=81=AEVC=E3=81=A7=E4=BD=BF=E3=82=8F?= =?UTF-8?q?=E3=82=8C=E3=81=A6=E3=81=84=E3=82=8BBot=E3=82=92=E5=85=A5?= =?UTF-8?q?=E3=82=8C=E6=9B=BF=E3=81=88=E3=81=A6=E3=81=A7=E3=82=82=E5=90=8C?= =?UTF-8?q?=E3=81=98Bot=E3=82=92=E4=BD=BF=E3=81=86=E3=82=88=E3=81=86?= =?UTF-8?q?=E3=81=AB=E4=BF=AE=E6=AD=A3=20(#544)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/connectionCtx.ts | 5 ++--- src/guildCtx.ts | 40 ++++++++++++++++++++++++++++++++-------- src/index.ts | 27 ++++++++++++++++++++------- 3 files changed, 54 insertions(+), 18 deletions(-) diff --git a/src/connectionCtx.ts b/src/connectionCtx.ts index 49a347ef..6ae02214 100644 --- a/src/connectionCtx.ts +++ b/src/connectionCtx.ts @@ -20,7 +20,6 @@ import { Message, ChatInputCommandInteraction, type DiscordErrorData, - type TextBasedChannel, type GuildTextBasedChannel, } from 'discord.js' import { Queue } from './utils.js' @@ -28,12 +27,12 @@ import { fetchAudioStream } from './voiceRead.js' import { getUserSetting } from './db.js' class ConnectionContext { - readChannel: TextBasedChannel + readChannel: GuildTextBasedChannel readQueue: any player: AudioPlayer | null = null connection: VoiceConnection - constructor(readChannel: TextBasedChannel, connection: VoiceConnection) { + constructor(readChannel: GuildTextBasedChannel, connection: VoiceConnection) { this.readChannel = readChannel this.readQueue = new Queue(this._readMessage.bind(this)) this.connection = connection diff --git a/src/guildCtx.ts b/src/guildCtx.ts index ccd56b46..60022c64 100644 --- a/src/guildCtx.ts +++ b/src/guildCtx.ts @@ -6,7 +6,7 @@ import { ChannelType, } from 'discord.js' import { WorkerClientMap } from './worker.js' -import { workerClientMap } from './index.js' +import { client, workerClientMap } from './index.js' import { ConnectionCtxManager } from './connectionCtx.js' const getBots = async (guild: Guild, worker: WorkerClientMap) => { @@ -45,18 +45,42 @@ class GuildContext { let workerId = (await this.bots)[vcArray.indexOf(voiceChannel)] - if ( - workerId === undefined || - [...this.connectionManager.values()].find( - (v) => v.connection.joinConfig.group === workerId, - ) - ) { + if (workerId === undefined) { workerId = (await this.bots).find( (botId) => ![...this.connectionManager.values()] .map((connectionCtx) => connectionCtx.connection.joinConfig.group) .includes(botId), ) + } else { + const oldConnectionCtx = [...this.connectionManager.values()].find( + (v) => v.connection.joinConfig.group === workerId, + ) + if (oldConnectionCtx !== undefined) { + const oldVoiceChannel = await client.channels + .fetch(oldConnectionCtx.connection.joinConfig.channelId!) + .then((channels) => { + return channels?.type === ChannelType.GuildVoice ? channels : null + }) + const forOldCtxWorkerId = (await this.bots).find( + (botId) => + ![...this.connectionManager.values()] + .map((connectionCtx) => connectionCtx.connection.joinConfig.group) + .includes(botId) && botId !== workerId, + ) + if (forOldCtxWorkerId === undefined) { + throw Error('No worker') + } + this.leave(oldVoiceChannel!) + try { + this.connectionManager.connectionJoin( + oldVoiceChannel!, + this.guild.id, + oldConnectionCtx.readChannel, + workerClientMap.get(forOldCtxWorkerId)!, + ) + } catch {} + } } if (workerId === undefined) { throw Error('No worker') @@ -72,7 +96,7 @@ class GuildContext { } catch {} return worker } - async leave(voiceChannel: VoiceChannel) { + leave(voiceChannel: VoiceChannel) { if (!this.connectionManager.channelMap.has(voiceChannel)) throw Error() const workerId = this.connectionManager.connectionLeave(voiceChannel) return workerId diff --git a/src/index.ts b/src/index.ts index f5c7f23c..ca3f7dfa 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,6 +11,7 @@ import type { SignalConstants } from 'os' import { getUserSetting } from './db.js' import { WorkerClientMap } from './worker.js' import { joinMessageRun } from './joinMessage.js' +import { ChannelType } from 'discord.js' const debug__ErrorHandler = debug('index.js:ErrorHandler') let isCalledDestroy = false @@ -84,17 +85,29 @@ client.on('messageCreate', async (message: typings.Message) => { connectionManager.get(message.channel)!.addMessage(convertedMessage, message) }) -client.on('voiceStateUpdate', (oldState, newState) => { +client.on('voiceStateUpdate', async (oldState, newState) => { + if (oldState.channel?.type !== ChannelType.GuildVoice) return const guildCtx = guildCtxManager.get(newState.guild) if ( (newState.channelId == null && - newState.id === client.user?.id && - oldState.channel instanceof VoiceChannel && - guildCtx.connectionManager.channelMap.has(oldState.channel)) || - (oldState.channel instanceof VoiceChannel && - guildCtx.connectionManager.channelMap.has(oldState.channel) && - oldState.channel.members.size === 1) + (await guildCtx.bots).includes(newState.id) && + [...guildCtx.connectionManager.values()].find( + (connectionCtx) => + connectionCtx.connection.joinConfig.channelId === + oldState.channelId && + connectionCtx.connection.joinConfig.group === oldState.id, + )) || + (guildCtx.connectionManager.channelMap.has(oldState.channel) && + oldState.channel.members.size === 1 && + oldState.channel.members.every((member) => + [...guildCtx.connectionManager.values()].find( + (connectionCtx) => + connectionCtx.connection.joinConfig.channelId === + oldState.channelId && + connectionCtx.connection.joinConfig.group === member.id, + ), + )) ) { guildCtx.connectionManager.channelMap .get(oldState.channel)!