This commit is contained in:
ITOH
2021-04-09 21:37:13 +02:00
parent 577010e953
commit 9312606100
26 changed files with 233 additions and 13 deletions
+4
View File
@@ -32,6 +32,10 @@ export async function handleChannelDelete(data: DiscordGatewayPayload) {
await cacheHandlers.delete("channels", payload.id); await cacheHandlers.delete("channels", payload.id);
cacheHandlers.forEach("messages", (message) => { cacheHandlers.forEach("messages", (message) => {
eventHandlers.debug(
"loop",
`Running forEach messages loop in CHANNEL_DELTE file.`,
);
if (message.channelId === payload.id) { if (message.channelId === payload.id) {
cacheHandlers.delete("messages", message.id); cacheHandlers.delete("messages", message.id);
} }
+12
View File
@@ -27,18 +27,30 @@ export async function handleGuildDelete(
} }
cacheHandlers.forEach("messages", (message) => { cacheHandlers.forEach("messages", (message) => {
eventHandlers.debug(
"loop",
`1. Running forEach messages loop in CHANNEL_DELTE file.`,
);
if (message.guildId === payload.id) { if (message.guildId === payload.id) {
cacheHandlers.delete("messages", message.id); cacheHandlers.delete("messages", message.id);
} }
}); });
cacheHandlers.forEach("channels", (channel) => { cacheHandlers.forEach("channels", (channel) => {
eventHandlers.debug(
"loop",
`2. Running forEach channels loop in CHANNEL_DELTE file.`,
);
if (channel.guildId === payload.id) { if (channel.guildId === payload.id) {
cacheHandlers.delete("channels", channel.id); cacheHandlers.delete("channels", channel.id);
} }
}); });
cacheHandlers.forEach("members", (member) => { cacheHandlers.forEach("members", (member) => {
eventHandlers.debug(
"loop",
`3. Running forEach members loop in CHANNEL_DELTE file.`,
);
if (!member.guilds.has(payload.id)) return; if (!member.guilds.has(payload.id)) return;
member.guilds.delete(payload.id); member.guilds.delete(payload.id);
@@ -46,12 +46,20 @@ export async function handleGuildMemberUpdate(data: DiscordGatewayPayload) {
const roleIds = guildMember.roles || []; const roleIds = guildMember.roles || [];
roleIds.forEach((id) => { roleIds.forEach((id) => {
eventHandlers.debug(
"loop",
`1. Running forEach loop in GUILD_MEMBER_UPDATE file.`,
);
if (!payload.roles.includes(id)) { if (!payload.roles.includes(id)) {
eventHandlers.roleLost?.(guild, memberStruct, id); eventHandlers.roleLost?.(guild, memberStruct, id);
} }
}); });
payload.roles.forEach((id) => { payload.roles.forEach((id) => {
eventHandlers.debug(
"loop",
`2. Running forEach loop in GUILD_MEMBER_UPDATE file.`,
);
if (!roleIds.includes(id)) { if (!roleIds.includes(id)) {
eventHandlers.roleGained?.(guild, memberStruct, id); eventHandlers.roleGained?.(guild, memberStruct, id);
} }
+25 -3
View File
@@ -32,7 +32,13 @@ export async function handleReady(
shard.unavailableGuildIds = new Set(payload.guilds.map((g) => g.id)); shard.unavailableGuildIds = new Set(payload.guilds.map((g) => g.id));
// Start ready check in 2 seconds // Start ready check in 2 seconds
setTimeout(async () => await checkReady(payload, shardId, now), 2000); setTimeout(async () => {
eventHandlers.debug(
"loop",
`1. Running setTimeout in READY file.`,
);
await checkReady(payload, shardId, now);
}, 2000);
// Wait 5 seconds to spawn next shard // Wait 5 seconds to spawn next shard
await delay(5000); await delay(5000);
@@ -53,7 +59,13 @@ async function checkReady(payload: DiscordReady, shardId: number, now: number) {
await loaded(shardId); await loaded(shardId);
} else { } else {
// Not all guilds were loaded but 10 seconds haven't passed so check again // Not all guilds were loaded but 10 seconds haven't passed so check again
setTimeout(async () => await checkReady(payload, shardId, now), 2000); setTimeout(async () => {
eventHandlers.debug(
"loop",
`2. Running setTimeout in READY file.`,
);
await checkReady(payload, shardId, now);
}, 2000);
} }
} else { } else {
// All guilds were loaded // All guilds were loaded
@@ -71,13 +83,23 @@ async function loaded(shardId: number) {
if (shardId === ws.lastShardId - 1) { if (shardId === ws.lastShardId - 1) {
// Still some shards are loading so wait another 2 seconds for them // Still some shards are loading so wait another 2 seconds for them
if (ws.shards.some((shard) => !shard.ready)) { if (ws.shards.some((shard) => !shard.ready)) {
setTimeout(async () => await loaded(shardId), 2000); setTimeout(async () => {
eventHandlers.debug(
"loop",
`3. Running setTimeout in CHANNEL_DELTE file.`,
);
await loaded(shardId);
}, 2000);
} else { } else {
cache.isReady = true; cache.isReady = true;
eventHandlers.ready?.(); eventHandlers.ready?.();
// All the members that came in on guild creates should now be processed 1 by 1 // All the members that came in on guild creates should now be processed 1 by 1
for (const [guildId, members] of initialMemberLoadQueue.entries()) { for (const [guildId, members] of initialMemberLoadQueue.entries()) {
eventHandlers.debug(
"loop",
"Running for of loop in READY file for loading members.",
);
await Promise.allSettled( await Promise.allSettled(
members.map(async (member) => { members.map(async (member) => {
const memberStruct = await structures.createMemberStruct( const memberStruct = await structures.createMemberStruct(
+4
View File
@@ -10,6 +10,10 @@ export async function handleUserUpdate(data: DiscordGatewayPayload) {
if (!member) return; if (!member) return;
Object.entries(userData).forEach(([key, value]) => { Object.entries(userData).forEach(([key, value]) => {
eventHandlers.debug(
"loop",
`Running forEach loop in USER_UPDATE file.`,
);
// @ts-ignore index signatures // @ts-ignore index signatures
if (member[key] !== value) return member[key] = value; if (member[key] !== value) return member[key] = value;
}); });
+8
View File
@@ -15,10 +15,18 @@ export async function handleGuildRoleDelete(data: DiscordGatewayPayload) {
// For bots without GUILD_MEMBERS member.roles is never updated breaking permissions checking. // For bots without GUILD_MEMBERS member.roles is never updated breaking permissions checking.
cacheHandlers.forEach("members", (member) => { cacheHandlers.forEach("members", (member) => {
eventHandlers.debug(
"loop",
`1. Running forEach members loop in GUILD_ROLE_DELETE file.`,
);
// Not in the relevant guild so just skip. // Not in the relevant guild so just skip.
if (!member.guilds.has(guild.id)) return; if (!member.guilds.has(guild.id)) return;
member.guilds.forEach((g) => { member.guilds.forEach((g) => {
eventHandlers.debug(
"loop",
`2. Running forEach loop in CHANNEL_DELTE file.`,
);
// Member does not have this role // Member does not have this role
if (!g.roles.includes(payload.role_id)) return; if (!g.roles.includes(payload.role_id)) return;
// Remove this role from the members cache // Remove this role from the members cache
+5
View File
@@ -1,3 +1,4 @@
import { eventHandlers } from "../../bot.ts";
import { cacheHandlers } from "../../cache.ts"; import { cacheHandlers } from "../../cache.ts";
import { rest } from "../../rest/rest.ts"; import { rest } from "../../rest/rest.ts";
import { structures } from "../../structures/mod.ts"; import { structures } from "../../structures/mod.ts";
@@ -19,6 +20,10 @@ export async function createChannel(
const requiredPerms: Set<PermissionStrings> = new Set(["MANAGE_CHANNELS"]); const requiredPerms: Set<PermissionStrings> = new Set(["MANAGE_CHANNELS"]);
options?.permissionOverwrites?.forEach((overwrite) => { options?.permissionOverwrites?.forEach((overwrite) => {
eventHandlers.debug(
"loop",
`Running forEach loop in create_channel file.`,
);
overwrite.allow.forEach(requiredPerms.add, requiredPerms); overwrite.allow.forEach(requiredPerms.add, requiredPerms);
overwrite.deny.forEach(requiredPerms.add, requiredPerms); overwrite.deny.forEach(requiredPerms.add, requiredPerms);
}); });
+12 -1
View File
@@ -1,3 +1,4 @@
import { eventHandlers } from "../../bot.ts";
import { rest } from "../../rest/rest.ts"; import { rest } from "../../rest/rest.ts";
import { ModifyChannel } from "../../types/channels/modify_channel.ts"; import { ModifyChannel } from "../../types/channels/modify_channel.ts";
import { endpoints } from "../../util/constants.ts"; import { endpoints } from "../../util/constants.ts";
@@ -77,6 +78,10 @@ function processEditChannelQueue() {
const now = Date.now(); const now = Date.now();
editChannelNameTopicQueue.forEach((request) => { editChannelNameTopicQueue.forEach((request) => {
eventHandlers.debug(
"loop",
`Running forEach loop in edit_channel file.`,
);
if (now > request.timestamp) return; if (now > request.timestamp) return;
// 10 minutes have passed so we can reset this channel again // 10 minutes have passed so we can reset this channel again
if (!request.items.length) { if (!request.items.length) {
@@ -96,7 +101,13 @@ function processEditChannelQueue() {
}); });
if (editChannelNameTopicQueue.size) { if (editChannelNameTopicQueue.size) {
setTimeout(() => processEditChannelQueue(), 600000); setTimeout(() => {
eventHandlers.debug(
"loop",
`Running setTimeout in EDIT_CHANNEL file.`,
);
processEditChannelQueue();
}, 600000);
} else { } else {
editChannelProcessing = false; editChannelProcessing = false;
} }
@@ -1,4 +1,4 @@
import { applicationId } from "../../bot.ts"; import { applicationId, eventHandlers } from "../../bot.ts";
import { cache } from "../../cache.ts"; import { cache } from "../../cache.ts";
import { rest } from "../../rest/rest.ts"; import { rest } from "../../rest/rest.ts";
import { DiscordenoInteractionResponse } from "../../types/discordeno/interaction_response.ts"; import { DiscordenoInteractionResponse } from "../../types/discordeno/interaction_response.ts";
@@ -25,7 +25,13 @@ export async function sendInteractionResponse(
// Expire in 15 minutes // Expire in 15 minutes
cache.executedSlashCommands.set(token, id); cache.executedSlashCommands.set(token, id);
setTimeout( setTimeout(
() => cache.executedSlashCommands.delete(token), () => {
eventHandlers.debug(
"loop",
`Running setTimeout in send_interaction_response file.`,
);
cache.executedSlashCommands.delete(token);
},
900000, 900000,
); );
+8 -1
View File
@@ -1,3 +1,4 @@
import { eventHandlers } from "../../bot.ts";
import { cacheHandlers } from "../../cache.ts"; import { cacheHandlers } from "../../cache.ts";
import { rest } from "../../rest/rest.ts"; import { rest } from "../../rest/rest.ts";
import { Emoji } from "../../types/emojis/emoji.ts"; import { Emoji } from "../../types/emojis/emoji.ts";
@@ -17,7 +18,13 @@ export async function getEmojis(guildId: string, addToCache = true) {
const guild = await cacheHandlers.get("guilds", guildId); const guild = await cacheHandlers.get("guilds", guildId);
if (!guild) throw new Error(Errors.GUILD_NOT_FOUND); if (!guild) throw new Error(Errors.GUILD_NOT_FOUND);
result.forEach((emoji) => guild.emojis.set(emoji.id!, emoji)); result.forEach((emoji) => {
eventHandlers.debug(
"loop",
`Running forEach loop in get_emojis file.`,
);
guild.emojis.set(emoji.id!, emoji);
});
cacheHandlers.set("guilds", guildId, guild); cacheHandlers.set("guilds", guildId, guild);
} }
+10 -2
View File
@@ -1,4 +1,4 @@
import { identifyPayload } from "../../bot.ts"; import { eventHandlers, identifyPayload } from "../../bot.ts";
import { cacheHandlers } from "../../cache.ts"; import { cacheHandlers } from "../../cache.ts";
import { rest } from "../../rest/rest.ts"; import { rest } from "../../rest/rest.ts";
import { Member, structures } from "../../structures/mod.ts"; import { Member, structures } from "../../structures/mod.ts";
@@ -32,6 +32,8 @@ export async function getMembers(guildId: string, options?: GetMemberOptions) {
(options?.limit ?? guild.memberCount) > members.size && (options?.limit ?? guild.memberCount) > members.size &&
membersLeft > 0 membersLeft > 0
) { ) {
eventHandlers.debug("loop", "Running while loop in getMembers function.");
if (options?.limit && options.limit > 1000) { if (options?.limit && options.limit > 1000) {
console.log( console.log(
`Paginating get members from REST. #${loops} / ${ `Paginating get members from REST. #${loops} / ${
@@ -64,7 +66,13 @@ export async function getMembers(guildId: string, options?: GetMemberOptions) {
if (!memberStructures.length) break; if (!memberStructures.length) break;
memberStructures.forEach((member) => members.set(member.id, member)); memberStructures.forEach((member) => {
eventHandlers.debug(
"loop",
`Running forEach loop in get_members file.`,
);
members.set(member.id, member);
});
options = { options = {
limit: options?.limit, limit: options?.limit,
+5
View File
@@ -1,3 +1,4 @@
import { eventHandlers } from "../../bot.ts";
import { addReaction } from "./add_reaction.ts"; import { addReaction } from "./add_reaction.ts";
/** Adds multiple reactions to a message. If `ordered` is true(default is false), it will add the reactions one at a time in the order provided. Note: Reaction takes the form of **name:id** for custom guild emoji, or Unicode characters. Requires READ_MESSAGE_HISTORY and ADD_REACTIONS */ /** Adds multiple reactions to a message. If `ordered` is true(default is false), it will add the reactions one at a time in the order provided. Note: Reaction takes the form of **name:id** for custom guild emoji, or Unicode characters. Requires READ_MESSAGE_HISTORY and ADD_REACTIONS */
@@ -13,6 +14,10 @@ export async function addReactions(
); );
} else { } else {
for (const reaction of reactions) { for (const reaction of reactions) {
eventHandlers.debug(
"loop",
"Running for of loop in addReactions function.",
);
await addReaction(channelId, messageId, reaction); await addReaction(channelId, messageId, reaction);
} }
} }
+4
View File
@@ -3,6 +3,10 @@ import { rest } from "./rest.ts";
/** Cleans up the queues by checking if there is nothing left and removing it. */ /** Cleans up the queues by checking if there is nothing left and removing it. */
export function cleanupQueues() { export function cleanupQueues() {
for (const [key, queue] of rest.pathQueues) { for (const [key, queue] of rest.pathQueues) {
rest.eventHandlers.debug(
"loop",
"Running for of loop in cleanupQueues function.",
);
if (queue.length) continue; if (queue.length) continue;
// REMOVE IT FROM CACHE // REMOVE IT FROM CACHE
rest.pathQueues.delete(key); rest.pathQueues.delete(key);
+12 -1
View File
@@ -1,3 +1,4 @@
import { eventHandlers } from "../bot.ts";
import { DiscordHTTPResponseCodes } from "../types/codes/http_response_codes.ts"; import { DiscordHTTPResponseCodes } from "../types/codes/http_response_codes.ts";
import { delay } from "../util/utils.ts"; import { delay } from "../util/utils.ts";
import { rest } from "./rest.ts"; import { rest } from "./rest.ts";
@@ -8,9 +9,19 @@ export async function processQueue(id: string) {
if (!queue) return; if (!queue) return;
while (queue.length) { while (queue.length) {
rest.eventHandlers.debug(
"loop",
"Running while loop in processQueue function.",
);
// IF THE BOT IS GLOBALLY RATELIMITED TRY AGAIN // IF THE BOT IS GLOBALLY RATELIMITED TRY AGAIN
if (rest.globallyRateLimited) { if (rest.globallyRateLimited) {
setTimeout(() => processQueue(id), 1000); setTimeout(() => {
eventHandlers.debug(
"loop",
`Running setTimeout in processQueue function.`,
);
processQueue(id);
}, 1000);
break; break;
} }
+12 -1
View File
@@ -1,3 +1,4 @@
import { eventHandlers } from "../bot.ts";
import { rest } from "./rest.ts"; import { rest } from "./rest.ts";
/** This will create a infinite loop running in 1 seconds using tail recursion to keep rate limits clean. When a rate limit resets, this will remove it so the queue can proceed. */ /** This will create a infinite loop running in 1 seconds using tail recursion to keep rate limits clean. When a rate limit resets, this will remove it so the queue can proceed. */
@@ -5,6 +6,10 @@ export function processRateLimitedPaths() {
const now = Date.now(); const now = Date.now();
rest.ratelimitedPaths.forEach((value, key) => { rest.ratelimitedPaths.forEach((value, key) => {
rest.eventHandlers.debug(
"loop",
`Running forEach loop in process_rate_limited_paths file.`,
);
// IF THE TIME HAS NOT REACHED CANCEL // IF THE TIME HAS NOT REACHED CANCEL
if (value.resetTimestamp > now) return; if (value.resetTimestamp > now) return;
// RATE LIMIT IS OVER, DELETE THE RATE LIMITER // RATE LIMIT IS OVER, DELETE THE RATE LIMITER
@@ -20,6 +25,12 @@ export function processRateLimitedPaths() {
} else { } else {
rest.processingRateLimitedPaths = true; rest.processingRateLimitedPaths = true;
// RECHECK IN 1 SECOND // RECHECK IN 1 SECOND
setTimeout(() => processRateLimitedPaths(), 1000); setTimeout(() => {
eventHandlers.debug(
"loop",
`Running setTimeout in processRateLimitedPaths function.`,
);
processRateLimitedPaths();
}, 1000);
} }
} }
+5
View File
@@ -1,3 +1,4 @@
import { eventHandlers } from "../bot.ts";
import { cache } from "../cache.ts"; import { cache } from "../cache.ts";
import { channelOverwriteHasPermission } from "../helpers/channels/channel_overwrite_has_permission.ts"; import { channelOverwriteHasPermission } from "../helpers/channels/channel_overwrite_has_permission.ts";
import { deleteChannel } from "../helpers/channels/delete_channel.ts"; import { deleteChannel } from "../helpers/channels/delete_channel.ts";
@@ -81,6 +82,10 @@ export async function createChannelStruct(
const props: Record<string, PropertyDescriptor> = {}; const props: Record<string, PropertyDescriptor> = {};
Object.keys(rest).forEach((key) => { Object.keys(rest).forEach((key) => {
eventHandlers.debug(
"loop",
`Running forEach loop in createChannelStruct function.`,
);
// @ts-ignore index signature // @ts-ignore index signature
props[key] = createNewProp(rest[key]); props[key] = createNewProp(rest[key]);
}); });
+5 -1
View File
@@ -1,4 +1,4 @@
import { botId } from "../bot.ts"; import { botId, eventHandlers } from "../bot.ts";
import { cache, cacheHandlers } from "../cache.ts"; import { cache, cacheHandlers } from "../cache.ts";
import { deleteServer } from "../helpers/guilds/delete_server.ts"; import { deleteServer } from "../helpers/guilds/delete_server.ts";
import { editGuild } from "../helpers/guilds/edit_guild.ts"; import { editGuild } from "../helpers/guilds/edit_guild.ts";
@@ -147,6 +147,10 @@ export async function createGuildStruct(
const props: Record<string, ReturnType<typeof createNewProp>> = {}; const props: Record<string, ReturnType<typeof createNewProp>> = {};
for (const key of Object.keys(rest)) { for (const key of Object.keys(rest)) {
eventHandlers.debug(
"loop",
`Running for of loop in createGuildStruct function.`,
);
// @ts-ignore index signature // @ts-ignore index signature
props[key] = createNewProp(rest[key]); props[key] = createNewProp(rest[key]);
} }
+13
View File
@@ -1,3 +1,4 @@
import { eventHandlers } from "../bot.ts";
import { cache, cacheHandlers } from "../cache.ts"; import { cache, cacheHandlers } from "../cache.ts";
import { avatarURL } from "../helpers/members/avatar_url.ts"; import { avatarURL } from "../helpers/members/avatar_url.ts";
import { banMember } from "../helpers/members/ban_member.ts"; import { banMember } from "../helpers/members/ban_member.ts";
@@ -87,11 +88,19 @@ export async function createMemberStruct(
const props: Record<string, ReturnType<typeof createNewProp>> = {}; const props: Record<string, ReturnType<typeof createNewProp>> = {};
for (const key of Object.keys(rest)) { for (const key of Object.keys(rest)) {
eventHandlers.debug(
"loop",
`Running for of loop for Object.keys(rest) in createMemberStruct function.`,
);
// @ts-ignore index signature // @ts-ignore index signature
props[key] = createNewProp(rest[key]); props[key] = createNewProp(rest[key]);
} }
for (const key of Object.keys(user)) { for (const key of Object.keys(user)) {
eventHandlers.debug(
"loop",
`Running for of for Object.keys(user) loop in createMemberStruct function.`,
);
// @ts-ignore index signature // @ts-ignore index signature
props[key] = createNewProp(user[key]); props[key] = createNewProp(user[key]);
} }
@@ -105,6 +114,10 @@ export async function createMemberStruct(
const cached = await cacheHandlers.get("members", user.id); const cached = await cacheHandlers.get("members", user.id);
if (cached) { if (cached) {
for (const [id, guild] of cached.guilds.entries()) { for (const [id, guild] of cached.guilds.entries()) {
eventHandlers.debug(
"loop",
`Running for of for cached.guilds.entries() loop in createMemberStruct function.`,
);
member.guilds.set(id, guild); member.guilds.set(id, guild);
} }
} }
+5
View File
@@ -1,3 +1,4 @@
import { eventHandlers } from "../bot.ts";
import { cache, cacheHandlers } from "../cache.ts"; import { cache, cacheHandlers } from "../cache.ts";
import { sendDirectMessage } from "../helpers/members/send_direct_message.ts"; import { sendDirectMessage } from "../helpers/members/send_direct_message.ts";
import { addReaction } from "../helpers/messages/add_reaction.ts"; import { addReaction } from "../helpers/messages/add_reaction.ts";
@@ -129,6 +130,10 @@ export async function createMessageStruct(data: DiscordMessage) {
const props: Record<string, ReturnType<typeof createNewProp>> = {}; const props: Record<string, ReturnType<typeof createNewProp>> = {};
for (const key of Object.keys(rest)) { for (const key of Object.keys(rest)) {
eventHandlers.debug(
"loop",
`Running for of loop in createMessageStruct function.`,
);
// @ts-ignore index signature // @ts-ignore index signature
props[key] = createNewProp(rest[key]); props[key] = createNewProp(rest[key]);
} }
+5
View File
@@ -1,3 +1,4 @@
import { eventHandlers } from "../bot.ts";
import { cache } from "../cache.ts"; import { cache } from "../cache.ts";
import { deleteRole } from "../helpers/roles/delete_role.ts"; import { deleteRole } from "../helpers/roles/delete_role.ts";
import { editRole } from "../helpers/roles/edit_role.ts"; import { editRole } from "../helpers/roles/edit_role.ts";
@@ -74,6 +75,10 @@ export async function createRoleStruct(data: DiscordGuildRoleCreate) {
const props: Record<string, ReturnType<typeof createNewProp>> = {}; const props: Record<string, ReturnType<typeof createNewProp>> = {};
for (const key of Object.keys(rest)) { for (const key of Object.keys(rest)) {
eventHandlers.debug(
"loop",
`Running for of loop in createRoleStruct function.`,
);
// @ts-ignore index signature // @ts-ignore index signature
props[key] = createNewProp(rest[key]); props[key] = createNewProp(rest[key]);
} }
+5
View File
@@ -1,3 +1,4 @@
import { eventHandlers } from "../bot.ts";
import { cache } from "../cache.ts"; import { cache } from "../cache.ts";
import { createNewProp } from "../util/utils.ts"; import { createNewProp } from "../util/utils.ts";
@@ -25,6 +26,10 @@ export function createTemplateStruct(
const restProps: Record<string, Partial<PropertyDescriptor>> = {}; const restProps: Record<string, Partial<PropertyDescriptor>> = {};
for (const key of Object.keys(rest)) { for (const key of Object.keys(rest)) {
eventHandlers.debug(
"loop",
`Running for of loop in createTemplateStruct function.`,
);
// @ts-ignore index signature // @ts-ignore index signature
restProps[key] = createNewProp(rest[key]); restProps[key] = createNewProp(rest[key]);
} }
+26
View File
@@ -1,4 +1,5 @@
import { encode } from "../../deps.ts"; import { encode } from "../../deps.ts";
import { eventHandlers } from "../bot.ts";
import { DiscordGatewayOpcodes } from "../types/codes/gateway_opcodes.ts"; import { DiscordGatewayOpcodes } from "../types/codes/gateway_opcodes.ts";
import { Errors } from "../types/misc/errors.ts"; import { Errors } from "../types/misc/errors.ts";
import { DiscordImageFormat } from "../types/misc/image_format.ts"; import { DiscordImageFormat } from "../types/misc/image_format.ts";
@@ -10,10 +11,15 @@ export const sleep = (timeout: number) => {
return new Promise((resolve) => setTimeout(resolve, timeout)); return new Promise((resolve) => setTimeout(resolve, timeout));
}; };
// TODO: move this function to helpers
export function editBotStatus( export function editBotStatus(
data: Pick<GatewayStatusUpdatePayload, "activities" | "status">, data: Pick<GatewayStatusUpdatePayload, "activities" | "status">,
) { ) {
ws.shards.forEach((shard) => { ws.shards.forEach((shard) => {
eventHandlers.debug(
"loop",
`Running forEach loop in editBotStatus function.`,
);
shard.ws.send( shard.ws.send(
JSON.stringify({ JSON.stringify({
op: DiscordGatewayOpcodes.StatusUpdate, op: DiscordGatewayOpcodes.StatusUpdate,
@@ -83,6 +89,10 @@ export function camelKeysToSnakeCase<T>(
const convertedObject: Record<string, any> = {}; const convertedObject: Record<string, any> = {};
Object.keys(obj).forEach((key) => { Object.keys(obj).forEach((key) => {
eventHandlers.debug(
"loop",
`Running forEach loop in camelKeysToSnakeCase function.`,
);
convertedObject[camelToSnakeCase(key)] = camelKeysToSnakeCase( convertedObject[camelToSnakeCase(key)] = camelKeysToSnakeCase(
(obj as Record<string, any>)[key], (obj as Record<string, any>)[key],
); );
@@ -105,6 +115,10 @@ export function snakeKeysToCamelCase<T>(
const convertedObject: Record<string, any> = {}; const convertedObject: Record<string, any> = {};
Object.keys(obj).forEach((key) => { Object.keys(obj).forEach((key) => {
eventHandlers.debug(
"loop",
`Running forEach loop in snakeKeysToCamelCase function.`,
);
convertedObject[snakeToCamelCase(key)] = snakeKeysToCamelCase( convertedObject[snakeToCamelCase(key)] = snakeKeysToCamelCase(
(obj as Record<string, any>)[key], (obj as Record<string, any>)[key],
); );
@@ -124,6 +138,10 @@ function validateSlashOptionChoices(
optionType: SlashCommandOptionType, optionType: SlashCommandOptionType,
) { ) {
for (const choice of choices) { for (const choice of choices) {
eventHandlers.debug(
"loop",
`Running for of loop in validateSlashOptionChoices function.`,
);
if ([...choice.name].length < 1 || [...choice.name].length > 100) { if ([...choice.name].length < 1 || [...choice.name].length > 100) {
throw new Error(Errors.INVALID_SLASH_OPTIONS_CHOICES); throw new Error(Errors.INVALID_SLASH_OPTIONS_CHOICES);
} }
@@ -144,6 +162,10 @@ function validateSlashOptionChoices(
/** @private */ /** @private */
function validateSlashOptions(options: SlashCommandOption[]) { function validateSlashOptions(options: SlashCommandOption[]) {
for (const option of options) { for (const option of options) {
eventHandlers.debug(
"loop",
`Running for of loop in validateSlashOptions function.`,
);
if ( if (
option.choices?.length && option.choices?.length &&
(option.choices.length > 25 || (option.choices.length > 25 ||
@@ -174,6 +196,10 @@ export function validateSlashCommands(
create = false, create = false,
) { ) {
for (const command of commands) { for (const command of commands) {
eventHandlers.debug(
"loop",
`Running for of loop in validateSlashCommands function.`,
);
if ( if (
(command.name && !SLASH_COMMANDS_NAME_REGEX.test(command.name)) || (command.name && !SLASH_COMMANDS_NAME_REGEX.test(command.name)) ||
(create && !command.name) (create && !command.name)
+8
View File
@@ -4,8 +4,16 @@ import { ws } from "./ws.ts";
/** The handler to clean up shards that identified but never received a READY. */ /** The handler to clean up shards that identified but never received a READY. */
export async function cleanupLoadingShards() { export async function cleanupLoadingShards() {
while (ws.loadingShards.size) { while (ws.loadingShards.size) {
ws.log(
"DEBUG",
"Running while loop in cleanupLoadingShards function.",
);
const now = Date.now(); const now = Date.now();
ws.loadingShards.forEach((loadingShard) => { ws.loadingShards.forEach((loadingShard) => {
ws.log(
"DEBUG",
`Running forEach loop in cleanupLoadingShards function.`,
);
// Not a minute yet. Max should be few seconds but do a minute to be safe. // Not a minute yet. Max should be few seconds but do a minute to be safe.
if (now < loadingShard.startedAt + 60000) return; if (now < loadingShard.startedAt + 60000) return;
+3 -1
View File
@@ -42,6 +42,7 @@ export function log(type: "RAW", data: Record<string, unknown>): unknown;
export function log(type: "RECONNECT", data: { shardId: number }): unknown; export function log(type: "RECONNECT", data: { shardId: number }): unknown;
export function log(type: "RESUMED", data: { shardId: number }): unknown; export function log(type: "RESUMED", data: { shardId: number }): unknown;
export function log(type: "RESUMING", data: { shardId: number }): unknown; export function log(type: "RESUMING", data: { shardId: number }): unknown;
export function log(type: "DEBUG", data: unknown): unknown;
export function log( export function log(
type: type:
| "CLOSED" | "CLOSED"
@@ -56,7 +57,8 @@ export function log(
| "RAW" | "RAW"
| "RECONNECT" | "RECONNECT"
| "RESUMED" | "RESUMED"
| "RESUMING", | "RESUMING"
| "DEBUG",
data: unknown, data: unknown,
) { ) {
console.log(type, data); console.log(type, data);
+4
View File
@@ -15,6 +15,10 @@ export function heartbeat(shardId: number, interval: number) {
shard.heartbeat.interval = interval; shard.heartbeat.interval = interval;
shard.heartbeat.intervalId = setInterval(() => { shard.heartbeat.intervalId = setInterval(() => {
ws.log(
"DEBUG",
`Running setInterval in heartbeat file.`,
);
const currentShard = ws.shards.get(shardId); const currentShard = ws.shards.get(shardId);
if (!currentShard) return; if (!currentShard) return;
+17
View File
@@ -13,8 +13,16 @@ export function spawnShards(firstShardId = 0) {
index < ws.botGatewayData.sessionStartLimit.maxConcurrency; index < ws.botGatewayData.sessionStartLimit.maxConcurrency;
index++ index++
) { ) {
ws.log(
"DEBUG",
`1. Running for loop in spawnShards function.`,
);
// ORGANIZE ALL SHARDS INTO THEIR OWN BUCKETS // ORGANIZE ALL SHARDS INTO THEIR OWN BUCKETS
for (let i = 0; i < maxShards; i++) { for (let i = 0; i < maxShards; i++) {
ws.log(
"DEBUG",
`2. Running for loop in spawnShards function.`,
);
const bucketId = i % ws.botGatewayData.sessionStartLimit.maxConcurrency; const bucketId = i % ws.botGatewayData.sessionStartLimit.maxConcurrency;
const bucket = buckets.get(bucketId); const bucket = buckets.get(bucketId);
@@ -40,10 +48,19 @@ export function spawnShards(firstShardId = 0) {
// SPREAD THIS OUT TO DIFFERENT CLUSTERS TO BEGIN STARTING UP // SPREAD THIS OUT TO DIFFERENT CLUSTERS TO BEGIN STARTING UP
buckets.forEach(async (bucket, bucketId) => { buckets.forEach(async (bucket, bucketId) => {
ws.log(
"DEBUG",
`3. Running forEach loop in spawnShards function.`,
);
for (const [clusterId, ...queue] of bucket) { for (const [clusterId, ...queue] of bucket) {
ws.log(
"DEBUG",
`4. Running for of loop in spawnShards function.`,
);
let shardId = queue.shift(); let shardId = queue.shift();
while (shardId !== undefined) { while (shardId !== undefined) {
ws.log("DEBUG", "Running while loop in getMembers function.");
await ws.tellClusterToIdentify(clusterId as number, shardId, bucketId); await ws.tellClusterToIdentify(clusterId as number, shardId, bucketId);
shardId = queue.shift(); shardId = queue.shift();
} }