diff --git a/.drone.yml b/.drone.yml index 3f5a78c..deb7581 100644 --- a/.drone.yml +++ b/.drone.yml @@ -71,6 +71,7 @@ steps: when: branch: - CI/CD + - CI/CD #container deployment diff --git a/cryptide_project/package.json b/cryptide_project/package.json index 4bf2b23..810e10e 100644 --- a/cryptide_project/package.json +++ b/cryptide_project/package.json @@ -1,7 +1,6 @@ { "name": "cryptide", "version": "1.0.0", - "homepage": "/containers/Crypteam-website/", "dependencies": { "@fortawesome/fontawesome-svg-core": "^6.4.2", "@fortawesome/free-regular-svg-icons": "^6.4.2", diff --git a/cryptide_project/src/AdressSetup.ts b/cryptide_project/src/AdressSetup.ts index acf5b4f..5d94bdf 100644 --- a/cryptide_project/src/AdressSetup.ts +++ b/cryptide_project/src/AdressSetup.ts @@ -10,8 +10,6 @@ const ADRESSE_WEBSITE = "" const basePath = process.env.REACT_APP_BASEPATH || '/containers/Crypteam-website'; -console.log(basePath) - const tmp3 = basePath diff --git a/cryptide_project/src/App.tsx b/cryptide_project/src/App.tsx index 886c900..79c0c2f 100644 --- a/cryptide_project/src/App.tsx +++ b/cryptide_project/src/App.tsx @@ -37,6 +37,10 @@ import 'bootstrap/dist/css/bootstrap.min.css'; /* Internationnalisation */ import messagesFr from './Translations/fr.json'; import messagesEn from './Translations/en.json'; +import messagesEs from './Translations/es.json'; +import messagesPt from './Translations/pt.json'; +import messagesRu from './Translations/ru.json'; + /* Gestion d' erreur */ import ErrorBoundary from './Error/ErrorBoundary'; @@ -50,6 +54,9 @@ import Tutorial from './Pages/Tutorial'; const messages = { fr: messagesFr, en: messagesEn, + es: messagesEs, + pt: messagesPt, + ru: messagesRu, }; function App() { @@ -79,7 +86,7 @@ function App() { - {hasNavbarVisible && } + {hasNavbarVisible && } } /> diff --git a/cryptide_project/src/Components/GraphContainer.tsx b/cryptide_project/src/Components/GraphContainer.tsx index d090470..68e669f 100644 --- a/cryptide_project/src/Components/GraphContainer.tsx +++ b/cryptide_project/src/Components/GraphContainer.tsx @@ -21,6 +21,9 @@ import { json } from "body-parser"; import html2canvas from 'html2canvas'; import jsPDF from 'jspdf'; import {basePath} from "../AdressSetup" +import GameCreator from "../model/GameCreator"; +import Stub from "../model/Stub"; +import EnigmeDuJourCreator from "../model/EnigmeDuJourCreator"; import { io } from "socket.io-client"; import { ADRESSE_WEBSERVER } from "../AdressSetup"; @@ -35,7 +38,7 @@ interface MyGraphComponentProps { addToHistory: (message : string) => void solo : boolean isDaily : boolean - isEasy: boolean + difficulty: string setNetwork: (network: Network) => void showLast: boolean setNetworkEnigme: (networkEnigme: Map[]>) => void @@ -53,10 +56,13 @@ interface MyGraphComponentProps { putGreyBackground : () => void putCorrectBackground : () => void putImposssibleGrey : () => void + setChangeGraph : (func: (nbNodes: number, nbIndices: number) => void) => void handleTurn :() => void } +let askedWrongBot = false +let lastSocketId= "" let lastAskingPlayer = 0 let lastNodeId = -1 let first = true @@ -64,14 +70,10 @@ let askedWrongLocal = false let mapIndexPersons: Map = new Map() let touchedPlayer = -1 let botIndex = -1 -let askedWrongBot = false -let lastSocketId= "" let firstLap = true let cptHistory = 0 let lastNodes: NodePerson[] = [] let cptEndgame = 0 -let firstEnigme = true -let firstIndex = true let endgame= false let firstHistory = true let cptSquare = 0 @@ -79,26 +81,28 @@ let cptOnAskedWrong = 0 let cptPlayerLeft = 0 let firstPlayer = 0 let cptBug = 0 -let cptUseEffect = 0 let testPlayers: Player[] = [] let testTemps = 0 let testFirst = false +let gameStartTmp = true +let index = 0 - -const MyGraphComponent: React.FC = ({onNodeClick, handleShowTurnBar, handleTurnBarTextChange, playerTouched, setPlayerTouched, changecptTour, solo, isDaily, isEasy, addToHistory, showLast, setNetwork, setNetworkEnigme, setPlayerIndex, askedWrong, setAskedWrong, importToPdf, setImportToPdf, importToJSON, setImportToJSON, setPutCorrectBackground, setPutGreyBackground, setPutImposssibleGrey, putCorrectBackground, putGreyBackground, putImposssibleGrey, handleTurn}) => { - let cptTour: number = 0 +const MyGraphComponent: React.FC = ({onNodeClick, handleShowTurnBar, handleTurnBarTextChange, playerTouched, setPlayerTouched, changecptTour, solo, isDaily, difficulty, addToHistory, showLast, setNetwork, setNetworkEnigme, setPlayerIndex, askedWrong, setAskedWrong, importToPdf, setImportToPdf, importToJSON, setImportToJSON, setPutCorrectBackground, setPutGreyBackground, setPutImposssibleGrey, putCorrectBackground, putGreyBackground, putImposssibleGrey, handleTurn, setChangeGraph}) => { + let cptTour: number = 1 //* Gestion du temps : let initMtn = 0 const {isLoggedIn, user, manager} = useAuth(); - const { indices, indice, person, personNetwork, setNodeIdData, players, setPlayersData, askedPersons, setActualPlayerIndexData, room, actualPlayerIndex, turnPlayerIndex, setTurnPlayerIndexData, setWinnerData, dailyEnigme, setNbCoupData, settempsData, setNetworkDataData, setSeedData, nodesC, temps} = useGame(); + const { indices, indice, person, personNetwork, setNodeIdData, players, setPlayersData, askedPersons, setActualPlayerIndexData, room, actualPlayerIndex, turnPlayerIndex, setIndicesData, setWinnerData, dailyEnigme, setNbCoupData, settempsData, setNetworkDataData, setSeedData, nodesC, temps, setPersonData, setPersonNetworkData, setDailyEnigmeData, gameStart, setGameStartData} = useGame(); const params = new URLSearchParams(window.location.search); const navigate = useNavigate(); const [lastIndex, setLastIndex] = useState(-1) const [elapsedTime, setElapsedTime] = useState(0); + const [netEnigme, setNetEnigme] = useState[]> | null>(null) + const [downloaded, setDownloaded] = useState(false) useEffect(() => { if (testFirst){ @@ -109,13 +113,15 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS // Démarrez le timer au montage du composant const intervalId = setInterval(() => { setElapsedTime((prevElapsedTime) => prevElapsedTime + 0.5); - settempsData(elapsedTime) + settempsData(testTemps) testTemps += 0.5 - cptBug ++ - if (cptBug > 10){ - cptBug = 0 - socket.emit("who plays", room) + if (!solo){ + cptBug ++ + if (cptBug > 10){ + cptBug = 0 + socket.emit("who plays", room) + } } @@ -157,12 +163,10 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS useEffect(() => { testPlayers = players - console.log(testPlayers) }, [players]) useEffect(() =>{ touchedPlayer=playerTouched - console.log(playerTouched) if (touchedPlayer == -1){ if (!askedWrongLocal){ putCorrectBackground() @@ -201,17 +205,45 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS let playerIndex: number = turnPlayerIndex - if (firstIndex){ - firstIndex=false - setPlayerIndex(playerIndex) - } - let index = 0 - for (let i=0; i { + gameStartTmp=gameStart + if (gameStartTmp){ + setGameStartData(false) + console.log(gameStart) + setLastIndex(turnPlayerIndex) + setPlayerIndex(playerIndex) } - } + for (let i=0; i{ + if (p instanceof Bot && personNetwork!=null){ + p.index=index + p.initiateMap(personNetwork) + } + }) + } + setActualPlayerIndexData(index) + if (playerIndex == actualPlayerIndex){ + handleTurnBarTextChange("À vous de jouer") + handleShowTurnBar(true) + } + } + }, [gameStart]) + + + + useEffect(() =>{ //* Gestion du sound des tours : @@ -328,31 +360,6 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS } }, [lastIndex]) - - - if (first){ - first = false - endgame= false - if (!solo){ - for(let i = 0; i{ - if (p instanceof Bot && personNetwork!=null){ - p.index=index - p.initiateMap(personNetwork) - } - }) - } - setActualPlayerIndexData(index) - if (playerIndex == actualPlayerIndex){ - handleTurnBarTextChange("À vous de jouer") - handleShowTurnBar(true) - } - } - } - useEffect(() => { if (importToPdf){ setImportToPdf(false) @@ -367,7 +374,54 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS format: 'a4', // Format du papier (par exemple, a4) }); pdf.addImage(canvas.toDataURL('image/png'), 'PNG', 0, 0, pdf.internal.pageSize.getWidth(), pdf.internal.pageSize.getHeight()); + + if (isDaily){ + pdf.addPage(); + let text = "" + + if (difficulty === "easy"){ + indices.forEach((indice, index) => { + text += `Indice ${index + 1} : ${indice.ToString('fr')}.\n` + }) + } + else{ + const personIndice = new Map() + indices.forEach((i, index) => { + personIndice.set(index, []) + }) + + netEnigme?.forEach((pairs, index) => { + pairs.forEach((pair) => { + const person = personNetwork?.getPersons().find((n) => index == n.getId()) + const indice = indices.findIndex((i) => pair.first.getId() == i.getId()) + if (person != undefined && indice != -1){ + let string = "L'indice numéro " + (indice + 1) + " répond " + if (pair.second){ + string += "vrai " + } + else{ + string += "faux " + } + string += "pour " + person.getName() + personIndice.get(indice)?.push(string) + } + }) + }); + + personIndice.forEach((indices, index) => { + text += `Indice ${index + 1}:\n` + indices.forEach((string) => { + text += `${string}.\n` + }) + }) + } + pdf.text(text, 10, 10); + } + setDownloaded(true) pdf.save('graph.pdf'); + + + }); } }, [importToPdf]) @@ -391,10 +445,29 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS } }, [importToJSON]) + const changeGraph = (nbNodes: number, nbIndices: number) => { + //todo différencier les deux + const [networkPerson, choosenPerson, choosenIndices] = GameCreator.CreateGame(nbIndices, nbNodes) + setPersonData(choosenPerson) + setPersonNetworkData(networkPerson) + setIndicesData(choosenIndices) + const map = EnigmeDuJourCreator.createEnigme(networkPerson, choosenIndices, choosenPerson, Stub.GenerateIndice()) + setDailyEnigmeData(map) + addToHistory("<----- [Tour " + 1 +"/"+networkPerson.getPersons().length + "] ----->"); + changecptTour(1) + testTemps=0 + + + } + useEffect(() => { if (personNetwork == null){ return } + + if (solo){ + setChangeGraph(() => changeGraph) + } const graph = GraphCreator.CreateGraph(personNetwork) let n = graph.nodesPerson; @@ -449,7 +522,10 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS if (isDaily){ setNetworkEnigme(dailyEnigme) - if (!isEasy){ + setNetEnigme(dailyEnigme) + console.log(difficulty) + if (difficulty === "hard" || difficulty=== "intermediate"){ + console.log(dailyEnigme) dailyEnigme.forEach((pairs, index) => { pairs.forEach((pair) => { //@ts-ignore @@ -462,7 +538,7 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS }) }); } - else{ + else if (difficulty === "easy"){ if (firstHistory){ firstHistory=false indices.forEach((indice, index) => { @@ -600,7 +676,6 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS playerIndex = newPlayerIndex setPlayerIndex(playerIndex) setLastIndex(newPlayerIndex) - console.log(newPlayerIndex) //@ts-ignore if (mapIndexPersons.get(askedIndex)?.find((p) => p.getId() == id) == undefined){ //@ts-ignore @@ -754,7 +829,7 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS else { if (firstLap){ firstLap=false - if (!isDaily){ + if (solo && (difficulty === "intermediate" || !isDaily)){ addToHistory("<----- [Tour " + 1 +"/"+networkData.nodes.length + "] ----->"); } } @@ -1074,14 +1149,16 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS try{ console.log("time: " + testTemps) - if(user && isLoggedIn){ + if(user && isLoggedIn && !downloaded){ if(solo){ if(isDaily){ // TODO: verif difficulté et add les stats // TODO: verif pour facile et difficile, si réussi en one shot ou non - if(isEasy){ + if(difficulty==="easy"){ manager.userService.addEasyEnigmaStats(user.pseudo, 1, testTemps - 0.5); } + else if (difficulty === "intermediate"){ + } else{ manager.userService.addHardEnigmaStats(user.pseudo, 1, testTemps - 0.5); } @@ -1096,7 +1173,7 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS } else{ // add stats mastermind - if(user && user.mastermindStats){ + if(user && user.mastermindStats && !downloaded){ manager.userService.addMastermindStats(user.pseudo, cptTour, elapsedTime); } } @@ -1111,11 +1188,29 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS navigate(`${basePath}/endgame?solo=true&daily=${isDaily}`) } else{ - addToHistory(personTest.getName() + " n'est pas le coupable !"); //TODO préciser le nombre d'indice qu'il a de juste - cptTour ++; // On Incrémente le nombre de tour du joueur - const tour = cptTour+1; - addToHistory("<----- [Tour " + tour +"/"+networkData.nodes.length + "] ----->"); - changecptTour(cptTour); // On le transmet a la page précédente avec la fonction + if (isDaily){ + if (difficulty==="intermediate"){ + addToHistory(personTest.getName() + " n'est pas le coupable !"); //TODO préciser le nombre d'indice qu'il a de juste + cptTour ++; // On Incrémente le nombre de tour du joueur + addToHistory("<----- [Tour " + cptTour +"/"+networkData.nodes.length + "] ----->"); + changecptTour(cptTour); // On le transmet a la page précédente avec la fonction + } + else if (difficulty==="easy"){ + cptTour ++; // On Incrémente le nombre de tour du joueur + changecptTour(cptTour); // On le transmet a la page précédente avec la fonction + } + else{ + navigate(`${basePath}/endgame?solo=true&daily=true`) + setNetworkDataData(networkData) + setWinnerData(null) + } + } + else{ + addToHistory(personTest.getName() + " n'est pas le coupable !"); //TODO préciser le nombre d'indice qu'il a de juste + cptTour ++; // On Incrémente le nombre de tour du joueur + addToHistory("<----- [Tour " + cptTour +"/"+networkData.nodes.length + "] ----->"); + changecptTour(cptTour); // On le transmet a la page précédente avec la fonction + } } } } @@ -1127,7 +1222,7 @@ const MyGraphComponent: React.FC = ({onNodeClick, handleS setPlayerTouched(-1) } }); - }, []); // Le tableau vide signifie que cela ne s'exécutera qu'une fois après le premier rendu + }, [personNetwork]); // Le tableau vide signifie que cela ne s'exécutera qu'une fois après le premier rendu return ( <> diff --git a/cryptide_project/src/Components/LangDropDown.tsx b/cryptide_project/src/Components/LangDropDown.tsx index 56465e8..e12ecb7 100644 --- a/cryptide_project/src/Components/LangDropDown.tsx +++ b/cryptide_project/src/Components/LangDropDown.tsx @@ -3,11 +3,39 @@ import React from 'react'; import { NavDropdown } from 'react-bootstrap'; import LanguageNavItem from './LangNavItem'; import { HiLanguage } from 'react-icons/hi2'; +import ReactCountryFlag from 'react-country-flag'; + +//@ts-ignore +const localToCountryCode = (locale) => { + switch (locale) { + case 'fr': + return 'FR'; + case 'en': + return 'GB'; + case 'es': + return 'ES'; + case 'pt': + return 'PT'; + case 'ru': + return 'RU'; + default: + return 'FR'; + } +}; + // @ts-ignore -const LangDropdown = ({ changeLocale }) => { +const LangDropdown = ({ changeLocale, locale}) => { + const selectedcountryCode = localToCountryCode(locale); return ( - } id="language-dropdown" align='end' drop='down-centered'> + + } id="language-dropdown" align='end' drop='down-centered'> { languageKey="languageSelector.english" onClick={() => changeLocale('en')} /> - {/* Ajoutez d'autres langues selon vos besoins */} + changeLocale('es')} + /> + changeLocale('pt')} + /> + changeLocale('ru')} + /> ); }; diff --git a/cryptide_project/src/Components/NavBar.tsx b/cryptide_project/src/Components/NavBar.tsx index 548f34a..1aff0fe 100644 --- a/cryptide_project/src/Components/NavBar.tsx +++ b/cryptide_project/src/Components/NavBar.tsx @@ -1,7 +1,7 @@ import React, {useEffect, useState} from 'react'; /* Naviagtion */ -import { Navbar, Container, Nav, NavDropdown } from 'react-bootstrap'; +import { Navbar, Container, Nav, NavDropdown } from 'react-bootstrap'; /* Lang */ import { FormattedMessage } from 'react-intl'; @@ -31,7 +31,7 @@ import Player from '../model/Player'; import { set } from 'lodash'; // @ts-ignore -function AppNavbar({changeLocale}) { +function AppNavbar({changeLocale, locale}) { const theme = useTheme(); const navigate = useNavigate(); const {isLoggedIn, login, user, setUserData, manager } = useAuth(); @@ -93,6 +93,7 @@ function AppNavbar({changeLocale}) { + ); diff --git a/cryptide_project/src/Contexts/GameContext.tsx b/cryptide_project/src/Contexts/GameContext.tsx index 9910e73..3b88ded 100644 --- a/cryptide_project/src/Contexts/GameContext.tsx +++ b/cryptide_project/src/Contexts/GameContext.tsx @@ -26,6 +26,8 @@ interface GameContextProps { networkData: any seed: number | string; nodesC: NodePerson[] + gameStart: boolean + setGameStartData : (newStart: boolean) => void setIndicesData: (newIndices: Indice[]) => void; setIndiceData: (newIndice: Indice) => void; setPersonData: (newPerson: Person) => void; @@ -37,7 +39,7 @@ interface GameContextProps { setTurnPlayerIndexData: (newTurnPlayerIndex: number) => void; setRoomData: (newRoom: string) => void; setOnlyFalseData: (newOnlyFalse: boolean) => void - setWinnerData: (winner: Player) => void + setWinnerData: (winner: Player | null) => void reset: () => void setDailyEnigmeData: (map: Map[]>) => void setNbCoupData: (newNbCoup : number) => void @@ -72,8 +74,13 @@ export const GameProvider: React.FC = ({ children }) => { const [networkData, setNetworkData] = useState(null); const [seed, setSeed] = useState(0); const [nodesC, setNodes] = useState([]); + const [gameStart, setGameStart] = useState(true) + const setGameStartData = (newStart: boolean) => { + setGameStart(newStart) + } + const setNodesData = (nodes: NodePerson[]) => { setNodes(nodes) } @@ -131,7 +138,7 @@ export const GameProvider: React.FC = ({ children }) => { setOnlyFalse(newOnlyFalse) } - const setWinnerData = (winner: Player) =>{ + const setWinnerData = (winner: Player | null) =>{ setWinner(winner) } @@ -165,7 +172,7 @@ export const GameProvider: React.FC = ({ children }) => { } return ( - + {children} ); diff --git a/cryptide_project/src/Pages/InGame.tsx b/cryptide_project/src/Pages/InGame.tsx index 4a0d8d2..bf382d9 100644 --- a/cryptide_project/src/Pages/InGame.tsx +++ b/cryptide_project/src/Pages/InGame.tsx @@ -92,11 +92,12 @@ const InGame = ({locale, changeLocale}) => { } - let isEasy: boolean = true - const isEasytmp = params.get('easy'); - if (isEasytmp == "false"){ - isEasy=false + let difficulty: string = ""; + let difficultyTmp = params.get('difficulty') + if (difficultyTmp !== null){ + difficulty=difficultyTmp } + //* Historique const [history, setHistory] = useState([]); const [showLast, setShowLast] = useState(false) @@ -107,6 +108,8 @@ const InGame = ({locale, changeLocale}) => { const [putCorrectBackground, setPutCorrectBackground] = useState<() => void>(() => {}); const [putGreyBackgroud, setPutGreyBackground] = useState<() => void>(() => {}); const [putImposssibleGrey, setPutImposssibleGrey] = useState<() => void>(() => {}); + const [changeGraph, setChangeGraph] = useState<(nbNodes: number, nbIndices: number) => void>(() => {}); + const setPutCorrectBackgroundData = (func: () => void) => { @@ -121,6 +124,10 @@ const InGame = ({locale, changeLocale}) => { setPutImposssibleGrey(func) } + const setChangeGraphData = (func: (nbNodes: number, nbIndices: number) => void) => { + setChangeGraph(func) + } + const setImportToJSONData = (imp: boolean) => { setImportToJSON(imp) } @@ -255,7 +262,7 @@ const InGame = ({locale, changeLocale}) => { const handleCloseS = () => setShowS(false); const handleShowS = () => setShowS(true); - const [cptTour, setcptTour] = useState(0); + const [cptTour, setcptTour] = useState(1); const [LastVisible, setLastVisible] = useState(false); @@ -317,6 +324,22 @@ const InGame = ({locale, changeLocale}) => { const [playTurnSound, setPlayTurnSound] = useState(false); const [soundPreference, setSoundPreference] = useState(true); // utilisateur + const [enteredNumber, setEnteredNumber] = useState(25); + const [enteredNumberIndices, setEnteredNumberIndices] = useState(3); + + + //@ts-ignore + const handleNumberChange = (event) => { + const newNumber = Math.max(20, Math.min(50, parseInt(event.target.value, 10))); + setEnteredNumber(newNumber); + }; + + //@ts-ignore + const handleNumberIndicesChange = (event) => { + const newNumber = Math.max(3, Math.min(6, parseInt(event.target.value, 10))); + setEnteredNumberIndices(newNumber); +}; + const handleSoundPreferenceChange = () => { setSoundPreference(!soundPreference); console.log("changement des options du son : "+ soundPreference) @@ -346,7 +369,7 @@ const InGame = ({locale, changeLocale}) => { addToHistory={addToHistory} solo={IsSolo} isDaily={isDaily} - isEasy={isEasy} + difficulty={difficulty} setPlayerTouched={handleSetPlayerTouched} playerTouched={playerTouched} setNetwork={setNetworkData} @@ -365,12 +388,13 @@ const InGame = ({locale, changeLocale}) => { putCorrectBackground={putCorrectBackground} putGreyBackground={putGreyBackgroud} putImposssibleGrey={putImposssibleGrey} - handleTurn={handleTurn}/> + handleTurn={handleTurn} + setChangeGraph={setChangeGraphData}/> {playTurnSound &&