import * as React from 'react' import type { PJ } from '@lastres/pj' import type { Location } from '@lastres/location' import type { LogLine } from '@lastres/log-line' import type { ActionHash } from '@lastres/action' import type { TalkNPCs, TalkNPC } from '@lastres/talk-npc' import type { Words } from '@lastres/word' import UpperPanel from '@lastres/components/upper-panel' import BottomPanel from '@lastres/components/bottom-panel' import PJSelectionMenu from '@lastres/components/pj-selection-menu' import WordSelector from '@lastres/components/word-selector' import OutputPacketInit from '@lastres/output-packet/init' import OutputPacketPing from '@lastres/output-packet/ping' import InputPackets from '@lastres/input-packets' export type SetWebsocketCallback = (websocket: WebSocket | null) => WebSocket | null export interface GameProps { setSelectedPJ: (set: PJ | null) => void selectedPJ: PJ | null userWantsToCreatePJ: boolean setUserWantsToCreatePJ: (set: boolean) => void error: string | null setError: (set: string | null) => void websocket: WebSocket | null setWebsocket: (websocket: WebSocket | null | SetWebsocketCallback) => void } export enum StateGame { MainScreen, SelectingWord, } export default function Game (props: GameProps): JSX.Element { const selectedPJ = props.selectedPJ if (selectedPJ === null) { return ( <> ) } const [teamPJs, setTeamPJs] = React.useState(null) const [enemyTeamPJs, setEnemyTeamPJs] = React.useState(null) const [isBattling, setIsBattling] = React.useState(null) const [currentLocation, setCurrentLocation] = React.useState(null) const [connectedLocations, setConnectedLocations] = React.useState(null) const [logLines, setLogLines] = React.useState(null) const [error, setError] = React.useState(null) const [scrollLog, setScrollLog] = React.useState(null) const [movingTo, setMovingTo] = React.useState(null) const [remainingFrames, setRemainingFrames] = React.useState(null) const [actionHash, setActionHash] = React.useState(null) const [talkNPCs, setTalkNPCs] = React.useState(null) const [stateGame, setStateGame] = React.useState(StateGame.MainScreen) const [NPCToSayWord, setNPCToSayWord] = React.useState(null) const [words, setWords] = React.useState(null) const logPresentationRef = React.useRef(null) const websocket = props.websocket const setWebsocket = props.setWebsocket window.setTimeout(() => { setWebsocket((websocket): WebSocket | null => { if (websocket === null) { console.log('Opening websocket') const locationProtocol = window.location.protocol if (locationProtocol == null) { return null } const protocol = locationProtocol.match(/https:/) != null ? 'wss' : 'ws' const webSocket = new WebSocket(`${protocol}://${window.location.host}/ws`) webSocket.onopen = () => { new OutputPacketInit(selectedPJ.uuid).send(webSocket) let interval: number = 0 interval = window.setInterval(() => { if (webSocket.readyState === WebSocket.CONNECTING) { return } if (webSocket.readyState === WebSocket.OPEN) { new OutputPacketPing().send(webSocket) return } window.clearInterval(interval) }, 50000) } const inputPackets = new InputPackets(setTeamPJs, setEnemyTeamPJs, setIsBattling, setCurrentLocation, setConnectedLocations, logLines, setLogLines, setError, setScrollLog, logPresentationRef, setMovingTo, setRemainingFrames, setActionHash, setTalkNPCs, setWords) webSocket.onmessage = (event) => { const packet = JSON.parse(event.data) inputPackets.handle(packet) } webSocket.onerror = (event) => { console.log(event) } webSocket.onclose = (event) => { console.log('Websocket closed') setWebsocket(null) } return webSocket } return websocket }) }, 300) if (stateGame === StateGame.SelectingWord) { return ( ) } if (stateGame === StateGame.MainScreen) { return ( <> ) } return <> }