Setup logger and dynamic command loading

This commit is contained in:
Ethanell 2021-11-22 13:10:40 +01:00
parent c25ce1c0c8
commit 324b321e5b
22 changed files with 227 additions and 136 deletions

14
package-lock.json generated
View file

@ -12,6 +12,7 @@
"@discordjs/builders": "^0.6.0", "@discordjs/builders": "^0.6.0",
"@discordjs/rest": "^0.1.0-canary.0", "@discordjs/rest": "^0.1.0-canary.0",
"@discordjs/voice": "^0.7.5", "@discordjs/voice": "^0.7.5",
"colors": "^1.4.0",
"discord-api-types": "^0.23.1", "discord-api-types": "^0.23.1",
"discord.js": "^13.1.0", "discord.js": "^13.1.0",
"libsodium-wrappers": "^0.7.9", "libsodium-wrappers": "^0.7.9",
@ -219,6 +220,14 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/colors": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
"integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
"engines": {
"node": ">=0.1.90"
}
},
"node_modules/combined-stream": { "node_modules/combined-stream": {
"version": "1.0.8", "version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@ -896,6 +905,11 @@
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="
}, },
"colors": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
"integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA=="
},
"combined-stream": { "combined-stream": {
"version": "1.0.8", "version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",

View file

@ -28,6 +28,7 @@
"@discordjs/builders": "^0.6.0", "@discordjs/builders": "^0.6.0",
"@discordjs/rest": "^0.1.0-canary.0", "@discordjs/rest": "^0.1.0-canary.0",
"@discordjs/voice": "^0.7.5", "@discordjs/voice": "^0.7.5",
"colors": "^1.4.0",
"discord-api-types": "^0.23.1", "discord-api-types": "^0.23.1",
"discord.js": "^13.1.0", "discord.js": "^13.1.0",
"libsodium-wrappers": "^0.7.9", "libsodium-wrappers": "^0.7.9",

View file

@ -8,9 +8,11 @@ const client = new AdministratorClient({ intents: [Intents.FLAGS.GUILDS, Intents
client.once("ready", async () => { client.once("ready", async () => {
client.application = await client.application?.fetch() ?? null; await client.application?.fetch();
if (client.user?.username)
client.logger.name = client.user.username;
await client.modules.loadAllModules(); await client.modules.loadAllModules();
console.log("Started !"); client.logger.info("Started !");
}); });
client.on("interactionCreate", async interaction => { client.on("interactionCreate", async interaction => {
@ -23,7 +25,7 @@ client.on("interactionCreate", async interaction => {
try { try {
await command.execute(interaction); await command.execute(interaction);
} catch (error) { } catch (error) {
console.error(error); client.logger.err(error);
const msg = {content: "There was an error while executing this command !", ephemeral: true}; const msg = {content: "There was an error while executing this command !", ephemeral: true};
try { try {
await interaction.reply(msg); await interaction.reply(msg);
@ -34,7 +36,7 @@ client.on("interactionCreate", async interaction => {
try { try {
await (await interaction.fetchReply() as Message).reply(msg); await (await interaction.fetchReply() as Message).reply(msg);
} catch { } catch {
console.warn("Cant send error message to the user :/"); client.logger.warn("Cant send error message to the user :/");
} }
} }
} }

View file

@ -1,7 +1,8 @@
import {Client} from "discord.js"; import {Client} from "discord.js";
import {Modules} from "./Modules"; import {Modules} from "./Modules";
import {Logger} from "./Logger";
export class AdministratorClient extends Client { export class AdministratorClient extends Client {
logger: Logger = new Logger("Core");
modules: Modules = new Modules(this); modules: Modules = new Modules(this);
} }

View file

@ -1,14 +1,17 @@
import {ApplicationCommandData, CommandInteraction} from "discord.js"; import {ApplicationCommandData, CommandInteraction} from "discord.js";
import {Module} from "./Module"; import {Module} from "./Module";
import {Logger} from "./Logger";
export abstract class Command { export abstract class Command {
module: Module; module: Module;
data: ApplicationCommandData; data: ApplicationCommandData;
logger: Logger;
constructor(module: Module) { protected constructor(module: Module, data: ApplicationCommandData) {
this.module = module; this.module = module;
this.data = null as any; this.data = data;
this.logger = this.module.logger.createChild(this.data.name);
} }
abstract execute(interaction: CommandInteraction): void; abstract execute(interaction: CommandInteraction): void;

77
src/lib/Logger.ts Normal file
View file

@ -0,0 +1,77 @@
import "colors"
export enum LoggerLevel {
INFO = "Info",
LOG = "Log",
WARN = "Warn",
ERR = "Error"
}
export class Logger {
private _name: string;
private parent: Logger | null = null;
children: Logger[] = [];
constructor(name: string) {
this._name = name;
}
public createChild(name: string): Logger {
const child = new Logger(name);
child.parent = this;
this.children.push(child);
return child;
}
get name(): string {
if (this.parent)
return `${this.parent.name} - ${this._name}`;
return this._name;
}
set name(name: string) {
this._name = name;
}
get date(): string {
return new Date().toLocaleDateString();
}
private print(level: LoggerLevel, msg: any) {
const message = `[${this.date}] {${level}} ${this.name}: ${msg.toString()}`;
switch (level) {
case LoggerLevel.INFO:
console.info(message);
break;
case LoggerLevel.LOG:
console.log(message.gray);
break;
case LoggerLevel.WARN:
console.warn(message.yellow);
break;
case LoggerLevel.ERR:
console.error(message.red);
}
if (msg instanceof Error)
console.error(msg);
}
public info(msg: any) {
this.print(LoggerLevel.INFO, msg);
}
public log(msg: any) {
this.print(LoggerLevel.LOG, msg);
}
public warn(msg: any) {
this.print(LoggerLevel.WARN, msg);
}
public err(msg: any) {
this.print(LoggerLevel.ERR, msg);
}
}

View file

@ -1,21 +1,34 @@
import {Command} from "./Command"; import {Command} from "./Command";
import {Modules} from "./Modules"; import {Modules} from "./Modules";
import {Logger} from "./Logger";
import {readdirSync} from "fs";
export class Module {
commands: Command[] = new Array<Command>(); export abstract class Module {
modules: Modules; modules: Modules;
logger: Logger;
loadedCommands: Command[] = [];
constructor(modules: Modules) { protected constructor(modules: Modules, name: string) {
this.modules = modules; this.modules = modules;
this.logger = this.modules.client.logger.createChild(name);
}
get commands() {
const folder = `${__dirname}/../modules/${this.constructor.name}/commands`;
return readdirSync(folder, {withFileTypes: true})
.filter(file => file.isDirectory() || file.name.endsWith(".js"))
.map(file => (require(`${folder}/${file.name}`)[file.name.charAt(0).toUpperCase() + file.name.replace(/\.js$/, "").slice(1)+"Command"]));
} }
async load() { async load() {
await Promise.all(this.commands.map(cmd => cmd.load())); const commands = this.commands.map(cmd => new cmd(this));
await Promise.all(commands.map(cmd => cmd.load()));
this.loadedCommands = this.loadedCommands.concat(commands);
} }
async unload() { async unload() {
if (this.modules.client) { await Promise.all(this.loadedCommands.map(cmd => cmd.unload()));
await Promise.all(this.commands.map(cmd => cmd.unload())) this.loadedCommands = [];
}
} }
} }

View file

@ -19,12 +19,12 @@ export class Modules {
this.modules.set(name, module); this.modules.set(name, module);
if (createCommand) if (createCommand)
await this.registerCommand(module.commands.map(c => c.data)); await this.registerCommand(module.loadedCommands.map(c => c.data));
console.info(`Module ${name} loaded`) module.logger.info(`loaded`)
} catch (error) { } catch (error) {
console.error(`Fail to load module ${name}`); this.client.logger.err(`Fail to load module ${name}`);
console.error(error); this.client.logger.err(error);
return false return false
} }
return true; return true;
@ -34,15 +34,15 @@ export class Modules {
try { try {
const module = this.modules.get(name); const module = this.modules.get(name);
if (!module) { if (!module) {
console.error(`Module ${name} not found`); this.client.logger.err(`Module ${name} not found`);
return false; return false;
} }
await module.unload(); await module.unload();
this.modules.delete(name); this.modules.delete(name);
console.info(`Module ${name} unloaded`) this.client.logger.info(`Module ${name} unloaded`)
} catch (error) { } catch (error) {
console.error(`Fail to unload module ${name}`); this.client.logger.err(`Fail to unload module ${name}`);
console.error(error); this.client.logger.err(error);
return false return false
} }
return true; return true;
@ -103,7 +103,7 @@ export class Modules {
} }
allCommands() : Command[] { allCommands() : Command[] {
return Array.from(this.modules.values()).map(m => m.commands).reduce((l, m) => l.concat(m)); return Array.from(this.modules.values()).map(m => m.loadedCommands).reduce((l, m) => l.concat(m));
} }
getCommand(name: string): Command | null { getCommand(name: string): Command | null {

View file

@ -1,17 +1,16 @@
import {Command} from "../../../lib/Command"; import {Command} from "../../../lib/Command";
import {ChatInputApplicationCommandData, CommandInteraction, GuildMember} from "discord.js"; import {CommandInteraction, GuildMember} from "discord.js";
import {Music} from "../index"; import {Music} from "../index";
export class DisconnectCommand extends Command { export class DisconnectCommand extends Command {
data: ChatInputApplicationCommandData = {
name: "disconnect",
description: "Stop the music"
};
module: Music; module: Music;
constructor(module: Music) { constructor(module: Music) {
super(module); super(module, {
name: "disconnect",
description: "Stop the music"
});
this.module = module; this.module = module;
} }

View file

@ -1,17 +1,16 @@
import {Command} from "../../../lib/Command"; import {Command} from "../../../lib/Command";
import {ChatInputApplicationCommandData, CommandInteraction, GuildMember} from "discord.js"; import {CommandInteraction, GuildMember} from "discord.js";
import {Music} from "../index"; import {Music} from "../index";
export class FlushCommand extends Command { export class FlushCommand extends Command {
data: ChatInputApplicationCommandData = {
name: "flush",
description: "Flush the music queue"
};
module: Music; module: Music;
constructor(module: Music) { constructor(module: Music) {
super(module); super(module, {
name: "flush",
description: "Flush the music queue"
});
this.module = module; this.module = module;
} }

View file

@ -1,18 +1,17 @@
import {Command} from "../../../lib/Command"; import {Command} from "../../../lib/Command";
import {ChatInputApplicationCommandData, CommandInteraction, GuildMember} from "discord.js"; import {CommandInteraction, GuildMember} from "discord.js";
import {Music} from "../index"; import {Music} from "../index";
import {AudioPlayerStatus} from "@discordjs/voice"; import {AudioPlayerStatus} from "@discordjs/voice";
export class PauseCommand extends Command { export class PauseCommand extends Command {
data: ChatInputApplicationCommandData = {
name: "pause",
description: "Pause the music"
};
module: Music; module: Music;
constructor(module: Music) { constructor(module: Music) {
super(module); super(module, {
name: "pause",
description: "Pause the music"
});
this.module = module; this.module = module;
} }

View file

@ -1,5 +1,5 @@
import {Command} from "../../../lib/Command"; import {Command} from "../../../lib/Command";
import {ChatInputApplicationCommandData, CommandInteraction, GuildMember, VoiceChannel} from "discord.js"; import {CommandInteraction, GuildMember, VoiceChannel} from "discord.js";
import {Music} from "../index"; import {Music} from "../index";
import {Player} from "../lib/Player"; import {Player} from "../lib/Player";
import {Track} from "../lib/Track"; import {Track} from "../lib/Track";
@ -7,7 +7,10 @@ import {entersState, VoiceConnectionStatus} from "@discordjs/voice";
const {Constants: { ApplicationCommandOptionTypes }} = require("discord.js"); const {Constants: { ApplicationCommandOptionTypes }} = require("discord.js");
export class PlayCommand extends Command { export class PlayCommand extends Command {
data: ChatInputApplicationCommandData = { module: Music;
constructor(module: Music) {
super(module, {
name: "play", name: "play",
description: "Play a music", description: "Play a music",
options: [{ options: [{
@ -16,11 +19,7 @@ export class PlayCommand extends Command {
description: "The music to play", description: "The music to play",
required: true required: true
}] }]
}; });
module: Music;
constructor(module: Music) {
super(module);
this.module = module; this.module = module;
} }
@ -53,7 +52,7 @@ export class PlayCommand extends Command {
try { try {
await entersState(player.connexion, VoiceConnectionStatus.Ready, 20e3); await entersState(player.connexion, VoiceConnectionStatus.Ready, 20e3);
} catch (error) { } catch (error) {
console.warn("Fail to enter state Ready !"); this.logger.warn("Fail to enter state Ready !");
await interaction.followUp("Failed to join voice channel within 20 seconds, please try again later !"); await interaction.followUp("Failed to join voice channel within 20 seconds, please try again later !");
return; return;
} }
@ -65,7 +64,7 @@ export class PlayCommand extends Command {
player.enqueue(track); player.enqueue(track);
await interaction.followUp(`${track.info.videoDetails.title} added to queue`); await interaction.followUp(`${track.info.videoDetails.title} added to queue`);
} catch (error) { } catch (error) {
console.error(error); this.logger.err(error);
await interaction.followUp("Fail to add to queue") await interaction.followUp("Fail to add to queue")
} }
} }

View file

@ -1,5 +1,5 @@
import {Command} from "../../../lib/Command"; import {Command} from "../../../lib/Command";
import {ChatInputApplicationCommandData, CommandInteraction, GuildMember} from "discord.js"; import {CommandInteraction, GuildMember} from "discord.js";
import {Music} from "../index"; import {Music} from "../index";
import {AudioPlayerStatus} from "@discordjs/voice"; import {AudioPlayerStatus} from "@discordjs/voice";
@ -12,14 +12,13 @@ function millisecondsToTime(milli: number): string {
} }
export class QueueCommand extends Command { export class QueueCommand extends Command {
data: ChatInputApplicationCommandData = {
name: "queue",
description: "Display the current queue"
};
module: Music; module: Music;
constructor(module: Music) { constructor(module: Music) {
super(module); super(module, {
name: "queue",
description: "Display the current queue"
});
this.module = module; this.module = module;
} }

View file

@ -1,18 +1,17 @@
import {Command} from "../../../lib/Command"; import {Command} from "../../../lib/Command";
import {ChatInputApplicationCommandData, CommandInteraction, GuildMember} from "discord.js"; import {CommandInteraction, GuildMember} from "discord.js";
import {Music} from "../index"; import {Music} from "../index";
import {AudioPlayerStatus} from "@discordjs/voice"; import {AudioPlayerStatus} from "@discordjs/voice";
export class ResumeCommand extends Command { export class ResumeCommand extends Command {
data: ChatInputApplicationCommandData = {
name: "resume",
description: "Resume the music"
};
module: Music; module: Music;
constructor(module: Music) { constructor(module: Music) {
super(module); super(module, {
name: "resume",
description: "Resume the music"
});
this.module = module; this.module = module;
} }

View file

@ -1,18 +1,17 @@
import {Command} from "../../../lib/Command"; import {Command} from "../../../lib/Command";
import {ChatInputApplicationCommandData, CommandInteraction, GuildMember} from "discord.js"; import {CommandInteraction, GuildMember} from "discord.js";
import {Music} from "../index"; import {Music} from "../index";
import {AudioPlayerStatus} from "@discordjs/voice"; import {AudioPlayerStatus} from "@discordjs/voice";
export class SkipCommand extends Command { export class SkipCommand extends Command {
data: ChatInputApplicationCommandData = {
name: "skip",
description: "Skip the music"
};
module: Music; module: Music;
constructor(module: Music) { constructor(module: Music) {
super(module); super(module, {
name: "skip",
description: "Skip the music"
});
this.module = module; this.module = module;
} }

View file

@ -1,18 +1,17 @@
import {Command} from "../../../lib/Command"; import {Command} from "../../../lib/Command";
import {ChatInputApplicationCommandData, CommandInteraction, GuildMember} from "discord.js"; import {CommandInteraction, GuildMember} from "discord.js";
import {Music} from "../index"; import {Music} from "../index";
import {AudioPlayerStatus} from "@discordjs/voice"; import {AudioPlayerStatus} from "@discordjs/voice";
export class StopCommand extends Command { export class StopCommand extends Command {
data: ChatInputApplicationCommandData = {
name: "stop",
description: "Stop the music"
};
module: Music; module: Music;
constructor(module: Music) { constructor(module: Music) {
super(module); super(module, {
name: "stop",
description: "Stop the music"
});
this.module = module; this.module = module;
} }

View file

@ -1,30 +1,14 @@
import {Module} from "../../lib/Module"; import {Module} from "../../lib/Module";
import {Modules} from "../../lib/Modules"; import {Modules} from "../../lib/Modules";
import {PlayCommand} from "./play";
import {Snowflake} from "discord-api-types"; import {Snowflake} from "discord-api-types";
import {Player} from "./Player"; import {Player} from "./lib/Player";
import {StopCommand} from "./stop";
import {PauseCommand} from "./pause";
import {SkipCommand} from "./skip";
import {ResumeCommand} from "./resume";
import {FlushCommand} from "./flush";
import {QueueCommand} from "./queue";
import {DisconnectCommand} from "./disconnect";
export class Music extends Module { export class Music extends Module {
players: Map<Snowflake, Player> = new Map<Snowflake, Player>(); players: Map<Snowflake, Player> = new Map<Snowflake, Player>();
constructor(modules: Modules) { constructor(modules: Modules) {
super(modules); super(modules, "Music");
this.commands.push(new PlayCommand(this));
this.commands.push(new StopCommand(this));
this.commands.push(new PauseCommand(this));
this.commands.push(new ResumeCommand(this));
this.commands.push(new SkipCommand(this));
this.commands.push(new FlushCommand(this));
this.commands.push(new QueueCommand(this));
this.commands.push(new DisconnectCommand(this));
// ToDo: stop if nobody in the channel // ToDo: stop if nobody in the channel
} }
} }

View file

@ -62,12 +62,12 @@ export class Player {
} }
} }
}); });
this.audio.on('stateChange', (oldState: AudioPlayerState, newState: AudioPlayerState) => { this.audio.on('stateChange', async (oldState: AudioPlayerState, newState: AudioPlayerState) => {
if (newState.status === AudioPlayerStatus.Idle && oldState.status !== AudioPlayerStatus.Idle) { if (newState.status === AudioPlayerStatus.Idle && oldState.status !== AudioPlayerStatus.Idle) {
(oldState.resource as AudioResource<Track>).metadata.onFinish(); await (oldState.resource as AudioResource<Track>).metadata.onFinish();
void this.processQueue(); await this.processQueue();
} else if (newState.status === AudioPlayerStatus.Playing) { } else if (newState.status === AudioPlayerStatus.Playing) {
(newState.resource as AudioResource<Track>).metadata.onStart(); await (newState.resource as AudioResource<Track>).metadata.onStart();
} }
}); });

View file

@ -1,24 +1,30 @@
import {Command} from "../../lib/Command"; import {Command} from "../../../lib/Command";
import {ChatInputApplicationCommandData, CommandInteraction, MessageEmbed} from "discord.js"; import {CommandInteraction, MessageEmbed} from "discord.js";
import {Module} from "../../../lib/Module";
export class AboutCommand extends Command { export class AboutCommand extends Command {
data: ChatInputApplicationCommandData = {
constructor(module: Module) {
super(module, {
name: "about", name: "about",
description: "Show information about the bot" description: "Show information about the bot"
}; });
}
async execute(interaction: CommandInteraction) { async execute(interaction: CommandInteraction) {
const flifloo = await interaction.client.users.fetch("177393521051959306"); const flifloo = await interaction.client.users.fetch("177393521051959306");
await interaction.client.application?.fetch();
// @ts-ignore // @ts-ignore
const embed = new MessageEmbed().setTitle(interaction.guild ? interaction.guild.me.displayName : `${interaction.client.user.username}#${interaction.client.user.discriminator}`) const embed = new MessageEmbed().setTitle(interaction.guild ? interaction.guild.me.displayName : `${interaction.client.user.username}#${interaction.client.user.discriminator}`)
.setDescription(interaction.client.application?.description as string) // @ts-ignore .setDescription(interaction.client.application?.description || '') // @ts-ignore
.setAuthor("Administrator", interaction.client.user.avatarURL(), "https://github.com/flifloo") // @ts-ignore .setAuthor("Administrator", interaction.client.user.avatarURL(), "https://github.com/flifloo") // @ts-ignore
.setFooter(`Made with ❤️ by ${flifloo.username}#${flifloo.discriminator}`, flifloo.avatarURL()) // @ts-ignore .setFooter(`Made with ❤️ by ${flifloo.username}#${flifloo.discriminator}`, flifloo.avatarURL()) // @ts-ignore
.addField("Owned by", interaction.client.application?.owner.toString()) .addField("Owned by", interaction.client.application?.owner.toString())
.addField("Guilds", (await interaction.client.guilds.fetch()).size.toString()) .addField("Guilds", (await interaction.client.guilds.fetch()).size.toString())
.addField("Modules", this.module.modules.modules.size.toString()) .addField("Modules", this.module.modules.modules.size.toString())
.addField("Commands", Array.from(this.module.modules.modules.values()).map(m => m.commands.length).reduce((sum, current) => sum+current).toString()); .addField("Commands", Array.from(this.module.modules.modules.values()).map(m => m.loadedCommands.length).reduce((sum, current) => sum+current).toString());
await interaction.reply({embeds: [embed]}); await interaction.reply({embeds: [embed]});
} }

View file

@ -1,19 +1,21 @@
import {Command} from "../../lib/Command"; import {Command} from "../../../lib/Command";
import { import {
CategoryChannel, CategoryChannel,
ChatInputApplicationCommandData,
CommandInteraction, CommandInteraction,
GuildMember, GuildMember,
MessageEmbed, MessageEmbed,
TextChannel, TextChannel,
VoiceChannel VoiceChannel
} from "discord.js"; } from "discord.js";
import {Module} from "../../../lib/Module";
const {Constants: { ApplicationCommandOptionTypes }} = require("discord.js"); const {Constants: { ApplicationCommandOptionTypes }} = require("discord.js");
export class InfoCommand extends Command { export class InfoCommand extends Command {
data: ChatInputApplicationCommandData = {
constructor(module: Module) {
super(module, {
name: "info", name: "info",
description: "Show information of the current guild or the specified user", description: "Show information of the current guild or the specified user",
options: [{ options: [{
@ -21,7 +23,8 @@ export class InfoCommand extends Command {
name: "target", name: "target",
description: "The target user" description: "The target user"
}] }]
}; });
}
async execute(interaction: CommandInteraction) { async execute(interaction: CommandInteraction) {
let embed = new MessageEmbed(); let embed = new MessageEmbed();

View file

@ -1,14 +1,15 @@
import {Command} from "../../lib/Command"; import {Command} from "../../../lib/Command";
import { import {CommandInteraction} from "discord.js";
ChatInputApplicationCommandData, import {Module} from "../../../lib/Module";
CommandInteraction,
} from "discord.js";
export class PingCommand extends Command { export class PingCommand extends Command {
data: ChatInputApplicationCommandData = {
constructor(module: Module) {
super(module, {
name: "ping", name: "ping",
description: "Replies with Pong and the bot ping" description: "Replies with Pong and the bot ping"
}; });
}
async execute(interaction: CommandInteraction) { async execute(interaction: CommandInteraction) {
const msg = `Pong !\nReceive: ${new Date().getTime() - interaction.createdAt.getTime()}ms`; const msg = `Pong !\nReceive: ${new Date().getTime() - interaction.createdAt.getTime()}ms`;

View file

@ -1,15 +1,9 @@
import {AboutCommand} from "./about";
import {Module} from "../../lib/Module"; import {Module} from "../../lib/Module";
import {Modules} from "../../lib/Modules"; import {Modules} from "../../lib/Modules";
import {InfoCommand} from "./info";
import {PingCommand} from "./ping";
export class Utils extends Module { export class Utils extends Module {
constructor(modules: Modules) { constructor(modules: Modules) {
super(modules); super(modules, "Utils");
this.commands.push(new AboutCommand(this));
this.commands.push(new InfoCommand(this));
this.commands.push(new PingCommand(this))
} }
} }