-- ===== CONFIG ===== local CENTRAL_ID = nil -- set with :cid 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 "); 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 set central computer ID") push(":ping test connection") push(":proto set protocol (default central_cmd)") push(":send send raw line") push(":help show this help") push("Shortcuts (mapped to central commands):") push(" cam yaw | cam pitch | cam dist ") push(" track on|off | highlight x y z [r] | clear highlights") push(" center x y z | tid | tfind") push(" fwd/back/up/down | 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.")