gameobject module dev
This commit is contained in:
+23
-1
@@ -3,10 +3,13 @@ import { ObjectId, MongoClient } from 'mongodb';
|
||||
let db;
|
||||
let dbo;
|
||||
|
||||
/**
|
||||
* Manages database operations
|
||||
*/
|
||||
class Db {
|
||||
name = 'db';
|
||||
init(app){
|
||||
this.app = app;
|
||||
|
||||
}
|
||||
|
||||
async start(app){
|
||||
@@ -23,6 +26,12 @@ class Db {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a record in a db collection
|
||||
* @param {string} collection The name of the collection
|
||||
* @param {Object} value The object to insert
|
||||
* @returns Inserted Id
|
||||
*/
|
||||
async create(collection, value){
|
||||
try {
|
||||
delete value._id;
|
||||
@@ -31,6 +40,13 @@ class Db {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a record from db collection
|
||||
* @param {string} collection The name of the collection
|
||||
* @param {Object} key Record identifier
|
||||
* @param {Object} projection What data to take from the object
|
||||
* @returns A record
|
||||
*/
|
||||
async get(collection, key, projection){
|
||||
try {
|
||||
let res = await dbo.collection(collection).findOne(key, projection ? {projection} : undefined)
|
||||
@@ -39,6 +55,12 @@ class Db {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a database query
|
||||
* @param {string} collection Collection name
|
||||
* @param {Object} query A mongo db query
|
||||
* @returns Array of records
|
||||
*/
|
||||
async list(collection, query){
|
||||
try {
|
||||
let cursor = dbo.collection(collection).find(query.query, query.project ? {projection: query.project} : undefined);
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
import decompress from "decompress";
|
||||
import sharp from 'sharp';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
const collection = 'assets';
|
||||
|
||||
/**
|
||||
* Application layer manager
|
||||
*/
|
||||
class GameObjectsManager{
|
||||
name = 'gameObject';
|
||||
|
||||
/**
|
||||
* Plugin initializer
|
||||
* @param {App} app The Application
|
||||
*/
|
||||
init(app){
|
||||
const {db, config} = app;
|
||||
|
||||
/**
|
||||
* Gets last asset Id from database
|
||||
* @returns {Number} Last Asset Id
|
||||
*/
|
||||
this.getLastId = async function(){
|
||||
let ag = await db.aggregate(collection, [
|
||||
{
|
||||
$group:{
|
||||
_id: null,
|
||||
max: {
|
||||
$max: "$id",
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
return ag.max || 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a game object
|
||||
* @param {Context} ctx Request context
|
||||
* @param {GameObject} data Asset data
|
||||
*/
|
||||
this.create = async function(ctx, data){
|
||||
data.id = (await this.getLastId()) + 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';
|
||||
}else{
|
||||
object.asset.type = 'single';
|
||||
await fs.promises.copyFile(src, def + 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
|
||||
*/
|
||||
class GameObject {
|
||||
/**
|
||||
* Game object name
|
||||
* @type string
|
||||
*/
|
||||
name = null;
|
||||
|
||||
type = null;
|
||||
|
||||
|
||||
file = null;
|
||||
}
|
||||
|
||||
export { GameObjectsManager }
|
||||
@@ -0,0 +1,27 @@
|
||||
import express from 'express';
|
||||
|
||||
class AssetController{
|
||||
|
||||
name = 'assetController'
|
||||
route = '/asset'
|
||||
|
||||
init(app){
|
||||
const router = express.Router();
|
||||
const {config} = app;
|
||||
|
||||
router.get('/:where/:id(*)', async (req, res)=>{
|
||||
res.sendFile(config.fs.repo + req.params.where + '/' + req.params.id, (err)=>{
|
||||
if (err){
|
||||
console.error('Error retreiving file', req.params, err.code, err.message);
|
||||
if (req.params.where == 'thumb'){
|
||||
res.redirect(302, '/empty.png');
|
||||
}else res.status(404).end();
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
app.webServer.xapp.use(this.route, router);
|
||||
}
|
||||
}
|
||||
|
||||
export {AssetController}
|
||||
@@ -1,25 +0,0 @@
|
||||
import express from 'express';
|
||||
import fs from 'fs';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import multipart from 'connect-multiparty';
|
||||
|
||||
const multipartMiddleware = multipart();
|
||||
class GameObjectsApi{
|
||||
|
||||
name = 'gameObjectsApi'
|
||||
route = '/api/game-object'
|
||||
|
||||
init(app){
|
||||
const { am, config } = app;
|
||||
const router = express.Router();
|
||||
router.put('/', multipartMiddleware, async (req, res)=>{
|
||||
try{
|
||||
}catch(err){
|
||||
}
|
||||
});
|
||||
|
||||
app.webServer.xapp.use(this.route, router);
|
||||
}
|
||||
}
|
||||
|
||||
export {GameObjectsApi}
|
||||
@@ -0,0 +1,49 @@
|
||||
import express from 'express';
|
||||
import multipart from 'connect-multiparty';
|
||||
|
||||
const multipartMiddleware = multipart();
|
||||
class GameObjectsController{
|
||||
|
||||
name = 'gameObjectsApi'
|
||||
route = '/api/game-object'
|
||||
|
||||
init(app){
|
||||
const { gameObject } = app;
|
||||
const router = express.Router();
|
||||
|
||||
/**
|
||||
* Create & update
|
||||
*/
|
||||
router.put('/', multipartMiddleware, async (req, res)=>{
|
||||
try{
|
||||
let data = req.body;
|
||||
let object = await gameObject[data.id? 'update' : 'create'](req, data)
|
||||
res.json({status: 'OK', object});
|
||||
}catch(err){
|
||||
console.error(err);
|
||||
res.status(500).json({status: 'ERR', err});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* List
|
||||
*/
|
||||
router.post('/', async (req, res)=>{
|
||||
let result = await gameObject.list(req.body);
|
||||
res.json(result);
|
||||
})
|
||||
|
||||
router.get('/', async (req, res)=>{
|
||||
|
||||
})
|
||||
|
||||
router.get('/:id', async (req, res)=>{
|
||||
let object = await gameObject.read(parseInt(req.params.id));
|
||||
res.json(object);
|
||||
})
|
||||
|
||||
app.webServer.xapp.use(this.route, router);
|
||||
}
|
||||
}
|
||||
|
||||
export {GameObjectsController}
|
||||
+3
-1
@@ -11,8 +11,10 @@ import App from './app/App.js';
|
||||
const modules = [
|
||||
{name:'Config', path:'app/Config.js'},
|
||||
{name:'Db', path:'app/Db.js'},
|
||||
{name:'GameObjectsManager', path:'app/bl/GameObjectsManager.js'},
|
||||
{name:'WebServer', path:'app/WebServer.js'},
|
||||
{name:'GameObjectsApi', path:'controllers/api/GameObjects.js'},
|
||||
{name: 'AssetController', path: 'controllers/AssetController.js'},
|
||||
{name:'GameObjectsController', path:'controllers/api/GameObjectsController.js'},
|
||||
]
|
||||
|
||||
process.on('uncaughtException', err => {
|
||||
|
||||
Reference in New Issue
Block a user