From f93bcf9836a1909495a767e588ce4b36dba471e6 Mon Sep 17 00:00:00 2001 From: Skillz4Killz <23035000+Skillz4Killz@users.noreply.github.com> Date: Tue, 12 Oct 2021 21:30:01 +0000 Subject: [PATCH] a few handlers --- src/bot.ts | 45 +++- src/cache.ts | 244 ++---------------- src/handlers/channels/CHANNEL_DELETE.ts | 51 ++-- src/handlers/channels/CHANNEL_PINS_UPDATE.ts | 20 +- src/handlers/channels/CHANNEL_UPDATE.ts | 19 +- .../channels/STAGE_INSTANCE_CREATE.ts | 16 +- .../channels/STAGE_INSTANCE_DELETE.ts | 16 +- .../channels/STAGE_INSTANCE_UPDATE.ts | 16 +- src/transformers/channel.ts | 6 + 9 files changed, 140 insertions(+), 293 deletions(-) diff --git a/src/bot.ts b/src/bot.ts index e4c1224b9..df02ca02e 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -33,7 +33,7 @@ import { transformMember, transformUser } from "./transformers/member.ts"; import { SnakeCasedPropertiesDeep } from "./types/util.ts"; import { Channel } from "./types/channels/channel.ts"; import { DiscordenoChannel, transformChannel } from "./transformers/channel.ts"; -import { transformVoiceState } from "./transformers/voice_state.ts"; +import { DiscordenoVoiceState, transformVoiceState } from "./transformers/voice_state.ts"; import { transformRole } from "./transformers/role.ts"; import { transformMessage } from "./transformers/message.ts"; import { DiscordenoGuild, transformGuild } from "./transformers/guild.ts"; @@ -67,6 +67,7 @@ import { delay, validateSlashOptionChoices, validateSlashOptions } from "./util/ import { iconBigintToHash, iconHashToBigInt } from "./util/hash.ts"; import { validateLength } from "./util/validate_length.ts"; import { processGlobalQueue } from "./rest/process_global_queue.ts"; +import { ChannelPinsUpdate } from "./types/channels/channel_pins_update.ts"; export async function createBot(options: CreateBotOptions) { return { @@ -101,6 +102,9 @@ export async function createBot(options: CreateBotOptions) { set: async function (id: bigint, guild: DiscordenoChannel): Promise { return; }, + delete: async function (id: bigint): Promise { + return; + }, }, members: { get: async function (id: bigint): Promise { @@ -164,6 +168,13 @@ export function createEventHandlers(events: Partial): EventHandle channelCreate: events.channelCreate ?? ignore, debug: events.debug ?? ignore, dispatchRequirements: events.dispatchRequirements ?? ignore, + voiceChannelLeave: events.voiceChannelLeave ?? ignore, + channelDelete: events.channelDelete ?? ignore, + channelPinsUpdate: events.channelPinsUpdate ?? ignore, + channelUpdate: events.channelUpdate ?? ignore, + stageInstanceCreate: events.stageInstanceCreate ?? ignore, + stageInstanceDelete: events.stageInstanceDelete ?? ignore, + stageInstanceUpdate: events.stageInstanceUpdate ?? ignore, }; } @@ -489,8 +500,36 @@ export interface GatewayManager { export interface EventHandlers { debug: (text: string) => unknown; - channelCreate: (bot: Bot, channel: DiscordenoChannel) => unknown; - dispatchRequirements: (bot: Bot, data: GatewayPayload, shardId: number) => Promise | unknown; + channelCreate: (bot: Bot, channel: DiscordenoChannel) => any; + dispatchRequirements: (bot: Bot, data: GatewayPayload, shardId: number) => any; + voiceChannelLeave: (bot: Bot, voiceState: DiscordenoVoiceState, channel: DiscordenoChannel) => any; + channelDelete: (bot: Bot, channel: DiscordenoChannel) => any; + channelPinsUpdate: (bot: Bot, data: { guildId?: bigint; channelId: bigint; lastPinTimestamp?: number }) => any; + channelUpdate: (bot: Bot, channel: DiscordenoChannel, oldChannel: DiscordenoChannel) => any; + stageInstanceCreate: (bot: Bot, data: { + id: bigint; + guildId: bigint; + channelId: bigint; + topic: string; + privacyLevel: number; + discoverableDisabled: boolean; + }) => any; + stageInstanceDelete: (bot: Bot, data: { + id: bigint; + guildId: bigint; + channelId: bigint; + topic: string; + privacyLevel: number; + discoverableDisabled: boolean; + }) => any; + stageInstanceUpdate: (bot: Bot, data: { + id: bigint; + guildId: bigint; + channelId: bigint; + topic: string; + privacyLevel: number; + discoverableDisabled: boolean; + }) => any; } export function createBotConstants() { diff --git a/src/cache.ts b/src/cache.ts index 2f8678cdf..2ea0ed136 100644 --- a/src/cache.ts +++ b/src/cache.ts @@ -1,76 +1,10 @@ -// // deno-lint-ignore-file require-await no-explicit-any prefer-const -// import { botId } from "./bot.ts"; -// import type { DiscordenoChannel } from "./structures/channel.ts"; -// import type { DiscordenoGuild } from "./structures/guild.ts"; -// import type { DiscordenoMember } from "./structures/member.ts"; -// import type { DiscordenoMessage } from "./structures/message.ts"; -// import type { PresenceUpdate } from "./types/activity/presence_update.ts"; -// import type { Emoji } from "./types/emojis/emoji.ts"; -// import { DiscordenoThread } from "./util/transformers/channel_to_thread.ts"; -// import { Collection } from "./util/collection.ts"; -// import { Channel } from "./types/channels/channel.ts"; -// import { Guild } from "./types/guilds/guild.ts"; -// import { GuildMember } from "./types/members/guild_member.ts"; -// import { Message } from "./types/messages/message.ts"; -// import { Role } from "./types/permissions/role.ts"; -// import { VoiceState } from "./types/voice/voice_state.ts"; -// import { User } from "./types/users/user.ts"; +import { Bot } from "./bot.ts"; +import type { DiscordenoChannel } from "./transformers/channel.ts"; +import type { DiscordenoGuild } from "./transformers/guild.ts"; +import type { DiscordenoMember } from "./transformers/member.ts"; +import type { DiscordenoMessage } from "./transformers/message.ts"; -// export const cache = { -// isReady: false, -// /** All of the guild objects the bot has access to, mapped by their Ids */ -// guilds: new Collection([], { sweeper: { filter: guildSweeper, interval: 3600000 } }), -// /** All of the channel objects the bot has access to, mapped by their Ids. Sweep channels 1 minute after guilds are sweeped so dispatchedGuildIds is filled. */ -// channels: new Collection([], { sweeper: { filter: channelSweeper, interval: 3660000 } }), -// /** All of the message objects the bot has cached since the bot acquired `READY` state, mapped by their Ids */ -// messages: new Collection([], { sweeper: { filter: messageSweeper, interval: 300000 } }), -// /** All of the member objects that have been cached since the bot acquired `READY` state, mapped by their Ids */ -// members: new Collection([], { sweeper: { filter: memberSweeper, interval: 300000 } }), -// /** All of the unavailable guilds, mapped by their Ids (id, timestamp) */ -// unavailableGuilds: new Collection(), -// /** All of the presence update objects received in PRESENCE_UPDATE gateway event, mapped by their user Id */ -// presences: new Collection([], { sweeper: { filter: () => true, interval: 300000 } }), -// fetchAllMembersProcessingRequests: new Collection< -// string, -// (value: Collection | PromiseLike>) => void -// >(), -// executedSlashCommands: new Set(), -// get emojis() { -// return new Collection( -// this.guilds.reduce((a, b) => [...a, ...b.emojis.map((e, id) => [id, e])], [] as any[]) -// ); -// }, -// activeGuildIds: new Set(), -// dispatchedGuildIds: new Set(), -// dispatchedChannelIds: new Set(), -// threads: new Collection(), -// /** ADVANCED USER ONLY: Please ask for help before modifying these. The properties that you want to use for your bot's structures. If you do not set any properties, all properties will be used by default. */ -// requiredStructureProperties: { -// /** Only these properties will be added to memory for your channels. */ -// channels: new Set(), -// /** Only these properties will be added to memory for your guilds. */ -// guilds: new Set(), -// /** Only these properties will be added to memory for your members. */ -// members: new Set(), -// /** Only these properties will be added to memory for your messages. */ -// messages: new Set< -// | keyof Message -// | "isBot" -// | "tag" -// | "authorId" -// | "mentionedUserIds" -// | "mentionedRoleIds" -// | "mentionedChannelIds" -// | "bitfield" -// >(), -// /** Only these properties will be added to memory for your roles. */ -// roles: new Set(), -// /** Only these properties will be added to memory for your voice states. */ -// voiceStates: new Set(), -// }, -// }; - -function messageSweeper(message: DiscordenoMessage) { +function messageSweeper(bot: Bot, message: DiscordenoMessage) { // DM messages aren't needed if (!message.guildId) return true; @@ -78,182 +12,34 @@ function messageSweeper(message: DiscordenoMessage) { return Date.now() - message.timestamp > 600000; } -function memberSweeper(member: DiscordenoMember) { +function memberSweeper(bot: Bot, member: DiscordenoMember) { // Don't sweep the bot else strange things will happen - if (member.id === botId) return false; + if (member.id === bot.id) return false; // Only sweep members who were not active the last 30 minutes return Date.now() - member.cachedAt > 1800000; } -function guildSweeper(guild: DiscordenoGuild) { +async function guildSweeper(bot: Bot, guild: DiscordenoGuild) { // Reset activity for next interval - if (cache.activeGuildIds.delete(guild.id)) return false; + if (await bot.cache.activeGuildIds.delete(guild.id)) return false; // This is inactive guild. Not a single thing has happened for atleast 30 minutes. // Not a reaction, not a message, not any event! - cache.dispatchedGuildIds.add(guild.id); + await bot.cache.dispatchedGuildIds.set(guild.id); return true; } -function channelSweeper(channel: DiscordenoChannel, key: bigint) { +async function channelSweeper(bot: Bot, channel: DiscordenoChannel, key: bigint) { // If this is in a guild and the guild was dispatched, then we can dispatch the channel - if (channel.guildId && cache.dispatchedGuildIds.has(channel.guildId)) { - cache.dispatchedChannelIds.add(channel.id); + if (channel.guildId && await bot.cache.dispatchedGuildIds.has(channel.guildId)) { + await bot.cache.dispatchedChannelIds.set(channel.id); return true; } // THE KEY DM CHANNELS ARE STORED BY IS THE USER ID. If the user is not cached, we dont need to cache their dm channel. - if (!channel.guildId && !cache.members.has(key)) return true; + if (!channel.guildId && !(await bot.cache.members.has(key))) return true; return false; } - -export let cacheHandlers = { - /** Deletes all items from the cache */ - async clear(table: TableName) { - return cache[table].clear(); - }, - /** Deletes 1 item from cache using the key */ - async delete(table: TableName, key: bigint) { - return cache[table].delete(key); - }, - /** Check if something exists in cache with a key */ - async has(table: TableName, key: bigint) { - return cache[table].has(key); - }, - - /** Get the number of key-value pairs */ - async size(table: TableName) { - return cache[table].size; - }, - - // Done differently to have overloads - /** Add a key value pair to the cache */ - set, - /** Get the value from the cache using its key */ - get, - /** Run a function on all items in this cache */ - forEach, - /** Allows you to filter our all items in this cache. */ - filter, -}; - -export type TableName = "guilds" | "unavailableGuilds" | "channels" | "messages" | "members" | "presences" | "threads"; - -async function set( - table: "threads", - key: bigint, - value: DiscordenoThread -): Promise>; -async function set(table: "guilds", key: bigint, value: DiscordenoGuild): Promise>; -async function set( - table: "channels", - key: bigint, - value: DiscordenoChannel -): Promise>; -async function set( - table: "messages", - key: bigint, - value: DiscordenoMessage -): Promise>; -async function set( - table: "members", - key: bigint, - value: DiscordenoMember -): Promise>; -async function set(table: "presences", key: bigint, value: PresenceUpdate): Promise>; -async function set(table: "unavailableGuilds", key: bigint, value: number): Promise>; -async function set(table: TableName, key: bigint, value: any) { - return cache[table].set(key, value); -} - -async function get(table: "threads", key: bigint): Promise; -async function get(table: "guilds", key: bigint): Promise; -async function get(table: "channels", key: bigint): Promise; -async function get(table: "messages", key: bigint): Promise; -async function get(table: "members", key: bigint): Promise; -async function get(table: "presences", key: bigint): Promise; -async function get(table: "unavailableGuilds", key: bigint): Promise; -async function get(table: TableName, key: bigint) { - return cache[table].get(key); -} - -// callback: (value: DiscordenoThread, key: bigint, map: Map) => void -async function forEach(type: "DELETE_MESSAGES_FROM_CHANNEL", options: { channelId: bigint }): Promise; -async function forEach(type: "DELETE_MESSAGES_FROM_GUILD", options: { guildId: bigint }): Promise; -async function forEach(type: "DELETE_CHANNELS_FROM_GUILD", options: { guildId: bigint }): Promise; -async function forEach(type: "DELETE_GUILD_FROM_MEMBER", options: { guildId: bigint }): Promise; -async function forEach(type: "DELETE_ROLE_FROM_MEMBER", options: { guildId: bigint; roleId: bigint }): Promise; -async function forEach( - type: - | "DELETE_MESSAGES_FROM_CHANNEL" - | "DELETE_MESSAGES_FROM_GUILD" - | "DELETE_CHANNELS_FROM_GUILD" - | "DELETE_GUILD_FROM_MEMBER" - | "DELETE_ROLE_FROM_MEMBER", - options?: Record -) { - if (type === "DELETE_MESSAGES_FROM_CHANNEL") { - cache.messages.forEach((message) => { - if (message.channelId === options?.channelId) cache.messages.delete(message.id); - }); - return; - } - - if (type === "DELETE_MESSAGES_FROM_GUILD") { - cache.messages.forEach((message) => { - if (message.guildId === options?.guildId) cache.messages.delete(message.id); - }); - return; - } - - if (type === "DELETE_CHANNELS_FROM_GUILD") { - cache.channels.forEach((channel) => { - if (channel.guildId === options?.guildId) cache.channels.delete(channel.id); - }); - return; - } - - if (type === "DELETE_GUILD_FROM_MEMBER") { - cache.members.forEach((member) => { - if (!member.guilds.has(options?.guildId as bigint)) return; - - member.guilds.delete(options?.guildId as bigint); - - if (!member.guilds.size) { - return cache.members.delete(member.id); - } - - cache.members.set(member.id, member); - }); - return; - } - - if (type === "DELETE_ROLE_FROM_MEMBER") { - cache.members.forEach((member) => { - // Not in the relevant guild so just skip - if (!member.guilds.has(options?.guildId as bigint)) return; - - const guildMember = member.guilds.get(options?.guildId as bigint)!; - - guildMember.roles = guildMember.roles.filter((id) => id !== (options?.roleId as bigint)); - cache.members.set(member.id, member); - }); - return; - } -} - -async function filter( - type: "GET_MEMBERS_IN_GUILD", - options: { guildId: bigint } -): Promise>; -async function filter( - type: "GET_MEMBERS_IN_GUILD", - options?: Record -): Promise | undefined> { - if (type === "GET_MEMBERS_IN_GUILD") { - return cache.members.filter((member) => member.guilds.has(options?.guildId as bigint)); - } -} diff --git a/src/handlers/channels/CHANNEL_DELETE.ts b/src/handlers/channels/CHANNEL_DELETE.ts index d0626aabf..627b989fd 100644 --- a/src/handlers/channels/CHANNEL_DELETE.ts +++ b/src/handlers/channels/CHANNEL_DELETE.ts @@ -1,37 +1,25 @@ -import { eventHandlers } from "../../bot.ts"; -import { cacheHandlers } from "../../cache.ts"; import type { Channel } from "../../types/channels/channel.ts"; -import { DiscordChannelTypes } from "../../types/channels/channel_types.ts"; import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; -import { snowflakeToBigint } from "../../util/bigint.ts"; +import { Bot } from "../../bot.ts"; +import { DiscordChannelTypes } from "../../types/channels/channel_types.ts"; +import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; -export async function handleChannelDelete(data: DiscordGatewayPayload) { - const payload = data.d as Channel; +export async function handleChannelDelete(bot: Bot, data: SnakeCasedPropertiesDeep) { + const payload = data.d as SnakeCasedPropertiesDeep; - const cachedChannel = await cacheHandlers.get("channels", snowflakeToBigint(payload.id)); - if (!cachedChannel) return; + const channel = await bot.cache.channels.get(bot.transformers.snowflake(payload.id)); + if (!channel) return; - if (cachedChannel.type === DiscordChannelTypes.GuildVoice && payload.guildId) { - const guild = await cacheHandlers.get("guilds", cachedChannel.guildId); + if ([DiscordChannelTypes.GuildVoice, DiscordChannelTypes.GuildStageVoice].includes(channel.type)) { + channel.voiceStates?.forEach((vs, key) => { + if (vs.channelId !== channel.id) return; - if (guild) { - return Promise.all( - guild.voiceStates.map(async (vs, key) => { - if (vs.channelId !== cachedChannel.id) return; + // Since this channel was deleted all voice states for this channel should be deleted + channel.voiceStates?.delete(key); - // Since this channel was deleted all voice states for this channel should be deleted - guild.voiceStates.delete(key); - - const member = await cacheHandlers.get("members", vs.userId); - if (!member) return; - - eventHandlers.voiceChannelLeave?.(member, vs.channelId); - }) - ); - } - } - - if ( + bot.events.voiceChannelLeave(bot, vs, channel); + }); + } else if ( [ DiscordChannelTypes.GuildText, DiscordChannelTypes.DM, @@ -39,11 +27,12 @@ export async function handleChannelDelete(data: DiscordGatewayPayload) { DiscordChannelTypes.GuildNews, ].includes(payload.type) ) { - await cacheHandlers.delete("channels", snowflakeToBigint(payload.id)); - await cacheHandlers.forEach("DELETE_MESSAGES_FROM_CHANNEL", { channelId: snowflakeToBigint(payload.id) }); + await bot.cache.channels.forEach("DELETE_MESSAGES_FROM_CHANNEL", { + channelId: bot.transformers.snowflake(payload.id), + }); } - await cacheHandlers.delete("channels", snowflakeToBigint(payload.id)); + await bot.cache.channels.delete(bot.transformers.snowflake(payload.id)); - eventHandlers.channelDelete?.(cachedChannel); + bot.events.channelDelete(bot, channel); } diff --git a/src/handlers/channels/CHANNEL_PINS_UPDATE.ts b/src/handlers/channels/CHANNEL_PINS_UPDATE.ts index 19dad784c..261e1a4d5 100644 --- a/src/handlers/channels/CHANNEL_PINS_UPDATE.ts +++ b/src/handlers/channels/CHANNEL_PINS_UPDATE.ts @@ -1,16 +1,14 @@ -import { eventHandlers } from "../../bot.ts"; -import { cacheHandlers } from "../../cache.ts"; +import { Bot } from "../../bot.ts"; import type { ChannelPinsUpdate } from "../../types/channels/channel_pins_update.ts"; import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; -import { snowflakeToBigint } from "../../util/bigint.ts"; +import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; -export async function handleChannelPinsUpdate(data: DiscordGatewayPayload) { - const payload = data.d as ChannelPinsUpdate; +export async function handleChannelPinsUpdate(bot: Bot, data: SnakeCasedPropertiesDeep) { + const payload = data.d as SnakeCasedPropertiesDeep; - const channel = await cacheHandlers.get("channels", snowflakeToBigint(payload.channelId)); - if (!channel) return; - - const guild = payload.guildId ? await cacheHandlers.get("guilds", snowflakeToBigint(payload.guildId)) : undefined; - - eventHandlers.channelPinsUpdate?.(channel, guild, payload.lastPinTimestamp); + bot.events.channelPinsUpdate(bot, { + guildId: payload.guild_id ? bot.transformers.snowflake(payload.guild_id) : undefined, + channelId: bot.transformers.snowflake(payload.channel_id), + lastPinTimestamp: payload.last_pin_timestamp ? Date.parse(payload.last_pin_timestamp) : undefined, + }); } diff --git a/src/handlers/channels/CHANNEL_UPDATE.ts b/src/handlers/channels/CHANNEL_UPDATE.ts index b0a5209f0..19fbb622f 100644 --- a/src/handlers/channels/CHANNEL_UPDATE.ts +++ b/src/handlers/channels/CHANNEL_UPDATE.ts @@ -1,17 +1,16 @@ -import { eventHandlers } from "../../bot.ts"; -import { cacheHandlers } from "../../cache.ts"; -import { structures } from "../../structures/mod.ts"; +import { Bot } from "../../bot.ts"; import type { Channel } from "../../types/channels/channel.ts"; import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; -import { snowflakeToBigint } from "../../util/bigint.ts"; +import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; -export async function handleChannelUpdate(data: DiscordGatewayPayload) { - const payload = data.d as Channel; - const cachedChannel = await cacheHandlers.get("channels", snowflakeToBigint(payload.id)); +export async function handleChannelUpdate(bot: Bot, data: SnakeCasedPropertiesDeep) { + const payload = data.d as SnakeCasedPropertiesDeep; + + const cachedChannel = await bot.cache.channels.get(bot.transformers.snowflake(payload.id)); if (!cachedChannel) return; - const discordenoChannel = await structures.createDiscordenoChannel(payload); - await cacheHandlers.set("channels", discordenoChannel.id, discordenoChannel); + const channel = bot.transformers.channel(bot, { channel: payload }); + await bot.cache.channels.set(channel.id, channel); - eventHandlers.channelUpdate?.(discordenoChannel, cachedChannel); + bot.events.channelUpdate(bot, channel, cachedChannel); } diff --git a/src/handlers/channels/STAGE_INSTANCE_CREATE.ts b/src/handlers/channels/STAGE_INSTANCE_CREATE.ts index d99387dc5..d65635df2 100644 --- a/src/handlers/channels/STAGE_INSTANCE_CREATE.ts +++ b/src/handlers/channels/STAGE_INSTANCE_CREATE.ts @@ -1,7 +1,17 @@ -import { eventHandlers } from "../../bot.ts"; +import { Bot } from "../../bot.ts"; import type { StageInstance } from "../../types/channels/stage_instance.ts"; import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; +import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; -export function handleStageInstanceCreate(data: DiscordGatewayPayload) { - eventHandlers.stageInstanceCreate?.(data.d as StageInstance); +export function handleStageInstanceCreate(bot: Bot, data: SnakeCasedPropertiesDeep) { + const payload = data.d as SnakeCasedPropertiesDeep; + + bot.events.stageInstanceCreate(bot, { + id: bot.transformers.snowflake(payload.id), + guildId: bot.transformers.snowflake(payload.guild_id), + channelId: bot.transformers.snowflake(payload.channel_id), + topic: payload.topic, + privacyLevel: payload.privacy_level, + discoverableDisabled: payload.discoverable_disabled, + }); } diff --git a/src/handlers/channels/STAGE_INSTANCE_DELETE.ts b/src/handlers/channels/STAGE_INSTANCE_DELETE.ts index 43e765ba2..fced34649 100644 --- a/src/handlers/channels/STAGE_INSTANCE_DELETE.ts +++ b/src/handlers/channels/STAGE_INSTANCE_DELETE.ts @@ -1,7 +1,17 @@ -import { eventHandlers } from "../../bot.ts"; +import { Bot } from "../../bot.ts"; import type { StageInstance } from "../../types/channels/stage_instance.ts"; import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; +import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; -export function handleStageInstanceDelete(data: DiscordGatewayPayload) { - eventHandlers.stageInstanceDelete?.(data.d as StageInstance); +export function handleStageInstanceDelete(bot: Bot, data: SnakeCasedPropertiesDeep) { + const payload = data.d as SnakeCasedPropertiesDeep; + + bot.events.stageInstanceDelete(bot, { + id: bot.transformers.snowflake(payload.id), + guildId: bot.transformers.snowflake(payload.guild_id), + channelId: bot.transformers.snowflake(payload.channel_id), + topic: payload.topic, + privacyLevel: payload.privacy_level, + discoverableDisabled: payload.discoverable_disabled, + }); } diff --git a/src/handlers/channels/STAGE_INSTANCE_UPDATE.ts b/src/handlers/channels/STAGE_INSTANCE_UPDATE.ts index d0cf177bf..e65cfb498 100644 --- a/src/handlers/channels/STAGE_INSTANCE_UPDATE.ts +++ b/src/handlers/channels/STAGE_INSTANCE_UPDATE.ts @@ -1,7 +1,17 @@ -import { eventHandlers } from "../../bot.ts"; +import { Bot } from "../../bot.ts"; import type { StageInstance } from "../../types/channels/stage_instance.ts"; import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; +import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; -export function handleStageInstanceUpdate(data: DiscordGatewayPayload) { - eventHandlers.stageInstanceUpdate?.(data.d as StageInstance); +export function handleStageInstanceUpdate(bot: Bot, data: SnakeCasedPropertiesDeep) { + const payload = data.d as SnakeCasedPropertiesDeep; + + bot.events.stageInstanceUpdate(bot, { + id: bot.transformers.snowflake(payload.id), + guildId: bot.transformers.snowflake(payload.guild_id), + channelId: bot.transformers.snowflake(payload.channel_id), + topic: payload.topic, + privacyLevel: payload.privacy_level, + discoverableDisabled: payload.discoverable_disabled, + }); } diff --git a/src/transformers/channel.ts b/src/transformers/channel.ts index 7becee48f..2396874b3 100644 --- a/src/transformers/channel.ts +++ b/src/transformers/channel.ts @@ -2,6 +2,9 @@ import { Channel } from "../types/channels/channel.ts"; import { Bot } from "../bot.ts"; import { SnakeCasedPropertiesDeep } from "../types/util.ts"; import { DiscordOverwrite } from "../types/channels/overwrite.ts"; +import { DiscordChannelTypes } from "../types/channels/channel_types.ts"; +import type { DiscordenoVoiceState } from "./voice_state.ts"; +import { Collection } from "../util/collection.ts"; export function transformChannel( bot: Bot, @@ -42,6 +45,7 @@ export function transformChannel( ? bot.transformers.snowflake(payload.channel.application_id) : undefined, parentId: payload.channel.parent_id ? bot.transformers.snowflake(payload.channel.parent_id) : undefined, + voiceStates: payload.channel.type === DiscordChannelTypes.GuildVoice ? new Collection() : undefined, }; } @@ -77,4 +81,6 @@ export interface DiscordenoChannel applicationId?: bigint; /** Id of the parent category for a channel (each parent category can contain up to 50 channels) */ parentId?: bigint; + /** The voice states that are in this channel assuming it is a voice channel. */ + voiceStates?: Collection; }