diff --git a/cryptide_project/package-lock.json b/cryptide_project/package-lock.json index bb63537..14a8bc0 100644 --- a/cryptide_project/package-lock.json +++ b/cryptide_project/package-lock.json @@ -17,6 +17,8 @@ "@testing-library/user-event": "^13.5.0", "@types/lodash": "^4.14.200", "bootstrap": "^5.3.2", + "cors": "^2.8.5", + "express": "^4.18.2", "lodash": "^4.17.21", "react": "^18.2.0", "react-bootstrap": "^2.9.1", @@ -27,6 +29,8 @@ "react-router-dom": "^6.18.0", "react-scripts": "5.0.1", "react-switch": "^7.0.0", + "socket.io": "^4.7.2", + "socket.io-client": "^4.7.2", "typescript": "^5.2.2", "vis-network": "^9.1.9", "web-vitals": "^2.1.4" @@ -3788,6 +3792,11 @@ "@sinonjs/commons": "^1.7.0" } }, + "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/@surma/rollup-plugin-off-main-thread": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", @@ -4208,6 +4217,19 @@ "@types/node": "*" } }, + "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.16", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.16.tgz", + "integrity": "sha512-Trx5or1Nyg1Fq138PCuWqoApzvoSLWzZ25ORBiHMbbUT42g578lH1GT4TwYDbiUOLFuDsCkfLneT2105fsFWGg==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/eslint": { "version": "8.44.7", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.7.tgz", @@ -5652,6 +5674,14 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "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/batch": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", @@ -6381,6 +6411,18 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, + "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/cosmiconfig": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", @@ -7251,6 +7293,94 @@ "node": ">= 0.8" } }, + "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-client": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.3.tgz", + "integrity": "sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.11.0", + "xmlhttprequest-ssl": "~2.0.0" + } + }, + "node_modules/engine.io-client/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 + } + } + }, + "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/engine.io/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/engine.io/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 + } + } + }, "node_modules/enhanced-resolve": { "version": "5.15.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", @@ -15614,6 +15744,77 @@ "node": ">=8" } }, + "node_modules/socket.io": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.2.tgz", + "integrity": "sha512-bvKVS29/I5fl2FGLNHuXlQaUH/BlzX1IN6S+NKLNZpBsPZIDH+90eQmCs2Railn4YUiww4SzUedJ6+uzwFnKLw==", + "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-adapter/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 + } + } + }, + "node_modules/socket.io-client": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.2.tgz", + "integrity": "sha512-vtA0uD4ibrYD793SOIAwlo8cj6haOeMHrGvwPxJsxH7CeIksqJ+3Zc06RvWTIFgiSqx4A3sOnTXpfAEE2Zyz6w==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.0.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/sockjs": { "version": "0.3.24", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", @@ -17930,6 +18131,14 @@ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" }, + "node_modules/xmlhttprequest-ssl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", + "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/cryptide_project/package.json b/cryptide_project/package.json index 73a098b..c3658bd 100644 --- a/cryptide_project/package.json +++ b/cryptide_project/package.json @@ -11,6 +11,8 @@ "@testing-library/user-event": "^13.5.0", "@types/lodash": "^4.14.200", "bootstrap": "^5.3.2", + "cors": "^2.8.5", + "express": "^4.18.2", "lodash": "^4.17.21", "react": "^18.2.0", "react-bootstrap": "^2.9.1", @@ -21,6 +23,11 @@ "react-router-dom": "^6.18.0", "react-scripts": "5.0.1", "react-switch": "^7.0.0", + "socket.io": "^4.7.2", + "socket.io-client": "^4.7.2", + "socket.io": "^4.7.2", + "socket.io-client": "^4.7.2", + "react-switch": "^7.0.0", "typescript": "^5.2.2", "vis-network": "^9.1.9", "web-vitals": "^2.1.4" diff --git a/cryptide_project/server/server.js b/cryptide_project/server/server.js new file mode 100644 index 0000000..f1a5414 --- /dev/null +++ b/cryptide_project/server/server.js @@ -0,0 +1,79 @@ +const express = require('express'); +const http = require('http'); +const socketIO = require('socket.io'); +const cors = require('cors'); + +const app = express(); +const server = http.createServer(app); +const io = socketIO(server, { + cors: { + origin: ["http://localhost:3000", "http://localhost:3001"], // Remplacez par l'URL de votre application React + methods: ["GET", "POST"], + credentials: true + } +}); + + +const map = new Map() +// ... le reste de votre configuration du serveur + +server.listen(3002, () => { + console.log('Serveur Socket.IO écoutant sur le port 3001'); +}); + +io.on('connection', (socket) => { + console.log(socket.id); + + socket.on('network created', (network, person, indices, room) =>{ + io.to(room).emit("game created", network, person, indices, Math.floor(Math.random() * map.get(room).length)) + }); + + socket.on("lobby joined", (room, name) =>{ + socket.join(room) + if (map.get(room) == undefined){ + map.set(room, [{id: socket.id, name: name}]) + } + else{ + const tab = map.get(room) + for(let i = 0; i{ + io.to(socket.id).emit("lobby created", 134) + }) + + socket.on("already asked", (nodeId, askingPlayer, askedPlayer) =>{ + io.to(askingPlayer.id).emit("already asked", nodeId, askedPlayer) + }) + + socket.on("ask player", (nodeId, playerId, askingPlayer) =>{ + io.to(playerId).emit("asked", nodeId, askingPlayer) + }) + + socket.on("disconnect", () =>{ + for (const k of map.keys()){ + const tab = map.get(k) + for (let i = 0; i{ + console.log(playerIndex) + io.to(room).emit("node checked", id, works, color, playerIndex) + }) + +}); diff --git a/cryptide_project/src/App.tsx b/cryptide_project/src/App.tsx index a787606..e2dafb6 100644 --- a/cryptide_project/src/App.tsx +++ b/cryptide_project/src/App.tsx @@ -2,6 +2,7 @@ import React from 'react'; import { useState } from 'react'; import { IntlProvider } from 'react-intl'; +import { GameProvider } from './Contexts/GameContext'; /* Page */ import Home from './Pages/Home'; @@ -62,28 +63,30 @@ function App() { // logo // // - - //@ts-ignore - - - - {/* */} - {hasNavbarVisible && } - - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> + + + {/*@ts-ignore*/} + + + + {hasNavbarVisible && } + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> } /> - - - - + + + + + + ); } diff --git a/cryptide_project/src/ColorHelper.ts b/cryptide_project/src/ColorHelper.ts new file mode 100644 index 0000000..6e10218 --- /dev/null +++ b/cryptide_project/src/ColorHelper.ts @@ -0,0 +1,56 @@ +import Player from "./model/Player"; +import { socket } from "./SocketConfig"; + +function positionToColor(pos: number): string{ + switch (pos) { + case 0: + return "blue"; + case 1: + return "green"; + case 2: + return "yellow"; + case 3: + return "purple"; + case 4: + return "red"; + default: + return "brown"; + } +} + +function colorToEmoji(color: string, works: boolean): string{ + if (works){ + switch (color) { + case "blue": + return "🔵"; + case "green": + return "🟢"; + case "yellow": + return "🟡"; + case "purple": + return "🟣"; + case "red": + return "🔴"; + default: + return "🟤"; + } + } + else{ + switch (color) { + case "blue": + return "🟦"; + case "green": + return "🟩"; + case "yellow": + return "🟨"; + case "purple": + return "🟪"; + case "red": + return "🟥"; + default: + return "🟫"; + } + } +} + +export {colorToEmoji, positionToColor} diff --git a/cryptide_project/src/Components/ChoiceBar.tsx b/cryptide_project/src/Components/ChoiceBar.tsx index 6769f62..74e22bd 100644 --- a/cryptide_project/src/Components/ChoiceBar.tsx +++ b/cryptide_project/src/Components/ChoiceBar.tsx @@ -1,17 +1,61 @@ import React from 'react'; +import { useGame } from '../Contexts/GameContext'; +import { socket } from '../SocketConfig'; import './ChoiceBar.css'; import { useTheme } from '../Style/ThemeContext'; +import IndiceTesterFactory from '../model/Factory/IndiceTesterFactory'; +import { positionToColor } from '../ColorHelper'; const ChoiceBar = () => { - const players = ['Player1', 'Player2', 'Player3']; + const { players, nodeId, actualPlayerIndex, personNetwork, indices, room } = useGame(); const theme = useTheme(); + + + function askPlayer(playerId: string){ + if (nodeId !== null){ + socket.emit("ask player", nodeId, playerId, players.find((p) => p.id === socket.id)) + } + } + + function askEveryone(){ + if (nodeId !== null){ + const person = personNetwork?.getPersons().find((p) => p.getId() == nodeId) + if (person != undefined){ + const indiceTester = IndiceTesterFactory.Create(indices[actualPlayerIndex]) + let nextPlayerIndex = actualPlayerIndex + 1 + if (nextPlayerIndex == players.length){ + nextPlayerIndex = 0 + } + + let playerIndex = actualPlayerIndex + 1 + if (indiceTester.Works(person)){ + socket.emit("node checked", nodeId, true, positionToColor(actualPlayerIndex), room, nextPlayerIndex) + while(playerIndex != actualPlayerIndex){ + if (playerIndex == players.length){ + playerIndex = 0 + } + const tester = IndiceTesterFactory.Create(indices[playerIndex]) + const works = tester.Works(person) + socket.emit("node checked", nodeId, works, positionToColor(playerIndex), room, nextPlayerIndex) + if(!works){ + return + } + playerIndex ++ + } + } + } + } + } + return (

Quel joueur voulez-vous interroger ?

+ {players.map((player, index) => ( - ))}
diff --git a/cryptide_project/src/Components/GraphContainer.tsx b/cryptide_project/src/Components/GraphContainer.tsx index bf8061a..b2f5f3a 100644 --- a/cryptide_project/src/Components/GraphContainer.tsx +++ b/cryptide_project/src/Components/GraphContainer.tsx @@ -11,24 +11,58 @@ import "./GraphContainer.css"; import NodePerson from "../model/Graph/NodePerson"; import IndiceTesterFactory from "../model/Factory/IndiceTesterFactory"; import GameCreator from "../model/GameCreator"; +import io from 'socket.io-client'; +import JSONParser from "../JSONParser"; +import PersonNetwork from "../model/PersonsNetwork"; +import Person from "../model/Person"; +import Indice from "../model/Indices/Indice"; +import { useLocation } from "react-router-dom"; +import { useGame } from "../Contexts/GameContext"; +import { socket } from "../SocketConfig" +import { colorToEmoji, positionToColor } from "../ColorHelper"; -const [networkPerson, choosenPerson, choosenIndices, graph] = GameCreator.CreateGame(3, 30) - - -console.log(networkPerson) -console.log(graph) -choosenIndices.forEach((indice) =>{ - console.log(indice.ToString("fr")) -}); -console.log(choosenPerson) -const testIndice = choosenIndices[0] interface MyGraphComponentProps { onNodeClick: (shouldShowChoiceBar: boolean) => void; + handleShowTurnBar: (shouldShowTurnBar: boolean) => void } -const MyGraphComponent: React.FC = ({onNodeClick}) => { +let lastAskingPlayer = 0 +let lastNodeId = -1 +let first = true + +const MyGraphComponent: React.FC = ({onNodeClick, handleShowTurnBar}) => { + + const { indices, indice, person, personNetwork, setNodeIdData, players, askedPersons, setActualPlayerIndexData, room, actualPlayerIndex, turnPlayerIndex } = useGame(); + + let playerIndex: number = turnPlayerIndex + let index = 0 + for (let i=0; i { + console.log(i.ToString("en")) + }); + } + useEffect(() => { + if (personNetwork == null){ + return + } + const graph = GraphCreator.CreateGraph(personNetwork) + const container = document.getElementById('graph-container'); if (!container) { console.error("Container not found"); @@ -58,26 +92,84 @@ const MyGraphComponent: React.FC = ({onNodeClick}) => { } }; - + const networkData = { nodes: nodes, edges: graph.edges }; const network = new Network(container, networkData, initialOptions); - //TEST POUR MONTRER QU'IL Y EN A QU'UN A CHAQUE FOIS - /* - networkPerson.getPersons().forEach(p => { + + + socket.on("node checked",(id, works, color, newPlayerIndex) => { + const node = nodes.get().find((n) => id == n.id) + if (node!=undefined){ + onNodeClick(false) + playerIndex = newPlayerIndex + networkData.nodes.update({id: id, label: node.label + colorToEmoji(color, works)}) + if (playerIndex === thisPlayerIndex){ + handleShowTurnBar(true) + } + else{ + handleShowTurnBar(false) + console.log("je passe bien ici ?????") + } + } + lastAskingPlayer = 0 + lastNodeId = -1 + }) + + socket.on("already asked", (nodeId, askedPlayer) =>{ + console.log("player: " + askedPlayer + " already asked on node " + nodeId) + }) + + + socket.on("asked", (nodeId, askingPlayer) => { + if (askingPlayer.id !== lastAskingPlayer || nodeId !== lastNodeId ){ + lastAskingPlayer = askingPlayer.id + lastNodeId = nodeId + const pers = personNetwork.getPersons().find((p) => p.getId() == nodeId) + if (pers!=undefined){ + if (askedPersons.includes(pers)){ + socket.emit("already asked", nodeId, askingPlayer, socket.id) + return + } + else{ + askedPersons.push(pers) + const node = nodes.get().find((n) => nodeId == n.id) + if (node != undefined && indice != null){ + var tester = IndiceTesterFactory.Create(indice) + playerIndex = playerIndex + 1 + if(playerIndex == players.length){ + playerIndex = 0 + } + if (tester.Works(pers)){ + socket.emit("node checked", nodeId, true, positionToColor(thisPlayerIndex), room, playerIndex) + } + else{ + socket.emit("node checked", nodeId, false, positionToColor(thisPlayerIndex), room, playerIndex) + } + } + } + } + } + + }) + + + + personNetwork.getPersons().forEach(p => { let a = 0 - for (let i of choosenIndices){ + for (let i of indices){ let tester = IndiceTesterFactory.Create(i) if (tester.Works(p)){ a++ } } - if (a==choosenIndices.length){ - networkData.nodes.update({id: p.getId(), label: p.getName() + "\n🔵"}) + if (a==indices.length){ + //networkData.nodes.update({id: p.getId(), label: p.getName() + "\n🔵"}) + console.log(p) } }); - */ + // Gérer le changement entre la physique et le déplacement manuel network.on("dragging", (params) => { @@ -89,28 +181,17 @@ const MyGraphComponent: React.FC = ({onNodeClick}) => { }); network.on("click", (params) => { + if(params.nodes.length > 0){ - //TEST POUR VOIR SI ON PEUT RAJOUTER DES TRUCS AU LABEL - - const pers = networkPerson.getPersons().find((p) => p.getId() == params.nodes[0]) - if (pers!=undefined){ - //@ts-ignore - const node = nodes.get().find((n) => params.nodes[0] == n.id) - if (node != undefined){ - var tester = IndiceTesterFactory.Create(testIndice) - if (tester.Works(pers)){ - networkData.nodes.update({id: params.nodes[0], label: node.label + "🔵"}) - } - else{ - networkData.nodes.update({id: params.nodes[0], label: node.label + "🟦"}) - } - } - - } - + setNodeIdData(params.nodes[0]) // Renvoyer un true pour afficher la choice bar - onNodeClick(true) + if (thisPlayerIndex == playerIndex){ + onNodeClick(true) + } + else{ + onNodeClick(false) + } } else{ // Renvoyer un false pour cacher la choice bar @@ -124,6 +205,8 @@ const MyGraphComponent: React.FC = ({onNodeClick}) => {
); -}; +} + + export default MyGraphComponent; \ No newline at end of file diff --git a/cryptide_project/src/Components/NavBar.tsx b/cryptide_project/src/Components/NavBar.tsx index 3c18aad..2cdf95d 100644 --- a/cryptide_project/src/Components/NavBar.tsx +++ b/cryptide_project/src/Components/NavBar.tsx @@ -30,10 +30,6 @@ function AppNavbar({changeLocale}) { logo - {/*
-

Cryptide

-
by Crypteam
-
*/}
diff --git a/cryptide_project/src/Components/PersonStatus.tsx b/cryptide_project/src/Components/PersonStatus.tsx index 66abe64..7afcca2 100644 --- a/cryptide_project/src/Components/PersonStatus.tsx +++ b/cryptide_project/src/Components/PersonStatus.tsx @@ -9,7 +9,7 @@ import Person from '../res/img/Person.png' import leave from '../res/img/bot.png' //@ts-ignore -function PersonStatus({img = Person, state= leave, name = "Dummy"}) { +function PersonStatus({img = Person, state= Person, name = "Dummy"}) { const theme=useTheme(); return (
diff --git a/cryptide_project/src/Components/TurnBar.tsx b/cryptide_project/src/Components/TurnBar.tsx new file mode 100644 index 0000000..155bbce --- /dev/null +++ b/cryptide_project/src/Components/TurnBar.tsx @@ -0,0 +1,17 @@ +import React from "react"; +import { useTheme } from "../Style/ThemeContext"; + +const TurnBar = () => { + const theme = useTheme(); + return ( +
+ {/* texte changeable et a traduire */} +

Dummy, à vous de jouer !

+
+ ); + }; + + export default TurnBar; \ No newline at end of file diff --git a/cryptide_project/src/Contexts/GameContext.tsx b/cryptide_project/src/Contexts/GameContext.tsx new file mode 100644 index 0000000..a725498 --- /dev/null +++ b/cryptide_project/src/Contexts/GameContext.tsx @@ -0,0 +1,103 @@ +import React, { createContext, useContext, useState, ReactNode } from 'react'; +import Indice from '../model/Indices/Indice'; +import Person from '../model/Person'; +import PersonNetwork from '../model/PersonsNetwork'; +import Player from '../model/Player'; + +interface GameContextProps { + indices: Indice[]; + indice: Indice | null + person: Person | null; + personNetwork: PersonNetwork | null; + players: Player[] + nodeId: number | null + askedPersons: Person[]; + actualPlayerIndex: number; + turnPlayerIndex: number; + room: string; + setIndicesData: (newIndices: Indice[]) => void; + setIndiceData: (newIndice: Indice) => void; + setPersonData: (newPerson: Person) => void; + setPersonNetworkData: (newPersonNetwork: PersonNetwork) => void; + setPlayersData: (newPlayer: Player[]) => void; + setNodeIdData: (newId: number) => void; + setAskedPersonsData: (newAskedPersons: Person[]) => void; + setActualPlayerIndexData: (newActualPlayerIndex: number) => void; + setTurnPlayerIndexData: (newTurnPlayerIndex: number) => void; + setRoomData: (newRoom: string) => void; +} + +const GameContext = createContext(undefined); + +interface GameProviderProps { + children: ReactNode; +} + +export const GameProvider: React.FC = ({ children }) => { + const [indices, setIndices] = useState([]); + const [indice, setIndice] = useState(null); + const [person, setPerson] = useState(null); + const [personNetwork, setPersonNetwork] = useState(null); + const [players, setPlayers] = useState([]) + const [nodeId, setNodeId] = useState(null); + const [askedPersons, setAskedPersons] = useState([]) + const [actualPlayerIndex, setActualPlayerIndex] = useState(-1) + const [turnPlayerIndex, setTurnPlayerIndex] = useState(-1) + const [room, setRoom] = useState("") + + + const setIndicesData = (newIndices: Indice[]) => { + setIndices(newIndices); + }; + + const setIndiceData = (newIndice: Indice) =>{ + setIndice(newIndice) + }; + + + const setPersonData = (newPerson: Person) => { + setPerson(newPerson); + }; + + const setPersonNetworkData = (newPersonNetwork: PersonNetwork) => { + setPersonNetwork(newPersonNetwork); + }; + + const setPlayersData = (newPlayers: Player[]) => { + setPlayers(newPlayers); + }; + + const setNodeIdData = (newId: number) => { + setNodeId(newId); + }; + + const setAskedPersonsData = (newAskedPerson: Person[]) => { + setAskedPersons(newAskedPerson); + }; + + const setActualPlayerIndexData = (newActualPlayerIndex: number) =>{ + setActualPlayerIndex(newActualPlayerIndex) + } + + const setTurnPlayerIndexData = (newTurnPlayerIndex: number) =>{ + setTurnPlayerIndex(newTurnPlayerIndex) + } + + const setRoomData = (newRoom: string) =>{ + setRoom(newRoom) + } + + return ( + + {children} + + ); +}; + +export const useGame = (): GameContextProps => { + const context = useContext(GameContext); + if (!context) { + throw new Error('useGame must be used within an GameProvider'); + } + return context; +}; diff --git a/cryptide_project/src/JSONParser.ts b/cryptide_project/src/JSONParser.ts new file mode 100644 index 0000000..037cf19 --- /dev/null +++ b/cryptide_project/src/JSONParser.ts @@ -0,0 +1,83 @@ +import AgeIndice from "./model/Indices/AgeIndice"; +import ColorEdgesIndice from "./model/Indices/ColorEdgesIndice"; +import ColorIndice from "./model/Indices/ColorIndice"; +import Indice from "./model/Indices/Indice"; +import NbEdgesIndice from "./model/Indices/NbEdgesIndice"; +import NbSportIndice from "./model/Indices/NbSportIndice"; +import SportIndice from "./model/Indices/SportIndice"; +import Person from "./model/Person"; +import PersonNetwork from "./model/PersonsNetwork"; + +class JSONParser{ + + static JSONToNetwork(jsonString: any): PersonNetwork{ + const json = JSON.parse(jsonString) + const persons: Person[] = [] + const personFriends = new Map() + json.persons.forEach((personJson: any) => { + persons.push(JSONParser.JSONToPerson(personJson)) + personJson.friends.forEach((f: any) => { + if (personFriends.get(personJson.id) == undefined){ + personFriends.set(personJson.id, [f.id]) + } + else{ + personFriends.get(personJson.id)?.push(f.id) + } + }); + }); + + for(const person of persons){ + const tab = personFriends.get(person.getId()) + if (tab != undefined){ + for(const i of tab){ + person.addFriend(persons.filter((p) => p.getId() == i)[0]) + } + } + } + + return new PersonNetwork(persons); + } + + static JSONToPerson(json: any): Person { + const person = new Person( + json.id, + json.name, + json.age, + json.color, + json.sports, + [] + ); + return person; + } + + + static JSONToIndice(json: any): Indice{ + switch (json.type){ + case "AgeIndice": + return new AgeIndice(json.id, json.minimum, json.maximum) + case "ColorEdgesIndice": + return new ColorEdgesIndice(json.id, json.neighborsColors) + case "ColorIndice": + return new ColorIndice(json.id, json.colors) + case "NbEdgesIndice": + return new NbEdgesIndice(json.id, json.nbNeighbors) + case "NbSportIndice": + return new NbSportIndice(json.id, json.nbSport) + case "SportIndice": + return new SportIndice(json.id, json.sports) + default: + throw new Error("PARSER unable to parse indice: " + json.type); + } + } + + static JSONToIndices(jsonString: any): Indice[]{ + const json = JSON.parse(jsonString) + const tabIndice: Indice[] = [] + json.forEach((i: any) => { + tabIndice.push(this.JSONToIndice(i)) + }); + return tabIndice + } +} + +export default JSONParser \ No newline at end of file diff --git a/cryptide_project/src/Pages/InGame.tsx b/cryptide_project/src/Pages/InGame.tsx index 38946bc..61567f6 100644 --- a/cryptide_project/src/Pages/InGame.tsx +++ b/cryptide_project/src/Pages/InGame.tsx @@ -32,38 +32,27 @@ import { HiLanguage } from 'react-icons/hi2'; import { Nav, NavDropdown } from 'react-bootstrap'; import { FormattedMessage } from 'react-intl'; import Color from '../model/Color'; +import TurnBar from '../Components/TurnBar'; +import { useGame } from '../Contexts/GameContext'; //@ts-ignore const InGame = ({locale, changeLocale}) => { - const players = [ - { state: Replay, name: 'Dummy' }, - { state: Replay, name: 'Boat' }, - { state: Replay, name: 'Bot-tom' }, - { state: Replay, name: 'Dummy' }, - { state: Replay, name: 'Boat' }, - { state: Replay, name: 'Bot-tom' }, - { state: Replay, name: 'Dummy' }, - { state: Replay, name: 'Boat' }, - { state: Replay, name: 'Bot-tom' }, - { state: Replay, name: 'Dummy' }, - { state: Replay, name: 'Boat' }, - { state: Replay, name: 'Bot-tom' }, - { state: Replay, name: 'Dummy' }, - { state: Replay, name: 'Boat' }, - { state: Replay, name: 'Bot-tom' } - // Ajouter d'autres joueurs au besoin - ]; - - const theme = useTheme(); const [showChoiceBar, setShowChoiceBar] = useState(false); + const [showTurnBar, setShowTurnBar] = useState(false); + const handleNodeClick = (shouldShowChoiceBar: boolean) => { setShowChoiceBar(shouldShowChoiceBar); }; + + const handleShowTurnBar = (shouldShowTurnBar: boolean) => { + setShowTurnBar(shouldShowTurnBar); + }; + /* offcanvas */ //? faire une fonction pour close et show en fonction de l'etat du canva ? //? comment faire pour eviter la recopie de tout le code a chaque canvas boostrap ? @@ -114,18 +103,14 @@ const InGame = ({locale, changeLocale}) => { const [SwitchEnabled, setSwitchEnabled] = useState(false) const indices = Stub.GenerateIndice() + const { indice, players } = useGame(); + return (
-
- {/* texte changeable et a traduire */} -

Dummy, à vous de jouer !

-
+ {showTurnBar && }
- +
@@ -211,9 +196,7 @@ const InGame = ({locale, changeLocale}) => { {/* Possède les cheveux noir ou joue au basket */} - {indices[0].ToString(locale)}
- {indices[1].ToString(locale)}
- {indices[2].ToString(locale)} + {indice?.ToString(locale)}
@@ -248,13 +231,14 @@ const InGame = ({locale, changeLocale}) => { -
{showChoiceBar && }
-
{/* tmp */} + {/* +
{/* tmp
+ */}
); }; diff --git a/cryptide_project/src/Pages/Lobby.css b/cryptide_project/src/Pages/Lobby.css index 5aed52c..5c4bfbd 100644 --- a/cryptide_project/src/Pages/Lobby.css +++ b/cryptide_project/src/Pages/Lobby.css @@ -1,5 +1,4 @@ - .lobby-container { display: flex; background-color: #fff; @@ -41,4 +40,17 @@ margin: 20px; } +.codeDiv{ + display: flex; + align-items: end; + justify-content: end; + margin: auto 20px; +} +.codeDiv p{ + font-style: italic; + font-weight: bold; + color: gray; + font-size: 20px; + cursor: pointer; +} \ No newline at end of file diff --git a/cryptide_project/src/Pages/Lobby.tsx b/cryptide_project/src/Pages/Lobby.tsx index aea8d22..d6b97da 100644 --- a/cryptide_project/src/Pages/Lobby.tsx +++ b/cryptide_project/src/Pages/Lobby.tsx @@ -1,45 +1,126 @@ -import React from 'react'; -import { useState } from 'react'; - -// import { useId } from 'react'; -// import { v4 as uuidv4 } from 'uuid'; - - -/* Style */ +import React, { useEffect, useState } from 'react'; import './Lobby.css'; import { useTheme } from '../Style/ThemeContext'; /* res */ -import Person from '../res/img/Person.png'; +import PlayerItemList from '../Components/PlayerItemList' +import PersonImg from '../res/img/Person.png'; import Bot from '../res/img/bot.png'; import param from '../res/icon/param.png'; import cible from '../res/icon/cible.png'; /* Component */ import ButtonImgNav from '../Components/ButtonImgNav'; -import PlayerItemList from '../Components/PlayerItemList' +import { io } from 'socket.io-client'; +import { Link } from 'react-router-dom'; +import PersonNetwork from '../model/PersonsNetwork'; +import Person from '../model/Person'; +import GameCreator from '../model/GameCreator'; +import { useGame } from '../Contexts/GameContext'; +import JSONParser from '../JSONParser'; +import Indice from '../model/Indices/Indice'; +import { useNavigate } from 'react-router-dom'; +import { socket } from "../SocketConfig"; +import { random } from 'lodash'; +import Player from '../model/Player'; + + function Lobby() { const theme=useTheme(); + + const [codeShowed, setCodeShowed] = useState(true); - const players = [ + const playerslst = [ { pdp: Person, name: "Dummy (vous)", id: 1 }, { pdp: Person, name: "Dummy2)", id: 1 }, //{ pdp: Bot, name: "Boat", id: 2 }, // { pdp: Bot, name: "Bot-tom", id: 3 }, ]; - while (players.length < 3) { - players.push({ pdp: Bot, name: "BotAdded", id: players.length + 1 }); + while (playerslst.length < 3) { + playerslst.push({ pdp: Bot, name: "BotAdded", id: playerslst.length + 1 }); + } + + const navigate = useNavigate(); + + + const { indices, setIndicesData, indice, setIndiceData, person, setPersonData, personNetwork, setPersonNetworkData, players, setPlayersData, setActualPlayerIndexData, setTurnPlayerIndexData, setRoomData } = useGame(); + + let first = true + + const params = new URLSearchParams(window.location.search); + const room = params.get('room'); + + useEffect(() => { + if (first){ + first = false + socket.emit("lobby joined", room, "test name" + Math.floor(Math.random() * 10)) + + return () => { + socket.off('game created'); + }; + } + + }, []); + + socket.on("game created", (jsonNetwork, jsonPersonString, jsonIndicesString, playerIndex)=> { + const jsonPerson = JSON.parse(jsonPersonString) + const network: PersonNetwork = JSONParser.JSONToNetwork(jsonNetwork) + const choosenOne: Person = network.getPersons().filter((i) => i.getId() == jsonPerson.id)[0] + const choosenIndices : Indice[] = JSONParser.JSONToIndices(jsonIndicesString) + let index = 0 + for (let i=0; i{ + const tmpTab: Player[] = [] + for (const p of tab){ + tmpTab.push(new Player(p.id, p.name)) + } + setPlayersData(tab.map((p: any) => new Player(p.id, p.name))) + }) + + function StartGame(){ + const [networkPerson, choosenPerson, choosenIndices] = GameCreator.CreateGame(players.length, 30) + setPersonData(choosenPerson) + setPersonNetworkData(networkPerson) + setIndicesData(choosenIndices) + socket.emit('network created', JSON.stringify(networkPerson, null, 2), JSON.stringify(choosenPerson), JSON.stringify(choosenIndices), room); } return (
+
setCodeShowed(!codeShowed)}> + { + codeShowed ? ( +

Room : {room}

+ ) : ( +

Room : ******

+ ) + } +
{/* //! voir pour la gestion avec un liste, utilisateur avec le "+ (vous)" et les pdp avec les lettres grecs (?)*/} - {players.map((player) => ( - + {players.map((player, index) => ( + ))}
@@ -63,12 +144,24 @@ function Lobby() { //? indice avancé ? ==> négation, voisin du 2e degré etc. } -
- {/* page de baptiste ici */} +
+
); + + function shuffleArray(array: Indice[]) { + for (var i = array.length - 1; i > 0; i--) { + var j = Math.floor(Math.random() * (i + 1)); + var temp = array[i]; + array[i] = array[j]; + array[j] = temp; + } + } } export default Lobby; diff --git a/cryptide_project/src/Pages/Play.tsx b/cryptide_project/src/Pages/Play.tsx index 08b8a33..b6ead60 100644 --- a/cryptide_project/src/Pages/Play.tsx +++ b/cryptide_project/src/Pages/Play.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; /* Style */ import './Play.css'; @@ -17,10 +17,46 @@ import Person from '../res/img/Person.png'; import trophy from '../res/icon/trophy.png'; import param from '../res/icon/param.png'; import share from '../res/icon/share.png'; +import { socket } from '../SocketConfig'; +import { useNavigate } from 'react-router-dom'; function Play() { const theme=useTheme() + + const [room, setRoom] = useState(null); + const navigate = useNavigate(); + + function createLobby(){ + socket.emit("lobby created") + } + + + + useEffect(() => { + const handleLobbyCreated = (newRoom: any) => { + setRoom(newRoom); + }; + + // Ajouter l'event listener + socket.on('lobby created', handleLobbyCreated); + + // Nettoyer l'event listener lors du démontage du composant + return () => { + socket.off('lobby created', handleLobbyCreated); + }; + + }, []); // Aucune dépendance ici + + useEffect(() => { + if (room !== null) { + const nouvelleURL = `/lobby?room=${room}`; + navigate(nouvelleURL); + } + }, [room, navigate]); + + + return (
@@ -42,13 +78,11 @@ function Play() { />
- + + - - -
diff --git a/cryptide_project/src/SocketConfig.ts b/cryptide_project/src/SocketConfig.ts new file mode 100644 index 0000000..2fea1de --- /dev/null +++ b/cryptide_project/src/SocketConfig.ts @@ -0,0 +1,6 @@ +import { io } from "socket.io-client"; + + +const socket = io("http://localhost:3002"); + +export {socket} \ No newline at end of file diff --git a/cryptide_project/src/Translations/en.json b/cryptide_project/src/Translations/en.json index dd6bacd..96cbb54 100644 --- a/cryptide_project/src/Translations/en.json +++ b/cryptide_project/src/Translations/en.json @@ -42,7 +42,7 @@ "and": "and", "or": "or", - "or_sport": "or", + "or_sport": "and/or", "age_indice_start": "The suspect is between", diff --git a/cryptide_project/src/Translations/fr.json b/cryptide_project/src/Translations/fr.json index 6d3d1e3..e46c3e1 100644 --- a/cryptide_project/src/Translations/fr.json +++ b/cryptide_project/src/Translations/fr.json @@ -42,7 +42,7 @@ "and": "et", "or": "ou", - "or_sport": "ou du", + "or_sport": "et/ou du", "age_indice_start": "Le suspect a entre", "age_indice_more_start": "Le suspect a ou a plus de", diff --git a/cryptide_project/src/model/GameCreator.ts b/cryptide_project/src/model/GameCreator.ts index 1d9d8ca..026969c 100644 --- a/cryptide_project/src/model/GameCreator.ts +++ b/cryptide_project/src/model/GameCreator.ts @@ -10,7 +10,7 @@ import PersonNetwork from "./PersonsNetwork"; import Stub from "./Stub"; class GameCreator{ - static CreateGame(nbPlayers: number, nbNodes: number): [PersonNetwork, Person, Indice[], GraphPerson]{ + static CreateGame(nbPlayers: number, nbNodes: number): [PersonNetwork, Person, Indice[]]{ const edgesCreator = new EdgesCreator() const chooser = new IndiceChooser() @@ -26,9 +26,7 @@ class GameCreator{ edgesCreator.CreateAllEdges(networkPerson, person, choosenIndices) - const graph = GraphCreator.CreateGraph(networkPerson) - - return [networkPerson, person, choosenIndices, graph] + return [networkPerson, person, choosenIndices] } } diff --git a/cryptide_project/src/model/Indices/AgeIndice.ts b/cryptide_project/src/model/Indices/AgeIndice.ts index ba7eb7d..9edb813 100644 --- a/cryptide_project/src/model/Indices/AgeIndice.ts +++ b/cryptide_project/src/model/Indices/AgeIndice.ts @@ -28,6 +28,15 @@ class AgeIndice extends Indice { getMaximum(): number{ return this.maximum } + + toJSON() { + return { + type: "AgeIndice", + id: this.id, + minimum: this.minimum, + maximum: this.maximum + }; + } } export default AgeIndice \ No newline at end of file diff --git a/cryptide_project/src/model/Indices/ColorEdgesIndice.ts b/cryptide_project/src/model/Indices/ColorEdgesIndice.ts index e922ed2..d4c368a 100644 --- a/cryptide_project/src/model/Indices/ColorEdgesIndice.ts +++ b/cryptide_project/src/model/Indices/ColorEdgesIndice.ts @@ -29,6 +29,14 @@ class ColorEdgesIndice extends EdgesIndice { } return `${string} ${json.color_edges_end}` } + + toJSON() { + return { + type: "ColorEdgesIndice", + id: this.id, + neighborsColors: this.neighborsColors, + }; + } } export default ColorEdgesIndice \ No newline at end of file diff --git a/cryptide_project/src/model/Indices/ColorIndice.ts b/cryptide_project/src/model/Indices/ColorIndice.ts index 3ec00ac..6bf22a4 100644 --- a/cryptide_project/src/model/Indices/ColorIndice.ts +++ b/cryptide_project/src/model/Indices/ColorIndice.ts @@ -28,6 +28,15 @@ class ColorIndice extends Indice { getColors(): Color[]{ return this.colors } + + toJSON() { + return { + type: "ColorIndice", + id: this.id, + colors: this.colors, + }; + } } + export default ColorIndice \ No newline at end of file diff --git a/cryptide_project/src/model/Indices/Indice.ts b/cryptide_project/src/model/Indices/Indice.ts index 8a5ffec..622f65e 100644 --- a/cryptide_project/src/model/Indices/Indice.ts +++ b/cryptide_project/src/model/Indices/Indice.ts @@ -17,7 +17,8 @@ abstract class Indice { // Méthode abstraite pour être implémentée par les classes dérivées abstract ToString(lang: string): string; - + abstract toJSON(): any } + export default Indice diff --git a/cryptide_project/src/model/Indices/NbEdgesIndice.ts b/cryptide_project/src/model/Indices/NbEdgesIndice.ts index b0e4e7f..0aab020 100644 --- a/cryptide_project/src/model/Indices/NbEdgesIndice.ts +++ b/cryptide_project/src/model/Indices/NbEdgesIndice.ts @@ -18,6 +18,14 @@ class NbEdgesIndice extends EdgesIndice { let json = GetJsonFile(lang) return `${json.nb_friends_indice_start} ${this.nbNeighbors} ${json.nb_friends_indice_end}`; } + + toJSON() { + return { + type: "NbEdgesIndice", + id: this.id, + nbNeighbors: this.nbNeighbors, + }; + } } export default NbEdgesIndice \ No newline at end of file diff --git a/cryptide_project/src/model/Indices/NbSportIndice.ts b/cryptide_project/src/model/Indices/NbSportIndice.ts index fe660e7..a34bcbb 100644 --- a/cryptide_project/src/model/Indices/NbSportIndice.ts +++ b/cryptide_project/src/model/Indices/NbSportIndice.ts @@ -18,6 +18,14 @@ class NbSportIndice extends Indice { let json = GetJsonFile(lang) return `${json.nb_sports_indice_start} ${this.nbSport} ${json.nb_sports_indice_end}`; } + + toJSON() { + return { + type: "NbSportIndice", + id: this.id, + nbSport: this.nbSport, + }; + } } export default NbSportIndice \ No newline at end of file diff --git a/cryptide_project/src/model/Indices/SportIndice.ts b/cryptide_project/src/model/Indices/SportIndice.ts index c4038fb..2dbae4b 100644 --- a/cryptide_project/src/model/Indices/SportIndice.ts +++ b/cryptide_project/src/model/Indices/SportIndice.ts @@ -29,6 +29,14 @@ class SportIndice extends Indice { getSports(): Sport[]{ return this.sports } + + toJSON() { + return { + type: "SportIndice", + id: this.id, + sports: this.sports, + }; + } } export default SportIndice \ No newline at end of file diff --git a/cryptide_project/src/model/Person.ts b/cryptide_project/src/model/Person.ts index 782d7d4..caf4b49 100644 --- a/cryptide_project/src/model/Person.ts +++ b/cryptide_project/src/model/Person.ts @@ -78,6 +78,24 @@ class Person { setFriends(friends: Person[]): void { this.friends = friends; } + + toJSON() { + return { + id: this.id, + name: this.name, + age: this.age, + color: this.color, + sports: this.sports, + friends: this.friends.map(friend => ({ + id: friend.id, + name: friend.name, + age: friend.age, + color: friend.color, + sports: friend.sports, + // Ne pas inclure friends ici pour éviter la boucle infinie + })) + }; + } } export default Person diff --git a/cryptide_project/src/model/Player.ts b/cryptide_project/src/model/Player.ts new file mode 100644 index 0000000..4af4485 --- /dev/null +++ b/cryptide_project/src/model/Player.ts @@ -0,0 +1,12 @@ +class Player{ + + public id: string + public name: string; + + constructor(id: string, name: string){ + this.id=id + this.name=name + } +} + +export default Player \ No newline at end of file diff --git a/cryptide_project/yarn.lock b/cryptide_project/yarn.lock index da6e76a..af7f0f6 100644 --- a/cryptide_project/yarn.lock +++ b/cryptide_project/yarn.lock @@ -1869,6 +1869,11 @@ dependencies: "@sinonjs/commons" "^1.7.0" +"@socket.io/component-emitter@~3.1.0": + 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== + "@surma/rollup-plugin-off-main-thread@^2.2.3": version "2.2.3" resolved "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz" @@ -2126,6 +2131,18 @@ dependencies: "@types/node" "*" +"@types/cookie@^0.4.1": + 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== + +"@types/cors@^2.8.12": + version "2.8.16" + resolved "https://registry.npmjs.org/@types/cors/-/cors-2.8.16.tgz" + integrity sha512-Trx5or1Nyg1Fq138PCuWqoApzvoSLWzZ25ORBiHMbbUT42g578lH1GT4TwYDbiUOLFuDsCkfLneT2105fsFWGg== + dependencies: + "@types/node" "*" + "@types/eslint-scope@^3.7.3": version "3.7.7" resolved "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz" @@ -2263,7 +2280,7 @@ dependencies: "@types/node" "*" -"@types/node@*": +"@types/node@*", "@types/node@>=10.0.0": version "20.8.10" resolved "https://registry.npmjs.org/@types/node/-/node-20.8.10.tgz" integrity sha512-TlgT8JntpcbmKUFzjhsyhGfP2fsiz1Mv56im6enJ905xG1DAYesxJaeSbGqQmAw8OWPdhyJGhGSQGKRNJ45u9w== @@ -3168,6 +3185,11 @@ balanced-match@^1.0.0: resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +base64id@~2.0.0, base64id@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz" + integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== + batch@0.6.1: version "0.6.1" resolved "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz" @@ -3630,6 +3652,11 @@ cookie-signature@1.0.6: resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== +cookie@~0.4.1: + version "0.4.2" + resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz" + integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== + cookie@0.5.0: version "0.5.0" resolved "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz" @@ -3657,6 +3684,14 @@ core-util-is@~1.0.0: resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== +cors@^2.8.5, cors@~2.8.5: + 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" + cosmiconfig@^6.0.0: version "6.0.0" resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz" @@ -3924,7 +3959,7 @@ debug@^3.2.7: dependencies: ms "^2.1.1" -debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4, debug@4: +debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2, debug@4: version "4.3.4" resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -4256,6 +4291,38 @@ encodeurl@~1.0.2: resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== +engine.io-client@~6.5.2: + version "6.5.3" + resolved "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.3.tgz" + integrity sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q== + dependencies: + "@socket.io/component-emitter" "~3.1.0" + debug "~4.3.1" + engine.io-parser "~5.2.1" + ws "~8.11.0" + xmlhttprequest-ssl "~2.0.0" + +engine.io-parser@~5.2.1: + version "5.2.1" + resolved "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz" + integrity sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ== + +engine.io@~6.5.2: + 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" + enhanced-resolve@^5.15.0: version "5.15.0" resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz" @@ -4779,7 +4846,7 @@ expect@^29.0.0: jest-message-util "^29.7.0" jest-util "^29.7.0" -express@^4.17.3: +express@^4.17.3, express@^4.18.2: version "4.18.2" resolved "https://registry.npmjs.org/express/-/express-4.18.2.tgz" integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== @@ -7022,7 +7089,7 @@ nwsapi@^2.2.0: resolved "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz" integrity sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ== -object-assign@^4.0.1, object-assign@^4.1.1: +object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== @@ -8825,6 +8892,44 @@ slash@^4.0.0: resolved "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz" integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== +socket.io-adapter@~2.5.2: + 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" + +socket.io-client@^4.7.2: + version "4.7.2" + resolved "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.2.tgz" + integrity sha512-vtA0uD4ibrYD793SOIAwlo8cj6haOeMHrGvwPxJsxH7CeIksqJ+3Zc06RvWTIFgiSqx4A3sOnTXpfAEE2Zyz6w== + dependencies: + "@socket.io/component-emitter" "~3.1.0" + debug "~4.3.2" + engine.io-client "~6.5.2" + socket.io-parser "~4.2.4" + +socket.io-parser@~4.2.4: + 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" + +socket.io@^4.7.2: + version "4.7.2" + resolved "https://registry.npmjs.org/socket.io/-/socket.io-4.7.2.tgz" + integrity sha512-bvKVS29/I5fl2FGLNHuXlQaUH/BlzX1IN6S+NKLNZpBsPZIDH+90eQmCs2Railn4YUiww4SzUedJ6+uzwFnKLw== + 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" + sockjs@^0.3.24: version "0.3.24" resolved "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz" @@ -9663,7 +9768,7 @@ v8-to-istanbul@^8.1.0: convert-source-map "^1.6.0" source-map "^0.7.3" -vary@~1.1.2: +vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== @@ -10173,6 +10278,11 @@ ws@^8.13.0: resolved "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz" integrity sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g== +ws@~8.11.0: + version "8.11.0" + resolved "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz" + integrity sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg== + xml-name-validator@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz" @@ -10183,6 +10293,11 @@ xmlchars@^2.2.0: resolved "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== +xmlhttprequest-ssl@~2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz" + integrity sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A== + y18n@^5.0.5: version "5.0.8" resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz"