Started socketio things

This commit is contained in:
BinarySandia04 2024-08-05 00:30:33 +02:00
parent 1991fd8f02
commit 44771fc4af
24 changed files with 626 additions and 60 deletions

View File

@ -19,6 +19,7 @@
"marked-katex-extension": "^4.0.1", "marked-katex-extension": "^4.0.1",
"mitt": "^3.0.1", "mitt": "^3.0.1",
"prismjs": "^1.29.0", "prismjs": "^1.29.0",
"socket.io-client": "^4.7.5",
"three": "^0.164.1", "three": "^0.164.1",
"vue": "^3.3.4", "vue": "^3.3.4",
"vue-draggable": "^2.0.6", "vue-draggable": "^2.0.6",
@ -1024,6 +1025,12 @@
"dev": true, "dev": true,
"license": "BSD-3-Clause" "license": "BSD-3-Clause"
}, },
"node_modules/@socket.io/component-emitter": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
"integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==",
"license": "MIT"
},
"node_modules/@soda/friendly-errors-webpack-plugin": { "node_modules/@soda/friendly-errors-webpack-plugin": {
"version": "1.8.1", "version": "1.8.1",
"resolved": "https://registry.npmjs.org/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.8.1.tgz", "resolved": "https://registry.npmjs.org/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.8.1.tgz",
@ -4887,7 +4894,6 @@
"version": "4.3.4", "version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"dev": true,
"dependencies": { "dependencies": {
"ms": "2.1.2" "ms": "2.1.2"
}, },
@ -5301,6 +5307,49 @@
"once": "^1.4.0" "once": "^1.4.0"
} }
}, },
"node_modules/engine.io-client": {
"version": "6.5.4",
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.4.tgz",
"integrity": "sha512-GeZeeRjpD2qf49cZQ0Wvh/8NJNfeXkXXcoGh+F77oEAgo9gUHwT1fCRxSNU+YEEaysOJTnsFHmM5oAcPy4ntvQ==",
"license": "MIT",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1",
"engine.io-parser": "~5.2.1",
"ws": "~8.17.1",
"xmlhttprequest-ssl": "~2.0.0"
}
},
"node_modules/engine.io-client/node_modules/ws": {
"version": "8.17.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/engine.io-parser": {
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz",
"integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/enhanced-resolve": { "node_modules/enhanced-resolve": {
"version": "5.17.1", "version": "5.17.1",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz",
@ -8371,8 +8420,7 @@
"node_modules/ms": { "node_modules/ms": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
"dev": true
}, },
"node_modules/multicast-dns": { "node_modules/multicast-dns": {
"version": "7.2.5", "version": "7.2.5",
@ -11003,6 +11051,34 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
}, },
"node_modules/socket.io-client": {
"version": "4.7.5",
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.5.tgz",
"integrity": "sha512-sJ/tqHOCe7Z50JCBCXrsY3I2k03iOiUe+tj1OmKeD2lXPiGH/RUCdTZFoqVyN7l1MnpIzPrGtLcijffmeouNlQ==",
"license": "MIT",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.2",
"engine.io-client": "~6.5.2",
"socket.io-parser": "~4.2.4"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/socket.io-parser": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
"integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
"license": "MIT",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/sockjs": { "node_modules/sockjs": {
"version": "0.3.24", "version": "0.3.24",
"resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz",
@ -12704,6 +12780,14 @@
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/xmlhttprequest-ssl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz",
"integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/xss": { "node_modules/xss": {
"version": "1.0.14", "version": "1.0.14",
"resolved": "https://registry.npmjs.org/xss/-/xss-1.0.14.tgz", "resolved": "https://registry.npmjs.org/xss/-/xss-1.0.14.tgz",

View File

@ -20,6 +20,7 @@
"marked-katex-extension": "^4.0.1", "marked-katex-extension": "^4.0.1",
"mitt": "^3.0.1", "mitt": "^3.0.1",
"prismjs": "^1.29.0", "prismjs": "^1.29.0",
"socket.io-client": "^4.7.5",
"three": "^0.164.1", "three": "^0.164.1",
"vue": "^3.3.4", "vue": "^3.3.4",
"vue-draggable": "^2.0.6", "vue-draggable": "^2.0.6",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 54 KiB

View File

@ -12,6 +12,7 @@
--c-white-blurred: #f8f8f8cc; --c-white-blurred: #f8f8f8cc;
--c-blacker: #1a1a1a;
--c-black: #181818; --c-black: #181818;
--c-black-semisoft:1 #1d1d1d; --c-black-semisoft:1 #1d1d1d;
--c-black-soft: #222222; --c-black-soft: #222222;
@ -65,6 +66,7 @@
--color-heading: var(--c-text-light-1); --color-heading: var(--c-text-light-1);
--color-text: var(--c-text-light-1); --color-text: var(--c-text-light-1);
--separator: var(--c-black-mute); --separator: var(--c-black-mute);
--chat-background: var(--c-white);
--section-gap: 160px; --section-gap: 160px;
} }
@ -89,6 +91,8 @@
--color-text: var(--c-text-dark-2); --color-text: var(--c-text-dark-2);
--separator: var(--c-white-mute); --separator: var(--c-white-mute);
--chat-background: var(--c-blacker);
--color-hover: var() --color-hover: var()
} }
} }

