diff --git a/src/client/editor/editor.tsx b/src/client/editor/editor.tsx index fc9b2052..1bf63b4c 100644 --- a/src/client/editor/editor.tsx +++ b/src/client/editor/editor.tsx @@ -275,7 +275,7 @@ export function Editor() { startIdx, endIdx + 1, ); - console.log(selectedEvents); + // console.log(selectedEvents); await navigator.clipboard.writeText( JSON.stringify(selectedEvents), diff --git a/src/client/puzzle/setup-puzzle.tsx b/src/client/puzzle/setup-puzzle.tsx index 8355dbb4..d84c7da9 100644 --- a/src/client/puzzle/setup-puzzle.tsx +++ b/src/client/puzzle/setup-puzzle.tsx @@ -1,5 +1,4 @@ import { useState } from "react"; -import { SetupBase } from "../setup/setup-base"; import { SelectPuzzle } from "./select-puzzle"; import { NonIdealState, Spinner } from "@blueprintjs/core"; import { get, useEffectQuery } from "../api"; @@ -29,12 +28,10 @@ export function SetupPuzzle() { } return ( - - - + ); } diff --git a/src/server/api/api.ts b/src/server/api/api.ts index 2ae01704..82096c1a 100644 --- a/src/server/api/api.ts +++ b/src/server/api/api.ts @@ -117,8 +117,8 @@ let canReloadQueue = true; export const websocketHandler: WebsocketRequestHandler = (ws, req) => { // on close, delete the cookie id ws.on("close", () => { - console.log("We closed the connection"); - socketManager.handleSocketClosed(req.cookies.id); + console.log(`We closed the connection of ${req.cookies.id}`); + socketManager.handleSocketClosed(req.cookies.id, ws); //if you reload and the game is over if (gameManager?.isGameEnded() && canReloadQueue) { @@ -172,7 +172,7 @@ export const websocketHandler: WebsocketRequestHandler = (ws, req) => { //wait in case the client is just reloading or disconnected instead of leaving setTimeout(() => { - if (socketManager.getSocket(req.cookies.id) === undefined) { + if (socketManager.getSockets(req.cookies.id) === undefined) { //remove the person from the queue to free up space queue.popInd(queue.find(req.cookies.id)); names.delete(req.cookies.id); @@ -228,16 +228,14 @@ export const websocketHandler: WebsocketRequestHandler = (ws, req) => { const message = parseMessage(data.toString()); console.log("Received message: " + message.toJson()); + // take out that page value, add a delimeter + // // add current page to the cookie id + // const finalSocketId = pageValue.concat(req.cookies.id); + if (message instanceof RegisterWebsocketMessage) { - console.log(`Register a new socket with request ${req.url}`); - //find in the url where we specify the page - const cutoffIndex = req.url.indexOf("page=") + 5; - // take out that page value, add a delimeter - const pageValue = req.url.substring(cutoffIndex) + "|o|o|"; - // add current page to the cookie id - const finalSocketId = pageValue.concat(req.cookies.id); - - socketManager.registerSocket(finalSocketId, ws); + console.log(`Register a new socket with request ${req.cookies.id}`); + + socketManager.registerSocket(req.cookies.id, ws); } else if ( message instanceof GameInterruptedMessage || message instanceof MoveMessage || @@ -246,7 +244,6 @@ export const websocketHandler: WebsocketRequestHandler = (ws, req) => { message instanceof GameFinishedMessage || message instanceof GameEndMessage ) { - // TODO: Handle game manager not existing await gameManager?.handleMessage(message, req.cookies.id); } else if (message instanceof DriveRobotMessage) { await doDriveRobot(message); @@ -373,6 +370,7 @@ apiRouter.get("/game-state", (req, res) => { * returns a success message */ apiRouter.post("/start-computer-game", async (req, res) => { + console.log("start comp game"); canReloadQueue = true; const side = req.query.side as Side; const difficulty = parseInt(req.query.difficulty as string) as Difficulty; diff --git a/src/server/api/client-manager.ts b/src/server/api/client-manager.ts index b0892446..89416bb4 100644 --- a/src/server/api/client-manager.ts +++ b/src/server/api/client-manager.ts @@ -20,9 +20,9 @@ export class ClientManager { * get the host's socket * @returns the host socket */ - public getHostSocket(): WebSocket | undefined { + public getHostSocket(): Set | undefined { if (this.hostId !== undefined) { - return this.socketManager.getSocket(this.hostId); + return this.socketManager.getSockets(this.hostId); } return undefined; } @@ -33,11 +33,11 @@ export class ClientManager { * @returns if the socket was found */ public sendToHost(message: Message): boolean { - const socket = this.getHostSocket(); - if (socket !== undefined) { - socket.send(message.toJson()); + const sockets = this.getHostSocket(); + if (sockets !== undefined) { + for (const socket of sockets) socket.send(message.toJson()); } - return socket !== undefined; + return sockets !== undefined; } /** @@ -46,11 +46,11 @@ export class ClientManager { * @returns if the socket was found */ public sendToClient(message: Message): boolean { - const socket = this.getClientSocket(); - if (socket !== undefined) { - socket.send(message.toJson()); + const sockets = this.getClientSocket(); + if (sockets !== undefined) { + for (const socket of sockets) socket.send(message.toJson()); } - return socket !== undefined; + return sockets !== undefined; } /** @@ -61,8 +61,12 @@ export class ClientManager { public sendToSpectators(message: Message): boolean { if (this.spectatorIds.size !== 0) { for (const item of this.spectatorIds) { - if (this.socketManager.getSocket(item)) - this.socketManager.getSocket(item).send(message.toJson()); + const potentialSocket = this.socketManager.getSockets(item); + if (potentialSocket !== null && potentialSocket !== undefined) { + for (const socket of potentialSocket) { + socket.send(message.toJson()); + } + } } return true; } @@ -73,9 +77,9 @@ export class ClientManager { * get the client socket * @returns the socket of the client */ - public getClientSocket(): WebSocket | undefined { + public getClientSocket(): Set | undefined { if (this.clientId !== undefined) { - return this.socketManager.getSocket(this.clientId); + return this.socketManager.getSockets(this.clientId); } return undefined; } diff --git a/src/server/api/game-manager.ts b/src/server/api/game-manager.ts index 084744a3..e72fb2f4 100644 --- a/src/server/api/game-manager.ts +++ b/src/server/api/game-manager.ts @@ -119,6 +119,8 @@ export class HumanGameManager extends GameManager { * @param id - id of the sender */ public async handleMessage(message: Message, id: string): Promise { + // console.log("handling message"); + // check which type the id is const clientType = this.clientManager.getClientType(id); let sendToPlayer: SendMessage; @@ -148,6 +150,7 @@ export class HumanGameManager extends GameManager { const ids = this.clientManager.getIds(); const currentSave = SaveManager.loadGame(id); // update the internal chess object if it is a move massage and game not paused + console.log("up to here"); if (message instanceof MoveMessage && !gamePaused) { // Call path materializer and send to bots const command = materializePath(message.move); @@ -155,7 +158,7 @@ export class HumanGameManager extends GameManager { this.chess.makeMove(message.move); console.log("running executor"); - console.dir(command, { depth: null }); + // console.dir(command, { depth: null }); await executor.execute(command).catch((reason) => { setPaused(true); console.log(reason); diff --git a/src/server/api/socket-manager.ts b/src/server/api/socket-manager.ts index 8f259766..302c6582 100644 --- a/src/server/api/socket-manager.ts +++ b/src/server/api/socket-manager.ts @@ -5,27 +5,36 @@ import type { Message } from "../../common/message/message"; * A class which maps player client ids to their corresponding websocket (if any). */ export class SocketManager { - constructor(private sockets: Record) {} + constructor(private sockets: Record>) {} public registerSocket(id: string, socket: WebSocket): void { + if (this.sockets[id] === null || this.sockets[id] === undefined) { + this.sockets[id] = new Set(); + } console.log(`Id is: ${id}`); - this.sockets[id] = socket; + this.sockets[id].add(socket); } /** * deletes the socket at the provided id * @param id - id to be deleted */ - public handleSocketClosed(id: string): void { - delete this.sockets[id]; + public handleSocketClosed(id: string, socket: WebSocket): void { + // find if the socket exists and is in the set for that user + if (this.sockets[id] && this.sockets[id].has(socket)) { + // if so, KILL IT! + this.sockets[id].delete(socket); + return; + } } /** - * gets the socket at the provided id + * gets the socket at the provided id, which may be multiple if they have multiple tabs open * @param id - id of the desired socket */ - public getSocket(id: string): WebSocket { - return this.sockets[id]; + public getSockets(id: string): Set | undefined { + if (this.sockets[id]) return this.sockets[id]; + return undefined; } /** @@ -33,9 +42,9 @@ export class SocketManager { * Returns true if the message was sent successfully, and false otherwise. */ public sendToSocket(id: string, message: Message): boolean { - const socket = this.getSocket(id); - if (socket !== undefined) { - socket.send(message.toJson()); + const sockets = this.getSockets(id); + if (sockets !== undefined) { + for (const socket of sockets) socket.send(message.toJson()); return true; } return false; @@ -49,8 +58,10 @@ export class SocketManager { public sendToAll(message: Message): boolean { const sockets = Object.values(this.sockets); console.log(`Current list of connections are: ${sockets.length}`); - for (const socket of sockets) { - socket.send(message.toJson()); + for (const socketSet of sockets) { + for (const socket of socketSet) { + socket.send(message.toJson()); + } } return true; } diff --git a/src/server/robot/path-materializer.ts b/src/server/robot/path-materializer.ts index f533363d..189d7ff5 100644 --- a/src/server/robot/path-materializer.ts +++ b/src/server/robot/path-materializer.ts @@ -243,7 +243,7 @@ function findShimmyLocation( collisionType: CollisionType, ): Position { const shimmyPos: Position = robotManager.getRobot(pieceId).position; - const axisShimmyAmount: number = 1 / 3; + const axisShimmyAmount: number = 1 / 2; switch (collisionType) { // Horizontal case CollisionType.HORIZONTAL: { @@ -490,6 +490,8 @@ function moveToDeadZone(origin: GridIndices): GridMove { ]; collisionTuple.sort((a, b) => a[1].length - b[1].length); + console.log("Collision decision:"); + console.log(collisionTuple[0]); return collisionTuple[0][0]; } @@ -522,7 +524,7 @@ function returnToHome(from: GridIndices, id: string): SequentialCommandGroup { //const capturedPiece: GridIndices = GridIndices.squareToGrid(from); const home: GridIndices = robotManager.getRobot(id).homeIndices; const fastestMoveToDeadzone = moveToDeadZone(from); - const toDeadzone = moveMainPiece(fastestMoveToDeadzone, true); + const toDeadzone = moveMainPiece(fastestMoveToDeadzone); const startInDeadzone = fastestMoveToDeadzone.to; let finalDestination: GridIndices | undefined; @@ -1168,11 +1170,13 @@ export function materializePath(move: Move): Command { rookPiece.id, Position.fromGridIndices(new GridIndices(7, 2)), ); - } else { + } + // black side castling + else { rookPiece = robotManager.getRobotAtIndices(new GridIndices(9, 9)); kingMove = new AbsoluteMoveCommand( robotManager.getRobotAtIndices(moveToGridMove(move).from).id, - Position.fromGridIndices(new GridIndices(9, 8)), + Position.fromGridIndices(new GridIndices(8, 9)), ); rookMove1 = new AbsoluteMoveCommand( rookPiece.id,