From 183902ced323bd873a0c5264b47f6a37ca6b6c78 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Fri, 11 Oct 2019 18:32:36 +0200 Subject: [PATCH 01/11] Port fix incorrect property checks in researchSync Fix naive checks for properties being set of the form obj[key] into the proper form Object.hasOwnProperty.call(obj, key). The reason for this is that if the key has a value of a built-in property like 'constructor' then a check of the form obj[key] will always return true even if that property hasn't been set on the object. This is a port of 6a6274e. --- CHANGELOG.md | 7 +++ sharedPlugins/researchSync/index.js | 69 ++++++++++++++++------------- 2 files changed, 45 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 824e2746..1ac4de35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,13 @@ Version 2.0.0 .ejs. Breaks playerManager. +Version 1.2.2 +------------- + +- Fixed possible crash with modded technologies named the same as a built-in + Object prototype property in researchSync. + + Version 1.2.1 ------------- diff --git a/sharedPlugins/researchSync/index.js b/sharedPlugins/researchSync/index.js index 918d63e9..1aeef8b0 100644 --- a/sharedPlugins/researchSync/index.js +++ b/sharedPlugins/researchSync/index.js @@ -145,10 +145,11 @@ class ResearchSync { } clear_contribution_to_researched_techs() { - // if between updates tech was researched - if (!this.prev_research) - return for (let [name, research] of Object.entries(this.research)) { + if (!Object.hasOwnProperty.call(this.prev_research, name)) { + continue; + } + let researched if (research.infinite) researched = this.prev_research[name].level < research.level @@ -168,7 +169,7 @@ class ResearchSync { if (isNaN(node_tech.researched) || isNaN(node_tech.level) || isNaN(node_tech.infinite)) continue - if (cluster_techs[name]) { + if (Object.hasOwnProperty.call(cluster_techs, name)) { if (cluster_techs[name].infinite === 1 && cluster_techs[name].level < node_tech.level) { cluster_techs[name].level = node_tech.level } else if (node_tech.researched > cluster_techs[name].researched) { @@ -188,8 +189,9 @@ class ResearchSync { for (let slave_data of slaves_data) { for (let [name, research] of Object.entries(slave_data.meta.research)) { - if (!cluster_researches[name]) - continue + if (!Object.hasOwnProperty.call(cluster_researches, name)) { + continue; + } if (isNaN(cluster_researches[name].progress) || isNaN(research.contribution) || isNaN(research.level) @@ -213,35 +215,37 @@ class ResearchSync { } filter_researched_techs(cluster_researches) { - let local_researches = this.research let result = {}; - for (let key in local_researches) { - if (!cluster_researches[key]) - continue - if (isNaN(cluster_researches[key].researched) || isNaN(cluster_researches[key].level)) + for (let [name, tech] of Object.entries(this.research)) { + if (!Object.hasOwnProperty.call(cluster_researches, name)) { + continue; + } + + if (isNaN(cluster_researches[name].researched) || isNaN(cluster_researches[name].level)) continue let researched - if (local_researches[key].infinite) - researched = local_researches[key].level < cluster_researches[key].level - else - researched = local_researches[key].researched < cluster_researches[key].researched + if (tech.infinite) { + researched = tech.level < cluster_researches[name].level; + } else { + researched = tech.researched < cluster_researches[name].researched; + } if (researched) - result[key] = cluster_researches[key] + result[name] = cluster_researches[name] } return result; } filter_updated_techs(cluster_techs, to_research) { - let local_techs = this.research let result = {} - for (let name in local_techs) { - if (name in to_research || !cluster_techs[name]) - continue + for (let [name, tech] of Object.entries(this.research)) { + if (Object.hasOwnProperty.call(to_research, name) || !Object.hasOwnProperty.call(cluster_techs, name)) { + continue; + } if (isNaN(cluster_techs[name].progress)) continue - if (local_techs[name].progress < cluster_techs[name].progress) + if (tech.progress < cluster_techs[name].progress) result[name] = cluster_techs[name] } return result @@ -249,8 +253,9 @@ class ResearchSync { research_technologies(to_research) { for (let name of Object.keys(to_research)) - if (!this.research[name]) - delete to_research[name] + if (!Object.hasOwnProperty.call(this.research, name)) { + delete to_research[name]; + } const notify = Object.keys(to_research).length === 1 for (let [name, tech] of Object.entries(to_research)) { @@ -274,8 +279,9 @@ class ResearchSync { update_technologies_progress(to_update) { for (let [name, tech] of Object.entries(to_update)) { - if (!this.research[name]) - continue + if (!Object.hasOwnProperty.call(this.research, name)) { + continue; + } let progress = this.research[name].progress if (progress === null) progress = 'nil' @@ -292,11 +298,10 @@ class ResearchSync { } print_own_contribution() { - if (!this.prev_research) - return for (let [name, tech] of Object.entries(this.research)) { - if (!this.prev_research[name]) - continue + if (!Object.hasOwnProperty.call(this.prev_research, name)) { + continue; + } let diff = this.research[name].contribution - this.prev_research[name].contribution if (Math.abs(diff) > Number.EPSILON * 1000) this.log(`Own research ${name}: ${this.research[name].progress} += ${diff}`) @@ -321,8 +326,10 @@ class ResearchSync { if (isNaN(level) || isNaN(researched)) return - this.prev_research[name] = this.research[name] - if (!this.prev_research[name]) { + + if (Object.hasOwnProperty.call(this.research, name)) { + this.prev_research[name] = this.research[name] + } else { this.prev_research[name] = { researched: null, level: null, From 9098b3cf19e2e631d7b17b87966004102dc94c54 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Fri, 11 Oct 2019 18:42:20 +0200 Subject: [PATCH 02/11] Port rename research to tech Use tech as the loop variable for researches as this is consistent with the rest of the researchSync module. This is a port of 3b1ed1a --- sharedPlugins/researchSync/index.js | 66 ++++++++++++++++------------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/sharedPlugins/researchSync/index.js b/sharedPlugins/researchSync/index.js index 1aeef8b0..1efcf93f 100644 --- a/sharedPlugins/researchSync/index.js +++ b/sharedPlugins/researchSync/index.js @@ -144,22 +144,24 @@ class ResearchSync { }) } - clear_contribution_to_researched_techs() { - for (let [name, research] of Object.entries(this.research)) { + clear_contribution_to_researched_techs() { + for (let [name, tech] of Object.entries(this.research)) { if (!Object.hasOwnProperty.call(this.prev_research, name)) { continue; } - let researched - if (research.infinite) - researched = this.prev_research[name].level < research.level - else - researched = this.prev_research[name].researched < research.researched + let researched; + if (tech.infinite) { + researched = this.prev_research[name].level < tech.level; + } else { + researched = this.prev_research[name].researched < tech.researched; + } - if (researched) - research.contribution = 0 - } - } + if (researched) { + tech.contribution = 0; + } + } + } get_cluster_techs(slavesData) { let cluster_techs = {} @@ -184,32 +186,38 @@ class ResearchSync { } recount_cluster_research_progress(slaves_data, cluster_researches) { - for (let [name, research] of Object.entries(cluster_researches)) - research.progress = this.research[name].contribution + for (let [name, tech] of Object.entries(cluster_researches)) + tech.progress = this.research[name].contribution for (let slave_data of slaves_data) { - for (let [name, research] of Object.entries(slave_data.meta.research)) { + for (let [name, tech] of Object.entries(slave_data.meta.research)) { if (!Object.hasOwnProperty.call(cluster_researches, name)) { continue; } - if (isNaN(cluster_researches[name].progress) - || isNaN(research.contribution) - || isNaN(research.level) - || isNaN(cluster_researches[name].level)) - continue - if (cluster_researches[name].level === research.level) - cluster_researches[name].progress += research.contribution + + if ( + isNaN(cluster_researches[name].progress) + || isNaN(tech.contribution) + || isNaN(tech.level) + || isNaN(cluster_researches[name].level) + ) { + continue; + } + + if (cluster_researches[name].level === tech.level) { + cluster_researches[name].progress += tech.contribution; + } } } - for (let [name, research] of Object.entries(cluster_researches)) { - if (research.progress > 1) { - research.progress = null - research.researched = 1 + for (let [name, tech] of Object.entries(cluster_researches)) { + if (tech.progress > 1) { + tech.progress = null + tech.researched = 1 this.research[name].contribution = 0 - research.contribution = 0 - if (this.research[name].level >= research.level) - research.level = this.research[name].level + 1 + tech.contribution = 0 + if (this.research[name].level >= tech.level) + tech.level = this.research[name].level + 1 } } } @@ -328,7 +336,7 @@ class ResearchSync { return if (Object.hasOwnProperty.call(this.research, name)) { - this.prev_research[name] = this.research[name] + this.prev_research[name] = this.research[name]; } else { this.prev_research[name] = { researched: null, From 7f82680511225b8324a3becddb08c6d2388e96e7 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Sat, 12 Oct 2019 01:45:41 +0200 Subject: [PATCH 03/11] Port set progress when completing infinite researches Set the progress for the next level of an infinite research when unlocking it via a script. This is necessary when the research is actively being researched as Factorio will carry over the progress for the current level into the next one when set via a script. It's possible for the new progress to be non-zero if the next level was on the research queue. This is a port of 62f3a99. --- CHANGELOG.md | 2 ++ sharedPlugins/researchSync/enableResearch.lua | 17 ++++++++++++----- sharedPlugins/researchSync/index.js | 2 +- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ac4de35..c35883c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,8 @@ Version 1.2.2 - Fixed possible crash with modded technologies named the same as a built-in Object prototype property in researchSync. +- Fixed progress of a current infinite tech carrying over to the next one + when researching it and another node completes it in researchSync. Version 1.2.1 diff --git a/sharedPlugins/researchSync/enableResearch.lua b/sharedPlugins/researchSync/enableResearch.lua index f83a1e93..8c8b7329 100644 --- a/sharedPlugins/researchSync/enableResearch.lua +++ b/sharedPlugins/researchSync/enableResearch.lua @@ -11,15 +11,22 @@ local function updateTech() end end -if game.forces['player'].technologies['{tech_name}'] then +local force = game.forces['player'] +local tech = force.technologies['{tech_name}'] +if tech then if 1 == {tech_infinite} then - if (game.forces['player'].technologies['{tech_name}'].level ~= level) then - game.forces['player'].technologies['{tech_name}'].level = {tech_level} + if (tech.level ~= level) then + tech.level = {tech_level} + if tech == force.current_research then + force.research_progress = {tech_progress} + else + force.set_saved_technology_progress(tech.name, {tech_progress}); + end updateTech() end else - if not game.forces['player'].technologies['{tech_name}'].researched then - game.forces['player'].technologies['{tech_name}'].researched = true + if not tech.researched then + tech.researched = true updateTech() end end diff --git a/sharedPlugins/researchSync/index.js b/sharedPlugins/researchSync/index.js index 1efcf93f..37fb7a0d 100644 --- a/sharedPlugins/researchSync/index.js +++ b/sharedPlugins/researchSync/index.js @@ -271,9 +271,9 @@ class ResearchSync { this.research[name].progress = null let command = this.functions.enableResearch; command = command.replace(/{tech_name}/g, name); - command = command.replace(/{tech_researched}/g, tech.researched); command = command.replace(/{tech_level}/g, tech.level); command = command.replace(/{tech_infinite}/g, tech.infinite); + command = command.replace(/{tech_progress}/g, tech.progress) command = command.replace(/{notify}/g, notify); this.messageInterface(command); let log_message = tech.infinite From 4eda983cf4de6cb86ca42f04ebfa571f16d69919 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Sat, 12 Oct 2019 02:01:46 +0200 Subject: [PATCH 04/11] Port filter out lower levels when syncing research Fix the next level of an infinite research getting updated with the progress of the previous level from other nodes in the cluster by filtering out infinite researches with a lower level than the local level. This is a port of 075d54f. --- CHANGELOG.md | 2 ++ sharedPlugins/researchSync/index.js | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c35883c0..de87842b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,8 @@ Version 1.2.2 Object prototype property in researchSync. - Fixed progress of a current infinite tech carrying over to the next one when researching it and another node completes it in researchSync. +- Fixed progress of a previous infinite tech from another node being applied + to the current one in researchSync. Version 1.2.1 diff --git a/sharedPlugins/researchSync/index.js b/sharedPlugins/researchSync/index.js index 37fb7a0d..1407b5d6 100644 --- a/sharedPlugins/researchSync/index.js +++ b/sharedPlugins/researchSync/index.js @@ -253,6 +253,12 @@ class ResearchSync { } if (isNaN(cluster_techs[name].progress)) continue + + // Do not update progress for infinite techs with a local level that's higher. + if (tech.infinite && tech.level > cluster_techs[name].level) { + continue; + } + if (tech.progress < cluster_techs[name].progress) result[name] = cluster_techs[name] } From 5d2432945616a3aed9bff3dc39c85ff89c9e72f2 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Sat, 12 Oct 2019 02:33:47 +0200 Subject: [PATCH 05/11] Port fix crash in recount_cluster_research_progress Check that the relevant research is present in the research mapping before accessing it in recount_cluster_research_progress. This is a port of 0cdb5d0. --- CHANGELOG.md | 2 ++ sharedPlugins/researchSync/index.js | 11 ++++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index de87842b..da7794b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,8 @@ Version 1.2.2 when researching it and another node completes it in researchSync. - Fixed progress of a previous infinite tech from another node being applied to the current one in researchSync. +- Fixed crash in researchSync when modded technologies are present only on some + nodes. Version 1.2.1 diff --git a/sharedPlugins/researchSync/index.js b/sharedPlugins/researchSync/index.js index 1407b5d6..5054083f 100644 --- a/sharedPlugins/researchSync/index.js +++ b/sharedPlugins/researchSync/index.js @@ -186,8 +186,13 @@ class ResearchSync { } recount_cluster_research_progress(slaves_data, cluster_researches) { - for (let [name, tech] of Object.entries(cluster_researches)) - tech.progress = this.research[name].contribution + for (let [name, tech] of Object.entries(cluster_researches)) { + if (Object.hasOwnProperty.call(this.research, name)) { + tech.progress = this.research[name].contribution + } else { + tech.progress = 0; + } + } for (let slave_data of slaves_data) { for (let [name, tech] of Object.entries(slave_data.meta.research)) { @@ -211,7 +216,7 @@ class ResearchSync { } for (let [name, tech] of Object.entries(cluster_researches)) { - if (tech.progress > 1) { + if (Object.hasOwnProperty.call(this.research, name) && tech.progress > 1) { tech.progress = null tech.researched = 1 this.research[name].contribution = 0 From de20635aea1a7982e58f26bdeb0e2bf433da57ec Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Sat, 12 Oct 2019 16:55:35 +0200 Subject: [PATCH 06/11] Port reorder install instructions Reorder the install pm2 step to be after the npm install step in the instructions. This is necessary to avoid npm creating some files in the home directory owned as root and then failing the npm install step because of this. This is a port of c25bf23. --- CHANGELOG.md | 2 ++ README.md | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index da7794b6..acb0833d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,8 @@ Version 1.2.2 to the current one in researchSync. - Fixed crash in researchSync when modded technologies are present only on some nodes. +- Reordered install instructions to avoid problem with npm creating files owned + by root in the home directory. Version 1.2.1 diff --git a/README.md b/README.md index 695077ad..d3f522dd 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,6 @@ Master and all slaves: sudo curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash - sudo apt install -y nodejs python-dev git wget curl tar build-essential - sudo npm install pm2 -g git clone -b 1.2.x https://github.com/clusterio/factorioClusterio.git cd factorioClusterio curl -o factorio.tar.gz -L https://www.factorio.com/get-download/latest/headless/linux64 @@ -110,8 +109,11 @@ Master and all slaves: cp config.json.dist config.json node ./lib/npmPostinstall.js +downloads and installs nodejs, git and clusterio. To specify a version, change "latest" in the link to a version number like 0.14.21. -downloads and installs nodejs, pm2, git and clusterio. To specify a version, change "latest" in the link to a version number like 0.14.21. +Optional step (if you want to use pm2): + + sudo npm install pm2 -g Now you need to edit the `config.json` file. If you skip this step nothing will work. Pretty much all the blank fields should be filled in, except on the master where a few can be omitted. From 77571d3c712d661a55364fc248c7f114e983b509 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Sat, 12 Oct 2019 16:57:48 +0200 Subject: [PATCH 07/11] Port swap curl with wget in install instructions Swap out curl with wget in the install instructions as wget is pre-installed on Ubuntu. This is a port of 72b56a0 and dbef2bd. --- CHANGELOG.md | 2 ++ README.md | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index acb0833d..6e331835 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,8 @@ Version 1.2.2 nodes. - Reordered install instructions to avoid problem with npm creating files owned by root in the home directory. +- Swapped curl out with wget in the install instructions as the latter comes + pre-installed on Ubuntu. Version 1.2.1 diff --git a/README.md b/README.md index d3f522dd..7429b797 100644 --- a/README.md +++ b/README.md @@ -99,11 +99,11 @@ NodeJS does not support EOL ubuntu releases. Make sure you are on the most recen Master and all slaves: - sudo curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash - - sudo apt install -y nodejs python-dev git wget curl tar build-essential + wget -qO - https://deb.nodesource.com/setup_10.x | sudo -E bash - + sudo apt install -y nodejs python-dev git build-essential git clone -b 1.2.x https://github.com/clusterio/factorioClusterio.git cd factorioClusterio - curl -o factorio.tar.gz -L https://www.factorio.com/get-download/latest/headless/linux64 + wget -O factorio.tar.gz https://www.factorio.com/get-download/latest/headless/linux64 tar -xf factorio.tar.gz npm install --only=production cp config.json.dist config.json From 999fb79570149b83906ecfd766dea2116476d986 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Sat, 12 Oct 2019 22:57:41 +0200 Subject: [PATCH 08/11] Fix changelog entries for 1.2.2 Move node v10 requirement to 1.2.2 and add changelog entry for updating bcrypt (which has already been done for the master branch.) --- CHANGELOG.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e331835..afd8f639 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,6 @@ Version 2.0.0 ### Breaking Changes -- Node.js versions below 10 are no longer supported. - lib/authenticate no longer requires config to be passed to it. Breaks playerManager. - The masterIP and masterPort config entries has been merged into masterURL. @@ -39,11 +38,17 @@ Version 1.2.2 to the current one in researchSync. - Fixed crash in researchSync when modded technologies are present only on some nodes. +- Fixed install failing due to bcrypt version less than 3 not being supported + on node v10. - Reordered install instructions to avoid problem with npm creating files owned by root in the home directory. - Swapped curl out with wget in the install instructions as the latter comes pre-installed on Ubuntu. +### Breaking Changes + +- Node.js versions below 10 are no longer supported. + Version 1.2.1 ------------- From e8d9d160c4cbad0f328ae27da2d880d682bae19b Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Sat, 12 Oct 2019 23:36:43 +0200 Subject: [PATCH 09/11] Port recommend running without pm2 first Recommend running master server without pm2 first as this makes discovering any potential errors much simpler. This is a port of 6e26d32. --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7429b797..c83ae930 100644 --- a/README.md +++ b/README.md @@ -126,11 +126,12 @@ Pretty much all the blank fields should be filled in, except on the master where **Master** + node master.js + +Or with pm2 (it's recommened to run it without pm2 first): + pm2 start master.js --name master -OR - - node master.js **Server Host** From 34fc6f0820e6a484d19559d086a2c811b69c3aa6 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Sat, 12 Oct 2019 23:39:40 +0200 Subject: [PATCH 10/11] Port exit if masterAuthToken is missing Exit client.js with a non-zero exit code if it's detected that the masterAuthToken is missing in the config. This is a port of 8b4ec58. --- client.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/client.js b/client.js index f4318ae4..ddeec91b 100644 --- a/client.js +++ b/client.js @@ -631,9 +631,14 @@ async function startClient() { // make sure we have the master access token (can't write to master without it since clusterio 2.0) if(!config.masterAuthToken || typeof config.masterAuthToken !== "string"){ console.error("ERROR invalid config!"); - console.error("Master server now needs an access token for write operations. As clusterio slaves depends \ - upon this, please add your token to config.json in the field named masterAuthToken. \ - You can retrieve your auth token from the master in secret-api-token.txt after running it once."); + console.error( + "Master server now needs an access token for write operations. As clusterio\n"+ + "slaves depends upon this, please add your token to config.json in the field\n"+ + "named masterAuthToken. You can retrieve your auth token from the master in\n"+ + "secret-api-token.txt after running it once." + ); + process.exitCode = 1; + return; } // messageInterface Management From debb33eb3fbc2afb29c7cb839a0cdb0cc3f57eca Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Sat, 12 Oct 2019 15:50:36 +0200 Subject: [PATCH 11/11] Change instructions to install master branch Change back the instructions in README.md to install the master branch of clusterio and add warnings for this in the relevant locations directing users to the stable branch for instructions on how to install the stable version. --- README.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c83ae930..88dbcf95 100644 --- a/README.md +++ b/README.md @@ -13,11 +13,13 @@ Discord for development/support/play: https://discord.gg/5XuDkje This is the development branch for factorioClusterio 2.0 which is currently undergoing heavy restructuring and refactoring. Expect plugins and existing installations to frequently break when using this branch. If you don't want to be an alpha tester for 2.0 please use the stable -[1.2.x branch](https://github.com/clusterio/factorioClusterio/tree/1.2.x) or +[1.2.x branch][1.2.x] or [latest stable release](https://github.com/clusterio/factorioClusterio/releases/latest). -Installation instructions below are for stable release - if you need a development version - -just drop `-b 1.2.x` from clone command and `--only=production` from the `npm install` command. +Installation instructions below are for the unstable master branch. Go to the page for +the [1.2.x branch][1.2.x] for instructions on how to install the stable version. + +[1.2.x]: https://github.com/clusterio/factorioClusterio/tree/1.2.x ### Ways to support me/the project: @@ -95,13 +97,16 @@ Clusterio can also do a few other neat things, such as giving you access to epoc ## Ubuntu setup +**Warning**: These instructions are for the unstable master version and is not +recommended for use, see [the 1.2.x branch][1.2.x] for how to install the stable version. + NodeJS does not support EOL ubuntu releases. Make sure you are on the most recent LTS release or newer. Master and all slaves: wget -qO - https://deb.nodesource.com/setup_10.x | sudo -E bash - sudo apt install -y nodejs python-dev git build-essential - git clone -b 1.2.x https://github.com/clusterio/factorioClusterio.git + git clone -b master https://github.com/clusterio/factorioClusterio.git cd factorioClusterio wget -O factorio.tar.gz https://www.factorio.com/get-download/latest/headless/linux64 tar -xf factorio.tar.gz @@ -163,6 +168,9 @@ The -v flag is used to specify the instance directory. Your instances (save file ## Windows setup +**Warning**: These instructions are for the unstable master version and is not +recommended for use, see [the 1.2.x branch][1.2.x] for how to install the stable version. + Clusterio is built up of multiple parts. Here is a quick guide: Master = master.js