From 6a6274e85c2789758a52aa60b2f363832a678f34 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Fri, 11 Oct 2019 18:32:36 +0200 Subject: [PATCH 1/5] 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. --- CHANGELOG.md | 7 +++ package.json | 2 +- sharedPlugins/researchSync/index.js | 69 ++++++++++++++++------------- 3 files changed, 46 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63f1da2f..faf69858 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ Changelog ========= +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/package.json b/package.json index bd47e6a5..43149858 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "clusterio", - "version": "1.2.1", + "version": "1.2.2-alpha", "description": "Interserver communication for factorio", "repository": "https://github.com/Danielv123/factorioClusterio", "main": "master.js", diff --git a/sharedPlugins/researchSync/index.js b/sharedPlugins/researchSync/index.js index 395e885a..91935839 100644 --- a/sharedPlugins/researchSync/index.js +++ b/sharedPlugins/researchSync/index.js @@ -170,10 +170,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 @@ -193,7 +194,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) { @@ -213,8 +214,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) @@ -238,35 +240,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 @@ -274,8 +278,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)) { @@ -299,8 +304,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' @@ -317,11 +323,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}`) @@ -346,8 +351,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 3b1ed1a6674faedba29bc02ffb0a3716427dad35 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Fri, 11 Oct 2019 18:42:20 +0200 Subject: [PATCH 2/5] Rename research to tech Use tech as the loop variable for researches as this is consistent with the rest of the researchSync module. --- 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 91935839..e595597a 100644 --- a/sharedPlugins/researchSync/index.js +++ b/sharedPlugins/researchSync/index.js @@ -169,22 +169,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 = {} @@ -209,32 +211,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 } } } @@ -353,7 +361,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 62f3a99febc7bb9b4b4ea7a1ae677bb6bace7f1f Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Sat, 12 Oct 2019 01:45:41 +0200 Subject: [PATCH 3/5] 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. --- 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 faf69858..ee540aaa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,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 e595597a..a2e7a840 100644 --- a/sharedPlugins/researchSync/index.js +++ b/sharedPlugins/researchSync/index.js @@ -296,9 +296,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 075d54f7088354e8e1d9dcf8467696d24d2b39a6 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Sat, 12 Oct 2019 02:01:46 +0200 Subject: [PATCH 4/5] 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. --- CHANGELOG.md | 2 ++ sharedPlugins/researchSync/index.js | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee540aaa..994793f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,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 a2e7a840..17ee5c09 100644 --- a/sharedPlugins/researchSync/index.js +++ b/sharedPlugins/researchSync/index.js @@ -278,6 +278,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 0cdb5d0ce4689f310262c7217ada0b5ebc777f5c Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Sat, 12 Oct 2019 02:33:47 +0200 Subject: [PATCH 5/5] 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. --- CHANGELOG.md | 2 ++ sharedPlugins/researchSync/index.js | 11 ++++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 994793f7..bc6b8b4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,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 17ee5c09..1a0cdd7d 100644 --- a/sharedPlugins/researchSync/index.js +++ b/sharedPlugins/researchSync/index.js @@ -211,8 +211,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)) { @@ -236,7 +241,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