Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

disconnect automatically when no user in voice #53

Merged
merged 10 commits into from
May 11, 2023
26 changes: 25 additions & 1 deletion src/zundacord/app.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { entersState, getVoiceConnection, joinVoiceChannel, VoiceConnectionStatus } from "@discordjs/voice"
import { ActionRowBuilder, ActivityType, ApplicationCommandType, ButtonBuilder, ButtonInteraction, ButtonStyle, ChatInputCommandInteraction, Client, CommandInteraction, ContextMenuCommandBuilder, EmbedBuilder, GatewayIntentBits, Interaction, Message, MessageContextMenuCommandInteraction, Routes, SelectMenuBuilder, SelectMenuInteraction, SlashCommandBuilder, SlashCommandUserOption, User } from "discord.js"
import { ActionRowBuilder, ActivityType, ApplicationCommandType, ButtonBuilder, ButtonInteraction, ButtonStyle, ChatInputCommandInteraction, Client, CommandInteraction, ContextMenuCommandBuilder, EmbedBuilder, GatewayIntentBits, GuildBasedChannel, Interaction, Message, MessageContextMenuCommandInteraction, Routes, SelectMenuBuilder, SelectMenuInteraction, SlashCommandBuilder, SlashCommandUserOption, User, VoiceChannel, VoiceState } from "discord.js"
import { getReadableString } from "./utils"
import { StyledSpeaker, VoiceVoxClient } from "./voicevox"
import { Player } from "./player"
Expand All @@ -9,6 +9,7 @@ import { logger } from "./logger"
const COLOR_SUCCESS = 0x47ff94
const COLOR_FAILURE = 0xff4a47
const COLOR_ACTION = 0x45b5ff
const AUTO_DISCONNECT_TIMEOUT = 5000 //ms

const log = logger.child({ "module": "zundacord/app" })

Expand Down Expand Up @@ -47,6 +48,8 @@ export class Zundacord {
this.client.on("ready", this.onReady.bind(this))
this.client.on("messageCreate", this.onMessageCreate.bind(this))
this.client.on("interactionCreate", this.onInteractionCreate.bind(this))
this.client.on("voiceStateUpdate", this.onVoiceStateUpdate.bind(this));
log.debug(`registerd cmds`);
}

async start(): Promise<void> {
Expand Down Expand Up @@ -129,6 +132,27 @@ export class Zundacord {
this.queueMessage(msg, memberConfig?.voiceStyleId)
}

onVoiceStateUpdate(oldState: VoiceState, newState: VoiceState)
mnsinri marked this conversation as resolved.
Show resolved Hide resolved
{
const vc = getVoiceConnection(newState.guild.id)
if(!vc) {
return
}

const player = this.guildPlayers.get(newState.guild.id)
if (!player) {
log.debug(`bot is not in vc (player not found)`)
return
}

const channel = newState.guild.channels.cache.find(c => c.id === vc.joinConfig.channelId)
if(channel === undefined || !channel.isVoiceBased()) {
return
}

player.autoDisconnect(vc, channel, this.applicationId, AUTO_DISCONNECT_TIMEOUT);
sarisia marked this conversation as resolved.
Show resolved Hide resolved
}

async slashVoice(interaction: CommandInteraction<"cached">) {
let user = interaction.user

Expand Down
12 changes: 12 additions & 0 deletions src/zundacord/player.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { VoiceVoxClient } from "./voicevox";
import { Readable } from "stream";
import { once } from 'node:events'
import { logger } from "./logger"
import { VoiceBasedChannel } from "discord.js";


interface Message {
Expand All @@ -22,6 +23,7 @@ export class Player {
private readonly audioQueueSize: number = 5

private running: boolean = false
private disconnectTimeoutId: NodeJS.Timeout | undefined = undefined;

constructor(client: VoiceVoxClient) {
this.client = client
Expand All @@ -33,6 +35,16 @@ export class Player {
vc.subscribe(this.audioPlayer)
}

autoDisconnect(vc: VoiceConnection, channel: VoiceBasedChannel, appId: string, timeout: number = 5000) {
mnsinri marked this conversation as resolved.
Show resolved Hide resolved
clearTimeout(this.disconnectTimeoutId)
mnsinri marked this conversation as resolved.
Show resolved Hide resolved
this.disconnectTimeoutId = setTimeout(() => {
if(channel.members.size === 1 && channel.members.has(appId)) {
vc.disconnect();
}
this.disconnectTimeoutId = undefined
}, timeout)
}

skipCurrentMessage() {
this.audioPlayer.stop()
}
Expand Down