1
0
forked from noxious/client
This commit is contained in:
Dennis Postma 2024-05-28 21:54:05 +02:00
parent 9ef697d812
commit da728a1fc6
11 changed files with 242 additions and 85 deletions

196
package-lock.json generated
View File

@ -9,11 +9,14 @@
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"@vueuse/core": "^10.9.0", "@vueuse/core": "^10.9.0",
"@vueuse/integrations": "^10.10.0",
"axios": "^1.6.8", "axios": "^1.6.8",
"phaser": "^3.80.1", "phaser": "^3.80.1",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"socket.io-client": "^4.7.5", "socket.io-client": "^4.7.5",
"vue": "^3.4.21" "universal-cookie": "^6.1.3",
"vue": "^3.4.21",
"zod": "^3.23.8"
}, },
"devDependencies": { "devDependencies": {
"@rushstack/eslint-patch": "^1.3.3", "@rushstack/eslint-patch": "^1.3.3",
@ -1729,6 +1732,12 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/cookie": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
"integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==",
"license": "MIT"
},
"node_modules/@types/estree": { "node_modules/@types/estree": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
@ -2456,14 +2465,14 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@vueuse/core": { "node_modules/@vueuse/core": {
"version": "10.9.0", "version": "10.10.0",
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.9.0.tgz", "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.10.0.tgz",
"integrity": "sha512-/1vjTol8SXnx6xewDEKfS0Ra//ncg4Hb0DaZiwKf7drgfMsKFExQ+FnnENcN6efPen+1kIzhLQoGSy0eDUVOMg==", "integrity": "sha512-vexJ/YXYs2S42B783rI95lMt3GzEwkxzC8Hb0Ndpd8rD+p+Lk/Za4bd797Ym7yq4jXqdSyj3JLChunF/vyYjUw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@types/web-bluetooth": "^0.0.20", "@types/web-bluetooth": "^0.0.20",
"@vueuse/metadata": "10.9.0", "@vueuse/metadata": "10.10.0",
"@vueuse/shared": "10.9.0", "@vueuse/shared": "10.10.0",
"vue-demi": ">=0.14.7" "vue-demi": ">=0.14.7"
}, },
"funding": { "funding": {
@ -2496,19 +2505,111 @@
} }
} }
}, },
"node_modules/@vueuse/integrations": {
"version": "10.10.0",
"resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-10.10.0.tgz",
"integrity": "sha512-vHGeK7X6mkdkpcm1eE9t3Cpm21pNVfZRwrjwwbrEs9XftnSgszF4831G2rei8Dt9cIYJIfFV+iyx/29muimJPQ==",
"license": "MIT",
"dependencies": {
"@vueuse/core": "10.10.0",
"@vueuse/shared": "10.10.0",
"vue-demi": ">=0.14.7"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"async-validator": "*",
"axios": "*",
"change-case": "*",
"drauu": "*",
"focus-trap": "*",
"fuse.js": "*",
"idb-keyval": "*",
"jwt-decode": "*",
"nprogress": "*",
"qrcode": "*",
"sortablejs": "*",
"universal-cookie": "*"
},
"peerDependenciesMeta": {
"async-validator": {
"optional": true
},
"axios": {
"optional": true
},
"change-case": {
"optional": true
},
"drauu": {
"optional": true
},
"focus-trap": {
"optional": true
},
"fuse.js": {
"optional": true
},
"idb-keyval": {
"optional": true
},
"jwt-decode": {
"optional": true
},
"nprogress": {
"optional": true
},
"qrcode": {
"optional": true
},
"sortablejs": {
"optional": true
},
"universal-cookie": {
"optional": true
}
}
},
"node_modules/@vueuse/integrations/node_modules/vue-demi": {
"version": "0.14.7",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz",
"integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==",
"hasInstallScript": true,
"license": "MIT",
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/@vueuse/metadata": { "node_modules/@vueuse/metadata": {
"version": "10.9.0", "version": "10.10.0",
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.9.0.tgz", "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.10.0.tgz",
"integrity": "sha512-iddNbg3yZM0X7qFY2sAotomgdHK7YJ6sKUvQqbvwnf7TmaVPxS4EJydcNsVejNdS8iWCtDk+fYXr7E32nyTnGA==", "integrity": "sha512-UNAo2sTCAW5ge6OErPEHb5z7NEAg3XcO9Cj7OK45aZXfLLH1QkexDcZD77HBi5zvEiLOm1An+p/4b5K3Worpug==",
"license": "MIT", "license": "MIT",
"funding": { "funding": {
"url": "https://github.com/sponsors/antfu" "url": "https://github.com/sponsors/antfu"
} }
}, },
"node_modules/@vueuse/shared": { "node_modules/@vueuse/shared": {
"version": "10.9.0", "version": "10.10.0",
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.9.0.tgz", "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.10.0.tgz",
"integrity": "sha512-Uud2IWncmAfJvRaFYzv5OHDli+FbOzxiVEQdLCKQKLyhz94PIyFC3CHcH7EDMwIn8NPtD06+PNbC/PiO0LGLtw==", "integrity": "sha512-2aW33Ac0Uk0U+9yo3Ypg9s5KcR42cuehRWl7vnUHadQyFvCktseyxxEPBi1Eiq4D2yBGACOnqLZpx1eMc7g5Og==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"vue-demi": ">=0.14.7" "vue-demi": ">=0.14.7"
@ -2833,9 +2934,9 @@
} }
}, },
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001621", "version": "1.0.30001624",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001621.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001624.tgz",
"integrity": "sha512-+NLXZiviFFKX0fk8Piwv3PfLPGtRqJeq2TiNoUff/qB5KJgwecJTvCXDpmlyP/eCI/GUEmp/h/y5j0yckiiZrA==", "integrity": "sha512-0dWnQG87UevOCPYaOR49CBcLBwoZLpws+k6W37nLjWUhumP1Isusj0p2u+3KhjNloRWK9OKMgjBBzPujQHw4nA==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@ -3021,6 +3122,15 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/cookie": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
"integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/cross-fetch": { "node_modules/cross-fetch": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz",
@ -3072,6 +3182,13 @@
"node": ">=18" "node": ">=18"
} }
}, },
"node_modules/cssstyle/node_modules/rrweb-cssom": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz",
"integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==",
"dev": true,
"license": "MIT"
},
"node_modules/csstype": { "node_modules/csstype": {
"version": "3.1.3", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
@ -4498,9 +4615,9 @@
} }
}, },
"node_modules/jsdom": { "node_modules/jsdom": {
"version": "24.0.0", "version": "24.1.0",
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.0.0.tgz", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.1.0.tgz",
"integrity": "sha512-UDS2NayCvmXSXVP6mpTj+73JnNQadZlr9N68189xib2tx5Mls7swlTNao26IoHv46BZJFvXygyRtyXd1feAk1A==", "integrity": "sha512-6gpM7pRXCwIOKxX47cgOyvyQDN/Eh0f1MeKySBV2xGdKtqJBLj8P25eY3EVCWo2mglDDzozR2r2MW4T+JiNUZA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -4509,21 +4626,21 @@
"decimal.js": "^10.4.3", "decimal.js": "^10.4.3",
"form-data": "^4.0.0", "form-data": "^4.0.0",
"html-encoding-sniffer": "^4.0.0", "html-encoding-sniffer": "^4.0.0",
"http-proxy-agent": "^7.0.0", "http-proxy-agent": "^7.0.2",
"https-proxy-agent": "^7.0.2", "https-proxy-agent": "^7.0.4",
"is-potential-custom-element-name": "^1.0.1", "is-potential-custom-element-name": "^1.0.1",
"nwsapi": "^2.2.7", "nwsapi": "^2.2.10",
"parse5": "^7.1.2", "parse5": "^7.1.2",
"rrweb-cssom": "^0.6.0", "rrweb-cssom": "^0.7.0",
"saxes": "^6.0.0", "saxes": "^6.0.0",
"symbol-tree": "^3.2.4", "symbol-tree": "^3.2.4",
"tough-cookie": "^4.1.3", "tough-cookie": "^4.1.4",
"w3c-xmlserializer": "^5.0.0", "w3c-xmlserializer": "^5.0.0",
"webidl-conversions": "^7.0.0", "webidl-conversions": "^7.0.0",
"whatwg-encoding": "^3.1.1", "whatwg-encoding": "^3.1.1",
"whatwg-mimetype": "^4.0.0", "whatwg-mimetype": "^4.0.0",
"whatwg-url": "^14.0.0", "whatwg-url": "^14.0.0",
"ws": "^8.16.0", "ws": "^8.17.0",
"xml-name-validator": "^5.0.0" "xml-name-validator": "^5.0.0"
}, },
"engines": { "engines": {
@ -5788,9 +5905,9 @@
} }
}, },
"node_modules/rrweb-cssom": { "node_modules/rrweb-cssom": {
"version": "0.6.0", "version": "0.7.0",
"resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.0.tgz",
"integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", "integrity": "sha512-KlSv0pm9kgQSRxXEMgtivPJ4h826YHsuob8pSHcfSZsSXGtvpEAie8S0AnXuObEJ7nhikOb4ahwxDm0H2yW17g==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
@ -6387,6 +6504,16 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/universal-cookie": {
"version": "6.1.3",
"resolved": "https://registry.npmjs.org/universal-cookie/-/universal-cookie-6.1.3.tgz",
"integrity": "sha512-AETYRrhpRgl9T1YtnODmQE32G81U3A+f3HO3ZeK7efbXqe3x+RNOW4RTpV0iff7zJWhGYJA6EI0Mm+w50aFTAw==",
"license": "MIT",
"dependencies": {
"@types/cookie": "^0.6.0",
"cookie": "^0.6.0"
}
},
"node_modules/universalify": { "node_modules/universalify": {
"version": "0.2.0", "version": "0.2.0",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
@ -6457,9 +6584,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/vite": { "node_modules/vite": {
"version": "5.2.11", "version": "5.2.12",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.2.11.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.12.tgz",
"integrity": "sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==", "integrity": "sha512-/gC8GxzxMK5ntBwb48pR32GGhENnjtY30G4A0jemunsBkiEZFw60s8InGpN8gkhHEkjnRK1aSAxeQgwvFhUHAA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -7065,6 +7192,15 @@
"funding": { "funding": {
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
},
"node_modules/zod": {
"version": "3.23.8",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz",
"integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
} }
} }
} }

