上传文件至 /
This commit is contained in:
274
Keyboard_client.lua
Normal file
274
Keyboard_client.lua
Normal file
@@ -0,0 +1,274 @@
|
|||||||
|
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
|
||||||
|
)
|
||||||
78
Keyboard_server.lua
Normal file
78
Keyboard_server.lua
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
local config = {}
|
||||||
|
|
||||||
|
function log(text)
|
||||||
|
--print("[" .. os.date("%H:%M:%S") .. "] " .. 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 = {
|
||||||
|
protocol = "wireless_keyboard",
|
||||||
|
external_program = "shell", -- 默认外部程序
|
||||||
|
}
|
||||||
|
saveConfig()
|
||||||
|
log("Default config created")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- 初始化 rednet
|
||||||
|
local function initRednet()
|
||||||
|
peripheral.find("modem", rednet.open)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 网络监听函数
|
||||||
|
local function networkListener()
|
||||||
|
while true do
|
||||||
|
local senderId, message, protocol = rednet.receive()
|
||||||
|
|
||||||
|
if protocol == config.protocol and message.type then
|
||||||
|
-- 注入事件到本机事件队列
|
||||||
|
|
||||||
|
os.queueEvent(message.type, table.unpack(message.args[1]))
|
||||||
|
|
||||||
|
log("Event from ID " .. senderId .. ": " .. message.type)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 外部程序运行函数
|
||||||
|
local function runExternalProgram()
|
||||||
|
shell.run(config.external_program)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 主函数
|
||||||
|
local function main()
|
||||||
|
loadOrCreateConfig()
|
||||||
|
initRednet()
|
||||||
|
|
||||||
|
log("=== Wireless Keyboard Server ===")
|
||||||
|
log("Protocol: " .. config.protocol)
|
||||||
|
log("External program: " .. config.external_program)
|
||||||
|
log("")
|
||||||
|
|
||||||
|
-- 并行执行网络监听和外部程序
|
||||||
|
parallel.waitForAny(networkListener, runExternalProgram)
|
||||||
|
|
||||||
|
log("Server stopped")
|
||||||
|
rednet.close()
|
||||||
|
end
|
||||||
|
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user