Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- ===== CONFIG =====
- local CENTRAL_ID = nil -- set with :cid <id>
- local PROTO_CMD = "central_cmd" -- protocol for sending commands to central
- local TIMEOUT_S = 2
- -- ==================
- -- open wireless modem
- rednet.close()
- for _,s in ipairs(rs.getSides()) do if peripheral.getType(s)=="modem" then rednet.open(s) end end
- assert(rednet.isOpen(), "No wireless modem. Use an Advanced Wireless Pocket Computer.")
- -- ui state
- local W,H = term.getSize()
- local log = {}
- local input = ""
- local cursor = 1
- local running = true
- local function push(msg)
- log[#log+1] = msg
- if #log > 100 then table.remove(log,1) end
- end
- local function redraw()
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- term.clear()
- W,H = term.getSize()
- -- header
- term.setCursorPos(1,1)
- term.setTextColor(colors.yellow)
- local hdr = ("central:%s proto:%s"):format(CENTRAL_ID and tostring(CENTRAL_ID) or "none", PROTO_CMD)
- term.write(hdr)
- -- log
- term.setTextColor(colors.white)
- local maxLines = math.max(0, H-3)
- local start = math.max(1, #log - maxLines + 1)
- local y = 2
- for i=start,#log do
- term.setCursorPos(1,y)
- term.write(("%-"..W.."s"):format(tostring(log[i]):sub(1,W)))
- y=y+1
- end
- -- input line
- term.setCursorPos(1,H)
- term.setBackgroundColor(colors.blue)
- term.setTextColor(colors.white)
- term.write((":%s"):format(input))
- term.setBackgroundColor(colors.black)
- term.setCursorPos(2+cursor, H)
- end
- local function send_line(line)
- if not CENTRAL_ID then push("ERR: set central id with :cid <id>"); return end
- local ok = rednet.send(CENTRAL_ID, {type="cmd", line=line}, PROTO_CMD)
- if not ok then push("ERR: rednet.send failed") else push("> "..line) end
- end
- local function ping()
- if not CENTRAL_ID then push("ERR: no central id") return end
- rednet.send(CENTRAL_ID, {type="ping"}, PROTO_CMD)
- local id,msg,proto = rednet.receive(PROTO_CMD, TIMEOUT_S)
- if id==CENTRAL_ID and type(msg)=="table" and msg.type=="pong" then
- push("pong:"..(msg.note or "ok"))
- else
- push("no pong")
- end
- end
- local function help()
- push("Commands:")
- push(":cid <id> set central computer ID")
- push(":ping test connection")
- push(":proto <name> set protocol (default central_cmd)")
- push(":send <text> send raw line")
- push(":help show this help")
- push("Shortcuts (mapped to central commands):")
- push(" cam yaw <deg> | cam pitch <deg> | cam dist <n>")
- push(" track on|off | highlight x y z [r] | clear highlights")
- push(" center x y z | tid <id> | tfind")
- push(" fwd/back/up/down <n> | left/right | halt | goto x y z")
- end
- local function parse_local(cmdline)
- local args = {}
- for w in tostring(cmdline):gmatch("%S+") do args[#args+1]=w end
- if #args==0 then return end
- local c = args[1]:lower()
- if c=="cid" and args[2] then CENTRAL_ID = tonumber(args[2]); push("central id="..tostring(CENTRAL_ID)); return
- elseif c=="ping" then ping(); return
- elseif c=="proto" and args[2] then PROTO_CMD = args[2]; push("proto="..PROTO_CMD); return
- elseif c=="send" then table.remove(args,1); send_line(table.concat(args, " ")); return
- elseif c=="help" or c=="?" then help(); return end
- -- otherwise treat whole line as central command
- send_line(table.concat(args, " "))
- end
- -- receive loop (acks or server help)
- local function net_loop()
- while running do
- local id,msg,proto = rednet.receive(PROTO_CMD, 0.2)
- if id and type(msg)=="table" then
- if msg.type=="ack" then push("ack:"..tostring(msg.note or msg.line or "ok"))
- elseif msg.type=="err" then push("err:"..tostring(msg.note or ""))
- elseif msg.type=="info" then push(tostring(msg.text or ""))
- elseif msg.type=="pong" then push("pong")
- end
- end
- end
- end
- -- input loop
- local function input_loop()
- redraw()
- while running do
- local e = {os.pullEvent()}
- if e[1]=="char" then
- input = input .. e[2]
- cursor = #input
- redraw()
- elseif e[1]=="key" then
- local k=e[2]
- if k==keys.enter then
- local line = input
- input=""; cursor=0
- redraw()
- parse_local(line)
- redraw()
- elseif k==keys.backspace then
- input = input:sub(1, math.max(0,#input-1))
- cursor = #input
- redraw()
- elseif k==keys.q then
- running=false
- end
- elseif e[1]=="term_resize" then
- redraw()
- end
- end
- end
- parallel.waitForAny(net_loop, input_loop)
- term.setBackgroundColor(colors.black); term.setTextColor(colors.white); term.clear()
- print("Console closed.")
Advertisement
Add Comment
Please, Sign In to add comment