Merge branch 'luke' into cherif_back_and_game
This commit is contained in:
47
memo.txt
Normal file
47
memo.txt
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
DONE :
|
||||||
|
|
||||||
|
|
||||||
|
TODO :
|
||||||
|
routes gameServer -> Nest :
|
||||||
|
- validation
|
||||||
|
- creation de partie
|
||||||
|
- fin de partie
|
||||||
|
- mode spectateur
|
||||||
|
- quelques routes cote serveur
|
||||||
|
- une interface cote front (liste des matchs en cours)
|
||||||
|
- etat du client (en ligne, en jeu, ...)
|
||||||
|
- le chat
|
||||||
|
|
||||||
|
-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
|
||||||
|
"Bonus" :
|
||||||
|
- HTTPS
|
||||||
|
- mettre le site en ligne
|
||||||
|
-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
|
||||||
|
BUG :
|
||||||
|
- Bug de son étonnant dans le front, ça pop une fois de temps en temps :
|
||||||
|
Uncaught (in promise) DOMException: The element has no supported sources.
|
||||||
|
-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
|
||||||
|
|
||||||
|
- Comment fonctionne .env ? Comment faire pour ne pas le push sur le depot ?
|
||||||
|
|
||||||
|
- certains status 200 pourrait peut-être être du 204 ?
|
||||||
|
(exemple dans TwoFactorAuthentication.svelte)
|
||||||
|
|
||||||
|
A la place de :
|
||||||
|
```
|
||||||
|
if (response.status === 401) {
|
||||||
|
// Wrong
|
||||||
|
}
|
||||||
|
if (response.status === 200) {
|
||||||
|
// Ok
|
||||||
|
}
|
||||||
|
```
|
||||||
|
On pourrait mettre :
|
||||||
|
```
|
||||||
|
if (!response.ok) {
|
||||||
|
// Wrong
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Ok
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -17,6 +17,8 @@ export class Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class ClientPlayer extends Client {
|
export class ClientPlayer extends Client {
|
||||||
|
token: string;
|
||||||
|
username: string;
|
||||||
matchOptions: en.MatchOptions = 0;
|
matchOptions: en.MatchOptions = 0;
|
||||||
inputBuffer: ev.EventInput = new ev.EventInput();
|
inputBuffer: ev.EventInput = new ev.EventInput();
|
||||||
lastInputId: number = 0;
|
lastInputId: number = 0;
|
||||||
|
|||||||
@@ -24,15 +24,18 @@ export class GameSession {
|
|||||||
spectatorsUpdateInterval: NodeJS.Timer | number = 0;
|
spectatorsUpdateInterval: NodeJS.Timer | number = 0;
|
||||||
components: GameComponentsServer;
|
components: GameComponentsServer;
|
||||||
matchOptions: en.MatchOptions;
|
matchOptions: en.MatchOptions;
|
||||||
|
isPrivateMatch: boolean; // WIP: could be used to separate leaderboards for example.
|
||||||
matchEnded: boolean = false;
|
matchEnded: boolean = false;
|
||||||
|
lastStateSnapshot: ev.EventGameUpdate;
|
||||||
|
|
||||||
actual_time: number;
|
actual_time: number;
|
||||||
last_time: number;
|
last_time: number;
|
||||||
delta_time: number;
|
delta_time: number;
|
||||||
|
|
||||||
constructor(id: string, matchOptions: en.MatchOptions) {
|
constructor(id: string, matchOptions: en.MatchOptions, isPrivateMatch: boolean = false) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.matchOptions = matchOptions;
|
this.matchOptions = matchOptions;
|
||||||
|
this.isPrivateMatch = isPrivateMatch;
|
||||||
this.components = new GameComponentsServer(this.matchOptions);
|
this.components = new GameComponentsServer(this.matchOptions);
|
||||||
}
|
}
|
||||||
start() {
|
start() {
|
||||||
@@ -51,6 +54,7 @@ export class GameSession {
|
|||||||
});
|
});
|
||||||
|
|
||||||
s.actual_time = Date.now();
|
s.actual_time = Date.now();
|
||||||
|
s.lastStateSnapshot = s._gameStateSnapshot();
|
||||||
s.gameLoopInterval = setInterval(s._gameLoop, c.serverGameLoopIntervalMS, s);
|
s.gameLoopInterval = setInterval(s._gameLoop, c.serverGameLoopIntervalMS, s);
|
||||||
s.playersUpdateInterval = setInterval(s._playersUpdate, c.playersUpdateIntervalMS, s);
|
s.playersUpdateInterval = setInterval(s._playersUpdate, c.playersUpdateIntervalMS, s);
|
||||||
s.spectatorsUpdateInterval = setInterval(s._spectatorsUpdate, c.spectatorsUpdateIntervalMS, s);
|
s.spectatorsUpdateInterval = setInterval(s._spectatorsUpdate, c.spectatorsUpdateIntervalMS, s);
|
||||||
@@ -139,16 +143,16 @@ export class GameSession {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
private _playersUpdate(s: GameSession) {
|
private _playersUpdate(s: GameSession) {
|
||||||
const gameState: ev.EventGameUpdate = s._gameStateSnapshot();
|
s.lastStateSnapshot = s._gameStateSnapshot();
|
||||||
s.playersMap.forEach( (client) => {
|
s.playersMap.forEach( (client) => {
|
||||||
gameState.lastInputId = client.lastInputId;
|
s.lastStateSnapshot.lastInputId = client.lastInputId;
|
||||||
client.socket.send(JSON.stringify(gameState));
|
client.socket.send(JSON.stringify(s.lastStateSnapshot));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
private _spectatorsUpdate(s: GameSession) {
|
private _spectatorsUpdate(s: GameSession) {
|
||||||
const gameState = s._gameStateSnapshot();
|
s.lastStateSnapshot.lastInputId = 0;
|
||||||
s.spectatorsMap.forEach( (client) => {
|
s.spectatorsMap.forEach( (client) => {
|
||||||
client.socket.send(JSON.stringify(gameState));
|
client.socket.send(JSON.stringify(s.lastStateSnapshot));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
private _gameStateSnapshot() : ev.EventGameUpdate {
|
private _gameStateSnapshot() : ev.EventGameUpdate {
|
||||||
@@ -182,7 +186,12 @@ export class GameSession {
|
|||||||
{
|
{
|
||||||
if (Math.abs(gc.scoreLeft - gc.scoreRight) >= 2)
|
if (Math.abs(gc.scoreLeft - gc.scoreRight) >= 2)
|
||||||
{
|
{
|
||||||
s._matchEnd(s);
|
if (gc.scoreLeft > gc.scoreRight) {
|
||||||
|
s._matchEnd(en.PlayerSide.left);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
s._matchEnd(en.PlayerSide.right);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -197,45 +206,53 @@ export class GameSession {
|
|||||||
this.matchEnded = true;
|
this.matchEnded = true;
|
||||||
if (this.playersMap.size != 0)
|
if (this.playersMap.size != 0)
|
||||||
{
|
{
|
||||||
|
console.log("Forfeit Ending");
|
||||||
const gc = this.components;
|
const gc = this.components;
|
||||||
const luckyWinner: ClientPlayer = this.playersMap.values().next().value;
|
const luckyWinner: ClientPlayer = this.playersMap.values().next().value;
|
||||||
let eventEnd: ev.EventMatchEnd;
|
|
||||||
if (luckyWinner.racket === gc.playerLeft) {
|
if (luckyWinner.racket === gc.playerLeft) {
|
||||||
eventEnd = new ev.EventMatchEnd(en.PlayerSide.left, true);
|
this._matchEnd(en.PlayerSide.left, true);
|
||||||
console.log("Player Left WIN (by forfeit)");
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
eventEnd = new ev.EventMatchEnd(en.PlayerSide.right, true);
|
this._matchEnd(en.PlayerSide.right, true);
|
||||||
console.log("Player Right WIN (by forfeit)");
|
|
||||||
}
|
}
|
||||||
luckyWinner.socket.send(JSON.stringify(eventEnd));
|
|
||||||
this.spectatorsMap.forEach( (client) => {
|
|
||||||
client.socket.send(JSON.stringify(eventEnd));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
private _matchEnd(s: GameSession) {
|
private async _matchEnd(winner: en.PlayerSide, forfeit_flag: boolean = false)
|
||||||
s.matchEnded = true;
|
{
|
||||||
const gc = s.components;
|
this.matchEnded = true;
|
||||||
|
|
||||||
let eventEnd: ev.EventMatchEnd;
|
let eventEnd: ev.EventMatchEnd;
|
||||||
if (gc.scoreLeft > gc.scoreRight) {
|
eventEnd = new ev.EventMatchEnd(winner, forfeit_flag);
|
||||||
eventEnd = new ev.EventMatchEnd(en.PlayerSide.left);
|
this.playersMap.forEach( (client) => {
|
||||||
|
client.socket.send(JSON.stringify(eventEnd));
|
||||||
|
});
|
||||||
|
this.spectatorsMap.forEach( (client) => {
|
||||||
|
client.socket.send(JSON.stringify(eventEnd));
|
||||||
|
});
|
||||||
|
|
||||||
|
/* // WIP nest , send match result
|
||||||
|
const gc = this.components;
|
||||||
|
await fetch(c.addressBackEnd + "/game/matchEnd",
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
id: this.id,
|
||||||
|
scoreLeft: gc.scoreLeft,
|
||||||
|
scoreRight: gc.scoreRight,
|
||||||
|
})
|
||||||
|
}); */
|
||||||
|
|
||||||
|
// logs
|
||||||
|
if (winner === en.PlayerSide.left) {
|
||||||
console.log("Player Left WIN");
|
console.log("Player Left WIN");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
eventEnd = new ev.EventMatchEnd(en.PlayerSide.right);
|
|
||||||
console.log("Player Right WIN");
|
console.log("Player Right WIN");
|
||||||
}
|
}
|
||||||
|
|
||||||
s.playersMap.forEach( (client) => {
|
|
||||||
client.socket.send(JSON.stringify(eventEnd));
|
|
||||||
});
|
|
||||||
s.spectatorsMap.forEach( (client) => {
|
|
||||||
client.socket.send(JSON.stringify(eventEnd));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,3 +8,5 @@ export const fixedDeltaTime = serverGameLoopIntervalMS/1000; // second
|
|||||||
// 33.333ms == 1000/30
|
// 33.333ms == 1000/30
|
||||||
export const playersUpdateIntervalMS = 1000/30; // millisecond
|
export const playersUpdateIntervalMS = 1000/30; // millisecond
|
||||||
export const spectatorsUpdateIntervalMS = 1000/30; // millisecond
|
export const spectatorsUpdateIntervalMS = 1000/30; // millisecond
|
||||||
|
|
||||||
|
export const addressBackEnd = "http://backend_dev:3000";
|
||||||
|
|||||||
@@ -10,16 +10,17 @@ import { v4 as uuidv4 } from 'uuid';
|
|||||||
|
|
||||||
import * as en from "../shared_js/enums.js"
|
import * as en from "../shared_js/enums.js"
|
||||||
import * as ev from "../shared_js/class/Event.js"
|
import * as ev from "../shared_js/class/Event.js"
|
||||||
|
import * as c from "./constants.js"
|
||||||
import { Client, ClientPlayer, ClientSpectator } from "./class/Client.js"
|
import { Client, ClientPlayer, ClientSpectator } from "./class/Client.js"
|
||||||
import { GameSession } from "./class/GameSession.js"
|
import { GameSession } from "./class/GameSession.js"
|
||||||
import { shortId } from "./utils.js";
|
import { shortId } from "./utils.js";
|
||||||
import { gameSessionIdPLACEHOLDER } from "./constants.js";
|
import { gameSessionIdPLACEHOLDER } from "./constants.js";
|
||||||
|
|
||||||
// pas indispensable d'avoir un autre port si le WebSocket est relié à un serveur http préexistant ?
|
|
||||||
const wsPort = 8042;
|
const wsPort = 8042;
|
||||||
export const wsServer = new WebSocketServer<WebSocket>({host: "0.0.0.0", port: wsPort, path: "/pong"});
|
export const wsServer = new WebSocketServer<WebSocket>({host: "0.0.0.0", port: wsPort, path: "/pong"});
|
||||||
const clientsMap: Map<string, Client> = new Map; // socket.id/Client
|
const clientsMap: Map<string, Client> = new Map; // socket.id/Client
|
||||||
const matchmakingPlayersMap: Map<string, ClientPlayer> = new Map; // socket.id/ClientPlayer (duplicates with clientsMap)
|
const matchmakingMap: Map<string, ClientPlayer> = new Map; // socket.id/ClientPlayer (duplicates with clientsMap)
|
||||||
|
const privateMatchmakingMap: Map<string, ClientPlayer> = new Map; // socket.id/ClientPlayer (duplicates with clientsMap)
|
||||||
const gameSessionsMap: Map<string, GameSession> = new Map; // GameSession.id(url)/GameSession
|
const gameSessionsMap: Map<string, GameSession> = new Map; // GameSession.id(url)/GameSession
|
||||||
|
|
||||||
wsServer.on("connection", connectionListener);
|
wsServer.on("connection", connectionListener);
|
||||||
@@ -54,7 +55,7 @@ function connectionListener(socket: WebSocket, request: IncomingMessage)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function clientAnnounceListener(this: WebSocket, data: string)
|
async function clientAnnounceListener(this: WebSocket, data: string)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
const msg : ev.ClientAnnounce = JSON.parse(data);
|
const msg : ev.ClientAnnounce = JSON.parse(data);
|
||||||
@@ -65,11 +66,46 @@ function clientAnnounceListener(this: WebSocket, data: string)
|
|||||||
if (msg.role === en.ClientRole.player)
|
if (msg.role === en.ClientRole.player)
|
||||||
{
|
{
|
||||||
const announce: ev.ClientAnnouncePlayer = <ev.ClientAnnouncePlayer>msg;
|
const announce: ev.ClientAnnouncePlayer = <ev.ClientAnnouncePlayer>msg;
|
||||||
|
|
||||||
|
// WIP nest, fetch token validation
|
||||||
|
const body = {
|
||||||
|
playerOneUsername: announce.username,
|
||||||
|
playerTwoUsername: "",
|
||||||
|
gameOptions: announce.matchOptions,
|
||||||
|
isGameIsWithInvitation: announce.privateMatch,
|
||||||
|
token: announce.token,
|
||||||
|
};
|
||||||
|
if (announce.privateMatch) {
|
||||||
|
body.playerTwoUsername = announce.playerTwoUsername;
|
||||||
|
}
|
||||||
|
const response = await fetch(c.addressBackEnd + "/game/validateToken",
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify(body)
|
||||||
|
});
|
||||||
|
if (!response.ok)
|
||||||
|
{
|
||||||
|
// send message to client ? or just gtfo ?
|
||||||
|
clientTerminate(clientsMap.get(this.id));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const player = clientsMap.get(this.id) as ClientPlayer;
|
const player = clientsMap.get(this.id) as ClientPlayer;
|
||||||
player.matchOptions = announce.matchOptions;
|
player.matchOptions = announce.matchOptions;
|
||||||
this.send(JSON.stringify( new ev.EventAssignId(this.id) ));
|
player.token = announce.token;
|
||||||
|
player.username = announce.username;
|
||||||
|
|
||||||
|
this.send(JSON.stringify( new ev.EventAssignId(this.id) )); // unused
|
||||||
this.send(JSON.stringify( new ev.ServerEvent(en.EventTypes.matchmakingInProgress) ));
|
this.send(JSON.stringify( new ev.ServerEvent(en.EventTypes.matchmakingInProgress) ));
|
||||||
matchmaking(player);
|
if (announce.privateMatch) {
|
||||||
|
privateMatchmaking(player);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
publicMatchmaking(player);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (msg.role === en.ClientRole.spectator)
|
else if (msg.role === en.ClientRole.spectator)
|
||||||
{
|
{
|
||||||
@@ -77,6 +113,7 @@ function clientAnnounceListener(this: WebSocket, data: string)
|
|||||||
const gameSession = gameSessionsMap.get(announce.gameSessionId);
|
const gameSession = gameSessionsMap.get(announce.gameSessionId);
|
||||||
if (!gameSession) {
|
if (!gameSession) {
|
||||||
// WIP: send "invalid game session"
|
// WIP: send "invalid game session"
|
||||||
|
clientTerminate(clientsMap.get(this.id));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const spectator = clientsMap.get(this.id) as ClientSpectator;
|
const spectator = clientsMap.get(this.id) as ClientSpectator;
|
||||||
@@ -97,15 +134,15 @@ function clientAnnounceListener(this: WebSocket, data: string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function matchmaking(player: ClientPlayer)
|
function publicMatchmaking(player: ClientPlayer)
|
||||||
{
|
{
|
||||||
const minPlayersNumber = 2;
|
const minPlayersNumber = 2;
|
||||||
const maxPlayersNumber = 2;
|
const maxPlayersNumber = 2;
|
||||||
|
matchmakingMap.set(player.id, player);
|
||||||
const matchOptions = player.matchOptions;
|
const matchOptions = player.matchOptions;
|
||||||
matchmakingPlayersMap.set(player.id, player);
|
|
||||||
|
|
||||||
const compatiblePlayers: ClientPlayer[] = [];
|
const compatiblePlayers: ClientPlayer[] = [];
|
||||||
for (const [id, client] of matchmakingPlayersMap)
|
for (const [id, client] of matchmakingMap)
|
||||||
{
|
{
|
||||||
if (client.matchOptions === matchOptions)
|
if (client.matchOptions === matchOptions)
|
||||||
{
|
{
|
||||||
@@ -116,17 +153,52 @@ function matchmaking(player: ClientPlayer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compatiblePlayers.length < minPlayersNumber) {
|
if (compatiblePlayers.length >= minPlayersNumber) {
|
||||||
return;
|
compatiblePlayers.forEach((client) => {
|
||||||
|
matchmakingMap.delete(client.id);
|
||||||
|
});
|
||||||
|
createGameSession(compatiblePlayers, matchOptions);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function privateMatchmaking(player: ClientPlayer)
|
||||||
|
{
|
||||||
|
const minPlayersNumber = 2;
|
||||||
|
const maxPlayersNumber = 2;
|
||||||
|
privateMatchmakingMap.set(player.id, player);
|
||||||
|
const matchOptions = player.matchOptions;
|
||||||
|
|
||||||
|
const token = player.token;
|
||||||
|
const compatiblePlayers: ClientPlayer[] = [];
|
||||||
|
for (const [id, client] of privateMatchmakingMap)
|
||||||
|
{
|
||||||
|
if (client.token === token)
|
||||||
|
{
|
||||||
|
compatiblePlayers.push(client);
|
||||||
|
if (compatiblePlayers.length === maxPlayersNumber) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compatiblePlayers.length >= minPlayersNumber) {
|
||||||
|
compatiblePlayers.forEach((client) => {
|
||||||
|
privateMatchmakingMap.delete(client.id);
|
||||||
|
});
|
||||||
|
createGameSession(compatiblePlayers, matchOptions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function createGameSession(playersArr: ClientPlayer[], matchOptions: en.MatchOptions)
|
||||||
|
{
|
||||||
// const id = gameSessionIdPLACEHOLDER; // Force ID, TESTING SPECTATOR
|
// const id = gameSessionIdPLACEHOLDER; // Force ID, TESTING SPECTATOR
|
||||||
const id = uuidv4();
|
const id = uuidv4();
|
||||||
const gameSession = new GameSession(id, matchOptions);
|
const gameSession = new GameSession(id, matchOptions);
|
||||||
gameSessionsMap.set(id, gameSession);
|
gameSessionsMap.set(id, gameSession);
|
||||||
|
|
||||||
compatiblePlayers.forEach((client) => {
|
playersArr.forEach((client) => {
|
||||||
matchmakingPlayersMap.delete(client.id);
|
|
||||||
client.gameSession = gameSession;
|
client.gameSession = gameSession;
|
||||||
gameSession.playersMap.set(client.id, client);
|
gameSession.playersMap.set(client.id, client);
|
||||||
gameSession.unreadyPlayersMap.set(client.id, client);
|
gameSession.unreadyPlayersMap.set(client.id, client);
|
||||||
@@ -134,15 +206,15 @@ function matchmaking(player: ClientPlayer)
|
|||||||
|
|
||||||
// WIP: Not pretty, hardcoded two players.
|
// WIP: Not pretty, hardcoded two players.
|
||||||
// Could be done in gameSession maybe ?
|
// Could be done in gameSession maybe ?
|
||||||
compatiblePlayers[0].racket = gameSession.components.playerRight;
|
playersArr[0].racket = gameSession.components.playerRight;
|
||||||
compatiblePlayers[1].racket = gameSession.components.playerLeft;
|
playersArr[1].racket = gameSession.components.playerLeft;
|
||||||
|
|
||||||
compatiblePlayers.forEach((client) => {
|
playersArr.forEach((client) => {
|
||||||
client.socket.once("message", playerReadyConfirmationListener);
|
client.socket.once("message", playerReadyConfirmationListener);
|
||||||
});
|
});
|
||||||
|
|
||||||
compatiblePlayers[0].socket.send(JSON.stringify( new ev.EventMatchmakingComplete(en.PlayerSide.right) ));
|
playersArr[0].socket.send(JSON.stringify( new ev.EventMatchmakingComplete(en.PlayerSide.right) ));
|
||||||
compatiblePlayers[1].socket.send(JSON.stringify( new ev.EventMatchmakingComplete(en.PlayerSide.left) ));
|
playersArr[1].socket.send(JSON.stringify( new ev.EventMatchmakingComplete(en.PlayerSide.left) ));
|
||||||
|
|
||||||
setTimeout(function abortMatch() {
|
setTimeout(function abortMatch() {
|
||||||
if (gameSession.unreadyPlayersMap.size !== 0)
|
if (gameSession.unreadyPlayersMap.size !== 0)
|
||||||
@@ -158,7 +230,7 @@ function matchmaking(player: ClientPlayer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function playerReadyConfirmationListener(this: WebSocket, data: string)
|
async function playerReadyConfirmationListener(this: WebSocket, data: string)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
const msg : ev.ClientEvent = JSON.parse(data);
|
const msg : ev.ClientEvent = JSON.parse(data);
|
||||||
@@ -167,7 +239,34 @@ function playerReadyConfirmationListener(this: WebSocket, data: string)
|
|||||||
const client = clientsMap.get(this.id);
|
const client = clientsMap.get(this.id);
|
||||||
const gameSession = client.gameSession;
|
const gameSession = client.gameSession;
|
||||||
gameSession.unreadyPlayersMap.delete(this.id);
|
gameSession.unreadyPlayersMap.delete(this.id);
|
||||||
if (gameSession.unreadyPlayersMap.size === 0) {
|
if (gameSession.unreadyPlayersMap.size === 0)
|
||||||
|
{
|
||||||
|
// WIP nest , send gameSession.id
|
||||||
|
const gameSessionPlayersIterator = gameSession.playersMap.values();
|
||||||
|
const response = await fetch(c.addressBackEnd + "/game/newGameSession",
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
id: gameSession.id,
|
||||||
|
gameOptions: gameSession.matchOptions,
|
||||||
|
playerOneUsername: (<ClientPlayer>gameSessionPlayersIterator.next().value).username,
|
||||||
|
playerTwoUsername: (<ClientPlayer>gameSessionPlayersIterator.next().value).username,
|
||||||
|
})
|
||||||
|
});
|
||||||
|
if (!response.ok)
|
||||||
|
{
|
||||||
|
gameSessionsMap.delete(gameSession.id);
|
||||||
|
gameSession.playersMap.forEach((client) => {
|
||||||
|
client.socket.send(JSON.stringify( new ev.ServerEvent(en.EventTypes.matchAbort) ));
|
||||||
|
client.gameSession = null;
|
||||||
|
clientTerminate(client);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
gameSession.playersMap.forEach( (client) => {
|
gameSession.playersMap.forEach( (client) => {
|
||||||
client.socket.send(JSON.stringify( new ev.ServerEvent(en.EventTypes.matchStart) ));
|
client.socket.send(JSON.stringify( new ev.ServerEvent(en.EventTypes.matchStart) ));
|
||||||
});
|
});
|
||||||
@@ -227,7 +326,8 @@ const pingInterval = setInterval( () => {
|
|||||||
}
|
}
|
||||||
console.log("gameSessionMap size: " + gameSessionsMap.size);
|
console.log("gameSessionMap size: " + gameSessionsMap.size);
|
||||||
console.log("clientsMap size: " + clientsMap.size);
|
console.log("clientsMap size: " + clientsMap.size);
|
||||||
console.log("matchmakingPlayersMap size: " + matchmakingPlayersMap.size);
|
console.log("matchmakingMap size: " + matchmakingMap.size);
|
||||||
|
console.log("privateMatchmakingMap size: " + privateMatchmakingMap.size);
|
||||||
console.log("");
|
console.log("");
|
||||||
}, 4200);
|
}, 4200);
|
||||||
|
|
||||||
@@ -247,8 +347,11 @@ function clientTerminate(client: Client)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
clientsMap.delete(client.id);
|
clientsMap.delete(client.id);
|
||||||
if (matchmakingPlayersMap.has(client.id)) {
|
if (matchmakingMap.has(client.id)) {
|
||||||
matchmakingPlayersMap.delete(client.id);
|
matchmakingMap.delete(client.id);
|
||||||
|
}
|
||||||
|
else if (privateMatchmakingMap.has(client.id)) {
|
||||||
|
privateMatchmakingMap.delete(client.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -89,12 +89,21 @@ export class ClientAnnounce extends ClientEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class ClientAnnouncePlayer extends ClientAnnounce {
|
export class ClientAnnouncePlayer extends ClientAnnounce {
|
||||||
clientId: string;
|
clientId: string; // unused
|
||||||
matchOptions: en.MatchOptions;
|
matchOptions: en.MatchOptions;
|
||||||
constructor(matchOptions: en.MatchOptions, clientId: string = "") {
|
token: string;
|
||||||
|
username: string;
|
||||||
|
privateMatch: boolean;
|
||||||
|
playerTwoUsername?: string;
|
||||||
|
constructor(matchOptions: en.MatchOptions, token: string, username: string, privateMatch: boolean = false, playerTwoUsername?: string) {
|
||||||
super(en.ClientRole.player);
|
super(en.ClientRole.player);
|
||||||
this.clientId = clientId;
|
|
||||||
this.matchOptions = matchOptions;
|
this.matchOptions = matchOptions;
|
||||||
|
this.token = token;
|
||||||
|
this.username = username;
|
||||||
|
this.privateMatch = privateMatch;
|
||||||
|
if (playerTwoUsername) {
|
||||||
|
this.playerTwoUsername = playerTwoUsername;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
import { Vector, VectorInteger } from "./Vector.js";
|
import { Vector, VectorInteger } from "./Vector.js";
|
||||||
import { Component, Moving } from "./interface.js";
|
import type { Component, Moving } from "./interface.js";
|
||||||
import * as c from "../constants.js"
|
import * as c from "../constants.js"
|
||||||
|
|
||||||
export class Rectangle implements Component {
|
export class Rectangle implements Component {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
import { Vector, VectorInteger } from "./Vector.js";
|
import type { Vector, VectorInteger } from "./Vector.js";
|
||||||
|
|
||||||
export interface Component {
|
export interface Component {
|
||||||
pos: VectorInteger;
|
pos: VectorInteger;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
import { MovingRectangle } from "./class/Rectangle.js";
|
import type { MovingRectangle } from "./class/Rectangle.js";
|
||||||
|
|
||||||
export function random(min: number = 0, max: number = 1) {
|
export function random(min: number = 0, max: number = 1) {
|
||||||
return Math.random() * (max - min) + min;
|
return Math.random() * (max - min) + min;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
import * as c from "./constants.js";
|
import * as c from "./constants.js";
|
||||||
import { MovingRectangle } from "../shared_js/class/Rectangle.js";
|
import type { MovingRectangle } from "../shared_js/class/Rectangle.js";
|
||||||
import { GameComponents } from "./class/GameComponents.js";
|
import type { GameComponents } from "./class/GameComponents.js";
|
||||||
|
|
||||||
export function wallsMovements(delta: number, gc: GameComponents)
|
export function wallsMovements(delta: number, gc: GameComponents)
|
||||||
{
|
{
|
||||||
|
|||||||
BIN
srcs/requirements/svelte/api_front/public/favicon.ico
Normal file
BIN
srcs/requirements/svelte/api_front/public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 3.1 KiB |
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<title>Potato Pong</title>
|
<title>Potato Pong</title>
|
||||||
|
|
||||||
<link rel='icon' type='image/png' href='/favicon.png'>
|
<link rel='icon' type='image/x-icon' href='/favicon.ico'>
|
||||||
<link rel='stylesheet' href='/global.css'>
|
<link rel='stylesheet' href='/global.css'>
|
||||||
<link rel='stylesheet' href='/build/bundle.css'>
|
<link rel='stylesheet' href='/build/bundle.css'>
|
||||||
|
|
||||||
|
|||||||
@@ -34,11 +34,10 @@
|
|||||||
let token = "";
|
let token = "";
|
||||||
|
|
||||||
//Game's stuff gameserver side
|
//Game's stuff gameserver side
|
||||||
let sound = false;
|
let sound = "on"; // possible de faire un boolean avec svelte et radio buttons ?
|
||||||
let multi_balls = false;
|
let multi_balls = false;
|
||||||
let moving_walls = false;
|
let moving_walls = false;
|
||||||
let matchOption : enumeration.MatchOptions = enumeration.MatchOptions.noOption;
|
let matchOptions : enumeration.MatchOptions = enumeration.MatchOptions.noOption;
|
||||||
|
|
||||||
//html boolean for pages
|
//html boolean for pages
|
||||||
let showWaitPage = false;
|
let showWaitPage = false;
|
||||||
let showInvitations = false;
|
let showInvitations = false;
|
||||||
@@ -61,72 +60,18 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
const init = async() => {
|
const init = async() => {
|
||||||
optionsAreNotSet = false
|
|
||||||
showWaitPage = true
|
|
||||||
console.log("Player two username " + playerTwoUsername)
|
|
||||||
if (multi_balls === true)
|
if (multi_balls === true)
|
||||||
matchOption |= enumeration.MatchOptions.multiBalls
|
matchOption |= enumeration.MatchOptions.multiBalls
|
||||||
if (moving_walls === true )
|
if (moving_walls === true )
|
||||||
matchOption |= enumeration.MatchOptions.movingWalls
|
matchOption |= enumeration.MatchOptions.movingWalls
|
||||||
const res = await fetch("http://transcendance:8080/api/v2/game/ticket", {
|
|
||||||
method : "POST",
|
|
||||||
headers : {'Content-Type': 'application/json'},
|
|
||||||
body : JSON.stringify({
|
|
||||||
playerOneUsername : user.username,
|
|
||||||
playerTwoUsername : playerTwoUsername,
|
|
||||||
gameOptions : matchOption,
|
|
||||||
isGameIsWithInvitation : invite_someone
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.then(x => x.json())
|
|
||||||
.catch(error => {
|
|
||||||
console.log(error)
|
|
||||||
})
|
|
||||||
if (res.status === 403 || res.status === 404 || res.status === 500)
|
|
||||||
{
|
|
||||||
errorMessageWhenAttemptingToGetATicket = res.message;
|
|
||||||
showError = true;
|
|
||||||
setTimeout(() => {
|
|
||||||
showError = false;
|
|
||||||
showWaitPage = false
|
|
||||||
optionsAreNotSet = true
|
|
||||||
playerTwoUsername = "";
|
|
||||||
matchOption = 0;
|
|
||||||
token = ""
|
|
||||||
}, 5000)
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
else if (res.status === 200)
|
|
||||||
{
|
|
||||||
initAudio(sound)
|
initAudio(sound)
|
||||||
initMatchOptions(matchOption)
|
initMatchOptions(matchOption)
|
||||||
|
optionsAreNotSet = false
|
||||||
initPong(new GameArea())
|
initPong(new GameArea())
|
||||||
initGc(new GameComponentsClient(matchOption, pong.ctx))
|
initGc(new GameComponentsClient(matchOption, pong.ctx))
|
||||||
initStartFunction(start)
|
initStartFunction(start)
|
||||||
initWebSocket(matchOption)
|
initWebSocket(matchOption)
|
||||||
}
|
}
|
||||||
// const fetch = await fetch("http://transcendance:8080/api/v2/game/gameServer/validate", {
|
|
||||||
// method : "POST",
|
|
||||||
// headers : {'Content-Type': 'application/json'},
|
|
||||||
// body : JSON.stringify({
|
|
||||||
// playerOneUsername : user.username,
|
|
||||||
// playerTwoUsername : playerTwoUsername,
|
|
||||||
// gameOptions : matchOption,
|
|
||||||
// isGameIsWithInvitation : invite_someone,
|
|
||||||
// token : token
|
|
||||||
// })
|
|
||||||
// })
|
|
||||||
// .then(x => x.json())
|
|
||||||
// .catch(error => {
|
|
||||||
// console.log(error)
|
|
||||||
// })
|
|
||||||
// if (res.status !== 200)
|
|
||||||
// {
|
|
||||||
// showError = true;
|
|
||||||
// errorMessageWhenAttemptingToGetATicket = "Your session is not valid. Please try again."
|
|
||||||
// return ;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
function start() : void {
|
function start() : void {
|
||||||
gc.text1.pos.assign(constants.w*0.5, constants.h*0.75);
|
gc.text1.pos.assign(constants.w*0.5, constants.h*0.75);
|
||||||
@@ -188,30 +133,9 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="preload_font">.</div>
|
<div id="preload_font">.</div>
|
||||||
{#if showError === true}
|
|
||||||
<div id="div_game">
|
|
||||||
<fieldset>
|
|
||||||
<legend>Error</legend>
|
|
||||||
<p>{errorMessageWhenAttemptingToGetATicket}</p>
|
|
||||||
<button id="pong_button" on:click={() => push('/game')}>Retry</button>
|
|
||||||
</fieldset>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{#if showWaitPage === true}
|
|
||||||
<div id="div_game">
|
|
||||||
<fieldset>
|
|
||||||
<legend>Connecting to the game...</legend>
|
|
||||||
<p>{waitingMessage}</p>
|
|
||||||
</fieldset>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{#if optionsAreNotSet}
|
{#if optionsAreNotSet}
|
||||||
{#if showGameOption === true}
|
|
||||||
<form on:submit|preventDefault={init}>
|
<form on:submit|preventDefault={init}>
|
||||||
<div id="div_game">
|
<div id="div_game_options">
|
||||||
<button id="pong_button" on:click={showInvitation}>Show invitations</button>
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>game options</legend>
|
<legend>game options</legend>
|
||||||
<div>
|
<div>
|
||||||
@@ -227,44 +151,17 @@
|
|||||||
<label for="moving_walls">Sound</label>
|
<label for="moving_walls">Sound</label>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<input type="checkbox" id="invite_someone" name="moving_walls" bind:checked={invite_someone}>
|
<button id="play_pong_button" >PLAY</button>
|
||||||
<label for="moving_walls">Invite a friend</label>
|
|
||||||
</div>
|
|
||||||
{#if invite_someone === true}
|
|
||||||
<select bind:value={playerTwoUsername}>
|
|
||||||
{#each allUsers as user }
|
|
||||||
<option value={user.username}>{user.username}</option>
|
|
||||||
{/each}
|
|
||||||
</select>
|
|
||||||
{/if}
|
|
||||||
<div>
|
|
||||||
<button id="pong_button" >PLAY</button>
|
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
{/if}
|
<div id="div_game_instructions">
|
||||||
{#if showInvitations}
|
<h2>--- keys ---</h2>
|
||||||
<div id="div_game">
|
<p>move up: 'w' or 'up arrow'</p>
|
||||||
<button id="pong_button" on:click={showOptions}>Play a Game</button>
|
<p>move down: 's' OR 'down arrow'</p>
|
||||||
<fieldset>
|
<p>grid on/off: 'g'</p>
|
||||||
<legend>Current invitation(s)</legend>
|
|
||||||
{#if isThereAnyInvitation}
|
|
||||||
{#each invitations as invitation }
|
|
||||||
<div>
|
|
||||||
{invitation.playerOneUsername} has invited you to play a pong !
|
|
||||||
<button id="pong_button" on:click={acceptInvitation}>V</button>
|
|
||||||
<button id="pong_button" on:click={rejectInvitation}>X</button>
|
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
|
||||||
{/if}
|
|
||||||
{#if isThereAnyInvitation ===false}
|
|
||||||
<p>Currently, no one asked to play with you.</p>
|
|
||||||
<button id="pong_button" on:click={showInvitation}>Reload</button>
|
|
||||||
{/if}
|
|
||||||
</fieldset>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div id="canvas_container">
|
<div id="canvas_container">
|
||||||
@@ -276,29 +173,26 @@
|
|||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Bit5x3";
|
font-family: "Bit5x3";
|
||||||
src: url("/fonts/Bit5x3.woff2") format("woff2"),local("Bit5x3"), url("/fonts/Bit5x3.woff") format("woff");
|
src:
|
||||||
|
url("/fonts/Bit5x3.woff2") format("woff2"),
|
||||||
|
local("Bit5x3"),
|
||||||
|
url("/fonts/Bit5x3.woff") format("woff");
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
}
|
}
|
||||||
#preload_font {
|
|
||||||
font-family: "Bit5x3";
|
|
||||||
opacity:0;
|
|
||||||
height:0;
|
|
||||||
width:0;
|
|
||||||
display:inline-block;
|
|
||||||
}
|
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
background-color: #222425;
|
background-color: #222425;
|
||||||
}
|
}
|
||||||
#canvas_container {
|
#canvas_container {
|
||||||
|
margin-top: 20px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
/* border: dashed rgb(245, 245, 245) 5px; */
|
/* border: dashed rgb(245, 245, 245) 5px; */
|
||||||
/* max-height: 80vh; */
|
/* max-height: 80vh; */
|
||||||
/* overflow: hidden; */
|
/* overflow: hidden; */
|
||||||
}
|
}
|
||||||
#div_game {
|
#div_game_options {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-family: "Bit5x3";
|
font-family: "Bit5x3";
|
||||||
color: rgb(245, 245, 245);
|
color: rgb(245, 245, 245);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { Vector, VectorInteger } from "../../shared_js/class/Vector.js";
|
|||||||
import { TextElem, TextNumericValue } from "./Text.js";
|
import { TextElem, TextNumericValue } from "./Text.js";
|
||||||
import { RectangleClient, MovingRectangleClient, RacketClient, BallClient, Line } from "./RectangleClient.js";
|
import { RectangleClient, MovingRectangleClient, RacketClient, BallClient, Line } from "./RectangleClient.js";
|
||||||
import { GameComponents } from "../../shared_js/class/GameComponents.js";
|
import { GameComponents } from "../../shared_js/class/GameComponents.js";
|
||||||
import { MovingRectangle } from "../../shared_js/class/Rectangle.js";
|
import type { MovingRectangle } from "../../shared_js/class/Rectangle.js";
|
||||||
|
|
||||||
class GameComponentsExtensionForClient extends GameComponents {
|
class GameComponentsExtensionForClient extends GameComponents {
|
||||||
wallTop: RectangleClient | MovingRectangleClient;
|
wallTop: RectangleClient | MovingRectangleClient;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
import * as en from "../../shared_js/enums.js"
|
import type * as en from "../../shared_js/enums.js"
|
||||||
import * as ev from "../../shared_js/class/Event.js"
|
import type * as ev from "../../shared_js/class/Event.js"
|
||||||
|
|
||||||
export class InputHistory {
|
export class InputHistory {
|
||||||
input: en.InputEnum;
|
input: en.InputEnum;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
import { Vector, VectorInteger } from "../../shared_js/class/Vector.js";
|
import { Vector, VectorInteger } from "../../shared_js/class/Vector.js";
|
||||||
import { Component, GraphicComponent, Moving } from "../../shared_js/class/interface.js";
|
import type { GraphicComponent } from "../../shared_js/class/interface.js";
|
||||||
import { Rectangle, MovingRectangle, Racket, Ball } from "../../shared_js/class/Rectangle.js";
|
import { Rectangle, MovingRectangle, Racket, Ball } from "../../shared_js/class/Rectangle.js";
|
||||||
import { soundPongArr } from "../audio.js"
|
import { soundPongArr } from "../audio.js"
|
||||||
import { random } from "../utils.js";
|
import { random } from "../utils.js";
|
||||||
@@ -81,7 +81,9 @@ export class BallClient extends Ball implements GraphicComponent {
|
|||||||
}
|
}
|
||||||
bounce(collider?: Rectangle) {
|
bounce(collider?: Rectangle) {
|
||||||
this._bounceAlgo(collider);
|
this._bounceAlgo(collider);
|
||||||
soundPongArr[ Math.floor(random(0, soundPongArr.length)) ].play();
|
let i = Math.floor(random(0, soundPongArr.length));
|
||||||
|
soundPongArr[ i ].play();
|
||||||
|
console.log(`sound_i=${i}`); // debug log
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
import { Vector, VectorInteger } from "../../shared_js/class/Vector.js";
|
import { Vector, VectorInteger } from "../../shared_js/class/Vector.js";
|
||||||
import { Component } from "../../shared_js/class/interface.js";
|
import type { Component } from "../../shared_js/class/interface.js";
|
||||||
|
|
||||||
// conflict with Text
|
// conflict with Text
|
||||||
export class TextElem implements Component {
|
export class TextElem implements Component {
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import * as c from "./constants.js";
|
|||||||
import * as en from "../shared_js/enums.js"
|
import * as en from "../shared_js/enums.js"
|
||||||
import { gc, matchOptions, clientInfo, clientInfoSpectator} from "./global.js";
|
import { gc, matchOptions, clientInfo, clientInfoSpectator} from "./global.js";
|
||||||
import { wallsMovements } from "../shared_js/wallsMovement.js";
|
import { wallsMovements } from "../shared_js/wallsMovement.js";
|
||||||
import { RacketClient } from "./class/RectangleClient.js";
|
import type { RacketClient } from "./class/RectangleClient.js";
|
||||||
import { VectorInteger } from "../shared_js/class/Vector.js";
|
import type { VectorInteger } from "../shared_js/class/Vector.js";
|
||||||
|
|
||||||
let actual_time: number = Date.now();
|
let actual_time: number = Date.now();
|
||||||
let last_time: number;
|
let last_time: number;
|
||||||
|
|||||||
@@ -30,11 +30,17 @@ export let socket: WebSocket; /* TODO: A way to still use "const" not "let" ? */
|
|||||||
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
|
||||||
|
|
||||||
export function initWebSocket(options: en.MatchOptions)
|
|
||||||
|
export function initWebSocket(options: en.MatchOptions, token: string, username: string, privateMatch = false, playerTwoUsername?: string)
|
||||||
{
|
{
|
||||||
socket = new WebSocket(wsUrl, "json");
|
socket = new WebSocket(wsUrl, "json");
|
||||||
socket.addEventListener("open", (event) => {
|
socket.addEventListener("open", (event) => {
|
||||||
socket.send(JSON.stringify( new ev.ClientAnnouncePlayer(options, clientInfo.id) ));
|
if (privateMatch) {
|
||||||
|
socket.send(JSON.stringify( new ev.ClientAnnouncePlayer(options, token, username, privateMatch, playerTwoUsername) ));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
socket.send(JSON.stringify( new ev.ClientAnnouncePlayer(options, token, username) ));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
// socket.addEventListener("message", logListener); // for testing purpose
|
// socket.addEventListener("message", logListener); // for testing purpose
|
||||||
socket.addEventListener("message", preMatchListener);
|
socket.addEventListener("message", preMatchListener);
|
||||||
|
|||||||
@@ -89,12 +89,21 @@ export class ClientAnnounce extends ClientEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class ClientAnnouncePlayer extends ClientAnnounce {
|
export class ClientAnnouncePlayer extends ClientAnnounce {
|
||||||
clientId: string;
|
clientId: string; // unused
|
||||||
matchOptions: en.MatchOptions;
|
matchOptions: en.MatchOptions;
|
||||||
constructor(matchOptions: en.MatchOptions, clientId: string = "") {
|
token: string;
|
||||||
|
username: string;
|
||||||
|
privateMatch: boolean;
|
||||||
|
playerTwoUsername?: string;
|
||||||
|
constructor(matchOptions: en.MatchOptions, token: string, username: string, privateMatch: boolean = false, playerTwoUsername?: string) {
|
||||||
super(en.ClientRole.player);
|
super(en.ClientRole.player);
|
||||||
this.clientId = clientId;
|
|
||||||
this.matchOptions = matchOptions;
|
this.matchOptions = matchOptions;
|
||||||
|
this.token = token;
|
||||||
|
this.username = username;
|
||||||
|
this.privateMatch = privateMatch;
|
||||||
|
if (playerTwoUsername) {
|
||||||
|
this.playerTwoUsername = playerTwoUsername;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
import { Vector, VectorInteger } from "./Vector.js";
|
import { Vector, VectorInteger } from "./Vector.js";
|
||||||
import { Component, Moving } from "./interface.js";
|
import type { Component, Moving } from "./interface.js";
|
||||||
import * as c from "../constants.js"
|
import * as c from "../constants.js"
|
||||||
|
|
||||||
export class Rectangle implements Component {
|
export class Rectangle implements Component {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
import { Vector, VectorInteger } from "./Vector.js";
|
import type { Vector, VectorInteger } from "./Vector.js";
|
||||||
|
|
||||||
export interface Component {
|
export interface Component {
|
||||||
pos: VectorInteger;
|
pos: VectorInteger;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
import { MovingRectangle } from "./class/Rectangle.js";
|
import type { MovingRectangle } from "./class/Rectangle.js";
|
||||||
|
|
||||||
export function random(min: number = 0, max: number = 1) {
|
export function random(min: number = 0, max: number = 1) {
|
||||||
return Math.random() * (max - min) + min;
|
return Math.random() * (max - min) + min;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
import * as c from "./constants.js";
|
import * as c from "./constants.js";
|
||||||
import { MovingRectangle } from "../shared_js/class/Rectangle.js";
|
import type { MovingRectangle } from "../shared_js/class/Rectangle.js";
|
||||||
import { GameComponents } from "./class/GameComponents.js";
|
import type { GameComponents } from "./class/GameComponents.js";
|
||||||
|
|
||||||
export function wallsMovements(delta: number, gc: GameComponents)
|
export function wallsMovements(delta: number, gc: GameComponents)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user