diff --git a/src/module/basicShard.ts b/src/module/basicShard.ts index 60717ca3c..68b9196ff 100644 --- a/src/module/basicShard.ts +++ b/src/module/basicShard.ts @@ -51,7 +51,7 @@ export async function createBasicShard( const basicShard: BasicShard = { id: shardID, - socket: await connectWebSocket(`${data.url}?v=6&encoding=json`), + socket: await connectWebSocket(`${data.url}?v=8&encoding=json`), resumeInterval: 0, sessionID: oldShard?.sessionID || "", previousSequenceNumber: oldShard?.previousSequenceNumber || 0, diff --git a/src/module/bigbrainbot.ts b/src/module/bigbrainbot.ts index db30b173a..aa18c76e7 100644 --- a/src/module/bigbrainbot.ts +++ b/src/module/bigbrainbot.ts @@ -1,16 +1,12 @@ -import { delay } from "../../deps.ts"; -import { DiscordBotGatewayData, RequestManager } from "../../mod.ts"; +import { DiscordBotGatewayData, RequestManager, spawnBigBrainBotShards } from "../../mod.ts"; import { endpoints } from "../constants/discord.ts"; import { ClientOptions, EventHandlers } from "../types/options.ts"; -import { botGatewayData } from "./client.ts"; const botOptions = { createNextShard: false, workers: new Map(), eventHandlers: {} as EventHandlers, botGatewayData: {} as DiscordBotGatewayData, - customShards: [] as number[], - shardsPerWorker: 25, identifyPayload: { token: "", compress: true, @@ -20,7 +16,7 @@ const botOptions = { $device: "Discordeno", }, intents: 0, - shard: [0, 0], + shard: [0, 0] as [number, number], }, }; @@ -33,9 +29,7 @@ const botOptions = { export async function startBigBrainBot(data: BigBrainBotOptions) { botOptions.identifyPayload.token = `Bot ${data.token}`; if (data.eventHandlers) botOptions.eventHandlers = data.eventHandlers; - if (data.shards) botOptions.customShards = data.shards; if (data.compress) botOptions.identifyPayload.compress = data.compress; - if (data.shardsPerWorker) botOptions.shardsPerWorker = data.shardsPerWorker; // Initial API connection to get info about bots connection botOptions.botGatewayData = await RequestManager.get( @@ -46,58 +40,19 @@ export async function startBigBrainBot(data: BigBrainBotOptions) { (bits, next) => (bits |= next), 0, ); - botOptions.identifyPayload.shard = [0, botGatewayData.shards]; - spawnBigBrainBotShards(); + spawnBigBrainBotShards(botOptions.botGatewayData, botOptions.identifyPayload, data.firstShardID, data.lastShardID || (data.firstShardID + 25)); } -async function spawnBigBrainBotShards(shardID = 0, skipChecks = 0) { - if (shardID >= botOptions.botGatewayData.shards) return; - // 25 shards but shards start at 0 so we use 24 - const workerID = shardID % botOptions.shardsPerWorker - 1; - const worker = botOptions.workers.get(workerID) - - // High max concurrency allows starting shards faster - if (skipChecks) { - // If the worker exists we just need to add - if (worker) { - worker.postMessage({ type: "CREATE_SHARD", shardID, workerID, botOptions }); - } else { - const path = new URL("./shard.ts", import.meta.url).toString(); - const newWorker = new Worker(path, { type: "module", deno: true }); - // Add to worker map - botOptions.workers.set(workerID, newWorker); - newWorker.postMessage({ type: "CREATE_SHARD", shardID, workerID, botOptions }); - } - - spawnBigBrainBotShards(shardID + 1, skipChecks - 1); - } - - // Make sure we can create a shard or we are waiting for shards to connect still. - if (botOptions.createNextShard) { - // !(shardid % botOptions.botGatewayData.session_start_limit.max_concurrency) - botOptions.createNextShard = false; - // Start the next few shards based on max concurrency - spawnBigBrainBotShards(shardID + 1, botOptions.botGatewayData.session_start_limit.max_concurrency); - return; - } - - await delay(1000); - spawnBigBrainBotShards(shardID); -} export interface BigBrainBotOptions extends ClientOptions { - /** This can be used to distribute your bot across different servers. For example, if you wanted 1 million shards per server you could control it using this. */ - shards?: [number, number]; + /** The first shard to start at for this worker. Use this to control which shards to run in each worker. */ + firstShardID: number; + /** The last shard to start for this worker. By default it will be 25 + the firstShardID. */ + lastShardID?: number; /** This can be used to forward the ws handling to a proxy. */ wsURL?: string; /** This can be used to forward the REST handling to a proxy. */ restURL?: string; - /** This allows you to control how many shards per worker. For the times where you can optimize with more shards per worker as your bot has less tasks per shard. - * @default 25 - */ - shardsPerWorker?: number; - /** The absolute file path to the file where the worker will run. */ - workerFilePath?: string; } diff --git a/src/module/shardingManager.ts b/src/module/shardingManager.ts index 4b1cb2d31..68d8e7476 100644 --- a/src/module/shardingManager.ts +++ b/src/module/shardingManager.ts @@ -60,6 +60,31 @@ export function createShardWorker(shardID?: number) { shards.push(shard); } +export async function spawnBigBrainBotShards(data: DiscordBotGatewayData, payload: IdentifyPayload, shardID: number, lastShardID: number, skipChecks?: number) { + // All shards on this worker have started! Cancel out. + if (shardID > lastShardID) return; + + if (skipChecks) { + payload.shard = [shardID, data.shards]; + // Start The shard + createBasicShard(data, payload, false, shardID); + // Spawn next shard + spawnBigBrainBotShards(data, payload, shardID, lastShardID, skipChecks - 1); + return; + } + + // Make sure we can create a shard or we are waiting for shards to connect still. + if (createNextShard) { + createNextShard = false; + // Start the next few shards based on max concurrency + spawnBigBrainBotShards(data, payload, shardID + 1, lastShardID, data.session_start_limit.max_concurrency); + return; + } + + await delay(1000); + spawnBigBrainBotShards(data, payload, shardID, lastShardID, skipChecks); +} + export const spawnShards = async ( data: DiscordBotGatewayData, payload: IdentifyPayload,