avatar display on game pages

+ multiples user.status bug unresolved, temp rollback in generateToken()
+ STATUS enum fix game.service.ts
+ multiples smalls refactoring
This commit is contained in:
LuckyLaszlo
2023-01-11 12:00:03 +01:00
parent 0f60b83121
commit de26c3c89c
10 changed files with 191 additions and 73 deletions

View File

@@ -94,10 +94,15 @@ async function clientAnnounceListener(this: WebSocket, data: string)
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
body: JSON.stringify(body) body: JSON.stringify(body)
}); })
if (!response.ok) .catch(error => console.log("ERROR : " + error));
if (!response || !response.ok)
{ {
this.send(JSON.stringify( new ev.EventError((await response.json()).message) )); let errMessage = "validate token error";
if (response) {
errMessage = (await response.json()).message;
}
this.send(JSON.stringify( new ev.EventError(errMessage) ));
clientTerminate(clientsMap.get(this.id)); clientTerminate(clientsMap.get(this.id));
return; return;
} }
@@ -154,6 +159,8 @@ function publicMatchmaking(player: ClientPlayer)
const compatiblePlayers: ClientPlayer[] = []; const compatiblePlayers: ClientPlayer[] = [];
compatiblePlayers.push(player); compatiblePlayers.push(player);
/* // Replace with this code to enable the possibility to play against self
for (const [id, client] of matchmakingMap) for (const [id, client] of matchmakingMap)
{ {
if (client.matchOptions === matchOptions) if (client.matchOptions === matchOptions)
@@ -163,10 +170,9 @@ function publicMatchmaking(player: ClientPlayer)
break; break;
} }
} }
} } */
// TODO: Replace with this code to disable the possibility to play against self for (const [id, client] of matchmakingMap)
/* for (const [id, client] of matchmakingMap)
{ {
if (client.matchOptions === matchOptions && client.username !== player.username) if (client.matchOptions === matchOptions && client.username !== player.username)
{ {
@@ -175,7 +181,7 @@ function publicMatchmaking(player: ClientPlayer)
break; break;
} }
} }
} */ }
if (compatiblePlayers.length >= minPlayersNumber) { if (compatiblePlayers.length >= minPlayersNumber) {
compatiblePlayers.forEach((client) => { compatiblePlayers.forEach((client) => {
@@ -231,7 +237,6 @@ function privateMatchmaking(player: ClientPlayer)
token : player.token token : player.token
}) })
}) })
.then(x => x.json())
.catch(error => console.log("ERROR : " + error)); .catch(error => console.log("ERROR : " + error));
clientTerminate(player); clientTerminate(player);
} }
@@ -252,18 +257,26 @@ function createGameSession(playersArr: ClientPlayer[], matchOptions: en.MatchOpt
gameSession.unreadyPlayersMap.set(client.id, client); gameSession.unreadyPlayersMap.set(client.id, client);
client.socket.once("message", playerReadyConfirmationListener); client.socket.once("message", playerReadyConfirmationListener);
}); });
let gameSessionPlayersIterator = gameSession.playersMap.values();
const eventMatchmakingComplete = new ev.EventMatchmakingComplete(
(<ClientPlayer>gameSessionPlayersIterator.next().value).username,
(<ClientPlayer>gameSessionPlayersIterator.next().value).username
);
// REFACTORING: Not pretty, hardcoded two players. // REFACTORING: Not pretty, hardcoded two players.
// Could be done in gameSession maybe ? // Could be done in gameSession maybe ?
const gameSessionPlayersIterator = gameSession.playersMap.values(); gameSessionPlayersIterator = gameSession.playersMap.values();
let player: ClientPlayer; let player: ClientPlayer;
player = (<ClientPlayer>gameSessionPlayersIterator.next().value); player = (<ClientPlayer>gameSessionPlayersIterator.next().value);
player.racket = gameSession.components.playerLeft; player.racket = gameSession.components.playerLeft;
player.socket.send(JSON.stringify( new ev.EventMatchmakingComplete(en.PlayerSide.left) )); eventMatchmakingComplete.side = en.PlayerSide.left;
player.socket.send(JSON.stringify( eventMatchmakingComplete ));
player = (<ClientPlayer>gameSessionPlayersIterator.next().value); player = (<ClientPlayer>gameSessionPlayersIterator.next().value);
player.racket = gameSession.components.playerRight; player.racket = gameSession.components.playerRight;
player.socket.send(JSON.stringify( new ev.EventMatchmakingComplete(en.PlayerSide.right) )); eventMatchmakingComplete.side = en.PlayerSide.right;
player.socket.send(JSON.stringify( eventMatchmakingComplete ));
// REFACTORING // REFACTORING
setTimeout(function abortMatch() { setTimeout(function abortMatch() {

View File

@@ -18,10 +18,13 @@ export class EventAssignId extends ServerEvent {
} }
export class EventMatchmakingComplete extends ServerEvent { export class EventMatchmakingComplete extends ServerEvent {
side: en.PlayerSide; side: en.PlayerSide = en.PlayerSide.noSide;
constructor(side: en.PlayerSide) { playerOneUsername: string;
playerTwoUsername: string;
constructor(playerOneUsername: string, playerTwoUsername: string) {
super(en.EventTypes.matchmakingComplete); super(en.EventTypes.matchmakingComplete);
this.side = side; this.playerOneUsername = playerOneUsername;
this.playerTwoUsername = playerTwoUsername;
} }
} }

View File

@@ -92,7 +92,8 @@ export class GameService {
} }
this.userRepository.save(user); this.userRepository.save(user);
} }
if (grantTicketDto.isGameIsWithInvitation === true && user.status !== STATUS.IN_GAME) // if (grantTicketDto.isGameIsWithInvitation === true && user.status !== STATUS.IN_GAME) // WIP: need to fix STATUS.IN_GAME
if (grantTicketDto.isGameIsWithInvitation === true)
{ {
const secondUser : Partial<User> = await this.userService.findOne(grantTicketDto.playerTwoUsername) const secondUser : Partial<User> = await this.userService.findOne(grantTicketDto.playerTwoUsername)
if (!secondUser || secondUser.username === user.username) if (!secondUser || secondUser.username === user.username)
@@ -104,17 +105,18 @@ export class GameService {
tok.numberOfRegisteredUser = 0; tok.numberOfRegisteredUser = 0;
tok.token = encryptedTextToReturn; tok.token = encryptedTextToReturn;
this.tokenGameRepository.save(tok); this.tokenGameRepository.save(tok);
this.userService.updateStatus(user.id, "In Pool") this.userService.updateStatus(user.id, STATUS.IN_POOL)
return res.status(HttpStatus.OK).json({ token : encryptedTextToReturn }); return res.status(HttpStatus.OK).json({ token : encryptedTextToReturn });
} }
else if (grantTicketDto.isGameIsWithInvitation === false && user.status !== STATUS.IN_GAME) { // else if (grantTicketDto.isGameIsWithInvitation === false && user.status !== STATUS.IN_GAME) { // WIP: need to fix STATUS.IN_GAME
else if (grantTicketDto.isGameIsWithInvitation === false) {
const encryptedTextToReturn = await this.encryptToken(user.username + '_' const encryptedTextToReturn = await this.encryptToken(user.username + '_'
+ grantTicketDto.gameOptions + '_' + grantTicketDto.isGameIsWithInvitation + '_' + new Date()) + grantTicketDto.gameOptions + '_' + grantTicketDto.isGameIsWithInvitation + '_' + new Date())
const tok = this.tokenGameRepository.create(grantTicketDto); const tok = this.tokenGameRepository.create(grantTicketDto);
tok.numberOfRegisteredUser = 0; tok.numberOfRegisteredUser = 0;
tok.token = encryptedTextToReturn; tok.token = encryptedTextToReturn;
this.tokenGameRepository.save(tok); this.tokenGameRepository.save(tok);
this.userService.updateStatus(user.id, "In Pool") this.userService.updateStatus(user.id, STATUS.IN_POOL)
return res.status(HttpStatus.OK).json({ token : encryptedTextToReturn }); return res.status(HttpStatus.OK).json({ token : encryptedTextToReturn });
} }
return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({message : "Internal Server Error"}); return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({message : "Internal Server Error"});
@@ -140,13 +142,13 @@ export class GameService {
const userOne : User = await this.userRepository.createQueryBuilder('user') const userOne : User = await this.userRepository.createQueryBuilder('user')
.where("user.username = :username", {username : tokenGame.playerOneUsername}) .where("user.username = :username", {username : tokenGame.playerOneUsername})
.getOne(); .getOne();
this.userService.updateStatus(userOne.id, "In Game") this.userService.updateStatus(userOne.id, STATUS.IN_GAME)
const userTwo : User = await this.userRepository.createQueryBuilder('user') const userTwo : User = await this.userRepository.createQueryBuilder('user')
.where("user.username = :username", {username : tokenGame.playerTwoUsername}) .where("user.username = :username", {username : tokenGame.playerTwoUsername})
.getOne(); .getOne();
this.deleteToken(userOne) this.deleteToken(userOne)
this.deleteToken(userTwo) this.deleteToken(userTwo)
this.userService.updateStatus(userTwo.id, "In Game") this.userService.updateStatus(userTwo.id, STATUS.IN_GAME)
} }
return true; return true;
} }
@@ -166,7 +168,7 @@ export class GameService {
const user : User = await this.userRepository.createQueryBuilder('user') const user : User = await this.userRepository.createQueryBuilder('user')
.where("user.username = :username", {username : tokenGame.playerOneUsername}) .where("user.username = :username", {username : tokenGame.playerOneUsername})
.getOne(); .getOne();
this.userService.updateStatus(user.id, "In Game") this.userService.updateStatus(user.id, STATUS.IN_GAME)
this.deleteToken(user) this.deleteToken(user)
return true; return true;
} }
@@ -196,7 +198,7 @@ export class GameService {
async declineInvitation(user : User, token : string, @Res() res : Response) async declineInvitation(user : User, token : string, @Res() res : Response)
{ {
if (user.status !== "Connected") if (user.status !== STATUS.CONNECTED)
return res.status(HttpStatus.FORBIDDEN).json({message : "You must not be in game to decline an invitation"}); return res.status(HttpStatus.FORBIDDEN).json({message : "You must not be in game to decline an invitation"});
console.log("On décline l'invitation") console.log("On décline l'invitation")
const tokenGame = await this.tokenGameRepository.createQueryBuilder('tokengame') const tokenGame = await this.tokenGameRepository.createQueryBuilder('tokengame')
@@ -221,10 +223,10 @@ export class GameService {
{ {
const playerOne = await this.userRepository.findOneBy({username : tokenGame.playerOneUsername}) const playerOne = await this.userRepository.findOneBy({username : tokenGame.playerOneUsername})
const playerTwo = await this.userRepository.findOneBy({username : tokenGame.playerTwoUsername}) const playerTwo = await this.userRepository.findOneBy({username : tokenGame.playerTwoUsername})
if (playerOne.status !== "Disconnected") if (playerOne.status !== STATUS.DISCONNECTED)
this.userService.updateStatus(playerOne.id, "Connected") this.userService.updateStatus(playerOne.id, STATUS.CONNECTED)
if (playerTwo.status !== "Disconnected") if (playerTwo.status !== STATUS.DISCONNECTED)
this.userService.updateStatus(playerTwo.id, "Connected") this.userService.updateStatus(playerTwo.id, STATUS.CONNECTED)
return this.tokenGameRepository.remove(tokenGame); return this.tokenGameRepository.remove(tokenGame);
} }
return new HttpException("Token not found !", HttpStatus.NOT_FOUND) return new HttpException("Token not found !", HttpStatus.NOT_FOUND)
@@ -232,7 +234,7 @@ export class GameService {
async acceptInvitation(user : User, token : string, @Res() res : Response) async acceptInvitation(user : User, token : string, @Res() res : Response)
{ {
if (user.status !== "Connected") if (user.status !== STATUS.CONNECTED)
return res.status(HttpStatus.FORBIDDEN).send("") return res.status(HttpStatus.FORBIDDEN).send("")
const tokenGame = await this.tokenGameRepository.createQueryBuilder('tokenGame') const tokenGame = await this.tokenGameRepository.createQueryBuilder('tokenGame')
.andWhere('tokenGame.playerTwoUsername = :playerTwoUsername', {playerTwoUsername : user.username}) .andWhere('tokenGame.playerTwoUsername = :playerTwoUsername', {playerTwoUsername : user.username})
@@ -294,8 +296,8 @@ export class GameService {
this.userService.incrementVictories(playerOne.id) this.userService.incrementVictories(playerOne.id)
this.userService.incrementDefeats(playerTwo.id) this.userService.incrementDefeats(playerTwo.id)
} }
this.userService.updateStatus(playerOne.id, "Connected") this.userService.updateStatus(playerOne.id, STATUS.CONNECTED)
this.userService.updateStatus(playerTwo.id, "Connected") this.userService.updateStatus(playerTwo.id, STATUS.CONNECTED)
return HttpStatus.OK return HttpStatus.OK
} }
} }

View File

@@ -12,6 +12,9 @@
let user; let user;
let allUsers; let allUsers;
let playerOneAvatar;
let playerTwoAvatar;
//Game's stuff //Game's stuff
const options = new pong.InitOptions(); const options = new pong.InitOptions();
const gameAreaId = "game_area"; const gameAreaId = "game_area";
@@ -26,9 +29,10 @@
let showWaitPage = false; let showWaitPage = false;
let invitations = []; let invitations = [];
let watchGameStateInterval; let watchGameStateInterval;
const watchGameStateIntervalRate = 142; const watchGameStateIntervalRate = 142;
let watchMatchStartInterval;
const watchMatchStartIntervalRate = 111;
onMount( async() => { onMount( async() => {
user = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user`) user = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user`)
@@ -39,6 +43,7 @@
}) })
onDestroy( async() => { onDestroy( async() => {
clearInterval(watchMatchStartInterval);
clearInterval(watchGameStateInterval); clearInterval(watchGameStateInterval);
pong.destroy(); pong.destroy();
}) })
@@ -76,6 +81,7 @@
showWaitPage = false; showWaitPage = false;
if (response.ok && token) if (response.ok && token)
{ {
watchMatchStartInterval = setInterval(watchMatchStart, watchMatchStartIntervalRate);
watchGameStateInterval = setInterval(watchGameState, watchGameStateIntervalRate); watchGameStateInterval = setInterval(watchGameState, watchGameStateIntervalRate);
pong.init(matchOptions, options, gameAreaId, token); pong.init(matchOptions, options, gameAreaId, token);
hiddenGame = false; hiddenGame = false;
@@ -106,6 +112,7 @@
console.log(invitation); console.log(invitation);
if (invitation.token) if (invitation.token)
{ {
watchMatchStartInterval = setInterval(watchMatchStart, watchMatchStartIntervalRate);
watchGameStateInterval = setInterval(watchGameState, watchGameStateIntervalRate); watchGameStateInterval = setInterval(watchGameState, watchGameStateIntervalRate);
options.playerOneUsername = invitation.playerOneUsername; options.playerOneUsername = invitation.playerOneUsername;
options.playerTwoUsername = invitation.playerTwoUsername; options.playerTwoUsername = invitation.playerTwoUsername;
@@ -117,16 +124,24 @@
} }
} }
async function watchMatchStart()
{
if (gameState.matchStarted)
{
clearInterval(watchMatchStartInterval);
playerOneAvatar = await fetchAvatar(gameState.playerOneUsername);
playerTwoAvatar = await fetchAvatar(gameState.playerTwoUsername);
gameState.matchStarted = gameState.matchStarted; // trigger Svelte reactivity
}
}
const watchGameState = () => { const watchGameState = () => {
console.log("watchGameState"); console.log("watchGameState");
if (gameState) { // trigger Svelte reactivity
gameState.matchStarted = gameState.matchStarted;
gameState.matchEnded = gameState.matchEnded;
gameState.matchAborted = gameState.matchAborted;
}
if (gameState.matchAborted || gameState.matchEnded) if (gameState.matchAborted || gameState.matchEnded)
{ {
clearInterval(watchGameStateInterval); clearInterval(watchGameStateInterval);
gameState.matchEnded = gameState.matchEnded; // trigger Svelte reactivity
gameState.matchAborted = gameState.matchAborted; // trigger Svelte reactivity
console.log("watchGameState, end"); console.log("watchGameState, end");
setTimeout(() => { setTimeout(() => {
resetPage(); resetPage();
@@ -176,10 +191,28 @@
} }
function leaveMatch() { function leaveMatch() {
clearInterval(watchMatchStartInterval);
clearInterval(watchGameStateInterval); clearInterval(watchGameStateInterval);
resetPage(); resetPage();
}; };
async function fetchAvatar(username: string) // TODO: Could be shared with others components
{
return fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user/avatar?username=${username}`)
.then((response) => {
if (!response.ok) {
throw new Error("Avatar not retrieved");
}
return response.blob();
})
.then((blob) => {
return URL.createObjectURL(blob);
})
.catch((error) => {
console.log("catch fetchAvatar: ", error);
});
}
</script> </script>
<Header /> <Header />
@@ -213,6 +246,14 @@
</div> </div>
{#if !hiddenGame} {#if !hiddenGame}
{#if gameState.matchStarted}
<div class="div_game">
<img class="avatar" src="{playerOneAvatar}" alt="player one avatar">
'{gameState.playerOneUsername}' VS '{gameState.playerTwoUsername}'
<img class="avatar" src="{playerTwoAvatar}" alt="player two avatar">
</div>
{/if}
{#if gameState.matchStarted && !gameState.matchEnded} {#if gameState.matchStarted && !gameState.matchEnded}
<div class="div_game"> <div class="div_game">
<button class="pong_button" on:click={leaveMatch}>forfeit</button> <button class="pong_button" on:click={leaveMatch}>forfeit</button>
@@ -356,5 +397,11 @@ canvas {
font-size: x-large; font-size: x-large;
padding: 10px; padding: 10px;
} }
.avatar {
min-height: 100px;
min-width: 100px;
max-width: 100px;
max-height: 100px;
}
</style> </style>

View File

@@ -1,10 +1,11 @@
<script lang="ts"> <script lang="ts">
import { onMount, onDestroy } from "svelte"; import { onMount, onDestroy } from "svelte";
import Header from '../../pieces/Header.svelte';
import MatchListElem from "../../pieces/MatchListElem.svelte";
import { fade, fly } from 'svelte/transition'; import { fade, fly } from 'svelte/transition';
import Header from '../../pieces/Header.svelte';
import MatchListElem from "../../pieces/MatchListElem.svelte";
import type { Match } from "../../pieces/Match";
import * as pongSpectator from "./client/pongSpectator"; import * as pongSpectator from "./client/pongSpectator";
import { gameState } from "./client/ws"; import { gameState } from "./client/ws";
@@ -13,14 +14,17 @@
let user; let user;
let allUsers; let allUsers;
//Game's stuff client side only let playerOneAvatar;
let playerTwoAvatar;
//Game's stuff
const gameAreaId = "game_area"; const gameAreaId = "game_area";
let sound = "off"; let sound = "off";
let matchList = [];
//html boolean for pages //html boolean for pages
let hiddenGame = true; let hiddenGame = true;
let matchList: Match[] = [];
let watchGameStateInterval; let watchGameStateInterval;
const watchGameStateIntervalRate = 142; const watchGameStateIntervalRate = 142;
@@ -39,22 +43,27 @@
pongSpectator.destroy(); pongSpectator.destroy();
}) })
async function initGameSpectator(gameSessionId: string, matchOptions: pongSpectator.MatchOptions) async function initGameSpectator(match: Match)
{ {
watchGameStateInterval = setInterval(watchGameState, watchGameStateIntervalRate); watchGameStateInterval = setInterval(watchGameState, watchGameStateIntervalRate);
pongSpectator.init(matchOptions, sound, gameAreaId, gameSessionId); pongSpectator.init(match.gameOptions, sound, gameAreaId, match.gameServerIdOfTheMatch);
// Users avatar
gameState.playerOneUsername = match.playerOneUsername;
gameState.playerTwoUsername = match.playerTwoUsername;
playerOneAvatar = await fetchAvatar(gameState.playerOneUsername);
playerTwoAvatar = await fetchAvatar(gameState.playerTwoUsername);
hiddenGame = false; hiddenGame = false;
}; };
const watchGameState = () => { const watchGameState = () => {
console.log("watchGameState") console.log("watchGameState")
if (gameState) { // trigger Svelte reactivity // gameState.matchStarted = gameState.matchStarted; // trigger Svelte reactivity
gameState.matchStarted = gameState.matchStarted;
gameState.matchEnded = gameState.matchEnded;
gameState.matchAborted = gameState.matchAborted;
}
if (gameState.matchAborted || gameState.matchEnded) if (gameState.matchAborted || gameState.matchEnded)
{ {
gameState.matchEnded = gameState.matchEnded; // trigger Svelte reactivity
gameState.matchAborted = gameState.matchAborted; // trigger Svelte reactivity
clearInterval(watchGameStateInterval); clearInterval(watchGameStateInterval);
console.log("watchGameState, end") console.log("watchGameState, end")
setTimeout(() => { setTimeout(() => {
@@ -80,6 +89,22 @@
.then( x => x.json() ); .then( x => x.json() );
}; };
async function fetchAvatar(username: string) // TODO: Could be shared with others components
{
return fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user/avatar?username=${username}`)
.then((response) => {
if (!response.ok) {
throw new Error("Avatar not retrieved");
}
return response.blob();
})
.then((blob) => {
return URL.createObjectURL(blob);
})
.catch((error) => {
console.log("catch fetchAvatar: ", error);
});
}
</script> </script>
<!-- --> <!-- -->
@@ -102,6 +127,12 @@
</div> </div>
{#if !hiddenGame} {#if !hiddenGame}
<div class="div_game">
<img class="avatar" src="{playerOneAvatar}" alt="player one avatar">
'{gameState.playerOneUsername}' VS '{gameState.playerTwoUsername}'
<img class="avatar" src="{playerTwoAvatar}" alt="player two avatar">
</div>
{#if !gameState.matchEnded} {#if !gameState.matchEnded}
<div class="div_game"> <div class="div_game">
<button class="pong_button" on:click={leaveMatch}>leave</button> <button class="pong_button" on:click={leaveMatch}>leave</button>
@@ -127,7 +158,7 @@
{#if matchList.length !== 0} {#if matchList.length !== 0}
<menu id="match_list"> <menu id="match_list">
{#each matchList as match} {#each matchList as match}
<MatchListElem match={match} on:click={(e) => initGameSpectator(match.gameServerIdOfTheMatch, match.gameOptions)} /> <MatchListElem match={match} on:click={(e) => initGameSpectator(match)} />
{/each} {/each}
</menu> </menu>
{:else} {:else}
@@ -195,10 +226,15 @@ canvas {
font-size: x-large; font-size: x-large;
padding: 10px; padding: 10px;
} }
#match_list { #match_list {
font-family: 'Courier New', Courier, monospace; font-family: 'Courier New', Courier, monospace;
font-size: large; font-size: large;
} }
.avatar {
min-height: 100px;
min-width: 100px;
max-width: 100px;
max-height: 100px;
}
</style> </style>

View File

@@ -3,7 +3,7 @@ import * as c from "./constants.js"
import * as en from "../shared_js/enums.js" import * as en from "../shared_js/enums.js"
import { GameArea } from "./class/GameArea.js"; import { GameArea } from "./class/GameArea.js";
import { GameComponentsClient } from "./class/GameComponentsClient.js"; import { GameComponentsClient } from "./class/GameComponentsClient.js";
import { socket, resetGameState } from "./ws.js"; import { socket, gameState } from "./ws.js";
import { initAudio } from "./audio.js"; import { initAudio } from "./audio.js";
import type { InitOptions } from "./class/InitOptions.js"; import type { InitOptions } from "./class/InitOptions.js";
@@ -57,5 +57,5 @@ export function destroyBase()
} }
setGc(null); setGc(null);
setMatchOptions(null); setMatchOptions(null);
resetGameState(); gameState.resetGameState();
} }

View File

@@ -10,16 +10,22 @@ import { muteFlag, soundRoblox } from "./audio.js"
import { sleep } from "./utils.js"; import { sleep } from "./utils.js";
import { Vector, VectorInteger } from "../shared_js/class/Vector.js"; import { Vector, VectorInteger } from "../shared_js/class/Vector.js";
export const gameState = { class GameState {
matchStarted: false, matchStarted: boolean;
matchEnded: false, matchEnded: boolean;
matchAborted: false matchAborted: boolean;
} playerOneUsername: string;
playerTwoUsername: string;
export function resetGameState() { constructor() {
gameState.matchStarted = false; this.resetGameState();
gameState.matchEnded = false; }
gameState.matchAborted = false; resetGameState() {
this.matchStarted = false;
this.matchEnded = false;
this.matchAborted = false;
this.playerOneUsername = "";
this.playerTwoUsername = "";
}
} }
class ClientInfo { class ClientInfo {
@@ -39,6 +45,7 @@ class ClientInfoSpectator {
const wsUrl = "ws://" + process.env.WEBSITE_HOST + ":" + process.env.WEBSITE_PORT + "/pong"; const wsUrl = "ws://" + process.env.WEBSITE_HOST + ":" + process.env.WEBSITE_PORT + "/pong";
export let socket: WebSocket; export let socket: WebSocket;
export const gameState = new GameState();
export const clientInfo = new ClientInfo(); export const clientInfo = new ClientInfo();
export const clientInfoSpectator = new ClientInfoSpectator(); // WIP, could refactor this export const clientInfoSpectator = new ClientInfoSpectator(); // WIP, could refactor this
@@ -85,6 +92,8 @@ function preMatchListener(this: WebSocket, event: MessageEvent)
break; break;
case en.EventTypes.matchmakingComplete: case en.EventTypes.matchmakingComplete:
clientInfo.side = (<ev.EventMatchmakingComplete>data).side; clientInfo.side = (<ev.EventMatchmakingComplete>data).side;
gameState.playerOneUsername = (<ev.EventMatchmakingComplete>data).playerOneUsername;
gameState.playerTwoUsername = (<ev.EventMatchmakingComplete>data).playerTwoUsername;
if (clientInfo.side === en.PlayerSide.left) if (clientInfo.side === en.PlayerSide.left)
{ {
clientInfo.racket = gc.playerLeft; clientInfo.racket = gc.playerLeft;

View File

@@ -18,10 +18,13 @@ export class EventAssignId extends ServerEvent {
} }
export class EventMatchmakingComplete extends ServerEvent { export class EventMatchmakingComplete extends ServerEvent {
side: en.PlayerSide; side: en.PlayerSide = en.PlayerSide.noSide;
constructor(side: en.PlayerSide) { playerOneUsername: string;
playerTwoUsername: string;
constructor(playerOneUsername: string, playerTwoUsername: string) {
super(en.EventTypes.matchmakingComplete); super(en.EventTypes.matchmakingComplete);
this.side = side; this.playerOneUsername = playerOneUsername;
this.playerTwoUsername = playerTwoUsername;
} }
} }

View File

@@ -0,0 +1,10 @@
import type { MatchOptions } from "../pages/game/client/pongSpectator";
export { MatchOptions } from "../pages/game/client/pongSpectator";
export class Match {
gameServerIdOfTheMatch: string;
gameOptions: MatchOptions;
playerOneUsername: string;
playerTwoUsername: string;
}

View File

@@ -1,14 +1,9 @@
<script lang="ts"> <script lang="ts">
import { onMount, onDestroy } from "svelte"; import { onMount, onDestroy } from "svelte";
import { MatchOptions } from "../pages/game/client/pongSpectator"; import { Match, MatchOptions} from "./Match";
export let match: { export let match: Match;
gameServerIdOfTheMatch: string,
gameOptions: MatchOptions,
playerOneUsername: string,
playerTwoUsername: string
};
let matchOptionsString = ""; let matchOptionsString = "";
@@ -32,7 +27,7 @@
<li> <li>
<button on:click> <button on:click>
"{match.playerOneUsername}" VS "{match.playerTwoUsername}" '{match.playerOneUsername}' VS '{match.playerTwoUsername}'
<br/> [{matchOptionsString}] <br/> [{matchOptionsString}]
</button> </button>
</li> </li>