From 6375434aaad8be9f8bf2b5e0cafd394e267252a0 Mon Sep 17 00:00:00 2001 From: Sewmina Dilshan Date: Sat, 19 Nov 2022 19:37:43 +0530 Subject: [PATCH] New system finished, Ready to use? --- README.md | 45 ++++++++++++++++++++++++++++++++++++++++++--- app.js | 15 +++++++++------ helpers.js | 23 ++++++++++++++++++++++- 3 files changed, 73 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 9477354..ff18438 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,43 @@ -# CupidServer -This is the Server daemon for Cupid Matchmaking system for Mirror unity. +# Cupid Server - Matchmake with Dedicated Servers. NOT RELAYS +Cupid is a Matchmaking backend that can open game instances on demand. Just like making rooms in a relay server, This will open Game instance for each room so the Rooms can be dedicated servers instead of making the players the host. -You have to run this program on the same server where you'll be hosting your game +This consists of two parts, This is the server backend written in NodeJS. Client will communicate with this and this will manage rooms and game instances. + +# How to install +To install the server application, Download the repo or clone it using git command.
+``git clone https://github.com/Sewmina7/CupidServer.git`` + +Then get inside the directory where the ``app.js`` is locted, and enter
+``node app``
+to run the application. + +** Make sure to Allow the API listening port and Port range for Rooms. +For default config:
``sudo ufw allow 1601 && sudo ufw allow 2000:3000/tcp && sudo ufw allow 2000:3000/udp``
(You can open only the chosen Protocol if you are worried about safety when opening both) + +# Configuration +Inside the directory, There is a file called ``settings.json`` . Default Settings are like this +``` +{ + "port":1601, + "password":"xyz@123", + "game_exe":"/root/Unity/CupidSample/Builds/Linux/Cupid.x86_64", + "minimum_players": 2, + "maximum_players": 5, + "waiting_time": 30000, + "port_range_min":2000, + "port_range_max":3000, + "log_level":3 +} +``` + +Let me explain what each parameter does. + +``port`` : The port on server which will listen to clients. This port must be open / allowed by firewall (ex: ``ufw allow 1601``)

+``password`` : API key to validate the client. You can enter a safe phrase to make it secure.

+``game_exe`` : Where the ``Server Build`` Of the game is located. This is the file which will be opened when making a new room. (This instance is passed the argument ``-port``. Look on Unity implementation for further details.

+``minimum_players`` : Minimum players required to start a new Room.

+``maximum_players`` : Limit of players that can be on a single Room.

+``waiting_tiem`` : Time (in miliseconds) before the Room expires. Each room will only last this amount of time

+``port_range_min`` : Lower bound of the Port range available for Rooms.

+``port_range_max`` : Higher bound of the Port range available for Rooms.

+``log_level`` : What the application will spit. ( 0:only necessary, 1:debug, 2:verbose ) \ No newline at end of file diff --git a/app.js b/app.js index 91fcadb..c767257 100644 --- a/app.js +++ b/app.js @@ -3,8 +3,6 @@ console.log("Starting Cupid Matchmaker for unity " + version); console.log("") const { response } = require('express'); -const { exec, execFile } = require('child_process'); -var spawn = require('child_process').spawn; const express = require('express') const app = express() require('./settings')(); @@ -18,6 +16,7 @@ const queueGraceTime = 2000; var settings = ReadSettings(); if (settings == null) { return; } const logLevel = settings.log_level; + LogVerbose(settings); var Rooms = []; @@ -89,8 +88,10 @@ app.get('/', (req, res) => { //Neither in a room nor in queue, Let's see if(possibleRoom == null){ if(Queue.length >= settings.minimum_players){ - var newRoom = {Players:[{Name:username, LastSeen: Date.now()}], Port: Helpers.GetRandomPort(settings.port_range_min, settings.port_range_max), InitTime: Date.now()}; + var newPort = Helpers.GetRandomPort(settings.port_range_min, settings.port_range_max); + var newRoom = {Players:[{Name:username, LastSeen: Date.now()}], Port: newPort, InitTime: Date.now()}; Rooms.push(newRoom); + Helpers.OpenGameInstance(settings.game_exe, newPort); res.send(newRoom); // <------- Exit [ Made a new room ] return; } @@ -122,16 +123,18 @@ app.get('/cancel', (req,res)=>{ if(!ValidateRequest(req,res)){ return; } - + var foundUser = false; Queue.forEach((element)=>{ if(element.Name == username){ Queue.pop(element); res.send("1"); + foundUser=true; return; } }) - - res.send("Couldn't find user " + username + " in the queue"); + if(!foundUser){ + res.send("Couldn't find user " + username + " in the queue"); + } }) function ValidateRequest(req, res){ diff --git a/helpers.js b/helpers.js index a2bc15c..ed2b5ff 100644 --- a/helpers.js +++ b/helpers.js @@ -1,10 +1,31 @@ +var spawn = require('child_process').spawn; + + exports.GetRandomPort =function(min,max){ var port = randomIntFromInterval(min,max); // console.log("min:"+min+", max:"+max+" = "+port); return port; }; +exports.OpenGameInstance = function(path,port){ + var arguments = ["-port", port]; + + var child = spawn(path, arguments); + + child.stdout.on('data', function (data) { + // console.log('stdout: ' + data); + }); + + child.stderr.on('data', function (data) { + console.log('stderr: ' + data); + }); + + child.on('close', function (code) { + + console.log('Game instance with port ' + port + " exited with code " + code); + }); +}; function randomIntFromInterval(min, max) { // min and max included return Math.floor(Math.random() * (max - min + 1) + min) - } \ No newline at end of file +} \ No newline at end of file