diff options
| author | Fuwn <[email protected]> | 2025-11-06 18:24:20 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2025-11-06 18:24:35 -0800 |
| commit | 7fde9bf0b76d929605f7981f8cc7f1846438a938 (patch) | |
| tree | f8888def52950aa60d43a5ffda28984646dab13d | |
| parent | feat(gateway:listeners): Add privileged access monitoring (diff) | |
| download | umabotdiscord-7fde9bf0b76d929605f7981f8cc7f1846438a938.tar.xz umabotdiscord-7fde9bf0b76d929605f7981f8cc7f1846438a938.zip | |
feat(gateway:listeners): Add #super-freak manager
| -rw-r--r-- | packages/gateway/src/listeners/clientReady/index.ts | 2 | ||||
| -rw-r--r-- | packages/gateway/src/listeners/superFreakChannel.ts | 163 |
2 files changed, 165 insertions, 0 deletions
diff --git a/packages/gateway/src/listeners/clientReady/index.ts b/packages/gateway/src/listeners/clientReady/index.ts index 06c24b2..8c43d3b 100644 --- a/packages/gateway/src/listeners/clientReady/index.ts +++ b/packages/gateway/src/listeners/clientReady/index.ts @@ -6,6 +6,7 @@ import { initializeMessageStatistics } from "../messageStatistics"; import { initializePersonaSystem } from "../messageCreate/personaRandomMessage"; import { initializeConversationStarterSystem } from "../messageCreate/dailyConversationStarter"; import { initializeWelcomeSystem } from "../memberJoin"; +import { initializeSuperFreakChannelSystem } from "../superFreakChannel"; export const handleClientReady = (client: Client) => { client.once(Events.ClientReady, async (readyClient) => { @@ -15,6 +16,7 @@ export const handleClientReady = (client: Client) => { initializePersonaSystem(readyClient); initializeConversationStarterSystem(readyClient); initializeWelcomeSystem(readyClient); + await initializeSuperFreakChannelSystem(readyClient); await handleUmagramCatchup(readyClient); // Character claim tracker will initialize on first use }); diff --git a/packages/gateway/src/listeners/superFreakChannel.ts b/packages/gateway/src/listeners/superFreakChannel.ts new file mode 100644 index 0000000..8c292f4 --- /dev/null +++ b/packages/gateway/src/listeners/superFreakChannel.ts @@ -0,0 +1,163 @@ +import { Client, EmbedBuilder } from "discord.js"; +import { CENTRAL_GUILD_ID } from "../constants"; +import { logUnexpectedDiscordAPIError } from "../utilities"; + +const SUPER_FREAK_CHANNEL_ID = "1410333697701314791"; +const PRIVILEGED_ACCESS_ROLE_ID = "1423213971422580736"; +const ALERT_CHANNEL_ID = "1436163337955184752"; + +const getRandomNonMultipleOf24Hours = ( + minHours: number = 1, + maxHours: number = 23, +): number => { + let hours: number; + + do { + hours = Math.floor(Math.random() * (maxHours - minHours + 1)) + minHours; + } while (24 % hours === 0); + + return hours * 60 * 60 * 1000; +}; + +class SuperFreakChannelSystem { + private client: Client | null = null; + private isOpen: boolean = false; + private timeoutHandle: any | null = null; + private nextToggleTime: Date | null = null; + + constructor() { + // + } + + public async initialize(client: Client) { + this.client = client; + + await this.checkCurrentState(); + this.scheduleNextToggle(); + } + + private async checkCurrentState() { + if (!this.client) return; + + try { + const guild = this.client.guilds.cache.get(CENTRAL_GUILD_ID); + + if (!guild) return; + + const channel = guild.channels.cache.get(SUPER_FREAK_CHANNEL_ID); + + if (!channel || !channel.isTextBased() || channel.isThread()) return; + + const privilegedRole = guild.roles.cache.get(PRIVILEGED_ACCESS_ROLE_ID); + + if (!privilegedRole) return; + + const permissions = channel.permissionsFor(privilegedRole); + this.isOpen = permissions?.has("ViewChannel") ?? false; + } catch (error) { + logUnexpectedDiscordAPIError(error); + } + } + + private async sendAlert() { + if (!this.client) return; + + try { + const alertChannel = this.client.channels.cache.get(ALERT_CHANNEL_ID); + + if ( + !alertChannel || + !alertChannel.isTextBased() || + alertChannel.isDMBased() + ) { + return; + } + + const embed = new EmbedBuilder() + .setTitle(this.isOpen ? "🔓 Channel Opened" : "🔒 Channel Closed") + .setColor(this.isOpen ? "#00ff00" : "#ff0000") + .addFields({ + name: "Channel", + value: `<#${SUPER_FREAK_CHANNEL_ID}>`, + inline: true, + }); + + if (this.nextToggleTime) { + const nextAction = this.isOpen ? "close" : "reopen"; + const unixTimestamp = Math.floor(this.nextToggleTime.getTime() / 1000); + const discordTimestamp = `<t:${unixTimestamp}:F>`; + + embed.addFields({ + name: `Will ${nextAction}`, + value: discordTimestamp, + inline: false, + }); + } + + embed.setTimestamp(); + await alertChannel.send({ embeds: [embed] }); + } catch (error) { + logUnexpectedDiscordAPIError(error); + } + } + + private async toggleChannel() { + if (!this.client) return; + + try { + const guild = this.client.guilds.cache.get(CENTRAL_GUILD_ID); + + if (!guild) return; + + const channel = guild.channels.cache.get(SUPER_FREAK_CHANNEL_ID); + + if (!channel || !channel.isTextBased() || channel.isThread()) return; + + const privilegedRole = guild.roles.cache.get(PRIVILEGED_ACCESS_ROLE_ID); + + if (!privilegedRole) return; + + this.isOpen = !this.isOpen; + + await channel.permissionOverwrites.edit(privilegedRole, { + ViewChannel: this.isOpen, + }); + + this.scheduleNextToggle(); + await this.sendAlert(); + } catch (error) { + logUnexpectedDiscordAPIError(error); + } + } + + private scheduleNextToggle() { + if (this.timeoutHandle) clearTimeout(this.timeoutHandle); + + const minHours = this.isOpen ? 5 : 3; + const maxHours = this.isOpen ? 11 : 5; + const duration = getRandomNonMultipleOf24Hours(minHours, maxHours); + + this.nextToggleTime = new Date(Date.now() + duration); + this.timeoutHandle = setTimeout(() => { + this.toggleChannel(); + }, duration); + } + + public destroy() { + if (this.timeoutHandle) { + clearTimeout(this.timeoutHandle); + + this.timeoutHandle = null; + } + } +} + +let superFreakChannelSystem: SuperFreakChannelSystem | null = null; + +export const initializeSuperFreakChannelSystem = async (client: Client) => { + if (superFreakChannelSystem) superFreakChannelSystem.destroy(); + + superFreakChannelSystem = new SuperFreakChannelSystem(); + + await superFreakChannelSystem.initialize(client); +}; |