View File

@ -1,10 +1,10 @@
import axios from 'axios'; import axios from 'axios';
import BackendURL from './BackendURL'; import { backendUrl } from './BackendURL';
export default () => { export default () => {
return axios.create({ return axios.create({
baseURL: BackendURL, baseURL: backendUrl,
headers: { headers: {
'Authorization': "Bearer " + localStorage.getItem('token'), 'Authorization': "Bearer " + localStorage.getItem('token'),
"Access-Control-Allow-Origin": "*", "Access-Control-Allow-Origin": "*",

View File

@ -6,4 +6,6 @@ if (import.meta.env.PROD) {
} }
export default backendUrl; export {
backendUrl
};

View File

@ -1,12 +1,43 @@
import { ref } from 'vue';
import { ClearAll, ClearWindow, CreateWindow } from './Windows'; import { ClearAll, ClearWindow, CreateWindow } from './Windows';
import { io } from "socket.io-client";
import Api from '@/services/Api'
import { backendUrl } from './BackendURL';
import { GetUser } from './User';
export const socket = io(backendUrl)
let currentCampaign = null;
const players = ref([]);
let GetPlayerList = () => { return players; };
socket.on('update-players', data => {
players.value = [];
Object.keys(data).forEach((key) => {
players.value.push(data[key]);
});
})
function DisplayCampaign(data){ function DisplayCampaign(data){
ClearAll(); ClearAll();
CreateWindow('campaign_preview', { CreateWindow('campaign_preview', {campaign: data});
title: data.name }
});
function ConnectToCampaign(campaign){
currentCampaign = campaign;
socket.emit('enter', GetUser(), currentCampaign._id);
}
function Disconnect(){
socket.emit('exit');
currentCampaign = null;
} }
export { export {
DisplayCampaign DisplayCampaign,
ConnectToCampaign,
Disconnect,
GetPlayerList,
}; };

View File

@ -0,0 +1,15 @@
function AddSound(element){
let soundClicks = element.getElementsByClassName("sound-click");
for (let i = 0; i < soundClicks.length; i++) {
soundClicks[i].addEventListener("click", async (event) => {
const audio = new Audio('/sounds/snap.wav');
audio.type = "audio/wav"
audio.play();
})
}
}
export {
AddSound
};

View File

@ -1,4 +1,5 @@
import { reactive, ref } from 'vue' import { reactive, ref } from 'vue'
import { Disconnect } from './Dragonroll';
const windows = { const windows = {
login: ref([]), login: ref([]),
@ -61,8 +62,9 @@ const defValues = {
id: 'campaign_preview', id: 'campaign_preview',
title: "Campaign Preview", title: "Campaign Preview",
back: () => { back: () => {
Disconnect();
ClearWindow('campaign_preview'); ClearWindow('campaign_preview');
CreateWindow('campaign_list') CreateWindow('campaign_list');
} }
} }
} }
@ -167,8 +169,6 @@ function ResetPosition(id, pos){
function CreateWindow(type, data = {}){ function CreateWindow(type, data = {}){
let finalData = {...{type}, ...defValues[type], ...data} let finalData = {...{type}, ...defValues[type], ...data}
console.log(finalData);
if(windows[finalData.type] === undefined){ if(windows[finalData.type] === undefined){
console.error("Window type " + finalData.type + " is not defined!"); console.error("Window type " + finalData.type + " is not defined!");
return; return;

View File

@ -4,6 +4,8 @@ import { onMounted, ref } from 'vue';
import Api from '@/services/Api' import Api from '@/services/Api'
import { DisplayCampaign } from '@/services/Dragonroll' import { DisplayCampaign } from '@/services/Dragonroll'
import { AddSound } from '../../services/Sound';
import { ConnectToCampaign } from '../../services/Dragonroll';
const props = defineProps(['data']); const props = defineProps(['data']);
const data = props.data; const data = props.data;
@ -11,21 +13,24 @@ const data = props.data;
const title = ref(""); const title = ref("");
const last_session = ref(""); const last_session = ref("");
const container = ref(null);
onMounted(() => { onMounted(() => {
console.log(data);
title.value = data.name; title.value = data.name;
last_session.value = new Date(data.last_opened).toISOString().slice(0, 10); last_session.value = new Date(data.last_opened).toISOString().slice(0, 10);
console.log(title);
AddSound(container.value)
}); });
function ViewCampaign(){ function ViewCampaign(){
ConnectToCampaign(data);
DisplayCampaign(data); DisplayCampaign(data);
} }
</script> </script>
<template> <template>
<div class="campaign-entry-container"> <div class="campaign-entry-container" ref="container">
<div class="main-campaign-entry-container-inner"> <div class="main-campaign-entry-container-inner">
<img class="campaign-icon" src="img/def-avatar.jpg" draggable="false"> <img class="campaign-icon" src="img/def-avatar.jpg" draggable="false">
<div class="campaign-info"> <div class="campaign-info">

View File

@ -7,10 +7,10 @@ import { onMounted, ref } from 'vue';
import { GetUser, LogoutUser } from '@/services/User' import { GetUser, LogoutUser } from '@/services/User'
import Api from '@/services/Api' import Api from '@/services/Api'
import url from '@/services/BackendURL'
import useEmitter from '@/services/Emitter'; import useEmitter from '@/services/Emitter';
import { ClearWindows, CreateWindow, CreateChildWindow } from '../../services/Windows'; import { ClearWindows, CreateWindow, CreateChildWindow } from '../../services/Windows';
import { backendUrl } from '../../services/BackendURL';
const emitter = useEmitter(); const emitter = useEmitter();
const username = ref(""); const username = ref("");
@ -19,7 +19,7 @@ username.value = GetUser().username;
function retrieveAvatar(){ function retrieveAvatar(){
let userAvatarDisplay = document.getElementById("upload-image"); let userAvatarDisplay = document.getElementById("upload-image");
Api().get('/user/retrieve-avatar?username=' + GetUser().username).then((response) => { Api().get('/user/retrieve-avatar?username=' + GetUser().username).then((response) => {
userAvatarDisplay.src = url + "public/" + response.data.image; if(response.data.image) userAvatarDisplay.src = backendUrl + "public/" + response.data.image;
}).catch((err) => console.log("Internal error")); }).catch((err) => console.log("Internal error"));
} }

View File

@ -0,0 +1,88 @@
<script setup>
import { onMounted, onUpdated, ref } from 'vue';
import Api from '@/services/Api.js'
import { backendUrl } from '../../services/BackendURL';
const props = defineProps(['player']);
const player = props.player;
const playerName = ref("");
const isDm = ref(false);
const avatar = ref(null);
function retrieveAvatar(){
let userAvatarDisplay = avatar.value;
Api().get('/user/retrieve-avatar?username=' + player.data.username).then((response) => {
if(response.data.image) userAvatarDisplay.src = backendUrl + "public/" + response.data.image;
}).catch((err) => console.log("Internal error"));
}
onMounted(() => {
playerName.value = player.data.username;
if(player.is_dm) isDm.value = true;
retrieveAvatar();
});
</script>
<template>
<div class="main-player-container">
<div class="main-player-container-inner">
<img class="user-icon" src="img/def-avatar.jpg" ref="avatar" draggable="false">
<div class="main-user-info">
<b>{{ playerName }}</b><span class="dm" v-if="isDm"> DM</span><br>Miauler
</div>
<div class="main-user-actions">
</div>
</div>
</div>
</template>
<style scoped lang="scss">
#send-avatar-form {
display: none;
}
.button-small {
height: 32px;
padding: 10px;
}
.main-player-container {
width: 100%;
user-select: none;
}
.dm {
color: gold;
font-weight: bold;
}
.main-player-container-inner {
padding: 10px;
display: flex;
align-items: center;
justify-content: center;
}
.main-user-info {
text-align: left;
margin-left: 10px;
}
.user-icon {
width: 40px;
height: 40px;
}
.main-user-actions {
margin-left: auto;
}
</style>

View File

@ -0,0 +1,29 @@
<script setup>
import { onMounted, onUpdated, ref } from 'vue';
import { SetupHandle, SetSize, SetPosition, ResetPosition } from '@/services/Windows';
import Api from '@/services/Api.js'
import PlayerEntry from './PlayerEntry.vue';
import { GetPlayerList } from '../../services/Dragonroll';
const props = defineProps(['campaign']);
const campaign = props.campaign;
const players = GetPlayerList();
onMounted(() => {
});
</script>
<template>
<PlayerEntry v-for="player in players" :key="player.data._id" :player="player" class="player-list"></PlayerEntry>
</template>
<style scoped lang="scss">
.player-list {
height: 100%;
}
</style>

View File

@ -3,6 +3,8 @@ import { onMounted, ref } from 'vue';
import { GetWindowWithId } from '@/services/Windows'; import { GetWindowWithId } from '@/services/Windows';
import { ClearWindow } from '../../services/Windows'; import { ClearWindow } from '../../services/Windows';
import { AddSound } from '../../services/Sound';
const props = defineProps(['window']); const props = defineProps(['window']);
const id = props.window; const id = props.window;
@ -28,16 +30,8 @@ function setupHandle() {
// Setup sounds // Setup sounds
let currentWindowId = "window-wrapper-" + id; let currentWindowId = "window-wrapper-" + id;
let currentWindow = document.getElementById(currentWindowId); let currentWindow = document.getElementById(currentWindowId);
let soundClicks = currentWindow.getElementsByClassName("sound-click");
AddSound(currentWindow);
for (let i = 0; i < soundClicks.length; i++) {
soundClicks[i].addEventListener("click", async (event) => {
const audio = new Audio('/sounds/snap.wav');
audio.type = "audio/wav"
audio.play();
})
}
} }

View File

@ -32,7 +32,7 @@ onMounted(() => {
successMessage.value = success; successMessage.value = success;
SetupHandle(id, handle); SetupHandle(id, handle);
SetSize(id, {x: 450, y: 480}); SetSize(id, {x: 450, y: 500});
ResetPosition(id, "center"); ResetPosition(id, "center");
}); });
@ -115,7 +115,7 @@ p {
} }
.splash-image { .splash-image {
width: 400px; width: 450px;
} }
form { form {

View File

@ -29,7 +29,7 @@ let title = data.title;
onMounted(() => { onMounted(() => {
SetupHandle(id, handle); SetupHandle(id, handle);
SetSize(id, {x: 450, y: 780}); SetSize(id, {x: 450, y: 800});
ResetPosition(id, "center"); ResetPosition(id, "center");
}); });
@ -133,7 +133,7 @@ p {
} }
.splash-image { .splash-image {
width: 400px; width: 450px;
user-select: none; user-select: none;
} }

View File

@ -3,6 +3,7 @@ import { onMounted, onUpdated, ref } from 'vue';
import { SetupHandle, SetSize, SetPosition, ResetPosition } from '@/services/Windows'; import { SetupHandle, SetSize, SetPosition, ResetPosition } from '@/services/Windows';
import WindowHandle from '@/views/partials/WindowHandle.vue'; import WindowHandle from '@/views/partials/WindowHandle.vue';
import PlayerList from '../../partials/PlayerList.vue';
const handle = ref(null); const handle = ref(null);
@ -12,7 +13,7 @@ const data = props.data;
let id = data.id; let id = data.id;
onMounted(() => { onMounted(() => {
SetupHandle(id, handle); SetupHandle(id, handle);
SetSize(id, {x: 500, y: 380}); SetSize(id, {x: 1200, y: 750});
ResetPosition(id, "center"); ResetPosition(id, "center");
}); });
</script> </script>
@ -22,37 +23,59 @@ onMounted(() => {
<div class="window-wrapper" :id="'window-wrapper-' + id"> <div class="window-wrapper" :id="'window-wrapper-' + id">
<WindowHandle :window="id" ref="handle"></WindowHandle> <WindowHandle :window="id" ref="handle"></WindowHandle>
<!-- Body --> <!-- Body
<h1>{{ data.campaign.name }}</h1> -->
<div class="campaign-preview-container">
<div class="campaign-preview-column left">
<h2>Players</h2>
<PlayerList :campaign="data.campaign"></PlayerList>
</div>
<div class="campaign-preview-column center">
</div>
<div class="campaign-preview-column right">
<h2>Chat</h2>
</div>
</div>
</div> </div>
</template> </template>
<style scoped> <style scoped lang="scss">
.window-wrapper { .campaign-preview-container {
min-width: 700px; width: 100%;
min-height: 630px; height: 100%;
display: grid;
grid-template-columns: 3fr 5fr 5fr;
}
.campaign-preview-column {
display: flex; display: flex;
flex-direction: column;
&.left {
background-color: var(--color-background-soft);
}
&.center {
background-color: var(--color-background-semisoft);
}
&.right {
background-color: var(--chat-background);
}
}
.window-wrapper {
display: flex;
user-select: none;
align-items: center; align-items: center;
} }
.splash-image { h1, h2 {
width: 600px; font-family: MrEavesRemake;
height: 250px;
}
.form-field {
padding: 10px;
display: flex;
align-items: left;
flex-direction: column;
justify-content: left;
width: 600px;
}
label {
text-align: left;
} }
</style> </style>

46
server/io/campaign.js Normal file
View File

@ -0,0 +1,46 @@
const CampaignUser = require("../models/CampaignUser");
const User = require("../models/User");
const FilterUser = require('../utils/filters');
let sessions = {};
module.exports = io => {
io.on('connection', (socket) => {
socket.on('enter', (user, campaignId) => {
User.findOne(user).then(user => {
if(user){
socket.user = user;
CampaignUser.findOne({campaign: campaignId, user}).then(campaignUser => {
if(campaignUser){
socket.join(campaignId);
socket.campaign = campaignId;
if(!sessions[campaignId]) sessions[campaignId] = {
players: {}
};
sessions[campaignId].players[socket.user._id] = {
online: true,
is_dm: campaignUser.is_dm,
data: FilterUser(socket.user)
};
console.log(socket.user.username + " ha entrado!");
io.to(socket.campaign).emit('update-players', sessions[campaignId].players)
console.log(JSON.stringify(sessions, null, 4));
}
});
}
})
});
socket.on('exit', () => {
io.to(socket.campaign).emit('update-players', sessions[campaignId].players)
socket.leave(socket.campaign)
sessions[socket.campaign].players[socket.user._id].online = false;
console.log(socket.user.username + " ha salido!")
});
});
}

217
server/package-lock.json generated
View File

@ -30,7 +30,8 @@
"passport": "^0.6.0", "passport": "^0.6.0",
"passport-jwt": "^4.0.1", "passport-jwt": "^4.0.1",
"simplemde-vue": "^0.4.4", "simplemde-vue": "^0.4.4",
"slugify": "^1.6.5" "slugify": "^1.6.5",
"socket.io": "^4.7.5"
}, },
"devDependencies": { "devDependencies": {
"nodemon": "^2.0.22" "nodemon": "^2.0.22"
@ -1336,6 +1337,12 @@
"node": ">=16.0.0" "node": ">=16.0.0"
} }
}, },
"node_modules/@socket.io/component-emitter": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
"integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==",
"license": "MIT"
},
"node_modules/@types/body-parser": { "node_modules/@types/body-parser": {
"version": "1.19.5", "version": "1.19.5",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",
@ -1365,6 +1372,21 @@
"@types/node": "*" "@types/node": "*"
} }
}, },
"node_modules/@types/cookie": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz",
"integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==",
"license": "MIT"
},
"node_modules/@types/cors": {
"version": "2.8.17",
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz",
"integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==",
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/express": { "node_modules/@types/express": {
"version": "4.17.21", "version": "4.17.21",
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz",
@ -1582,6 +1604,15 @@
], ],
"license": "MIT" "license": "MIT"
}, },
"node_modules/base64id": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
"integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==",
"license": "MIT",
"engines": {
"node": "^4.5.0 || >= 5.9"
}
},
"node_modules/basic-auth": { "node_modules/basic-auth": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
@ -2043,6 +2074,59 @@
"once": "^1.4.0" "once": "^1.4.0"
} }
}, },
"node_modules/engine.io": {
"version": "6.5.5",
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz",
"integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==",
"license": "MIT",
"dependencies": {
"@types/cookie": "^0.4.1",
"@types/cors": "^2.8.12",
"@types/node": ">=10.0.0",
"accepts": "~1.3.4",
"base64id": "2.0.0",
"cookie": "~0.4.1",
"cors": "~2.8.5",
"debug": "~4.3.1",
"engine.io-parser": "~5.2.1",
"ws": "~8.17.1"
},
"engines": {
"node": ">=10.2.0"
}
},
"node_modules/engine.io-parser": {
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz",
"integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/engine.io/node_modules/debug": {
"version": "4.3.6",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
"integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
"license": "MIT",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/engine.io/node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"license": "MIT"
},
"node_modules/es-define-property": { "node_modules/es-define-property": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
@ -3519,6 +3603,116 @@
"npm": ">= 3.0.0" "npm": ">= 3.0.0"
} }
}, },
"node_modules/socket.io": {
"version": "4.7.5",
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz",
"integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==",
"license": "MIT",
"dependencies": {
"accepts": "~1.3.4",
"base64id": "~2.0.0",
"cors": "~2.8.5",
"debug": "~4.3.2",
"engine.io": "~6.5.2",
"socket.io-adapter": "~2.5.2",
"socket.io-parser": "~4.2.4"
},
"engines": {
"node": ">=10.2.0"
}
},
"node_modules/socket.io-adapter": {
"version": "2.5.5",
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz",
"integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==",
"license": "MIT",
"dependencies": {
"debug": "~4.3.4",
"ws": "~8.17.1"
}
},
"node_modules/socket.io-adapter/node_modules/debug": {
"version": "4.3.6",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
"integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
"license": "MIT",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/socket.io-adapter/node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"license": "MIT"
},
"node_modules/socket.io-parser": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
"integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
"license": "MIT",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/socket.io-parser/node_modules/debug": {
"version": "4.3.6",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
"integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
"license": "MIT",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/socket.io-parser/node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"license": "MIT"
},
"node_modules/socket.io/node_modules/debug": {
"version": "4.3.6",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
"integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
"license": "MIT",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/socket.io/node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"license": "MIT"
},
"node_modules/socks": { "node_modules/socks": {
"version": "2.8.3", "version": "2.8.3",
"resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz",
@ -3770,6 +3964,27 @@
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"license": "ISC" "license": "ISC"
}, },
"node_modules/ws": {
"version": "8.17.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/xtend": { "node_modules/xtend": {
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",

View File

@ -31,7 +31,8 @@
"passport": "^0.6.0", "passport": "^0.6.0",
"passport-jwt": "^4.0.1", "passport-jwt": "^4.0.1",
"simplemde-vue": "^0.4.4", "simplemde-vue": "^0.4.4",
"slugify": "^1.6.5" "slugify": "^1.6.5",
"socket.io": "^4.7.5"
}, },
"devDependencies": { "devDependencies": {
"nodemon": "^2.0.22" "nodemon": "^2.0.22"

View File

@ -53,4 +53,13 @@ router.get('/list', passport.authenticate('jwt', {session: false}), (req, res) =
}).catch((err) => res.json({status: "error", msg: "internal"})); }).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) => {
CampaignUser.find({campaign}).populate('user').then((data) => {
res.json(data);
return;
}).catch((err) => res.json({status: "error", msg: "internal"}));
}).catch((err) => res.json({status: "error", msg: "not-found"}));
});
module.exports = router; module.exports = router;

