forked from noxious/server
POC working new caching method - moved controllers folder, renamed assets to textures, fixed HTTP bug, formatted code
This commit is contained in:
92
src/controllers/avatar.ts
Normal file
92
src/controllers/avatar.ts
Normal file
@ -0,0 +1,92 @@
|
||||
import fs from 'fs'
|
||||
|
||||
import { Request, Response } from 'express'
|
||||
import sharp from 'sharp'
|
||||
|
||||
import { BaseController } from '#application/base/baseController'
|
||||
import Storage from '#application/storage'
|
||||
import { UUID } from '#application/types'
|
||||
import CharacterHairRepository from '#repositories/characterHairRepository'
|
||||
import CharacterRepository from '#repositories/characterRepository'
|
||||
import CharacterTypeRepository from '#repositories/characterTypeRepository'
|
||||
|
||||
interface AvatarOptions {
|
||||
characterTypeId: UUID
|
||||
characterHairId?: UUID
|
||||
}
|
||||
|
||||
export class AvatarController extends BaseController {
|
||||
private readonly characterTypeRepository = new CharacterTypeRepository()
|
||||
private readonly characterHairRepository = new CharacterHairRepository()
|
||||
private readonly characterRepository = new CharacterRepository()
|
||||
|
||||
/**
|
||||
* Get avatar by character
|
||||
* @param req
|
||||
* @param res
|
||||
*/
|
||||
public async getByName(req: Request, res: Response) {
|
||||
const character = await this.characterRepository.getByName(req.params.characterName)
|
||||
if (!character?.characterType) {
|
||||
return this.sendError(res, 'Character or character type not found', 404)
|
||||
}
|
||||
|
||||
return this.generateAvatar(res, {
|
||||
characterTypeId: character.characterType.id,
|
||||
characterHairId: character.characterHair?.id
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Get avatar by character type and hair
|
||||
* @param req
|
||||
* @param res
|
||||
*/
|
||||
public async getByParams(req: Request, res: Response) {
|
||||
return this.generateAvatar(res, {
|
||||
characterTypeId: req.params.characterTypeId as UUID,
|
||||
characterHairId: req.params.characterHairId ? (req.params.characterHairId as UUID) : undefined
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate avatar
|
||||
* @param res
|
||||
* @param options
|
||||
* @private
|
||||
*/
|
||||
private async generateAvatar(res: Response, options: AvatarOptions) {
|
||||
try {
|
||||
const characterType = await this.characterTypeRepository.getById(options.characterTypeId)
|
||||
if (!characterType?.sprite?.id) {
|
||||
return this.sendError(res, 'Character type not found', 404)
|
||||
}
|
||||
|
||||
const bodySpritePath = Storage.getPublicPath('sprites', characterType.sprite.id, 'idle_right_down.png')
|
||||
if (!fs.existsSync(bodySpritePath)) {
|
||||
return this.sendError(res, 'Body sprite file not found', 404)
|
||||
}
|
||||
|
||||
let avatar = sharp(bodySpritePath).extend({
|
||||
top: 2,
|
||||
bottom: 2,
|
||||
background: { r: 0, g: 0, b: 0, alpha: 0 }
|
||||
})
|
||||
|
||||
if (options.characterHairId) {
|
||||
const characterHair = await this.characterHairRepository.getById(options.characterHairId)
|
||||
if (characterHair?.sprite?.id) {
|
||||
const hairSpritePath = Storage.getPublicPath('sprites', characterHair.sprite.id, 'front.png')
|
||||
if (fs.existsSync(hairSpritePath)) {
|
||||
avatar = avatar.composite([{ input: hairSpritePath, gravity: 'north' }])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res.setHeader('Content-Type', 'image/png')
|
||||
return avatar.pipe(res)
|
||||
} catch (error) {
|
||||
return this.sendError(res, 'Error generating avatar', 500)
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user