server/src/managers/commandManager.ts
2024-09-30 23:31:00 +02:00

107 lines
3.0 KiB
TypeScript

import * as readline from 'readline'
import * as fs from 'fs'
import * as path from 'path'
import { Server } from 'socket.io'
import { commandLogger } from '../utilities/logger'
import config from '../utilities/config'
class CommandManager {
private commands: Map<string, any> = new Map()
private rl: readline.Interface
private io: Server | null = null
private rlClosed: boolean = false
constructor() {
this.rl = readline.createInterface({
input: process.stdin,
output: process.stdout
})
this.rl.on('close', () => {
this.rlClosed = true
})
console.log(process.cwd())
}
public async boot(io: Server) {
this.io = io
await this.loadCommands()
commandLogger.info('Command manager loaded')
this.startPrompt()
}
private startPrompt() {
if (this.rlClosed) return
this.rl.question('> ', (command: string) => {
this.processCommand(command)
this.startPrompt()
})
}
private async processCommand(command: string): Promise<void> {
const [cmd, ...args] = command.trim().split(' ')
if (this.commands.has(cmd)) {
const CommandClass = this.commands.get(cmd)
const commandInstance = new CommandClass(this.io as Server)
await commandInstance.execute(args)
} else {
this.handleUnknownCommand(cmd)
}
}
private handleUnknownCommand(command: string) {
switch (command) {
case 'exit':
this.rl.close()
break
default:
console.error(`Unknown command: ${command}`)
break
}
}
private async loadCommands() {
const commandsDir = path.join(process.cwd(), 'commands');
commandLogger.info(`Loading commands from: ${commandsDir}`);
try {
const files = await fs.promises.readdir(commandsDir, { withFileTypes: true });
for (const file of files) {
if (!file.isFile() || (!file.name.endsWith('.ts') && !file.name.endsWith('.js'))) {
continue;
}
const fullPath = path.join(commandsDir, file.name);
const commandName = path.basename(file.name, path.extname(file.name));
try {
const module = await import(fullPath);
if (typeof module.default !== 'function') {
commandLogger.warn(`Unrecognized export in ${file.name}`);
continue;
}
this.registerCommand(commandName, module.default);
} catch (error) {
commandLogger.error(`Error loading command ${file.name}: ${error instanceof Error ? error.message : String(error)}`);
}
}
} catch (error) {
commandLogger.error(`Failed to read commands directory: ${error instanceof Error ? error.message : String(error)}`);
}
}
private registerCommand(name: string, CommandClass: any) {
if (this.commands.has(name)) {
commandLogger.warn(`Command '${name}' is already registered. Overwriting...`)
}
this.commands.set(name, CommandClass)
commandLogger.info(`Registered command: ${name}`)
}
}
export default new CommandManager()