feat: improve channel types & fix overwrites cache

This commit is contained in:
MARCROCK22 2024-12-09 13:28:44 -04:00
parent f75d4d5adf
commit c68c091b31
4 changed files with 67 additions and 68 deletions

View File

@ -143,7 +143,7 @@ export class Client<Ready extends boolean = boolean> extends BaseClient {
if (!this.memberUpdateHandler.check(packet.d)) { if (!this.memberUpdateHandler.check(packet.d)) {
return; return;
} }
await this.events?.execute(packet.t, packet, this as Client<true>, shardId); await this.events?.execute(packet, this as Client<true>, shardId);
} }
break; break;
case 'PRESENCE_UPDATE': case 'PRESENCE_UPDATE':
@ -151,7 +151,7 @@ export class Client<Ready extends boolean = boolean> extends BaseClient {
if (!this.presenceUpdateHandler.check(packet.d)) { if (!this.presenceUpdateHandler.check(packet.d)) {
return; return;
} }
await this.events?.execute(packet.t, packet, this as Client<true>, shardId); await this.events?.execute(packet, this as Client<true>, shardId);
} }
break; break;
case 'GUILD_DELETE': case 'GUILD_DELETE':
@ -166,7 +166,7 @@ export class Client<Ready extends boolean = boolean> extends BaseClient {
if (!this.__handleGuilds?.length) delete this.__handleGuilds; if (!this.__handleGuilds?.length) delete this.__handleGuilds;
return this.cache.onPacket(packet); return this.cache.onPacket(packet);
} }
await this.events?.execute(packet.t, packet, this as Client<true>, shardId); await this.events?.execute(packet, this as Client<true>, shardId);
break; break;
} }
//rest of the events //rest of the events
@ -174,13 +174,13 @@ export class Client<Ready extends boolean = boolean> extends BaseClient {
switch (packet.t) { switch (packet.t) {
case 'INTERACTION_CREATE': case 'INTERACTION_CREATE':
{ {
await this.events?.execute(packet.t as never, packet, this as Client<true>, shardId); await this.events?.execute(packet, this as Client<true>, shardId);
await this.handleCommand.interaction(packet.d, shardId); await this.handleCommand.interaction(packet.d, shardId);
} }
break; break;
case 'MESSAGE_CREATE': case 'MESSAGE_CREATE':
{ {
await this.events?.execute(packet.t as never, packet, this as Client<true>, shardId); await this.events?.execute(packet, this as Client<true>, shardId);
await this.handleCommand.message(packet.d, shardId); await this.handleCommand.message(packet.d, shardId);
} }
break; break;
@ -199,11 +199,11 @@ export class Client<Ready extends boolean = boolean> extends BaseClient {
delete this.__handleGuilds; delete this.__handleGuilds;
} }
this.debugger?.debug(`#${shardId}[${packet.d.user.username}](${this.botId}) is online...`); this.debugger?.debug(`#${shardId}[${packet.d.user.username}](${this.botId}) is online...`);
await this.events?.execute(packet.t as never, packet, this as Client<true>, shardId); await this.events?.execute(packet, this as Client<true>, shardId);
break; break;
} }
default: default:
await this.events?.execute(packet.t as never, packet, this as Client<true>, shardId); await this.events?.execute(packet, this as Client<true>, shardId);
break; break;
} }
break; break;

View File

