forked from noxious/server
Renamed command manager to console manager, improved log reading
This commit is contained in:
@ -1,107 +0,0 @@
|
||||
import * as fs from 'fs'
|
||||
import * as path from 'path'
|
||||
import * as readline from 'readline'
|
||||
|
||||
import { Server } from 'socket.io'
|
||||
|
||||
import Logger, { LoggerType } from '#application/logger'
|
||||
import { getAppPath } from '#application/storage'
|
||||
|
||||
class CommandManager {
|
||||
private logger = Logger.type(LoggerType.COMMAND)
|
||||
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
|
||||
})
|
||||
}
|
||||
|
||||
public async boot(io: Server) {
|
||||
this.io = io
|
||||
await this.loadCommands()
|
||||
this.logger.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 directory = getAppPath('commands')
|
||||
this.logger.info(`Loading commands from: ${directory}`)
|
||||
|
||||
try {
|
||||
const files = await fs.promises.readdir(directory, { withFileTypes: true })
|
||||
|
||||
for (const file of files) {
|
||||
if (!file.isFile() || (!file.name.endsWith('.ts') && !file.name.endsWith('.js'))) {
|
||||
continue
|
||||
}
|
||||
|
||||
const fullPath = getAppPath('commands', file.name)
|
||||
const commandName = path.basename(file.name, path.extname(file.name))
|
||||
|
||||
try {
|
||||
const module = await import(fullPath)
|
||||
if (typeof module.default !== 'function') {
|
||||
this.logger.warn(`Unrecognized export in ${file.name}`)
|
||||
continue
|
||||
}
|
||||
|
||||
this.registerCommand(commandName, module.default)
|
||||
} catch (error) {
|
||||
this.logger.error(`Error loading command ${file.name}: ${error instanceof Error ? error.message : String(error)}`)
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
this.logger.error(`Failed to read commands directory: ${error instanceof Error ? error.message : String(error)}`)
|
||||
}
|
||||
}
|
||||
|
||||
private registerCommand(name: string, CommandClass: any) {
|
||||
if (this.commands.has(name)) {
|
||||
this.logger.warn(`Command '${name}' is already registered. Overwriting...`)
|
||||
}
|
||||
this.commands.set(name, CommandClass)
|
||||
this.logger.info(`Registered command: ${name}`)
|
||||
}
|
||||
}
|
||||
|
||||
export default new CommandManager()
|
56
src/managers/consoleManager.ts
Normal file
56
src/managers/consoleManager.ts
Normal file
@ -0,0 +1,56 @@
|
||||
import { Server } from 'socket.io'
|
||||
import { CommandRegistry } from '#application/console/commandRegistry'
|
||||
import { ConsolePrompt } from '#application/console/consolePrompt'
|
||||
import { LogReader } from '#application/console/logReader'
|
||||
import Logger, { LoggerType } from '#application/logger'
|
||||
|
||||
export class ConsoleManager {
|
||||
private readonly logger = Logger.type(LoggerType.COMMAND)
|
||||
private readonly registry: CommandRegistry
|
||||
private readonly prompt: ConsolePrompt
|
||||
private readonly logReader: LogReader
|
||||
private io: Server | null = null
|
||||
|
||||
constructor() {
|
||||
this.registry = new CommandRegistry()
|
||||
this.prompt = new ConsolePrompt(
|
||||
(command: string) => this.processCommand(command)
|
||||
)
|
||||
|
||||
this.logReader = new LogReader(process.cwd())
|
||||
}
|
||||
|
||||
public async boot(io: Server): Promise<void> {
|
||||
this.io = io
|
||||
|
||||
await this.registry.loadCommands()
|
||||
this.logReader.start()
|
||||
this.prompt.start()
|
||||
|
||||
this.logger.info('Console manager loaded')
|
||||
}
|
||||
|
||||
private async processCommand(commandLine: string): Promise<void> {
|
||||
const [cmd, ...args] = commandLine.trim().split(' ')
|
||||
|
||||
if (cmd === 'exit') {
|
||||
this.prompt.close()
|
||||
return
|
||||
}
|
||||
|
||||
const CommandClass = this.registry.getCommand(cmd)
|
||||
if (!CommandClass) {
|
||||
console.error(`Unknown command: ${cmd}`)
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const commandInstance = new CommandClass(this.io as Server)
|
||||
await commandInstance.execute(args)
|
||||
} catch (error) {
|
||||
this.logger.error(`Error executing command ${cmd}: ${error instanceof Error ? error.message : String(error)}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default new ConsoleManager()
|
Reference in New Issue
Block a user