Début du serveur

pull/56/head
Thomas Chazot 1 year ago
parent db7654cfd0
commit 0020b164f7

@ -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",
@ -3784,6 +3786,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",
@ -4204,6 +4211,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",
@ -5642,6 +5662,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",
@ -6371,6 +6399,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",
@ -7241,6 +7281,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",
@ -15593,6 +15721,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",
@ -17896,6 +18095,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",

@ -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",
@ -19,7 +21,12 @@
"react-intl": "^6.5.2",
"react-router-dom": "^6.18.0",
"react-scripts": "5.0.1",
<<<<<<< HEAD
"react-switch": "^7.0.0",
=======
"socket.io": "^4.7.2",
"socket.io-client": "^4.7.2",
>>>>>>> af92727 (Début du serveur)
"typescript": "^5.2.2",
"vis-network": "^9.1.9",
"web-vitals": "^2.1.4"

@ -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<tab.length; i++){
if (tab[i].id === socket.id){
tab.splice(i, 1)
}
}
map.get(room).push({id: socket.id, name: name})
}
io.to(room).emit("new player", map.get(room))
})
socket.on("lobby created", () =>{
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<tab.length; i++){
if (tab[i].id === socket.id){
tab.splice(i, 1)
}
}
}
})
socket.on("node checked", (id, works, color, room, playerIndex) =>{
console.log(playerIndex)
io.to(room).emit("node checked", id, works, color, playerIndex)
})
});

@ -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';
@ -61,26 +62,25 @@ function App() {
// <img src={logo} className="App-logo" alt="logo" />
// </header>
// </div>
//@ts-ignore
<IntlProvider locale={locale} messages={messages[locale]}>
<ThemeProvider>
<BrowserRouter>
{/* <AppNavbar changeLocale={changeLocale} /> */}
{hasNavbarVisible && <AppNavbar changeLocale={changeLocale} />}
<Routes>
<Route path="/" element={<Home />} />
<Route path="/login" element={<Login />} />
<Route path="/signup" element={<SignUp />} />
<Route path="/play" element={<Play/>} />
<Route path="/lobby" element={<Lobby/>} />
<Route path="/endgame" element={<EndGame/>} />
<Route path="/game" element={<InGame locale={locale} changeLocale={changeLocale} />} />
<Route path="/info" element={<InfoPage/>} />
</Routes>
</BrowserRouter>
</ThemeProvider>
</IntlProvider>
<GameProvider>
{/*@ts-ignore*/}
<IntlProvider locale={locale} messages={messages[locale]}>
<BrowserRouter>
<AppNavbar changeLocale={changeLocale} />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/login" element={<Login />} />
<Route path="/signup" element={<SignUp />} />
<Route path="/play" element={<Play/>} />
<Route path="/lobby" element={<Lobby/>} />
<Route path="/endgame" element={<EndGame/>} />
<Route path="/game" element={<InGame/>} />
</Routes>
</BrowserRouter>
</IntlProvider>
</GameProvider>
);
}