View File

@ -16,11 +16,14 @@
}, },
"dependencies": { "dependencies": {
"@vueuse/core": "^10.9.0", "@vueuse/core": "^10.9.0",
"@vueuse/integrations": "^10.10.0",
"axios": "^1.6.8", "axios": "^1.6.8",
"phaser": "^3.80.1", "phaser": "^3.80.1",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"socket.io-client": "^4.7.5", "socket.io-client": "^4.7.5",
"vue": "^3.4.21" "universal-cookie": "^6.1.3",
"vue": "^3.4.21",
"zod": "^3.23.8"
}, },
"devDependencies": { "devDependencies": {
"@rushstack/eslint-patch": "^1.3.3", "@rushstack/eslint-patch": "^1.3.3",

View File

@ -17,11 +17,11 @@ const screen:Ref<string> = ref('login');
const socket = useSocketStore(); const socket = useSocketStore();
socket.$subscribe((mutation, state) => { socket.$subscribe((mutation, state) => {
if (!state.isAuthenticated) { if (!state.connection) {
screen.value = 'login'; screen.value = 'login';
} }
if (state.isAuthenticated){ if (state.connection){
screen.value = 'characters'; screen.value = 'characters';
if (state.character) { if (state.character) {

View File

@ -26,9 +26,14 @@ import { useSocketStore } from '@/stores/socket'
import Hud from '@/components/game/Hud.vue' import Hud from '@/components/game/Hud.vue'
import Chat from '@/components/game/Chat.vue' import Chat from '@/components/game/Chat.vue'
import Menubar from '@/components/game/Menu.vue' import Menubar from '@/components/game/Menu.vue'
import { onUnmounted } from 'vue'
const socket = useSocketStore(); const socket = useSocketStore();
onUnmounted(() => {
socket.disconnectSocket();
})
const gameConfig = { const gameConfig = {
name: 'New Quest', name: 'New Quest',
width: window.innerWidth, width: window.innerWidth,
@ -46,8 +51,8 @@ const bootGame = (game: Phaser.Game) => {
const preloadScene = (scene: Phaser.Scene) => { const preloadScene = (scene: Phaser.Scene) => {
/** /**
* @TODO * @TODO
* Write logic that downloads all assets from out websocket server in base64 format * Write logic that downloads all assets from out websocket or http server in base64 format
* Don't forget to check how intensive that operation is for performance * Don't forget to check how intensive that operation is with sockets for performance
*/ */
scene.load.image('tiles', '/assets/tiles/default.png'); scene.load.image('tiles', '/assets/tiles/default.png');
scene.load.image('waypoint', '/assets/waypoint.png'); scene.load.image('waypoint', '/assets/waypoint.png');

View File

@ -49,12 +49,12 @@ watch (() => zoneStore.tiles, () => { // @TODO : change to tiles for when loadin
// Load the zone from the server // Load the zone from the server
onBeforeMount(() => { onBeforeMount(() => {
socket.socket?.emit('character:connect'); socket.connection?.emit('character:connect');
socket.socket?.emit('character:zone:load'); socket.connection?.emit('character:zone:load');
}) })
// Listen for the zone event from the server and load the zone // Listen for the zone event from the server and load the zone
socket.socket?.on('character:zone:load', (data) => { socket.connection?.on('character:zone:load', (data) => {
console.log('character:zone:load', data); console.log('character:zone:load', data);
zoneStore.loadTiles(data.zone.tiles) zoneStore.loadTiles(data.zone.tiles)
/** /**
@ -66,22 +66,22 @@ socket.socket?.on('character:zone:load', (data) => {
// console.log(data.players[1]); // key is user id // console.log(data.players[1]); // key is user id
// //
// // remove self from the players list // // remove self from the players list
// delete data.players[socket.socket?.id]; // delete data.players[socket.connection?.id];
// //
// zoneStore.addPlayers(data.players); // zoneStore.addPlayers(data.players);
}) })
// Listen for player join events // Listen for player join events
socket.socket?.on('player_join', (data) => { socket.connection?.on('player_join', (data) => {
console.log('player_join', data) console.log('player_join', data)
if (data.id === socket.socket?.id) { if (data.id === socket.connection?.id) {
console.log('self'); console.log('self');
return; return;
} }
zoneStore.addPlayer(data); zoneStore.addPlayer(data);
}) })
socket.socket?.on('ping', (data) => { socket.connection?.on('ping', (data) => {
console.log('ping', data) console.log('ping', data)
}) })

View File

@ -26,7 +26,7 @@
import { useSocketStore } from '@/stores/socket' import { useSocketStore } from '@/stores/socket'
const socket = useSocketStore(); const socket = useSocketStore();
socket.getSocket.emit('characters:get'); socket.connection.emit('characters:get');
</script> </script>
<style lang="scss"> <style lang="scss">

View File

@ -1,41 +1,35 @@
<template> <template>
<audio ref="bgm" id="bgm" src="/assets/music/bgm.mp3" loop autoplay></audio>
<img src="/assets/bglogin.png" id="bg-img" alt="New Quest login background" />
<div class="content-wrapper"> <div class="content-wrapper">
<h1 class="main-title">NEW QUEST</h1> <h1 class="main-title">NEW QUEST</h1>
<div class="content-elements"> <div class="content-elements">
<div class="login-form"> <div class="login-form">
<form method="post"> <form method="post">
<div class="form-field"> <div class="form-field">
<label for="username">Username</label> <label for="username">Username</label>
<input v-model="username" type="text" name="username" required autofocus> <input id="username" v-model="username" type="text" name="username" required autofocus>
</div> </div>
<div class="form-field"> <div class="form-field">
<label for="password">Password</label> <label for="password">Password</label>
<input v-model="password" type="password" name="password" required> <input id="password" v-model="password" type="password" name="password" required>
</div> </div>
</form> </form>
</div> </div>
<div class="row-buttons"> <div class="row-buttons">
<button class="button" @click="loginFunc"> <button class="button" @click="loginFunc"><span>LOGIN</span></button>
<span>LOGIN</span> <button class="button" @click="registerFunc"><span>REGISTER</span></button>
</button> <button class="button"><span>CREDITS</span></button>
<button class="button" @click="registerFunc">
<span>REGISTER</span>
</button>
<button class="button">
<span>CREDITS</span>
</button>
</div> </div>
</div> </div>
</div> </div>
<audio ref="bgm" id="bgm" src="/assets/music/bgm.mp3" loop autoplay></audio>
<img src="/assets/bglogin.png" id="bg-img" alt="New Quest login background" />
</template> </template>
<script setup> <script setup>
import { onMounted, ref } from 'vue' import { onMounted, ref } from 'vue'
import { useSocketStore } from '@/stores/socket.ts' import { useSocketStore } from '@/stores/socket.ts'
import {login, register} from '@/services/authService' import {login, register} from '@/services/authService'
import { useCookies } from '@vueuse/integrations/useCookies'
const bgm = ref('bgm'); const bgm = ref('bgm');
if (bgm.value.paused) { if (bgm.value.paused) {
@ -43,6 +37,7 @@ if (bgm.value.paused) {
window.addEventListener('keydown', () => bgm.value.play()) window.addEventListener('keydown', () => bgm.value.play())
} }
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const socket = useSocketStore(); const socket = useSocketStore();
const username = ref(''); const username = ref('');
const password = ref(''); const password = ref('');
@ -54,11 +49,14 @@ async function loginFunc() {
return; return;
} }
// send register event to server // send login event to server
const success = await login(username.value, password.value); const success = await login(username.value, password.value);
if (!success) { if (!success) {
alert('Invalid username or password'); alert('Invalid username or password');
} }
// if (success) {}
} }
async function registerFunc() { async function registerFunc() {
@ -75,9 +73,7 @@ async function registerFunc() {
alert('Username already exists'); alert('Username already exists');
} }
if (success) { // if (success) {}
alert('User registered successfully, you can now log in!');
}
} }
</script> </script>

View File

@ -44,7 +44,7 @@ function onPointerClick(pointer: Phaser.Input.Pointer) {
position.x = worldPoint.x + config.tile_size.y; position.x = worldPoint.x + config.tile_size.y;
position.y = worldPoint.y; position.y = worldPoint.y;
socket.socket?.emit('move', { x: position.x, y: position.y }); socket.connection?.emit('move', { x: position.x, y: position.y });
} }
//Directions for player sprites + animations //Directions for player sprites + animations
@ -64,7 +64,7 @@ if (!props.player) {
scene.input.on(Phaser.Input.Events.POINTER_UP, onPointerClick); scene.input.on(Phaser.Input.Events.POINTER_UP, onPointerClick);
} }
socket.socket?.on('player_moved', (data) => { socket.connection?.on('player_moved', (data) => {
console.log('player_moved', data); console.log('player_moved', data);
if (data.id !== props.player?.id) { if (data.id !== props.player?.id) {

View File

@ -1,14 +1,16 @@
import axios from 'axios'; import axios from 'axios';
import config from '@/config'; import config from '@/config';
import { useSocketStore } from '@/stores/socket'; import { useSocketStore } from '@/stores/socket';
import { useCookies } from '@vueuse/integrations/useCookies'
export async function register(username: string, password: string, socketStore = useSocketStore()) { export async function register(username: string, password: string, socketStore = useSocketStore()) {
if (socketStore.getAuthenticated) return console.log('User already authenticated');
try { try {
const response = await axios.post(`${config.server_endpoint}/register`, { username, password }); const response = await axios.post(`${config.server_endpoint}/register`, { username, password });
console.log(response.data); if (response.status === 200) {
return true; useCookies().set('token', response.data.token as string)
await socketStore.setupSocketConnection();
return true;
}
} catch (error) { } catch (error) {
console.error('Error registering user:', error); console.error('Error registering user:', error);
return false; return false;
@ -16,13 +18,11 @@ export async function register(username: string, password: string, socketStore =
} }
export async function login(username: string, password: string, socketStore = useSocketStore()) { export async function login(username: string, password: string, socketStore = useSocketStore()) {
if (socketStore.getAuthenticated) return console.log('User already authenticated');
try { try {
const response = await axios.post(`${config.server_endpoint}/login`, { username, password }); const response = await axios.post(`${config.server_endpoint}/login`, { username, password });
if (response.status === 200) { if (response.status === 200) {
socketStore.isAuthenticated = true; useCookies().set('token', response.data.token as string)
socketStore.setupSocketConnection(username, password); await socketStore.setupSocketConnection();
return true; return true;
} }
} catch (error) { } catch (error) {

View File

@ -1,34 +1,42 @@
import { defineStore, type StoreDefinition } from 'pinia' import { defineStore, type StoreDefinition } from 'pinia'
import { io, Socket } from 'socket.io-client'; import { io, Socket } from 'socket.io-client';
import {useCookies} from '@vueuse/integrations/useCookies'
import config from '@/config'; import config from '@/config';
export const useSocketStore: StoreDefinition<any> = defineStore('socket', { export const useSocketStore: StoreDefinition<any> = defineStore('socket', {
state: () => ({ state: () => ({
socket: null as Socket | null, connection: null as Socket | null,
isAuthenticated: false,
character: null as any, character: null as any,
}), }),
getters: { getters: {
getSocket: (state: any) => state.socket, getConnection: (state: any) => state.connection,
getAuthenticated: (state: any) => state.isAuthenticated,
getCharacter: (state: any) => state.character, getCharacter: (state: any) => state.character,
}, },
actions: { actions: {
setupSocketConnection(username: string, password: string) { setupSocketConnection() {
this.socket = io(config.server_endpoint, { this.connection = io(config.server_endpoint, {
query: { username, password }, withCredentials: true,
transports: ['websocket'] transports: ['websocket'],
reconnectionAttempts: 5,
}); });
// Let the server know the user is logged in
this.connection.emit('login');
// When we can't reconnect, disconnect
this.connection.on('reconnect_failed', () => {
console.log("Reconnect failed")
this.disconnectSocket();
})
}, },
disconnectSocket() { disconnectSocket() {
if (!this.socket) { if (!this.connection) return;
return;
}
this.socket.disconnect(); this.connection.disconnect();
this.socket = null; this.connection = null;
this.character = null; this.character = null;
this.isAuthenticated = false;
useCookies().remove('token');
}, },
} }
}); });

9
src/types/user.ts Normal file
View File

@ -0,0 +1,9 @@
import { z } from "zod";
const UserObject = z.object({
username: z.string(),
});
type UserType = z.infer<typeof UserObject>;
export { UserObject, type UserType };