From cbd500e13bae8216a714e9709c0a238dc5271949 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Asti=C3=A9?= Date: Fri, 9 Aug 2024 18:35:57 +0200 Subject: [PATCH] Add persistence of connection --- app/[id]/page.tsx | 8 +++-- app/page.tsx | 16 +++++++++ app/usernameGenerate.ts | 36 ++++++++++++++++++++ server.mjs | 75 +++++++++++++++++++++++++++++++++++++---- 4 files changed, 126 insertions(+), 9 deletions(-) diff --git a/app/[id]/page.tsx b/app/[id]/page.tsx index 7c88966..1b1661a 100644 --- a/app/[id]/page.tsx +++ b/app/[id]/page.tsx @@ -19,6 +19,7 @@ export default function Home({ params }: roomProps) { const [role, setRole] = useState("") const [name, setName] = useState("") const [avatar, setAvatar] = useState(defaultAvatarImage) + const [browserId, setBrowserId] = useState("") const [gameStarted, setGameStarted] = useState(false) const [gameEnded, setGameEnded] = useState(false) @@ -43,12 +44,15 @@ export default function Home({ params }: roomProps) { setName(localName) const localAvatar = localStorage.getItem('avatar') setAvatar(localAvatar) + const localBrowserId = localStorage.getItem("browserId") + setBrowserId(localBrowserId) + // Listen for incoming setMessages socketRef.current = io("ws://localhost:3000"); socketRef.current.on("connect", () => { setIsConnected(true) - socketRef.current.emit('room_connect', {id: id, name: localName, avatar: localAvatar}) + socketRef.current.emit('room_connect', {id: id, name: localName, avatar: localAvatar, browserId: localBrowserId}) }); socketRef.current.on("new_player", (params) => { @@ -56,7 +60,7 @@ export default function Home({ params }: roomProps) { }) socketRef.current.on("start_game", (params) => { - setQuestionNbr(oldQ => oldQ + 1) + setQuestionNbr(params.questionNbr) setGameStarted(true) setQuestionDisplayed(params.question) setPossibleChoice(params.possibleChoice) diff --git a/app/page.tsx b/app/page.tsx index b3634c3..a53a2d6 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -10,6 +10,7 @@ import Webcam from 'react-webcam' export default function Home() { const [name, setName] = useState("") const [avatar, setAvatar] = useState(defaultAvatarImage) + const [browserId, setBrowserId] = useState("") const [showWebcam, setShowWebcam] = useState(false) const webcamRef = useRef() const modal = useRef() @@ -27,6 +28,12 @@ export default function Home() { }) } + function uuidv4() { + return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, c => + (+c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> +c / 4).toString(16) + ); + } + function takePictureAvatar() { const imageSrc = webcamRef.current.getScreenshot() setAndStoreAvatar(imageSrc) @@ -71,6 +78,7 @@ export default function Home() { useEffect(() => { let localName = localStorage.getItem("name") let localAvatar = localStorage.getItem("avatar") + let localBrowserId = localStorage.getItem("browserId") if(localName != null){ setName(localName) } else { @@ -80,6 +88,14 @@ export default function Home() { if(localAvatar != null) { setAvatar(localAvatar) } + + if(localBrowserId != null) { + setBrowserId(localBrowserId) + } else { + let uuid = uuidv4() + setBrowserId(uuid) + localStorage.setItem("browserId", uuid) + } }, []) return ( diff --git a/app/usernameGenerate.ts b/app/usernameGenerate.ts index 80e0d96..1428e35 100644 --- a/app/usernameGenerate.ts +++ b/app/usernameGenerate.ts @@ -7,6 +7,23 @@ const prenom = [ "Patrick", "Agathe", "Erneste", + "Gertrude", + "Eustache", + "Cunégonde", + "Barnabé", + "Arsène", + "Clotilde", + "Adélaïde", + "Rosalie", + "Firmin", + "Hortense", + "Gustave", + "Odile", + "Gontran", + "Léopoldine", + "Achille", + "Eugène", + "Gédéon", ] const nom = [ @@ -16,6 +33,25 @@ const nom = [ "Zigounette", "Pissenlit", "Détritus", + "Moufette", + "Panade", + "Boulet", + "Moustache", + "Tapage", + "Bidule", + "Patate", + "Clafoutis", + "Crouton", + "Bibelot", + "Pinceau", + "Chiffon", + "Trompette", + "Chipolata", + "Boussole", + "Touillette", + "Fanfreluche", + "Grenouille", + "Pamplemousse" ] export function getUsername(){ diff --git a/server.mjs b/server.mjs index d98f06a..1526b3e 100644 --- a/server.mjs +++ b/server.mjs @@ -11,6 +11,38 @@ const handler = app.getRequestHandler(); let active_rooms = {} +function findUserBySocketId(roomId, socketId){ + let ans = null + active_rooms[roomId].users.forEach((player, index) => { + if(player.id == socketId){ + ans = index + } + }) + return ans +} + +function findUserByBrowserId(roomId, browserId){ + let ans = null + active_rooms[roomId].users.forEach((player, index) => { + if(player.browserId == browserId){ + ans = index + } + }) + return ans +} + +function removeUnusedRoom(roomId){ + let removeRoom = true + active_rooms[roomId].users.forEach((player) => { + if(player.connected == true){ + removeRoom = false + } + }) + if(removeRoom){ + delete active_rooms[roomId] + } +} + app.prepare().then(() => { const httpServer = createServer(handler); @@ -22,19 +54,31 @@ app.prepare().then(() => { socket.on('room_connect', (params) => { if(!Object.keys(active_rooms).includes(params.id)){ console.log("First person joined " + params.id + " ! " + params.name + " is owner.") - active_rooms[params.id] = [{id: socket.id, name: params.name, avatar: params.avatar, role: "owner", vote: ""}] - socket.emit("room_joined", {"room_users": active_rooms[params.id], "role": "owner"}) + active_rooms[params.id] = { users: [{id: socket.id, name: params.name, avatar: params.avatar, browserId: params.browserId, connected: true, role: "owner", vote: ""}]} + socket.emit("room_joined", {"room_users": active_rooms[params.id].users, role: "owner"}) } else { - socket.to(params.id).emit("new_player",{"id": socket.id, "name": params.name, avatar: params.avatar, role: "player"}) - active_rooms[params.id].push({id: socket.id, name: params.name, avatar: params.avatar, role: "player", vote: ""}) - socket.emit("room_joined", {"room_users": active_rooms[params.id], role: "player"}) - console.log("New person joined " + params.id + " ! " + params.name + " is player.") + let userIndexByBrowserId = findUserByBrowserId(params.id, params.browserId) + if(userIndexByBrowserId != null) { + active_rooms[params.id].users[userIndexByBrowserId].connected = true + active_rooms[params.id].users[userIndexByBrowserId].id = socket.id + socket.emit("room_joined", {"room_users": active_rooms[params.id].users, role: active_rooms[params.id].users[userIndexByBrowserId].role}) + socket.emit("start_game",{possibleChoice: active_rooms[params.id].possibleChoice, question: active_rooms[params.id].question, questionNbr: active_rooms[params.id].questionNbr, duration: 15}) + } else { + socket.to(params.id).emit("new_player",{"id": socket.id, "name": params.name, avatar: params.avatar, browserId: params.browserId, connected: true, role: "player"}) + active_rooms[params.id].users.push({id: socket.id, name: params.name, avatar: params.avatar, browserId: params.browserId, connected: true, role: "player", vote: ""}) + socket.emit("room_joined", {"room_users": active_rooms[params.id].users, role: "player"}) + console.log("New person joined " + params.id + " ! " + params.name + " is player.") + } } socket.join(params.id) }) socket.on("start_game", (params) => { - socket.to(params.roomId).emit("start_game",{possibleChoice: params.possibleChoice, question: params.question, duration: params.duration}) + active_rooms[params.roomId].question = params.question + active_rooms[params.roomId].questionNbr = 1 + active_rooms[params.roomId].possibleChoice = params.possibleChoice + active_rooms[params.roomId].duration = params.duration + socket.to(params.roomId).emit("start_game",{possibleChoice: params.possibleChoice, question: params.question, questionNbr: 1, duration: params.duration}) }) socket.on("reset_game", (params) => { @@ -42,6 +86,10 @@ app.prepare().then(() => { }) socket.on("next_question", (params) => { + active_rooms[params.roomId].question = params.question + active_rooms[params.roomId].questionNbr += 1 + active_rooms[params.roomId].possibleChoice = params.possibleChoice + active_rooms[params.roomId].duration = params.duration socket.to(params.roomId).emit("next_question",{possibleChoice: params.possibleChoice, question: params.question, duration: params.duration}) }) @@ -49,6 +97,19 @@ app.prepare().then(() => { console.log(params) socket.to(params.roomId).emit("player_choice", {choice: params.choice, player: params.player}) }) + + socket.on("disconnecting", (reason) => { + for (const room of socket.rooms) { + if (room !== socket.id) { + let roomUserIndex = findUserBySocketId(room, socket.id) + if(roomUserIndex != null){ + active_rooms[room].users[roomUserIndex].connected = false + socket.to(room).emit("player_disconnected") + removeUnusedRoom(room) + } + } + } + }) // ... });