|
| 1 | +import { strict as assert } from "assert"; |
| 2 | + |
| 3 | +import * as Discord from "discord.js"; |
| 4 | + |
| 5 | +import { SECOND } from "../common.js"; |
| 6 | +import { BotComponent } from "../bot-component.js"; |
| 7 | +import { clear_timeout, set_timeout } from "../utils/node.js"; |
| 8 | + |
| 9 | +export default class AntiAFK extends BotComponent { |
| 10 | + private countdown = new Map<string, NodeJS.Timeout>(); |
| 11 | + |
| 12 | + private check_voice_state(old_state: Discord.VoiceState, new_state: Discord.VoiceState) { |
| 13 | + if ((!new_state.selfDeaf || new_state.channel != old_state.channel) && this.countdown.has(new_state.id)) { |
| 14 | + clear_timeout(this.countdown.get(new_state.id)); |
| 15 | + this.countdown.delete(new_state.id); |
| 16 | + } |
| 17 | + if ( |
| 18 | + new_state.channel != null && |
| 19 | + new_state.channelId != this.wheatley.guild.afkChannelId && |
| 20 | + new_state.selfDeaf |
| 21 | + ) { |
| 22 | + assert(new_state.member); |
| 23 | + const member = new_state.member; |
| 24 | + const timeout = set_timeout( |
| 25 | + () => { |
| 26 | + member.voice |
| 27 | + .fetch() |
| 28 | + .then(async current_state => { |
| 29 | + if (current_state.selfDeaf && current_state.channelId != this.wheatley.guild.afkChannelId) { |
| 30 | + await member.voice.setChannel(this.wheatley.guild.afkChannel); |
| 31 | + } |
| 32 | + }) |
| 33 | + .catch(this.wheatley.critical_error.bind(this.wheatley)); |
| 34 | + this.countdown.delete(new_state.id); |
| 35 | + }, |
| 36 | + (this.wheatley.guild.afkTimeout + 30) * SECOND, |
| 37 | + ); |
| 38 | + this.countdown.set(new_state.id, timeout); |
| 39 | + } |
| 40 | + } |
| 41 | + |
| 42 | + override async on_voice_state_update(old_state: Discord.VoiceState, new_state: Discord.VoiceState) { |
| 43 | + this.check_voice_state(old_state, new_state); |
| 44 | + } |
| 45 | + |
| 46 | + override async on_ready() { |
| 47 | + await Promise.all( |
| 48 | + this.wheatley.guild.channels.cache |
| 49 | + .filter(c => c.isVoiceBased()) |
| 50 | + .map(async channel => { |
| 51 | + await Promise.all( |
| 52 | + channel.members.map(async member => { |
| 53 | + const voice_state = await member.voice.fetch(); |
| 54 | + this.check_voice_state(voice_state, voice_state); |
| 55 | + }), |
| 56 | + ); |
| 57 | + }), |
| 58 | + ); |
| 59 | + } |
| 60 | +} |
0 commit comments