--[[ remote.lua - Bidirectional remote command execution Usage: remote [channel] Both computers must run this on the same channel. ]] local channel = tonumber(arg[1]) or 12345 local modem = peripheral.find("modem") if not modem then print("ERROR: No wireless modem attached.") return end modem.open(channel) local myID = os.getComputerID() local inputBuffer = "" print("=== Remote Control ===") print("My ID: " .. myID) print("Channel: " .. channel) print("Type a command and press Enter to send it to other computer(s).") print("Type 'exit' to quit.") print("-----------------------") local function printPrompt() term.write("[" .. myID .. "]> ", false) end -- Execute command and capture output local function executeCommand(cmd) local outFile = "/tmp/out_" .. myID .. ".txt" local errFile = "/tmp/err_" .. myID .. ".txt" shell.run(cmd .. " > " .. outFile .. " 2> " .. errFile) local output = "" if fs.exists(outFile) then local f = fs.open(outFile, "r") output = f.readAll() or "" f.close() fs.delete(outFile) end if fs.exists(errFile) then local f = fs.open(errFile, "r") local err = f.readAll() or "" f.close() fs.delete(errFile) if err ~= "" then if output ~= "" then output = output .. "\n" end output = output .. err end end if output == "" then output = "(no output)" end return output end -- Main loop while true do printPrompt() term.write(inputBuffer) term.setCursorBlink(true) local event, p1, p2, p3 = os.pullEvent() if event == "char" then local char = p1 inputBuffer = inputBuffer .. char local x, y = term.getCursorPos() term.setCursorPos(1, y) term.clearLine() printPrompt() term.write(inputBuffer) elseif event == "key" then if p2 == false then -- key release local key = p1 if key == keys.enter then local cmd = inputBuffer inputBuffer = "" if cmd == "exit" then print("\nExiting.") break end print("\nSending command: " .. cmd) modem.transmit(channel, channel, { type = "exec", cmd = cmd, sender = myID }) elseif key == keys.backspace then if #inputBuffer > 0 then inputBuffer = inputBuffer:sub(1, -2) local x, y = term.getCursorPos() term.setCursorPos(1, y) term.clearLine() printPrompt() term.write(inputBuffer) end end end elseif event == "modem_message" then local senderID = p1 local replyChannel = p2 local msg = p3 -- ********** 修复开始 ********** -- 检查 msg 是否是一个表,如果不是则忽略 if type(msg) ~= "table" then -- 非表消息直接丢弃(可以打印调试信息,但建议保持安静) -- print("[Ignored non-table message: " .. tostring(msg) .. "]") goto continue end -- 确保必要字段存在,否则忽略 if msg.target == nil and msg.type == nil then goto continue end -- ********** 修复结束 ********** -- 处理回复(来自其他电脑的执行结果) if msg.target and msg.target == myID then print("\n[Reply from " .. senderID .. "]") print(msg.data) -- 处理执行请求(来自其他电脑的命令) elseif msg.type == "exec" and msg.sender and msg.sender ~= myID then print("\n[Executing command from " .. msg.sender .. "]") print("Command: " .. msg.cmd) local output = executeCommand(msg.cmd) modem.transmit(channel, channel, { type = "result", data = output, target = msg.sender }) print("Reply sent.") end ::continue:: -- 忽略消息后继续循环 elseif event == "terminate" then print("\nTerminated.") break end end