mirror of
https://github.com/discordeno/discordeno.git
synced 2026-06-04 09:50:07 +00:00
finish transformers and setup gateway stuff
This commit is contained in:
187
src/bot.ts
187
src/bot.ts
@@ -17,6 +17,25 @@ import { Collection } from "./util/collection.ts";
|
||||
import { DiscordenoUser, transformMember, transformUser } from "./transformers/member.ts";
|
||||
import { SnakeCasedPropertiesDeep } from "./types/util.ts";
|
||||
import { Channel } from "./types/channels/channel.ts";
|
||||
import { DiscordenoChannel, transformChannel } from "./transformers/channel.ts";
|
||||
import { transformVoiceState } from "./transformers/voice_state.ts";
|
||||
import { transformRole } from "./transformers/role.ts";
|
||||
import { transformMessage } from "./transformers/message.ts";
|
||||
import { transformGuild } from "./transformers/guild.ts";
|
||||
import { DiscordenoShard } from "./ws/ws.ts";
|
||||
import { startGateway } from "./ws/start_gateway.ts";
|
||||
import { spawnShards } from "./ws/spawn_shards.ts";
|
||||
import { createShard } from "./ws/create_shard.ts";
|
||||
import { identify } from "./ws/identify.ts";
|
||||
import { heartbeat } from "./ws/heartbeat.ts";
|
||||
import { resharder } from "./ws/resharder.ts";
|
||||
import { tellClusterToIdentify } from "./ws/tell_cluster_to_identify.ts";
|
||||
import { handleDiscordPayload } from "./ws/handle_discord_payload.ts";
|
||||
import { log } from "./ws/events.ts";
|
||||
import { handleOnMessage } from "./ws/handle_on_message.ts";
|
||||
import { closeWS } from "./ws/close_ws.ts";
|
||||
import { sendShardMessage } from "./ws/send_shard_message.ts";
|
||||
import { resume } from "./ws/resume.ts";
|
||||
|
||||
export async function createBot(options: CreateBotOptions) {
|
||||
return {
|
||||
@@ -102,17 +121,55 @@ export async function startBot(bot: Bot) {
|
||||
bot.rest = createRestManager({ token: bot.token });
|
||||
|
||||
// START WS
|
||||
bot.gateway = createGatewayManager();
|
||||
|
||||
|
||||
bot.gateway = createGatewayManager({});
|
||||
}
|
||||
|
||||
export interface CreateGatewayManagerOptions {
|
||||
transformers: Partial<Transformers>;
|
||||
}
|
||||
|
||||
export function createGatewayManager(options: CreateGatewayManagerOptions) {
|
||||
export function createGatewayManager(options: Partial<GatewayManager>): GatewayManager {
|
||||
return {
|
||||
secretKey: options.secretKey ?? "",
|
||||
url: options.url ?? "",
|
||||
reshard: options.reshard ?? true,
|
||||
reshardPercentage: options.reshardPercentage ?? 80,
|
||||
spawnShardDelay: options.spawnShardDelay ?? 2600,
|
||||
maxShards: options.maxShards ?? 0,
|
||||
useOptimalLargeBotSharding: options.useOptimalLargeBotSharding ?? true,
|
||||
shardsPerCluster: options.shardsPerCluster ?? 25,
|
||||
maxClusters: options.maxClusters ?? 4,
|
||||
firstShardId: options.firstShardId ?? 0,
|
||||
lastShardId: options.lastShardId ?? 1,
|
||||
token: options.token ?? "",
|
||||
compress: options.compress ?? false,
|
||||
$os: options.$os ?? "linux",
|
||||
$browser: options.$browser ?? "Discordeno",
|
||||
$device: options.$device ?? "Discordeno",
|
||||
intents: options.intents ?? 0,
|
||||
shard: options.shard ?? [0, 0],
|
||||
urlWSS: options.urlWSS ?? "wss://gateway.discord.gg/?v=9&encoding=json",
|
||||
shardsRecommended: options.shardsRecommended ?? 1,
|
||||
sessionStartLimitTotal: options.sessionStartLimitTotal ?? 1000,
|
||||
sessionStartLimitRemaining: options.sessionStartLimitRemaining ?? 1000,
|
||||
sessionStartLimitResetAfter: options.sessionStartLimitResetAfter ?? 0,
|
||||
maxConcurrency: options.maxConcurrency ?? 1,
|
||||
shards: options.shards ?? new Collection(),
|
||||
loadingShards: options.loadingShards ?? new Collection(),
|
||||
buckets: new Collection(),
|
||||
utf8decoder: new TextDecoder(),
|
||||
|
||||
startGateway,
|
||||
spawnShards,
|
||||
createShard,
|
||||
identify,
|
||||
heartbeat,
|
||||
handleDiscordPayload,
|
||||
tellClusterToIdentify,
|
||||
log,
|
||||
resharder,
|
||||
handleOnMessage,
|
||||
processQueue,
|
||||
closeWS,
|
||||
sendShardMessage,
|
||||
resume,
|
||||
};
|
||||
}
|
||||
|
||||
export function stopBot(bot: Bot) {
|
||||
@@ -124,7 +181,7 @@ export interface CreateBotOptions {
|
||||
token: string;
|
||||
botId: bigint;
|
||||
applicationId?: bigint;
|
||||
events: EventHandlers;
|
||||
events: Partial<EventHandlers>;
|
||||
intents: (keyof typeof DiscordGatewayIntents)[];
|
||||
botGatewayData?: GetGatewayBot;
|
||||
rest?: Omit<CreateRestManagerOptions, "token">;
|
||||
@@ -145,22 +202,128 @@ export type Bot = CreatedBot & {
|
||||
|
||||
export interface Transformers {
|
||||
snowflake: typeof snowflakeToBigint;
|
||||
channel: typeof transformChannel;
|
||||
guild: typeof transformGuild;
|
||||
user: typeof transformUser;
|
||||
member: typeof transformMember;
|
||||
channel: typeof transformChannel;
|
||||
message: typeof transformMessage;
|
||||
role: typeof transformRole;
|
||||
voiceState: typeof transformVoiceState;
|
||||
}
|
||||
|
||||
export function createTransformers(options: Partial<Transformers>) {
|
||||
return {
|
||||
snowflake: options.snowflake || snowflakeToBigint,
|
||||
channel: options.channel || transformChannel,
|
||||
guild: options.guild || transformGuild,
|
||||
user: options.user || transformUser,
|
||||
member: options.member || transformMember,
|
||||
message: options.message || transformMessage,
|
||||
role: options.role || transformRole,
|
||||
voiceState: options.voiceState || transformVoiceState,
|
||||
};
|
||||
}
|
||||
|
||||
export type RestManager = ReturnType<typeof createRestManager>;
|
||||
|
||||
export interface GatewayManager {}
|
||||
export interface GatewayManager {
|
||||
/** The secret key authorization header the bot will expect when sending payloads. */
|
||||
secretKey: string;
|
||||
/** The url that all discord payloads for the dispatch type should be sent to. */
|
||||
url: string;
|
||||
/** Whether or not to automatically reshard. */
|
||||
reshard: boolean;
|
||||
/** The percentage at which resharding should occur. */
|
||||
reshardPercentage: number;
|
||||
/** The delay in milliseconds to wait before spawning next shard. OPTIMAL IS ABOVE 2500. YOU DON"T WANT TO HIT THE RATE LIMIT!!! */
|
||||
spawnShardDelay: number;
|
||||
/** The maximum shard Id number. Useful for zero-downtime updates or resharding. */
|
||||
maxShards: number;
|
||||
/** Whether or not the resharder should automatically switch to LARGE BOT SHARDING when you are above 100K servers. */
|
||||
useOptimalLargeBotSharding: boolean;
|
||||
/** The amount of shards to load per cluster. */
|
||||
shardsPerCluster: number;
|
||||
/** The maximum amount of clusters to use for your bot. */
|
||||
maxClusters: number;
|
||||
/** The first shard Id to start spawning. */
|
||||
firstShardId: number;
|
||||
/** The last shard Id for this cluster. */
|
||||
lastShardId: number;
|
||||
token: "";
|
||||
compress: false;
|
||||
$os: "linux";
|
||||
$browser: "Discordeno";
|
||||
$device: "Discordeno";
|
||||
intents: 0;
|
||||
shard: [0, 0];
|
||||
|
||||
/** The WSS URL that can be used for connecting to the gateway. */
|
||||
urlWSS: "wss://gateway.discord.gg/?v=9&encoding=json";
|
||||
/** The recommended number of shards to use when connecting. */
|
||||
shardsRecommended: 1;
|
||||
/** The total number of session starts the current user is allowed. */
|
||||
sessionStartLimitTotal: 1000;
|
||||
/** The remaining number of session starts the current user is allowed. */
|
||||
sessionStartLimitRemaining: 1000;
|
||||
/** Milliseconds left until limit is reset. */
|
||||
sessionStartLimitResetAfter: 0;
|
||||
/** The number of identify requests allowed per 5 seconds.
|
||||
* So, if you had a max concurrency of 16, and 16 shards for example, you could start them all up at the same time.
|
||||
* Whereas if you had 32 shards, if you tried to start up shard 0 and 16 at the same time for example, it would not work. You can start shards 0-15 concurrently, then 16-31...
|
||||
*/
|
||||
maxConcurrency: 1;
|
||||
shards: Collection<number, DiscordenoShard>;
|
||||
loadingShards: Collection<
|
||||
number,
|
||||
{
|
||||
shardId: number;
|
||||
resolve: (value: unknown) => void;
|
||||
startedAt: number;
|
||||
}
|
||||
>;
|
||||
/** Stored as bucketId: { clusters: [clusterId, [ShardIds]], createNextShard: boolean } */
|
||||
buckets: Collection<
|
||||
number,
|
||||
{
|
||||
clusters: number[][];
|
||||
createNextShard: (() => unknown)[];
|
||||
}
|
||||
>;
|
||||
utf8decoder: TextDecoder;
|
||||
|
||||
// METHODS
|
||||
|
||||
/** The handler function that starts the gateway. */
|
||||
startGateway: typeof startGateway;
|
||||
/** The handler for spawning ALL the shards. */
|
||||
spawnShards: typeof spawnShards;
|
||||
/** Create the websocket and adds the proper handlers to the websocket. */
|
||||
createShard: typeof createShard;
|
||||
/** Begins identification of the shard to discord. */
|
||||
identify: typeof identify;
|
||||
/** Begins heartbeating of the shard to keep it alive. */
|
||||
heartbeat: typeof heartbeat;
|
||||
/** Sends the discord payload to another server. */
|
||||
handleDiscordPayload: typeof handleDiscordPayload;
|
||||
/** Tell the cluster/worker to begin identifying this shard */
|
||||
tellClusterToIdentify: typeof tellClusterToIdentify;
|
||||
/** Handle the different logs. Used for debugging. */
|
||||
log: typeof log;
|
||||
/** Handles resharding the bot when necessary. */
|
||||
resharder: typeof resharder;
|
||||
/** Handles the message events from websocket. */
|
||||
handleOnMessage: typeof handleOnMessage;
|
||||
/** Handles processing queue of requests send to this shard. */
|
||||
processQueue: typeof processQueue;
|
||||
/** Closes shard WebSocket connection properly. */
|
||||
closeWS: typeof closeWS;
|
||||
/** Properly adds a message to the shards queue. */
|
||||
sendShardMessage: typeof sendShardMessage;
|
||||
/** Properly resume an old shards session. */
|
||||
resume: typeof resume;
|
||||
}
|
||||
|
||||
export interface EventHandlers {
|
||||
debug: (text: string) => unknown;
|
||||
channelCreate: (bot: Bot, channel: DiscordenoChannel);
|
||||
channelCreate: (bot: Bot, channel: DiscordenoChannel) => unknown;
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
import { eventHandlers, replaceEventHandlers } from "../bot.ts";
|
||||
import type { EventHandlers } from "../types/discordeno/event_handlers.ts";
|
||||
import type { EventEmitter } from "https://deno.land/std@0.97.0/node/events.ts";
|
||||
|
||||
export function proxyEvent(emitter: EventEmitter) {
|
||||
replaceEventHandlers(
|
||||
new Proxy(eventHandlers, {
|
||||
get(target, prop: keyof EventHandlers) {
|
||||
return target[prop] !== undefined ? target[prop] : (...args: unknown[]) => emitter.emit(prop, ...args);
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -1,46 +1,6 @@
|
||||
import { createDiscordenoChannel } from "./channel.ts";
|
||||
import { createDiscordenoGuild } from "./guild.ts";
|
||||
import { createDiscordenoMember } from "./member.ts";
|
||||
import { createDiscordenoMessage } from "./message.ts";
|
||||
import { createDiscordenoRole } from "./role.ts";
|
||||
import { createDiscordenoVoiceState } from "./voice_state.ts";
|
||||
|
||||
import type { DiscordenoChannel } from "./channel.ts";
|
||||
import type { DiscordenoGuild } from "./guild.ts";
|
||||
import type { DiscordenoMember } from "./member.ts";
|
||||
import type { DiscordenoMessage } from "./message.ts";
|
||||
import type { DiscordenoRole } from "./role.ts";
|
||||
import type { DiscordenoVoiceState } from "./voice_state.ts";
|
||||
|
||||
/** This is the placeholder where the structure creation functions are kept. */
|
||||
export let structures = {
|
||||
createDiscordenoChannel,
|
||||
createDiscordenoGuild,
|
||||
createDiscordenoMember,
|
||||
createDiscordenoMessage,
|
||||
createDiscordenoRole,
|
||||
createDiscordenoVoiceState,
|
||||
};
|
||||
|
||||
export type {
|
||||
DiscordenoChannel,
|
||||
DiscordenoGuild,
|
||||
DiscordenoMember,
|
||||
DiscordenoMessage,
|
||||
DiscordenoRole,
|
||||
DiscordenoVoiceState,
|
||||
};
|
||||
|
||||
export type Structures = typeof structures;
|
||||
|
||||
/** This function is used to update/reload/customize the internal structures of Discordeno.
|
||||
*
|
||||
* ⚠️ **ADVANCED USE ONLY: If you customize this incorrectly, you could potentially create many new errors/bugs.
|
||||
* Please take caution when using this.**
|
||||
*/
|
||||
export function updateStructures(newStructures: Structures) {
|
||||
structures = {
|
||||
...structures,
|
||||
...newStructures,
|
||||
};
|
||||
}
|
||||
export * from "./channel.ts";
|
||||
export * from "./guild.ts";
|
||||
export * from "./member.ts";
|
||||
export * from "./message.ts";
|
||||
export * from "./role.ts";
|
||||
export * from "./voice_state.ts";
|
||||
|
||||
Reference in New Issue
Block a user