/* * Copyright (C) 2021 Thomas Van Acker * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * this program. If not, see . * * This project is hosted on https://git.bitscuit.be/bitscuit/BoxEscape * */ // Imports const http = require("http"); const url = require("url"); const fs = require("fs"); const util = require("util"); // Vars const hostname = "192.168.0.128"; const port = 3000; const STATE_LOBBY = 0; const STATE_GAME = 1; var state = STATE_LOBBY; var userSockets = []; var userNames = []; var userOK = []; const BOX_TYPE_TIP = 0; const BOX_TYPE_KEY = 1; const BOX_TYPE_BOMB = 2; var boxes = []; // 2D array with box objects var currentUserID = -1; var guardID = 0; // Create HTTP server const server = http.createServer((req, res) => { // Parse url const requrl = url.parse(req.url); var reqpath = requrl.pathname; if(reqpath == "/") reqpath = "/index.html"; // Respond to requests try{ // Return requested page res.statusCode = 200; res.write(fs.readFileSync("html"+reqpath)); res.end(); }catch(error){ // 404 if page not found res.statusCode = 404; res.setHeader("Content-Type", "text/plain"); res.end("404 - Page Not Found"); } }); // Create socket.io server const io = require("socket.io")(server); // Can only be done when server is created io.on("connection", (socket) => { console.log("New user connected!"); // Init socket listeners // Disconnect socket.on("disconnect", () => { console.log("User disconnected!"); // Remove from user lists if(userSockets.indexOf(socket) != -1){ // When in users list name = userNames[userSockets.indexOf(socket)]; userNames.splice(userSockets.indexOf(socket), 1); userSockets.splice(userSockets.indexOf(socket), 1); if(state == STATE_LOBBY){ // Send new lobby userSockets.forEach(function(s){s.emit("LOBBY", userNames);}); }else{ // Send disconnect message userSockets.forEach(function(s){s.emit("DISCONNECT", name);}); } } }); // JOIN socket.on("JOIN", (username) => { console.log("JOIN request for "+username); // Check if can enter in lobby if(state == STATE_LOBBY){ // Add user to lists userSockets.push(socket); userNames.push(username); console.log(userNames); // Send lobby data userSockets.forEach(function(s){s.emit("LOBBY", userNames);}); }else{ // When can't enter socket.emit("LOBBY_CLOSED"); } }); // START socket.on("START", () => { console.log("START request"); // Send LAODING to all users userSockets.forEach(function(s){s.emit("LOADING");}); // Set state state = STATE_GAME; // Create game boxes = []; var usedCodes = []; for(y=0; y<6; y++){ boxes[y] = []; for(x=0; x<6; x++){ var code; do{ code = rand(10, 100); }while(usedCodes.indexOf(code) != -1); usedCodes.push(code); boxes[y][x] = {type:BOX_TYPE_TIP, code:code, tip:""}; } } // Pick random boxes for key var keyX = rand(0, 6); var keyY = rand(0, 6); var keyCode = boxes[keyY][keyX].code; boxes[keyY][keyX].type = BOX_TYPE_KEY; boxes[keyY][keyX].tip = "This is the key"; // Pick random boxes for bombs var nrBombs = 4; var bombXs = []; var bombYs = []; for(i=0; i a) t += "bigger than"; else if(keyCode < a) t += "less than"; else t += "equal to"; t += " "+a; tips.push(t); } // Key code odd or even tips.push("The key in the box with an "+(keyCode%2 == 0 ? "even" : "odd")+" number"); // Key not in same column as for(i=0; i<6; i++){ var c; do{ c = rand(0, 6); }while(c == keyX); var r = rand(0, 6); tips.push("The key is not in the same column as "+boxes[r][c].code); } // Key not in same row as for(i=0; i<6; i++){ var r; do{ r = rand(0, 6); }while(r == keyY); var c = rand(0, 6); tips.push("The key is not in the same row as "+boxes[r][c].code); } // Key not neighbour of for(i=0; i<6; i++){ var x; var y; do{ x = rand(0, 6); y = rand(0, 6); }while(Math.abs(keyX - x) <= 1 && Math.abs(keyY - y) <= 1); tips.push("The box with the key is not next to "+boxes[y][x].code); } // Player is not guard for(i=0; i { // Set OK for this player userOK[userSockets.indexOf(socket)] = true; // Check if everybody OK var OK = true; for(i=0; i { // When player picked box if(currentUserID != userSockets.indexOf(socket)) return; // Get box type var type = null; var x; var y; for(i=0; i<6; i++){ for(j=0; j<6; j++){ if(boxes[i][j].code == code){ type = boxes[i][j].type; x = j; y = i; break; } } if(type != null) break; } // Check type if(type == BOX_TYPE_TIP || guardID == currentUserID){ // Return tip to user var tip = boxes[y][x].tip; var data = {myTurn:false, currentUser:userNames[currentUserID], tip:""}; for(i=0; i { // When player pressed OK after tip if(currentUserID != userSockets.indexOf(socket)) return; // Next player nextPlayer(); }); }); // Start HTTP server server.listen(port, hostname, () => { console.log("Server running at http://"+hostname+":"+port); }); // Game methods function nextPlayer(){ // Increment currentPlayerID currentUserID = (currentUserID+1)%userSockets.length; console.log("Next player = "+currentUserID+" ("+userNames[currentUserID]+")"); // Show board to every player and listen for one to pick a box var board = []; for(y=0; y<6; y++){ board[y] = []; for(x=0; x<6; x++){ board[y][x] = {type:boxes[y][x].type, code:boxes[y][x].code}; } } var userData = {myTurn:false, board:board, currentUser:userNames[currentUserID]}; // Send userData for(i=0; i