added handler for login
This commit is contained in:
parent
ecc319b529
commit
9686276ece
9
.prettierrc
Normal file
9
.prettierrc
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"jsxSingleQuote": true,
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"printWidth": 120,
|
||||
"tabWidth": 4,
|
||||
"trailingComma": "es5",
|
||||
"arrowParens": "avoid"
|
||||
}
|
||||
85
backend/handlers/playerHandler.js
Normal file
85
backend/handlers/playerHandler.js
Normal file
@ -0,0 +1,85 @@
|
||||
const RoomModel = require('../schemas/room');
|
||||
const { colors } = require('../utils/constants');
|
||||
const { getStartPositions } = require('../utils/functions');
|
||||
|
||||
module.exports = (io, socket) => {
|
||||
const req = socket.request;
|
||||
const login = data => {
|
||||
// When new player login to game we are looking for not full and not started room to put player there
|
||||
RoomModel.findOne({ full: false, started: false }, function (err, room) {
|
||||
if (room) {
|
||||
// If there is one adds player to it
|
||||
addPlayerToExistingRoom(room, data);
|
||||
} else {
|
||||
// If not creates new room and add player to it
|
||||
createNewRoom(data);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
socket.on('player:login', login);
|
||||
|
||||
function createNewRoom(data) {
|
||||
const room = new RoomModel({
|
||||
createDate: new Date(),
|
||||
players: [
|
||||
{
|
||||
name: data.name,
|
||||
color: colors[0],
|
||||
},
|
||||
],
|
||||
pawns: getStartPositions(),
|
||||
});
|
||||
// Saves new room to database
|
||||
room.save().then(() => {
|
||||
// Since it is not bound to an HTTP request, the session must be manually reloaded and saved
|
||||
req.session.reload(err => {
|
||||
if (err) return socket.disconnect();
|
||||
// Saving session data
|
||||
req.session.roomId = room._id;
|
||||
req.session.playerId = room.players[0]._id;
|
||||
req.session.color = room.players[0].color;
|
||||
req.session.save();
|
||||
// Sending data to the user, after which player will be redirected to the game
|
||||
socket.emit('player:data', JSON.stringify(req.session));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function addPlayerToExistingRoom(room, data) {
|
||||
// Adding a new user to the room
|
||||
room.players.push({
|
||||
name: data.name,
|
||||
ready: false,
|
||||
color: colors[room.players.length],
|
||||
});
|
||||
const updatedRoom = { players: room.players };
|
||||
// Checking if the room is full
|
||||
if (room.players.length === 4) {
|
||||
// Changes the properties of the room to the state to start the game
|
||||
updatedRoom = {
|
||||
...updatedRoom,
|
||||
full: true,
|
||||
started: true,
|
||||
nextMoveTime: Date.now() + 15000,
|
||||
pawns: getStartPositions(),
|
||||
};
|
||||
updatedRoom.players.forEach(player => (player.ready = true));
|
||||
updatedRoom.players[0].nowMoving = true;
|
||||
}
|
||||
// Updates a room in the database
|
||||
RoomModel.findOneAndUpdate({ _id: room._id }, updatedRoom).then(() => {
|
||||
// Since it is not bound to an HTTP request, the session must be manually reloaded and saved
|
||||
req.session.reload(err => {
|
||||
if (err) return socket.disconnect();
|
||||
// Saving session data
|
||||
req.session.roomId = room._id;
|
||||
req.session.playerId = updatedRoom.players[updatedRoom.players.length - 1]._id;
|
||||
req.session.color = colors[updatedRoom.players.length - 1];
|
||||
req.session.save();
|
||||
// Sending data to the user, after which player will be redirected to the game
|
||||
socket.emit('player:data', JSON.stringify(req.session));
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
1626
backend/package-lock.json
generated
1626
backend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,7 @@
|
||||
"dependencies": {
|
||||
"body-parser": "^1.19.0",
|
||||
"connect-mongo": "^4.4.0",
|
||||
"connect-mongodb-session": "^2.4.1",
|
||||
"connect-mongodb-session": "^3.1.1",
|
||||
"cookie-parser": "^1.4.5",
|
||||
"cors": "^2.8.5",
|
||||
"express": "^4.17.1",
|
||||
|
||||
@ -1,125 +1,47 @@
|
||||
const express = require('express');
|
||||
const express = require("express");
|
||||
const router = express.Router();
|
||||
const RoomModel = require('../schemas/room');
|
||||
const RoomModel = require("../schemas/room");
|
||||
|
||||
const colors = ['red','blue','green','yellow'];
|
||||
|
||||
function getStartPositions(){
|
||||
const startPositions = [];
|
||||
for( let i = 0; i < 16; i++){
|
||||
let pawn = {};
|
||||
pawn.basePos = i;
|
||||
pawn.position = i;
|
||||
if(i < 4) pawn.color = colors[0];
|
||||
else if(i < 8) pawn.color = colors[1];
|
||||
else if(i < 12) pawn.color = colors[2];
|
||||
else if (i < 16) pawn.color = colors[3]
|
||||
startPositions.push(pawn);
|
||||
}
|
||||
return startPositions;
|
||||
}
|
||||
|
||||
//creating new room in db
|
||||
router.post('/add', function (req, res) {
|
||||
RoomModel.findOne( { full: false, started: false }, function (err, results) {
|
||||
if (err) console.log(err);
|
||||
if (!results) {
|
||||
let newRoom = new RoomModel({
|
||||
createDate: new Date,
|
||||
full: false,
|
||||
started: false,
|
||||
players: [{
|
||||
name: req.body.name,
|
||||
nowMoving: false,
|
||||
ready: false,
|
||||
color: colors[0]
|
||||
}],
|
||||
pawns: getStartPositions(),
|
||||
});
|
||||
newRoom.save()
|
||||
.then(function(){
|
||||
req.session.roomId = newRoom._id;
|
||||
req.session.playerId = newRoom.players[0]._id;
|
||||
req.session.color = newRoom.players[0].color;
|
||||
res.status(200).send(req.session.playerId);
|
||||
})
|
||||
.catch(err => res.status(400).json('Error: ' + err))
|
||||
}else {
|
||||
let players = results.players;
|
||||
|
||||
players.push({
|
||||
name: req.body.name,
|
||||
ready: false,
|
||||
color: colors[players.length]
|
||||
});
|
||||
|
||||
let updateObj = { players: players }
|
||||
// Checks if room is full => if true start game
|
||||
if (players.length === 4) {
|
||||
updateObj.full = true; // Room is full
|
||||
updateObj.started = true; // Game started
|
||||
updateObj.nextMoveTime = Date.now() + 15000;
|
||||
updateObj.players.forEach(player => player.ready = true);
|
||||
updateObj.players[0].nowMoving = true; //First joined player moving
|
||||
updateObj.pawns = getStartPositions();
|
||||
}
|
||||
RoomModel.findOneAndUpdate(
|
||||
{ _id: results._id }, //find room by id
|
||||
updateObj)
|
||||
.then(()=>{
|
||||
req.session.roomId = results._id;
|
||||
req.session.playerId = updateObj.players[updateObj.players.length-1]._id;
|
||||
req.session.color = colors[updateObj.players.length-1];
|
||||
res.status(200).send(req.session.playerId);
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
//get room values
|
||||
router.get('/', function(req,res){
|
||||
router.get("/", function (req, res) {
|
||||
RoomModel.findOne(
|
||||
{ _id: req.session.roomId }, //find room by id
|
||||
function (err, docs) {
|
||||
if (err){
|
||||
console.log(err)
|
||||
}
|
||||
else{
|
||||
if(docs){
|
||||
if(docs.nextMoveTime <= Date.now()){
|
||||
RoomModel.findOne({_id: req.session.roomId}, function (err, doc){
|
||||
if (err) {
|
||||
console.log(err);
|
||||
} else {
|
||||
if (docs) {
|
||||
if (docs.nextMoveTime <= Date.now()) {
|
||||
RoomModel.findOne({ _id: req.session.roomId }, function (err, doc) {
|
||||
if (err) {
|
||||
res.status(500).send(err)
|
||||
res.status(500).send(err);
|
||||
} else {
|
||||
const index = doc.players.findIndex( player => player.nowMoving === true);
|
||||
const index = doc.players.findIndex(player => player.nowMoving === true);
|
||||
const roomSize = doc.players.length;
|
||||
doc.players[index].nowMoving = false;
|
||||
if(index + 1 === roomSize){
|
||||
if (index + 1 === roomSize) {
|
||||
doc.players[0].nowMoving = true;
|
||||
}else{
|
||||
} else {
|
||||
doc.players[index + 1].nowMoving = true;
|
||||
}
|
||||
doc.nextMoveTime = Date.now()+15000;
|
||||
RoomModel.findOneAndUpdate({_id: req.session.roomId}, doc, function(err, docs){
|
||||
if(err){
|
||||
res.status(500).send(err)
|
||||
}else{
|
||||
doc.nextMoveTime = Date.now() + 15000;
|
||||
RoomModel.findOneAndUpdate({ _id: req.session.roomId }, doc, function (err, docs) {
|
||||
if (err) {
|
||||
res.status(500).send(err);
|
||||
} else {
|
||||
res.send(docs);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
}else{
|
||||
} else {
|
||||
res.send(docs);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
||||
@ -4,22 +4,26 @@ var Schema = mongoose.Schema;
|
||||
|
||||
var RoomSchema = new Schema({
|
||||
createDate: Date,
|
||||
started: Boolean,
|
||||
full: Boolean,
|
||||
started: { type: Boolean, default: false },
|
||||
full: { type: Boolean, default: false },
|
||||
nextMoveTime: Number,
|
||||
players: [{
|
||||
name: String,
|
||||
color: String,
|
||||
ready: Boolean,
|
||||
nowMoving: Boolean,
|
||||
}],
|
||||
pawns: [{
|
||||
color: String,
|
||||
basePos: Number,
|
||||
position: Number,
|
||||
}],
|
||||
players: [
|
||||
{
|
||||
name: String,
|
||||
color: String,
|
||||
ready: { type: Boolean, default: false },
|
||||
nowMoving: { type: Boolean, default: false },
|
||||
},
|
||||
],
|
||||
pawns: [
|
||||
{
|
||||
color: String,
|
||||
basePos: Number,
|
||||
position: Number,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
var RoomModel = mongoose.model('RoomModel', RoomSchema );
|
||||
var RoomModel = mongoose.model('RoomModel', RoomSchema);
|
||||
|
||||
module.exports = RoomModel;
|
||||
@ -1,66 +1,97 @@
|
||||
const express = require("express");
|
||||
const cors = require("cors");
|
||||
const cookieParser = require("cookie-parser");
|
||||
const { sessionMiddleware, wrap } = require("./controllers/serverController");
|
||||
const express = require('express');
|
||||
const cors = require('cors');
|
||||
const cookieParser = require('cookie-parser');
|
||||
const { sessionMiddleware, wrap } = require('./controllers/serverController');
|
||||
const registerPlayerHandlers = require('./handlers/playerHandler');
|
||||
const PORT = 8080;
|
||||
const mongoose = require('mongoose');
|
||||
const CONNECTION_URI = require('./credentials.js');
|
||||
const app = express();
|
||||
|
||||
app.use(cookieParser());
|
||||
app.use(
|
||||
express.urlencoded({
|
||||
extended: true,
|
||||
})
|
||||
express.urlencoded({
|
||||
extended: true,
|
||||
})
|
||||
);
|
||||
app.use(express.json());
|
||||
app.set("trust proxy", 1);
|
||||
app.set('trust proxy', 1);
|
||||
app.use(
|
||||
cors({
|
||||
origin: "http://localhost:3000",
|
||||
credentials: true,
|
||||
})
|
||||
cors({
|
||||
origin: 'http://localhost:3000',
|
||||
credentials: true,
|
||||
})
|
||||
);
|
||||
const PORT = 5000;
|
||||
app.use(sessionMiddleware);
|
||||
//DATABASE CONFIG
|
||||
const mongoose = require("mongoose");
|
||||
mongoose.set("useFindAndModify", false);
|
||||
const CONNECTION_URI = require("./credentials.js");
|
||||
|
||||
mongoose.set('useFindAndModify', false);
|
||||
mongoose
|
||||
.connect(CONNECTION_URI, {
|
||||
useNewUrlParser: true,
|
||||
useUnifiedTopology: true,
|
||||
})
|
||||
.then(() => {
|
||||
console.log("MongoDB Connected…");
|
||||
})
|
||||
.catch((err) => console.error(err));
|
||||
.connect(CONNECTION_URI, {
|
||||
useNewUrlParser: true,
|
||||
useUnifiedTopology: true,
|
||||
})
|
||||
.then(() => {
|
||||
console.log('MongoDB Connected…');
|
||||
})
|
||||
.catch(err => console.error(err));
|
||||
|
||||
//SESSION CONFIG
|
||||
|
||||
if (process.env.NODE_ENV === "production") {
|
||||
app.use(express.static("/app/build"));
|
||||
app.get("/", (req, res) => {
|
||||
res.sendFile("/app/build/index.html");
|
||||
});
|
||||
}
|
||||
const server = app.listen(PORT, () => {
|
||||
console.log("Server runs on port " + PORT);
|
||||
console.log('Server runs on port ' + PORT);
|
||||
});
|
||||
const io = require("socket.io")(server, {
|
||||
cors: {
|
||||
origin: "http://localhost:3000",
|
||||
credentials: true,
|
||||
},
|
||||
|
||||
const io = require('socket.io')(server, {
|
||||
cors: {
|
||||
origin: 'http://localhost:3000',
|
||||
credentials: true,
|
||||
},
|
||||
allowRequest: (req, callback) => {
|
||||
const fakeRes = {
|
||||
getHeader() {
|
||||
return [];
|
||||
},
|
||||
setHeader(key, values) {
|
||||
req.cookieHolder = values[0];
|
||||
},
|
||||
writeHead() {},
|
||||
};
|
||||
sessionMiddleware(req, fakeRes, () => {
|
||||
if (req.session) {
|
||||
fakeRes.writeHead();
|
||||
req.session.save();
|
||||
}
|
||||
callback(null, true);
|
||||
});
|
||||
},
|
||||
});
|
||||
io.engine.on('initial_headers', (headers, req) => {
|
||||
if (req.cookieHolder) {
|
||||
headers['set-cookie'] = req.cookieHolder;
|
||||
delete req.cookieHolder;
|
||||
}
|
||||
});
|
||||
io.use(wrap(sessionMiddleware));
|
||||
io.on("connection", (socket) => {
|
||||
socket.emit("client data", JSON.stringify(socket.request.session));
|
||||
|
||||
io.on('connection', socket => {
|
||||
registerPlayerHandlers(io, socket);
|
||||
if (socket.request.session.roomId) {
|
||||
socket.join(socket.request.session.roomId);
|
||||
socket.emit('player:data', JSON.stringify(session));
|
||||
io.to(socket.request.session.roomId).emit('player joined');
|
||||
}
|
||||
});
|
||||
|
||||
//ROUTES CONFIG
|
||||
const roomRoutes = require("./routes/room");
|
||||
const playerRoutes = require("./routes/player");
|
||||
const gameRoutes = require("./routes/game");
|
||||
const roomRoutes = require('./routes/room');
|
||||
const playerRoutes = require('./routes/player');
|
||||
const gameRoutes = require('./routes/game');
|
||||
|
||||
app.use("/player", playerRoutes);
|
||||
app.use("/room", roomRoutes);
|
||||
app.use("/game", gameRoutes);
|
||||
app.use('/player', playerRoutes);
|
||||
app.use('/room', roomRoutes);
|
||||
app.use('/game', gameRoutes);
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
app.use(express.static('/app/build'));
|
||||
app.get('/', (req, res) => {
|
||||
res.sendFile('/app/build/index.html');
|
||||
});
|
||||
}
|
||||
|
||||
2
backend/utils/constants.js
Normal file
2
backend/utils/constants.js
Normal file
@ -0,0 +1,2 @@
|
||||
const colors = ["red", "blue", "green", "yellow"];
|
||||
module.exports = { colors };
|
||||
16
backend/utils/functions.js
Normal file
16
backend/utils/functions.js
Normal file
@ -0,0 +1,16 @@
|
||||
const { colors } = require("./constants");
|
||||
function getStartPositions() {
|
||||
const startPositions = [];
|
||||
for (let i = 0; i < 16; i++) {
|
||||
let pawn = {};
|
||||
pawn.basePos = i;
|
||||
pawn.position = i;
|
||||
if (i < 4) pawn.color = colors[0];
|
||||
else if (i < 8) pawn.color = colors[1];
|
||||
else if (i < 12) pawn.color = colors[2];
|
||||
else if (i < 16) pawn.color = colors[3];
|
||||
startPositions.push(pawn);
|
||||
}
|
||||
return startPositions;
|
||||
}
|
||||
module.exports = { getStartPositions };
|
||||
22121
package-lock.json
generated
22121
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
104
src/App.js
104
src/App.js
@ -1,73 +1,51 @@
|
||||
import React, { useEffect, useState, createContext } from "react";
|
||||
import axios from "axios";
|
||||
import { io } from "socket.io-client";
|
||||
import { Beforeunload } from "react-beforeunload";
|
||||
import {
|
||||
BrowserRouter as Router,
|
||||
Route,
|
||||
Redirect,
|
||||
Switch,
|
||||
} from "react-router-dom";
|
||||
import React, { useEffect, useState, createContext } from 'react';
|
||||
import { io } from 'socket.io-client';
|
||||
import { BrowserRouter as Router, Route, Redirect, Switch } from 'react-router-dom';
|
||||
|
||||
import Gameboard from "./components/Gameboard";
|
||||
import NameInput from "./components/NameInput";
|
||||
import Gameboard from './components/Gameboard';
|
||||
import NameInput from './components/NameInput';
|
||||
|
||||
export const PlayerDataContext = createContext();
|
||||
export const SocketContext = createContext();
|
||||
|
||||
function App() {
|
||||
const [playerData, setPlayerData] = useState();
|
||||
const [redirect, setRedirect] = useState();
|
||||
const [playerData, setPlayerData] = useState();
|
||||
const [playerSocket, setPlayerSocket] = useState();
|
||||
const [redirect, setRedirect] = useState();
|
||||
|
||||
useEffect(() => {
|
||||
const socket = io("http://localhost:5000", { withCredentials: true });
|
||||
socket.on("client data", (data) => {
|
||||
data = JSON.parse(data);
|
||||
setPlayerData(data);
|
||||
data.roomId != null ? setRedirect(true) : setRedirect(false);
|
||||
});
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
const socket = io('http://localhost:8080', { withCredentials: true });
|
||||
socket.on('player:data', data => {
|
||||
console.log(data);
|
||||
data = JSON.parse(data);
|
||||
setPlayerData(data);
|
||||
data.roomId != null ? setRedirect(true) : setRedirect(false);
|
||||
});
|
||||
setPlayerSocket(socket);
|
||||
}, []);
|
||||
|
||||
const handleExit = (e) => {
|
||||
e.preventDefault();
|
||||
window.addEventListener("unload", () => {
|
||||
axios.post("/player/exit", { withCredentials: true });
|
||||
});
|
||||
};
|
||||
|
||||
const idCallback = () => {
|
||||
axios
|
||||
.get("/player/", {
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response) => {
|
||||
setPlayerData(response.data);
|
||||
console.log(response.data);
|
||||
setRedirect(true);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Router>
|
||||
{redirect ? <Redirect to="/game" /> : <Redirect to="/login" />}
|
||||
<Switch>
|
||||
<Route exact path="/">
|
||||
LOADING...
|
||||
</Route>
|
||||
<Route path="/login">
|
||||
<NameInput idCallback={idCallback} />
|
||||
</Route>
|
||||
<Route path="/game">
|
||||
{playerData ? (
|
||||
<Beforeunload onBeforeunload={handleExit}>
|
||||
<PlayerDataContext.Provider value={playerData}>
|
||||
<Gameboard />
|
||||
</PlayerDataContext.Provider>
|
||||
</Beforeunload>
|
||||
) : null}
|
||||
</Route>
|
||||
</Switch>
|
||||
</Router>
|
||||
);
|
||||
return (
|
||||
<SocketContext.Provider value={playerSocket}>
|
||||
<Router>
|
||||
{redirect ? <Redirect to='/game' /> : <Redirect to='/login' />}
|
||||
<Switch>
|
||||
<Route exact path='/'>
|
||||
LOADING...
|
||||
</Route>
|
||||
<Route path='/login'>
|
||||
<NameInput />
|
||||
</Route>
|
||||
<Route path='/game'>
|
||||
{playerData ? (
|
||||
<PlayerDataContext.Provider value={playerData}>
|
||||
<Gameboard />
|
||||
</PlayerDataContext.Provider>
|
||||
) : null}
|
||||
</Route>
|
||||
</Switch>
|
||||
</Router>
|
||||
</SocketContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
||||
@ -1,30 +1,25 @@
|
||||
import React, { useState } from 'react';
|
||||
import axios from 'axios';
|
||||
import React, { useState, useContext } from "react";
|
||||
import { SocketContext } from "../App";
|
||||
|
||||
const NameInput = ({ idCallback }) => {
|
||||
const [inputValue, setInputValue] = useState('');
|
||||
const handleInputChange = (e) => {
|
||||
setInputValue(e.target.value);
|
||||
}
|
||||
|
||||
const handleButtonClick = () => {
|
||||
axios.post('/room/add',{
|
||||
name: inputValue
|
||||
},{
|
||||
withCredentials:true,
|
||||
"Content-Type": "application/json"
|
||||
})
|
||||
.then(response => {
|
||||
console.log(response.data);
|
||||
idCallback(response.data);
|
||||
})
|
||||
}
|
||||
return(
|
||||
<div>
|
||||
<input placeholder = "Enter name" type="text" onChange={handleInputChange}/>
|
||||
<input type="submit" onClick={handleButtonClick}/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
const NameInput = () => {
|
||||
const socket = useContext(SocketContext);
|
||||
const [inputValue, setInputValue] = useState("");
|
||||
const handleInputChange = (e) => {
|
||||
setInputValue(e.target.value);
|
||||
};
|
||||
const handleButtonClick = () => {
|
||||
socket.emit("player:login", { name: inputValue });
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<input
|
||||
placeholder="Enter name"
|
||||
type="text"
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
<input type="submit" onClick={handleButtonClick} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default NameInput;
|
||||
Loading…
Reference in New Issue
Block a user