274 lines
6.0 KiB
Lua
274 lines
6.0 KiB
Lua
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
|
||
) |