diff --git a/denoImportMap.json b/denoImportMap.json index 7eb3cbc2f..4afeb3488 100644 --- a/denoImportMap.json +++ b/denoImportMap.json @@ -1,6 +1,7 @@ { "imports": { "node:buffer": "https://deno.land/std@0.176.0/node/buffer.ts", + "node:crypto": "https://deno.land/std@0.176.0/node/crypto.ts", "node:fs": "https://deno.land/std@0.176.0/node/fs.ts", "node:fs/promises": "https://deno.land/std@0.176.0/node/fs/promises.ts", "node:events": "https://deno.land/std@0.176.0/node/events.ts", diff --git a/packages/gateway/src/manager.ts b/packages/gateway/src/manager.ts index 47f952c36..0a9aa3010 100644 --- a/packages/gateway/src/manager.ts +++ b/packages/gateway/src/manager.ts @@ -1,3 +1,4 @@ +import { randomBytes } from 'node:crypto' import { type AtLeastOne, type BigString, @@ -506,22 +507,32 @@ export function createGatewayManager(options: CreateGatewayManagerOptions): Gate options.limit = options.userIds.length } - const members = - !gateway.cache.requestMembers.enabled || !options?.nonce - ? [] - : new Promise>((resolve, reject) => { - // Should never happen. - if (!gateway.cache.requestMembers.enabled || !options?.nonce) { - reject(new Error("Can't request the members without the nonce or with the feature disabled.")) - return - } + if (!options?.nonce) { + let nonce = '' - gateway.cache.requestMembers.pending.set(options.nonce, { - nonce: options.nonce, - resolve, - members: [], - }) + while (!nonce || gateway.cache.requestMembers.pending.has(nonce)) { + nonce = randomBytes(16).toString('hex') + } + + options ??= { limit: 0 } + options.nonce = nonce + } + + const members = !gateway.cache.requestMembers.enabled + ? [] + : new Promise>((resolve, reject) => { + // Should never happen. + if (!gateway.cache.requestMembers.enabled || !options?.nonce) { + reject(new Error("Can't request the members without the nonce or with the feature disabled.")) + return + } + + gateway.cache.requestMembers.pending.set(options.nonce, { + nonce: options.nonce, + resolve, + members: [], }) + }) await gateway.sendPayload(shardId, { op: GatewayOpcodes.RequestGuildMembers, @@ -807,7 +818,7 @@ export interface GatewayManager extends Required { */ editShardStatus: (shardId: number, data: StatusUpdate) => Promise /** - * Fetches the list of members for a guild over the gateway. + * Fetches the list of members for a guild over the gateway. If `gateway.cache.requestMembers.enabled` is not set, this function will return an empty array and you'll have to handle the `GUILD_MEMBERS_CHUNK` events yourself. * * @param guildId - The ID of the guild to get the list of members for. * @param options - The parameters for the fetching of the members.