├── .gitignore ├── README.md ├── package.json ├── app.js └── game-logic.js /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### This is the backend for my multiplayer chess game. 2 | 3 | Link to the frontend: [Frontend](https://github.com/ProjectsByJackHe/multiplayer-chess-game) -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chess-game-backend", 3 | "version": "1.0.0", 4 | "description": "Backend portion of my multi-player chess game", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "test", 8 | "start": "node app.js", 9 | "dev": "nodemon app.js" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/ProjectsByJackHe/multiplayer-chess-game-backend.git" 14 | }, 15 | "dependencies": { 16 | "express": "4.17.1", 17 | "socket.io": "2.3.0" 18 | }, 19 | "devDependencies": { 20 | "nodemon": "2.0.4" 21 | }, 22 | "author": "Jack He", 23 | "license": "MIT", 24 | "bugs": { 25 | "url": "https://github.com/ProjectsByJackHe/multiplayer-chess-game-backend/issues" 26 | }, 27 | "homepage": "https://github.com/ProjectsByJackHe/multiplayer-chess-game-backend#readme" 28 | } 29 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | const express = require('express') 2 | const http = require('http') 3 | const socketio = require('socket.io') 4 | const gameLogic = require('./game-logic') 5 | const app = express() 6 | 7 | /** 8 | * Backend flow: 9 | * - check to see if the game ID encoded in the URL belongs to a valid game session in progress. 10 | * - if yes, join the client to that game. 11 | * - else, create a new game instance. 12 | * - '/' path should lead to a new game instance. 13 | * - '/game/:gameid' path should first search for a game instance, then join it. Otherwise, throw 404 error. 14 | */ 15 | 16 | 17 | const server = http.createServer(app) 18 | const io = socketio(server) 19 | 20 | // get the gameID encoded in the URL. 21 | // check to see if that gameID matches with all the games currently in session. 22 | // join the existing game session. 23 | // create a new session. 24 | // run when client connects 25 | 26 | io.on('connection', client => { 27 | gameLogic.initializeGame(io, client) 28 | }) 29 | 30 | // usually this is where we try to connect to our DB. 31 | server.listen(process.env.PORT || 8000) -------------------------------------------------------------------------------- /game-logic.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | /** 4 | * Here is where we should register event listeners and emitters. 5 | */ 6 | 7 | var io 8 | var gameSocket 9 | // gamesInSession stores an array of all active socket connections 10 | var gamesInSession = [] 11 | 12 | 13 | const initializeGame = (sio, socket) => { 14 | /** 15 | * initializeGame sets up all the socket event listeners. 16 | */ 17 | 18 | // initialize global variables. 19 | io = sio 20 | gameSocket = socket 21 | 22 | // pushes this socket to an array which stores all the active sockets. 23 | gamesInSession.push(gameSocket) 24 | 25 | // Run code when the client disconnects from their socket session. 26 | gameSocket.on("disconnect", onDisconnect) 27 | 28 | // Sends new move to the other socket session in the same room. 29 | gameSocket.on("new move", newMove) 30 | 31 | // User creates new game room after clicking 'submit' on the frontend 32 | gameSocket.on("createNewGame", createNewGame) 33 | 34 | // User joins gameRoom after going to a URL with '/game/:gameId' 35 | gameSocket.on("playerJoinGame", playerJoinsGame) 36 | 37 | gameSocket.on('request username', requestUserName) 38 | 39 | gameSocket.on('recieved userName', recievedUserName) 40 | 41 | // register event listeners for video chat app: 42 | videoChatBackend() 43 | } 44 | 45 | 46 | function videoChatBackend() { 47 | // main function listeners 48 | gameSocket.on("callUser", (data) => { 49 | io.to(data.userToCall).emit('hey', {signal: data.signalData, from: data.from}); 50 | }) 51 | 52 | gameSocket.on("acceptCall", (data) => { 53 | io.to(data.to).emit('callAccepted', data.signal); 54 | }) 55 | } 56 | 57 | 58 | 59 | function playerJoinsGame(idData) { 60 | /** 61 | * Joins the given socket to a session with it's gameId 62 | */ 63 | 64 | // A reference to the player's Socket.IO socket object 65 | var sock = this 66 | 67 | // Look up the room ID in the Socket.IO manager object. 68 | var room = io.sockets.adapter.rooms[idData.gameId] 69 | // console.log(room) 70 | 71 | // If the room exists... 72 | if (room === undefined) { 73 | this.emit('status' , "This game session does not exist." ); 74 | return 75 | } 76 | if (room.length < 2) { 77 | // attach the socket id to the data object. 78 | idData.mySocketId = sock.id; 79 | 80 | // Join the room 81 | sock.join(idData.gameId); 82 | 83 | console.log(room.length) 84 | 85 | if (room.length === 2) { 86 | io.sockets.in(idData.gameId).emit('start game', idData.userName) 87 | } 88 | 89 | // Emit an event notifying the clients that the player has joined the room. 90 | io.sockets.in(idData.gameId).emit('playerJoinedRoom', idData); 91 | 92 | } else { 93 | // Otherwise, send an error message back to the player. 94 | this.emit('status' , "There are already 2 people playing in this room." ); 95 | } 96 | } 97 | 98 | 99 | function createNewGame(gameId) { 100 | // Return the Room ID (gameId) and the socket ID (mySocketId) to the browser client 101 | this.emit('createNewGame', {gameId: gameId, mySocketId: this.id}); 102 | 103 | // Join the Room and wait for the other player 104 | this.join(gameId) 105 | } 106 | 107 | 108 | function newMove(move) { 109 | /** 110 | * First, we need to get the room ID in which to send this message. 111 | * Next, we actually send this message to everyone except the sender 112 | * in this room. 113 | */ 114 | 115 | const gameId = move.gameId 116 | 117 | io.to(gameId).emit('opponent move', move); 118 | } 119 | 120 | function onDisconnect() { 121 | var i = gamesInSession.indexOf(gameSocket); 122 | gamesInSession.splice(i, 1); 123 | } 124 | 125 | 126 | function requestUserName(gameId) { 127 | io.to(gameId).emit('give userName', this.id); 128 | } 129 | 130 | function recievedUserName(data) { 131 | data.socketId = this.id 132 | io.to(data.gameId).emit('get Opponent UserName', data); 133 | } 134 | 135 | exports.initializeGame = initializeGame --------------------------------------------------------------------------------