View File

@ -116,6 +116,7 @@ router.post('/login', rateLimitMiddleware, (req, res) => {
}); });
}); });
/*
router.get('/test', passport.authenticate('jwt', {session: false}), (req, res) => { router.get('/test', passport.authenticate('jwt', {session: false}), (req, res) => {
const token = req.headers.authorization.slice(7); const token = req.headers.authorization.slice(7);
const payload = jwtDecode(token); const payload = jwtDecode(token);
@ -126,10 +127,10 @@ router.get('/test', passport.authenticate('jwt', {session: false}), (req, res) =
}); });
return; return;
}); });
*/
router.post("/upload-avatar", upload.single("image"), passport.authenticate('jwt', {session: false}), (req, res) => { router.post("/upload-avatar", upload.single("image"), passport.authenticate('jwt', {session: false}), (req, res) => {
const imageName = req.file.filename; const imageName = req.file.filename;
console.log(req.body);
User.updateOne(req.user, {image: imageName}).then(() => { User.updateOne(req.user, {image: imageName}).then(() => {
res.json({ res.json({

View File

@ -1,4 +1,6 @@
const express = require('express'); const express = require('express');
const http = require('http')
const socketIo = require('socket.io');
const app = express(); const app = express();
const cookieParser = require('cookie-parser'); const cookieParser = require('cookie-parser');
@ -10,6 +12,13 @@ const morgan = require('morgan');
const cors = require('cors'); const cors = require('cors');
const passport = require('passport'); const passport = require('passport');
const server = http.createServer(app);
const io = socketIo(server, {
cors: {
origin: '*',
}
});
const PORT = 8081; const PORT = 8081;
const config = JSON.parse(fs.readFileSync("config.json")); const config = JSON.parse(fs.readFileSync("config.json"));
@ -56,9 +65,12 @@ app.use(cors());
app.use('/user', require('./routes/user')); app.use('/user', require('./routes/user'));
app.use('/campaign', require('./routes/campaign')); app.use('/campaign', require('./routes/campaign'));
app.use('/public', express.static('uploads'));
require('./io/campaign')(io);
// app.use('/users', require('./routes/users')); // app.use('/users', require('./routes/users'));
app.listen(PORT, () => { server.listen(PORT, () => {
console.log("Dragonroll backend started"); console.log("Dragonroll backend started");
}); });
app.use('/public', express.static('uploads'));

6
server/utils/filters.js Normal file
View File

@ -0,0 +1,6 @@
module.exports = user => {
let filterUser = JSON.parse(JSON.stringify(user));
delete filterUser['password'];
delete filterUser['email'];
return filterUser;
}