Merge branch 'dev'

This commit is contained in:
Danielv123 committed 2017-04-24 19:50:14 +02:00
commit 625f0eec3b
6 files changed
+71 -25

No files matched your search

+12 -4
View File
@@ -1,11 +1,19 @@
FROM node:latest
RUN apt-get update && apt install git -y && git clone https://github.com/Danielv123/factorioClusterio.git && cd factorioClusterio && npm install && curl -o factorio.tar.gz -L https://www.factorio.com/get-download/latest/headless/linux64 && tar -xvzf factorio.tar.gz
RUN apt-get update && apt install git -y
RUN mkdir factorioClusterio
RUN git clone -b dev https://github.com/Danielv123/factorioClusterio.git && cd factorioClusterio && npm install && curl -o factorio.tar.gz -L https://www.factorio.com/get-download/latest/headless/linux64 && tar -xvzf factorio.tar.gz
WORKDIR factorioClusterio
RUN mkdir instances sharedMods sharedPlugins
RUN node client.js download
LABEL maintainer "danielv@live.no"
EXPOSE 8080 34167
VOLUME /factorioClusterio/instances
VOLUME /factorioClusterio/sharedMods
VOLUME /factorioClusterio/sharedPlugins
WORKDIR factorioClusterio
CMD node $MODE\.js start $INSTANCE
CMD RCONPORT="$RCONPORT" FACTORIOPORT="$FACTORIOPORT" MODE="$MODE" node $MODE\.js start $INSTANCE
+45 -14
View File
@@ -4,10 +4,11 @@ var needle = require("needle");
var child_process = require('child_process');
var path = require('path');
var syncRequest = require('sync-request');
var request = require("request")
var request = require("request");
var ncp = require('ncp').ncp;
var Rcon = require('simple-rcon');
var hashFiles = require('hash-files');
var _ = require('underscore');
var libomega = require("./libomega.js");
// require config.json
@@ -62,7 +63,16 @@ function messageInterface(command, callback) {
command = command.toString('utf8');
}
if(typeof command == "string" && client && client.exec && typeof client.exec == "function") {
if(process.platform == "linux" && typeof command == "string" && serverprocess) {
/*
to send to stdin, use:
serverprocess.stdin.write("/c command;\n")
*/
serverprocess.stdin.write(command+"\n");
if(typeof callback == "function"){
callback();
}
} else if(typeof command == "string" && client && client.exec && typeof client.exec == "function") {
try {
client.exec(command, callback);
} catch (err) {
@@ -130,8 +140,8 @@ write-data=__PATH__executable__/../../../instances/" + instance + "\r\n\
fs.copySync('sharedMods', instancedirectory + "/mods")
let instconf = {
"factorioPort": Math.floor(Math.random() * 65535),
"clientPort": Math.floor(Math.random() * 65535),
"factorioPort": process.env.FACTORIOPORT | Math.floor(Math.random() * 65535),
"clientPort": process.env.RCONPORT | Math.floor(Math.random() * 65535),
"clientPassword": Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 8),
}
console.log("Clusterio | Moving shared mods...")
@@ -175,6 +185,12 @@ write-data=__PATH__executable__/../../../instances/" + instance + "\r\n\
if(instancedirectory != "./instances/undefined"){
var instanceconfig = require(instancedirectory + '/config');
instanceconfig.unique = instanceconfig.clientPassword.hashCode();
if(process.env.FACTORIOPORT){
instanceconfig.factorioPort = process.env.FACTORIOPORT;
}
if(process.env.RCONPORT){
instanceconfig.rconPort = process.env.RCONPORT;
}
} else {
process.exit(1)
}
@@ -185,7 +201,9 @@ write-data=__PATH__executable__/../../../instances/" + instance + "\r\n\
fs.unlinkSync(instancedirectory + "/saves/" + savefiles[i]);
}
}
/*setInterval(function(){
console.log(process.env);
},5000);*/
console.log("Deleting logs");
// clean old log file to avoid crash
// file exists, delete so we don't get in trouble
@@ -211,14 +229,15 @@ write-data=__PATH__executable__/../../../instances/" + instance + "\r\n\
// Spawn factorio server
//var serverprocess = child_process.exec(commandline)
getNewestFile(instancedirectory + "/saves/", fs.readdirSync(instancedirectory + "/saves/"),function(latestSave) {
var serverprocess = child_process.spawn(
// implicit global
serverprocess = child_process.spawn(
'./' + config.factorioDirectory + '/bin/x64/factorio', [
'-c', instancedirectory + '/config.ini',
'--start-server', latestSave.file,
'--rcon-port', instanceconfig.clientPort,
'--rcon-port', Number(process.env.RCONPORT) || instanceconfig.clientPort,
'--rcon-password', instanceconfig.clientPassword,
'--server-settings', instancedirectory + '/server-settings.json',
'--port', instanceconfig.factorioPort
'--port', Number(process.env.FACTORIOPORT) || instanceconfig.factorioPort
], {
'stdio': ['pipe', 'pipe', 'pipe']
}
@@ -228,6 +247,15 @@ write-data=__PATH__executable__/../../../instances/" + instance + "\r\n\
console.log(`child process exited with code ${code}`);
process.exit();
});
serverprocess.stdout.on("data", (data) => {
// log("Stdout: " + data);
if(data.toString('utf8').includes("Couldn't parse RCON data: Maximum payload size exceeded")){
console.error("ERROR: RCON CONNECTION BROKE DUE TO TOO LARGE PACKET!");
console.error("Attempting reconnect...");
client.close();
client.connect();
}
});
serverprocess.stdout.on('data', (chunk) => {
if(process.platform == "linux"){
console.log('Factorio: ' + chunk);
@@ -242,7 +270,7 @@ write-data=__PATH__executable__/../../../instances/" + instance + "\r\n\
// IP, port, password
client = new Rcon({
host: 'localhost',
port: instanceconfig.clientPort,
port: Number(process.env.RCONPORT) || instanceconfig.clientPort,
password: instanceconfig.clientPassword,
timeout: 0
});
@@ -271,8 +299,7 @@ write-data=__PATH__executable__/../../../instances/" + instance + "\r\n\
// getID();
}).on('disconnected', function () {
console.log('Clusterio | Disconnected!');
// now reconnect
client.connect();
process.exit(0); // exit because RCON disconnecting is undefined behaviour and we rather just wanna restart now
});
// set some globals
@@ -280,8 +307,9 @@ write-data=__PATH__executable__/../../../instances/" + instance + "\r\n\
lastSignalCheck = Date.now();
})
}
_.once(instanceManagement);
function instanceManagement() {
console.log("Started instanceManagement();")
// load plugins and execute onLoad event
let pluginDirectories = getDirectories("./sharedPlugins/");
let plugins = [];
@@ -384,9 +412,12 @@ function instanceManagement() {
require('getmac').getMac(function (err, mac) {
if (err) throw err
payload.mac = mac
// console.log(payload)
console.log("Registered our precense with master "+config.masterIP+" at " + payload.time);
needle.post(config.masterIP + ":" + config.masterPort + '/api/getID', payload, function (err, response, body) {
if (response && response.body) {
if (err && err.code != "ECONNRESET"){
console.error("We got problems, something went wrong when contacting master");
console.error(err);
} else if (response && response.body) {
// In the future we might be interested in whether or not we actually manage to send it, but honestly I don't care.
console.log(response.body)
}
+2 -1
View File
@@ -32,6 +32,7 @@
"portfinder": "^1.0.9",
"request": "^2.79.0",
"simple-rcon": "^0.3.1",
"sync-request": "^4.0.1"
"sync-request": "^4.0.1",
"underscore": "^1.8.3"
}
}
+1
View File
@@ -2,6 +2,7 @@
(function (){
ensureSetting("Display offline slaves", "boolean", false);
ensureSetting("Enable production graphs", "boolean", true);
ensureSetting("Periodically update storage screen", "boolean", true);
}())
function ensureSetting(setting, type, defaultSetting) {
+1 -1
View File
@@ -19,7 +19,7 @@ setTimeout(function() {
}
HTML += "<div class='slaveBox'>";
HTML += '<div id="' + slaveData[key].unique + '" class="productionGraph" style="width: calc(100% - 200px);"></div>';
HTML += "<h2>" + slaveData[key].instanceName + "</h2><p>ID: " + slaveData[key].unique + "</p><p>Last seen: "+seenDate+"</p><p>IP: "+slaveData[key].publicIP +":"+ slaveData[key].serverPort+"</p>"
HTML += "<h2>" + slaveData[key].instanceName + "</h2><p>ID: " + slaveData[key].unique + "</p><p>Last seen: "+seenDate+"</p><p>Online players: "+slaveData[key].playerCount+"</p><p>IP: "+slaveData[key].publicIP +":"+ slaveData[key].serverPort+"</p>"
HTML += "<p>Host: "+slaveData[key].mac+"</p>";
HTML += "<button onclick='hideAllDatasets(\"" + slaveData[key].unique + "\")\'>Hide all</button>";
HTML += "<button onclick='showAllDatasets(\"" + slaveData[key].unique + "\")\'>Show all</button>";
+10 -5
View File
@@ -1,7 +1,7 @@
// function to draw data we recieve from ajax requests
function drawcontents(data) {
var data = sortByKey(data, "count");
result = "<table>";
data = sortByKey(data, "count");
let result = "<table>";
for(i = 0;i < data.length; i++) {
var img = "";
if(imagedata[data[i].name]) {
@@ -18,17 +18,22 @@ function drawcontents(data) {
}
// get cluster inventory from master
setInterval(function() {
function updateInventory() {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if(xmlhttp.readyState == 4 && xmlhttp.status == 200) {
data = JSON.parse(xmlhttp.responseText);
let data = JSON.parse(xmlhttp.responseText);
drawcontents(data);
}
}
xmlhttp.open("GET", "api/inventory", true);
xmlhttp.send();
}, 500)
}
if(JSON.parse(localStorage.settings)["Periodically update storage screen"]) {
setInterval(updateInventory, 500);
} else {
updateInventory();
}
// function to sort arrays of objects after a keys value
function sortByKey(array, key) {