mirror of
https://github.com/discordeno/discordeno.git
synced 2026-06-16 11:28:15 +00:00
+8
-8
@@ -5,8 +5,8 @@ import { baseEndpoints, GATEWAY_VERSION } from "./util/constants.ts";
|
|||||||
|
|
||||||
export let authorization = "";
|
export let authorization = "";
|
||||||
export let secretKey = "";
|
export let secretKey = "";
|
||||||
export let botID = "";
|
export let botId = "";
|
||||||
export let applicationID = "";
|
export let applicationId = "";
|
||||||
|
|
||||||
export let eventHandlers: EventHandlers = {};
|
export let eventHandlers: EventHandlers = {};
|
||||||
|
|
||||||
@@ -109,10 +109,10 @@ export async function startBigBrainBot(data: BigBrainBotConfig) {
|
|||||||
await spawnShards(
|
await spawnShards(
|
||||||
botGatewayData,
|
botGatewayData,
|
||||||
identifyPayload,
|
identifyPayload,
|
||||||
data.firstShardID,
|
data.firstShardId,
|
||||||
data.lastShardID ||
|
data.lastShardId ||
|
||||||
(botGatewayData.shards >= 25
|
(botGatewayData.shards >= 25
|
||||||
? (data.firstShardID + 25)
|
? (data.firstShardId + 25)
|
||||||
: botGatewayData.shards),
|
: botGatewayData.shards),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -127,9 +127,9 @@ export interface BotConfig {
|
|||||||
|
|
||||||
export interface BigBrainBotConfig extends BotConfig {
|
export interface BigBrainBotConfig extends BotConfig {
|
||||||
/** The first shard to start at for this worker. Use this to control which shards to run in each worker. */
|
/** The first shard to start at for this worker. Use this to control which shards to run in each worker. */
|
||||||
firstShardID: number;
|
firstShardId: number;
|
||||||
/** The last shard to start for this worker. By default it will be 25 + the firstShardID. */
|
/** The last shard to start for this worker. By default it will be 25 + the firstShardId. */
|
||||||
lastShardID?: number;
|
lastShardId?: number;
|
||||||
/** This can be used to forward the ws handling to a proxy. It will disable the sharding done by the bot side. */
|
/** This can be used to forward the ws handling to a proxy. It will disable the sharding done by the bot side. */
|
||||||
wsPort?: number;
|
wsPort?: number;
|
||||||
/** This can be used to forward the REST handling to a proxy. */
|
/** This can be used to forward the REST handling to a proxy. */
|
||||||
|
|||||||
@@ -240,13 +240,13 @@ export interface GuildStruct extends
|
|||||||
/** Returns the audit logs for the guild. Requires VIEW AUDIT LOGS permission */
|
/** Returns the audit logs for the guild. Requires VIEW AUDIT LOGS permission */
|
||||||
auditLogs(options: GetGuildAuditLog): ReturnType<typeof getAuditLogs>;
|
auditLogs(options: GetGuildAuditLog): ReturnType<typeof getAuditLogs>;
|
||||||
/** Returns a ban object for the given user or a 404 not found if the ban cannot be found. Requires the BAN_MEMBERS permission. */
|
/** Returns a ban object for the given user or a 404 not found if the ban cannot be found. Requires the BAN_MEMBERS permission. */
|
||||||
getBan(memberID: string): ReturnType<typeof getBan>;
|
getBan(memberId: string): ReturnType<typeof getBan>;
|
||||||
/** Returns a list of ban objects for the users banned from this guild. Requires the BAN_MEMBERS permission. */
|
/** Returns a list of ban objects for the users banned from this guild. Requires the BAN_MEMBERS permission. */
|
||||||
bans(): ReturnType<typeof getBans>;
|
bans(): ReturnType<typeof getBans>;
|
||||||
/** Ban a user from the guild and optionally delete previous messages sent by the user. Requires the BAN_MEMBERS permission. */
|
/** Ban a user from the guild and optionally delete previous messages sent by the user. Requires the BAN_MEMBERS permission. */
|
||||||
ban(memberID: string, options: CreateGuildBan): ReturnType<typeof banMember>;
|
ban(memberId: string, options: CreateGuildBan): ReturnType<typeof banMember>;
|
||||||
/** Remove the ban for a user. Requires BAN_MEMBERS permission */
|
/** Remove the ban for a user. Requires BAN_MEMBERS permission */
|
||||||
unban(memberID: string): ReturnType<typeof unbanMember>;
|
unban(memberId: string): ReturnType<typeof unbanMember>;
|
||||||
/** Get all the invites for this guild. Requires MANAGE_GUILD permission */
|
/** Get all the invites for this guild. Requires MANAGE_GUILD permission */
|
||||||
invites(): ReturnType<typeof getInvites>;
|
invites(): ReturnType<typeof getInvites>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/** https://discord.com/developers/docs/topics/opcodes-and-status-codes#rpc */
|
/** https://discord.com/developers/docs/topics/opcodes-and-status-codes#rpc */
|
||||||
export enum DiscordRpcCloseEventCodes {
|
export enum DiscordRpcCloseEventCodes {
|
||||||
InvalidClientID = 4000,
|
InvalidClientId = 4000,
|
||||||
InvalidOrigin,
|
InvalidOrigin,
|
||||||
RateLimited,
|
RateLimited,
|
||||||
TokenRevoked,
|
TokenRevoked,
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ export enum DiscordRpcErrorCodes {
|
|||||||
InvalidEvent,
|
InvalidEvent,
|
||||||
InvalidChannel,
|
InvalidChannel,
|
||||||
InvalidPermissions,
|
InvalidPermissions,
|
||||||
InvalidClientID,
|
InvalidClientId,
|
||||||
InvalidOrigin,
|
InvalidOrigin,
|
||||||
InvalidToken,
|
InvalidToken,
|
||||||
InvalidUser,
|
InvalidUser,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { SnakeCaseProps } from "../util.ts";
|
|||||||
import { ApplicationCommandInteractionDataOption } from "./application_command_interaction_data_option.ts";
|
import { ApplicationCommandInteractionDataOption } from "./application_command_interaction_data_option.ts";
|
||||||
|
|
||||||
export interface ApplicationCommandInteractionData {
|
export interface ApplicationCommandInteractionData {
|
||||||
/** The ID of the invoked command */
|
/** The Id of the invoked command */
|
||||||
id: string;
|
id: string;
|
||||||
/** The name of the invoked command */
|
/** The name of the invoked command */
|
||||||
name: string;
|
name: string;
|
||||||
|
|||||||
+12
-12
@@ -67,10 +67,10 @@ startGateway({
|
|||||||
intents: ["GUILDS", "GUILD_MESSAGES"],
|
intents: ["GUILDS", "GUILD_MESSAGES"],
|
||||||
/** The max amount of shards used for identifying. This can be useful for zero-downtime updates or resharding. */
|
/** The max amount of shards used for identifying. This can be useful for zero-downtime updates or resharding. */
|
||||||
maxShards: 885,
|
maxShards: 885,
|
||||||
/** The first shard ID for this group of shards. */
|
/** The first shard Id for this group of shards. */
|
||||||
firstShardID: 100,
|
firstShardId: 100,
|
||||||
/** The last shard ID for this group. If none is provided, it will default to loading all shards. */
|
/** The last shard Id for this group. If none is provided, it will default to loading all shards. */
|
||||||
lastShardID: 124,
|
lastShardId: 124,
|
||||||
/** The url to forward all payloads to. */
|
/** The url to forward all payloads to. */
|
||||||
url: "http://urlToYourServerHere",
|
url: "http://urlToYourServerHere",
|
||||||
/** The amount of shards per cluster. By default this is 25. Use this to spread the load from shards to different CPU cores. */
|
/** The amount of shards per cluster. By default this is 25. Use this to spread the load from shards to different CPU cores. */
|
||||||
@@ -93,16 +93,16 @@ export const ws = {
|
|||||||
reshard: true,
|
reshard: true,
|
||||||
/** The percentage at which resharding should occur. */
|
/** The percentage at which resharding should occur. */
|
||||||
reshardPercentage: 80,
|
reshardPercentage: 80,
|
||||||
/** The maximum shard ID number. Useful for zero-downtime updates or resharding. */
|
/** The maximum shard Id number. Useful for zero-downtime updates or resharding. */
|
||||||
maxShards: 1,
|
maxShards: 1,
|
||||||
/** The amount of shards to load per cluster */
|
/** The amount of shards to load per cluster */
|
||||||
shardsPerCluster: 25,
|
shardsPerCluster: 25,
|
||||||
/** The maximum amount of clusters to use for your bot. */
|
/** The maximum amount of clusters to use for your bot. */
|
||||||
maxClusters: 4,
|
maxClusters: 4,
|
||||||
/** The first shard ID to start spawning. */
|
/** The first shard Id to start spawning. */
|
||||||
firstShardID: 0,
|
firstShardId: 0,
|
||||||
/** The last shard ID for this cluster. */
|
/** The last shard Id for this cluster. */
|
||||||
lastShardID: 1,
|
lastShardId: 1,
|
||||||
/** This prop decides whether Discord allows our next shard to be started. When 1 starts, this is set to false until it is ready for the next one. */
|
/** This prop decides whether Discord allows our next shard to be started. When 1 starts, this is set to false until it is ready for the next one. */
|
||||||
createNextShard: true,
|
createNextShard: true,
|
||||||
/** The identify payload holds the necessary data to connect and stay connected with Discords WSS. */
|
/** The identify payload holds the necessary data to connect and stay connected with Discords WSS. */
|
||||||
@@ -141,7 +141,7 @@ export const ws = {
|
|||||||
loadingShards: new Collection<
|
loadingShards: new Collection<
|
||||||
number,
|
number,
|
||||||
{
|
{
|
||||||
shardID: number;
|
shardId: number;
|
||||||
resolve: (value: unknown) => void;
|
resolve: (value: unknown) => void;
|
||||||
reject: (reason?: unknown) => void;
|
reject: (reason?: unknown) => void;
|
||||||
startedAt: number;
|
startedAt: number;
|
||||||
@@ -181,7 +181,7 @@ export interface DiscordenoShard {
|
|||||||
/** The amount of milliseconds to wait between heartbeats */
|
/** The amount of milliseconds to wait between heartbeats */
|
||||||
resumeInterval: number;
|
resumeInterval: number;
|
||||||
/** The session id important for resuming connections. */
|
/** The session id important for resuming connections. */
|
||||||
sessionID: string;
|
sessionId: string;
|
||||||
/** The previous sequence number, important for resuming connections. */
|
/** The previous sequence number, important for resuming connections. */
|
||||||
previousSequenceNumber: number | null;
|
previousSequenceNumber: number | null;
|
||||||
/** Whether the shard is currently resuming. */
|
/** Whether the shard is currently resuming. */
|
||||||
@@ -198,7 +198,7 @@ export interface DiscordenoShard {
|
|||||||
/** The interval between heartbeats requested by discord. */
|
/** The interval between heartbeats requested by discord. */
|
||||||
interval: number;
|
interval: number;
|
||||||
/** The id of the interval, useful for stopping the interval if ws closed. */
|
/** The id of the interval, useful for stopping the interval if ws closed. */
|
||||||
intervalID: number;
|
intervalId: number;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export async function cleanupLoadingShards() {
|
|||||||
if (now < loadingShard.startedAt + 60000) return;
|
if (now < loadingShard.startedAt + 60000) return;
|
||||||
|
|
||||||
loadingShard.reject(
|
loadingShard.reject(
|
||||||
`[Identify Failure] Shard ${loadingShard.shardID} has not received READY event in over a minute.`,
|
`[Identify Failure] Shard ${loadingShard.shardId} has not received READY event in over a minute.`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -3,18 +3,18 @@ import { resume } from "./resume.ts";
|
|||||||
import { ws } from "./ws.ts";
|
import { ws } from "./ws.ts";
|
||||||
|
|
||||||
// deno-lint-ignore require-await
|
// deno-lint-ignore require-await
|
||||||
export async function createShard(shardID: number) {
|
export async function createShard(shardId: number) {
|
||||||
const socket = new WebSocket(ws.botGatewayData.url);
|
const socket = new WebSocket(ws.botGatewayData.url);
|
||||||
socket.binaryType = "arraybuffer";
|
socket.binaryType = "arraybuffer";
|
||||||
|
|
||||||
socket.onerror = (errorEvent) => {
|
socket.onerror = (errorEvent) => {
|
||||||
ws.log("ERROR", { shardID, error: errorEvent });
|
ws.log("ERROR", { shardId, error: errorEvent });
|
||||||
};
|
};
|
||||||
|
|
||||||
socket.onmessage = ({ data: message }) => handleOnMessage(message, shardID);
|
socket.onmessage = ({ data: message }) => handleOnMessage(message, shardId);
|
||||||
|
|
||||||
socket.onclose = (event) => {
|
socket.onclose = (event) => {
|
||||||
ws.log("CLOSED", { shardID, payload: event });
|
ws.log("CLOSED", { shardId, payload: event });
|
||||||
|
|
||||||
// TODO: ENUM FOR THESE CODES?
|
// TODO: ENUM FOR THESE CODES?
|
||||||
switch (event.code) {
|
switch (event.code) {
|
||||||
@@ -35,11 +35,11 @@ export async function createShard(shardID: number) {
|
|||||||
case 4007:
|
case 4007:
|
||||||
case 4008:
|
case 4008:
|
||||||
case 4009:
|
case 4009:
|
||||||
ws.log("CLOSED_RECONNECT", { shardID, payload: event });
|
ws.log("CLOSED_RECONNECT", { shardId, payload: event });
|
||||||
identify(shardID, ws.maxShards);
|
identify(shardId, ws.maxShards);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
resume(shardID);
|
resume(shardId);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+12
-12
@@ -3,44 +3,44 @@ import { DiscordenoShard } from "./ws.ts";
|
|||||||
/** The handler for logging different actions happening inside the ws. User can override and put custom handling per event. */
|
/** The handler for logging different actions happening inside the ws. User can override and put custom handling per event. */
|
||||||
export function log(
|
export function log(
|
||||||
type: "CLOSED",
|
type: "CLOSED",
|
||||||
data: { shardID: number; payload: CloseEvent },
|
data: { shardId: number; payload: CloseEvent },
|
||||||
): unknown;
|
): unknown;
|
||||||
export function log(
|
export function log(
|
||||||
type: "CLOSED_RECONNECT",
|
type: "CLOSED_RECONNECT",
|
||||||
data: { shardID: number; payload: CloseEvent },
|
data: { shardId: number; payload: CloseEvent },
|
||||||
): unknown;
|
): unknown;
|
||||||
export function log(
|
export function log(
|
||||||
type: "ERROR",
|
type: "ERROR",
|
||||||
data: Record<string, unknown> & { shardID: number },
|
data: Record<string, unknown> & { shardId: number },
|
||||||
): unknown;
|
): unknown;
|
||||||
export function log(
|
export function log(
|
||||||
type: "HEARTBEATING",
|
type: "HEARTBEATING",
|
||||||
data: { shardID: number; shard: DiscordenoShard },
|
data: { shardId: number; shard: DiscordenoShard },
|
||||||
): unknown;
|
): unknown;
|
||||||
export function log(
|
export function log(
|
||||||
type: "HEARTBEATING_CLOSED",
|
type: "HEARTBEATING_CLOSED",
|
||||||
data: { shardID: number; shard: DiscordenoShard },
|
data: { shardId: number; shard: DiscordenoShard },
|
||||||
): unknown;
|
): unknown;
|
||||||
export function log(
|
export function log(
|
||||||
type: "HEARTBEATING_DETAILS",
|
type: "HEARTBEATING_DETAILS",
|
||||||
data: { shardID: number; interval: number; shard: DiscordenoShard },
|
data: { shardId: number; interval: number; shard: DiscordenoShard },
|
||||||
): unknown;
|
): unknown;
|
||||||
export function log(
|
export function log(
|
||||||
type: "HEARTBEATING_STARTED",
|
type: "HEARTBEATING_STARTED",
|
||||||
data: { shardID: number; interval: number },
|
data: { shardId: number; interval: number },
|
||||||
): unknown;
|
): unknown;
|
||||||
export function log(
|
export function log(
|
||||||
type: "IDENTIFYING",
|
type: "IDENTIFYING",
|
||||||
data: { shardID: number; maxShards: number },
|
data: { shardId: number; maxShards: number },
|
||||||
): unknown;
|
): unknown;
|
||||||
export function log(
|
export function log(
|
||||||
type: "INVALID_SESSION",
|
type: "INVALID_SESSION",
|
||||||
data: { shardID: number; payload: DiscordPayload },
|
data: { shardId: number; payload: DiscordPayload },
|
||||||
): unknown;
|
): unknown;
|
||||||
export function log(type: "RAW", data: Record<string, unknown>): unknown;
|
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(
|
export function log(
|
||||||
type:
|
type:
|
||||||
| "CLOSED"
|
| "CLOSED"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { ws } from "./ws.ts";
|
|||||||
/** Handler for processing all dispatch payloads that should be sent/forwarded to another server/vps/process. */
|
/** Handler for processing all dispatch payloads that should be sent/forwarded to another server/vps/process. */
|
||||||
export async function handleDiscordPayload(
|
export async function handleDiscordPayload(
|
||||||
data: DiscordPayload,
|
data: DiscordPayload,
|
||||||
shardID: number,
|
shardId: number,
|
||||||
) {
|
) {
|
||||||
await fetch(ws.url, {
|
await fetch(ws.url, {
|
||||||
headers: {
|
headers: {
|
||||||
@@ -11,7 +11,7 @@ export async function handleDiscordPayload(
|
|||||||
},
|
},
|
||||||
method: "post",
|
method: "post",
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
shardID,
|
shardId,
|
||||||
data,
|
data,
|
||||||
}),
|
}),
|
||||||
}).catch(console.error);
|
}).catch(console.error);
|
||||||
|
|||||||
+25
-25
@@ -1,13 +1,13 @@
|
|||||||
|
import { DiscordGatewayOpcodes } from "../types/codes/gateway_opcodes.ts";
|
||||||
|
import { DiscordReady } from "../types/gateway/ready.ts";
|
||||||
|
import { decompressWith } from "./deps.ts";
|
||||||
import { identify } from "./identify.ts";
|
import { identify } from "./identify.ts";
|
||||||
import { resume } from "./resume.ts";
|
import { resume } from "./resume.ts";
|
||||||
import { ws } from "./ws.ts";
|
import { ws } from "./ws.ts";
|
||||||
import { decompressWith } from "./deps.ts";
|
|
||||||
import { DiscordGatewayOpcodes } from "../types/codes/gateway_opcodes.ts";
|
|
||||||
import { DiscordReady } from "../types/gateway/ready.ts";
|
|
||||||
|
|
||||||
/** Handler for handling every message event from websocket. */
|
/** Handler for handling every message event from websocket. */
|
||||||
// deno-lint-ignore no-explicit-any
|
// deno-lint-ignore no-explicit-any
|
||||||
export function handleOnMessage(message: any, shardID: number) {
|
export function handleOnMessage(message: any, shardId: number) {
|
||||||
if (message instanceof ArrayBuffer) {
|
if (message instanceof ArrayBuffer) {
|
||||||
message = new Uint8Array(message);
|
message = new Uint8Array(message);
|
||||||
}
|
}
|
||||||
@@ -28,69 +28,69 @@ export function handleOnMessage(message: any, shardID: number) {
|
|||||||
switch (messageData.op) {
|
switch (messageData.op) {
|
||||||
case DiscordGatewayOpcodes.Hello:
|
case DiscordGatewayOpcodes.Hello:
|
||||||
ws.heartbeat(
|
ws.heartbeat(
|
||||||
shardID,
|
shardId,
|
||||||
(messageData.d as DiscordHeartbeat).heartbeat_interval,
|
(messageData.d as DiscordHeartbeat).heartbeat_interval,
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case DiscordGatewayOpcodes.HeartbeatACK:
|
case DiscordGatewayOpcodes.HeartbeatACK:
|
||||||
if (ws.shards.has(shardID)) {
|
if (ws.shards.has(shardId)) {
|
||||||
ws.shards.get(shardID)!.heartbeat.acknowledged = true;
|
ws.shards.get(shardId)!.heartbeat.acknowledged = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DiscordGatewayOpcodes.Reconnect:
|
case DiscordGatewayOpcodes.Reconnect:
|
||||||
ws.log("RECONNECT", { shardID });
|
ws.log("RECONNECT", { shardId });
|
||||||
|
|
||||||
if (ws.shards.has(shardID)) {
|
if (ws.shards.has(shardId)) {
|
||||||
ws.shards.get(shardID)!.resuming = true;
|
ws.shards.get(shardId)!.resuming = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
resume(shardID);
|
resume(shardId);
|
||||||
break;
|
break;
|
||||||
case DiscordGatewayOpcodes.InvalidSession:
|
case DiscordGatewayOpcodes.InvalidSession:
|
||||||
ws.log("INVALID_SESSION", { shardID, payload: messageData });
|
ws.log("INVALID_SESSION", { shardId, payload: messageData });
|
||||||
|
|
||||||
// When d is false we need to reidentify
|
// When d is false we need to reidentify
|
||||||
if (!messageData.d) {
|
if (!messageData.d) {
|
||||||
identify(shardID, ws.maxShards);
|
identify(shardId, ws.maxShards);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ws.shards.has(shardID)) {
|
if (ws.shards.has(shardId)) {
|
||||||
ws.shards.get(shardID)!.resuming = true;
|
ws.shards.get(shardId)!.resuming = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
resume(shardID);
|
resume(shardId);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (messageData.t === "RESUMED") {
|
if (messageData.t === "RESUMED") {
|
||||||
ws.log("RESUMED", { shardID });
|
ws.log("RESUMED", { shardId });
|
||||||
|
|
||||||
if (ws.shards.has(shardID)) {
|
if (ws.shards.has(shardId)) {
|
||||||
ws.shards.get(shardID)!.resuming = false;
|
ws.shards.get(shardId)!.resuming = false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Important for RESUME
|
// Important for RESUME
|
||||||
if (messageData.t === "READY") {
|
if (messageData.t === "READY") {
|
||||||
const shard = ws.shards.get(shardID);
|
const shard = ws.shards.get(shardId);
|
||||||
if (shard) {
|
if (shard) {
|
||||||
shard.sessionID = (messageData.d as DiscordReady).session_id;
|
shard.sessionId = (messageData.d as DiscordReady).session_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
ws.loadingShards.get(shardID)?.resolve(true);
|
ws.loadingShards.get(shardId)?.resolve(true);
|
||||||
ws.loadingShards.delete(shardID);
|
ws.loadingShards.delete(shardId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the sequence number if it is present
|
// Update the sequence number if it is present
|
||||||
if (messageData.s) {
|
if (messageData.s) {
|
||||||
const shard = ws.shards.get(shardID);
|
const shard = ws.shards.get(shardId);
|
||||||
if (shard) {
|
if (shard) {
|
||||||
shard.previousSequenceNumber = messageData.s;
|
shard.previousSequenceNumber = messageData.s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ws.handleDiscordPayload(messageData, shardID);
|
ws.handleDiscordPayload(messageData, shardId);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-10
@@ -1,33 +1,33 @@
|
|||||||
import { ws } from "./ws.ts";
|
|
||||||
import { DiscordGatewayOpcodes } from "../types/codes/gateway_opcodes.ts";
|
import { DiscordGatewayOpcodes } from "../types/codes/gateway_opcodes.ts";
|
||||||
|
import { ws } from "./ws.ts";
|
||||||
|
|
||||||
export function heartbeat(shardID: number, interval: number) {
|
export function heartbeat(shardId: number, interval: number) {
|
||||||
ws.log("HEARTBEATING_STARTED", { shardID, interval });
|
ws.log("HEARTBEATING_STARTED", { shardId, interval });
|
||||||
|
|
||||||
const shard = ws.shards.get(shardID);
|
const shard = ws.shards.get(shardId);
|
||||||
if (!shard) return;
|
if (!shard) return;
|
||||||
|
|
||||||
ws.log("HEARTBEATING_DETAILS", { shardID, interval, shard });
|
ws.log("HEARTBEATING_DETAILS", { shardId, interval, shard });
|
||||||
|
|
||||||
shard.heartbeat.keepAlive = true;
|
shard.heartbeat.keepAlive = true;
|
||||||
shard.heartbeat.acknowledged = false;
|
shard.heartbeat.acknowledged = false;
|
||||||
shard.heartbeat.lastSentAt = Date.now();
|
shard.heartbeat.lastSentAt = Date.now();
|
||||||
shard.heartbeat.interval = interval;
|
shard.heartbeat.interval = interval;
|
||||||
|
|
||||||
shard.heartbeat.intervalID = setInterval(() => {
|
shard.heartbeat.intervalId = setInterval(() => {
|
||||||
const currentShard = ws.shards.get(shardID);
|
const currentShard = ws.shards.get(shardId);
|
||||||
if (!currentShard) return;
|
if (!currentShard) return;
|
||||||
|
|
||||||
ws.log("HEARTBEATING", { shardID, shard: currentShard });
|
ws.log("HEARTBEATING", { shardId, shard: currentShard });
|
||||||
|
|
||||||
if (
|
if (
|
||||||
currentShard.ws.readyState === WebSocket.CLOSED ||
|
currentShard.ws.readyState === WebSocket.CLOSED ||
|
||||||
!currentShard.heartbeat.keepAlive
|
!currentShard.heartbeat.keepAlive
|
||||||
) {
|
) {
|
||||||
ws.log("HEARTBEATING_CLOSED", { shardID, shard: currentShard });
|
ws.log("HEARTBEATING_CLOSED", { shardId, shard: currentShard });
|
||||||
|
|
||||||
// STOP THE HEARTBEAT
|
// STOP THE HEARTBEAT
|
||||||
return clearInterval(currentShard.heartbeat.intervalID);
|
return clearInterval(currentShard.heartbeat.intervalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
currentShard.ws.send(
|
currentShard.ws.send(
|
||||||
|
|||||||
+10
-10
@@ -1,18 +1,18 @@
|
|||||||
import { DiscordGatewayOpcodes } from "../types/codes/gateway_opcodes.ts";
|
import { DiscordGatewayOpcodes } from "../types/codes/gateway_opcodes.ts";
|
||||||
import { ws } from "./ws.ts";
|
import { ws } from "./ws.ts";
|
||||||
|
|
||||||
export async function identify(shardID: number, maxShards: number) {
|
export async function identify(shardId: number, maxShards: number) {
|
||||||
ws.log("IDENTIFYING", { shardID, maxShards });
|
ws.log("IDENTIFYING", { shardId, maxShards });
|
||||||
|
|
||||||
// CREATE A SHARD
|
// CREATE A SHARD
|
||||||
const socket = await ws.createShard(shardID);
|
const socket = await ws.createShard(shardId);
|
||||||
|
|
||||||
// Identify can just set/reset the settings for the shard
|
// Identify can just set/reset the settings for the shard
|
||||||
ws.shards.set(shardID, {
|
ws.shards.set(shardId, {
|
||||||
id: shardID,
|
id: shardId,
|
||||||
ws: socket,
|
ws: socket,
|
||||||
resumeInterval: 0,
|
resumeInterval: 0,
|
||||||
sessionID: "",
|
sessionId: "",
|
||||||
previousSequenceNumber: 0,
|
previousSequenceNumber: 0,
|
||||||
resuming: false,
|
resuming: false,
|
||||||
heartbeat: {
|
heartbeat: {
|
||||||
@@ -21,7 +21,7 @@ export async function identify(shardID: number, maxShards: number) {
|
|||||||
acknowledged: false,
|
acknowledged: false,
|
||||||
keepAlive: false,
|
keepAlive: false,
|
||||||
interval: 0,
|
interval: 0,
|
||||||
intervalID: 0,
|
intervalId: 0,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -29,14 +29,14 @@ export async function identify(shardID: number, maxShards: number) {
|
|||||||
socket.send(
|
socket.send(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
op: DiscordGatewayOpcodes.Identify,
|
op: DiscordGatewayOpcodes.Identify,
|
||||||
d: { ...ws.identifyPayload, shard: [shardID, maxShards] },
|
d: { ...ws.identifyPayload, shard: [shardId, maxShards] },
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
ws.loadingShards.set(shardID, {
|
ws.loadingShards.set(shardId, {
|
||||||
shardID,
|
shardId,
|
||||||
resolve,
|
resolve,
|
||||||
reject,
|
reject,
|
||||||
startedAt: Date.now(),
|
startedAt: Date.now(),
|
||||||
|
|||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
import { ws } from "./ws.ts";
|
|
||||||
import { getGatewayBot } from "../helpers/misc/get_gateway_bot.ts";
|
import { getGatewayBot } from "../helpers/misc/get_gateway_bot.ts";
|
||||||
|
import { ws } from "./ws.ts";
|
||||||
|
|
||||||
/** The handler to automatically reshard when necessary. */
|
/** The handler to automatically reshard when necessary. */
|
||||||
export async function resharder() {
|
export async function resharder() {
|
||||||
@@ -26,5 +26,5 @@ export async function resharder() {
|
|||||||
ws.botGatewayData.shards = data.shards;
|
ws.botGatewayData.shards = data.shards;
|
||||||
ws.botGatewayData.url = data.url;
|
ws.botGatewayData.url = data.url;
|
||||||
|
|
||||||
ws.spawnShards(ws.firstShardID);
|
ws.spawnShards(ws.firstShardId);
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-11
@@ -1,31 +1,31 @@
|
|||||||
import { DiscordGatewayOpcodes } from "../types/codes/gateway_opcodes.ts";
|
import { DiscordGatewayOpcodes } from "../types/codes/gateway_opcodes.ts";
|
||||||
import { ws } from "./ws.ts";
|
import { ws } from "./ws.ts";
|
||||||
|
|
||||||
export async function resume(shardID: number) {
|
export async function resume(shardId: number) {
|
||||||
ws.log("RESUMING", { shardID });
|
ws.log("RESUMING", { shardId });
|
||||||
|
|
||||||
// CREATE A SHARD
|
// CREATE A SHARD
|
||||||
const socket = await ws.createShard(shardID);
|
const socket = await ws.createShard(shardId);
|
||||||
|
|
||||||
// NOW WE HANDLE RESUMING THIS SHARD
|
// NOW WE HANDLE RESUMING THIS SHARD
|
||||||
// Get the old data for this shard necessary for resuming
|
// Get the old data for this shard necessary for resuming
|
||||||
const oldShard = ws.shards.get(shardID);
|
const oldShard = ws.shards.get(shardId);
|
||||||
|
|
||||||
if (oldShard) {
|
if (oldShard) {
|
||||||
// HOW TO CLOSE OLD SHARD SOCKET!!!
|
// HOW TO CLOSE OLD SHARD SOCKET!!!
|
||||||
oldShard.ws.close(4009, "Resuming the shard, closing old shard.");
|
oldShard.ws.close(4009, "Resuming the shard, closing old shard.");
|
||||||
// STOP OLD HEARTBEAT
|
// STOP OLD HEARTBEAT
|
||||||
clearInterval(oldShard.heartbeat.intervalID);
|
clearInterval(oldShard.heartbeat.intervalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
const sessionID = oldShard?.sessionID || "";
|
const sessionId = oldShard?.sessionId || "";
|
||||||
const previousSequenceNumber = oldShard?.previousSequenceNumber || 0;
|
const previousSequenceNumber = oldShard?.previousSequenceNumber || 0;
|
||||||
|
|
||||||
ws.shards.set(shardID, {
|
ws.shards.set(shardId, {
|
||||||
id: shardID,
|
id: shardId,
|
||||||
ws: socket,
|
ws: socket,
|
||||||
resumeInterval: 0,
|
resumeInterval: 0,
|
||||||
sessionID,
|
sessionId,
|
||||||
previousSequenceNumber,
|
previousSequenceNumber,
|
||||||
resuming: false,
|
resuming: false,
|
||||||
heartbeat: {
|
heartbeat: {
|
||||||
@@ -34,7 +34,7 @@ export async function resume(shardID: number) {
|
|||||||
acknowledged: false,
|
acknowledged: false,
|
||||||
keepAlive: false,
|
keepAlive: false,
|
||||||
interval: 0,
|
interval: 0,
|
||||||
intervalID: 0,
|
intervalId: 0,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ export async function resume(shardID: number) {
|
|||||||
op: DiscordGatewayOpcodes.Resume,
|
op: DiscordGatewayOpcodes.Resume,
|
||||||
d: {
|
d: {
|
||||||
token: ws.identifyPayload.token,
|
token: ws.identifyPayload.token,
|
||||||
session_id: sessionID,
|
session_id: sessionId,
|
||||||
seq: previousSequenceNumber,
|
seq: previousSequenceNumber,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|||||||
+12
-12
@@ -2,25 +2,25 @@ import { Collection } from "../util/collection.ts";
|
|||||||
import { ws } from "./ws.ts";
|
import { ws } from "./ws.ts";
|
||||||
|
|
||||||
/** Begin spawning shards. */
|
/** Begin spawning shards. */
|
||||||
export function spawnShards(firstShardID = 0) {
|
export function spawnShards(firstShardId = 0) {
|
||||||
/** Stored as bucketID: [clusterID, [ShardIDs]] */
|
/** Stored as bucketId: [clusterId, [ShardIds]] */
|
||||||
const buckets = new Collection<number, number[][]>();
|
const buckets = new Collection<number, number[][]>();
|
||||||
const maxShards = ws.maxShards || ws.botGatewayData.shards;
|
const maxShards = ws.maxShards || ws.botGatewayData.shards;
|
||||||
let cluster = 0;
|
let cluster = 0;
|
||||||
|
|
||||||
for (
|
for (
|
||||||
let index = firstShardID;
|
let index = firstShardId;
|
||||||
index < ws.botGatewayData.sessionStartLimit.maxConcurrency;
|
index < ws.botGatewayData.sessionStartLimit.maxConcurrency;
|
||||||
index++
|
index++
|
||||||
) {
|
) {
|
||||||
// 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++) {
|
||||||
const bucketID = i % ws.botGatewayData.sessionStartLimit.maxConcurrency;
|
const bucketId = i % ws.botGatewayData.sessionStartLimit.maxConcurrency;
|
||||||
const bucket = buckets.get(bucketID);
|
const bucket = buckets.get(bucketId);
|
||||||
|
|
||||||
if (!bucket) {
|
if (!bucket) {
|
||||||
// Create the bucket since it doesnt exist
|
// Create the bucket since it doesnt exist
|
||||||
buckets.set(bucketID, [[cluster, i]]);
|
buckets.set(bucketId, [[cluster, i]]);
|
||||||
|
|
||||||
if (cluster + 1 <= ws.maxClusters) cluster++;
|
if (cluster + 1 <= ws.maxClusters) cluster++;
|
||||||
} else {
|
} else {
|
||||||
@@ -39,13 +39,13 @@ 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) => {
|
||||||
for (const [clusterID, ...queue] of bucket) {
|
for (const [clusterId, ...queue] of bucket) {
|
||||||
let shardID = queue.shift();
|
let shardId = queue.shift();
|
||||||
|
|
||||||
while (shardID !== undefined) {
|
while (shardId !== undefined) {
|
||||||
await ws.tellClusterToIdentify(clusterID as number, shardID, bucketID);
|
await ws.tellClusterToIdentify(clusterId as number, shardId, bucketId);
|
||||||
shardID = queue.shift();
|
shardId = queue.shift();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { StartGatewayOptions } from "./start_gateway_options.ts";
|
|
||||||
import { DiscordGatewayIntents } from "../types/gateway/gateway_intents.ts";
|
import { DiscordGatewayIntents } from "../types/gateway/gateway_intents.ts";
|
||||||
|
import { StartGatewayOptions } from "./start_gateway_options.ts";
|
||||||
import { ws } from "./ws.ts";
|
import { ws } from "./ws.ts";
|
||||||
|
|
||||||
/** ADVANCED DEVS ONLY!!!!!!
|
/** ADVANCED DEVS ONLY!!!!!!
|
||||||
@@ -9,7 +9,7 @@ import { ws } from "./ws.ts";
|
|||||||
export async function startGateway(options: StartGatewayOptions) {
|
export async function startGateway(options: StartGatewayOptions) {
|
||||||
ws.identifyPayload.token = `Bot ${options.token}`;
|
ws.identifyPayload.token = `Bot ${options.token}`;
|
||||||
ws.secretKey = options.secretKey;
|
ws.secretKey = options.secretKey;
|
||||||
ws.firstShardID = options.firstShardID;
|
ws.firstShardId = options.firstShardId;
|
||||||
ws.url = options.url;
|
ws.url = options.url;
|
||||||
if (options.shardsPerCluster) ws.shardsPerCluster = options.shardsPerCluster;
|
if (options.shardsPerCluster) ws.shardsPerCluster = options.shardsPerCluster;
|
||||||
if (options.maxClusters) ws.maxClusters = options.maxClusters;
|
if (options.maxClusters) ws.maxClusters = options.maxClusters;
|
||||||
@@ -36,7 +36,7 @@ export async function startGateway(options: StartGatewayOptions) {
|
|||||||
}).then((res) => res.json())) as DiscordBotGatewayData;
|
}).then((res) => res.json())) as DiscordBotGatewayData;
|
||||||
|
|
||||||
ws.maxShards = options.maxShards || data.shards;
|
ws.maxShards = options.maxShards || data.shards;
|
||||||
ws.lastShardID = options.lastShardID || data.shards - 1;
|
ws.lastShardId = options.lastShardId || data.shards - 1;
|
||||||
|
|
||||||
// TODO: ALL THE FOLLOWING CAN BE REPLACED BY THIS 1 LINE
|
// TODO: ALL THE FOLLOWING CAN BE REPLACED BY THIS 1 LINE
|
||||||
// ws.botGatewayData = snakeToCamel(await getGatewayBot())
|
// ws.botGatewayData = snakeToCamel(await getGatewayBot())
|
||||||
@@ -50,6 +50,6 @@ export async function startGateway(options: StartGatewayOptions) {
|
|||||||
ws.botGatewayData.shards = data.shards;
|
ws.botGatewayData.shards = data.shards;
|
||||||
ws.botGatewayData.url = data.url;
|
ws.botGatewayData.url = data.url;
|
||||||
|
|
||||||
ws.spawnShards(ws.firstShardID);
|
ws.spawnShards(ws.firstShardId);
|
||||||
ws.cleanupLoadingShards();
|
ws.cleanupLoadingShards();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,10 +9,10 @@ export interface StartGatewayOptions {
|
|||||||
intents: (DiscordGatewayIntents | keyof typeof DiscordGatewayIntents)[];
|
intents: (DiscordGatewayIntents | keyof typeof DiscordGatewayIntents)[];
|
||||||
/** The max amount of shards used for identifying. This can be useful for zero-downtime updates or resharding. */
|
/** The max amount of shards used for identifying. This can be useful for zero-downtime updates or resharding. */
|
||||||
maxShards?: number;
|
maxShards?: number;
|
||||||
/** The first shard ID for this group of shards. */
|
/** The first shard Id for this group of shards. */
|
||||||
firstShardID: number;
|
firstShardId: number;
|
||||||
/** The last shard ID for this group. If none is provided, it will default to loading all shards. */
|
/** The last shard Id for this group. If none is provided, it will default to loading all shards. */
|
||||||
lastShardID?: number;
|
lastShardId?: number;
|
||||||
/** The url to forward all payloads to. */
|
/** The url to forward all payloads to. */
|
||||||
url: string;
|
url: string;
|
||||||
/** The amount of shards per cluster. By default this is 25. Use this to spread the load from shards to different CPU cores. */
|
/** The amount of shards per cluster. By default this is 25. Use this to spread the load from shards to different CPU cores. */
|
||||||
|
|||||||
@@ -2,15 +2,15 @@ import { ws } from "./ws.ts";
|
|||||||
|
|
||||||
/** Allows users to hook in and change to communicate to different clusters across different servers or anything they like. For example using redis pubsub to talk to other servers. */
|
/** Allows users to hook in and change to communicate to different clusters across different servers or anything they like. For example using redis pubsub to talk to other servers. */
|
||||||
export async function tellClusterToIdentify(
|
export async function tellClusterToIdentify(
|
||||||
workerID: number,
|
workerId: number,
|
||||||
shardID: number,
|
shardId: number,
|
||||||
bucketID: number,
|
bucketId: number,
|
||||||
) {
|
) {
|
||||||
// When resharding this may exist already
|
// When resharding this may exist already
|
||||||
const oldShard = ws.shards.get(shardID);
|
const oldShard = ws.shards.get(shardId);
|
||||||
|
|
||||||
// TODO: Use workers
|
// TODO: Use workers
|
||||||
await ws.identify(shardID, ws.maxShards);
|
await ws.identify(shardId, ws.maxShards);
|
||||||
|
|
||||||
if (oldShard) {
|
if (oldShard) {
|
||||||
oldShard.ws.close(4009, "Resharded!");
|
oldShard.ws.close(4009, "Resharded!");
|
||||||
|
|||||||
+17
-17
@@ -1,15 +1,15 @@
|
|||||||
import { Collection } from "../util/collection.ts";
|
import { Collection } from "../util/collection.ts";
|
||||||
import { log } from "./events.ts";
|
|
||||||
import { resharder } from "./resharder.ts";
|
|
||||||
import { startGateway } from "./start_gateway.ts";
|
|
||||||
import { spawnShards } from "./spawn_shards.ts";
|
|
||||||
import { createShard } from "./create_shard.ts";
|
|
||||||
import { identify } from "./identify.ts";
|
|
||||||
import { heartbeat } from "./heartbeat.ts";
|
|
||||||
import { handleDiscordPayload } from "./handle_discord_payload.ts";
|
|
||||||
import { tellClusterToIdentify } from "./tell_cluster_to_identify.ts";
|
|
||||||
import { cleanupLoadingShards } from "./cleanup_loading_shards.ts";
|
import { cleanupLoadingShards } from "./cleanup_loading_shards.ts";
|
||||||
|
import { createShard } from "./create_shard.ts";
|
||||||
|
import { log } from "./events.ts";
|
||||||
|
import { handleDiscordPayload } from "./handle_discord_payload.ts";
|
||||||
import { handleOnMessage } from "./handle_on_message.ts";
|
import { handleOnMessage } from "./handle_on_message.ts";
|
||||||
|
import { heartbeat } from "./heartbeat.ts";
|
||||||
|
import { identify } from "./identify.ts";
|
||||||
|
import { resharder } from "./resharder.ts";
|
||||||
|
import { spawnShards } from "./spawn_shards.ts";
|
||||||
|
import { startGateway } from "./start_gateway.ts";
|
||||||
|
import { tellClusterToIdentify } from "./tell_cluster_to_identify.ts";
|
||||||
|
|
||||||
// CONTROLLER LIKE INTERFACE FOR WS HANDLING
|
// CONTROLLER LIKE INTERFACE FOR WS HANDLING
|
||||||
export const ws = {
|
export const ws = {
|
||||||
@@ -21,16 +21,16 @@ export const ws = {
|
|||||||
reshard: true,
|
reshard: true,
|
||||||
/** The percentage at which resharding should occur. */
|
/** The percentage at which resharding should occur. */
|
||||||
reshardPercentage: 80,
|
reshardPercentage: 80,
|
||||||
/** The maximum shard ID number. Useful for zero-downtime updates or resharding. */
|
/** The maximum shard Id number. Useful for zero-downtime updates or resharding. */
|
||||||
maxShards: 1,
|
maxShards: 1,
|
||||||
/** The amount of shards to load per cluster */
|
/** The amount of shards to load per cluster */
|
||||||
shardsPerCluster: 25,
|
shardsPerCluster: 25,
|
||||||
/** The maximum amount of clusters to use for your bot. */
|
/** The maximum amount of clusters to use for your bot. */
|
||||||
maxClusters: 4,
|
maxClusters: 4,
|
||||||
/** The first shard ID to start spawning. */
|
/** The first shard Id to start spawning. */
|
||||||
firstShardID: 0,
|
firstShardId: 0,
|
||||||
/** The last shard ID for this cluster. */
|
/** The last shard Id for this cluster. */
|
||||||
lastShardID: 1,
|
lastShardId: 1,
|
||||||
/** This prop decides whether Discord allows our next shard to be started. When 1 starts, this is set to false until it is ready for the next one. */
|
/** This prop decides whether Discord allows our next shard to be started. When 1 starts, this is set to false until it is ready for the next one. */
|
||||||
createNextShard: true,
|
createNextShard: true,
|
||||||
/** The identify payload holds the necessary data to connect and stay connected with Discords WSS. */
|
/** The identify payload holds the necessary data to connect and stay connected with Discords WSS. */
|
||||||
@@ -69,7 +69,7 @@ export const ws = {
|
|||||||
loadingShards: new Collection<
|
loadingShards: new Collection<
|
||||||
number,
|
number,
|
||||||
{
|
{
|
||||||
shardID: number;
|
shardId: number;
|
||||||
resolve: (value: unknown) => void;
|
resolve: (value: unknown) => void;
|
||||||
reject: (reason?: unknown) => void;
|
reject: (reason?: unknown) => void;
|
||||||
startedAt: number;
|
startedAt: number;
|
||||||
@@ -111,7 +111,7 @@ export interface DiscordenoShard {
|
|||||||
/** The amount of milliseconds to wait between heartbeats */
|
/** The amount of milliseconds to wait between heartbeats */
|
||||||
resumeInterval: number;
|
resumeInterval: number;
|
||||||
/** The session id important for resuming connections. */
|
/** The session id important for resuming connections. */
|
||||||
sessionID: string;
|
sessionId: string;
|
||||||
/** The previous sequence number, important for resuming connections. */
|
/** The previous sequence number, important for resuming connections. */
|
||||||
previousSequenceNumber: number | null;
|
previousSequenceNumber: number | null;
|
||||||
/** Whether the shard is currently resuming. */
|
/** Whether the shard is currently resuming. */
|
||||||
@@ -128,6 +128,6 @@ export interface DiscordenoShard {
|
|||||||
/** The interval between heartbeats requested by discord. */
|
/** The interval between heartbeats requested by discord. */
|
||||||
interval: number;
|
interval: number;
|
||||||
/** The id of the interval, useful for stopping the interval if ws closed. */
|
/** The id of the interval, useful for stopping the interval if ws closed. */
|
||||||
intervalID: number;
|
intervalId: number;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user