mirror of
https://github.com/randyjc/Rahoot.git
synced 2026-03-13 20:15:35 +01:00
First Commit
This commit is contained in:
234
socket/package-lock.json
generated
Normal file
234
socket/package-lock.json
generated
Normal file
@@ -0,0 +1,234 @@
|
||||
{
|
||||
"name": "socket",
|
||||
"version": "0.1.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"socket.io": "^4.7.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@socket.io/component-emitter": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
|
||||
"integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg=="
|
||||
},
|
||||
"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=="
|
||||
},
|
||||
"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==",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.11.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.13.tgz",
|
||||
"integrity": "sha512-5G4zQwdiQBSWYTDAH1ctw2eidqdhMJaNsiIDKHFr55ihz5Trl2qqR8fdrT732yPBho5gkNxXm67OxWFBqX9aPg==",
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
},
|
||||
"node_modules/accepts": {
|
||||
"version": "1.3.8",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
|
||||
"integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
|
||||
"dependencies": {
|
||||
"mime-types": "~2.1.34",
|
||||
"negotiator": "0.6.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"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==",
|
||||
"engines": {
|
||||
"node": "^4.5.0 || >= 5.9"
|
||||
}
|
||||
},
|
||||
"node_modules/cookie": {
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
|
||||
"integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/cors": {
|
||||
"version": "2.8.5",
|
||||
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
|
||||
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
|
||||
"dependencies": {
|
||||
"object-assign": "^4",
|
||||
"vary": "^1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
|
||||
"dependencies": {
|
||||
"ms": "2.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"supports-color": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/engine.io": {
|
||||
"version": "6.5.4",
|
||||
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.4.tgz",
|
||||
"integrity": "sha512-KdVSDKhVKyOi+r5uEabrDLZw2qXStVvCsEB/LN3mw4WFi6Gx50jTyuxYVCwAAC0U46FdnzP/ScKRBTXb/NiEOg==",
|
||||
"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.11.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/engine.io-parser": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz",
|
||||
"integrity": "sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ==",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-types": {
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"dependencies": {
|
||||
"mime-db": "1.52.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"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=="
|
||||
},
|
||||
"node_modules/negotiator": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
|
||||
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/socket.io": {
|
||||
"version": "4.7.4",
|
||||
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.4.tgz",
|
||||
"integrity": "sha512-DcotgfP1Zg9iP/dH9zvAQcWrE0TtbMVwXmlV4T4mqsvY+gw+LqUGPfx2AoVyRk0FLME+GQhufDMyacFmw7ksqw==",
|
||||
"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.2",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz",
|
||||
"integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==",
|
||||
"dependencies": {
|
||||
"ws": "~8.11.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==",
|
||||
"dependencies": {
|
||||
"@socket.io/component-emitter": "~3.1.0",
|
||||
"debug": "~4.3.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "5.26.5",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
|
||||
},
|
||||
"node_modules/vary": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.11.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
|
||||
"integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
|
||||
"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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
8
socket/package.json
Normal file
8
socket/package.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"socket.io": "^4.7.4"
|
||||
}
|
||||
}
|
||||
52
socket/src/index.js
Normal file
52
socket/src/index.js
Normal file
@@ -0,0 +1,52 @@
|
||||
import { Server } from "socket.io"
|
||||
import { GAME_STATE_INIT } from "./quizz.config.js"
|
||||
import Manager from "./roles/manager.js"
|
||||
import Player from "./roles/player.js"
|
||||
|
||||
let gameState = GAME_STATE_INIT
|
||||
|
||||
const io = new Server({
|
||||
cors: {
|
||||
origin: "*",
|
||||
},
|
||||
path: "/ws/",
|
||||
})
|
||||
|
||||
io.listen(5057)
|
||||
|
||||
io.on("connection", (socket) => {
|
||||
console.log(`A user connected ${socket.id}`)
|
||||
|
||||
socket.on("player:join", (player) =>
|
||||
Player.join(gameState, io, socket, player)
|
||||
)
|
||||
|
||||
socket.on("manager:createRoom", () =>
|
||||
Manager.createRoom(gameState, io, socket)
|
||||
)
|
||||
socket.on("manager:kickPlayer", (playerId) =>
|
||||
Manager.kickPlayer(gameState, socket, io, playerId)
|
||||
)
|
||||
|
||||
socket.on("manager:startGame", () => Manager.startGame(gameState, io, socket))
|
||||
|
||||
socket.on("player:selectedAnswer", (answerKey) =>
|
||||
Player.selectedAnswer(gameState, io, socket, answerKey)
|
||||
)
|
||||
|
||||
socket.on("manager:nextQuestion", () =>
|
||||
Manager.nextQuestion(gameState, io, socket)
|
||||
)
|
||||
|
||||
socket.on("manager:showLeaderboard", () =>
|
||||
Manager.showLoaderboard(gameState, io, socket)
|
||||
)
|
||||
|
||||
socket.on("disconnect", () => {
|
||||
console.log(`user disconnected ${socket.id}`)
|
||||
/*if (gameState.manager === socket.id) {
|
||||
console.log("Reset game")
|
||||
gameState = gameStateInit
|
||||
}*/
|
||||
})
|
||||
})
|
||||
83
socket/src/quizz.config.js
Normal file
83
socket/src/quizz.config.js
Normal file
@@ -0,0 +1,83 @@
|
||||
export const GAME_STATE_INIT = {
|
||||
started: false,
|
||||
players: [],
|
||||
playersAnswer: [],
|
||||
manager: null,
|
||||
room: null,
|
||||
currentQuestion: 0,
|
||||
roundStartTime: 0,
|
||||
questions: [
|
||||
{
|
||||
question: "Who are the founders of Adobe?",
|
||||
answers: [
|
||||
"Steve Jobs and Charles Geschke",
|
||||
"Jhon Warnock and Charles Geschke",
|
||||
"Jhon Jonse and Charles Geskie",
|
||||
"Bill Gate",
|
||||
],
|
||||
image: "/question/Adobe-Logo.png",
|
||||
solution: 1,
|
||||
time: 15,
|
||||
},
|
||||
{
|
||||
question: "What is Adobe's most famous software?",
|
||||
answers: ["Encore", "AfterEffect", "Creative Cloud", "Photoshop"],
|
||||
image: "/question/Adobe-Packages.webp",
|
||||
solution: 3,
|
||||
time: 15,
|
||||
},
|
||||
{
|
||||
question: "When was Adobe created?",
|
||||
answers: ["2000", "1982", "2003", "1987"],
|
||||
solution: 1,
|
||||
time: 15,
|
||||
},
|
||||
{
|
||||
question: "Where is headquertes located?",
|
||||
answers: [
|
||||
"San Jose, California",
|
||||
"Bookworm, Cascui",
|
||||
"DowTown, Texas",
|
||||
"Tokyo, Japan",
|
||||
],
|
||||
image: "/question/Adobe_World_Headquarters.jpg",
|
||||
solution: 0,
|
||||
time: 15,
|
||||
},
|
||||
{
|
||||
question: "How many employees at Adobe?",
|
||||
answers: [
|
||||
"15,423 employees",
|
||||
"30,803 employees",
|
||||
"25,988 employees",
|
||||
"5,073 employees",
|
||||
],
|
||||
image: "/question/000012204568_Large.jpg",
|
||||
solution: 2,
|
||||
time: 15,
|
||||
},
|
||||
{
|
||||
question: "Who is the Current CEO?",
|
||||
answers: [
|
||||
"Jhon Warnock",
|
||||
"Victor Newway",
|
||||
"Mark Java",
|
||||
"Shantanu Narayen",
|
||||
],
|
||||
image: "/question/guess-the-person.png",
|
||||
solution: 3,
|
||||
time: 15,
|
||||
},
|
||||
{
|
||||
question: "Adobe's core business is focused on?",
|
||||
answers: [
|
||||
"Creative Software",
|
||||
"Video Game",
|
||||
"Logistics software",
|
||||
"Other",
|
||||
],
|
||||
solution: 0,
|
||||
time: 15,
|
||||
},
|
||||
],
|
||||
}
|
||||
85
socket/src/roles/manager.js
Normal file
85
socket/src/roles/manager.js
Normal file
@@ -0,0 +1,85 @@
|
||||
import { GAME_STATE_INIT } from "../quizz.config.js"
|
||||
import { startRound } from "../utils/round.js"
|
||||
import generateRoomId from "../utils/generateRoomId.js"
|
||||
|
||||
const Manager = {
|
||||
createRoom: (game, io, socket) => {
|
||||
if (game.manager || game.room) {
|
||||
io.to(socket.id).emit("message", "Already manager")
|
||||
return
|
||||
}
|
||||
|
||||
let roomInvite = "207223" //generateRoomId()
|
||||
game.room = roomInvite
|
||||
game.manager = socket.id
|
||||
|
||||
socket.join(roomInvite)
|
||||
io.to(socket.id).emit("manager:inviteCode", roomInvite)
|
||||
|
||||
console.log("New room created: " + roomInvite)
|
||||
},
|
||||
|
||||
kickPlayer: (game, io, socket, playerId) => {
|
||||
if (game.manager !== socket.id) {
|
||||
return
|
||||
}
|
||||
|
||||
const player = game.players.find((p) => p.id === playerId)
|
||||
game.players = game.players.filter((p) => p.id !== playerId)
|
||||
|
||||
io.to(player.id).emit("game:kick")
|
||||
io.to(game.manager).emit("manager:playerKicked", player.id)
|
||||
},
|
||||
|
||||
startGame: (game, io, socket) => {
|
||||
if (game.started || !game.room) {
|
||||
return
|
||||
}
|
||||
|
||||
game.started = true
|
||||
io.to(game.room).emit("startGame", game.room)
|
||||
startRound(game, io, socket)
|
||||
},
|
||||
|
||||
nextQuestion: (game, io, socket) => {
|
||||
if (!game.started) {
|
||||
return
|
||||
}
|
||||
|
||||
if (socket.id !== game.manager) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!game.questions[game.currentQuestion + 1]) {
|
||||
return
|
||||
}
|
||||
|
||||
game.currentQuestion++
|
||||
startRound(game, io, socket)
|
||||
},
|
||||
|
||||
showLoaderboard: (game, io, socket) => {
|
||||
if (!game.questions[game.currentQuestion + 1]) {
|
||||
io.to(game.room).emit("game:status", {
|
||||
name: "FINISH",
|
||||
data: {
|
||||
winners: game.players.slice(0, 3).sort((a, b) => b.points - a.points),
|
||||
},
|
||||
})
|
||||
|
||||
game = GAME_STATE_INIT
|
||||
return
|
||||
}
|
||||
|
||||
io.to(game.room).emit("game:status", {
|
||||
name: "SHOW_LEADERBOARD",
|
||||
data: {
|
||||
leaderboard: game.players
|
||||
.sort((a, b) => b.points - a.points)
|
||||
.slice(0, 5),
|
||||
},
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
export default Manager
|
||||
57
socket/src/roles/player.js
Normal file
57
socket/src/roles/player.js
Normal file
@@ -0,0 +1,57 @@
|
||||
import convertTimeToPoint from "../utils/convertTimeToPoint.js"
|
||||
import { abortCooldown } from "../utils/round.js"
|
||||
|
||||
const Player = {
|
||||
join: (game, io, socket, player) => {
|
||||
if (!player.room || !player.room || game.started) {
|
||||
return
|
||||
}
|
||||
|
||||
console.log("joined", player)
|
||||
|
||||
socket.join(player.room)
|
||||
|
||||
let playerData = {
|
||||
username: player.username,
|
||||
room: player.room,
|
||||
id: socket.id,
|
||||
points: 0,
|
||||
}
|
||||
socket.to(player.room).emit("manager:newPlayer", playerData)
|
||||
|
||||
game.players.push(playerData)
|
||||
|
||||
io.to(socket.id).emit("game:successJoin")
|
||||
},
|
||||
|
||||
selectedAnswer: (game, io, socket, answerKey) => {
|
||||
const player = game.players.find((player) => player.id === socket.id)
|
||||
const question = game.questions[game.currentQuestion]
|
||||
|
||||
if (!player) {
|
||||
return
|
||||
}
|
||||
|
||||
if (game.playersAnswer.find((p) => p.id === socket.id)) {
|
||||
return
|
||||
}
|
||||
|
||||
game.playersAnswer.push({
|
||||
id: socket.id,
|
||||
answer: answerKey,
|
||||
points: convertTimeToPoint(game.roundStartTime, question.time),
|
||||
})
|
||||
|
||||
io.to(socket.id).emit("game:status", {
|
||||
name: "WAIT",
|
||||
data: { text: "Waiting for the players to answer" },
|
||||
})
|
||||
socket.to(game.room).emit("game:playerAnswer", game.playersAnswer.length)
|
||||
|
||||
if (game.playersAnswer.length === game.players.length) {
|
||||
abortCooldown()
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default Player
|
||||
13
socket/src/utils/convertTimeToPoint.js
Normal file
13
socket/src/utils/convertTimeToPoint.js
Normal file
@@ -0,0 +1,13 @@
|
||||
const convertTimeToPoint = (startTime, secondes) => {
|
||||
let points = 1000
|
||||
|
||||
const actualTime = Date.now()
|
||||
const tempsPasseEnSecondes = (actualTime - startTime) / 1000
|
||||
|
||||
points -= (1000 / secondes) * tempsPasseEnSecondes
|
||||
points = Math.max(0, points)
|
||||
|
||||
return points
|
||||
}
|
||||
|
||||
export default convertTimeToPoint
|
||||
14
socket/src/utils/generateRoomId.js
Normal file
14
socket/src/utils/generateRoomId.js
Normal file
@@ -0,0 +1,14 @@
|
||||
const generateRoomId = (length = 6) => {
|
||||
let result = ""
|
||||
const characters = "0123456789"
|
||||
const charactersLength = characters.length
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
const randomIndex = Math.floor(Math.random() * charactersLength)
|
||||
result += characters.charAt(randomIndex)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
export default generateRoomId
|
||||
109
socket/src/utils/round.js
Normal file
109
socket/src/utils/round.js
Normal file
@@ -0,0 +1,109 @@
|
||||
let cooldownTimeout
|
||||
let cooldownResolve
|
||||
|
||||
export const abortCooldown = () => {
|
||||
clearInterval(cooldownTimeout)
|
||||
cooldownResolve()
|
||||
}
|
||||
|
||||
function cooldown(ms, io, room) {
|
||||
let count = ms - 1
|
||||
|
||||
return new Promise((resolve) => {
|
||||
cooldownResolve = resolve
|
||||
|
||||
cooldownTimeout = setInterval(() => {
|
||||
if (!count) {
|
||||
clearInterval(cooldownTimeout)
|
||||
resolve()
|
||||
}
|
||||
io.to(room).emit("game:cooldown", count)
|
||||
count -= 1
|
||||
}, 1000)
|
||||
})
|
||||
}
|
||||
|
||||
const sleep = (sec) => new Promise((r) => setTimeout(r, sec * 1000))
|
||||
|
||||
export const startRound = async (game, io, socket) => {
|
||||
const question = game.questions[game.currentQuestion]
|
||||
|
||||
io.to(game.room).emit("game:status", {
|
||||
name: "SHOW_QUESTION",
|
||||
data: {
|
||||
question: question.question,
|
||||
number: game.currentQuestion + 1,
|
||||
image: question.image,
|
||||
cooldown: 6,
|
||||
},
|
||||
})
|
||||
|
||||
await sleep(6)
|
||||
|
||||
game.roundStartTime = Date.now()
|
||||
|
||||
io.to(game.room).emit("game:status", {
|
||||
name: "SELECT_ANSWER",
|
||||
data: {
|
||||
question: question.question,
|
||||
answers: question.answers,
|
||||
image: question.image,
|
||||
time: question.time,
|
||||
totalPlayer: game.players.length,
|
||||
},
|
||||
})
|
||||
|
||||
await cooldown(question.time, io, game.room)
|
||||
|
||||
game.players.map(async (player) => {
|
||||
let playerAnswer = await game.playersAnswer.find((p) => p.id === player.id)
|
||||
|
||||
let isCorrect = playerAnswer
|
||||
? playerAnswer.answer === question.solution
|
||||
: false
|
||||
|
||||
let points =
|
||||
(isCorrect && Math.round(playerAnswer && playerAnswer.points)) || 0
|
||||
|
||||
game.players.find((p) => p.id === player.id).points += points
|
||||
|
||||
setTimeout(() => {
|
||||
let rank =
|
||||
game.players
|
||||
.sort((a, b) => b.points - a.points)
|
||||
.findIndex((p) => p.id === player.id) + 1
|
||||
|
||||
io.to(player.id).emit("game:status", {
|
||||
name: "SHOW_RESULT",
|
||||
data: {
|
||||
correct: isCorrect,
|
||||
message: isCorrect ? "Nice !" : "Too bad",
|
||||
points: points,
|
||||
myPoints: player.points,
|
||||
totalPlayer: game.players.length,
|
||||
rank: rank,
|
||||
},
|
||||
})
|
||||
}, 200)
|
||||
})
|
||||
|
||||
let totalParType = {}
|
||||
|
||||
game.playersAnswer.forEach(({ answer }) => {
|
||||
totalParType[answer] = (totalParType[answer] || 0) + 1
|
||||
})
|
||||
|
||||
// Manager
|
||||
io.to(game.manager).emit("game:status", {
|
||||
name: "SHOW_RESPONSES",
|
||||
data: {
|
||||
question: game.questions[game.currentQuestion].question,
|
||||
responses: totalParType,
|
||||
correct: game.questions[game.currentQuestion].solution,
|
||||
answers: game.questions[game.currentQuestion].answers,
|
||||
image: game.questions[game.currentQuestion].image,
|
||||
},
|
||||
})
|
||||
|
||||
game.playersAnswer = []
|
||||
}
|
||||
14
socket/web.js
Normal file
14
socket/web.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import { Server } from "socket.io"
|
||||
|
||||
const io = new Server({
|
||||
cors: {
|
||||
origin: "*",
|
||||
},
|
||||
})
|
||||
|
||||
io.on("connection", (socket) => {
|
||||
console.log("a user connected")
|
||||
io.to(socket.id).emit("message", "Hello from server")
|
||||
})
|
||||
|
||||
io.listen(5057)
|
||||
Reference in New Issue
Block a user