Skip to content

Commit 66f7b52

Browse files
Add anti AFK component (#177)
Keep members from taking up voice slots by moving them to AFK if they linger in a self-deafened state.
1 parent 8d31999 commit 66f7b52

1 file changed

Lines changed: 60 additions & 0 deletions

File tree

src/components/anti-afk.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
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

Comments
 (0)