#169 : Re-enabled command manager, created extrudeTiles command for testing
This commit is contained in:
parent
ddeee356b4
commit
3a83f2c1ff
6
package-lock.json
generated
6
package-lock.json
generated
@ -982,9 +982,9 @@
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/bullmq": {
|
||||
"version": "5.13.2",
|
||||
"resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.13.2.tgz",
|
||||
"integrity": "sha512-McGE8k3mrCvdUHdU0sHkTKDS1xr4pff+hbEKBY51wk5S6Za0gkuejYA620VQTo3Zz37E/NVWMgumwiXPQ3yZcA==",
|
||||
"version": "5.14.0",
|
||||
"resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.14.0.tgz",
|
||||
"integrity": "sha512-qxZHtRuGEp0oHM1aNokuZ4gA0xr6vcZQPe1OLuQoDTuhaEXB4faxApUoo85v/PHnzrniAAqNT9kqD+UBbmECDQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cron-parser": "^4.6.0",
|
||||
|
136
src/commands/extrudeTiles.ts
Normal file
136
src/commands/extrudeTiles.ts
Normal file
@ -0,0 +1,136 @@
|
||||
import { Server } from 'socket.io'
|
||||
import ZoneManager from '../managers/zoneManager'
|
||||
import sharp from 'sharp'
|
||||
import path from 'path'
|
||||
import fs from 'fs'
|
||||
import { commandLogger } from '../utilities/logger'
|
||||
|
||||
type CommandInput = string[]
|
||||
|
||||
/**
|
||||
* Extrude tiles command
|
||||
* This command will get all the tiles inside process.cwd() > public > tiles
|
||||
* And overwrite the existing tiles.
|
||||
* @param input
|
||||
* @param io
|
||||
*/
|
||||
export default async function extrudeTiles(input: CommandInput, io: Server) {
|
||||
const [tileWidth, tileHeight, extrusion = '1', color = '0xffffff00'] = input
|
||||
|
||||
if (!tileWidth || !tileHeight) {
|
||||
console.log('Missing tileWidth or tileHeight! Usage: extrudeTiles <tileWidth> <tileHeight> [extrusion] [color]')
|
||||
return
|
||||
}
|
||||
|
||||
const options = {
|
||||
tileWidth: parseInt(tileWidth),
|
||||
tileHeight: parseInt(tileHeight),
|
||||
extrusion: parseInt(extrusion),
|
||||
color: parseInt(color, 16)
|
||||
}
|
||||
|
||||
const tilesDir = path.join(process.cwd(), 'public', 'tiles')
|
||||
const files = fs.readdirSync(tilesDir).filter(file => file.endsWith('.png'))
|
||||
|
||||
for (const file of files) {
|
||||
const inputPath = path.join(tilesDir, file)
|
||||
const outputPath = path.join(tilesDir, `${path.parse(file).name}.png`)
|
||||
|
||||
try {
|
||||
await extrudeTile(
|
||||
options.tileWidth,
|
||||
options.tileHeight,
|
||||
inputPath,
|
||||
outputPath,
|
||||
options.extrusion,
|
||||
options.color
|
||||
)
|
||||
commandLogger.info(`Extruded tile ${file}`)
|
||||
} catch (error: any) {
|
||||
console.log(error)
|
||||
commandLogger.error('Error extruding tile:', error.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function extrudeTile(
|
||||
tileWidth: number,
|
||||
tileHeight: number,
|
||||
inputPath: string,
|
||||
outputPath: string,
|
||||
extrusion: number,
|
||||
backgroundColor: number
|
||||
) {
|
||||
const borderWidth = 4; // You can adjust this value to change the border width
|
||||
|
||||
const image = sharp(inputPath)
|
||||
const metadata = await image.metadata()
|
||||
|
||||
if (!metadata.width || !metadata.height) {
|
||||
throw new Error('Unable to get image dimensions')
|
||||
}
|
||||
|
||||
const tilesX = Math.floor(metadata.width / tileWidth)
|
||||
const tilesY = Math.floor(metadata.height / tileHeight)
|
||||
|
||||
// Use borderWidth in the new dimensions calculation
|
||||
const newWidth = metadata.width + (tilesX + 1) * extrusion + tilesX * borderWidth * 2
|
||||
const newHeight = metadata.height + (tilesY + 1) * extrusion + tilesY * borderWidth * 2
|
||||
|
||||
const background = {
|
||||
r: (backgroundColor >> 24) & 0xff,
|
||||
g: (backgroundColor >> 16) & 0xff,
|
||||
b: (backgroundColor >> 8) & 0xff,
|
||||
alpha: backgroundColor & 0xff
|
||||
}
|
||||
|
||||
const newImage = sharp({
|
||||
create: {
|
||||
width: newWidth,
|
||||
height: newHeight,
|
||||
channels: 4,
|
||||
background
|
||||
}
|
||||
})
|
||||
|
||||
const compositeOperations = []
|
||||
|
||||
for (let y = 0; y < tilesY; y++) {
|
||||
for (let x = 0; x < tilesX; x++) {
|
||||
const tileBuffer = await image
|
||||
.extract({
|
||||
left: x * tileWidth,
|
||||
top: y * tileHeight,
|
||||
width: tileWidth,
|
||||
height: tileHeight
|
||||
})
|
||||
.extend({
|
||||
top: borderWidth,
|
||||
bottom: borderWidth,
|
||||
left: borderWidth,
|
||||
right: borderWidth,
|
||||
background: { r: 0, g: 0, b: 0, alpha: 0 }
|
||||
})
|
||||
.raw()
|
||||
.toBuffer()
|
||||
|
||||
compositeOperations.push({
|
||||
input: tileBuffer,
|
||||
// Use borderWidth in positioning calculation
|
||||
left: x * (tileWidth + extrusion + borderWidth * 2),
|
||||
top: y * (tileHeight + extrusion + borderWidth * 2),
|
||||
raw: {
|
||||
width: tileWidth + borderWidth * 2,
|
||||
height: tileHeight + borderWidth * 2,
|
||||
channels: 4
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
await newImage
|
||||
// @ts-ignore
|
||||
.composite(compositeOperations)
|
||||
.png()
|
||||
.toFile(outputPath)
|
||||
}
|
@ -2,6 +2,7 @@ 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'
|
||||
|
||||
class CommandManager {
|
||||
private commands: Map<string, Function> = new Map()
|
||||
@ -23,7 +24,7 @@ class CommandManager {
|
||||
public async boot(io: Server) {
|
||||
this.io = io
|
||||
await this.loadCommands()
|
||||
console.log('[✅] Command manager loaded')
|
||||
commandLogger.info('Command manager loaded')
|
||||
this.startPrompt()
|
||||
}
|
||||
|
||||
@ -48,7 +49,6 @@ class CommandManager {
|
||||
private handleUnknownCommand(command: string) {
|
||||
switch (command) {
|
||||
case 'exit':
|
||||
console.log('Goodbye!')
|
||||
this.rl.close()
|
||||
break
|
||||
default:
|
||||
@ -58,7 +58,7 @@ class CommandManager {
|
||||
}
|
||||
|
||||
private async loadCommands() {
|
||||
const commandsDir = path.resolve(__dirname, 'commands')
|
||||
const commandsDir = path.resolve(process.cwd(), 'src', 'commands')
|
||||
try {
|
||||
const files: string[] = await fs.promises.readdir(commandsDir)
|
||||
|
||||
@ -66,7 +66,7 @@ class CommandManager {
|
||||
await this.loadCommand(commandsDir, file)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[❌] Failed to read commands directory:', error)
|
||||
commandLogger.error(`Failed to read commands directory: ${error}`)
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,16 +79,16 @@ class CommandManager {
|
||||
|
||||
this.registerCommand(commandName, module.default)
|
||||
} catch (error) {
|
||||
console.error('[❌] Failed to load command:', file, error)
|
||||
commandLogger.error(`Failed to load command: ${file}: ${error}`)
|
||||
}
|
||||
}
|
||||
|
||||
private registerCommand(name: string, command: (args: string[], io: Server) => void) {
|
||||
if (this.commands.has(name)) {
|
||||
console.warn(`Command '${name}' is already registered. Overwriting...`)
|
||||
commandLogger.warn(`Command '${name}' is already registered. Overwriting...`)
|
||||
}
|
||||
this.commands.set(name, command)
|
||||
console.log(`Registered command: ${name}`)
|
||||
commandLogger.info(`Registered command: ${name}`)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,19 +1,19 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import express, { Application } from 'express'
|
||||
import config from './utilities/config'
|
||||
import { createServer as httpServer, Server as HTTPServer } from 'http'
|
||||
import { addHttpRoutes } from './utilities/http'
|
||||
import cors from 'cors'
|
||||
import { Server as SocketServer } from 'socket.io'
|
||||
import { TSocket } from './utilities/types'
|
||||
import config from './utilities/config'
|
||||
import prisma from './utilities/prisma'
|
||||
import ZoneManager from './managers/zoneManager'
|
||||
import UserManager from './managers/userManager'
|
||||
import { Authentication } from './middleware/authentication'
|
||||
// import CommandManager from './managers/CommandManager'
|
||||
import { TSocket } from './utilities/types'
|
||||
import prisma from './utilities/prisma'
|
||||
import { Dirent } from 'node:fs'
|
||||
import { appLogger, watchLogs } from './utilities/logger'
|
||||
import ZoneManager from './managers/zoneManager'
|
||||
import UserManager from './managers/userManager'
|
||||
import CommandManager from './managers/commandManager'
|
||||
import CharacterManager from './managers/characterManager'
|
||||
import QueueManager from './managers/queueManager'
|
||||
|
||||
@ -58,12 +58,12 @@ export class Server {
|
||||
appLogger.error(`Socket.IO failed to start: ${error.message}`)
|
||||
}
|
||||
|
||||
// Load queue manager
|
||||
await QueueManager.boot(this.io)
|
||||
|
||||
// Add http API routes
|
||||
await addHttpRoutes(this.app)
|
||||
|
||||
// Load queue manager
|
||||
await QueueManager.boot(this.io)
|
||||
|
||||
// Load user manager
|
||||
await UserManager.boot()
|
||||
|
||||
@ -73,8 +73,8 @@ export class Server {
|
||||
// Load character manager
|
||||
await CharacterManager.boot()
|
||||
|
||||
// Load command manager - Disabled for now
|
||||
// await CommandManager.boot(this.io);
|
||||
// Load command manager
|
||||
await CommandManager.boot(this.io);
|
||||
|
||||
// Listen for socket connections
|
||||
this.io.on('connection', this.handleConnection.bind(this))
|
||||
@ -106,15 +106,9 @@ export class Server {
|
||||
try {
|
||||
const module = await import(fullPath)
|
||||
if (typeof module.default === 'function') {
|
||||
if (module.default.prototype && module.default.prototype.listen) {
|
||||
// This is a class-based event
|
||||
const EventClass = module.default
|
||||
const eventInstance = new EventClass(this.io, socket)
|
||||
eventInstance.listen()
|
||||
} else {
|
||||
// This is a function-based event
|
||||
module.default(this.io, socket)
|
||||
}
|
||||
const EventClass = module.default
|
||||
const eventInstance = new EventClass(this.io, socket)
|
||||
eventInstance.listen()
|
||||
} else {
|
||||
appLogger.warn(`Unrecognized export in ${file.name}`)
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
// Array of log types
|
||||
const LOG_TYPES = ['http', 'game', 'gameMaster', 'app', 'queue'] as const
|
||||
const LOG_TYPES = ['http', 'game', 'gameMaster', 'app', 'queue', 'command'] as const
|
||||
type LogType = (typeof LOG_TYPES)[number]
|
||||
|
||||
const createLogger = (name: LogType) =>
|
||||
@ -43,6 +43,13 @@ const watchLogs = () => {
|
||||
})
|
||||
}
|
||||
|
||||
export const { http: httpLogger, game: gameLogger, gameMaster: gameMasterLogger, app: appLogger, queue: queueLogger } = loggers
|
||||
export const {
|
||||
http: httpLogger,
|
||||
game: gameLogger,
|
||||
gameMaster: gameMasterLogger,
|
||||
app: appLogger,
|
||||
queue: queueLogger,
|
||||
command: commandLogger
|
||||
} = loggers
|
||||
|
||||
export { watchLogs }
|
||||
|
Loading…
x
Reference in New Issue
Block a user