|
|
|
|
@@ -18,6 +18,7 @@ const wsPort = 8042;
|
|
|
|
|
export const wsServer = new WebSocketServer<WebSocket>({port: wsPort, path: "/pong"});
|
|
|
|
|
|
|
|
|
|
const clientsMap: Map<string, Client> = new Map; // socket.id/Client
|
|
|
|
|
const matchmakingPlayersMap: Map<string, ClientPlayer> = new Map; // socket.id/ClientPlayer (duplicates with clientsMap)
|
|
|
|
|
const gameSessionsMap: Map<string, GameSession> = new Map; // GameSession.id(url)/GameSession
|
|
|
|
|
|
|
|
|
|
wsServer.on("connection", connectionListener);
|
|
|
|
|
@@ -38,6 +39,13 @@ function connectionListener(socket: WebSocket, request: IncomingMessage)
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
socket.on("message", function log(data: string) {
|
|
|
|
|
try {
|
|
|
|
|
const event: ev.ClientEvent = JSON.parse(data);
|
|
|
|
|
if (event.type === en.EventTypes.clientInput) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (e) {}
|
|
|
|
|
console.log("data: " + data);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
@@ -50,8 +58,8 @@ function clientAnnounceListener(this: WebSocket, data: string)
|
|
|
|
|
try {
|
|
|
|
|
const msg : ev.ClientAnnounce = JSON.parse(data);
|
|
|
|
|
if (msg.type === en.EventTypes.clientAnnounce) {
|
|
|
|
|
// TODO: reconnection with msg.id
|
|
|
|
|
// TODO: spectator/player distinction with msg.type
|
|
|
|
|
// TODO: reconnection with msg.id ?
|
|
|
|
|
// TODO: spectator/player distinction with msg.type ?
|
|
|
|
|
|
|
|
|
|
this.send(JSON.stringify( new ev.EventAssignId(this.id) ))
|
|
|
|
|
this.send(JSON.stringify( new ev.ServerEvent(en.EventTypes.matchmakingInProgress) ))
|
|
|
|
|
@@ -63,7 +71,7 @@ function clientAnnounceListener(this: WebSocket, data: string)
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
catch (e) {
|
|
|
|
|
console.log("Invalid JSON");
|
|
|
|
|
console.log("Invalid JSON (clientAnnounceListener)");
|
|
|
|
|
}
|
|
|
|
|
this.once("message", clientAnnounceListener);
|
|
|
|
|
}
|
|
|
|
|
@@ -71,25 +79,41 @@ function clientAnnounceListener(this: WebSocket, data: string)
|
|
|
|
|
|
|
|
|
|
function matchmaking(socket: WebSocket)
|
|
|
|
|
{
|
|
|
|
|
// TODO Actual Matchmaking
|
|
|
|
|
|
|
|
|
|
// TODO: Only once
|
|
|
|
|
const id = uuidv4();
|
|
|
|
|
const gameSession = new GameSession(id);
|
|
|
|
|
gameSessionsMap.set(id, gameSession);
|
|
|
|
|
|
|
|
|
|
// TODO: Per player
|
|
|
|
|
const player: ClientPlayer = clientsMap.get(socket.id) as ClientPlayer;
|
|
|
|
|
player.gameSession = gameSession;
|
|
|
|
|
gameSession.playersMap.set(socket.id, player);
|
|
|
|
|
gameSession.unreadyPlayersMap.set(socket.id, player);
|
|
|
|
|
if (matchmakingPlayersMap.size < 1)
|
|
|
|
|
{
|
|
|
|
|
matchmakingPlayersMap.set(socket.id, player);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
const id = uuidv4();
|
|
|
|
|
const gameSession = new GameSession(id);
|
|
|
|
|
gameSessionsMap.set(id, gameSession);
|
|
|
|
|
|
|
|
|
|
player.racket = gameSession.components.playerLeft;
|
|
|
|
|
socket.send(JSON.stringify( new ev.EventMatchmakingComplete(en.PlayerSide.left) ));
|
|
|
|
|
// for player
|
|
|
|
|
gameSession.playersMap.set(player.id, player);
|
|
|
|
|
player.racket = gameSession.components.playerRight;
|
|
|
|
|
socket.send(JSON.stringify( new ev.EventMatchmakingComplete(en.PlayerSide.right) ));
|
|
|
|
|
|
|
|
|
|
// for opponent
|
|
|
|
|
const opponent: ClientPlayer = matchmakingPlayersMap.values().next().value;
|
|
|
|
|
gameSession.playersMap.set(opponent.id, opponent);
|
|
|
|
|
matchmakingPlayersMap.delete(opponent.id);
|
|
|
|
|
opponent.racket = gameSession.components.playerLeft;
|
|
|
|
|
opponent.socket.send(JSON.stringify( new ev.EventMatchmakingComplete(en.PlayerSide.left) ));
|
|
|
|
|
|
|
|
|
|
socket.once("message", playerReadyConfirmationListener);
|
|
|
|
|
|
|
|
|
|
// for both
|
|
|
|
|
gameSession.playersMap.forEach( (client) => {
|
|
|
|
|
gameSession.unreadyPlayersMap.set(client.id, client);
|
|
|
|
|
client.gameSession = gameSession;
|
|
|
|
|
});
|
|
|
|
|
gameSession.playersMap.forEach( (client) => {
|
|
|
|
|
/* set listener last to be absolutly sure there no early game launch
|
|
|
|
|
(unlikely, but theoretically possible) */
|
|
|
|
|
client.socket.once("message", playerReadyConfirmationListener);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -109,12 +133,12 @@ function playerReadyConfirmationListener(this: WebSocket, data: string)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
console.log("Invalid PlayerReady confirmation");
|
|
|
|
|
console.log("Invalid playerReadyConfirmation");
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
catch (e) {
|
|
|
|
|
console.log("Invalid JSON");
|
|
|
|
|
console.log("Invalid JSON (playerReadyConfirmationListener)");
|
|
|
|
|
}
|
|
|
|
|
this.once("message", playerReadyConfirmationListener);
|
|
|
|
|
}
|
|
|
|
|
@@ -130,11 +154,11 @@ export function clientInputListener(this: WebSocket, data: string)
|
|
|
|
|
client.gameSession.handleInput(client as ClientPlayer, input.input);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
console.log("Invalid EventInput");
|
|
|
|
|
console.log("Invalid clientInput");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (e) {
|
|
|
|
|
console.log("Invalid JSON");
|
|
|
|
|
console.log("Invalid JSON (clientInputListener)");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -146,6 +170,9 @@ const pingInterval = setInterval( () => {
|
|
|
|
|
if (client.isAlive === false) {
|
|
|
|
|
client.socket.terminate();
|
|
|
|
|
map.delete(key);
|
|
|
|
|
if (matchmakingPlayersMap.has(key)) {
|
|
|
|
|
matchmakingPlayersMap.delete(key);
|
|
|
|
|
}
|
|
|
|
|
console.log("%i: client %s is no more :'(", Date.now(), key);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|