Files
discordeno/src/api/controllers/guilds.ts
ITOH 62af388820 fix(controllers): update cache with new value in gateway events (#433)
* fix(controllers): cache updated member

* fix(controllers): cache update guild

* fix(controllers): cache user update

* fix(controllers): cache voice state update

* refactor(controllers): message reaction add remove previousReactions

* refactor(controllers): message reaction remove remove previousReactions

* fix(controllers): cache message reaction remove all

* fix(controllers): cache message reaction remove emoji

* fix(controllers): cache guild role create

* fix(controllers): role delete event update cache and return eventHandler

* fix(controllers): cache role update

* don't return eventHandlers

* don't return eventHandlers
2021-01-22 19:20:33 +04:00

128 lines
3.6 KiB
TypeScript

import { eventHandlers } from "../../bot.ts";
import {
CreateGuildPayload,
DiscordPayload,
GuildDeletePayload,
GuildEmojisUpdatePayload,
GuildUpdateChange,
UpdateGuildPayload,
} from "../../types/mod.ts";
import { cache } from "../../util/cache.ts";
import { structures } from "../structures/mod.ts";
import { cacheHandlers } from "./cache.ts";
export async function handleInternalGuildCreate(
data: DiscordPayload,
shardID: number,
) {
if (data.t !== "GUILD_CREATE") return;
const payload = data.d as CreateGuildPayload;
// When shards resume they emit GUILD_CREATE again.
if (await cacheHandlers.has("guilds", payload.id)) return;
const guild = await structures.createGuild(
data.d as CreateGuildPayload,
shardID,
);
await cacheHandlers.set("guilds", guild.id, guild);
if (await cacheHandlers.has("unavailableGuilds", payload.id)) {
await cacheHandlers.delete("unavailableGuilds", payload.id);
}
if (!cache.isReady) return eventHandlers.guildLoaded?.(guild);
eventHandlers.guildCreate?.(guild);
}
export async function handleInternalGuildDelete(data: DiscordPayload) {
if (data.t !== "GUILD_DELETE") return;
const payload = data.d as GuildDeletePayload;
cacheHandlers.forEach("messages", (message) => {
if (message.guildID === payload.id) {
cacheHandlers.delete("messages", message.id);
}
});
cacheHandlers.forEach("channels", (channel) => {
if (channel.guildID === payload.id) {
cacheHandlers.delete("channels", channel.id);
}
});
await cacheHandlers.delete("guilds", payload.id);
if (payload.unavailable) {
return cacheHandlers.set("unavailableGuilds", payload.id, Date.now());
}
const guild = await cacheHandlers.get("guilds", payload.id);
if (!guild) return;
eventHandlers.guildDelete?.(guild);
}
export async function handleInternalGuildUpdate(data: DiscordPayload) {
if (data.t !== "GUILD_UPDATE") return;
const payload = data.d as UpdateGuildPayload;
const cachedGuild = await cacheHandlers.get("guilds", payload.id);
if (!cachedGuild) return;
const keysToSkip = [
"roles",
"guild_hashes",
"guild_id",
"max_members",
"emojis",
];
const changes = Object.entries(payload)
.map(([key, value]) => {
if (keysToSkip.includes(key)) return;
// @ts-ignore index signature
const cachedValue = cachedGuild[key];
if (cachedValue !== value) {
// Guild create sends undefined and update sends false.
if (!cachedValue && !value) return;
if (Array.isArray(cachedValue) && Array.isArray(value)) {
const different = (cachedValue.length !== value.length) ||
cachedValue.find((val) => !value.includes(val)) ||
value.find((val) => !cachedValue.includes(val));
if (!different) return;
}
// @ts-ignore index signature
cachedGuild[key] = value;
return { key, oldValue: cachedValue, value };
}
}).filter((change) => change) as GuildUpdateChange[];
await cacheHandlers.set("guilds", payload.id, { ...cachedGuild, ...changes });
eventHandlers.guildUpdate?.(cachedGuild, changes);
}
export async function handleInternalGuildEmojisUpdate(data: DiscordPayload) {
if (data.t !== "GUILD_EMOJIS_UPDATE") return;
const payload = data.d as GuildEmojisUpdatePayload;
const guild = await cacheHandlers.get("guilds", payload.guild_id);
if (!guild) return;
const cachedEmojis = guild.emojis;
guild.emojis = payload.emojis;
cacheHandlers.set("guilds", payload.guild_id, guild);
eventHandlers.guildEmojisUpdate?.(
guild,
payload.emojis,
cachedEmojis,
);
}