Reformat
This commit is contained in:
parent
1f19022d45
commit
742bd4f106
|
@ -27,9 +27,7 @@
|
||||||
<input type="text" id="game-link" size="50" readonly />
|
<input type="text" id="game-link" size="50" readonly />
|
||||||
<button onclick="copyGameLink()">Copy</button>
|
<button onclick="copyGameLink()">Copy</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="ws-status" style="margin-top: 10px; color: grey">
|
<div id="ws-status" style="margin-top: 10px; color: grey">Disconnected</div>
|
||||||
Disconnected
|
|
||||||
</div>
|
|
||||||
<script src="scripts/display-ws-connection.js"></script>
|
<script src="scripts/display-ws-connection.js"></script>
|
||||||
<script src="scripts/send-ws-messages.js"></script>
|
<script src="scripts/send-ws-messages.js"></script>
|
||||||
<script src="scripts/copy-game-link.js"></script>
|
<script src="scripts/copy-game-link.js"></script>
|
||||||
|
|
|
@ -22,12 +22,10 @@ htmx.trigger(gameContainer, ' and connect');
|
||||||
// Update the game link input
|
// Update the game link input
|
||||||
const gameLinkInput = document.getElementById('game-link');
|
const gameLinkInput = document.getElementById('game-link');
|
||||||
if (!gameLinkInput) {
|
if (!gameLinkInput) {
|
||||||
console.error('Missing game-link element.')
|
console.error('Missing game-link element.');
|
||||||
}
|
}
|
||||||
gameLinkInput.value =
|
gameLinkInput.value =
|
||||||
window.location.origin +
|
window.location.origin + window.location.pathname + `?gameId=${gameId}`;
|
||||||
window.location.pathname +
|
|
||||||
`?gameId=${gameId}`;
|
|
||||||
|
|
||||||
// Update the WebSocket status indicator
|
// Update the WebSocket status indicator
|
||||||
const wsStatusDiv = document.getElementById('ws-status');
|
const wsStatusDiv = document.getElementById('ws-status');
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
document.addEventListener('htmx:wsConfigSend', function(e) {
|
document.addEventListener('htmx:wsConfigSend', function (e) {
|
||||||
if (e.target.classList.contains('board-cell')) {
|
if (e.target.classList.contains('board-cell')) {
|
||||||
const row = parseInt(e.target.dataset.row);
|
const row = parseInt(e.target.dataset.row);
|
||||||
const col = parseInt(e.target.dataset.col);
|
const col = parseInt(e.target.dataset.col);
|
||||||
|
|
||||||
// Set the custom JSON data
|
// Set the custom JSON data
|
||||||
e.detail.parameters = {
|
e.detail.parameters = {
|
||||||
type: "make_move",
|
type: 'make_move',
|
||||||
row: row,
|
row: row,
|
||||||
col: col
|
col: col,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
|
@ -12,7 +12,7 @@ interface MakeMoveMessage {
|
||||||
col: number;
|
col: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
type WS = ElysiaWS<{query: {playerId: string, gameId: string}}>;
|
type WS = ElysiaWS<{ query: { playerId: string; gameId: string } }>;
|
||||||
export class WebSocketHandler {
|
export class WebSocketHandler {
|
||||||
private connections: Map<string, Array<WS>>;
|
private connections: Map<string, Array<WS>>;
|
||||||
private games: Map<string, GameInstance>;
|
private games: Map<string, GameInstance>;
|
||||||
|
@ -23,7 +23,7 @@ export class WebSocketHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
public handleConnection(ws: WS): void {
|
public handleConnection(ws: WS): void {
|
||||||
const {gameId, playerId} = ws.data.query;
|
const { gameId, playerId } = ws.data.query;
|
||||||
|
|
||||||
if (!this.connections.has(gameId)) {
|
if (!this.connections.has(gameId)) {
|
||||||
this.connections.set(gameId, []);
|
this.connections.set(gameId, []);
|
||||||
|
@ -53,14 +53,13 @@ export class WebSocketHandler {
|
||||||
|
|
||||||
private handleMakeMove(ws: WS, message: MakeMoveMessage): void {
|
private handleMakeMove(ws: WS, message: MakeMoveMessage): void {
|
||||||
const { row, col } = message;
|
const { row, col } = message;
|
||||||
const {gameId, playerId} = ws.data.query;
|
const { gameId, playerId } = ws.data.query;
|
||||||
console.log(`Handling make_move message in game ${gameId} from player ${playerId}: ${{message}}`);
|
console.log(
|
||||||
|
`Handling make_move message in game ${gameId} from player ${playerId}: ${{ message }}`,
|
||||||
|
);
|
||||||
|
|
||||||
if (!gameId || !playerId || row === undefined || col === undefined) {
|
if (!gameId || !playerId || row === undefined || col === undefined) {
|
||||||
this.sendMessage(
|
this.sendMessage(ws, 'Error: missing gameId, playerId, row, or col');
|
||||||
ws,
|
|
||||||
'Error: missing gameId, playerId, row, or col',
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,10 +73,7 @@ export class WebSocketHandler {
|
||||||
([_, id]) => id === playerId,
|
([_, id]) => id === playerId,
|
||||||
)?.[0] as ('black' | 'white') | undefined;
|
)?.[0] as ('black' | 'white') | undefined;
|
||||||
if (!playerColor) {
|
if (!playerColor) {
|
||||||
this.sendMessage(
|
this.sendMessage(ws, 'Error: you are not a player in this game');
|
||||||
ws,
|
|
||||||
'Error: you are not a player in this game',
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,11 +98,13 @@ export class WebSocketHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
public handleDisconnect(ws: WS): void {
|
public handleDisconnect(ws: WS): void {
|
||||||
const {gameId, playerId} = ws.data.query;
|
const { gameId, playerId } = ws.data.query;
|
||||||
|
|
||||||
const connectionsInGame = this.connections.get(gameId);
|
const connectionsInGame = this.connections.get(gameId);
|
||||||
if (!connectionsInGame) {
|
if (!connectionsInGame) {
|
||||||
console.error(`Disconnecting WebSocket for player ${playerId} from game ${gameId}, but that game has no connections!`);
|
console.error(
|
||||||
|
`Disconnecting WebSocket for player ${playerId} from game ${gameId}, but that game has no connections!`,
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.connections.set(
|
this.connections.set(
|
||||||
|
@ -127,28 +125,30 @@ export class WebSocketHandler {
|
||||||
public broadcastGameState(gameId: string): void {
|
public broadcastGameState(gameId: string): void {
|
||||||
const game = this.games.get(gameId);
|
const game = this.games.get(gameId);
|
||||||
if (!game) {
|
if (!game) {
|
||||||
console.warn('Attempted to broadcast state of game ${gameId}, which is not loaded.');
|
console.warn(
|
||||||
|
'Attempted to broadcast state of game ${gameId}, which is not loaded.',
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const connectionsToUpdate = this.connections.get(gameId);
|
const connectionsToUpdate = this.connections.get(gameId);
|
||||||
if (connectionsToUpdate) {
|
if (connectionsToUpdate) {
|
||||||
connectionsToUpdate.forEach((ws) => {
|
connectionsToUpdate.forEach((ws) => {
|
||||||
const {gameId, playerId} = ws.data.query;
|
const { gameId, playerId } = ws.data.query;
|
||||||
|
|
||||||
const updatedBoardHtml = renderGameBoardHtml(game, playerId);
|
const updatedBoardHtml = renderGameBoardHtml(game, playerId);
|
||||||
ws.send(updatedBoardHtml);
|
ws.send(updatedBoardHtml);
|
||||||
const updatedPlayerInfoHtml = renderPlayerInfoHtml(
|
const updatedPlayerInfoHtml = renderPlayerInfoHtml(game.id, playerId);
|
||||||
game.id,
|
|
||||||
playerId,
|
|
||||||
);
|
|
||||||
ws.send(updatedPlayerInfoHtml);
|
ws.send(updatedPlayerInfoHtml);
|
||||||
|
|
||||||
if (game.status === 'finished') {
|
if (game.status === 'finished') {
|
||||||
if (game.winner === 'draw') {
|
if (game.winner === 'draw') {
|
||||||
this.sendMessageToGame(gameId, 'Game ended in draw.');
|
this.sendMessageToGame(gameId, 'Game ended in draw.');
|
||||||
} else if (game.winner) {
|
} else if (game.winner) {
|
||||||
this.sendMessageToGame(gameId, `${game.winner.toUpperCase()} wins!`);
|
this.sendMessageToGame(
|
||||||
|
gameId,
|
||||||
|
`${game.winner.toUpperCase()} wins!`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else if (game.status === 'playing') {
|
} else if (game.status === 'playing') {
|
||||||
const clientPlayerColor = Object.entries(game.players).find(
|
const clientPlayerColor = Object.entries(game.players).find(
|
||||||
|
@ -168,27 +168,21 @@ export class WebSocketHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public sendMessageToGame(
|
public sendMessageToGame(gameId: string, message: string): void {
|
||||||
gameId: string,
|
|
||||||
message: string,
|
|
||||||
): void {
|
|
||||||
const connections = this.connections.get(gameId);
|
const connections = this.connections.get(gameId);
|
||||||
if (connections) {
|
if (connections) {
|
||||||
connections.forEach((ws) => {
|
connections.forEach((ws) => {
|
||||||
ws.send('<div id="messages">' + message + '</div>')
|
ws.send('<div id="messages">' + message + '</div>');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public sendMessage(
|
public sendMessage(targetWs: WS, message: string): void {
|
||||||
targetWs: WS,
|
targetWs.send('<div id="messages">' + message + '</div>');
|
||||||
message: string,
|
|
||||||
): void {
|
|
||||||
targetWs.send('<div id="messages">' + message + '</div>')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public getGame(gameId: string): GameInstance | undefined {
|
public getGame(gameId: string): GameInstance | undefined {
|
||||||
return this.games.get(gameId)
|
return this.games.get(gameId);
|
||||||
}
|
}
|
||||||
|
|
||||||
createGame(gameId?: string): GameInstance {
|
createGame(gameId?: string): GameInstance {
|
||||||
|
|
|
@ -12,9 +12,8 @@ export function renderGameBoardHtml(
|
||||||
let boardHtml = '<div id="game-board" class="game-board-grid">';
|
let boardHtml = '<div id="game-board" class="game-board-grid">';
|
||||||
|
|
||||||
const currentPlayerColor =
|
const currentPlayerColor =
|
||||||
Object.entries(gameState.players).find(
|
Object.entries(gameState.players).find(([_, id]) => id === playerId)?.[0] ||
|
||||||
([_, id]) => id === playerId,
|
null;
|
||||||
)?.[0] || null;
|
|
||||||
const isPlayersTurn =
|
const isPlayersTurn =
|
||||||
gameState.status === 'playing' &&
|
gameState.status === 'playing' &&
|
||||||
gameState.currentPlayer === currentPlayerColor;
|
gameState.currentPlayer === currentPlayerColor;
|
||||||
|
@ -30,9 +29,7 @@ export function renderGameBoardHtml(
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTMX attributes for making a move
|
// HTMX attributes for making a move
|
||||||
const wsAttrs = isPlayersTurn && !stone
|
const wsAttrs = isPlayersTurn && !stone ? `ws-send="click"` : '';
|
||||||
? `ws-send="click"`
|
|
||||||
: '';
|
|
||||||
|
|
||||||
boardHtml += `
|
boardHtml += `
|
||||||
<div
|
<div
|
||||||
|
|
Loading…
Reference in New Issue