Files
pronature-platform/backend/app/bl/GameObjectsManager.js
T
2025-03-15 11:23:55 +02:00

165 lines
6.4 KiB
JavaScript

import decompress from "decompress";
import sharp from 'sharp';
sharp.cache({ files : 0 });
import fs from 'fs';
import path from 'path';
const collection = 'assets';
/**
* Game objects manager, контролен клас за управление на игрови обекти
*/
class GameObjectsManager{
name = 'gameObject';
/**
* Plugin initializer, инициализация на плъгин
* @param {App} app The Application, обект приложение
*/
init(app){
const {db, config} = app;
/**
* Creates a game object, създаване на игрови обект
* @param {Context} ctx Request context, контекст на заявката
* @param {GameObject} data Asset data, данни за игровия обект
*/
this.create = async function(ctx, data){
data.id = (await db.getLastId(collection)) + 1;
await db.create(collection, data);
if (ctx.files?.file){
await this.addFile(data, ctx.files.file)
await fs.promises.unlink(ctx.files.file.path)
await db.update(collection, {id: data.id}, data);
}
return data;
}
/**
* Retrieves game object from database, прочитане на обект от базата от данни
* @param {Number} id Game object ID, идентификатор на обекта
* @returns {GameObject} The game object, игрови обект
*/
this.read = async function(id){
id = parseInt(id);
return await db.get(collection, {id});
}
/**
* Updates game object into the database, обновяване на игрови обект
* @param {Context} ctx Request context, контекст на заявката
* @param {GameObject} data Game object, данни за игровия обект
*/
this.update = async function(ctx, data){
data.id = parseInt(data.id);
let object = await this.read(data.id);
data = Object.assign(object, data);
if (ctx.files?.file){
await this.addFile(data, ctx.files.file)
await fs.promises.unlink(ctx.files.file.path)
}if (ctx.files?.thumb){
await this.addThumb(data, ctx.files.thumb.path);
await fs.promises.unlink(ctx.files.thumb.path)
}
await db.update(collection, {id: data.id}, data);
return data;
}
/**
* Removes game object from database, изтриване на игрови обект от базата от данни
* @param {Number} id Game object ID, идентификатор на игровия обект
*/
this.remove = async function(id){
id = parseInt(id);
await db.remove(collection, {id});
}
/**
* Assigns a file to a game object, закачване на файл към игрови обект
* @param {GameObject} object Game object, игрови обект
* @param {File} tmpFile A file, файл
*/
this.addFile = async function(object, tmpFile){
let i = tmpFile;
let ofn = i.name;
let ext = path.extname(ofn).toLowerCase();
let src = `${config.fs.repo}/source/${object.id}${ext}`;
let def = `${config.fs.repo}/default/${object.id}`;
await fs.promises.copyFile(i.path, src);
object.asset = {
ofn,
name: `${object.id}${ext}`
}
if (ext == '.zip'){
let result = await decompress(src, def);
object.asset.list = result.map(f=>f.path);
object.asset.type = 'bundle';
object.asset.name = `${object.id}/` + result.find(f=>f.path.endsWith('.gltf'))?.path;
}else{
object.asset.type = 'single';
await fs.promises.copyFile(src, def + ext);
if (['.jpg', '.png', '.webp'].includes(ext)){
await this.addThumb(object, src);
}
}
}
/**
* Assigns a thumbnail to a game object, закачане на представително изображение към игрови обект
* @param {GameObject} object Game object, игрови обект
* @param {File} thumbSrc A thumbnail, представително изображение
*/
this.addThumb = async function(object, thumbSrc){
let dest = `${config.fs.repo}/thumb/${object.id}.webp`;
await sharp(thumbSrc).resize({height: 250}).toFile(dest);
object.asset.thumb = `${object.id}.webp`;
}
/**
* Returns list of GameObjects, търсене в игровите обекти по зададени критерии
* @param {Object} query Query to DB, критерии - заявка към базата от данни
* @returns {GameObject[]} Array of game objects, масив от игрови обекти
*/
this.list = async function(query = {}){
return await db.list(collection, {
query,
project: { name:1, id:1, type:1, asset:1}
});
}
}
/**
* Class starter, стартиране на класа
* @param {App} app The application, базова апликация
*/
async start(app){
}
}
/**
* GameObject entity, can be: panorama picture, 3d environment, 3d object, 2d object (picture), a player (3d), audio or video asset
* Игрови обект, може да бъде панорамна снимка, триизмерна среда, обект или играч, двуизмерен обект, аудио или видео актив
*/
class GameObject {
/**
* Game object name, име на игровия обект
* @type string
*/
name = null;
/**
* Game object type, тип на игровия обект
* @type string
*/
type = null;
/**
* Associated file, асоцииран файл
* @type File
*/
file = null;
}
export { GameObjectsManager }