import { ClusterClient } from 'detritus-client' ; import { ClientEvents } from 'detritus-client/lib/constants' ; import { EventSubscription } from 'detritus-utils' ; import { Store } from './store' ; import { RequestContext , fetchGuildSettings , putGuildSettings } from '../api' ; import { GuildSettings } from '../api/structures/guildsettings' ; import { RedisChannels } from '../constants' ; import { RedisSpewer } from '../redis' ; import { RedisPayloads } from '../types' ; class GuildSettingsStore extends Store < string , GuildSettings > { constructor ( ) { super ( { expire : 2 * 60 * 60 * 1000 } ) ; } insert ( payload ) { this . set ( payload . id , payload ) ; } async getOrFetch ( context , guildId ) { let settings = null ; if ( GuildSettingsPromisesStore . has ( guildId ) ) { const promise = GuildSettingsPromisesStore . get ( guildId ) as GuildSettingsPromise ; settings = await promise ; } else { if ( this . has ( guildId ) ) { settings = this . get ( guildId ) as GuildSettings ; } else { settings = await this . fetch ( context , guildId ) ; } } return settings ; } async fetch ( context , guildId ) { let promise ; if ( GuildSettingsPromisesStore . has ( guildId ) ) { promise = GuildSettingsPromisesStore . get ( guildId ) as GuildSettingsPromise ; } else { promise = new Promise ( async ( resolve ) => { const { client } = context ; const guild = client . guilds . get ( guildId ) ; try { let settings ; if ( guild ) { settings = await putGuildSettings ( context , guildId , { icon : guild . icon , name : guild . name , } ) ; } else { settings = await fetchGuildSettings ( context , guildId ) ; } this . insert ( settings ) ; resolve ( settings ) ; } catch ( error ) { resolve ( null ) ; } GuildSettingsPromisesStore . delete ( guildId ) ; } ) ; GuildSettingsPromisesStore . set ( guildId , promise ) ; } return promise ; } create ( cluster , redis ) { const subscriptions = [ ] ; { const subscription = cluster . subscribe ( ClientEvents . CHANNEL_DELETE , async ( event ) => { const { channel , shard } = event ; const { guildId } = channel ; if ( guildId && this . has ( guildId ) ) { const settings = this . get ( guildId ) as GuildSettings ; { const loggers = settings . loggers . filter ( ( logger ) => logger . channelId === channel . id ) ; for ( let logger of loggers ) { await logger . delete ( shard ) ; } } { const disabledCommands = settings . disabledCommands . filter ( ( disabledCommand ) => disabledCommand . id === channel . id ) ; for ( let disabledCommand of disabledCommands ) { } } { const allowlist = settings . allowlist . filter ( ( allowed ) => allowed . id === channel . id ) ; for ( let allowed of allowlist ) { } } { const blocklist = settings . blocklist . filter ( ( blocked ) => blocked . id === channel . id ) ; for ( let blocked of blocklist ) { } } } } ) ; subscriptions . push ( subscription ) ; } { const subscription = cluster . subscribe ( ClientEvents . GUILD_DELETE , ( event ) => { const { guildId } = event ; this . delete ( guildId ) ; } ) ; subscriptions . push ( subscription ) ; } { const subscription = cluster . subscribe ( ClientEvents . WEBHOOKS_UPDATE , async ( event ) => { const { channelId , guildId , shard } = event ; if ( this . has ( guildId ) ) { const channel = shard . channels . get ( channelId ) ; const settings = this . get ( guildId ) as GuildSettings ; const loggers = settings . loggers . filter ( ( logger ) => logger . channelId === channelId ) ; if ( loggers . length && channel && channel . canManageWebhooks ) { try { const webhooks = await shard . rest . fetchChannelWebhooks ( channelId ) ; for ( let logger of loggers ) { if ( logger . webhookId && ! webhooks . has ( logger . webhookId ) ) { settings . loggers . delete ( logger . key ) ; await logger . delete ( shard ) ; } } } catch ( error ) { } } } } ) ; subscriptions . push ( subscription ) ; } { const subscription = redis . subscribe ( RedisChannels . GUILD_ALLOWLIST_UPDATE , ( payload ) => { if ( this . has ( payload . id ) ) { const settings = this . get ( payload . id ) as GuildSettings ; settings . merge ( payload ) ; } } ) ; subscriptions . push ( subscription ) ; } { const subscription = redis . subscribe ( RedisChannels . GUILD_BLOCKLIST_UPDATE , ( payload ) => { if ( this . has ( payload . id ) ) { const settings = this . get ( payload . id ) as GuildSettings ; settings . merge ( payload ) ; } } ) ; subscriptions . push ( subscription ) ; } { const subscription = redis . subscribe ( RedisChannels . GUILD_DISABLED_COMMAND_UPDATE , ( payload ) => { if ( this . has ( payload . id ) ) { const settings = this . get ( payload . id ) as GuildSettings ; settings . merge ( payload ) ; } } ) ; subscriptions . push ( subscription ) ; } { const subscription = redis . subscribe ( RedisChannels . GUILD_LOGGER_UPDATE , ( payload ) => { if ( this . has ( payload . id ) ) { const settings = this . get ( payload . id ) as GuildSettings ; settings . merge ( payload ) ; } } ) ; subscriptions . push ( subscription ) ; } { const subscription = redis . subscribe ( RedisChannels . GUILD_PREFIX_UPDATE , ( payload ) => { if ( this . has ( payload . id ) ) { const settings = this . get ( payload . id ) as GuildSettings ; settings . merge ( payload ) ; } } ) ; subscriptions . push ( subscription ) ; } { const subscription = redis . subscribe ( RedisChannels . GUILD_SETTINGS_UPDATE , ( payload ) => { if ( this . has ( payload . id ) ) { const settings = this . get ( payload . id ) as GuildSettings ; settings . merge ( payload ) ; } } ) ; subscriptions . push ( subscription ) ; } return subscriptions ; } } export default new GuildSettingsStore ( ) ; export type GuildSettingsPromise = Promise < GuildSettings | null > ; class GuildSettingsPromises extends Store < string , GuildSettingsPromise > { insert ( guildId , promise ) { this . set ( guildId , promise ) ; } } export const GuildSettingsPromisesStore = new GuildSettingsPromises ( ) ;