Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local m = peripheral.find("modem", function(_, o) return o.isWireless() end)
- local ec_oc = peripheral.find "ender_chest"
- local ec_cc = peripheral.find "minecraft:ender chest"
- local spatial = "back"
- local spatialp = peripheral.wrap(spatial)
- local name = os.getComputerLabel()
- local channel = 236
- local spatial_ec_loc = settings.get "spatial_ec_loc" or "east"
- local busy = false
- local needed_energy = 34000
- local function send(x)
- print("->", unpack(x))
- m.transmit(channel, channel, x)
- end
- local function recv_filter(fn)
- while true do
- local _, _, c, rc, msg = os.pullEvent "modem_message"
- print("<-", unpack(msg))
- if type(msg) == "table" and fn(msg) then return msg end
- end
- end
- local function pick_channel()
- return math.random(0xA00, 0xC00)
- end
- local function run_spatial()
- rs.setOutput(spatial, true)
- sleep(0.1)
- rs.setOutput(spatial, false)
- sleep(0.1)
- print "Run spatial"
- end
- local function run_transfer(trg)
- busy = true
- local function run_transfer_internal()
- if spatialp.getNetworkEnergyStored() < needed_energy then print "Insufficient energy" return end
- print "Pinging"
- send { "ping", trg }
- if (recv_filter(function(m) return m[1] == "pong" and m[2] == trg end))[3] then print "Remote busy" return end
- print "Destination available"
- local ec_channel = pick_channel()
- ec_oc.setFrequency(ec_channel)
- send { "transfer", trg, ec_channel }
- if not (recv_filter(function(m) return m[1] == "transfer_ack" and m[2] == trg end))[3] then print "Remote denied transfer" return end
- print "Ack received"
- run_spatial()
- spatialp.pushItems(spatial_ec_loc, 2, 1, 1)
- print "Sent item to remote"
- repeat
- sleep(0.1)
- until ec_cc.getItemMeta(27) ~= nil
- print("Remote sent item")
- spatialp.pullItems(spatial_ec_loc, 27, 1, 1)
- run_spatial()
- spatialp.pullItems("self", 2, 1, 1)
- print "Done"
- end
- parallel.waitForAny(run_transfer_internal, function() sleep(5) print "Transfer timed out" end)
- busy = false
- end
- local pings_timer = nil
- local function list_all()
- pings_timer = os.startTimer(1)
- send { "ping" }
- end
- local function inbound()
- local function run_transfer_recv(msg)
- print("Transfer request from", msg[2])
- if spatialp.getNetworkEnergyStored() < needed_energy then print "Insufficient energy" send { "transfer_ack", msg[2], false } return end
- if busy then print "Already busy, cannot accept transfer" send { "transfer_ack", msg[2], false } return end
- busy = true
- send { "transfer_ack", msg[2], true }
- print("Accepting transfer from", msg[2])
- ec_oc.setFrequency(msg[3])
- repeat
- sleep(0.1)
- until ec_cc.getItemMeta(1) ~= nil
- print "Remote sent item"
- run_spatial()
- spatialp.pullItems(spatial_ec_loc, 1, 1, 1)
- spatialp.pushItems(spatial_ec_loc, 2, 1, 27)
- print "Sent item to remote"
- run_spatial()
- spatialp.pullItems("self", 2, 1, 1)
- print "Done"
- end
- local function process(msg)
- local cmd = msg[1]
- if cmd == "ping" and (msg[2] == nil or msg[2] == name) then
- send { "pong", name, busy }
- elseif pings_timer and cmd == "pong" then
- print(msg[2])
- elseif cmd == "transfer" and msg[2] == name and type(msg[3]) == "number" then
- parallel.waitForAny(function() run_transfer_recv(msg) end, function() sleep(5) print "Inbound transfer timed out" end)
- busy = false
- end
- end
- m.open(channel)
- while true do
- local ev, timer, c, rc, msg = os.pullEvent()
- if ev == "modem_message" and c == channel and rc == channel and type(msg) == "table" then
- local ok, err = pcall(process, msg)
- if not ok then printError(err) end
- elseif ev == "timer" and timer == pings_timer then
- pings_timer = nil
- end
- end
- end
- local function split_at_spaces(s)
- local t = {}
- for i in string.gmatch(s, "%S+") do
- table.insert(t, i)
- end
- return t
- end
- local function update_self()
- print "Downloading update."
- local h = http.get "https://pastebin.com/raw/R4HrijSg"
- local t = h.readAll()
- h.close()
- local fn, err = load(t, "@program")
- if not fn then printError("Not updating: syntax error in new version:\n" .. err) return end
- local f = fs.open("startup", "w")
- f.write(t)
- f.close()
- os.reboot()
- end
- local function ui()
- local history = {}
- while true do
- write "|> "
- local input = read(nil, history)
- table.insert(history, input)
- local tokens = split_at_spaces(input)
- if tokens[1] == "list" then
- list_all()
- sleep(1)
- elseif tokens[1] == "update" then
- update_self()
- elseif tokens[1] == "tp" then
- table.remove(tokens, 1)
- run_transfer(table.concat(tokens, " "))
- else
- printError "Not found"
- end
- end
- end
- parallel.waitForAll(ui, inbound)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement