From 6415784e8a5c377db5258da61d2be164dd618a79 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Wed, 7 Aug 2019 16:03:51 +0200 Subject: [PATCH] Remove outdated remoteMap Remove the old and outdated remoteMap plugin. Also removes the directory for linvodb in databases and the troubleshooting step related to linvodb. --- README.md | 12 -- lib/npmPostinstall.js | 1 - sharedPlugins/remoteMap/DISABLED | 0 sharedPlugins/remoteMap/chunkStore.js | 100 ------------ sharedPlugins/remoteMap/chunkStore.spec.js | 65 -------- sharedPlugins/remoteMap/config.js | 16 -- sharedPlugins/remoteMap/control.lua | 145 ------------------ .../remoteMap/destroyEntityCommand.lua | 5 - sharedPlugins/remoteMap/index.js | 130 ---------------- sharedPlugins/remoteMap/index.spec.js | 10 -- sharedPlugins/remoteMap/info.json | 11 -- 11 files changed, 495 deletions(-) delete mode 100644 sharedPlugins/remoteMap/DISABLED delete mode 100644 sharedPlugins/remoteMap/chunkStore.js delete mode 100644 sharedPlugins/remoteMap/chunkStore.spec.js delete mode 100644 sharedPlugins/remoteMap/config.js delete mode 100644 sharedPlugins/remoteMap/control.lua delete mode 100644 sharedPlugins/remoteMap/destroyEntityCommand.lua delete mode 100644 sharedPlugins/remoteMap/index.js delete mode 100644 sharedPlugins/remoteMap/index.spec.js delete mode 100644 sharedPlugins/remoteMap/info.json diff --git a/README.md b/README.md index 68efdcbe..b8cc1903 100644 --- a/README.md +++ b/README.md @@ -230,18 +230,6 @@ According to [this link](https://askubuntu.com/questions/839520/open-port-443-fo sudo setcap 'cap_net_bind_service=+ep' $(readlink -f $(which node)) -### InitializationError: First argument must be an abstract-leveldown compliant store - -do: - - npm install linvodb3@3.25.1 - -if that does not suffice do - - npm install levelup@1.3.9 - -If it still doesn't work, come over to our support discord linked at the top of this readme. - ### Portforwarding doesn't work on the master server when running under WSL If you follow the ubuntu guide on WSL (Windows Subsystem for Linux, Bash on Ubuntu on Windows specifically), you will find that the website works on localhost and on your local ip, but not on the global ip. This is also true when you correctly port-forwarded the correct ports. Even when routing this server through nginx in WSL, the issue persists. Then, on a hunch, I tried to run nginx from windows itself and found that this DID work. It came to me that the only usage difference between the 2 versions of nginx is that I got a Windows Firewall popup. diff --git a/lib/npmPostinstall.js b/lib/npmPostinstall.js index 842efdb7..70ee1417 100644 --- a/lib/npmPostinstall.js +++ b/lib/npmPostinstall.js @@ -56,7 +56,6 @@ function download(url, file, callback){ } var directories = [ - "database/linvodb", "sharedMods", "instances", ]; diff --git a/sharedPlugins/remoteMap/DISABLED b/sharedPlugins/remoteMap/DISABLED deleted file mode 100644 index e69de29b..00000000 diff --git a/sharedPlugins/remoteMap/chunkStore.js b/sharedPlugins/remoteMap/chunkStore.js deleted file mode 100644 index 4e33b1f3..00000000 --- a/sharedPlugins/remoteMap/chunkStore.js +++ /dev/null @@ -1,100 +0,0 @@ -var mkdirp = require("mkdirp-promise"); -var mkdirpSync = require("mkdirp").sync; -var fs = require("fs"); -var events = require("events"); -var path = require("path"); - -var objectOps = require("lib/objectOps"); - -var LinvoDB = require("linvodb3"); -// LinvoDB.dbPath = "./database/linvodb/"; - - -let allowLogging = true; -let log = string => (allowLogging)? console.log(string):"" - -module.exports = class chunkStore { - constructor(name, chunkSize = 32, path = "./chunkStore/"){ - if(!name || (typeof name != "string" && typeof name != "number")) throw new Error("chunkstore requires a name string as first param"); - name = name.toString(); - this.name = name; - this.chunkSize = chunkSize; - this.path = (path[path.length] == "/") ? path : path+"/"; - mkdirpSync(path+name); - LinvoDB.dbPath = this.path; - - this.db = new LinvoDB(name, {}, {}); - - this.eventEmitter = new events.EventEmitter(); - } - setEntity(x/**{number}*/, y/**{number}*/, newEntity/**{object}*/){ - return new Promise((resolve, reject) => { - x = Math.floor(x); - y = Math.floor(y); - this.db.find({x, y}, (err, docs) => { - if(typeof newEntity == "object"){ - if(err) reject(err); - let entityDoc = {x, y, entity: newEntity}; - if(docs && docs[0] && docs[0]._id){ - entityDoc._id = docs[0]._id; - } - this.db.save(entityDoc, (err,docs) => { - if(err) reject(err); - resolve(docs); - this.eventEmitter.emit("change", docs) - }); - } else { - docs.forEach(doc => { - doc.remove(()=>{ - // removed :) - }); - }); - resolve(); - this.eventEmitter.emit("change", {x,y}); - } - }); - }); - } - getEntity(x, y){ - return new Promise((resolve, reject) => { - this.db.find({x:Math.floor(x), y:Math.floor(y)}, (err, docs) => { - if(err) reject(err); - resolve(docs); - }); - }); - } - onEntityChange(eventhandler/**function*/){ - if(typeof eventhandler == "function") { - this.eventEmitter.on("change", eventhandler); - } - } - getChunk(x, y){ - return new Promise((resolve, reject) => { - - /* - // make new chunk in case we can't find an existing one - let chunk = { - dataObject: {}, - position:{x,y}, // fancy ES6 feature that generates to {x:x, y:y} - chunkSize:this.chunkSize - }; - fs.readFile(this.path+this.name+"/"+x+"/"+y, (err, chunkFile) => { - - if(err){ - log(err) - resolve(chunk); - } else { - if(objectOps.isJSON(chunkFile)) { - log("returned from file") - let chunk = JSON.parse(chunkFile); - resolve(chunk); - } else { - log("file failed") - resolve(chunk); - } - } - }); // add x and y values as well and we are done? - */ - }); - } -} \ No newline at end of file diff --git a/sharedPlugins/remoteMap/chunkStore.spec.js b/sharedPlugins/remoteMap/chunkStore.spec.js deleted file mode 100644 index a14fb38d..00000000 --- a/sharedPlugins/remoteMap/chunkStore.spec.js +++ /dev/null @@ -1,65 +0,0 @@ -return // Disabled until it actually works -var assert = require("assert"); - -var chunkStore = require("./chunkStore.js"); - -describe("remoteMap/chunkStore.js", () => { - // define some values for our test - const inserterX = 14.5; // rounds to 15 - const inserterY = -17.5; // rounds to -17, +64 would be 47 - const inserterName = "inserter"; - - let store // make our store elevated - it("is a constructor", ()=>{ - assert.equal(typeof chunkStore, "function"); - // create a new store and elevate it - store = new chunkStore("910239"/* instanceID, use defaults for the rest */, undefined, "./database/unitTests/chunkStore/"); - assert.equal(store.name, "910239"); - }); - it("allows you to store the locations of entities", done => { - store.setEntity(inserterX, inserterY, {name:inserterName, otherData:"can be arbitrary"}).then(() => { - done(); - // nothing to do here really - }); - }); - it("returns entities at positions you query for", done => { - setTimeout(()=>{ - store.getEntity(inserterX, inserterY).then(entities => { - entity = entities[0] - // console.log(entity) - assert.equal(entity.x, 14); - assert.equal(entity.y, -18); - assert.equal(entity.entity.name, "inserter"); - assert.equal(entity.entity.otherData, "can be arbitrary"); - done(); - }); - },300); - }); - it("deletes entities when not provided with an object as 3rd arg", done => { - store.setEntity(inserterX, inserterY).then(entity => { - assert(entity === undefined); - setTimeout(()=>{ - store.getEntity(inserterX, inserterY).then(entities => { - // console.log(entities) - assert.equal(entities.length, 0, "Why are we getting results, it should be empty?"); - done(); - }); - },300); - }); - }); - describe("validates input by throwing when it is invalid", ()=>{ - it("throws if called without a string as the first parameter", ()=>{ - assert.throws(()=>{ - let throwingChunkStore = new chunkStore(undefined, undefined, "asdasda"); - }); - assert.throws(()=>{ - let throwingChunkStore = new chunkStore({}, undefined, "asdasdas"); - }); - }); - it("converts numbers to strings automatically if they are provided as the first parameter", ()=>{ - assert.ok(()=>{ - let nonThrowingChunkStore = new chunkStore(42, undefined, "./database/unitTests/chunkStore/"); - }); - }); - }); -}); diff --git a/sharedPlugins/remoteMap/config.js b/sharedPlugins/remoteMap/config.js deleted file mode 100644 index f210afc1..00000000 --- a/sharedPlugins/remoteMap/config.js +++ /dev/null @@ -1,16 +0,0 @@ -/* - Config for clusterio remote mapping plugin. Will handle writing out new map data, aggregating it and sending it to the master (or something) for - display/interaction. -*/ -var modInfo = require("./info.json"); -module.exports = { - // Name of package. For display somewhere I guess. - name: modInfo.name, - version: modInfo.version, - // Binary entrypoint for plugin. Don't let it crash. Stdout is sent to game as server chat (run /c commands from here for interface) - // Make sure its cross platform somehow. - binary: "nodePackage", - description: modInfo.description, - // We'll send everything in this file to your stdin. Beware. - scriptOutputFileSubscription: "remoteMap.txt", -} \ No newline at end of file diff --git a/sharedPlugins/remoteMap/control.lua b/sharedPlugins/remoteMap/control.lua deleted file mode 100644 index c9d3826d..00000000 --- a/sharedPlugins/remoteMap/control.lua +++ /dev/null @@ -1,145 +0,0 @@ --- MIT License --- --- Copyright (c) 2017 Florian Jung --- --- Permission is hereby granted, free of charge, to any person obtaining a --- copy of this factorio lua stub and associated --- documentation files (the "Software"), to deal in the Software without --- restriction, including without limitation the rights to use, copy, modify, --- merge, publish, distribute, sublicense, and/or sell copies of the --- Software, and to permit persons to whom the Software is furnished to do --- so, subject to the following conditions: --- --- The above copyright notice and this permission notice shall be included in --- all copies or substantial portions of the Software. --- --- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL --- THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING --- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER --- DEALINGS IN THE SOFTWARE. - -function write_file(data) - stringsToWriteNextTick = stringsToWriteNextTick .. data .. '\n' - -- game.write_file("remoteMap.txt", data, true) -end - -function dump_cached_writes() - game.write_file("remoteMap.txt", stringsToWriteNextTick, true, 0) -end - -function complain(text) - if false then -- only print during development - print(text) - game.forces["player"].print(text) - end -end - -local todo_next_tick = {} -must_write_initstuff = true -function on_tick(event) - dump_cached_writes() - stringsToWriteNextTick = '' - if must_write_initstuff then - must_write_initstuff = false - log("I must write init stuff!") - writeout_initial_stuff() - end - if #todo_next_tick > 0 then - complain("on_tick executing "..#todo_next_tick.." stored callbacks") - for _,func in ipairs(todo_next_tick) do - func() - end - todo_next_tick = {} - end -end - -function writeout_initial_stuff() - log("Writing out initial stuff...") - writeout_objects(game.surfaces['nauvis'], {left_top={x=-64,y=-64},right_bottom={x=64,y=64}}) -end - -function writeout_objects(surface, area) - --if my_client_id ~= 1 then return end - for idx, ent in pairs(surface.find_entities(area)) do - if area.left_top.x <= ent.position.x and ent.position.x < area.right_bottom.x and area.left_top.y <= ent.position.y and ent.position.y < area.right_bottom.y then - if ent.prototype.collision_mask ~= nil and ent.prototype.collision_mask['player-layer'] then - -- line = line .. ent.name.." "..ent.position.x.." "..ent.position.y.."\n" - -- local line = ent.name..","..ent.position.x..","..ent.position.y - -- if ent.supports_direction then - -- line = line .. ",rot="..ent.direction - -- end - -- write_file(line) - on_some_entity_created(nil, ent) - end - end - end - --write_file(header..table.concat(lines,"").."\n") - --write_file(table.concat(lines,"").."\n") -end -function on_chunk_generated(event) - local area = event.area - local surface = event.surface - --print("chunk generated at ("..area.left_top.x..","..area.left_top.y..") -- ("..area.right_bottom.x..","..area.right_bottom.y..")") - - if surface ~= game.surfaces['nauvis'] then -- we only support one surface - return - end - - -- writeout_resources(surface, area) - writeout_objects(surface, area) - -- writeout_tiles(surface, area) -end -function on_some_entity_created(event, entp) - local ent - if entp then - ent = entp - else - ent = event.entity or event.created_entity or nil - end - - if ent == nil then - complain("wtf, on_some_entity_created has nil entity") - return - end - local entityData = ent.name..","..ent.position.x..","..ent.position.y - if ent.supports_direction then - entityData = entityData .. ",rot="..ent.direction - end - -- log(entityData) - write_file(entityData) - --writeout_objects(ent.surface, {left_top={x=math.floor(ent.position.x), y=math.floor(ent.position.y)}, right_bottom={x=math.floor(ent.position.x)+1, y=math.floor(ent.position.y)+1}}) - --complain("on_some_entity_created: "..ent.name.." at "..ent.position.x..","..ent.position.y) -end -function on_some_entity_deleted(event) - local ent = event.entity - if ent == nil then - complain("wtf, on_some_entity_deleted has nil entity") - return - end - - -- we can't do this now, because the entity still exists at this point. instead, we schedule the writeout for the next tick - - --local surface = ent.surface - --local area = {left_top={x=math.floor(ent.position.x), y=math.floor(ent.position.y)}, right_bottom={x=math.floor(ent.position.x)+1, y=math.floor(ent.position.y)+1}} - - --table.insert(todo_next_tick, function () writeout_objects(surface, area ) end) - write_file("deleted,"..ent.position.x..","..ent.position.y) - --complain("on_some_entity_deleted: "..ent.name.." at "..ent.position.x..","..ent.position.y) -end - -script.on_event(defines.events.on_tick, on_tick) -script.on_event(defines.events.on_chunk_generated, on_chunk_generated) - -script.on_event(defines.events.on_biter_base_built, on_some_entity_created) --entity -script.on_event(defines.events.on_built_entity, on_some_entity_created) --created_entity -script.on_event(defines.events.on_robot_built_entity, on_some_entity_created) --created_entity -script.on_event(defines.events.on_player_rotated_entity, on_some_entity_created) --created_entity - -script.on_event(defines.events.on_entity_died, on_some_entity_deleted) --entity -script.on_event(defines.events.on_player_mined_entity, on_some_entity_deleted) --entity -script.on_event(defines.events.on_robot_mined_entity, on_some_entity_deleted) --entity -script.on_event(defines.events.on_resource_depleted, on_some_entity_deleted) --entity - diff --git a/sharedPlugins/remoteMap/destroyEntityCommand.lua b/sharedPlugins/remoteMap/destroyEntityCommand.lua deleted file mode 100644 index bd52ed8a..00000000 --- a/sharedPlugins/remoteMap/destroyEntityCommand.lua +++ /dev/null @@ -1,5 +0,0 @@ -/c -local toDelete = game.surfaces[1].find_entities({{3,7},{4,8}}) -for i, entity in pairs(toDelete) do - entity.die() -end \ No newline at end of file diff --git a/sharedPlugins/remoteMap/index.js b/sharedPlugins/remoteMap/index.js deleted file mode 100644 index 9c03cc08..00000000 --- a/sharedPlugins/remoteMap/index.js +++ /dev/null @@ -1,130 +0,0 @@ -const needle = require("needle"); -const ioClient = require("socket.io-client"); - -const chunkStore = require("./chunkStore.js"); - -const moduleConfig = require("./config"); // not to be confused with clusterio config. This config is private to this plugin. - -class remoteMap { - constructor(slaveConfig, messageInterface){ - this.config = slaveConfig; - this.messageInterface = messageInterface; - - // initialize chunk database - this.chunkMap = new chunkStore(this.config.unique, 64, "./database/chunkStore/"); - this.chunkMap.onEntityChange(entity => { - // this.messageInterface("Entity changed: ") - // this.messageInterface(entity); - // check valid coordinates (dunno what could go wrong, but can never be too sure) - if(entity && entity.x !== undefined && !isNaN(Number(entity.x)) && entity.y !== undefined && !isNaN(Number(entity.y))){ - this.socket.emit("sendEntity", entity); - } - }); - - // set up websocket communication and handle requests from web interface users (which are going through master) - // socket should be a global - this.socket = ioClient("http://"+this.config.masterIP+":"+this.config.masterPort); - this.socket.on("hello", data => { - this.socket.emit("registerSlaveMapper", {instanceID: this.config.unique}); - setInterval(()=>{ - this.socket.emit("heartbeat"); // send our heartbeat to prevent being assumed dead - },10000); - }); - this.socket.on("getChunk", req => { - this.messageInterface("getChunk is not supported!"); - /*this.chunkMap.getChunk(req.x, req.y).then(chunk => { - chunk.requesterID = req.requesterID; - this.socket.emit("sendChunk", chunk); - });*/ - }); - this.socket.on("getEntity", req => { - // check for valid coordinates - if(req.x !== undefined && !isNaN(Number(req.x)) && req.y !== undefined && !isNaN(Number(req.y))){ - this.chunkMap.getEntity(req.x, req.y).then(entities => { - if(entities && entities.length > 0){ - entities.forEach(entity => { - this.socket.emit("sendEntity", entity); - }); - } - }); - } else { - this.messageInterface("socket.getEntity triggered called with invalid parameters"); - } - }); - // both placing and deleting entities via the web interface - this.socket.on("placeEntity", req => { - // game.player.surface.create_entity{name="small-ship-wreck", position={game.player.position.x-2, game.player.position.y+1}, direction=..., force=...} - this.messageInterface("placing "+JSON.stringify(req)); - if(req.name && typeof req.name == "string" && req.position && !isNaN(Number(req.position.x)) && !isNaN(Number(req.position.y))){ - if(req.name == "deleted"){ // {{'+req.position.x+','+req.position.y+'},{'+req.position.x+','+req.position.y+'}} - // delete entity from game world using LUA command - this.messageInterface('/silent-command local toDelete = game.surfaces[1].find_entities({{'+req.position.x+','+req.position.y+'},{'+(req.position.x+1)+','+(req.position.y+1)+'}}) for i, entity in pairs(toDelete) do entity.die() end'); - // this position is now empty, delete whatever was there from DB - this.deleteEntity(req.position.x, req.position.y); - } else { - let command = '/silent-command game.surfaces[1].create_entity{name="'+req.name+'", position={'+Number(req.position.x)+', '+Number(req.position.y)+'}, force="neutral"' - if(req.direction) command += ', direction='+req.direction; - command += '}'; - this.messageInterface(command); // execute command - - // add entity to the chunkStore database because create_entity does not trigger any events - let name = req.name; - let entity = {name}; - if(typeof req.direction == "string"){ - entity.rot = req.direction; - } - this.addEntity(req.position.x, req.position.y, entity); - } - } - }); - - this.messageInterface("/silent-command game.print('"+moduleConfig.name+" version "+moduleConfig.version+" enabled')"); - } - addEntity(x,y,entity){ // add entity to database - this.chunkMap.setEntity(Number(x), Number(y), entity).then(data => { - this.messageInterface("Added "+entity.name+" to data "+Number(x)+", "+Number(y)); - }).catch((err)=>this.messageInterface(err)); - } - deleteEntity(x,y){ // remove entity from database - // this position is now empty, delete whatever was there from DB - this.chunkMap.setEntity(x, y, "delete this entity").then(() => { - this.messageInterface("Deleted entity at "+x+", "+y); - }).catch((err)=>this.messageInterface(err)); - } - scriptOutput(data){ - if(data){ - this.messageInterface(data); - // express-transport-belt,-35.5,-14.5,[...] - data = data.split(","); - if(data && data[0] == undefined){ - this.messageInterface("empty: "); - this.messageInterface(data); - return - } - let name = data[0]; - let xPos = data[1]; - let yPos = data[2]; - if(xPos && yPos && name){ - if(name == "deleted"){ - // this position is now empty, delete whatever was there from DB - this.deleteEntity(xPos, yPos); - } else { - let entity = {name}; - for(let i = 3; i < data.length; i++){ - if(data[i].includes("=")){ - let kv = data[i].split("="); - entity[kv[0]] = kv[1]; - } - } - // save this entity in the database - this.addEntity(xPos, yPos, entity); - /* this.chunkMap.setEntity(xPos, yPos, entity).then(data => { - this.messageInterface("Added "+name+" to data "+xPos+", "+yPos); - }).catch((err)=>this.messageInterface(err)); */ - } - } - - } - } -} -module.exports = remoteMap; diff --git a/sharedPlugins/remoteMap/index.spec.js b/sharedPlugins/remoteMap/index.spec.js deleted file mode 100644 index cffb3a91..00000000 --- a/sharedPlugins/remoteMap/index.spec.js +++ /dev/null @@ -1,10 +0,0 @@ -return // Disabled until it actually works -var assert = require("assert"); - -var remoteMap = require("./index.js"); - -describe("remoteMap/index.js", () => { - it("exports a single class (or at least a function)", ()=>{ - assert.equal(typeof remoteMap, "function"); - }); -}); diff --git a/sharedPlugins/remoteMap/info.json b/sharedPlugins/remoteMap/info.json deleted file mode 100644 index e60aaa47..00000000 --- a/sharedPlugins/remoteMap/info.json +++ /dev/null @@ -1,11 +0,0 @@ - -{ -"name": "remoteMap", -"title": "Clusterio remote map", -"version": "2.2.0", -"date": "18-11-2017", -"author": "Danielv123", -"dependencies": ["base >= 0.15"], -"factorio_version": "0.16", -"description": "Clusterio plugin for mapping and building through the browser. No more need to start game, download and catching up for every game, also mobile factorio confirmed?" -}