local config = {} function log(text) --print(text) end -- 保存配置文件 local function saveConfig() local file = fs.open(".key_config", "w") file. write(textutils.serialize(config)) file.close() end -- 加载或创建配置文件 local function loadOrCreateConfig() if fs.exists(".key_config") then local file = fs.open(".key_config", "r") local content = file.readAll() file.close() config = textutils.unserialize(content) log("Config loaded") else log("Creating default config...") config = { events = { "key", "key_up", "mouse_click", "mouse_drag", "mouse_scroll", "mouse_up", "char", "paste", }, fn_key = "rightAlt", target_channels = {["q"] = "nil", ["w"] = "nil", ["e"] = "nil", ["r"] = "nil"}, special_keys = { ["one"] = "f1", ["two"] = "f2", ["three"] = "f3", ["four"] = "f4", ["five"] = "f5", ["six"] = "f6", ["seven"] = "f7", ["eight"] = "f8", ["nine"] = "f9", ["zero"] = "f10", ["minus"] = "f11", ["equals"] = "f12", ["1"] = "f1", ["2"] = "f2", ["3"] = "f3", ["4"] = "f4", ["5"] = "f5", ["6"] = "f6", ["7"] = "f7", ["8"] = "f8", ["9"] = "f9", ["0"] = "f10", ["-"] = "f11", ["="] = "f12" }, target = "q", -- 默认目标频道 protocol = "wireless_keyboard" -- 通信协议 } saveConfig() log("Default config created") end end -- 初始化 rednet local function initRednet() peripheral.find("modem", rednet.open) end -- 在表中查找值的索引 local function findIndex(tbl, value) for i, v in ipairs(tbl) do if v == value then return i end end return false end -- 显示状态信息 local function updateDisplay() term.setCursorPos(1, 1) term.setTextColor(colors.white) term.setBackgroundColor(colors.gray) term.clearLine() local id = config.target_channels[config.target] term.write("Target: " .. config.target.." | ID: " .. id) term.setBackgroundColor(colors.lightGray) end -- 发送事件到服务器 local function sendEvent(eventType, ...) log("Sending event: " .. eventType) local args = {...} local payload = { type = eventType, args = args, timestamp = os.clock() } local id = config.target_channels[config.target] if id ~= "nil" then rednet.send(id, payload, config.protocol) end end -- ID输入对话框 local function showIdInputDialog(keyName) term.clear() term.setCursorPos(1, 1) term.setTextColor(colors.yellow) print("=== ID Pairing Mode ===") term.setTextColor(colors.white) print("") print("Enter target computer ID:") print("") while true do local input = read() local id = tonumber(input) if not id then term.setTextColor(colors.red) print("Invalid ID! Please enter a numeric ID:") term.setTextColor(colors.white) end config.target_channels[keyName] = id break end term.setCursorPos(1, 1) term.setTextColor(colors.white) term.setBackgroundColor(colors.lightGray) term.clear() updateDisplay() saveConfig() end function key_Handle(event, ...) arg = {...} -- 处理key事件 if event == "key" then local keyName = keys.getName(arg[1]) if keyName == config.fn_key then return end if fnPressed then if config.special_keys[keyName] then -- 特殊键映射(Fn + 1-0-= -> F1-F12) log(keyName.." to "..config.special_keys[keyName]) local specialKey = config.special_keys[keyName] arg[1] = keys[specialKey] sendEvent("key", arg) elseif config.target_channels[keyName] then if arg[2] then -- Fn + 长按 Q/W/E/R -> 进入配对模式 showIdInputDialog(keyName) else -- Fn + 短按 Q/W/E/R -> 切换频率 config.target = keyName updateDisplay() end else -- 其他按键与 Fn 一起按下,直接发送原始按键 log("Sending key for key: " .. keyName) sendEvent("key", arg) end else -- 正常按键 sendEvent("key", arg) end --处理key_up事件 elseif event == "key_up" then local keyName = keys.getName(arg[1]) if keyName == config.fn_key then return end if fnPressed then if config.special_keys[keyName] then log(keyName.." to "..config.special_keys[keyName]) -- 特殊键映射(Fn + 1-0-= -> F1-F12) local specialKey = config.special_keys[keyName] arg[1] = keys[specialKey] sendEvent("key_up", arg) elseif config.target_channels[keyName] then -- 忽略 Fn + Q/W/E/R 的 key_up 事件 return else -- 其他按键与 Fn 一起按下,直接发送原始按键 log("Sending key_up for key: " .. keyName) sendEvent("key_up", arg) end else sendEvent("key_up", arg) end elseif event == 'char' then local keyName = arg[1] if fnPressed then if config.special_keys[keyName] then return elseif config.target_channels[keyName] then -- 忽略 Fn + Q/W/E/R 的 char 事件 return else -- 其他按键与 Fn 一起按下,直接发送原始按键 log("Sending char for key: " .. keyName) sendEvent("char", arg) end else sendEvent("char", arg) end -- 检查事件是否在events列表中 elseif findIndex(config.events, event) then sendEvent(event, arg) end end function fn_Thread() fnPressed = false while true do local event, key, is_held = os.pullEvent("key") if keys.getName(key) == config.fn_key then fnPressed = true while true do local event, key = os.pullEvent("key_up") if keys.getName(key) == config.fn_key then fnPressed = false break end end end end end function key_Thread() while true do key_Handle(os.pullEvent()) end end term.clear() loadOrCreateConfig() initRednet() updateDisplay() parallel.waitForAny( fn_Thread, key_Thread )