diff --git a/.vscode/launch.json b/.vscode/launch.json index 97ac4c63..10697ba5 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -6,17 +6,24 @@ "configurations": [ { "command": "npm run start:dev", - "name": "Run npm Auth dev", + "name": "Launch Auth", "request": "launch", "type": "node-terminal", "cwd": "${workspaceRoot}/auth", }, { "command": "npm run start:dev", - "name": "Launch Dev Server", + "name": "Launch Server", "request": "launch", "type": "node-terminal", "cwd": "${workspaceRoot}/server", + }, + { + "command": "npm run start", + "name": "Launch Client", + "request": "launch", + "type": "node-terminal", + "cwd": "${workspaceRoot}/client", } ] } \ No newline at end of file diff --git a/client/src/engine/gui/mainMenu.ts b/client/src/engine/gui/mainMenu.ts index 5da87983..b71a8309 100644 --- a/client/src/engine/gui/mainMenu.ts +++ b/client/src/engine/gui/mainMenu.ts @@ -1,4 +1,4 @@ -import { Color4, Engine, Scene, SceneLoader } from '@babylonjs/core' +import { Color3, Color4, Engine, Scene, SceneLoader, Animation } from '@babylonjs/core' import { FullScreenMenu } from './fullScreenMenu' import { Button, TextBlock, InputText, InputPassword } from '@babylonjs/gui' import dungeonEntrance from '../../../public/assets/models/Main_Menu_Background.glb' @@ -9,14 +9,18 @@ type MainMenuActions = { onQuitGame: () => void } -export class MainMenu extends FullScreenMenu { +export class Login extends FullScreenMenu { constructor(canvas: HTMLCanvasElement, engine: Engine, scene: Scene, action: () => Promise) { const menuId = 'main_menu' super(canvas, engine, menuId, new Color4(0.67, 0.47, 0.16), scene) const title = new TextBlock(`${menuId}__title`, 'Dungeon Delvers') + const colors = { + white: new Color3(1, 1, 1), + red: new Color3(1, 0, 0) + } title.fontSize = 48 title.width = '500px' - title.color = 'white' + title.color = '#ffffff' title.paddingBottom = '80px' const usernameLabel = new TextBlock( `${menuId}__username_label`, @@ -32,8 +36,35 @@ export class MainMenu extends FullScreenMenu { password.width = '500px' const login = Button.CreateSimpleButton(`${menuId}__login`, 'Login') login.width = '500px' - login.onPointerDownObservable.add(() => { - action() + login.onPointerDownObservable.add(async () => { + const login = async () => { + const response = await fetch('http://localhost:4000/login', { + method: 'POST', + mode: 'cors', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + username: username.text, + password: password.text + }) + }) + if (response.status === 200) { + return response.json() + + } else { + controls.forEach((control) => { + control.color = colors.red.toHexString() + }) + } + } + login().then((data) => { + if (data) { + const { token } = data; + localStorage.setItem('token', token); + action() + } + }) }) const controls = [ title, @@ -46,7 +77,7 @@ export class MainMenu extends FullScreenMenu { const buttonHeight = 60 controls.forEach((control, index) => { control.height = `${buttonHeight}px` - control.color = 'white' + control.color = colors.white.toHexString() control.paddingTop = '10px' control.paddingBottom = '10px' // Evenly space controls vertically based on index diff --git a/client/src/engine/index.ts b/client/src/engine/index.ts index b303f4bf..33dc1955 100644 --- a/client/src/engine/index.ts +++ b/client/src/engine/index.ts @@ -26,18 +26,20 @@ import { Stage } from './stage/stage' import { Player } from './player/player' import { PlayerInput } from './core/inputController' -import { MainMenu } from './gui/mainMenu' +import { Login } from './gui/mainMenu' import { CharacterSelect } from './gui/characterSelect' import { CharacterCreation } from './gui/characterCreation/characterCreation' import { CharacterModels, CharacterModelsProps } from './race/race' export enum GAME_STATE { - MAIN_MENU = 0, - SERVER_SELECT = 1, - CHARACTER_SELECT = 2, - PLAYING = 3, - CHARACTER_CREATION_RACE = 4, - CHARACTER_CREATION_CLASS = 5, + LOGIN = 0, + SIGN_UP = 1, + SERVER_SELECT = 2, + CHARACTER_SELECT = 3, + LOADING = 4, + PLAYING = 5, + CHARACTER_CREATION_RACE = 6, + CHARACTER_CREATION_CLASS = 7, } export class Game { // General Entire Application @@ -103,14 +105,26 @@ export class Game { } private async _main(): Promise { - const socket = io('http://localhost:4000') - - - await this._goToMenu() + const token = localStorage.getItem('token'); + if (!token) { + await this._goToLogin() + } + const res = await fetch('http://localhost:4000/self', { + mode: 'cors', + headers: { + authorization: `bearer ${token}` + } + }); + console.log(res) + if (res.status === 200) { + await this._goToCharacterSelect() + } else { + await this._goToLogin() + } // run the main render loop this._engine.runRenderLoop(() => { switch (this._state) { - case GAME_STATE.MAIN_MENU: + case GAME_STATE.LOGIN: this._scene.render() break case GAME_STATE.PLAYING: @@ -137,13 +151,8 @@ export class Game { }) } - private async _goToMenu() { - const mainMenu = new MainMenu(this._canvas, this._engine, this._scene, this.goToCharacterSelect.bind(this)) - // const characterSelect = new CharacterCreation( - // this._canvas, - // this._engine, - // this._scene, - // ) + private async _goToLogin() { + const mainMenu = new Login(this._canvas, this._engine, this._scene, this._goToCharacterSelect.bind(this)) this._scene = mainMenu.scene } @@ -157,8 +166,8 @@ export class Game { await this._loadCharacterAssets(scene) //character } - private async goToCharacterSelect() { - const characterSelect = new CharacterSelect(this._canvas, this._engine, this._scene, this.goToCharacterCreation.bind(this )) + private async _goToCharacterSelect() { + const characterSelect = new CharacterSelect(this._canvas, this._engine, this._scene, this.goToCharacterCreation.bind(this)) this._scene = characterSelect.scene } @@ -249,7 +258,7 @@ export class Game { guiMenu.addControl(mainBtn) //this handles interactions with the start button attached to the scene mainBtn.onPointerUpObservable.add(() => { - this._goToMenu() + this._goToLogin() }) //--SCENE FINISHED LOADING-- diff --git a/package-lock.json b/package-lock.json index 703e98aa..2d76ca8d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7723,6 +7723,7 @@ "version": "2.8.5", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "license": "MIT", "dependencies": { "object-assign": "^4", "vary": "^1" @@ -15328,6 +15329,7 @@ "@types/passport": "^1.0.16", "@types/passport-jwt": "^4.0.1", "body-parser": "^1.20.2", + "cors": "^2.8.5", "dotenv": "^16.4.5", "express": "^4.19.2", "jsonwebtoken": "^9.0.2", diff --git a/server/package.json b/server/package.json index e0817a69..93aea33d 100644 --- a/server/package.json +++ b/server/package.json @@ -21,6 +21,7 @@ "@types/passport": "^1.0.16", "@types/passport-jwt": "^4.0.1", "body-parser": "^1.20.2", + "cors": "^2.8.5", "dotenv": "^16.4.5", "express": "^4.19.2", "jsonwebtoken": "^9.0.2", diff --git a/server/server.ts b/server/server.ts index 84cebd81..28e16b7e 100644 --- a/server/server.ts +++ b/server/server.ts @@ -1,14 +1,13 @@ -import express from "express"; -import { type Request, type Response } from "express"; import { createServer } from "node:http"; -import { dirname, join } from "node:path"; -import { fileURLToPath } from "node:url"; -import passport from "passport"; +import { Server } from "socket.io"; import { Strategy as JwtStrategy, ExtractJwt } from "passport-jwt"; +import { type Request, type Response } from "express"; import bodyParser from "body-parser"; -import { Server } from "socket.io"; -import jwt from "jsonwebtoken"; +import cors from 'cors'; import dotenv from "dotenv"; +import express from "express"; +import jwt from "jsonwebtoken"; +import passport from "passport"; declare global { namespace Express { @@ -25,7 +24,7 @@ const jwtSecret = process.env.JWT_SECRET || 'Mys3cr3t' const app = express(); const httpServer = createServer(app); - +app.use(cors()) app.use(bodyParser.json()); app.get(