You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
191 lines
4.8 KiB
191 lines
4.8 KiB
local net = require("net")
|
|
local component = require("component")
|
|
local sides = require("sides")
|
|
local os = require("os")
|
|
|
|
-- location of eeprom in computer case
|
|
local EEPROM_SLOT = 10
|
|
local transposer = component.transposer
|
|
|
|
-- Waits for a SYN from a worker and responds with an ACK
|
|
-- Returns the workers address
|
|
local function meetWorker(port)
|
|
print("Waiting for worker")
|
|
|
|
local function syn(name, ...)
|
|
-- local addr, remote addr, port, distance, msg
|
|
local t = {...}
|
|
|
|
return t[5] == "SYN"
|
|
end
|
|
|
|
-- Wait for a SYN
|
|
local pkt, err = net.recv{port, filter = syn}
|
|
|
|
-- ACK the worker
|
|
net.send(pkt.raddr, port, "ACK")
|
|
print("Found worker", pkt.raddr)
|
|
|
|
return pkt.raddr
|
|
end
|
|
|
|
-- Checks if the top chest is filled
|
|
local function isFilled()
|
|
local i = 1
|
|
for k in transposer.getAllStacks(sides.top) do
|
|
if k.size == nil then break end
|
|
|
|
i = i + 1
|
|
end
|
|
|
|
return i >= 27
|
|
end
|
|
|
|
-- Moves the EEPROM from the worker into the top chest
|
|
-- Optionally include the slot
|
|
-- Returns the slot the eeprom was moved to
|
|
local function removeEEPROM(sink_slot)
|
|
print("REMOVING - ", sink_slot)
|
|
|
|
if sink_slot == nil then
|
|
local i = 1
|
|
for k in transposer.getAllStacks(sides.top) do
|
|
if k.size == nil then break end
|
|
|
|
i = i + 1
|
|
end
|
|
|
|
if i == 27 then
|
|
return nil, "Inventory filled"
|
|
end
|
|
|
|
sink_slot = i
|
|
end
|
|
|
|
-- Remove the OpenOS Bios and store it in the top chest
|
|
transposer.transferItem(sides.left, sides.top, 1, EEPROM_SLOT, sink_slot)
|
|
|
|
return sink_slot
|
|
end
|
|
|
|
-- Moves a blank EEPROM from storage into the worker
|
|
local function loadNewEEPROM()
|
|
print("LOADING")
|
|
|
|
-- Find largest inventory slot in the storage with an eeprom
|
|
local i = 1
|
|
local last = nil
|
|
|
|
for k in transposer.getAllStacks(sides.right) do
|
|
if k.size ~= nil then
|
|
last = i
|
|
end
|
|
|
|
i = i + 1
|
|
end
|
|
|
|
if last == nil then
|
|
return nil, "No EEPROMS"
|
|
end
|
|
|
|
-- Move the new EEPROM into computer
|
|
transposer.transferItem(sides.right, sides.left, 1, last, EEPROM_SLOT)
|
|
|
|
return true
|
|
end
|
|
|
|
local function flashEEPROM(worker, port, data, label)
|
|
print("Send", worker, port, "flash", label)
|
|
|
|
net.send(worker, port, "flash", data, label)
|
|
|
|
local function fromWorker(name, ...)
|
|
t = {...}
|
|
|
|
return t[2] == worker
|
|
end
|
|
|
|
local pkt, error = net.recv{port, filter=fromWorker}
|
|
|
|
if pkt.msg == "flash-good" then
|
|
return true
|
|
else
|
|
return nil, pkt.msg
|
|
end
|
|
end
|
|
|
|
local function respond(pkt, code, error)
|
|
print("SEND", pkt.raddr, pkt.port, code, error)
|
|
net.send(pkt.raddr, pkt.port, code, error)
|
|
computer.beep(200)
|
|
end
|
|
|
|
-- Waits to recv a message
|
|
local function waitForJob(port, worker)
|
|
local pkt, err = net.recv{port}
|
|
|
|
if pkt == nil and err ~= "interrupted" then
|
|
return pkt
|
|
end
|
|
|
|
-- "eeprom-flash file-contents"
|
|
if pkt.msg == "eeprom-flash" then
|
|
-- 4k is the largest an eeprom can hold
|
|
if #pkt.data[2] > 4096 then
|
|
respond(pkt, 400, "file too large")
|
|
return pkt
|
|
end
|
|
|
|
if isFilled() then respond(pkt, 500, "inventory filled") return end
|
|
|
|
-- Remove the OpenOS Bios and store it in the last slot of top chest
|
|
local res, err = removeEEPROM(27)
|
|
if res == nil then respond(pkt, 500, err) return end
|
|
computer.beep(100)
|
|
|
|
local res, err = loadNewEEPROM()
|
|
if res == nil then respond(pkt, 500, err) return end
|
|
computer.beep(100)
|
|
|
|
if pkt.data[3] == nil then
|
|
pkt.data[3] = "Flashed EEPROM"
|
|
end
|
|
|
|
local res, err = flashEEPROM(worker, port, pkt.data[2], pkt.data[3])
|
|
if res == nil then respond(pkt, 500, err) return end
|
|
|
|
-- Now the NBT data of the eeprom will update on the next auto save
|
|
-- To detect this we're going to check the item stack every few seconds until the labels match
|
|
local i = 0
|
|
while transposer.getStackInSlot(sides.left, EEPROM_SLOT).label ~= pkt.data[3] do
|
|
print("Checking for autosave...")
|
|
computer.beep(500)
|
|
os.sleep(2.5)
|
|
i = i + 1
|
|
end
|
|
|
|
print("Autosave detected! Took " .. tostring(2.5 * i) .. " seconds")
|
|
computer.beep(1000)
|
|
|
|
local location, err = removeEEPROM()
|
|
if location == nil then respond(pkt, 500, err) return end
|
|
computer.beep(100)
|
|
|
|
-- Load the old EERPOM
|
|
transposer.transferItem(sides.top, sides.left, 1, 27, EEPROM_SLOT)
|
|
computer.beep(100)
|
|
|
|
respond(pkt, 200, location)
|
|
computer.beep(1000)
|
|
end
|
|
end
|
|
|
|
local function startServer(port)
|
|
worker = meetWorker(port)
|
|
|
|
while true do
|
|
print(waitForJob(port, worker))
|
|
end
|
|
end
|
|
|
|
startServer(10)
|