@ -499,7 +499,7 @@ export class WorkerClient<Ready extends boolean = boolean> extends BaseClient {
if (!this.memberUpdateHandler.check(packet.d)) { if (!this.memberUpdateHandler.check(packet.d)) {
return; return;
} }
await this.events?.execute(packet.t, packet, this as WorkerClient<true>, shardId); await this.events?.execute(packet, this as WorkerClient<true>, shardId);
} }
break; break;
case 'PRESENCE_UPDATE': case 'PRESENCE_UPDATE':
@ -507,7 +507,7 @@ export class WorkerClient<Ready extends boolean = boolean> extends BaseClient {
if (!this.presenceUpdateHandler.check(packet.d)) { if (!this.presenceUpdateHandler.check(packet.d)) {
return; return;
} }
await this.events?.execute(packet.t, packet, this as WorkerClient<true>, shardId); await this.events?.execute(packet, this as WorkerClient<true>, shardId);
} }
break; break;
case 'GUILD_DELETE': case 'GUILD_DELETE':
@ -526,20 +526,20 @@ export class WorkerClient<Ready extends boolean = boolean> extends BaseClient {
if (!this.__handleGuilds?.length) delete this.__handleGuilds; if (!this.__handleGuilds?.length) delete this.__handleGuilds;
return this.cache.onPacket(packet); return this.cache.onPacket(packet);
} }
await this.events?.execute(packet.t, packet, this, shardId); await this.events?.execute(packet, this, shardId);
break; break;
} }
default: { default: {
switch (packet.t) { switch (packet.t) {
case 'INTERACTION_CREATE': case 'INTERACTION_CREATE':
{ {
await this.events?.execute(packet.t as never, packet, this, shardId); await this.events?.execute(packet, this, shardId);
await this.handleCommand.interaction(packet.d, shardId); await this.handleCommand.interaction(packet.d, shardId);
} }
break; break;
case 'MESSAGE_CREATE': case 'MESSAGE_CREATE':
{ {
await this.events?.execute(packet.t as never, packet, this, shardId); await this.events?.execute(packet, this, shardId);
await this.handleCommand.message(packet.d, shardId); await this.handleCommand.message(packet.d, shardId);
} }
break; break;
@ -552,7 +552,7 @@ export class WorkerClient<Ready extends boolean = boolean> extends BaseClient {
this.botId = packet.d.user.id; this.botId = packet.d.user.id;
this.applicationId = packet.d.application.id; this.applicationId = packet.d.application.id;
this.me = Transformers.ClientUser(this, packet.d.user, packet.d.application) as never; this.me = Transformers.ClientUser(this, packet.d.user, packet.d.application) as never;
await this.events?.execute(packet.t as never, packet, this, shardId); await this.events?.execute(packet, this, shardId);
if (!this._ready && [...this.shards.values()].every(shard => shard.data.session_id)) { if (!this._ready && [...this.shards.values()].every(shard => shard.data.session_id)) {
this._ready = true; this._ready = true;
this.postMessage({ this.postMessage({
@ -575,7 +575,7 @@ export class WorkerClient<Ready extends boolean = boolean> extends BaseClient {
} }
break; break;
default: default:
await this.events?.execute(packet.t as never, packet, this, shardId); await this.events?.execute(packet, this, shardId);
break; break;
} }
break; break;

View File

@ -12,16 +12,7 @@ import {
} from '../common'; } from '../common';
import type { ClientEvents } from '../events/hooks'; import type { ClientEvents } from '../events/hooks';
import * as RawEvents from '../events/hooks'; import * as RawEvents from '../events/hooks';
import { import { type APIThreadChannel, ChannelType, type GatewayDispatchPayload } from '../types';
type APIThreadChannel,
ChannelType,
type GatewayChannelDeleteDispatch,
type GatewayDispatchPayload,
type GatewayGuildDeleteDispatch,
type GatewayMessageDeleteBulkDispatch,
type GatewayMessageDeleteDispatch,
type GatewayThreadDeleteDispatch,
} from '../types';
import type { ClientEvent, ClientNameEvents, CustomEvents, CustomEventsKeys, EventContext } from './event'; import type { ClientEvent, ClientNameEvents, CustomEvents, CustomEventsKeys, EventContext } from './event';
export type EventValue = MakeRequired<ClientEvent, '__filePath'> & { fired?: boolean }; export type EventValue = MakeRequired<ClientEvent, '__filePath'> & { fired?: boolean };
@ -105,66 +96,62 @@ export class EventHandler extends BaseHandler {
} }
} }
async execute(name: GatewayEvents, ...args: [GatewayDispatchPayload, Client<true> | WorkerClient<true>, number]) { async execute(raw: GatewayDispatchPayload, client: Client<true> | WorkerClient<true>, shardId: number) {
switch (name) { switch (raw.t) {
case 'MESSAGE_DELETE': case 'MESSAGE_DELETE':
{ {
if (!args[1].components?.values.size) break; if (!client.components?.values.size) break;
const { d: data } = args[0] as GatewayMessageDeleteDispatch; const value = client.components.values.get(raw.d.id);
const value = args[1].components.values.get(data.id);
if (value) { if (value) {
args[1].components.deleteValue(value.messageId, 'messageDelete'); client.components.deleteValue(value.messageId, 'messageDelete');
} }
} }
break; break;
case 'MESSAGE_DELETE_BULK': case 'MESSAGE_DELETE_BULK':
{ {
if (!args[1].components?.values.size) break; if (!client.components?.values.size) break;
const { d: payload } = args[0] as GatewayMessageDeleteBulkDispatch; for (const id of raw.d.ids) {
for (const id of payload.ids) { const value = client.components.values.get(id);
const value = args[1].components.values.get(id);
if (value) { if (value) {
args[1].components.deleteValue(value.messageId, 'messageDelete'); client.components.deleteValue(value.messageId, 'messageDelete');
} }
} }
} }
break; break;
case 'GUILD_DELETE': case 'GUILD_DELETE':
{ {
if (!args[1].components?.values.size) break; if (!client.components?.values.size) break;
const { d: payload } = args[0] as GatewayGuildDeleteDispatch;
// ignore unavailable guilds? // ignore unavailable guilds?
if (payload.unavailable) break; if (raw.d.unavailable) break;
for (const [messageId, value] of args[1].components.values) { for (const [messageId, value] of client.components.values) {
if (value.guildId === payload.id) args[1].components.deleteValue(messageId, 'guildDelete'); if (value.guildId === raw.d.id) client.components.deleteValue(messageId, 'guildDelete');
} }
} }
break; break;
case 'CHANNEL_DELETE': case 'CHANNEL_DELETE':
{ {
if (!args[1].components?.values.size) break; if (!client.components?.values.size) break;
const { d: payload } = args[0] as GatewayChannelDeleteDispatch;
if (payload.type === ChannelType.DM || payload.type === ChannelType.GroupDM) { if (raw.d.type === ChannelType.DM || raw.d.type === ChannelType.GroupDM) {
for (const value of args[1].components.values) { for (const value of client.components.values) {
if (payload.id === value[1].channelId) args[1].components.deleteValue(value[0], 'channelDelete'); if (raw.d.id === value[1].channelId) client.components.deleteValue(value[0], 'channelDelete');
} }
} else { } else {
if (!payload.guild_id) break; if (!raw.d.guild_id) break;
// this is why we dont recommend to use collectors, use ComponentCommand instead // this is why we dont recommend to use collectors, use ComponentCommand instead
const channels = await args[1].cache.channels?.valuesRaw(payload.guild_id); const channels = await client.cache.channels?.valuesRaw(raw.d.guild_id);
const threads = channels const threads = channels
?.filter( ?.filter(
x => x =>
[ChannelType.PublicThread, ChannelType.PrivateThread, ChannelType.AnnouncementThread].includes( [ChannelType.PublicThread, ChannelType.PrivateThread, ChannelType.AnnouncementThread].includes(
x.type, x.type,
) && (x as APIThreadChannel).parent_id === payload.id, ) && (x as APIThreadChannel).parent_id === raw.d.id,
) )
.map(x => x.id); .map(x => x.id);
for (const value of args[1].components.values) { for (const value of client.components.values) {
const channelId = value[1].channelId; const channelId = value[1].channelId;
if (payload.id === channelId || threads?.includes(channelId)) { if (raw.d.id === channelId || threads?.includes(channelId)) {
args[1].components.deleteValue(value[0], 'channelDelete'); client.components.deleteValue(value[0], 'channelDelete');
} }
} }
} }
@ -172,11 +159,10 @@ export class EventHandler extends BaseHandler {
break; break;
case 'THREAD_DELETE': case 'THREAD_DELETE':
{ {
if (!args[1].components?.values.size) break; if (!client.components?.values.size) break;
const { d: payload } = args[0] as GatewayThreadDeleteDispatch; for (const value of client.components.values) {
for (const value of args[1].components.values) { if (value[1].channelId === raw.d.id) {
if (value[1].channelId === payload.id) { client.components.deleteValue(value[0], 'channelDelete');
args[1].components.deleteValue(value[0], 'channelDelete');
} }
} }
} }
@ -184,12 +170,18 @@ export class EventHandler extends BaseHandler {
} }
await Promise.all([ await Promise.all([
this.runEvent(args[0].t as never, args[1], args[0].d, args[2]), this.runEvent(raw.t as never, client, raw.d, shardId),
this.client.collectors.run(args[0].t as never, args[0].d as never, this.client), this.client.collectors.run(raw.t as never, raw.d as never, this.client),
]); ]);
} }
async runEvent(name: GatewayEvents, client: Client | WorkerClient, packet: any, shardId: number, runCache = true) { async runEvent(
name: GatewayEvents,
client: Client | WorkerClient,
packet: unknown,
shardId: number,
runCache = true,
) {
const Event = this.values[name]; const Event = this.values[name];
if (!Event) { if (!Event) {
return runCache return runCache

View File

@ -1,5 +1,6 @@
import { Collection, Formatter, type RawFile, type ReturnCache } from '..'; import { Collection, Formatter, type RawFile, type ReturnCache } from '..';
import { ActionRow, Embed, PollBuilder, resolveAttachment } from '../builders'; import { ActionRow, Embed, PollBuilder, resolveAttachment } from '../builders';
import type { Overwrites } from '../cache/resources/overwrites';
import { import {
type BaseChannelStructure, type BaseChannelStructure,
type BaseGuildChannelStructure, type BaseGuildChannelStructure,
@ -162,11 +163,11 @@ export class BaseNoEditableChannel<T extends ChannelType> extends DiscordBase<AP
} }
export class BaseChannel<T extends ChannelType> extends BaseNoEditableChannel<T> { export class BaseChannel<T extends ChannelType> extends BaseNoEditableChannel<T> {
edit(body: RESTPatchAPIChannelJSONBody, reason?: string) { edit(body: RESTPatchAPIChannelJSONBody, reason?: string): Promise<this> {
return this.client.channels.edit(this.id, body, { return this.client.channels.edit(this.id, body, {
reason, reason,
guildId: 'guildId' in this ? (this.guildId as string) : '@me', guildId: 'guildId' in this ? (this.guildId as string) : '@me',
}); }) as Promise<this>;
} }
} }
@ -193,8 +194,16 @@ export class BaseGuildChannel extends BaseChannel<ChannelType> {
} }
permissionOverwrites = { permissionOverwrites = {
fetch: () => this.client.cache.overwrites?.get(this.id), fetch: (): ReturnType<Overwrites['get']> =>
values: () => (this.guildId ? (this.client.cache.overwrites?.values(this.guildId) ?? []) : []), this.client.cache.overwrites?.get(this.id) ||
(this.client.cache.adapter.isAsync ? (Promise.resolve() as never) : undefined),
values: (): ReturnCache<ReturnType<Overwrites['values']>> =>
this.guildId
? this.client.cache.overwrites?.values(this.guildId) ||
(this.client.cache.adapter.isAsync ? (Promise.resolve([]) as never) : [])
: this.client.cache.adapter.isAsync
? (Promise.resolve([]) as never)
: [],
}; };
memberPermissions(member: GuildMember, checkAdmin = true) { memberPermissions(member: GuildMember, checkAdmin = true) {
@ -410,9 +419,7 @@ export class VoiceChannelMethods extends DiscordBase {
if (!this.guildId) return this.cache.adapter.isAsync ? (Promise.resolve([]) as never) : []; if (!this.guildId) return this.cache.adapter.isAsync ? (Promise.resolve([]) as never) : [];
return fakePromise( return fakePromise(
this.cache.voiceStates?.values(this.guildId) ?? this.cache.voiceStates?.values(this.guildId) ??
(this.cache.adapter.isAsync (this.cache.adapter.isAsync ? (Promise.resolve([]) as never) : []),
? (Promise.resolve([]) as Promise<VoiceStateStructure[]>)
: ([] as VoiceStateStructure[])),
).then(states => { ).then(states => {
return states.filter(state => state.channelId === this.id); return states.filter(state => state.channelId === this.id);
}); });
@ -484,7 +491,7 @@ export class DMChannel extends BaseNoEditableChannel<ChannelType.DM> {
} }
export interface VoiceChannel export interface VoiceChannel
extends ObjectToLower<Omit<APIGuildVoiceChannel, 'permission_overwrites'>>, extends ObjectToLower<Omit<APIGuildVoiceChannel, 'permission_overwrites'>>,
Omit<TextGuildChannel, 'type'>, Omit<TextGuildChannel, 'type' | 'edit'>,
VoiceChannelMethods, VoiceChannelMethods,
WebhookChannelMethods {} WebhookChannelMethods {}
@mix(TextGuildChannel, WebhookChannelMethods, VoiceChannelMethods) @mix(TextGuildChannel, WebhookChannelMethods, VoiceChannelMethods)
@ -509,7 +516,7 @@ export class MediaChannel extends BaseChannel<ChannelType> {
export interface ForumChannel export interface ForumChannel
extends ObjectToLower<APIGuildForumChannel>, extends ObjectToLower<APIGuildForumChannel>,
Omit<ThreadOnlyMethods, 'type'>, Omit<ThreadOnlyMethods, 'type' | 'edit'>,
WebhookChannelMethods {} WebhookChannelMethods {}
@mix(ThreadOnlyMethods, WebhookChannelMethods) @mix(ThreadOnlyMethods, WebhookChannelMethods)
export class ForumChannel extends BaseChannel<ChannelType.GuildForum> { export class ForumChannel extends BaseChannel<ChannelType.GuildForum> {