Merge pull request #197 from Hornwitser/remove-remotemap

Remove outdated remoteMap
This commit is contained in:
Arvids Godjuks authored and GitHub committed 2019-08-07 17:55:25 +03:00
commit 9c108dd4dd
11 files changed
-495

No files matched your search

-12
View File
@@ -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.
-1
View File
@@ -56,7 +56,6 @@ function download(url, file, callback){
}
var directories = [
"database/linvodb",
"sharedMods",
"instances",
];
View File
Whitespace-only changes.
-100
View File
@@ -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?
*/
});
}
}
@@ -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/");
});
});
});
});
-16
View File
@@ -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",
}
-145
View File
@@ -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
@@ -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
-130
View File
@@ -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;
-10
View File
@@ -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");
});
});
-11
View File
@@ -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?"
}