mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-13 23:14:53 +09:00
Merge branch 'master' into spread_researching
# Conflicts: # sharedPlugins/researchSync/dumpResearch.lua # sharedPlugins/researchSync/index.js
This commit is contained in:
commit
93c210f0c7
6 files changed
+107
-55
No files matched your search
@@ -378,8 +378,13 @@ app.post("/api/getSlaveMeta", function (req, res) {
|
||||
endpointHitCounter.labels(req.route.path).inc();
|
||||
console.log("body", req.body);
|
||||
if(req.body && req.body.instanceID && req.body.password){
|
||||
console.log("returning meta for ", req.body.instanceID);
|
||||
res.send(JSON.stringify(slaves[req.body.instanceID].meta))
|
||||
if (slaves[req.body.instanceID]) {
|
||||
console.log("returning meta for ", req.body.instanceID);
|
||||
res.send(JSON.stringify(slaves[req.body.instanceID].meta))
|
||||
} else {
|
||||
res.status(404)
|
||||
res.send('{"status": 404, "info": "Slave not registered"}')
|
||||
}
|
||||
} else {
|
||||
res.status(400);
|
||||
res.send('{"INVALID REQUEST":1}');
|
||||
|
||||
@@ -9,11 +9,13 @@ for _, tech in pairs(force.technologies) do
|
||||
else
|
||||
progress = force.get_saved_technology_progress(tech.name);
|
||||
end
|
||||
local infinite = tech.enabled == true and tech.prototype.max_level == 4294967295;
|
||||
local tech_data = {
|
||||
tech.name,
|
||||
tostring(tech.researched),
|
||||
tostring(tech.level),
|
||||
tostring(progress),
|
||||
tostring(infinite),
|
||||
}
|
||||
tech_data = table.concat(tech_data, ':')
|
||||
table.insert(data, tech_data);
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
|
||||
if game.forces['player'].technologies['{tech_name}'] then
|
||||
if game.forces['player'].technologies['{tech_name}'].researched ~= {tech_researched} then
|
||||
game.forces['player'].technologies['{tech_name}'].researched = {tech_researched}
|
||||
end
|
||||
if game.forces['player'].technologies['{tech_name}'].level ~= {tech_level} then
|
||||
game.forces['player'].technologies['{tech_name}'].level = {tech_level}
|
||||
end
|
||||
if 1 == {tech_infinite} then
|
||||
game.forces['player'].technologies['{tech_name}'].level = {tech_level}
|
||||
else
|
||||
game.forces['player'].technologies['{tech_name}'].researched = true
|
||||
end
|
||||
script.raise_event(defines.events.on_research_finished, {research=game.forces['player'].technologies['{tech_name}'], by_script=true})
|
||||
game.play_sound({path="utility/research_completed"})
|
||||
if game.forces['player'].technologies['{tech_name}'].researched == false then
|
||||
game.print("Technology {tech_name} synced at level {tech_level}")
|
||||
else
|
||||
game.print("Technology {tech_name} synced")
|
||||
end
|
||||
if {notify} then
|
||||
if 1 == {tech_infinite} then
|
||||
game.print("Infinite technology {tech_name} level {tech_level} unlocked")
|
||||
else
|
||||
game.print("Technology {tech_name} researched")
|
||||
end
|
||||
game.play_sound({path="utility/research_completed"})
|
||||
end
|
||||
end
|
||||
@@ -1,10 +1,6 @@
|
||||
const fs = require('fs');
|
||||
const needle = require("needle");
|
||||
|
||||
function format_tech(tech) {
|
||||
return `${!!tech.researched} at level ${tech.level}`
|
||||
}
|
||||
|
||||
|
||||
class ResearchSync {
|
||||
constructor(slaveConfig, messageInterface, extras = {}){
|
||||
@@ -39,6 +35,14 @@ class ResearchSync {
|
||||
console.error(err)
|
||||
return
|
||||
}
|
||||
if (res.statusCode === 404) {
|
||||
console.log('researchSync: slave is not registered yet. Delaying for 5 secs')
|
||||
setTimeout(
|
||||
() => this.initial_request_own_data(callback),
|
||||
5000
|
||||
)
|
||||
return
|
||||
}
|
||||
if (res.statusCode !== 200) {
|
||||
console.log(`Can't get own slave data:`)
|
||||
console.error(`status code ${res.statusCode}, ${res.body}`)
|
||||
@@ -47,6 +51,7 @@ class ResearchSync {
|
||||
techs = JSON.parse(techs)
|
||||
if (typeof techs.research === 'object')
|
||||
this.research = techs.research
|
||||
console.log('researchSync: techs imported from master')
|
||||
callback()
|
||||
})
|
||||
}
|
||||
@@ -82,6 +87,7 @@ class ResearchSync {
|
||||
&& slave_data.meta && slave_data.meta.research
|
||||
)
|
||||
|
||||
this.clear_contribution_to_researched_techs()
|
||||
let cluster_techs = this.get_cluster_techs(slaves_data)
|
||||
this.recount_cluster_research_progress(slaves_data, cluster_techs)
|
||||
|
||||
@@ -98,6 +104,7 @@ class ResearchSync {
|
||||
password: this.config.clientPassword,
|
||||
meta: {research: this.research}
|
||||
}, {headers: {'x-access-token': this.config.masterAuthToken}, json: true}, function (err, resp) {
|
||||
// it doesn't get called
|
||||
if (err)
|
||||
console.error(err)
|
||||
else
|
||||
@@ -105,27 +112,42 @@ 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)) {
|
||||
let researched
|
||||
if (research.infinite)
|
||||
researched = this.prev_research[name].level < research.level
|
||||
else
|
||||
researched = this.prev_research[name].researched < research.researched
|
||||
|
||||
if (researched)
|
||||
research.contribution = 0
|
||||
}
|
||||
}
|
||||
|
||||
get_cluster_techs(slavesData) {
|
||||
let researches = {}
|
||||
let cluster_techs = {}
|
||||
for (let slave_data of slavesData) {
|
||||
let node_researches = slave_data.meta.research
|
||||
for (let [name, research] of Object.entries(node_researches)) {
|
||||
if (isNaN(research.researched) || isNaN(research.level))
|
||||
for (let [name, node_tech] of Object.entries(node_researches)) {
|
||||
if (isNaN(node_tech.researched) || isNaN(node_tech.level) || isNaN(node_tech.infinite))
|
||||
continue
|
||||
|
||||
if (researches[name]) {
|
||||
if (researches[name].researched === 0) {
|
||||
researches[name].researched = research.researched
|
||||
}
|
||||
if (researches[name].level < research.level) {
|
||||
researches[name].level = research.level
|
||||
if (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) {
|
||||
cluster_techs[name].researched = 1
|
||||
}
|
||||
} else {
|
||||
researches[name] = research
|
||||
cluster_techs[name] = node_tech
|
||||
}
|
||||
}
|
||||
}
|
||||
return researches
|
||||
return cluster_techs
|
||||
}
|
||||
|
||||
recount_cluster_research_progress(slaves_data, cluster_researches) {
|
||||
@@ -158,10 +180,14 @@ class ResearchSync {
|
||||
if (isNaN(cluster_researches[key].researched) || isNaN(cluster_researches[key].level))
|
||||
continue
|
||||
|
||||
if (cluster_researches[key].researched > local_researches[key].researched
|
||||
|| cluster_researches[key].level > local_researches[key].level) {
|
||||
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 (researched)
|
||||
result[key] = cluster_researches[key]
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -181,22 +207,26 @@ class ResearchSync {
|
||||
}
|
||||
|
||||
research_technologies(to_research) {
|
||||
for (let [name, tech] of Object.entries(to_research)) {
|
||||
for (let name of Object.keys(to_research))
|
||||
if (!this.research[name])
|
||||
continue
|
||||
delete to_research[name]
|
||||
|
||||
const notify = Object.keys(to_research).length === 1
|
||||
for (let [name, tech] of Object.entries(to_research)) {
|
||||
this.research[name].contribution = 0
|
||||
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(/{notify}/g, notify);
|
||||
this.messageInterface(command);
|
||||
console.log(
|
||||
`Unlocking ${name}: ${format_tech(tech)}, was ${format_tech(this.research[name])}`
|
||||
);
|
||||
this.messageInterface(
|
||||
`Unlocking research: ${name} with research state ${format_tech(tech)}`
|
||||
);
|
||||
let log_message = tech.infinite
|
||||
? `Unlocking infinite research ${name} at level ${this.research[name].level}`
|
||||
: `Unlocking research ${name}`
|
||||
console.log(log_message);
|
||||
this.messageInterface(log_message);
|
||||
this.research[name] = tech;
|
||||
}
|
||||
}
|
||||
@@ -210,7 +240,6 @@ class ResearchSync {
|
||||
progress = 'nil'
|
||||
let command = this.functions.updateProgress
|
||||
command = command.replace(/{tech_name}/g, name)
|
||||
|
||||
command = command.replace(/{last_check_progress}/g, progress)
|
||||
command = command.replace(/{new_progress}/g, tech.progress)
|
||||
this.messageInterface(command);
|
||||
@@ -240,8 +269,9 @@ class ResearchSync {
|
||||
return command;
|
||||
}
|
||||
scriptOutput(data) {
|
||||
let [name, researched, level, progress] = data.split(":")
|
||||
researched = +(researched === 'true');
|
||||
let [name, researched, level, progress, infinite] = data.split(":")
|
||||
researched = +(researched === 'true')
|
||||
infinite = +(infinite === 'true')
|
||||
level = parseInt(level);
|
||||
if (progress === 'nil')
|
||||
progress = null
|
||||
@@ -257,13 +287,15 @@ class ResearchSync {
|
||||
level: null,
|
||||
progress: null,
|
||||
contribution: 0,
|
||||
infinite,
|
||||
}
|
||||
}
|
||||
this.research[name] = {
|
||||
researched,
|
||||
level,
|
||||
progress,
|
||||
contribution: this.prev_research[name].contribution
|
||||
contribution: this.prev_research[name].contribution,
|
||||
infinite
|
||||
}
|
||||
if (this.prev_research[name].progress && this.research[name].progress) {
|
||||
// this.prev_research[name].progress gets updated to overall cluster progress
|
||||
|
||||
@@ -20,13 +20,19 @@ module.exports = class remoteCommands {
|
||||
setInterval(async () => {
|
||||
let stats = await this.getStats();
|
||||
stats.forEach(force => {
|
||||
needle.post(`${mergedConfig.masterIP}:${mergedConfig.masterPort}/api/logStats`, {
|
||||
// I have no idea why I need to do JSON.stringify before passing it to needle.post,
|
||||
// but if you do forceData: force.data, it doesn't work...
|
||||
let request = {
|
||||
instanceID: this.config.unique,
|
||||
force: force.forceName,
|
||||
data: force.data,
|
||||
}, needleOptionsWithTokenAuthHeader, (err, resp) => {
|
||||
if(!err && resp.body && resp.body.ok == false) console.log(resp.body);
|
||||
});
|
||||
forceData: JSON.stringify(force.data),
|
||||
};
|
||||
needle.post(`${mergedConfig.masterIP}:${mergedConfig.masterPort}/api/logStats`,
|
||||
request,
|
||||
needleOptionsWithTokenAuthHeader, (err, resp) => {
|
||||
if(!err && resp.body && resp.body.ok == false) console.log("Error calling /api/logStats: " + resp.body);
|
||||
}
|
||||
);
|
||||
});
|
||||
}, 15000);
|
||||
}
|
||||
|
||||
@@ -26,18 +26,22 @@ class masterPlugin {
|
||||
@returns {string} failure
|
||||
*/
|
||||
app.post("/api/logStats", authenticate.middleware, function(req,res) {
|
||||
let data = req.body.forceData;
|
||||
if(typeof req.body.forceData == "string") {
|
||||
data = JSON.parse(req.body.forceData);
|
||||
}
|
||||
// endpointHitCounter.labels(req.route.path).inc();
|
||||
if(typeof req.body == "object"
|
||||
&& req.body.instanceID
|
||||
&& typeof req.body.instanceID == "string"
|
||||
&& req.body.instanceID.length < 100
|
||||
&& req.body.data
|
||||
&& typeof req.body.data == "object"
|
||||
&& !Array.isArray(req.body.data)){
|
||||
&& data
|
||||
&& typeof data == "object"
|
||||
&& !Array.isArray(data)){
|
||||
try{
|
||||
Object.keys(req.body.data).forEach(statisticName => {
|
||||
Object.keys(req.body.data[statisticName]).forEach(direction => {
|
||||
let statHash = req.body.data[statisticName][direction];
|
||||
Object.keys(data).forEach(statisticName => {
|
||||
Object.keys(data[statisticName]).forEach(direction => {
|
||||
let statHash = data[statisticName][direction];
|
||||
Object.keys(statHash).forEach(item => {
|
||||
let value = Number(statHash[item]);
|
||||
if(value) prometheusStatisticsGauge.labels(req.body.instanceID, req.body.force, statisticName, direction, item).set(value);
|
||||
@@ -50,6 +54,8 @@ class masterPlugin {
|
||||
console.log(e)
|
||||
};
|
||||
} else {
|
||||
console.log(`/api/logStats: Invalid request. instanceID: ${req.body.instanceID}, dataIsArray: `
|
||||
+ `${Array.isArray(data)}, ${typeof req.body.instanceID}, ${typeof data}`);
|
||||
res.send({
|
||||
ok:false,
|
||||
msg:"Invalid request parameters"
|
||||
|
||||
Reference in new issue
Block a user