Realtime sync

This commit is contained in:
BinarySandia04 2024-09-14 02:10:05 +02:00
parent f22be8d6f2
commit 5a5fa05667
20 changed files with 424 additions and 276 deletions

View File

@ -5,11 +5,6 @@
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.css" />
<script src="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.css" integrity="sha384-GvrOXuhMATgEsSwCs4smul74iXGOixntILdUW9XmUC6+HX0sLNAK3q71HotJqlAn" crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js" integrity="sha384-XjKyOOlGwcjNTAIQHIpgOno0Hl1YQqzUOEleOLALmuqehneUG+vnGctmUb0ZY0l8" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js" integrity="sha384-+VBxd3r6XgURycqtZ117nYw44OOcIax56Z4dCRWbxyPt0Koah1uHoK0o4+/RRE05" crossorigin="anonymous"></script>
<title>Dragonroll</title>
</head>
<body>

View File

@ -88,6 +88,7 @@
--chat-background: var(--c-white);
--color-border: var(--c-white-border);
--color-border-soft: #a5a5a511;
--section-gap: 160px;
--separator-color: #2e2e2e;

View File

@ -12,7 +12,6 @@ import VueMarkdownEditor from '@kangc/v-md-editor';
import '@kangc/v-md-editor/lib/style/base-editor.css';
import vuepressTheme from '@kangc/v-md-editor/lib/theme/vuepress.js';
import '@kangc/v-md-editor/lib/theme/style/vuepress.css';
import createKatexPlugin from '@kangc/v-md-editor/lib/plugins/katex/cdn';
import esEs from '@kangc/v-md-editor/lib/lang/es-ES'
@ -29,7 +28,6 @@ import 'prismjs/components/prism-bash';
VueMarkdownEditor.lang.use('es-Es', esEs);
VueMarkdownEditor.use(vuepressTheme, { Prism });
VueMarkdownEditor.use(createKatexPlugin());
const app = createApp(App).use(VueMarkdownEditor);
app.config.globalProperties.emitter = emitter

View File

