From 0b33ae63700c36980d00cbb0cd14ed60d4e365c2 Mon Sep 17 00:00:00 2001 From: BinarySandia04 Date: Sat, 19 Oct 2024 00:42:22 +0200 Subject: [PATCH] Posat mes coses i datagen --- backend/services/api.js | 98 ++++++++++++++----- client/src/views/HomeView.vue | 2 - plugins/dnd-5e/backend/main.js | 110 +++++++++++++--------- plugins/dnd-5e/client/views/ItemSheet.vue | 6 +- plugins/dnd-5e/datagen/datagen.json | 5 + plugins/dnd-5e/datagen/locales/en-US.json | 6 ++ plugins/dnd-5e/locales/en-US.json | 8 ++ plugins/dnd-5e/plugin.json | 15 ++- 8 files changed, 176 insertions(+), 74 deletions(-) create mode 100644 plugins/dnd-5e/datagen/datagen.json create mode 100644 plugins/dnd-5e/datagen/locales/en-US.json diff --git a/backend/services/api.js b/backend/services/api.js index a8e087c5..4a783fbb 100644 --- a/backend/services/api.js +++ b/backend/services/api.js @@ -56,8 +56,8 @@ class BackendApi { * image: { type: String } * }); */ - createModel(name, schema){ - return new BackendModel(name, this.#_plugin.package, schema); + createModel(name, schema, parentModels = undefined){ + return new BackendModel(name, this.#_plugin.package, schema, parentModels); } createModule(id){ @@ -109,21 +109,6 @@ class BackendRouter { delete(route, callback){ this.#_expressRouter.delete(this.#_root + route, callback); } - - /** - * Creates backend REST routes for the specified model. These routes are located - * relative to the plugin base route: - * - `//` (POST) - Creates the element - * - `//` (GET) - Gets a list with elements - * - `?id=` return the document with that id - * - `?=` returns all documents that match this criteria - * - `//` (UPDATE) - Updates a element by id - * - `//` (DELETE) - Deletes an element - * @param {BackendModel} model - */ - createModelRoutes(model, path){ - - } } class BackendModule { @@ -151,10 +136,63 @@ class BackendModule { // Creates a model for the Module // it also includes the campaign id for later on - createModel(name, schema){ + createModel(name, schema, parentModels = undefined){ return new BackendModel(name, `${this.#_plugin.package}/${this.#_id}`, {...{ campaign: { type: "ObjectId", ref: "Campaign"} - }, ...schema}); + }, ...schema}, parentModels); + } + + // scope => ['campaign'] + // coses que es necessiten verificar a tots els models + // i s'agafa de req.query + createModelRoutes(model, scope = []){ + this.router.get(`/${model.name}/list`, (req, res) => { + let query = {} + scope.forEach(k => query[k] = req.query[k]); + model.find(query).select('-data').lean().then(data => { + res.json({status: 'ok', data}); + }); + }); + + this.router.get(`/${model.name}/get`, (req, res) => { + let query = {} + scope.forEach(k => query[k] = req.query[k]); + query['_id'] = req.query.id; + model.findOne(query).lean().then(data => { + res.json({status: 'ok', data}); + }) + }); + + this.router.post(`/${model.name}/create`, (req, res) => { + let query = {} + scope.forEach(k => query[k] = req.query[k]); + model.create({...query, ...req.body.data}).then(data => { + this.socket.emit(query['campaign'], `update-${model.name}`); + res.json({status: "ok", data}); + }); + }); + + this.router.put(`/${model.name}/update`, (req, res) => { + let query = {} + scope.forEach(k => query[k] = req.query[k]); + query['_id'] = req.query.id; + model.findOneAndUpdate(query, req.body.data).then(data => { + if(req.query.fireUpdate) this.socket.emit(query['campaign'], `update-${model.name}-all`); + this.socket.emit(query['campaign'], `update-${model.name}`, req.query.id); + res.json({status: 'ok'}); + }) + }); + + this.router.delete(`/${model.name}/destroy`, (req, res) => { + let query = {} + scope.forEach(k => query[k] = req.query[k]); + query['_id'] = req.query.id; + model.deleteOne(query).then(data => { + if(req.query.fireUpdate) this.socket.emit(query['campaign'], `update-${model.name}-all`); + this.socket.emit(query['campaign'], `update-${model.name}`, req.query.id); + res.json({status: 'ok'}); + }); + }); } } @@ -168,11 +206,16 @@ class BackendModel { #_mongoSchema; - constructor(name, prefix, schema){ + constructor(name, prefix, schema, parentModels){ this.#_name = name; this.#_prefix = prefix; this.#_schema = ParseSchema(schema); - this.#_mongoSchema = mongoose.model(`${prefix}/${name}`, new Schema(schema)); + if(parentModels === undefined) { + this.#_mongoSchema = mongoose.model(`${prefix}/${name}`, new Schema(schema)); + } else { + parentModels.mongoSchema.discriminator(`${prefix}/${name}`, new Schema(schema)); + this.#_mongoSchema = mongoose.model(`${prefix}/${name}`); + } } /** @@ -234,6 +277,18 @@ class BackendModel { updateMany(params, data){ return this.#_mongoSchema.updateMany(params, data); } + + deleteOne(params){ + return this.#_mongoSchema.deleteOne(params); + } + + get name(){ + return this.#_name; + } + + get mongoSchema() { + return this.#_mongoSchema; + } }; class BackendSocket { @@ -262,6 +317,7 @@ function ParseSchema(schema){ ObjectId: mongoose.Types.ObjectId, Boolean: Boolean, Date: Date, + Number: Number }; let newSchema = structuredClone(schema); diff --git a/client/src/views/HomeView.vue b/client/src/views/HomeView.vue index 1703add6..7ec38f9b 100644 --- a/client/src/views/HomeView.vue +++ b/client/src/views/HomeView.vue @@ -29,8 +29,6 @@ SetEmitter(emitter); async function DisplayFirstWindow(){ if(GetUser()){ - - Server().get('/plugins/dnd-5e/_module/dnd-5e/testing').then(res => {}) CreateWindow('main_menu'); return; } diff --git a/plugins/dnd-5e/backend/main.js b/plugins/dnd-5e/backend/main.js index 378a7d9f..348fb9ef 100644 --- a/plugins/dnd-5e/backend/main.js +++ b/plugins/dnd-5e/backend/main.js @@ -16,55 +16,75 @@ function Main(api){ book: { type: "ObjectId", ref: "Book"} }); + let entityDataModel = Api.createModel('entitydata', { + name: { type: "String", required: true }, + hp: { type: "Number", required: true }, + max_hp: { type: "Number", required: true }, + effects: [ { type: "ObjectId", ref: "dnd-5e/effect" } ], + attributes: { type: "Object" }, // {str, dex, ...} + saving_attributes: {type: "Object"}, + skill_prof: { type: "Object" }, + initiative: { type: "Number" }, + speed: {type: "Number" }, + ac: {type: "Number"}, + proficency: { type: "Number" }, + size: {type: "String"}, + items: [ {type: "ObjectId", ref: 'dnd-5e/item'} ], + competences: {type: "Object"}, + resources: {type: "Object"}, + class: { type: "ObjectId", ref: "dnd-5e/progressable" }, + race: { type: "ObjectId", ref: "dnd-5e/progressable" }, + lvl: { type: "Number" }, + desc: { type: "String" }, + token: { type: "Object" } + }); + + let monsterModel = Api.createModel('monster', { + hp_formulae: { type: "String", required: true }, + cr: { type: "Number" }, + xp_drop: { type: "Number" } + }, entityDataModel); + + let actorModel = Api.createModel('actor', { + picture: { type: "String" }, + xp: { type: "Number", required: true }, + death_throws: { type: "Object" } + }, entityDataModel); + + let tableModel = Api.createModel('table', { + name: { type: "String", required: true }, + info: { type: "Object" } + }); + + let progressableModel = Api.createModel('progressable', { + name: { type: "String", required: true }, + type: { type: "String", required: true }, + icon: { type: "String", required: true }, + resources: { type: "Object" }, + tables: [ { type: "ObjectId", ref: "dnd-5e/table" } ], + rewards: { type: "Object" } + }); + + let effectsModel = Api.createModel('effect', { + name: { type: "String", required: true }, + icon: { type: "String", required: true }, + desc: { type: "String" } + }); + let entityModel = Api.createModel('entity', { - + data: { type: "ObjectId" }, + position: { type: "Object" } }); - let characterModel = Api.createModel('character', { + dndModule.createModelRoutes(itemModel); + dndModule.createModelRoutes(monsterModel); + dndModule.createModelRoutes(actorModel); + dndModule.createModelRoutes(tableModel); + dndModule.createModelRoutes(progressableModel); + dndModule.createModelRoutes(effectsModel); + dndModule.createModelRoutes(entityModel); - }); - - dndModule.router.get('/item/list', (req, res) => { - const campaign = req.query.campaign; - itemModel.find({campaign}).select('-data').lean().then(data => { - res.json({status: "ok", data}); - }); - }); - - dndModule.router.post('/item/create', (req, res) => { - const campaign = req.query.campaign; - let data = req.body.data; - - if(!(data.type && data.name)) { - res.json({status: "error", msg: "args"}); - return; - } - - itemModel.create({campaign, type: data.type, name: data.name, info: {}, data: {}}).then(item => { - dndModule.socket.emit(campaign, 'update-concepts'); - res.json({status: "ok", item}); - }); - }); - dndModule.router.get('/item/get', (req, res) => { - const campaign = req.query.campaign; - let id = req.query.id; - - itemModel.findOne({_id: id, campaign}).lean().then(concept => { - res.json({status: "ok", concept}); - }); - }) - dndModule.router.put('/item/update', (req, res) => { - const campaign = req.query.campaign; - let id = req.query.id; - - itemModel.findOneAndUpdate({_id: id, campaign}, req.body.concept).then(result => { - if(req.query.fireUpdate) dndModule.socket.emit(campaign, 'update-concepts'); - dndModule.socket.emit(campaign, 'update-concept', id); - res.json({status: "ok"}); - }); - }) - - Api.socket.on("test", () => console.log("test")); + // Api.socket.on("test", () => console.log("test")); // Api.router.createModelRoutes(itemModel, 'item'); } diff --git a/plugins/dnd-5e/client/views/ItemSheet.vue b/plugins/dnd-5e/client/views/ItemSheet.vue index 24fc2033..ee20152f 100644 --- a/plugins/dnd-5e/client/views/ItemSheet.vue +++ b/plugins/dnd-5e/client/views/ItemSheet.vue @@ -80,7 +80,7 @@ function Upload(){ oldInfo = structuredClone(concept.value.info); } - dndModule.router.put('/item/update', params, {concept: concept.value}).then(response => { + dndModule.router.put('/item/update', params, {data: concept.value}).then(response => { // console.log(response); }); } @@ -153,14 +153,14 @@ if(data.item_create){ name: "New " + data.item_type }, }).then(response => { - concept.value = response.data.concept; + concept.value = response.data.data; InitValues(); }).catch(err => console.log(err)); } else { // Get concept GetConcept(data.item_id).then(response => { - concept.value = response.data.concept; + concept.value = response.data.data; InitValues(); }).catch(err => console.log(err)); } diff --git a/plugins/dnd-5e/datagen/datagen.json b/plugins/dnd-5e/datagen/datagen.json new file mode 100644 index 00000000..6eadf575 --- /dev/null +++ b/plugins/dnd-5e/datagen/datagen.json @@ -0,0 +1,5 @@ +{ + "package": "dnd-5e", + "name": "info.name", + "desc": "info.description" +} \ No newline at end of file diff --git a/plugins/dnd-5e/datagen/locales/en-US.json b/plugins/dnd-5e/datagen/locales/en-US.json new file mode 100644 index 00000000..63310fd4 --- /dev/null +++ b/plugins/dnd-5e/datagen/locales/en-US.json @@ -0,0 +1,6 @@ +{ + "info": { + "name": "Dnd 5e Essential Books", + "description": "

This book contians all the essential data for playing a barebones Dnd 5e campaign. It includes:

  • The players manual
  • The dungeon master manual
  • The monsters manual
" + } +} \ No newline at end of file diff --git a/plugins/dnd-5e/locales/en-US.json b/plugins/dnd-5e/locales/en-US.json index 52117e54..4a08d597 100644 --- a/plugins/dnd-5e/locales/en-US.json +++ b/plugins/dnd-5e/locales/en-US.json @@ -1,4 +1,12 @@ { + "plugin": { + "name": "Dnd 5e System", + "desc": "This plugin provides the Dnd 5e module and the basic books for making a barebone campaign" + }, + "module": { + "name": "Dnd 5e", + "desc": "The official Dnd 5e system for Dragonroll" + }, "database": { "title": "Database", "tabs": { diff --git a/plugins/dnd-5e/plugin.json b/plugins/dnd-5e/plugin.json index cabb5f72..9c22c6de 100644 --- a/plugins/dnd-5e/plugin.json +++ b/plugins/dnd-5e/plugin.json @@ -1,7 +1,8 @@ { "package": "dnd-5e", - "name": "Dnd 5e System", - "description": "This plugin provides the Dnd 5e module", + "name": "plugin.name", + "description": "plugin.desc", + "icon": "icon.png", "authors": [ { "name": "Aran Roig" @@ -13,5 +14,13 @@ }, "backend": { "entrypoint": "main.js" - } + }, + "modules": [ + { + "id": "dnd-5e", + "name": "module.name", + "desc": "module.desc", + "icon": "icon.png" + } + ] } \ No newline at end of file