From f9d6d9e001e502f49b4241d9411bc8716af40e6e Mon Sep 17 00:00:00 2001 From: Thomas Deal Date: Sat, 1 Oct 2016 17:51:04 -0400 Subject: [PATCH 1/7] Add Transmit/Receive Combinators. Transmit combinators are Deciders which also output into txbuffer.txt. Receive Combinators are Constants which replay frames received from external sources via remote calls to receiveFrame and recieveMany. --- clusterio_0.0.2/config.lua | 8 +- clusterio_0.0.2/control.lua | 198 ++++++++++++++++++----- clusterio_0.0.2/data.lua | 122 +++++++++++--- clusterio_0.0.2/info.json | 4 +- clusterio_0.0.2/locale/en/item-names.cfg | 7 +- 5 files changed, 267 insertions(+), 72 deletions(-) diff --git a/clusterio_0.0.2/config.lua b/clusterio_0.0.2/config.lua index 8aecd67b..e1007a8a 100644 --- a/clusterio_0.0.2/config.lua +++ b/clusterio_0.0.2/config.lua @@ -18,9 +18,15 @@ OUTPUT_TANK_NAME = "get-tank" OUTPUT_TANK_PICTURE_PATH = nil OUTPUT_TANK_ICON_PATH = nil +MAX_RX_BUFFER_SIZE = 40 -- slightly more than one second +RX_COMBINATOR_NAME = "get-combinator" +TX_COMBINATOR_NAME = "put-combinator" + OUTPUT_FILE = "output.txt" ORDER_FILE = "orders.txt" +TX_BUFFER_FILE = "txbuffer.txt" -UPATE_RATE = 60 \ No newline at end of file +UPATE_RATE = 60 +CIRCUIT_UPATE_RATE = 5 diff --git a/clusterio_0.0.2/control.lua b/clusterio_0.0.2/control.lua index cb2ab1b1..4152db57 100644 --- a/clusterio_0.0.2/control.lua +++ b/clusterio_0.0.2/control.lua @@ -43,12 +43,17 @@ function AddEntity(entity) --add the chests to a lists if these chests so they can be interated over global.outputTanks[HashPosition(entity.position)] = entity entity.active = false + elseif entity.name == TX_COMBINATOR_NAME then + table.insert(global.txControls, entity.get_or_create_control_behavior()) + elseif entity.name == RX_COMBINATOR_NAME then + table.insert(global.rxControls, entity.get_or_create_control_behavior()) + entity.operable=false end end function OnKilledEntity(event) local entity = event.entity - if entity.type ~= "entity-ghost" then + if entity.type ~= "entity-ghost" then --remove the entities from the tables as they are dead if entity.name == INPUT_CHEST_NAME then global.inputChests[HashPosition(entity.position)] = nil @@ -85,23 +90,29 @@ end) script.on_event(defines.events.on_tick, function(event) - + global.inputChests = global.inputChests or {} global.outputChests = global.outputChests or {} global.inputTanks = global.inputTanks or {} global.outputTanks = global.outputTanks or {} global.outputList = global.outputList or {} global.inputList = global.inputList or {} - + global.rxControls = global.rxControls or {} + global.txControls = global.txControls or {} + + + -- TX Combinators must run every tick to catch single pulses + HandleTXCombinators() + local todo = game.tick % UPATE_RATE - + local onlinePlayers = GetOnlinePlayerCount() - + if global.previousPlayerCount == nil or global.previousPlayerCount ~= onlinePlayers then Reset() end global.previousPlayerCount = onlinePlayers - + if todo == 0 then HandleInputChests() elseif todo == 1 then @@ -114,6 +125,14 @@ script.on_event(defines.events.on_tick, function(event) ExportInputList() elseif todo == 5 then ExportOutputList() + end + + local rxstate = game.tick % CIRCUIT_UPATE_RATE + -- RX Combinators are set and then cleared on sequential ticks to create pulses + if rxstate == 0 then + SetRXCombinators() + elseif rxstate == 1 then + ClearRXCombinators() end end) @@ -131,12 +150,12 @@ function Reset() global.outputList = {} global.inputList = {} global.itemStorage = {} - + global.inputChests = {} global.outputChests = {} global.inputTanks = {} global.outputTanks = {} - + AddAllEntitiesOfName(INPUT_CHEST_NAME) AddAllEntitiesOfName(OUTPUT_CHEST_NAME) AddAllEntitiesOfName(INPUT_TANK_NAME) @@ -171,7 +190,7 @@ function HandleInputTanks() v.fluidbox[1] = fluid end end - + end function HandleOutputChests() @@ -195,7 +214,7 @@ function HandleOutputChests() --insert the missing items local insertedItemsCount = chestInventory.insert(simpleItemStack) local itemsNotInsertedCount = itemCountAllowedToInsert - insertedItemsCount - + if itemsNotInsertedCount > 0 then GiveItemsToStorage(requestItem.name, itemsNotInsertedCount) end @@ -214,16 +233,15 @@ function HandleOutputTanks() local MAX_FLUID_AMOUNT = 1000 for k,v in pairs(global.outputTanks) do --.recipe.products[1].name - if v.recipe ~= nil then local fluidName = v.recipe.products[1].name - + --either get the fluid or reset it to the requested fluid local fluid = v.fluidbox[1] or {type = fluidName, amount = 0} if fluid.type ~= fluidName then fluid = {type = fluidName, amount = 0} end - + --if any fluid is missing then request the fluid --from store and give either what it's missing or --the rest of the liquid in the system @@ -237,11 +255,11 @@ function HandleOutputTanks() AddItemToOutputList(fluid.type, fluidToRequestAmount) end end - - v.fluidbox[1] = fluid - end + + v.fluidbox[1] = fluid end end +end function AddItemToInputList(itemName, itemCount) @@ -261,9 +279,9 @@ function ExportInputList() end global.inputList = {} if #exportStrings > 0 then - + --only write to file once as i/o is slow - --it's much faster to concatenate all the lines with table.concat + --it's much faster to concatenate all the lines with table.concat --instead of doing it with the .. operator game.write_file(OUTPUT_FILE, table.concat(exportStrings), true) end @@ -276,9 +294,9 @@ function ExportOutputList() end global.outputList = {} if #exportStrings > 0 then - + --only write to file once as i/o is slow - --it's much faster to concatenate all the lines with table.concat + --it's much faster to concatenate all the lines with table.concat --instead of doing it with the .. operator game.write_file(ORDER_FILE, table.concat(exportStrings), true) end @@ -296,7 +314,7 @@ function RequestItemsFromStorage(itemName, itemCount) --requested then take the number of items there are left otherwise take the requested amount local itemsTakenFromStorage = math.min(global.itemStorage[itemName], itemCount) global.itemStorage[itemName] = global.itemStorage[itemName] - itemsTakenFromStorage - + return itemsTakenFromStorage end @@ -311,10 +329,110 @@ end +function AddFrameToRXBuffer(frame) + -- Add a frame to the buffer. return remaining space in buffer + local validsignals = { + ["virtual"] = game.virtual_signal_prototypes, + ["fluid"] = game.fluid_prototypes, + ["item"] = game.item_prototypes + } + + global.rxBuffer = global.rxBuffer or {} + + -- if buffer is full, drop frame + if #global.rxBuffer >= MAX_RX_BUFFER_SIZE then return 0 end + + -- frame = {{count=42,name="signal-grey",type="virtual"},{...},...} + local signals = {} + local index = 1 + + for _,signal in pairs(frame) do + if validsignals[signal.type] and validsignals[signal.type][signal.name] then + signals[index] = + { + index=index, + count=signal.count, + signal={ name=signal.name, type=signal.type } + } + index = index + 1 + --TODO: break if too many? + --TODO: error token on mismatched signals? maybe mismatch1-n signals? + end + end + + if index > 1 then table.insert(global.rxBuffer,signals) end + + return MAX_RX_BUFFER_SIZE - #global.rxBuffer +end + +function HandleTXCombinators() + -- Check all TX Combinators, and if condition satisfied, add frame to transmit buffer + + -- frame = {{count=42,name="signal-grey",type="virtual"},{...},...} + local signals = {["item"]={},["virtual"]={},["fluid"]={}} + for i,txControl in pairs(global.txControls) do + if txControl.valid then + local frame = txControl.signals_last_tick + if frame then + for _,signal in pairs(frame) do + signals[signal.signal.type][signal.signal.name]= + (signals[signal.signal.type][signal.signal.name] or 0) + signal.count + end + end + else + table.remove(global.txControls,i) + end + end + + local frame = {} + for type,arr in pairs(signals) do + for name,count in pairs(arr) do + table.insert(frame,{count=count,name=name,type=type}) + end + end + + if #frame > 0 then + table.insert(frame,{count=game.tick,name="signal-srctick",type="virtual"}) + game.write_file(TX_BUFFER_FILE, json:encode(frame).."\n", true) + + -- Loopback for testing + --AddFrameToRXBuffer(frame) + + end +end + +function SetRXCombinators() + -- if the RX buffer is not empty, get a frame from it and output on all RX Combinators + if global.rxBuffer and #global.rxBuffer > 0 then + local frame = table.remove(global.rxBuffer) + for i,rxControl in pairs(global.rxControls) do + if rxControl.valid then + rxControl.parameters={parameters=frame} + rxControl.enabled=true + else + table.remove(global.rxControls,i) + end + end + end +end + +function ClearRXCombinators() + -- Clear all RX Combinators. + -- This makes them emit pulses, which are easier to + -- detect than slowly changing continusous signals. + for i,rxControl in pairs(global.rxControls) do + if rxControl.valid then + rxControl.enabled=false + else + table.remove(global.rxControls,i) + end + end +end + --[[ Remote Thing ]]-- -remote.add_interface("clusterio", +remote.add_interface("clusterio", { - import = function(itemName, itemCount) + import = function(itemName, itemCount) GiveItemsToStorage(itemName, itemCount) end, importMany = function(jsonString) @@ -332,23 +450,19 @@ remote.add_interface("clusterio", end game.print(items) end, - reset = Reset + reset = Reset, + receiveFrame = function(jsonframe) + local frame = json:decode(jsonframe) + -- frame = {tick=123456,frame={{count=42,name="signal-grey",type="virtual"},{...},...}} + return AddFrameToRXBuffer(frame) + end, + receiveMany = function(jsonframes) + local frames = json:decode(jsonframes) + local buffer + for _,frame in pairs(frames) do + buffer = AddFrameToRXBuffer(frame) + if buffer==0 then return 0 end + end + return buffer + end, }) - - - - - - - - - - - - - - - - - - diff --git a/clusterio_0.0.2/data.lua b/clusterio_0.0.2/data.lua index fa1bb0a4..a1ae8af6 100644 --- a/clusterio_0.0.2/data.lua +++ b/clusterio_0.0.2/data.lua @@ -18,10 +18,10 @@ function MakeLogisticEntity(entity, name, pictureFilename, pictureTablePath, ico ChangePictureFilename(entity, pictureTablePath, pictureFilename) --if no icon is defined then use the default one entity.icon = iconPath or entity.icon - + -- add the entity to a technology so it can be unlocked --local wasAddedToTech = AddEntityToTech("construction-robotics", name) - + data:extend( { -- add the entity @@ -70,7 +70,7 @@ function AddEntityToTech(techName, name) type = "unlock-recipe", recipe = name } - --if a new table for the effects is made then the effects has to be attached to the + --if a new table for the effects is made then the effects has to be attached to the -- tech again because the table won't otherwise be owned by the tech data.raw["technology"][techName].effects = effects return true @@ -86,22 +86,10 @@ MakeLogisticEntity(table.deepcopy(data.raw["container"]["iron-chest"]), --make tanks MakeLogisticEntity(table.deepcopy(data.raw["storage-tank"]["storage-tank"]), INPUT_TANK_NAME, INPUT_TANK_PICTURE_PATH, { "pictures", "picture", "sheet" }, INPUT_TANK_ICON_PATH) - - - - - - -------------------------------------------------------- --[[This section is purely to create the output tank]]-- -------------------------------------------------------- - - - - - - local CRAFING_FLUID_CATEGORY_NAME = "crafting-fluids" data:extend( @@ -121,10 +109,10 @@ fluidCreator.fluid_boxes = pipe_covers = pipecoverspictures(), base_area = 250, base_level = 1, - pipe_connections = + pipe_connections = { - { - type="output", position = {0, 2} + { + type="output", position = {0, 2} } } }, @@ -157,12 +145,96 @@ for k,v in pairs(data.raw.fluid) do end +-- Virtual signals +data:extend{ + { + type = "item-subgroup", + name = "virtual-signal-clusterio", + group = "signals", + order = "e" + }, + { + type = "virtual-signal", + name = "signal-srctick", + icon = "__base__/graphics/icons/signal/signal_grey.png", + subgroup = "virtual-signal-clusterio", + order = "e[clusterio]-[1srctick]" + }, + --[[{ + type = "virtual-signal", + name = "signal-srcid", + icon = "__base__/graphics/icons/signal/signal_grey.png", + subgroup = "virtual-signal-clusterio", + order = "e[clusterio]-[2srcid]" + },]] + --[[{ + type = "virtual-signal", + name = "signal-localid", + icon = "__base__/graphics/icons/signal/signal_grey.png", + subgroup = "virtual-signal-clusterio", + order = "e[clusterio]-[3localid]" + },]] +} +-- TX Combinator +local tx = table.deepcopy(data.raw["decider-combinator"]["decider-combinator"]) +tx.name = TX_COMBINATOR_NAME +tx.minable.result = TX_COMBINATOR_NAME +data:extend{ + tx, + { + type = "item", + name = TX_COMBINATOR_NAME, + icon = tx.icon, + flags = {"goes-to-quickbar"}, + subgroup = "storage", + place_result=TX_COMBINATOR_NAME, + order = "a[items]-b["..TX_COMBINATOR_NAME.."]", + stack_size = 50, + }, + { + type = "recipe", + name = TX_COMBINATOR_NAME, + enabled = true, -- TODO do this on a tech somewhere + ingredients = + { + {"decider-combinator", 1}, + {"electronic-circuit", 3}, + {"advanced-circuit", 1} + }, + result = TX_COMBINATOR_NAME, + requester_paste_multiplier = 1 + }, +} - - - - - - - +-- RX Combinator +local rx = table.deepcopy(data.raw["constant-combinator"]["constant-combinator"]) +rx.name = RX_COMBINATOR_NAME +rx.minable.result = RX_COMBINATOR_NAME +rx.item_slot_count = 100 +data:extend{ + rx, + { + type = "item", + name = RX_COMBINATOR_NAME, + icon = rx.icon, + flags = {"goes-to-quickbar"}, + subgroup = "storage", + place_result=RX_COMBINATOR_NAME, + order = "a[items]-b["..RX_COMBINATOR_NAME.."]", + stack_size = 50, + }, + { + type = "recipe", + name = RX_COMBINATOR_NAME, + enabled = true, -- TODO do this on a tech somewhere + ingredients = + { + {"constant-combinator", 1}, + {"electronic-circuit", 3}, + {"advanced-circuit", 1} + }, + result = RX_COMBINATOR_NAME, + requester_paste_multiplier = 1 + }, +} diff --git a/clusterio_0.0.2/info.json b/clusterio_0.0.2/info.json index 93e439f0..e9a8572e 100644 --- a/clusterio_0.0.2/info.json +++ b/clusterio_0.0.2/info.json @@ -4,8 +4,8 @@ "title": "Clusterio", "version": "0.0.2", "date": "19-08-2016", -"author": "Danielv123 & Keyboardhack", +"author": "Danielv123 & Keyboardhack & justarandomgeek", "dependencies": ["base >= 0.13"], "factorio_version": "0.14", "description": "Adds 2 chests to transfer items between saves and servers over the internet." -} \ No newline at end of file +} diff --git a/clusterio_0.0.2/locale/en/item-names.cfg b/clusterio_0.0.2/locale/en/item-names.cfg index 2a3d0920..08399bce 100644 --- a/clusterio_0.0.2/locale/en/item-names.cfg +++ b/clusterio_0.0.2/locale/en/item-names.cfg @@ -3,10 +3,13 @@ put-chest=Put chest get-chest=Get chest put-tank=Put tank get-tank=Get tank - +put-combinator=Transmit combinator +get-combinator=Receive combinator [item-name] put-chest=Put chest get-chest=Get chest put-tank=Put tank -get-tank=Get tank \ No newline at end of file +get-tank=Get tank +put-combinator=Transmit combinator +get-combinator=Receive combinator From b123d485d2e1d2087114eff7ff257cecb2942197 Mon Sep 17 00:00:00 2001 From: Danielv123 Date: Thu, 6 Oct 2016 17:47:03 +0200 Subject: [PATCH 2/7] Slave sending combinator signals finished So working on #22. --- client.js | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/client.js b/client.js index 60952455..49aed199 100644 --- a/client.js +++ b/client.js @@ -30,7 +30,7 @@ client.on('authenticated', function() { // set some globals confirmedOrders = []; - +// provide items -------------------------------------------------------------- // trigger when something happens to output.txt fs.watch(config.factorioDirectory + "/script-output/output.txt", "utf8", function(eventType, filename) { // get array of lines in file @@ -52,7 +52,7 @@ fs.watch(config.factorioDirectory + "/script-output/output.txt", "utf8", functio } } }) - +// request items -------------------------------------------------------------- setInterval(function() { // get array of lines in file items = fs.readFileSync(config.factorioDirectory + "/script-output/orders.txt", "utf8").split("\n"); @@ -61,7 +61,7 @@ setInterval(function() { fs.writeFileSync(config.factorioDirectory + "/script-output/orders.txt", ""); // prepare a package of all our requested items in a more tranfer friendly format var preparedPackage = {}; - for(i = 2;i < items.length; i++) { + for(i = 0;i < items.length; i++) { (function(i){ if(items[i]) { items[i] = items[i].split(" "); @@ -97,8 +97,33 @@ setInterval(function() { client.exec("/silent-command remote.call('clusterio', 'importMany', '" + sadas + "')"); } }, 3000) -/* -fs.watch(config.factorioDirectory + "/script-output/orders.txt", "utf8", function(eventType, filename) { - -}) -*/ \ No newline at end of file +// COMBINATOR SIGNALS --------------------------------------------------------- +// send any signals the slave has been told to send +setInterval(function() { + // get array of lines in file + signals = fs.readFileSync(config.factorioDirectory + "/script-output/txbuffer.txt", "utf8").split("\n"); + // if we actually got anything from the file, proceed and reset file + if(signals[0]) { + fs.writeFileSync(config.factorioDirectory + "/script-output/txbuffer.txt", ""); + for(i = 0;i < signals.length; i++) { + (function(i){ + if(signals[i]) { + // signals[i] is a JSON array, we need to unnest it + signal = JSON.parse(signals[i]) + for(o=0;o Date: Thu, 6 Oct 2016 17:49:16 +0200 Subject: [PATCH 3/7] Removed DB from repo --- database/items.db | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 database/items.db diff --git a/database/items.db b/database/items.db deleted file mode 100644 index 08f2850e..00000000 --- a/database/items.db +++ /dev/null @@ -1,4 +0,0 @@ -{"name":"raw-fish","count":"2","_id":"a0TVkMwP8M99LLbp"} -{"name":"iron-ore","count":25823,"_id":"bEcyT728rLO8JvqY"} -{"name":"electronic-circuit","count":200,"_id":"n3JBn8ksl9YIkCWy"} -{"name":"coal","count":10406,"_id":"qnEjvk1EypjWAEQk"} From a3aafd8b1daa0b000e1c0d5995e907e2e9d87c4b Mon Sep 17 00:00:00 2001 From: Danielv123 Date: Fri, 7 Oct 2016 17:54:23 +0200 Subject: [PATCH 4/7] JS part of signals kinda finished but it aint working --- client.js | 46 ++++++++++++++++++++++++++++++++-------------- master.js | 22 ++++++++++++++++++++++ 2 files changed, 54 insertions(+), 14 deletions(-) diff --git a/client.js b/client.js index 49aed199..998bee75 100644 --- a/client.js +++ b/client.js @@ -12,11 +12,19 @@ var client = new Rcon({ timeout: 0 }).connect(); +if (!fs.existsSync(config.factorioDirectory)){ + console.error("FATAL ERROR: config.factorioDirectory DOES NOT EXIST, PLEASE UPDATE CONFIG.JSON"); + process.exit(1); +} +// make sure we got the files we need if (!fs.existsSync(config.factorioDirectory + "/script-output/")){ fs.mkdirSync(config.factorioDirectory + "/script-output/"); } -fs.writeFileSync(config.factorioDirectory + "/script-output/output.txt", "") +if (!fs.existsSync(config.factorioDirectory + "/script-output/")){ + fs.writeFileSync(config.factorioDirectory + "/script-output/output.txt", "") +} fs.writeFileSync(config.factorioDirectory + "/script-output/orders.txt", "") +fs.writeFileSync(config.factorioDirectory + "/script-output/txbuffer.txt", ""); client.on('authenticated', function() { console.log('Authenticated!'); @@ -30,6 +38,7 @@ client.on('authenticated', function() { // set some globals confirmedOrders = []; +lastSignalCheck = Date.now(); // provide items -------------------------------------------------------------- // trigger when something happens to output.txt fs.watch(config.factorioDirectory + "/script-output/output.txt", "utf8", function(eventType, filename) { @@ -100,6 +109,16 @@ setInterval(function() { // COMBINATOR SIGNALS --------------------------------------------------------- // send any signals the slave has been told to send setInterval(function() { + // Fetch combinator signals from the server + needle.post(config.masterIP + ":" + config.masterPort + '/readSignal', {since:lastSignalCheck}, function(err, response, body){ + if(response && response.body && typeof response.body == "object" && response.body[0]) { + // buffer confirmed orders + console.log("YESSSSSSSS" + JSON.stringify(response.body[0])); + client.exec("/c remote.call('clusterio', 'receiveFrame', '" + JSON.stringify(response.body[0]) + "')"); + // confirmedSignals[confirmedSignals.length] = {[response.body.name]: response.body.count} + } + }); + lastSignalCheck = Date.now(); // get array of lines in file signals = fs.readFileSync(config.factorioDirectory + "/script-output/txbuffer.txt", "utf8").split("\n"); // if we actually got anything from the file, proceed and reset file @@ -109,21 +128,20 @@ setInterval(function() { (function(i){ if(signals[i]) { // signals[i] is a JSON array, we need to unnest it - signal = JSON.parse(signals[i]) - for(o=0;o Date: Fri, 7 Oct 2016 20:29:35 +0200 Subject: [PATCH 5/7] Sending signals over Clusterio now works Closes #19 --- client.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client.js b/client.js index 998bee75..fd2d0802 100644 --- a/client.js +++ b/client.js @@ -114,7 +114,7 @@ setInterval(function() { if(response && response.body && typeof response.body == "object" && response.body[0]) { // buffer confirmed orders console.log("YESSSSSSSS" + JSON.stringify(response.body[0])); - client.exec("/c remote.call('clusterio', 'receiveFrame', '" + JSON.stringify(response.body[0]) + "')"); + client.exec("/silent-command remote.call('clusterio', 'receiveFrame', '" + JSON.stringify(response.body[0].frame) + "')"); // confirmedSignals[confirmedSignals.length] = {[response.body.name]: response.body.count} } }); @@ -127,8 +127,8 @@ setInterval(function() { for(i = 0;i < signals.length; i++) { (function(i){ if(signals[i]) { - // signals[i] is a JSON array, we need to unnest it - // actually, we don't. That array is our "frame", and we pass that along instead of seperate signals. + // signals[i] is a JSON array called a "frame" of signals. We timestamp it for storage on master + // then we unpack and RCON in this.frame to the game. framepart = JSON.parse(signals[i]) doneframe = { time: Date.now(), From a2d970fad6e544dbf14d22c961190f3d713aa61f Mon Sep 17 00:00:00 2001 From: Danielv123 Date: Fri, 7 Oct 2016 23:59:15 +0200 Subject: [PATCH 6/7] Use the many option for signals instead --- client.js | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/client.js b/client.js index fd2d0802..a900666a 100644 --- a/client.js +++ b/client.js @@ -112,23 +112,30 @@ setInterval(function() { // Fetch combinator signals from the server needle.post(config.masterIP + ":" + config.masterPort + '/readSignal', {since:lastSignalCheck}, function(err, response, body){ if(response && response.body && typeof response.body == "object" && response.body[0]) { - // buffer confirmed orders - console.log("YESSSSSSSS" + JSON.stringify(response.body[0])); - client.exec("/silent-command remote.call('clusterio', 'receiveFrame', '" + JSON.stringify(response.body[0].frame) + "')"); - // confirmedSignals[confirmedSignals.length] = {[response.body.name]: response.body.count} + // Take the new combinator frames and compress them so we can use a single command + frameset = []; + for(i=0;i Date: Sun, 9 Oct 2016 11:02:50 +0200 Subject: [PATCH 7/7] Updated readme --- README.md | 51 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 12a7b812..c1d6d509 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,54 @@ #factorioClusterio -- The first ever mod allowing you to transfer items between worlds +Features: + +- Entities to send/recieve items + +- Cross dimensional storage + +- Sending of liquids + +- Sending of circuit network signals #Windows setup -git clone +Clusterio is built up of multiple parts. Here is a quick guide: -npm install +Master = master.js -edit config.json +Slave = client.js + factorio server -node master.js on the master +Client = The people connecting to the server -start the server on the client, using the right rcon configs +Master and all all Slaves have to be running nodejs. Get it from nodejs.org. -node client.js +All Slaves AND Clients need to be running the clusterio mod located in this repository. Install it by dropping it into the mods folder. -connect to server +There are no requirements for other mods, they can be ran in any configuration allowed by the base game. -??? +**Master** -profit! \ No newline at end of file +To start master, clone the repo and do + + node master.js + +The clusterio monitoring interface can be found on [master]:8080 + +**Slave** + +To install a Slave, you need to set up config.json. + +clientIP should be localhost + +clientPort and password should be the port and password you have configured for RCON connections when launching factorio.exe. The defaults are correct if you are using a modified version of the included launchEverything.bat. + +factorioDirectory is the location of your factorio server folder, ex factorio_0.13.37. You HAVE to use the zip version downloaded from the website to use clusterio. Headless should also work. + +masterIP and port should be selfexplanatory. To test if these settings works, open a browser on the slave system and enter masterIP:masterPort. + +Once finished, do + + [factorioDirectory]/bin/x64/factorio.exe [flags] + node client.js + +See launchEverything.bat for example command. \ No newline at end of file