Some checks failed
Publish Docker image / Push Docker image to Docker Hub (push) Has been cancelled
226 lines
6.7 KiB
JavaScript
226 lines
6.7 KiB
JavaScript
const express = require("express");
|
|
const app = express();
|
|
const httpServer = require("http").createServer(app);
|
|
const path = require('path');
|
|
|
|
const io = require("socket.io")(httpServer, {cors: {origin: "*", connectionStateRecovery: {
|
|
maxDisconnectionDuration: 60000}}});
|
|
|
|
|
|
app.use(express.static(path.join(__dirname, './dist')));
|
|
|
|
app.get('*', (req, res) => res.sendFile(path.join(__dirname, './dist', 'index.html')));
|
|
|
|
const rooms = {};
|
|
|
|
/**
|
|
* Validates the provided input to create a room
|
|
* @param data The required data
|
|
* @param callback The callback
|
|
* @returns {boolean} true if the provided input is valid, false otherwise
|
|
*/
|
|
const validateInput = (data, callback) => {
|
|
if (Object.keys(data).length !== 5 && data.startCapital && data.costPerRound && data.costPerCake
|
|
&& data.maxProduction && data.maxPrice) {
|
|
callback(false);
|
|
return false;
|
|
}
|
|
|
|
try {
|
|
[data.startCapital, data.costPerRound, data.costPerCake, data.maxProduction, data.maxPrice].forEach((value) => {
|
|
if (value === undefined) {
|
|
callback(false);
|
|
return false;
|
|
}
|
|
|
|
const valueInt = parseInt(value);
|
|
if (isNaN(valueInt)) {
|
|
callback(false);
|
|
return false;
|
|
}
|
|
});
|
|
} catch (e) {
|
|
callback(false);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Generates a random room code.
|
|
* @returns {*|string} A random room code.
|
|
*/
|
|
const generateRoomCode = () => {
|
|
const code = Math.random().toString(36).substring(2, 6).toUpperCase();
|
|
return rooms[code] ? generateRoomCode() : code;
|
|
}
|
|
|
|
/**
|
|
* Returns the room code of the room the socket is in.
|
|
* @param socketId The socket id of the socket.
|
|
* @returns {string} The room code of the room the socket is in.
|
|
*/
|
|
const getRoomCodeBySocketId = (socketId) => {
|
|
return Object.keys(rooms).find((code) => rooms[code].host === socketId || rooms[code].players.some((player) => player.id === socketId));
|
|
}
|
|
|
|
/**
|
|
* Returns the name of the player with the given socket id in the given room.
|
|
* @param socketId The socket id of the player.
|
|
* @param roomCode The room code of the room the player is in.
|
|
* @returns {*|null} The name of the player with the given socket id in the given room.
|
|
*/
|
|
const getPlayerName = (socketId, roomCode) => {
|
|
const player = rooms[roomCode].players.find((player) => player.id === socketId);
|
|
return player ? player.name : null;
|
|
}
|
|
|
|
io.on("connection", (socket) => {
|
|
socket.on("CREATE_ROOM", (data, callback = () => {}) => {
|
|
if (getRoomCodeBySocketId(socket.id)) {
|
|
callback(false);
|
|
return;
|
|
}
|
|
|
|
if (Object.keys(rooms).length >= 100) {
|
|
callback(false);
|
|
return;
|
|
}
|
|
|
|
if (!validateInput(data, callback)) return;
|
|
|
|
const code = generateRoomCode();
|
|
rooms[code] = {host: socket.id, players: [], settings: data};
|
|
|
|
callback({code});
|
|
|
|
console.log(`Room ${code} created by ${socket.id}.`);
|
|
|
|
socket.join(code);
|
|
});
|
|
|
|
socket.on("JOIN_ROOM", (data, callback = () => {}) => {
|
|
if (getRoomCodeBySocketId(socket.id)) {
|
|
callback(false);
|
|
return;
|
|
}
|
|
|
|
const {code, name} = data;
|
|
|
|
if (!code || !name) {
|
|
callback(false);
|
|
return;
|
|
}
|
|
|
|
if (rooms[code]) {
|
|
socket.join(code);
|
|
rooms[code].players.push({id: socket.id, name});
|
|
io.to(rooms[code].host).emit("JOINED", {id: socket.id, name});
|
|
callback(true);
|
|
socket.emit("CAPITAL", {capital: rooms[code].settings.startCapital});
|
|
socket.emit("SETTINGS", rooms[code].settings);
|
|
} else {
|
|
callback(false);
|
|
}
|
|
});
|
|
|
|
socket.on("SUBMISSION_READY", (data, callback = () => {}) => {
|
|
const roomCode = getRoomCodeBySocketId(socket.id);
|
|
io.to(roomCode).emit("SUBMISSION_READY");
|
|
|
|
callback(true);
|
|
});
|
|
|
|
socket.on("SUBMIT", (data, callback = () => {}) => {
|
|
const {price, amount} = data;
|
|
const roomCode = getRoomCodeBySocketId(socket.id);
|
|
|
|
if (!roomCode) return;
|
|
|
|
if (price === undefined || amount === undefined) {
|
|
callback(false);
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const priceInt = parseInt(price);
|
|
const amountInt = parseInt(amount);
|
|
|
|
if (isNaN(priceInt) || isNaN(amountInt)) {
|
|
callback(false);
|
|
return;
|
|
}
|
|
|
|
if (priceInt.toString().indexOf(".") !== -1 || amountInt.toString().indexOf(".") !== -1
|
|
|| priceInt.toString().indexOf(",") !== -1 || amountInt.toString().indexOf(",") !== -1) {
|
|
callback(false);
|
|
return;
|
|
}
|
|
} catch (e) {
|
|
callback(false);
|
|
return;
|
|
}
|
|
|
|
if (price < 0 || price > rooms[roomCode].settings.maxPrice ||
|
|
amount < 0 || amount > rooms[roomCode].settings.maxProduction) {
|
|
callback(false);
|
|
return;
|
|
}
|
|
|
|
const playerName = getPlayerName(socket.id, roomCode);
|
|
|
|
io.to(rooms[roomCode].host).emit("RECEIVED", {id: socket.id, name: playerName, price, amount});
|
|
callback(true);
|
|
});
|
|
|
|
socket.on("UPDATE_CAPITAL", (data, callback = () => {}) => {
|
|
const {id, capital} = data;
|
|
|
|
if (rooms[getRoomCodeBySocketId(socket.id)].host !== socket.id) {
|
|
callback(false);
|
|
return;
|
|
}
|
|
|
|
if (!id || capital === undefined) {
|
|
callback(false);
|
|
return;
|
|
}
|
|
|
|
io.to(id).emit("CAPITAL", {capital});
|
|
|
|
let cost = rooms[getRoomCodeBySocketId(socket.id)].settings.costPerRound
|
|
+ rooms[getRoomCodeBySocketId(socket.id)].settings.costPerCake;
|
|
|
|
if (capital < cost) {
|
|
socket.emit("LEFT", {id: socket.id});
|
|
|
|
rooms[getRoomCodeBySocketId(socket.id)].players = rooms[getRoomCodeBySocketId(socket.id)].players
|
|
.filter((player) => player.id !== socket.id);
|
|
|
|
io.to(id).emit("GAME_OVER");
|
|
}
|
|
|
|
callback(true);
|
|
});
|
|
|
|
socket.conn.on("close", () => {
|
|
const roomCode = getRoomCodeBySocketId(socket.id);
|
|
|
|
if (!roomCode) return;
|
|
|
|
rooms[roomCode].players = rooms[roomCode].players.filter((player) => player.id !== socket.id);
|
|
if (rooms[roomCode].host === socket.id) {
|
|
for (const player of rooms[roomCode].players) io.sockets.sockets.get(player.id).disconnect();
|
|
|
|
delete rooms[roomCode];
|
|
} else {
|
|
io.to(rooms[roomCode].host).emit("LEFT", {id: socket.id});
|
|
}
|
|
|
|
});
|
|
});
|
|
|
|
httpServer.listen(3000, () => {
|
|
console.log("listening on *:3000");
|
|
}); |