@ -1,17 +1,26 @@
import React from 'react';
import { useGame } from '../Contexts/GameContext';
import { socket } from '../SocketConfig';
import './ChoiceBar.css';
import { useTheme } from '../Style/ThemeContext';
const ChoiceBar = () => {
const players = ['Player1', 'Player2', 'Player3'];
const theme = useTheme();
const { players, nodeId } = useGame();
function askPlayer(playerId: string){
if (nodeId !== null){
socket.emit("ask player", nodeId, playerId, players.find((p) => p.id === socket.id))
}
}
return (
<div className="choice-bar-container">
<h3 className="choice-bar-heading">Quel joueur voulez-vous interroger ?</h3>
<div>
{players.map((player, index) => (
<button key={index} className="choice-bar-button" style={{ backgroundColor: theme.colors.primary }}>
{player}
player.id !== socket.id &&
<button key={index} className="choice-bar-button" onClick={() => askPlayer(player.id)}>
{player.name}
</button>
))}
</div>

@ -11,24 +11,44 @@ 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"
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;
}
let lastAskingPlayer = 0
let first = true
const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick}) => {
const { indices, indice, person, personNetwork, setNodeIdData, players, askedPersons, setActualPlayerIndexData, room, actualPlayerIndex } = useGame();
let playerIndex: number = actualPlayerIndex
if (first){
first = false
console.log(indice)
indices.forEach(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 +78,76 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({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){
setActualPlayerIndexData(newPlayerIndex)
playerIndex = newPlayerIndex
networkData.nodes.update({id: id, label: node.label + colorToEmoji(color, works)})
}
lastAskingPlayer = 0
})
socket.on("already asked", (nodeId, askedPlayer) =>{
console.log("player: " + askedPlayer + " already asked on node " + nodeId)
})
socket.on("asked", (nodeId, askingPlayer) => {
if (askingPlayer.id !== lastAskingPlayer){
lastAskingPlayer = askingPlayer.id
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
}
console.log(playerIndex)
if (tester.Works(pers)){
socket.emit("node checked", nodeId, true, positionToColor(), room, playerIndex)
}
else{
socket.emit("node checked", nodeId, false, positionToColor(), 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 +159,24 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({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)
let index = 0
for (let i=0; i<players.length; i++){
if(players[i].id == socket.id){
index=i
break
}
}
if (index == playerIndex){
onNodeClick(true)
}
else{
onNodeClick(false)
}
}
else{
// Renvoyer un false pour cacher la choice bar
@ -124,6 +190,67 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick}) => {
<div id="graph-container"/>
</>
);
function positionToColor(): string{
let index = 0
for (let i=0; i<players.length; i++){
if(players[i].id == socket.id){
index=i
break
}
}
switch (index) {
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 default MyGraphComponent;

@ -0,0 +1,96 @@
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;
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;
setRoomData: (newRoom: string) => void;
}
const GameContext = createContext<GameContextProps | undefined>(undefined);
interface GameProviderProps {
children: ReactNode;
}
export const GameProvider: React.FC<GameProviderProps> = ({ children }) => {
const [indices, setIndices] = useState<Indice[]>([]);
const [indice, setIndice] = useState<Indice | null>(null);
const [person, setPerson] = useState<Person | null>(null);
const [personNetwork, setPersonNetwork] = useState<PersonNetwork | null>(null);
const [players, setPlayers] = useState<Player[]>([])
const [nodeId, setNodeId] = useState<number | null>(null);
const [askedPersons, setAskedPersons] = useState<Person[]>([])
const [actualPlayerIndex, setActualPlayerIndex] = useState<number>(-1)
const [room, setRoom] = useState<string>("")
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 setRoomData = (newRoom: string) =>{
setRoom(newRoom)
}
return (
<GameContext.Provider value={{ indices, setIndicesData, indice, setIndiceData, person, setPersonData, personNetwork, setPersonNetworkData, players, setPlayersData, nodeId, setNodeIdData, askedPersons, setAskedPersonsData, actualPlayerIndex, setActualPlayerIndexData, room, setRoomData }}>
{children}
</GameContext.Provider>
);
};
export const useGame = (): GameContextProps => {
const context = useContext(GameContext);
if (!context) {
throw new Error('useGame must be used within an GameProvider');
}
return context;
};

@ -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<number, number[]>()
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

@ -1,5 +1,4 @@
.lobby-container {
display: flex;
background-color: #fff;

@ -1,29 +1,99 @@
import React from 'react';
/* 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 navigate = useNavigate();
const { indices, setIndicesData, indice, setIndiceData, person, setPersonData, personNetwork, setPersonNetworkData, players, setPlayersData, setActualPlayerIndexData, 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<players.length; i++){
if(players[i].id == socket.id){
index=i
break
}
}
if (room != null){
setRoomData(room)
}
setActualPlayerIndexData(playerIndex)
setIndiceData(choosenIndices[index])
setPersonData(choosenOne)
setPersonNetworkData(network)
setIndicesData(choosenIndices)
first = true
navigate('/game');
});
socket.on("new player", (tab) =>{
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 (
<div className='lobby-container'>
<div className='left-part'>
<div className='player-board'>
{players.map((player, index) => (
<PlayerItemList key={player.id} pdp={PersonImg} name={player.name}/>
))}
{/* //! voir pour la gestion avec un liste, utilisateur avec le "+ (vous)" et les pdp avec les lettres grecs (?)*/}
<PlayerItemList pdp={Person} name="Dummy (vous)"/>
<PlayerItemList pdp={Bot} name="Boat"/>
<PlayerItemList pdp={Bot} name="Bot-tom"/>
</div>
</div>
@ -46,12 +116,24 @@ function Lobby() {
//? indice avancé ? ==> négation, voisin du 2e degré etc.
}
</ul>
<center>
<ButtonImgNav dest='/game' img={cible} text=' À la chasse !'/> {/* page de baptiste ici */}
<center >
<button className='buttonNabImg' onClick={StartGame}>
<img src={cible} alt="Button Image" height="50" width="50"/>
<p>{"la chasse !"}</p>
</button>
</center>
</div>
</div>
);
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;

@ -1,4 +1,4 @@
import React from 'react';
import React, { useEffect, useState } from 'react';
/* Style */
import './Play.css';
@ -17,10 +17,45 @@ 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 (
<div className="MainContainer">
@ -42,12 +77,10 @@ function Play() {
/>
</div>
<div className='buttonGroupVertical'>
<Link to="/lobby">
<button className="ButtonNav" style={{backgroundColor: theme.colors.primary, borderColor: theme.colors.secondary}}> Jouer seul </button>
</Link>
<Link to="/">
<button className="ButtonNav" style={{backgroundColor: theme.colors.primary, borderColor: theme.colors.secondary}}> Créer une partie </button>
<button className="ButtonNav"> Jouer seul </button>
</Link>
<button onClick={createLobby} className="ButtonNav"> Créer une partie </button>
<Link to="/">
<button className="ButtonNav" style={{backgroundColor: theme.colors.primary, borderColor: theme.colors.secondary}}> Rejoindre </button>
</Link>

@ -0,0 +1,6 @@
import { io } from "socket.io-client";
const socket = io("http://localhost:3002");
export {socket}

@ -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]
}
}

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save