@ -20,7 +20,7 @@ function DisplayToast(color, text, duration = 1000){
emitter.emit("toast", {color, text, duration});
}
export const socket = io(backendUrl)
const socket = io(backendUrl)
let currentCampaign = null;
let currentPlayer = null;
@ -115,6 +115,7 @@ function GetSystem(){
}
export {
socket,
SetEmitter,
GetEmitter,

View File

@ -243,7 +243,6 @@ function SetupHandle(id, handle){
function SetResizable(id, resizable){
let win = GetWindowWithId(id);
console.log(win);
win.resizable = resizable;
}

View File

@ -11,7 +11,6 @@ import EditProfileWindow from '@/views/windows/EditProfileWindow.vue'
import AccountSettingsWindow from '../windows/AccountSettingsWindow.vue'
import { Windows, ReloadRef } from '@/services/Windows';
import DbWindow from '../windows/database/DbWindow.vue'
import CampaignListWindow from '../windows/campaigns/CampaignListWindow.vue'
import NewCampaignWindow from '../windows/campaigns/NewCampaignWindow.vue'
import JoinCampaignWindow from '../windows/campaigns/JoinCampaignWindow.vue'
@ -73,12 +72,9 @@ async function InjectSystemWindows(system){
};
WindowMap = {...WindowMap, ...systemWidows};
console.log(WindowMap)
}
InjectSystemWindows('dnd-5e')
console.log(WindowMap);
</script>
<template>

View File

@ -0,0 +1,66 @@
<script setup>
import { onMounted, ref, watch } from 'vue';
import { GetCampaign } from '../../services/Dragonroll';
import { ClearWindow, CreateWindow } from '../../services/Windows';
const props = defineProps(['elements']);
const listContainer = ref(null);
const elements = ref([]);
onMounted(() => {
watch(() => props.elements, () => {
elements.value = props.elements;
});
});
function OpenConcept(element){
CreateWindow('item_sheet', {
id: 'item_sheet',
title: 'Edit Item',
item_id: element._id,
close: () => ClearWindow('item_sheet')
});
}
</script>
<template>
<div class="list-container" ref="listContainer">
<div class="list-element" v-for="element in elements" :key="element._id" v-on:click.prevent="OpenConcept(element)">
<img :src="element.info ? element.info.icon : 'icons/game-icons/ffffff/lorc/crossed-swords.svg'" class="concept-icon">
<span class="title">{{ element.name }}</span>
</div>
</div>
</template>
<style lang="scss" scoped>
.concept-icon {
width: 36px;
height: 36px;
border: 1px solid var(--color-border);
}
.list-element {
display: flex;
width: 100%;
padding: 10px;
align-items: center;
border-bottom: 1px solid var(--color-border-soft);
.title {
padding-left: 10px;
font-size: 16px;
font-weight: bold;
}
}
.list-container {
display: flex;
flex-direction: column;
width: 100%;
overflow-y: auto;
}
</style>

View File

@ -4,18 +4,19 @@ import { onMounted, ref, getCurrentInstance, defineExpose } from 'vue';
import { ClearWindow, CreateChildWindow } from '../../services/Windows';
const image = ref(null);
const props = defineProps(['window']);
const props = defineProps(['window', 'done']);
const uuid = getCurrentInstance().uid;
const icon = ref(null);
const icon = ref('icons/game-icons/ffffff/lorc/crossed-swords.svg');
const done = props.done;
function SelectIcon(){
CreateChildWindow(props.window, 'icon_selector', {
id: 'icon-selector-' + uuid,
done: (res) => {
icon.value = res;
console.log(res);
image.value.src = res.selected.path;
icon.value = res.selected.path;
done(res);
ClearWindow('icon-selector-' + uuid);
},
close: () => {
@ -33,7 +34,7 @@ defineExpose({
<template>
<div class="icon-selector">
<img ref="image" src="icons/sundries/books/book-red-exclamation.webp" v-on:click.prevent="SelectIcon">
<img ref="image" :src="icon" v-on:click.prevent="SelectIcon">
</div>
</template>

View File

@ -1,58 +0,0 @@
<script setup>
import { onMounted, onUpdated, ref } from 'vue';
import { SetupHandle, SetSize, SetPosition, ResetPosition } from '@/services/Windows';
import WindowHandle from '@/views/partials/WindowHandle.vue';
const handle = ref(null);
const props = defineProps(['data']);
const data = props.data;
let id = data.id;
onMounted(() => {
SetupHandle(id, handle);
SetSize(id, {width: 500, height: 380});
ResetPosition(id, "center");
});
</script>
<template>
<div class="window-wrapper" :id="'window-wrapper-' + id">
<WindowHandle :window="id" ref="handle"></WindowHandle>
<!-- Body -->
</div>
</template>
<style scoped>
.window-wrapper {
min-width: 700px;
min-height: 630px;
display: flex;
align-items: center;
}
.splash-image {
width: 600px;
height: 250px;
}
.form-field {
padding: 10px;
display: flex;
align-items: left;
flex-direction: column;
justify-content: left;
width: 600px;
}
label {
text-align: left;
}
</style>

View File

@ -1,9 +1,12 @@
<script setup>
import WindowHandle from '@/views/partials/WindowHandle.vue';
import Api from '@/services/Api'
import { onMounted, ref } from 'vue';
import { ClearWindow, CreateWindow, ResetPosition, SetSize, SetupHandle } from '../../../services/Windows';
import { onMounted, ref, shallowRef } from 'vue';
import { ClearWindow, CreateWindow, ResetPosition, SetMinSize, SetResizable, SetSize, SetupHandle } from '../../../services/Windows';
import IconButton from '@/views/partials/game/IconButton.vue'
import ConceptList from '../../partials/ConceptList.vue';
import { GetCampaign, socket } from '../../../services/Dragonroll';
const handle = ref(null);
@ -11,13 +14,35 @@ const props = defineProps(['data']);
const data = props.data;
let id = data.id;
const elements = shallowRef([]);
// SHOULD MOVE!!!
onMounted(() => {
SetupHandle(id, handle);
SetSize(id, {width: 700, height: 800});
ResetPosition(id, "center");
SetResizable(id, true);
SetMinSize(id, {width: 350, height: 300});
FetchConcepts();
socket.on('update-concepts', () => {
console.log("!!!");
FetchConcepts();
});
});
function FetchConcepts(){
Api().get('/concept/list?campaign=' + GetCampaign()._id).then(response => {
// console.log(response.data);
elements.value = response.data.data;
console.log(elements);
console.log("Updated???")
}).catch((err) => console.log(err));
}
function OpenCreateItemPrompt(){
CreateWindow('create_item_prompt', {id: 'create_item_prompt', title: 'Create Item', close: () => ClearWindow('create_item_prompt')})
}
@ -34,8 +59,10 @@ function OpenCreateItemPrompt(){
<div class="toggler">Spells</div>
<div class="toggler">Features</div>
</div>
<ConceptList :elements="elements"></ConceptList>
</div>
<div class="fixed-bottom-buttons">
<IconButton icon="icons/iconoir/regular/plus.svg" :action="OpenCreateItemPrompt"></IconButton>
</div>
@ -44,6 +71,10 @@ function OpenCreateItemPrompt(){
<style scoped>
.main-container {
height: calc(100% - 24px);
}
.toggler {
flex-grow: 1;
font-weight: bold;

View File

@ -27,6 +27,7 @@ function ConfirmSelection(){
id: 'item_sheet',
title: 'Edit Item',
item_type: value,
item_create: true,
close: () => ClearWindow('item_sheet')
});

View File

@ -1,79 +1,91 @@
<script setup>
import WindowHandle from '@/views/partials/WindowHandle.vue';
import Api from '@/services/Api'
import { onMounted, ref } from 'vue';
import { onMounted, ref, shallowRef } from 'vue';
import { SetupHandle, SetSize, ResetPosition } from '@/services/Windows';
import { CreateWindow } from '../../../../services/Windows';
import IconSelector from '../../../partials/IconSelector.vue';
import { AddContextMenu, HideContextMenu, ShowContextMenu } from '../../../../services/ContextMenu';
import { GetCampaign } from '../../../../services/Dragonroll';
const props = defineProps(['data']);
const data = props.data;
const handle = ref(null);
const item_type = ref("");
const rarity = ref(null);
const weaponType = ref(null);
const item_name = ref(null);
const icon_selector = ref(null);
function GenRarities(){
let rarities = [];
let raritiesNames = ['', 'Common', 'Uncommon', 'Rare', 'Very Rare', 'Legendary', 'Artifact'];
raritiesNames.forEach(name => {
let lowerName = name.replace(/\s+/g, '-').toLowerCase();
rarities.push({
name: `<span class='${lowerName}'>${name}</span>`,
action: () => {
rarity.value.innerHTML = `<span class='important ${lowerName}'>${name}</span>`;
HideContextMenu();
SetParam('rarity', name);
}
})
});
return rarities;
}
function GenTypes(list){
let types = [];
list.forEach(name => {
types.push({
name,
action: () => {
weaponType.value.innerHTML = `<span class="important">${name}</span>`;
HideContextMenu();
SetParam('weapon_type', name);
}
});
});
return types;
}
let id = data.id;
let concept = shallowRef({});
let oldInfo;
onMounted(() => {
SetupHandle(id, handle);
SetSize(id, {width: 500, height: 400});
ResetPosition(id, "center");
item_type.value = data.item_type;
const rarities = [
{name: "",
action: () => { rarity.value.innerHTML = ""; HideContextMenu(); }
},
{name: "<span class='common'>Common</span>",
action: () => { rarity.value.innerHTML = "<span class='important common'>Common</span>"; HideContextMenu(); }
},
{name: "<span class='uncommon'>Uncommon</span>",
action: () => { rarity.value.innerHTML = "<span class='important uncommon'>Uncommon</span>"; HideContextMenu(); }
},
{name: "<span class='rare'>Rare</span>",
action: () => { rarity.value.innerHTML = "<span class='important rare'>Rare</span>"; HideContextMenu(); }
},
{name: "<span class='very-rare'>Very rare</span>",
action: () => { rarity.value.innerHTML = "<span class='important very-rare'>Very rare</span>"; HideContextMenu(); }
},
{name: "<span class='legendary'>Legendary</span>",
action: () => { rarity.value.innerHTML = "<span class='important legendary'>Legendary</span>"; HideContextMenu(); }
},
{name: "<span class='artifact'>Artifact</span>",
action: () => { rarity.value.innerHTML = "<span class='important artifact'>Artifact</span>"; HideContextMenu(); }
function Upload(){
let extraParams = "";
if(oldInfo != concept.value.info){
extraParams = "&fireUpdate=true";
oldInfo = structuredClone(concept.value.info);
console.log("MAIASIUDHSAHJ")
}
]
Api().put('/concept/update?campaign=' + GetCampaign()._id + "&id=" + concept.value._id + extraParams, {concept: concept.value}).then(response => {
console.log(response);
});
}
const weapon_types = [
{name: "",
action: () => { weaponType.value.innerHTML = ""; HideContextMenu(); }
},
{name: "Melee",
action: () => { weaponType.value.innerHTML = "<span class='important'>Melee</span>"; HideContextMenu(); }
},
{name: "Ranged",
action: () => { weaponType.value.innerHTML = "<span class='important'>Ranged</span>"; HideContextMenu(); }
},
{name: "Martial Melee",
action: () => { weaponType.value.innerHTML = "<span class='important'>Martial Melee</span>"; HideContextMenu(); }
},
{name: "Martial Ranged",
action: () => { weaponType.value.innerHTML = "<span class='important'>Martial Ranged</span>"; HideContextMenu(); }
},
{name: "Natural",
action: () => { weaponType.value.innerHTML = "<span class='important'>Natural</span>"; HideContextMenu(); }
},
{name: "Improvised",
action: () => { weaponType.value.innerHTML = "<span class='important'>Improvised</span>"; HideContextMenu(); }
},
{name: "Siege Weapon",
action: () => { weaponType.value.innerHTML = "<span class='important'>Siege Weapon</span>"; HideContextMenu(); }
}
]
function SetParam(param, value){
concept.value.info[param] = value;
Upload();
}
function IconSelected(val){
SetParam('icon', val.selected.path);
Upload();
}
function InitValues(){
let rarities = GenRarities();
let weapon_types = GenTypes(["", "Melee", "Ranged", "Martial Melee", "Martial Ranged", "Natural", "Improvised", "Siege Weapon"]);
if(!concept.value.data) concept.value.data = {};
if(!concept.value.info) concept.value.info = {};
if(concept.value.info.icon) icon_selector.value.icon = concept.value.info.icon;
if(concept.value.info.rarity) rarity.value.innerHTML = `<span class='important ${concept.value.info.rarity.replace(/\s+/g, '-').toLowerCase()}'>${concept.value.info.rarity}</span>`;
if(concept.value.info.weapon_type) weaponType.value.innerHTML = `<span class='important'>${concept.value.info.weapon_type}</span>`;
rarity.value.addEventListener("click", () => {
ShowContextMenu(rarities)
@ -83,11 +95,39 @@ onMounted(() => {
weaponType.value.addEventListener("click", () => {
ShowContextMenu(weapon_types)
});
AddContextMenu(weaponType.value, weapon_types)
weaponType.value.addEventListener("click", () => {
AddContextMenu(weaponType.value, weapon_types);
item_name.value.addEventListener('blur', () => {
concept.value.name = item_name.value.textContent;
Upload();
});
}
onMounted(() => {
SetupHandle(id, handle);
SetSize(id, {width: 500, height: 400});
ResetPosition(id, "center");
item_type.value = data.item_type;
if(data.item_create){
Api().post('/concept/create?campaign=' + GetCampaign()._id, {
data: {
type: data.item_type,
name: "New " + data.item_type
},
}).then(response => {
concept.value = response.data.concept;
InitValues();
}).catch(err => console.log(err));
} else {
// Get concept
Api().get('/concept/get?campaign=' + GetCampaign()._id + "&id=" + data.item_id).then(response => {
concept.value = response.data.concept;
InitValues();
}).catch(err => console.log(err));
}
});
</script>
@ -99,20 +139,12 @@ onMounted(() => {
<div class="main-container">
<div class="item-header">
<IconSelector :window="id"></IconSelector>
<IconSelector :window="id" ref="icon_selector" :done="IconSelected"></IconSelector>
<div class="header-info">
<h1 contenteditable="true" spellcheck="false">New Item</h1>
<h1 contenteditable="true" spellcheck="false" ref="item_name">{{ concept.name }}</h1>
<div class="row">
<div class="grow subsection" ref="weaponType"></div>
<div class="grow subsection" ref="rarity"></div>
<!--
<option value="none"><span></span></option>
<option value="common"><span class="common">Common</span></option>
<option value="uncommon"><span class="uncommon">Uncommon</span></option>
<option value="rare"><span class="rare">Rare</span></option>
<option value="very rare"><span class="very-rare">Very Rare</span></option>
<option value="legendary"><span class="legendary">Legendary</span></option>
<option value="artifact"><span class="artifact">Artifact</span></option>-->
</div>
</div>
</div>

View File

@ -0,0 +1,21 @@
const Campaign = require("../models/Campaign");
const CampaignUser = require("../models/CampaignUser");
function hasCampaign(req, res, next){
Campaign.findById(req.query.campaign).lean().then((campaign) => {
CampaignUser.findOne({campaign, user: req.user}).lean().then((campaignUser) => {
if(!campaignUser) {
res.json({status: "error", msg: "not-found"})
return;
}
req.cu = campaignUser;
req.campaign = campaign;
req.room = req.query.campaign;
next();
}).catch((err) => res.json({status: "error", err}));
}).catch((err) => res.json({status: "error", err}));
}
module.exports = {
hasCampaign
}

15
server/io/socket.js Normal file
View File

@ -0,0 +1,15 @@
let ioInstance;
function setIo(io){
if(!ioInstance) ioInstance = io;
}
function getIo() {
return ioInstance;
}
module.exports = {
setIo,
getIo,
ioInstance
}

View File

@ -2,10 +2,10 @@ const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const ConceptSchema = new Schema({
name: {type: String, required: true},
system: {type: String, required: true},
type: { type: String },
data: { type: Object },
name: {type: String, required: true, default: "New Concept"},
type: { type: String, required: true, default: "Concept" },
info: { type: Object }, // For preview only
data: { type: Object }, // Advanced item
book: {type: mongoose.Types.ObjectId, ref: "Book"},
campaign: {type: mongoose.Types.ObjectId, ref: "Campaign"},
});

View File

@ -2,7 +2,6 @@ const express = require('express');
const router = express.Router();
const passport = require('passport');
const rateLimitMiddleware = require("../config/rate-limiter");
const Campaign = require("../models/Campaign");
const CampaignUser = require("../models/CampaignUser");
@ -13,8 +12,7 @@ const upload = require("../config/storage");
router.post('/register', passport.authenticate('jwt', {session: false}), rateLimitMiddleware, (req, res) => {
});
*/
router.post('/create', passport.authenticate('jwt', {session: false}), rateLimitMiddleware, (req, res) => {
router.post('/create', (req, res) => {
let {
name,
system
@ -47,7 +45,7 @@ router.post('/create', passport.authenticate('jwt', {session: false}), rateLimit
}).catch((err) => {res.json({status: "error", msg: "internal"})});
});
router.post('/join', passport.authenticate('jwt', {session: false}), rateLimitMiddleware, (req, res) => {
router.post('/join', (req, res) => {
let {
invite_code
} = req.body;
@ -82,16 +80,16 @@ router.post('/join', passport.authenticate('jwt', {session: false}), rateLimitMi
}).catch(err => res.json({status: "error", msg: "internal"}))
});
router.get('/list', passport.authenticate('jwt', {session: false}), (req, res) => {
CampaignUser.find({user: req.user}).populate("campaign").then((data) => {
router.get('/list', (req, res) => {
CampaignUser.find({user: req.user}).populate("campaign").lean().then((data) => {
res.json(data);
console.log(data);
return;
}).catch((err) => res.json({status: "error", msg: "internal"}));
});
router.get('/players', passport.authenticate('jwt', {session: false}), (req, res) => {
Campaign.findById(req.query.campaign).then((campaign) => {
router.get('/players', (req, res) => {
Campaign.findById(req.query.campaign).lean().then((campaign) => {
CampaignUser.find({campaign}).populate('user').then((data) => {
console.log("djskajdk")
console.log(data);

View File

@ -11,24 +11,24 @@ const Character = require('../models/Character');
const upload = require("../config/storage");
// Get characters from a campaign
router.get('/list', passport.authenticate('jwt', {session: false}), (req, res) => {
router.get('/list', (req, res) => {
});
// Character info
router.post('/create', passport.authenticate('jwt', {session: false}), rateLimitMiddleware, (req, res) => {
router.post('/create', rateLimitMiddleware, (req, res) => {
});
router.delete('/delete', passport.authenticate('jwt', {session: false}), rateLimitMiddleware, (req, res) => {
router.delete('/delete', rateLimitMiddleware, (req, res) => {
});
router.get('/get', passport.authenticate('jwt', {session: false}), (req, res) => {
router.get('/get', (req, res) => {
});
router.put('/update', passport.authenticate('jwt', {session: false}), (req, res) => {
router.put('/update', (req, res) => {
});

72
server/routes/concept.js Normal file
View File

@ -0,0 +1,72 @@
const express = require('express');
const router = express.Router();
const passport = require('passport');
const Campaign = require("../models/Campaign");
const CampaignUser = require("../models/CampaignUser");
const Concept = require('../models/Concept');
const { hasCampaign } = require('../config/middleware');
const { getIo } = require('../io/socket');
const io = getIo();
router.get('/list', hasCampaign, (req, res) => {
const campaign = req.campaign;
Concept.find({campaign}).select('-data').lean().then(data => {
res.json({status: "ok", data});
});
});
router.post('/create', hasCampaign, (req, res) => {
const campaign = req.campaign;
let data = req.body.data;
if(!(data.type && data.name)) {
res.json({status: "error", msg: "args"});
return;
}
let concept = new Concept({campaign, type: data.type, name: data.name});
concept.save().then(concept => {
io.to(req.room).emit('update-concepts');
res.json({status: "ok", concept});
})
});
router.delete('/delete', hasCampaign, (req, res) => {
const campaign = req.campaign;
let id = req.query.id;
if(!id) {
res.json({status: "error", msg: "args"});
return;
}
Concept.deleteOne({_id: id, campaign}).then(() => {
io.to(req.room).emit('update-concepts');
res.json({status: "ok"});
});
});
router.get('/get', hasCampaign, (req, res) => {
const campaign = req.campaign;
let id = req.query.id;
Concept.findOne({_id: id, campaign}).lean().then(concept => {
res.json({status: "ok", concept});
});
});
router.put('/update', hasCampaign, (req, res) => {
const campaign = req.campaign;
let id = req.query.id;
Concept.findOneAndUpdate({_id: id, campaign}, req.body.concept).then(result => {
console.log(req.room)
if(req.query.fireUpdate) io.to(req.room).emit('update-concepts');
io.to(req.room).emit('update-concept', id);
res.json({status: "ok"});
});
});
module.exports = router;

View File

@ -10,17 +10,11 @@ const Map = require("../models/Map");
const fs = require('fs');
const upload = require("../config/storage");
const { hasCampaign } = require('../config/middleware');
router.post('/create-resource', upload.single("image"), passport.authenticate('jwt', {session: false}), (req, res) => {
router.post('/create-resource', hasCampaign, upload.single("image"), (req, res) => {
const imageName = req.file.filename;
Campaign.findById(req.query.campaign).then((campaign) => {
CampaignUser.findOne({campaign, user: req.user}).then((data) => {
if(!data) {
res.json({status: "error", msg: "not-found"})
fs.unlink(imageName);
return;
}
const data = req.cu;
if(data.is_dm){
res.json({
@ -28,23 +22,17 @@ router.post('/create-resource', upload.single("image"), passport.authenticate('j
data: imageName
});
return;
} else {
res.json({status: "error", msg: "not-dm"})
}
res.json({status: "error", msg: "not-dm"})
fs.unlink(imageName);
return;
}).catch((err) => res.json({status: "error", msg: "not-found"}));
}).catch((err) => res.json({status: "error", err}));
});
// rateLimitMiddleware?
router.post('/create', passport.authenticate('jwt', {session: false}), (req, res) => {
Campaign.findById(req.body.campaign).then((campaign) => {
CampaignUser.findOne({campaign, user: req.user}).then((data) => {
if(!data) {
res.json({status: "error", msg: "not-found"})
return;
}
router.post('/create', hasCampaign, (req, res) => {
const data = req.cu;
const campaign = req.campaign;
if(data.is_dm){
let mapData = req.body.data;
@ -63,20 +51,13 @@ router.post('/create', passport.authenticate('jwt', {session: false}), (req, res
} else res.json({status: "error", msg: "args"})
return;
}
}).catch((err) => res.json({status: "error", msg: "not-found"}));
}).catch((err) => res.json({status: "error", err}));
});
router.post('/update', passport.authenticate('jwt', {session: false}), (req, res) => {
Campaign.findById(req.query.campaign).then((campaign) => {
CampaignUser.findOne({campaign, user: req.user}).then((data) => {
if(!data) {
res.json({status: "error", msg: "not-found"})
return;
}
router.post('/update', hasCampaign, (req, res) => {
const data = req.cu;
const campaign = req.campaign;
if(data.is_dm){
console.log("Ab");
let mapData = req.body.data;
if(mapData){
console.log("Map data:");
@ -90,31 +71,22 @@ router.post('/update', passport.authenticate('jwt', {session: false}), (req, res
} else res.json({status: "error", msg: "args"})
return;
}
}).catch((err) => res.json({status: "error", msg: "not-found"}));
}).catch((err) => res.json({status: "error", err}));
});
router.get('/list', passport.authenticate('jwt', {session: false}), (req, res) => {
Campaign.findById(req.query.campaign).then((campaign) => {
CampaignUser.findOne({campaign, user: req.user}).then((data) => {
if(!data) {
res.json({status: "error", msg: "not-found"})
return;
}
router.get('/list', hasCampaign, (req, res) => {
const campaign = req.campaign;
Map.find({campaign}).then(data => {
res.json({status: "ok", data});
return;
}).catch(err => res.json({status: "error", msg: "internal"}));
}).catch((err) => res.json({status: "error", msg: "not-found"}));
}).catch((err) => res.json({status: "error", err}));
});
router.get('/get', passport.authenticate('jwt', {session: false}), (req, res) => {
router.get('/get', (req, res) => {
});
router.delete('/delete', passport.authenticate('jwt', {session: false}), (req, res) => {
router.delete('/delete', (req, res) => {
});

View File

@ -1,7 +1,6 @@
const express = require('express');
const http = require('http')
const socketIo = require('socket.io');
const app = express();
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
@ -11,67 +10,75 @@ const path = require('path');
const morgan = require('morgan');
const cors = require('cors');
const passport = require('passport');
const server = http.createServer(app);
const io = socketIo(server, {
cors: {
origin: '*',
}
});
const PORT = 8081;
const config = JSON.parse(fs.readFileSync("config.json"));
// SET CONSTANTS
const PORT = 8081;
global.appRoot = path.resolve(__dirname);
var mongo_final_ip = "";
let mongo_final_ip = "";
console.log("Production? " + !process.env.DEBUG);
if(process.env.DEBUG){
mongo_final_ip = "mongodb://" + config.mongo_ip_debug + "/dragonroll";
} else {
mongo_final_ip = "mongodb://" + config.mongo_ip + "/dragonroll";
}
console.log(mongo_final_ip)
console.log("Db ip: " + mongo_final_ip)
// CONFIGURE SOCKET IO
const socket = require('./io/socket')
const io = socketIo(server, {
cors: {
origin: '*',
}
});
socket.setIo(io);
// CONNECT TO MONGODB
mongoose.connect(mongo_final_ip).then(() => {
console.log("Connected to database");
}).catch((error) => {
console.log(error);
});
// PASSPORT
app.use(morgan('tiny'));
app.use(passport.initialize());
require('./config/passport')(passport);
// Carpeta publica
// PUBLIC
app.use("/public", express.static(__dirname + '/public'));
// app.use("/.well-known", express.static(__dirname + '/.well-known'));
app.use('/public', express.static('uploads'));
// IDk per a què serveix això
// JSON LIMIT EXPRESS
app.use(express.json({limit: '50mb'}));
app.use(express.urlencoded({
extended : false,
limit: '50mb'
}));
// CORS
app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cors());
// Routes (/ només)
// ROUTES (NO AUTH)
app.use('/user', require('./routes/user'));
// AUTH
checkAuth = passport.authenticate('jwt', {session: false});
app.use(checkAuth);
// ROUTES WITH AUTH
app.use('/campaign', require('./routes/campaign'));
app.use('/maps', require('./routes/map'))
app.use('/concept', require('./routes/concept'))
// GET localhost:8081/concept/list
// SETUP IO
require('./io/campaign')(socket.getIo());
app.use('/public', express.static('uploads'));
require('./io/campaign')(io);
// app.use('/users', require('./routes/users'));
// LISTEN
server.listen(PORT, () => {
console.log("Dragonroll backend started");
});