You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
3.0 KiB
108 lines
3.0 KiB
import { WebSocket } from 'ws';
|
|
import {
|
|
ConnectedSocket,
|
|
MessageBody,
|
|
OnGatewayConnection,
|
|
OnGatewayDisconnect,
|
|
SubscribeMessage,
|
|
WebSocketGateway
|
|
} from '@nestjs/websockets';
|
|
import { randomUUID } from 'crypto';
|
|
import { Pong } from './pong';
|
|
import { formatWebsocketData, Point } from './game/utils';
|
|
import { GAME_EVENTS } from './game/constants';
|
|
import { PlayerNamesDto } from './dtos/PlayerNamesDto';
|
|
import { UsePipes, ValidationPipe } from '@nestjs/common';
|
|
|
|
interface WebSocketWithId extends WebSocket {
|
|
id: string;
|
|
}
|
|
|
|
@WebSocketGateway()
|
|
export class PongGateway implements OnGatewayConnection, OnGatewayDisconnect {
|
|
private pong: Pong = new Pong();
|
|
private socketToPlayerName: Map<WebSocketWithId, string> = new Map();
|
|
|
|
handleConnection(client: WebSocketWithId) {
|
|
const uuid = randomUUID();
|
|
client.id = uuid;
|
|
}
|
|
|
|
handleDisconnect(
|
|
@ConnectedSocket()
|
|
client: WebSocketWithId
|
|
) {
|
|
if (this.pong.isInAGame(client.id)) {
|
|
console.log(`Disconnected ${this.socketToPlayerName.get(client)}`);
|
|
if (this.pong.playerGame(client.id).isPlaying()) {
|
|
this.pong.playerGame(client.id).stop();
|
|
}
|
|
this.socketToPlayerName.delete(client);
|
|
}
|
|
}
|
|
|
|
@SubscribeMessage(GAME_EVENTS.REGISTER_PLAYER)
|
|
registerPlayer(
|
|
@ConnectedSocket()
|
|
client: WebSocketWithId,
|
|
@MessageBody('playerName') playerName: string
|
|
) {
|
|
this.socketToPlayerName.set(client, playerName);
|
|
console.log(`Connected ${this.socketToPlayerName.get(client)}`);
|
|
}
|
|
|
|
@SubscribeMessage(GAME_EVENTS.GET_GAME_INFO)
|
|
getPlayerCount(@ConnectedSocket() client: WebSocketWithId) {
|
|
client.send(formatWebsocketData(GAME_EVENTS.GET_GAME_INFO, this.pong.getGameInfo(client.id)));
|
|
}
|
|
|
|
@SubscribeMessage(GAME_EVENTS.PLAYER_MOVE)
|
|
movePlayer(
|
|
@ConnectedSocket()
|
|
client: WebSocketWithId,
|
|
@MessageBody('position') position: Point
|
|
) {
|
|
this.pong.movePlayer(client.id, position);
|
|
}
|
|
|
|
@UsePipes(new ValidationPipe({ whitelist: true }))
|
|
@SubscribeMessage(GAME_EVENTS.CREATE_GAME)
|
|
createGame(
|
|
@ConnectedSocket()
|
|
client: WebSocketWithId,
|
|
@MessageBody() playerNames: PlayerNamesDto
|
|
) {
|
|
console.log(playerNames);
|
|
const allPlayerNames: Array<string> = Array.from(this.socketToPlayerName.values());
|
|
if (allPlayerNames && allPlayerNames.length >= 2) {
|
|
const player1Socket: WebSocketWithId = Array.from(this.socketToPlayerName.keys()).find(
|
|
(key) => this.socketToPlayerName.get(key) === playerNames[0]
|
|
);
|
|
const player2Socket: WebSocketWithId = Array.from(this.socketToPlayerName.keys()).find(
|
|
(key) => this.socketToPlayerName.get(key) === playerNames[1]
|
|
);
|
|
|
|
if (
|
|
player1Socket &&
|
|
player2Socket &&
|
|
(client.id === player1Socket.id || client.id === player2Socket.id) &&
|
|
player1Socket.id !== player2Socket.id
|
|
) {
|
|
this.pong.newGame(
|
|
[player1Socket, player2Socket],
|
|
[player1Socket.id, player2Socket.id],
|
|
playerNames.playerNames
|
|
);
|
|
}
|
|
}
|
|
return { event: GAME_EVENTS.CREATE_GAME };
|
|
}
|
|
|
|
@SubscribeMessage(GAME_EVENTS.READY)
|
|
ready(
|
|
@ConnectedSocket()
|
|
client: WebSocketWithId
|
|
) {
|
|
this.pong.ready(client.id);
|
|
}
|
|
}
|
|
|