Skip to content

Commit

Permalink
feat: basic discord.js sharder and client
Browse files Browse the repository at this point in the history
  • Loading branch information
espimarisa committed Feb 14, 2024
1 parent 928233b commit 29ce4e9
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 86 deletions.
1 change: 0 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"svelte.enable-ts-plugin": true,
"typescript.preferences.importModuleSpecifier": "relative",
"javascript.preferences.importModuleSpecifierEnding": "js",
"typescript.preferences.importModuleSpecifierEnding": "js",

"[svelte]": {
"editor.defaultFormatter": "svelte.svelte-vscode"
Expand Down
Binary file modified bun.lockb
Binary file not shown.
3 changes: 1 addition & 2 deletions packages/bot/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
"test": "bun run lint"
},
"dependencies": {
"discord-hybrid-sharding": "^2.1.4",
"oceanic.js": "^1.9.0"
"discord.js": "^14.14.1"
}
}
15 changes: 9 additions & 6 deletions packages/bot/src/classes/Client.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
import env from "$shared/env.ts";
import logger from "$shared/logger.ts";
import { Client, type ClientOptions } from "oceanic.js";
import { Client, type ClientOptions } from "discord.js";

export class HibikiClient extends Client {
constructor(options: ClientOptions) {
super(options);

// Logs errors
this.on("error", (err) => {
throw new Error(Bun.inspect(err));
logger.error(Bun.inspect(err));
});
}

public init() {
try {
this.connect().catch((error) => {
logger.error("An error occured while connecting to Discord:", Bun.inspect(error));
this.login(env.BOT_TOKEN).catch((error) => {
throw new Error(Bun.inspect(error));
});

this.once("ready", () => {
logger.info(`Logged in to Discord as ${this.user.tag}`);
logger.info("Logged in to Discord");
});
} catch (error) {
logger.error("An error occured while starting:", Bun.inspect(error));
logger.error(`An error occured while starting:`);
throw new Error(Bun.inspect(error));
}
}
}
68 changes: 0 additions & 68 deletions packages/bot/src/classes/ClusterManager.ts

This file was deleted.

78 changes: 78 additions & 0 deletions packages/bot/src/classes/Sharder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import env from "$shared/env.ts";
import logger from "$shared/logger.ts";
import { ShardClientUtil, ShardingManager } from "discord.js";

type Auto = number | "auto";

export class HibikiShardingManager {
readonly shardingManager: ShardingManager;
private readonly _mainFile: string;
private readonly _token: string;
private readonly _shardCount: Auto;

// Creates a new Sharding manager
constructor(file: string, token: string, shardCount: Auto = "auto") {
this._mainFile = file;
this._shardCount = shardCount;
this._token = token;

this.shardingManager = new ShardingManager(this._mainFile, {
token: this._token,
totalShards: this._shardCount,
mode: env.isProduction ? "worker" : "process",
execArgv: process.execArgv,
respawn: false,
});
}

// Spawns all shards
public spawn() {
this.shardingManager.spawn({ amount: this._shardCount }).catch((error) => {
throw new Error(Bun.inspect(error));
});

// Shard event listeners
this.shardingManager.on("shardCreate", (shard) => {
shard.on("death", () => {
logger.error(`Shard #${shard.id} died`);
});

shard.on("disconnect", () => {
logger.warn(`Shard #${shard.id} disconnected`);
});

shard.on("error", (error) => {
logger.error(`Shard #${shard.id} encountered an error:`);
throw new Error(Bun.inspect(error));
});

shard.on("ready", () => {
logger.info(`Shard #${shard.id} is ready`);
});

shard.on("reconnecting", () => {
logger.warn(`Shard #${shard.id} is reconnecting`);
});

shard.on("spawn", () => {
logger.info(`Shard #${shard.id} was spawned`);
});
});
}
}

// Returns the amount of total cached guilds on every shard
export async function fetchTotalCachedGuilds(shard: ShardClientUtil | null) {
if (!shard) return;
const values = (await shard.fetchClientValues("guilds.cache.size")) as number[];
if (values.length === 0) return;
return values.reduce((a, b) => a + b);
}

// Returns the amount of total cached users on every shard
export async function fetchTotalCachedUsers(shard: ShardClientUtil | null) {
if (!shard) return;
const values = (await shard.fetchClientValues("users.cache.size")) as number[];
if (values.length === 0) return;
return values.reduce((a, b) => a + b);
}
21 changes: 15 additions & 6 deletions packages/bot/src/hibiki.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
import env from "$shared/env.ts";
import { HibikiClient } from "$classes/Client.ts";
import { HibikiClient } from "./classes/Client.ts";
import { GatewayIntentBits } from "discord.js";

export const subscribedIntents: GatewayIntentBits[] = [
// Required for guild, channel, and role objects
GatewayIntentBits.Guilds,

// Required for incoming messages
GatewayIntentBits.GuildMessages,

// PRIVILEGED: Required for getting guild member data
GatewayIntentBits.GuildMembers,
];

// Creates a new Hibiki client
new HibikiClient({
auth: `Bot ${env.BOT_TOKEN}`,
gateway: {
intents: ["GUILDS", "GUILD_MESSAGES", "GUILD_MEMBERS"],
},
intents: subscribedIntents,
}).init();
6 changes: 3 additions & 3 deletions packages/bot/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import env from "$shared/env.ts";
import { HibikiClusterManager } from "$classes/ClusterManager.ts";
import { HibikiShardingManager } from "$classes/Sharder.ts";

// Use .ts in development. .js in production
const HIBIKI_INDEX_FILE = `${import.meta.dir}/hibiki.${env.NODE_ENV === "production" ? "js" : "ts"}`;

// Spawns a new cluster manager
const manager = new HibikiClusterManager(HIBIKI_INDEX_FILE, env.BOT_TOKEN, "auto");
// Creates a new sharding manager
const manager = new HibikiShardingManager(HIBIKI_INDEX_FILE, env.BOT_TOKEN, "auto");
manager.spawn();

0 comments on commit 29ce4e9

Please sign in to comment.