Implement events and voice auto disconnect
This commit is contained in:
parent
324b321e5b
commit
b761c5ca0e
6 changed files with 121 additions and 20 deletions
|
@ -1,26 +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";
|
import {Component} from "./Component";
|
||||||
|
|
||||||
|
|
||||||
export abstract class Command {
|
export abstract class Command extends Component {
|
||||||
module: Module;
|
|
||||||
data: ApplicationCommandData;
|
data: ApplicationCommandData;
|
||||||
logger: Logger;
|
|
||||||
|
|
||||||
protected constructor(module: Module, data: ApplicationCommandData) {
|
protected constructor(module: Module, data: ApplicationCommandData) {
|
||||||
|
super(module, data.name);
|
||||||
this.module = module;
|
this.module = module;
|
||||||
this.data = data;
|
this.data = data;
|
||||||
this.logger = this.module.logger.createChild(this.data.name);
|
this.logger = this.module.logger.createChild(this.data.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract execute(interaction: CommandInteraction): void;
|
abstract execute(interaction: CommandInteraction): void;
|
||||||
|
|
||||||
load(): any {
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
unload(): any {
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
21
src/lib/Component.ts
Normal file
21
src/lib/Component.ts
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import {Module} from "./Module";
|
||||||
|
import {Logger} from "./Logger";
|
||||||
|
|
||||||
|
|
||||||
|
export abstract class Component {
|
||||||
|
module: Module;
|
||||||
|
logger: Logger;
|
||||||
|
|
||||||
|
protected constructor(module: Module, name: string | null = null) {
|
||||||
|
this.module = module;
|
||||||
|
this.logger = this.module.logger.createChild(name || this.constructor.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
load(): any {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
unload(): any {
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
5
src/lib/Event.ts
Normal file
5
src/lib/Event.ts
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import {Component} from "./Component";
|
||||||
|
|
||||||
|
export abstract class Event extends Component {
|
||||||
|
|
||||||
|
}
|
|
@ -1,34 +1,82 @@
|
||||||
import {Command} from "./Command";
|
import {Command} from "./Command";
|
||||||
import {Modules} from "./Modules";
|
import {Modules} from "./Modules";
|
||||||
import {Logger} from "./Logger";
|
import {Logger} from "./Logger";
|
||||||
import {readdirSync} from "fs";
|
import {readdirSync, existsSync} from "fs";
|
||||||
|
import {Event} from "./Event";
|
||||||
|
|
||||||
|
|
||||||
export abstract class Module {
|
export abstract class Module {
|
||||||
modules: Modules;
|
modules: Modules;
|
||||||
logger: Logger;
|
logger: Logger;
|
||||||
loadedCommands: Command[] = [];
|
loadedCommands: Command[] = [];
|
||||||
|
loadedEvents: Event[] = [];
|
||||||
|
|
||||||
protected constructor(modules: Modules, name: string) {
|
protected constructor(modules: Modules, name: string) {
|
||||||
this.modules = modules;
|
this.modules = modules;
|
||||||
this.logger = this.modules.client.logger.createChild(name);
|
this.logger = this.modules.client.logger.createChild(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
get commands() {
|
private getComponent(name: string) {
|
||||||
const folder = `${__dirname}/../modules/${this.constructor.name}/commands`;
|
const folder = `${__dirname}/../modules/${this.constructor.name}/${name}`;
|
||||||
|
if (existsSync(folder))
|
||||||
return readdirSync(folder, {withFileTypes: true})
|
return readdirSync(folder, {withFileTypes: true})
|
||||||
.filter(file => file.isDirectory() || file.name.endsWith(".js"))
|
.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"]));
|
.map(file => require(`${folder}/${file.name}`)[file.name.charAt(0).toUpperCase() + file.name.replace(/\.js$/, "").slice(1)+name.charAt(0).toUpperCase() + name.slice(1).replace(/s$/, "")]);
|
||||||
|
else
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
get commands() {
|
||||||
|
return this.getComponent("commands");
|
||||||
|
}
|
||||||
|
|
||||||
|
get events() {
|
||||||
|
return this.getComponent("events");
|
||||||
}
|
}
|
||||||
|
|
||||||
async load() {
|
async load() {
|
||||||
const commands = this.commands.map(cmd => new cmd(this));
|
await this.loadCommands();
|
||||||
await Promise.all(commands.map(cmd => cmd.load()));
|
await this.loadEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
async loadCommands() {
|
||||||
|
const commands: Command[] = [];
|
||||||
|
|
||||||
|
for (const command of this.commands) {
|
||||||
|
try {
|
||||||
|
const cmd: Command = new command(this);
|
||||||
|
await cmd.load();
|
||||||
|
commands.push(cmd);
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.err(`Fail to load command ${command}`);
|
||||||
|
this.logger.err(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.loadedCommands = this.loadedCommands.concat(commands);
|
this.loadedCommands = this.loadedCommands.concat(commands);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async loadEvents() {
|
||||||
|
const events: Event[] = [];
|
||||||
|
|
||||||
|
for (const event of this.events) {
|
||||||
|
try {
|
||||||
|
const env: Event = new event(this);
|
||||||
|
await env.load();
|
||||||
|
events.push(env);
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.err(`Fail to load event ${event}`);
|
||||||
|
this.logger.err(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loadedEvents = this.loadedEvents.concat(events);
|
||||||
|
}
|
||||||
|
|
||||||
async unload() {
|
async unload() {
|
||||||
await Promise.all(this.loadedCommands.map(cmd => cmd.unload()));
|
await Promise.all(this.loadedCommands.map(cmd => cmd.unload()));
|
||||||
this.loadedCommands = [];
|
this.loadedCommands = [];
|
||||||
|
await Promise.all(this.loadedEvents.map(cmd => cmd.unload()));
|
||||||
|
this.loadedEvents = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ export class Modules {
|
||||||
if (createCommand)
|
if (createCommand)
|
||||||
await this.registerCommand(module.loadedCommands.map(c => c.data));
|
await this.registerCommand(module.loadedCommands.map(c => c.data));
|
||||||
|
|
||||||
module.logger.info(`loaded`)
|
module.logger.info("loaded");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.client.logger.err(`Fail to load module ${name}`);
|
this.client.logger.err(`Fail to load module ${name}`);
|
||||||
this.client.logger.err(error);
|
this.client.logger.err(error);
|
||||||
|
|
36
src/modules/Music/events/VoiceStateUpdate.ts
Normal file
36
src/modules/Music/events/VoiceStateUpdate.ts
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
import {Event} from "../../../lib/Event";
|
||||||
|
import {VoiceState} from "discord.js";
|
||||||
|
import {Music} from "../index";
|
||||||
|
|
||||||
|
export class VoiceStateUpdateEvent extends Event {
|
||||||
|
module: Music;
|
||||||
|
private readonly callback;
|
||||||
|
|
||||||
|
constructor(module: Music) {
|
||||||
|
super(module);
|
||||||
|
this.module = module;
|
||||||
|
this.callback = async (oldState: VoiceState, newState: VoiceState) => {
|
||||||
|
const player = this.module.players.get(oldState.guild.id);
|
||||||
|
|
||||||
|
if (!player)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!oldState.channel || oldState.channelId != player.connexion.joinConfig.channelId || (newState.channelId == oldState.channelId))
|
||||||
|
return;
|
||||||
|
|
||||||
|
await oldState.channel.fetch(true);
|
||||||
|
if (oldState.channel.members.size == 1) {
|
||||||
|
player.disconnect();
|
||||||
|
this.module.players.delete(oldState.guild.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
load() {
|
||||||
|
this.module.modules.client.on("voiceStateUpdate", this.callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
unload() {
|
||||||
|
this.module.modules.client.removeListener("voiceStateUpdate", this.callback);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue