forked from Github/uno-online
Working two-player game ready!
This commit is contained in:
parent
6d064cec4b
commit
183229e791
44
client/package-lock.json
generated
44
client/package-lock.json
generated
@ -6408,6 +6408,11 @@
|
|||||||
"to-regex-range": "^5.0.1"
|
"to-regex-range": "^5.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"filter-obj": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz",
|
||||||
|
"integrity": "sha1-mzERErxsYSehbgFsbF1/GeCAXFs="
|
||||||
|
},
|
||||||
"finalhandler": {
|
"finalhandler": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
|
||||||
@ -10314,6 +10319,22 @@
|
|||||||
"prepend-http": "^1.0.0",
|
"prepend-http": "^1.0.0",
|
||||||
"query-string": "^4.1.0",
|
"query-string": "^4.1.0",
|
||||||
"sort-keys": "^1.0.0"
|
"sort-keys": "^1.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"query-string": {
|
||||||
|
"version": "4.3.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz",
|
||||||
|
"integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=",
|
||||||
|
"requires": {
|
||||||
|
"object-assign": "^4.1.0",
|
||||||
|
"strict-uri-encode": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"strict-uri-encode": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
|
||||||
|
"integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"npm-run-path": {
|
"npm-run-path": {
|
||||||
@ -12134,12 +12155,14 @@
|
|||||||
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
|
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
|
||||||
},
|
},
|
||||||
"query-string": {
|
"query-string": {
|
||||||
"version": "4.3.4",
|
"version": "6.14.0",
|
||||||
"resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/query-string/-/query-string-6.14.0.tgz",
|
||||||
"integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=",
|
"integrity": "sha512-In3o+lUxlgejoVJgwEdYtdxrmlL0cQWJXj0+kkI7RWVo7hg5AhFtybeKlC9Dpgbr8eOC4ydpEh8017WwyfzqVQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"object-assign": "^4.1.0",
|
"decode-uri-component": "^0.2.0",
|
||||||
"strict-uri-encode": "^1.0.0"
|
"filter-obj": "^1.1.0",
|
||||||
|
"split-on-first": "^1.0.0",
|
||||||
|
"strict-uri-encode": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"querystring": {
|
"querystring": {
|
||||||
@ -13853,6 +13876,11 @@
|
|||||||
"wbuf": "^1.7.3"
|
"wbuf": "^1.7.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"split-on-first": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw=="
|
||||||
|
},
|
||||||
"split-string": {
|
"split-string": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
|
||||||
@ -14028,9 +14056,9 @@
|
|||||||
"integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ=="
|
"integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ=="
|
||||||
},
|
},
|
||||||
"strict-uri-encode": {
|
"strict-uri-encode": {
|
||||||
"version": "1.1.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
|
||||||
"integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM="
|
"integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY="
|
||||||
},
|
},
|
||||||
"string-length": {
|
"string-length": {
|
||||||
"version": "4.0.1",
|
"version": "4.0.1",
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
"@testing-library/jest-dom": "^5.11.9",
|
"@testing-library/jest-dom": "^5.11.9",
|
||||||
"@testing-library/react": "^11.2.5",
|
"@testing-library/react": "^11.2.5",
|
||||||
"@testing-library/user-event": "^12.7.0",
|
"@testing-library/user-event": "^12.7.0",
|
||||||
|
"query-string": "^6.14.0",
|
||||||
"react": "^17.0.1",
|
"react": "^17.0.1",
|
||||||
"react-dom": "^17.0.1",
|
"react-dom": "^17.0.1",
|
||||||
"react-router-dom": "^5.2.0",
|
"react-router-dom": "^5.2.0",
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,11 +1,14 @@
|
|||||||
import React from 'react'
|
import React, { useState } from 'react'
|
||||||
import { Link } from 'react-router-dom'
|
import { Link } from 'react-router-dom'
|
||||||
|
|
||||||
const Homepage = () => {
|
const Homepage = () => {
|
||||||
|
const [roomCode, setRoomCode] = useState('')
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='Homepage'>
|
<div className='Homepage'>
|
||||||
<h1>UNO</h1>
|
<h1>UNO</h1>
|
||||||
<Link to='/play'><button>START GAME</button></Link>
|
<div><input type='text' placeholder='Room' onChange={(event) => setRoomCode(event.target.value)} /></div>
|
||||||
|
<Link to={`/play?roomCode=${roomCode}`}><button>START GAME</button></Link>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,8 @@
|
|||||||
"description": "Online multiplayer card game",
|
"description": "Online multiplayer card game",
|
||||||
"main": "server.js",
|
"main": "server.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node server"
|
"start": "node server",
|
||||||
|
"client": "npm start --prefix client"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
32
server.js
32
server.js
@ -2,6 +2,7 @@ const express = require('express')
|
|||||||
const socketio = require('socket.io')
|
const socketio = require('socket.io')
|
||||||
const http = require('http')
|
const http = require('http')
|
||||||
const cors = require('cors')
|
const cors = require('cors')
|
||||||
|
const { addUser, removeUser, getUser, getUsersInRoom } = require('./users')
|
||||||
|
|
||||||
const PORT = process.env.PORT || 5000
|
const PORT = process.env.PORT || 5000
|
||||||
|
|
||||||
@ -12,18 +13,41 @@ const io = socketio(server)
|
|||||||
app.use(cors())
|
app.use(cors())
|
||||||
|
|
||||||
io.on('connection', socket => {
|
io.on('connection', socket => {
|
||||||
console.log('connection made')
|
socket.on('join', (payload, callback) => {
|
||||||
|
let numberOfUsersInRoom = getUsersInRoom(payload.room).length
|
||||||
|
|
||||||
|
const { error, newUser} = addUser({
|
||||||
|
id: socket.id,
|
||||||
|
name: numberOfUsersInRoom===0 ? 'Player 1' : 'Player 2',
|
||||||
|
room: payload.room
|
||||||
|
})
|
||||||
|
|
||||||
|
if(error)
|
||||||
|
return callback(error)
|
||||||
|
|
||||||
|
socket.join(newUser.room)
|
||||||
|
|
||||||
|
io.to(newUser.room).emit('roomData', {room: newUser.room, users: getUsersInRoom(newUser.room)})
|
||||||
|
socket.emit('currentUserData', {name: newUser.name})
|
||||||
|
callback()
|
||||||
|
})
|
||||||
|
|
||||||
socket.on('initGameState', gameState => {
|
socket.on('initGameState', gameState => {
|
||||||
io.emit('initGameState', gameState)
|
const user = getUser(socket.id)
|
||||||
|
if(user)
|
||||||
|
io.to(user.room).emit('initGameState', gameState)
|
||||||
})
|
})
|
||||||
|
|
||||||
socket.on('updateGameState', gameState => {
|
socket.on('updateGameState', gameState => {
|
||||||
io.emit('updateGameState', gameState)
|
const user = getUser(socket.id)
|
||||||
|
if(user)
|
||||||
|
io.to(user.room).emit('updateGameState', gameState)
|
||||||
})
|
})
|
||||||
|
|
||||||
socket.on('disconnect', () => {
|
socket.on('disconnect', () => {
|
||||||
console.log('connection lost')
|
const user = removeUser(socket.id)
|
||||||
|
if(user)
|
||||||
|
io.to(user.room).emit('roomData', {room: user.room, users: getUsersInRoom(user.room)})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
28
users.js
Normal file
28
users.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
const users = []
|
||||||
|
|
||||||
|
const addUser = ({id, name, room}) => {
|
||||||
|
const numberOfUsersInRoom = users.filter(user => user.room === room).length
|
||||||
|
if(numberOfUsersInRoom === 2)
|
||||||
|
return { error: 'Room full' }
|
||||||
|
|
||||||
|
const newUser = { id, name, room }
|
||||||
|
users.push(newUser)
|
||||||
|
return { newUser }
|
||||||
|
}
|
||||||
|
|
||||||
|
const removeUser = id => {
|
||||||
|
const removeIndex = users.findIndex(user => user.id === id)
|
||||||
|
|
||||||
|
if(removeIndex!==-1)
|
||||||
|
return users.splice(removeIndex, 1)[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
const getUser = id => {
|
||||||
|
return users.find(user => user.id === id)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getUsersInRoom = room => {
|
||||||
|
return users.filter(user => user.room === room)
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { addUser, removeUser, getUser, getUsersInRoom }
|
Loading…
Reference in New Issue
Block a user