Setup logger and dynamic command loading
This commit is contained in:
parent
c25ce1c0c8
commit
324b321e5b
22 changed files with 227 additions and 136 deletions
14
package-lock.json
generated
14
package-lock.json
generated
|
@ -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",
|
||||||
|
|
|
@ -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",
|
||||||
|
|
10
src/index.ts
10
src/index.ts
|
@ -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 :/");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
77
src/lib/Logger.ts
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 = [];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,20 +7,19 @@ 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 = {
|
|
||||||
name: "play",
|
|
||||||
description: "Play a music",
|
|
||||||
options: [{
|
|
||||||
type: ApplicationCommandOptionTypes.STRING,
|
|
||||||
name: "music",
|
|
||||||
description: "The music to play",
|
|
||||||
required: true
|
|
||||||
}]
|
|
||||||
};
|
|
||||||
module: Music;
|
module: Music;
|
||||||
|
|
||||||
constructor(module: Music) {
|
constructor(module: Music) {
|
||||||
super(module);
|
super(module, {
|
||||||
|
name: "play",
|
||||||
|
description: "Play a music",
|
||||||
|
options: [{
|
||||||
|
type: ApplicationCommandOptionTypes.STRING,
|
||||||
|
name: "music",
|
||||||
|
description: "The music to play",
|
||||||
|
required: true
|
||||||
|
}]
|
||||||
|
});
|
||||||
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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -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 = {
|
|
||||||
name: "about",
|
constructor(module: Module) {
|
||||||
description: "Show information about the bot"
|
super(module, {
|
||||||
};
|
name: "about",
|
||||||
|
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]});
|
||||||
}
|
}
|
|
@ -1,27 +1,30 @@
|
||||||
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 = {
|
|
||||||
name: "info",
|
constructor(module: Module) {
|
||||||
description: "Show information of the current guild or the specified user",
|
super(module, {
|
||||||
options: [{
|
name: "info",
|
||||||
type: ApplicationCommandOptionTypes.USER,
|
description: "Show information of the current guild or the specified user",
|
||||||
name: "target",
|
options: [{
|
||||||
description: "The target user"
|
type: ApplicationCommandOptionTypes.USER,
|
||||||
}]
|
name: "target",
|
||||||
};
|
description: "The target user"
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async execute(interaction: CommandInteraction) {
|
async execute(interaction: CommandInteraction) {
|
||||||
let embed = new MessageEmbed();
|
let embed = new MessageEmbed();
|
|
@ -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 = {
|
|
||||||
name: "ping",
|
constructor(module: Module) {
|
||||||
description: "Replies with Pong and the bot ping"
|
super(module, {
|
||||||
};
|
name: "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`;
|
|
@ -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))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue