First Commit

This commit is contained in:
Ralex91
2024-01-31 20:06:10 +01:00
commit e122fe1078
58 changed files with 6853 additions and 0 deletions

52
socket/src/index.js Normal file
View 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
}*/
})
})

View 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,
},
],
}

View 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

View 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

View 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

View 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
View 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 = []
}