moved to root directory
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"HttpPort": 90,
|
||||
"UseHTTPS": false,
|
||||
"MatchmakerPort": 9999,
|
||||
"LogToFile": true
|
||||
}
|
||||
@@ -0,0 +1,295 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
var enableRedirectionLinks = true;
|
||||
var enableRESTAPI = true;
|
||||
|
||||
const defaultConfig = {
|
||||
// The port clients connect to the matchmaking service over HTTP
|
||||
HttpPort: 80,
|
||||
UseHTTPS: false,
|
||||
// The matchmaking port the signaling service connects to the matchmaker
|
||||
MatchmakerPort: 9999,
|
||||
|
||||
// Log to file
|
||||
LogToFile: true
|
||||
};
|
||||
|
||||
// Similar to the Signaling Server (SS) code, load in a config.json file for the MM parameters
|
||||
const argv = require('yargs').argv;
|
||||
|
||||
var configFile = (typeof argv.configFile != 'undefined') ? argv.configFile.toString() : 'config.json';
|
||||
console.log(`configFile ${configFile}`);
|
||||
const config = require('./modules/config.js').init(configFile, defaultConfig);
|
||||
console.log("Config: " + JSON.stringify(config, null, '\t'));
|
||||
|
||||
const express = require('express');
|
||||
var cors = require('cors');
|
||||
const app = express();
|
||||
const http = require('http').Server(app);
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const logging = require('./modules/logging.js');
|
||||
logging.RegisterConsoleLogger();
|
||||
|
||||
if (config.LogToFile) {
|
||||
logging.RegisterFileLogger('./logs');
|
||||
}
|
||||
|
||||
// A list of all the Cirrus server which are connected to the Matchmaker.
|
||||
var cirrusServers = new Map();
|
||||
|
||||
//
|
||||
// Parse command line.
|
||||
//
|
||||
|
||||
if (typeof argv.HttpPort != 'undefined') {
|
||||
config.HttpPort = argv.HttpPort;
|
||||
}
|
||||
if (typeof argv.MatchmakerPort != 'undefined') {
|
||||
config.MatchmakerPort = argv.MatchmakerPort;
|
||||
}
|
||||
|
||||
http.listen(config.HttpPort, () => {
|
||||
console.log('HTTP listening on *:' + config.HttpPort);
|
||||
});
|
||||
|
||||
|
||||
if (config.UseHTTPS) {
|
||||
//HTTPS certificate details
|
||||
const options = {
|
||||
key: fs.readFileSync(path.join(__dirname, './certificates/client-key.pem')),
|
||||
cert: fs.readFileSync(path.join(__dirname, './certificates/client-cert.pem'))
|
||||
};
|
||||
|
||||
var https = require('https').Server(options, app);
|
||||
|
||||
//Setup http -> https redirect
|
||||
console.log('Redirecting http->https');
|
||||
app.use(function (req, res, next) {
|
||||
if (!req.secure) {
|
||||
if (req.get('Host')) {
|
||||
var hostAddressParts = req.get('Host').split(':');
|
||||
var hostAddress = hostAddressParts[0];
|
||||
if (httpsPort != 443) {
|
||||
hostAddress = `${hostAddress}:${httpsPort}`;
|
||||
}
|
||||
return res.redirect(['https://', hostAddress, req.originalUrl].join(''));
|
||||
} else {
|
||||
console.error(`unable to get host name from header. Requestor ${req.ip}, url path: '${req.originalUrl}', available headers ${JSON.stringify(req.headers)}`);
|
||||
return res.status(400).send('Bad Request');
|
||||
}
|
||||
}
|
||||
next();
|
||||
});
|
||||
|
||||
https.listen(443, function () {
|
||||
console.log('Https listening on 443');
|
||||
});
|
||||
}
|
||||
|
||||
// No servers are available so send some simple JavaScript to the client to make
|
||||
// it retry after a short period of time.
|
||||
function sendRetryResponse(res) {
|
||||
res.send(`All ${cirrusServers.size} Cirrus servers are in use. Retrying in <span id="countdown">3</span> seconds.
|
||||
<script>
|
||||
var countdown = document.getElementById("countdown").textContent;
|
||||
setInterval(function() {
|
||||
countdown--;
|
||||
if (countdown == 0) {
|
||||
window.location.reload(1);
|
||||
} else {
|
||||
document.getElementById("countdown").textContent = countdown;
|
||||
}
|
||||
}, 1000);
|
||||
</script>`);
|
||||
}
|
||||
|
||||
// Get a Cirrus server if there is one available which has no clients connected.
|
||||
function getAvailableCirrusServer() {
|
||||
for (cirrusServer of cirrusServers.values()) {
|
||||
if (cirrusServer.numConnectedClients === 0 && cirrusServer.ready === true) {
|
||||
|
||||
// Check if we had at least 10 seconds since the last redirect, avoiding the
|
||||
// chance of redirecting 2+ users to the same SS before they click Play.
|
||||
// In other words, give the user 10 seconds to click play button the claim the server.
|
||||
if( cirrusServer.hasOwnProperty('lastRedirect')) {
|
||||
if( ((Date.now() - cirrusServer.lastRedirect) / 1000) < 10 )
|
||||
continue;
|
||||
}
|
||||
cirrusServer.lastRedirect = Date.now();
|
||||
|
||||
return cirrusServer;
|
||||
}
|
||||
}
|
||||
|
||||
console.log('WARNING: No empty Cirrus servers are available');
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if(enableRESTAPI) {
|
||||
// Handle REST signalling server only request.
|
||||
app.options('/signallingserver', cors())
|
||||
app.get('/signallingserver', cors(), (req, res) => {
|
||||
cirrusServer = getAvailableCirrusServer();
|
||||
if (cirrusServer != undefined) {
|
||||
res.json({ signallingServer: `${cirrusServer.address}:${cirrusServer.port}`});
|
||||
console.log(`Returning ${cirrusServer.address}:${cirrusServer.port}`);
|
||||
} else {
|
||||
res.json({ signallingServer: '', error: 'No signalling servers available'});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if(enableRedirectionLinks) {
|
||||
// Handle standard URL.
|
||||
app.get('/', (req, res) => {
|
||||
cirrusServer = getAvailableCirrusServer();
|
||||
if (cirrusServer != undefined) {
|
||||
res.redirect(`http://${cirrusServer.address}:${cirrusServer.port}/`);
|
||||
//console.log(req);
|
||||
console.log(`Redirect to ${cirrusServer.address}:${cirrusServer.port}`);
|
||||
} else {
|
||||
sendRetryResponse(res);
|
||||
}
|
||||
});
|
||||
|
||||
// Handle URL with custom HTML.
|
||||
app.get('/custom_html/:htmlFilename', (req, res) => {
|
||||
cirrusServer = getAvailableCirrusServer();
|
||||
if (cirrusServer != undefined) {
|
||||
res.redirect(`http://${cirrusServer.address}:${cirrusServer.port}/custom_html/${req.params.htmlFilename}`);
|
||||
console.log(`Redirect to ${cirrusServer.address}:${cirrusServer.port}`);
|
||||
} else {
|
||||
sendRetryResponse(res);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
// Connection to Cirrus.
|
||||
//
|
||||
|
||||
const net = require('net');
|
||||
|
||||
function disconnect(connection) {
|
||||
console.log(`Ending connection to remote address ${connection.remoteAddress}`);
|
||||
connection.end();
|
||||
}
|
||||
|
||||
const matchmaker = net.createServer((connection) => {
|
||||
connection.on('data', (data) => {
|
||||
try {
|
||||
message = JSON.parse(data);
|
||||
|
||||
if(message)
|
||||
console.log(`Message TYPE: ${message.type}`);
|
||||
} catch(e) {
|
||||
console.log(`ERROR (${e.toString()}): Failed to parse Cirrus information from data: ${data.toString()}`);
|
||||
disconnect(connection);
|
||||
return;
|
||||
}
|
||||
if (message.type === 'connect') {
|
||||
// A Cirrus server connects to this Matchmaker server.
|
||||
cirrusServer = {
|
||||
address: message.address,
|
||||
port: message.port,
|
||||
numConnectedClients: 0,
|
||||
lastPingReceived: Date.now()
|
||||
};
|
||||
cirrusServer.ready = message.ready === true;
|
||||
|
||||
// Handles disconnects between MM and SS to not add dupes with numConnectedClients = 0 and redirect users to same SS
|
||||
// Check if player is connected and doing a reconnect. message.playerConnected is a new variable sent from the SS to
|
||||
// help track whether or not a player is already connected when a 'connect' message is sent (i.e., reconnect).
|
||||
if(message.playerConnected == true) {
|
||||
cirrusServer.numConnectedClients = 1;
|
||||
}
|
||||
|
||||
// Find if we already have a ciruss server address connected to (possibly a reconnect happening)
|
||||
let server = [...cirrusServers.entries()].find(([key, val]) => val.address === cirrusServer.address && val.port === cirrusServer.port);
|
||||
|
||||
// if a duplicate server with the same address isn't found -- add it to the map as an available server to send users to.
|
||||
if (!server || server.size <= 0) {
|
||||
console.log(`Adding connection for ${cirrusServer.address.split(".")[0]} with playerConnected: ${message.playerConnected}`)
|
||||
cirrusServers.set(connection, cirrusServer);
|
||||
} else {
|
||||
console.log(`RECONNECT: cirrus server address ${cirrusServer.address.split(".")[0]} already found--replacing. playerConnected: ${message.playerConnected}`)
|
||||
var foundServer = cirrusServers.get(server[0]);
|
||||
|
||||
// Make sure to retain the numConnectedClients from the last one before the reconnect to MM
|
||||
if (foundServer) {
|
||||
cirrusServers.set(connection, cirrusServer);
|
||||
console.log(`Replacing server with original with numConn: ${cirrusServer.numConnectedClients}`);
|
||||
cirrusServers.delete(server[0]);
|
||||
} else {
|
||||
cirrusServers.set(connection, cirrusServer);
|
||||
console.log("Connection not found in Map() -- adding a new one");
|
||||
}
|
||||
}
|
||||
} else if (message.type === 'streamerConnected') {
|
||||
// The stream connects to a Cirrus server and so is ready to be used
|
||||
cirrusServer = cirrusServers.get(connection);
|
||||
if(cirrusServer) {
|
||||
cirrusServer.ready = true;
|
||||
console.log(`Cirrus server ${cirrusServer.address}:${cirrusServer.port} ready for use`);
|
||||
} else {
|
||||
disconnect(connection);
|
||||
}
|
||||
} else if (message.type === 'streamerDisconnected') {
|
||||
// The stream connects to a Cirrus server and so is ready to be used
|
||||
cirrusServer = cirrusServers.get(connection);
|
||||
if(cirrusServer) {
|
||||
cirrusServer.ready = false;
|
||||
console.log(`Cirrus server ${cirrusServer.address}:${cirrusServer.port} no longer ready for use`);
|
||||
} else {
|
||||
disconnect(connection);
|
||||
}
|
||||
} else if (message.type === 'clientConnected') {
|
||||
// A client connects to a Cirrus server.
|
||||
cirrusServer = cirrusServers.get(connection);
|
||||
if(cirrusServer) {
|
||||
cirrusServer.numConnectedClients++;
|
||||
console.log(`Client connected to Cirrus server ${cirrusServer.address}:${cirrusServer.port}`);
|
||||
} else {
|
||||
disconnect(connection);
|
||||
}
|
||||
} else if (message.type === 'clientDisconnected') {
|
||||
// A client disconnects from a Cirrus server.
|
||||
cirrusServer = cirrusServers.get(connection);
|
||||
if(cirrusServer) {
|
||||
cirrusServer.numConnectedClients--;
|
||||
console.log(`Client disconnected from Cirrus server ${cirrusServer.address}:${cirrusServer.port}`);
|
||||
if(cirrusServer.numConnectedClients === 0) {
|
||||
// this make this server immediately available for a new client
|
||||
cirrusServer.lastRedirect = 0;
|
||||
}
|
||||
} else {
|
||||
disconnect(connection);
|
||||
}
|
||||
} else if (message.type === 'ping') {
|
||||
cirrusServer = cirrusServers.get(connection);
|
||||
if(cirrusServer) {
|
||||
cirrusServer.lastPingReceived = Date.now();
|
||||
} else {
|
||||
disconnect(connection);
|
||||
}
|
||||
} else {
|
||||
console.log('ERROR: Unknown data: ' + JSON.stringify(message));
|
||||
disconnect(connection);
|
||||
}
|
||||
});
|
||||
|
||||
// A Cirrus server disconnects from this Matchmaker server.
|
||||
connection.on('error', () => {
|
||||
cirrusServer = cirrusServers.get(connection);
|
||||
if(cirrusServer) {
|
||||
cirrusServers.delete(connection);
|
||||
console.log(`Cirrus server ${cirrusServer.address}:${cirrusServer.port} disconnected from Matchmaker`);
|
||||
} else {
|
||||
console.log(`Disconnected machine that wasn't a registered cirrus server, remote address: ${connection.remoteAddress}`);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
matchmaker.listen(config.MatchmakerPort, () => {
|
||||
console.log('Matchmaker listening on *:' + config.MatchmakerPort);
|
||||
});
|
||||
@@ -0,0 +1,49 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
//-- Provides configuration information from file and combines it with default values and command line arguments --//
|
||||
//-- Hierachy of values: Default Values < Config File < Command Line arguments --//
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const argv = require('yargs').argv;
|
||||
|
||||
function initConfig(configFile, defaultConfig){
|
||||
defaultConfig = defaultConfig || {};
|
||||
|
||||
// Using object spread syntax: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals
|
||||
let config = {...defaultConfig};
|
||||
try{
|
||||
let configData = fs.readFileSync(configFile, 'UTF8');
|
||||
fileConfig = JSON.parse(configData);
|
||||
config = {...config, ...fileConfig}
|
||||
// Update config file with any additional defaults (does not override existing values if default has changed)
|
||||
fs.writeFileSync(configFile, JSON.stringify(config, null, '\t'), 'UTF8');
|
||||
} catch(err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
console.log("No config file found, writing defaults to log file " + configFile);
|
||||
fs.writeFileSync(configFile, JSON.stringify(config, null, '\t'), 'UTF8');
|
||||
} else if (err instanceof SyntaxError) {
|
||||
console.log(`ERROR: Invalid JSON in ${configFile}, ignoring file config, ${err}`)
|
||||
} else {
|
||||
console.log(`ERROR: ${err}`);
|
||||
}
|
||||
}
|
||||
|
||||
try{
|
||||
//Make a copy of the command line args and remove the unneccessary ones
|
||||
//The _ value is an array of any elements without a key
|
||||
let commandLineConfig = {...argv}
|
||||
delete commandLineConfig._;
|
||||
delete commandLineConfig.help;
|
||||
delete commandLineConfig.version;
|
||||
delete commandLineConfig['$0'];
|
||||
config = {...config, ...commandLineConfig}
|
||||
} catch(err) {
|
||||
console.log(`ERROR: ${err}`);
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
init: initConfig
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
const fs = require('fs');
|
||||
const { Console } = require('console');
|
||||
|
||||
var loggers=[];
|
||||
var logFunctions=[];
|
||||
var logColorFunctions=[];
|
||||
|
||||
console.log = function(msg, ...args) {
|
||||
logFunctions.forEach((logFunction) => {
|
||||
logFunction(msg, ...args);
|
||||
});
|
||||
}
|
||||
|
||||
console.logColor = function(color, msg, ...args) {
|
||||
logColorFunctions.forEach((logColorFunction) => {
|
||||
logColorFunction(color, msg, ...args);
|
||||
});
|
||||
}
|
||||
|
||||
const AllAttributesOff = '\x1b[0m';
|
||||
const BoldOn = '\x1b[1m';
|
||||
const Black = '\x1b[30m';
|
||||
const Red = '\x1b[31m';
|
||||
const Green = '\x1b[32m';
|
||||
const Yellow = '\x1b[33m';
|
||||
const Blue = '\x1b[34m';
|
||||
const Magenta = '\x1b[35m';
|
||||
const Cyan = '\x1b[36m';
|
||||
const White = '\x1b[37m';
|
||||
|
||||
/**
|
||||
* Pad the start of the given number with zeros so it takes up the number of digits.
|
||||
* e.g. zeroPad(5, 3) = '005' and zeroPad(23, 2) = '23'.
|
||||
*/
|
||||
function zeroPad(number, digits) {
|
||||
let string = number.toString();
|
||||
while (string.length < digits) {
|
||||
string = '0' + string;
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a string of the form 'YEAR.MONTH.DATE.HOURS.MINUTES.SECONDS'.
|
||||
*/
|
||||
function dateTimeToString() {
|
||||
let date = new Date();
|
||||
return `${date.getFullYear()}.${zeroPad(date.getMonth(), 2)}.${zeroPad(date.getDate(), 2)}.${zeroPad(date.getHours(), 2)}.${zeroPad(date.getMinutes(), 2)}.${zeroPad(date.getSeconds(), 2)}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a string of the form 'HOURS.MINUTES.SECONDS.MILLISECONDS'.
|
||||
*/
|
||||
function timeToString() {
|
||||
let date = new Date();
|
||||
return `${zeroPad(date.getHours(), 2)}:${zeroPad(date.getMinutes(), 2)}:${zeroPad(date.getSeconds(), 2)}.${zeroPad(date.getMilliseconds(), 3)}`;
|
||||
}
|
||||
|
||||
function RegisterFileLogger(path) {
|
||||
if(path == null)
|
||||
path = './';
|
||||
|
||||
if (!fs.existsSync(path))
|
||||
fs.mkdirSync(path);
|
||||
|
||||
var output = fs.createWriteStream(`./logs/${dateTimeToString()}.log`);
|
||||
var fileLogger = new Console(output);
|
||||
logFunctions.push(function(msg, ...args) {
|
||||
fileLogger.log(`${timeToString()} ${msg}`, ...args);
|
||||
});
|
||||
|
||||
logColorFunctions.push(function(color, msg, ...args) {
|
||||
fileLogger.log(`${timeToString()} ${msg}`, ...args);
|
||||
});
|
||||
loggers.push(fileLogger);
|
||||
}
|
||||
|
||||
function RegisterConsoleLogger() {
|
||||
var consoleLogger = new Console(process.stdout, process.stderr)
|
||||
logFunctions.push(function(msg, ...args) {
|
||||
consoleLogger.log(`${timeToString()} ${msg}`, ...args);
|
||||
});
|
||||
|
||||
logColorFunctions.push(function(color, msg, ...args) {
|
||||
consoleLogger.log(`${BoldOn}${color}${timeToString()} ${msg}${AllAttributesOff}`, ...args);
|
||||
});
|
||||
loggers.push(consoleLogger);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
//Functions
|
||||
RegisterFileLogger,
|
||||
RegisterConsoleLogger,
|
||||
|
||||
//Variables
|
||||
AllAttributesOff,
|
||||
BoldOn,
|
||||
Black,
|
||||
Red,
|
||||
Green,
|
||||
Yellow,
|
||||
Blue,
|
||||
Magenta,
|
||||
Cyan,
|
||||
White
|
||||
}
|
||||
Generated
+1491
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "cirrus-matchmaker",
|
||||
"version": "0.0.1",
|
||||
"description": "Cirrus servers connect to the Matchmaker which redirects a browser to the next available Cirrus server",
|
||||
"dependencies": {
|
||||
"cors": "^2.8.5",
|
||||
"express": "^4.16.2",
|
||||
"socket.io": "4.4.1",
|
||||
"yargs": "17.3.1"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
#!/bin/bash
|
||||
# Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
function log_msg() { #message
|
||||
if [ ! -z $VERBOSE ]; then
|
||||
echo $1
|
||||
fi
|
||||
}
|
||||
|
||||
function print_usage() {
|
||||
echo "
|
||||
Usage:
|
||||
${0} [--help] [--publicip <IP Address>] [--turn <turn server>] [--stun <stun server>] [cirrus options...]
|
||||
Where:
|
||||
--help will print this message and stop this script.
|
||||
--debug will run all scripts with --inspect
|
||||
--nosudo will run all scripts without \`sudo\` command useful for when run in containers.
|
||||
--verbose will enable additional logging
|
||||
--package-manager <package manager name> specify an alternative package manager to apt-get
|
||||
"
|
||||
exit 1
|
||||
}
|
||||
|
||||
function use_args() {
|
||||
while(($#)) ; do
|
||||
case "$1" in
|
||||
--debug ) IS_DEBUG=1; shift;;
|
||||
--nosudo ) NO_SUDO=1; shift;;
|
||||
--verbose ) VERBOSE=1; shift;;
|
||||
--help ) print_usage;;
|
||||
* ) echo "Unknown command"; shift;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
function call_setup_sh() {
|
||||
bash "setup.sh"
|
||||
}
|
||||
|
||||
function start_process() {
|
||||
if [ ! -z $NO_SUDO ]; then
|
||||
log_msg "running with sudo removed"
|
||||
eval $(echo "$@" | sed 's/sudo//g')
|
||||
else
|
||||
eval $@
|
||||
fi
|
||||
}
|
||||
|
||||
function get_version() {
|
||||
local version=$1
|
||||
|
||||
if command -v $version; then
|
||||
version=$($@)
|
||||
fi
|
||||
|
||||
echo $version | sed -E 's/[^0-9.]//g'
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
# Copyright Epic Games, Inc. All Rights Reserved.
|
||||
BASH_LOCATION=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||
|
||||
pushd "${BASH_LOCATION}" > /dev/null
|
||||
|
||||
source common_utils.sh
|
||||
|
||||
use_args "$@"
|
||||
call_setup_sh
|
||||
|
||||
process="${BASH_LOCATION}/node/bin/node matchmaker.js"
|
||||
|
||||
pushd ../.. > /dev/null
|
||||
|
||||
echo ""
|
||||
echo "Starting Matchmaker use ctrl-c to exit"
|
||||
echo "-----------------------------------------"
|
||||
echo ""
|
||||
|
||||
start_process $process
|
||||
|
||||
popd > /dev/null # ../..
|
||||
|
||||
popd > /dev/null # BASH_SOURCE
|
||||
@@ -0,0 +1,114 @@
|
||||
#!/bin/bash
|
||||
# Copyright Epic Games, Inc. All Rights Reserved.
|
||||
BASH_LOCATION=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||
|
||||
pushd "${BASH_LOCATION}" > /dev/null
|
||||
|
||||
source common_utils.sh
|
||||
|
||||
use_args $@
|
||||
# Azure specific fix to allow installing NodeJS from NodeSource
|
||||
if test -f "/etc/apt/sources.list.d/azure-cli.list"; then
|
||||
sudo touch /etc/apt/sources.list.d/nodesource.list
|
||||
sudo touch /usr/share/keyrings/nodesource.gpg
|
||||
sudo chmod 644 /etc/apt/sources.list.d/nodesource.list
|
||||
sudo chmod 644 /usr/share/keyrings/nodesource.gpg
|
||||
sudo chmod 644 /etc/apt/sources.list.d/azure-cli.list
|
||||
fi
|
||||
|
||||
function check_version() { #current_version #min_version
|
||||
#check if same string
|
||||
if [ -z "$2" ] || [ "$1" = "$2" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
local i current minimum
|
||||
|
||||
IFS="." read -r -a current <<< $1
|
||||
IFS="." read -r -a minimum <<< $2
|
||||
|
||||
# fill empty fields in current with zeros
|
||||
for ((i=${#current[@]}; i<${#minimum[@]}; i++))
|
||||
do
|
||||
current[i]=0
|
||||
done
|
||||
|
||||
for ((i=0; i<${#current[@]}; i++))
|
||||
do
|
||||
if [[ -z ${minimum[i]} ]]; then
|
||||
# fill empty fields in minimum with zeros
|
||||
minimum[i]=0
|
||||
fi
|
||||
|
||||
if ((10#${current[i]} > 10#${minimum[i]})); then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ((10#${current[i]} < 10#${minimum[i]})); then
|
||||
return 2
|
||||
fi
|
||||
done
|
||||
|
||||
# if got this far string is the same once we added missing 0
|
||||
return 0
|
||||
}
|
||||
|
||||
function check_and_install() { #dep_name #get_version_string #version_min #install_command
|
||||
local is_installed=0
|
||||
|
||||
log_msg "Checking for required $1 install"
|
||||
|
||||
local current=$(echo $2 | sed -E 's/[^0-9.]//g')
|
||||
local minimum=$(echo $3 | sed -E 's/[^0-9.]//g')
|
||||
|
||||
if [ $# -ne 4 ]; then
|
||||
log_msg "check_and_install expects 4 args (dep_name get_version_string version_min install_command) got $#"
|
||||
return -1
|
||||
fi
|
||||
|
||||
if [ ! -z $current ]; then
|
||||
log_msg "Current version: $current checking >= $minimum"
|
||||
check_version "$current" "$minimum"
|
||||
if [ "$?" -lt 2 ]; then
|
||||
log_msg "$1 is installed."
|
||||
return 0
|
||||
else
|
||||
log_msg "Required install of $1 not found installing"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $is_installed -ne 1 ]; then
|
||||
echo "$1 installation not found installing..."
|
||||
|
||||
start_process $4
|
||||
|
||||
if [ $? -ge 1 ]; then
|
||||
echo "Installation of $1 failed try running `export VERBOSE=1` then run this script again for more details"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
fi
|
||||
}
|
||||
|
||||
echo "Checking Matchmaker dependencies..."
|
||||
|
||||
# navigate to Matchmaker root
|
||||
pushd ../.. > /dev/null
|
||||
|
||||
node_version=""
|
||||
if [[ -f "${BASH_LOCATION}/node/bin/node" ]]; then
|
||||
node_version=$("${BASH_LOCATION}/node/bin/node" --version)
|
||||
fi
|
||||
check_and_install "node" "$node_version" "v16.4.2" "curl https://nodejs.org/dist/v16.14.2/node-v16.14.2-linux-x64.tar.gz --output node.tar.xz
|
||||
&& tar -xf node.tar.xz
|
||||
&& rm node.tar.xz
|
||||
&& mv node-v*-linux-x64 \"${BASH_LOCATION}/node\""
|
||||
|
||||
PATH="${BASH_LOCATION}/node/bin:$PATH"
|
||||
"${BASH_LOCATION}/node/lib/node_modules/npm/bin/npm-cli.js" install
|
||||
|
||||
popd > /dev/null # Matchmaker
|
||||
|
||||
popd > /dev/null # BASH_SOURCE
|
||||
|
||||
echo "All Matchmaker dependencies up to date."
|
||||
@@ -0,0 +1,25 @@
|
||||
@Rem Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
@echo off
|
||||
|
||||
@Rem Set script directory as working directory.
|
||||
pushd "%~dp0"
|
||||
|
||||
title Matchmaker
|
||||
|
||||
@Rem Run setup to ensure we have node and matchmaker installed.
|
||||
call setup.bat
|
||||
|
||||
@Rem Move to matchmaker.js directory.
|
||||
pushd ..\..
|
||||
|
||||
@Rem Run node server and pass any argument along.
|
||||
platform_scripts\cmd\node\node.exe matchmaker %*
|
||||
|
||||
@Rem Pop matchmaker.js directory.
|
||||
popd
|
||||
|
||||
@Rem Pop script directory.
|
||||
popd
|
||||
|
||||
pause
|
||||
@@ -0,0 +1,17 @@
|
||||
@Rem Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
@echo off
|
||||
|
||||
@Rem Set script location as working directory for commands.
|
||||
pushd "%~dp0"
|
||||
|
||||
@Rem Ensure we have NodeJs available for calling.
|
||||
call setup_node.bat
|
||||
|
||||
@Rem Move to matchmaker.js directory and install its package.json
|
||||
pushd %~dp0\..\..\
|
||||
call platform_scripts\cmd\node\npm install --no-save
|
||||
popd
|
||||
|
||||
@Rem Pop working directory
|
||||
popd
|
||||
@@ -0,0 +1,35 @@
|
||||
@Rem Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
@echo off
|
||||
|
||||
@Rem Set script location as working directory for commands.
|
||||
pushd "%~dp0"
|
||||
|
||||
@Rem Name and version of node that we are downloading
|
||||
SET NodeVersion=v16.4.2
|
||||
SET NodeName=node-%NodeVersion%-win-x64
|
||||
|
||||
@Rem Look for a node directory next to this script
|
||||
if exist node\ (
|
||||
echo Node directory found...skipping install.
|
||||
) else (
|
||||
echo Node directory not found...beginning NodeJS download for Windows.
|
||||
|
||||
@Rem Download nodejs and follow redirects.
|
||||
curl -L -o ./node.zip "https://nodejs.org/dist/%NodeVersion%/%NodeName%.zip"
|
||||
|
||||
@Rem Unarchive the .zip
|
||||
tar -xf node.zip
|
||||
|
||||
@Rem Rename the extracted, versioned, directory that contains the NodeJS binaries to simply "node".
|
||||
ren "%NodeName%\" "node"
|
||||
|
||||
@Rem Delete the downloaded node.zip
|
||||
del node.zip
|
||||
)
|
||||
|
||||
@Rem Print node version
|
||||
echo Node version: & node\node.exe -v
|
||||
|
||||
@Rem Pop working directory
|
||||
popd
|
||||
Reference in New Issue
Block a user