Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local channel = 31415
- local m = peripheral.find("modem", function(_, o) return o.isWireless() end)
- if not m then error "Modem required!" end
- local tele = peripheral.find "Teleporter"
- if not tele then error "Teleporter (see Mekanism wiki) required!" end
- local sign = peripheral.find "minecraft:sign"
- local rift_ID = os.getComputerLabel():match "Rift:([A-Za-z0-9_-]+)"
- if not rift_ID then error "Please relabel this computer `Rift:[unique rift identifier]`." end
- m.open(channel)
- local function display_status(...)
- if sign then sign.setSignText(rift_ID, ...) 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 first_letter(s)
- return string.sub(s, 1, 1)
- end
- local function update_self()
- print "Downloading update."
- local h = http.get "https://pastebin.com/raw/jta5puZL"
- local t = h.readAll()
- h.close()
- local fn, err = load(t, "@rift")
- if not fn then printError("Not updating: syntax error:\n" .. err) end
- local f = fs.open("startup", "w")
- f.write(t)
- f.close()
- os.reboot()
- end
- local teleporter_errors = {
- [2] = "Frame invalid.",
- [3] = "Pairing error.",
- [4] = "Insufficient energy."
- }
- local function send_message(...)
- m.transmit(channel, channel, { ... })
- end
- local function disconnect(remote)
- display_status "Idle"
- if not remote then send_message("command", "handle_disconnect", rift_ID) end
- tele.setFrequency(("rift-%s-null"):format(rift_ID), true)
- end
- local connected_to = nil
- local remote_commands = {
- ping = function()
- return { rift_ID }
- end,
- update = function()
- update_self()
- end,
- dial = function(from, to)
- if to ~= rift_ID then return end
- if type(from) ~= "string" then error("Invalid or no originator specified!") end
- local freq = ("rift-%s-%s"):format(from, to)
- tele.setFrequency(freq, true)
- local status = tele.canTeleport()
- if status == 1 then
- print(("Connection established from %s."):format(from))
- display_status("Dialed from:", from)
- connected_to = from
- return { true }
- else
- local e = teleporter_errors[status] or "Unknown error."
- display_status("Error:", e)
- printError(("Error receiving connection from %s: %s"):format(from, e))
- return { false, e }
- end
- end,
- handle_disconnect = function(other_end)
- if other_end == connected_to then disconnect(true) end
- end
- }
- local function timeout(fn, time)
- local timer = os.startTimer(time)
- local co = coroutine.create(fn)
- local filter
- while true do
- local ev = { os.pullEvent() }
- if coroutine.status(co) == "dead" or ev[1] == "timer" and ev[2] == timer then return end
- if not filter or filter == ev[1] then
- local ok, res = coroutine.resume(co, unpack(ev))
- if not ok then error(res)
- else filter = res end
- end
- end
- end
- local usage =
- [[Welcome to Rift. All listed commands are accessible by single-letter shortcuts.
- dial [destination] - Open a connection to rift [destination].
- scan - Scan for available rifts.
- scan [filter] - Scan for available rifts whose names contain [filter].
- help - Print this.
- update - Update this.
- disconnect - Disconnect from current paired rift.
- id - Get the ID of the current rift.]]
- local CLI_commands = {
- help = function() textutils.pagedPrint(usage) end,
- dial = function(dest)
- if not dest then error "No destination rift specified." end
- local freq = ("rift-%s-%s"):format(rift_ID, dest)
- print(("Setting frequency to %s."):format(freq))
- tele.setFrequency(freq, true)
- print(("Sending dial request to %s."):format(dest))
- send_message("command", "dial", rift_ID, dest)
- local result
- timeout(function()
- while true do
- local _, response_to, success, error_type = os.pullEvent "remote_result"
- if response_to == "dial" then
- if not success then
- print(dest, "reports error:", error_type)
- result = "remote_error"
- else
- print(dest, "reports success.")
- local status = tele.canTeleport()
- if status == 1 then
- result = "success"
- print "Link established."
- display_status("Dialed to:", dest)
- connected_to = dest
- else
- result = "local_error"
- local e = teleporter_errors[status] or "Unknown error."
- display_status("Error:", e)
- print(e)
- end
- end
- break
- end
- end
- end, 1)
- if result == nil then error(dest .. " is unreachable or nonexistent.", 0) end
- end,
- update = function(what)
- if what == "all" then
- send_message("command", "update")
- print "Update command broadcast"
- end
- update_self()
- end,
- scan = function(filter)
- send_message("command", "ping")
- print "Scanning..."
- timeout(function()
- while true do
- local _, resp_to, from = os.pullEvent "remote_result"
- if resp_to == "ping" and from and (not filter or from:match(filter)) then
- print("Found:", from)
- end
- end
- end, 1)
- end,
- disconnect = disconnect,
- id = function()
- print("Rift ID:", rift_ID)
- end
- }
- local function command_prompt()
- print "Welcome to Rift!"
- local history = {}
- while true do
- write "|> "
- local text = read(nil, history)
- if text ~= "" then table.insert(history, text) end
- local tokens = split_at_spaces(text)
- local command = table.remove(tokens, 1)
- local args = tokens
- local fn = CLI_commands[command]
- if not fn then
- for command_name, func in pairs(CLI_commands) do
- if command and first_letter(command_name) == first_letter(command) then fn = func end
- end
- end
- if not fn then
- print("Command", command, "not found.")
- else
- local ok, err = pcall(fn, table.unpack(args))
- if not ok then printError(err) end
- end
- end
- end
- local function message_handler()
- while true do
- local _, _, _, _, message = os.pullEvent "modem_message"
- if type(message) == "table" then
- local mtype = table.remove(message, 1)
- if mtype == "command" then
- local cmd = table.remove(message, 1)
- local cmd_fn = remote_commands[cmd]
- if cmd_fn then
- local ok, res = pcall(cmd_fn, unpack(message))
- if ok then
- if type(res) == "table" then
- send_message("result", cmd, unpack(res))
- end
- else
- printError(res)
- send_message("error", res)
- end
- end
- elseif mtype == "result" then os.queueEvent("remote_result", unpack(message))
- elseif mtype == "error" then os.queueEvent("remote_error", unpack(message)) end
- end
- end
- end
- if ... == "update" then update_self() end
- disconnect()
- parallel.waitForAny(message_handler, command_prompt)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement