style: run format:apply
This commit is contained in:
+162
-148
@@ -1,194 +1,208 @@
|
|||||||
import {
|
import {
|
||||||
CacheType,
|
CacheType,
|
||||||
Client,
|
Client,
|
||||||
GatewayIntentBits,
|
GatewayIntentBits,
|
||||||
Interaction,
|
Interaction,
|
||||||
Message,
|
Message,
|
||||||
OAuth2Scopes,
|
OAuth2Scopes,
|
||||||
PermissionFlagsBits,
|
PermissionFlagsBits,
|
||||||
VoiceState
|
VoiceState
|
||||||
} from 'discord.js';
|
} from 'discord.js';
|
||||||
import { Logger } from './utils/log';
|
import { Logger } from './utils/log';
|
||||||
import { config } from './utils/config';
|
import { config } from './utils/config';
|
||||||
|
|
||||||
type BotEventListeners = {
|
type BotEventListeners = {
|
||||||
'messageCreate': (message: Message) => void;
|
messageCreate: (message: Message) => void;
|
||||||
'interactionCreate': (interaction: Interaction) => void;
|
interactionCreate: (interaction: Interaction) => void;
|
||||||
'voiceStateUpdate': (oldState: VoiceState, newState: VoiceState) => void;
|
voiceStateUpdate: (oldState: VoiceState, newState: VoiceState) => void;
|
||||||
};
|
};
|
||||||
type BotEventListener<K extends keyof BotEventListeners> = BotEventListeners[K];
|
type BotEventListener<K extends keyof BotEventListeners> = BotEventListeners[K];
|
||||||
|
|
||||||
export class Bot {
|
export class Bot {
|
||||||
private client: Client | undefined;
|
private client: Client | undefined;
|
||||||
|
|
||||||
private readonly token: string;
|
private readonly token: string;
|
||||||
private readonly clientId: string;
|
private readonly clientId: string;
|
||||||
|
|
||||||
private readonly log: Logger;
|
private readonly log: Logger;
|
||||||
|
|
||||||
private eventListeners: {
|
private eventListeners: {
|
||||||
[K in keyof BotEventListeners]?: BotEventListener<K>[];
|
[K in keyof BotEventListeners]?: BotEventListener<K>[];
|
||||||
} = {};
|
} = {};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
event methods
|
event methods
|
||||||
*/
|
*/
|
||||||
public on<K extends keyof BotEventListeners>(
|
public on<K extends keyof BotEventListeners>(
|
||||||
event: K,
|
event: K,
|
||||||
listener: BotEventListener<K>
|
listener: BotEventListener<K>
|
||||||
): void {
|
): void {
|
||||||
if (!this.eventListeners[event]) {
|
if (!this.eventListeners[event]) {
|
||||||
this.eventListeners[event] = [];
|
this.eventListeners[event] = [];
|
||||||
}
|
}
|
||||||
(this.eventListeners[event] as BotEventListener<K>[]).push(listener);
|
(this.eventListeners[event] as BotEventListener<K>[]).push(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public off<K extends keyof BotEventListeners>(
|
public off<K extends keyof BotEventListeners>(
|
||||||
event: K,
|
event: K,
|
||||||
listener: BotEventListener<K>
|
listener: BotEventListener<K>
|
||||||
): boolean {
|
): boolean {
|
||||||
const listeners = this.eventListeners[event];
|
const listeners = this.eventListeners[event];
|
||||||
if (!listeners) return false;
|
if (!listeners) return false;
|
||||||
|
|
||||||
const index = (listeners as BotEventListener<K>[]).indexOf(listener);
|
const index = (listeners as BotEventListener<K>[]).indexOf(listener);
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
(listeners as BotEventListener<K>[]).splice(index, 1);
|
(listeners as BotEventListener<K>[]).splice(index, 1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public once<K extends keyof BotEventListeners>(
|
public once<K extends keyof BotEventListeners>(
|
||||||
event: K,
|
event: K,
|
||||||
listener: BotEventListener<K>
|
listener: BotEventListener<K>
|
||||||
): void {
|
): void {
|
||||||
const onceWrapper = ((...args: Parameters<BotEventListener<K>>) => {
|
const onceWrapper = ((...args: Parameters<BotEventListener<K>>) => {
|
||||||
this.off(event, onceWrapper as BotEventListener<K>);
|
this.off(event, onceWrapper as BotEventListener<K>);
|
||||||
(listener as (...args: unknown[]) => void)(...args);
|
(listener as (...args: unknown[]) => void)(...args);
|
||||||
}) as BotEventListener<K>;
|
}) as BotEventListener<K>;
|
||||||
|
|
||||||
this.on(event, onceWrapper);
|
this.on(event, onceWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
private emit<K extends keyof BotEventListeners>(
|
private emit<K extends keyof BotEventListeners>(
|
||||||
event: K,
|
event: K,
|
||||||
...args: Parameters<BotEventListener<K>>
|
...args: Parameters<BotEventListener<K>>
|
||||||
): void {
|
): void {
|
||||||
const listeners = this.eventListeners[event];
|
const listeners = this.eventListeners[event];
|
||||||
if (listeners) {
|
if (listeners) {
|
||||||
for (const listener of listeners as BotEventListener<K>[]) {
|
for (const listener of listeners as BotEventListener<K>[]) {
|
||||||
try {
|
try {
|
||||||
(listener as (...args: unknown[]) => void)(...args);
|
(listener as (...args: unknown[]) => void)(...args);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.log.error(`Error in event listener for ${String(event)}:`, error);
|
this.log.error(
|
||||||
}
|
`Error in event listener for ${String(event)}:`,
|
||||||
}
|
error
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
class methods
|
class methods
|
||||||
*/
|
*/
|
||||||
private constructor() {
|
private constructor() {
|
||||||
this.log = new Logger('Bot');
|
this.log = new Logger('Bot');
|
||||||
|
|
||||||
this.token = config.token;
|
this.token = config.token;
|
||||||
this.clientId = config.client_id;
|
this.clientId = config.client_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async init(): Promise<void> {
|
public async init(): Promise<void> {
|
||||||
this.log.info('Bot init');
|
this.log.info('Bot init');
|
||||||
|
|
||||||
if (this.client)
|
if (this.client)
|
||||||
throw new Error('Client already exists, was init called twice?');
|
throw new Error('Client already exists, was init called twice?');
|
||||||
|
|
||||||
this.log.info('Instantiating client');
|
this.log.info('Instantiating client');
|
||||||
this.client = new Client({
|
this.client = new Client({
|
||||||
intents: [
|
intents: [
|
||||||
GatewayIntentBits.Guilds,
|
GatewayIntentBits.Guilds,
|
||||||
GatewayIntentBits.GuildMessages,
|
GatewayIntentBits.GuildMessages,
|
||||||
GatewayIntentBits.GuildVoiceStates,
|
GatewayIntentBits.GuildVoiceStates,
|
||||||
GatewayIntentBits.MessageContent
|
GatewayIntentBits.MessageContent
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
this.log.info('Registering callbacks');
|
this.log.info('Registering callbacks');
|
||||||
this.client.on('clientReady', () => this.onReady());
|
this.client.on('clientReady', () => this.onReady());
|
||||||
this.client.on('error', (err) => this.onError(err, false));
|
this.client.on('error', (err) => this.onError(err, false));
|
||||||
this.client.on('shardError', (err) => this.onError(err, true));
|
this.client.on('shardError', (err) => this.onError(err, true));
|
||||||
this.client.on('messageCreate', (message: Message<boolean>) => this.onMessage(message));
|
this.client.on('messageCreate', (message: Message<boolean>) =>
|
||||||
this.client.on('interactionCreate', (interaction: Interaction<CacheType>) => this.onInteraction(interaction));
|
this.onMessage(message)
|
||||||
this.client.on('voiceStateUpdate', (oldState: VoiceState, newState: VoiceState) => this.onVoiceStateUpdate(oldState, newState));
|
);
|
||||||
|
this.client.on('interactionCreate', (interaction: Interaction<CacheType>) =>
|
||||||
|
this.onInteraction(interaction)
|
||||||
|
);
|
||||||
|
this.client.on(
|
||||||
|
'voiceStateUpdate',
|
||||||
|
(oldState: VoiceState, newState: VoiceState) =>
|
||||||
|
this.onVoiceStateUpdate(oldState, newState)
|
||||||
|
);
|
||||||
|
|
||||||
this.log.info('Logging in...');
|
this.log.info('Logging in...');
|
||||||
await this.client.login(this.token);
|
await this.client.login(this.token);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
event listeners
|
event listeners
|
||||||
*/
|
*/
|
||||||
private onReady(): void {
|
private onReady(): void {
|
||||||
this.log.info('Logged in');
|
this.log.info('Logged in');
|
||||||
|
|
||||||
const inviteLink = this.client?.generateInvite({
|
const inviteLink = this.client?.generateInvite({
|
||||||
scopes: [OAuth2Scopes.ApplicationsCommands, OAuth2Scopes.Bot],
|
scopes: [OAuth2Scopes.ApplicationsCommands, OAuth2Scopes.Bot],
|
||||||
permissions: [
|
permissions: [
|
||||||
PermissionFlagsBits.AddReactions,
|
PermissionFlagsBits.AddReactions,
|
||||||
PermissionFlagsBits.AttachFiles,
|
PermissionFlagsBits.AttachFiles,
|
||||||
PermissionFlagsBits.ChangeNickname,
|
PermissionFlagsBits.ChangeNickname,
|
||||||
PermissionFlagsBits.Connect,
|
PermissionFlagsBits.Connect,
|
||||||
PermissionFlagsBits.Speak,
|
PermissionFlagsBits.Speak,
|
||||||
PermissionFlagsBits.ViewChannel,
|
PermissionFlagsBits.ViewChannel,
|
||||||
PermissionFlagsBits.ReadMessageHistory,
|
PermissionFlagsBits.ReadMessageHistory,
|
||||||
PermissionFlagsBits.SendMessages,
|
PermissionFlagsBits.SendMessages,
|
||||||
PermissionFlagsBits.SendMessagesInThreads,
|
PermissionFlagsBits.SendMessagesInThreads,
|
||||||
PermissionFlagsBits.SendVoiceMessages,
|
PermissionFlagsBits.SendVoiceMessages,
|
||||||
PermissionFlagsBits.EmbedLinks
|
PermissionFlagsBits.EmbedLinks
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
this.log.info('Invite link: %s', inviteLink);
|
this.log.info('Invite link: %s', inviteLink);
|
||||||
}
|
}
|
||||||
|
|
||||||
private onError(error: Error, isShardError: boolean): void {
|
private onError(error: Error, isShardError: boolean): void {
|
||||||
if (isShardError)
|
if (isShardError)
|
||||||
this.log.error(
|
this.log.error(
|
||||||
'A shard error ocurred: %s - %s - %s',
|
'A shard error ocurred: %s - %s - %s',
|
||||||
error.name,
|
error.name,
|
||||||
error.message,
|
error.message,
|
||||||
error.stack
|
error.stack
|
||||||
);
|
);
|
||||||
else
|
else
|
||||||
this.log.error(
|
this.log.error(
|
||||||
'An error ocurred: %s - %s - %s',
|
'An error ocurred: %s - %s - %s',
|
||||||
error.name,
|
error.name,
|
||||||
error.message,
|
error.message,
|
||||||
error.stack
|
error.stack
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
public event listeners
|
public event listeners
|
||||||
*/
|
*/
|
||||||
private async onInteraction(interaction: Interaction): Promise<void> {
|
private async onInteraction(interaction: Interaction): Promise<void> {
|
||||||
this.emit('interactionCreate', interaction);
|
this.emit('interactionCreate', interaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async onMessage(message: Message): Promise<void> {
|
private async onMessage(message: Message): Promise<void> {
|
||||||
this.emit('messageCreate', message);
|
this.emit('messageCreate', message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async onVoiceStateUpdate(oldState: VoiceState, newState: VoiceState): Promise<void> {
|
private async onVoiceStateUpdate(
|
||||||
this.emit('voiceStateUpdate', oldState, newState);
|
oldState: VoiceState,
|
||||||
}
|
newState: VoiceState
|
||||||
|
): Promise<void> {
|
||||||
|
this.emit('voiceStateUpdate', oldState, newState);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
singleton logic
|
singleton logic
|
||||||
*/
|
*/
|
||||||
static #instance: Bot | null = null;
|
static #instance: Bot | null = null;
|
||||||
|
|
||||||
public static get get(): Bot {
|
public static get get(): Bot {
|
||||||
if (!Bot.#instance) Bot.#instance = new Bot();
|
if (!Bot.#instance) Bot.#instance = new Bot();
|
||||||
return Bot.#instance;
|
return Bot.#instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user