222 lines
6.9 KiB
Lua
222 lines
6.9 KiB
Lua
-- ME空间原件控制器测试客户端
|
||
-- 在另一台计算机上运行,用于测试和控制海龟
|
||
printUtf8 = load(http.get("https://git.liulikeji.cn/xingluo/ComputerCraft-Utf8/raw/branch/main/utf8ptrint.lua").readAll())()
|
||
basalt = require("basalt")
|
||
|
||
-- 配置文件常量
|
||
local CLIENT_CONFIG_FILE = "disk_client_cfg"
|
||
|
||
-- 默认端口配置
|
||
local DEFAULT_PORTS = {
|
||
control = 101, -- 控制信道(发送切换命令)
|
||
response = 102, -- 响应接收信道
|
||
status = 100 -- 状态接收信道(原INVENTORY_CHANNEL)
|
||
}
|
||
|
||
-- 读取客户端配置文件
|
||
local function readClientConfig()
|
||
if not fs.exists(CLIENT_CONFIG_FILE) then
|
||
-- 创建默认配置文件
|
||
local defaultConfig = {
|
||
rednet_ports = DEFAULT_PORTS
|
||
}
|
||
|
||
local file = fs.open(CLIENT_CONFIG_FILE, "w")
|
||
file.write(textutils.serialize(defaultConfig))
|
||
file.close()
|
||
|
||
print("已创建客户端默认配置文件: " .. CLIENT_CONFIG_FILE)
|
||
return defaultConfig
|
||
end
|
||
|
||
local file = fs.open(CLIENT_CONFIG_FILE, "r")
|
||
local content = file.readAll()
|
||
file.close()
|
||
|
||
local config = textutils.unserialize(content) or {rednet_ports = DEFAULT_PORTS}
|
||
|
||
-- 确保端口配置完整
|
||
if not config.rednet_ports then
|
||
config.rednet_ports = DEFAULT_PORTS
|
||
else
|
||
-- 设置默认值
|
||
config.rednet_ports.control = config.rednet_ports.control or DEFAULT_PORTS.control
|
||
config.rednet_ports.response = config.rednet_ports.response or DEFAULT_PORTS.response
|
||
config.rednet_ports.status = config.rednet_ports.status or DEFAULT_PORTS.status
|
||
end
|
||
|
||
return config
|
||
end
|
||
|
||
-- 读取配置
|
||
local config = readClientConfig()
|
||
|
||
-- 初始化红网
|
||
local function initRednet()
|
||
local sides = {"left", "right", "front", "back", "top", "bottom"}
|
||
local modem = nil
|
||
|
||
for _, side in ipairs(sides) do
|
||
if peripheral.getType(side) == "modem" then
|
||
modem = peripheral.wrap(side)
|
||
-- 打开所有需要的端口
|
||
modem.open(config.rednet_ports.control)
|
||
modem.open(config.rednet_ports.response)
|
||
modem.open(config.rednet_ports.status)
|
||
print("找到网卡在: " .. side)
|
||
print("端口配置:")
|
||
print(" 控制端口: " .. config.rednet_ports.control)
|
||
print(" 响应端口: " .. config.rednet_ports.response)
|
||
print(" 状态端口: " .. config.rednet_ports.status)
|
||
break
|
||
end
|
||
end
|
||
|
||
if not modem then
|
||
error("未找到可用的网卡!")
|
||
end
|
||
|
||
return modem
|
||
end
|
||
|
||
local modem = initRednet()
|
||
|
||
-- 发送切换命令
|
||
local function sendSwitchCommand(diskName)
|
||
local message = {
|
||
type = "switch_disk",
|
||
disk_name = diskName
|
||
}
|
||
|
||
modem.transmit(config.rednet_ports.control, config.rednet_ports.control, message)
|
||
print("已发送切换命令: " .. diskName)
|
||
end
|
||
|
||
disks = {}
|
||
|
||
local mainf = basalt.createFrame()
|
||
local main = {
|
||
panel = mainf:addFrame():setPosition(1, 1):setSize("parent.w", "parent.h"):setBackground(colors.white),
|
||
}
|
||
|
||
UI = {}
|
||
|
||
-- 生成界面
|
||
function addFrameS(disks)
|
||
SY = {}
|
||
local SYI = 1
|
||
local h = 2
|
||
for name,slot in pairs(disks) do
|
||
UI[name] = {}
|
||
UI[name]["Back"] = main["panel"]:addFrame():setPosition(1, h):setSize("parent.w", 3):setBackground(colors.gray)
|
||
UI[name]["XZ"] = UI[name]["Back"]:addPane():setPosition(1, 1):setSize(1, 3):setBackground(false, "\149", colors.gray)
|
||
UI[name]["Name"] = UI[name]["Back"]:addProgram():setPosition(2, 1):setSize(35, 4):execute(function()
|
||
term.setBackgroundColor(colors.gray)
|
||
term.clear()
|
||
printUtf8(name, colors.white, colors.gray)
|
||
end):injectEvent("char", false, "w"):disable()
|
||
SY[SYI] = name
|
||
SYI = SYI + 1
|
||
h = h+4
|
||
end
|
||
end
|
||
|
||
-- 辅助函数:比较两个表是否相等
|
||
local function areTablesEqual(t1, t2)
|
||
if t1 == t2 then return true end
|
||
if type(t1) ~= "table" or type(t2) ~= "table" then return false end
|
||
|
||
for k, v in pairs(t1) do
|
||
if t2[k] ~= v then
|
||
return false
|
||
end
|
||
end
|
||
|
||
for k, v in pairs(t2) do
|
||
if t1[k] == nil then
|
||
return false
|
||
end
|
||
end
|
||
|
||
return true
|
||
end
|
||
|
||
-- 处理红网消息
|
||
local function handleRednetMessage(message)
|
||
if message.type == "status_update" then
|
||
-- 只有当两个表数值不一样时才执行
|
||
if not areTablesEqual(message.disks, disks) then
|
||
disks = message.disks
|
||
addFrameS(disks)
|
||
end
|
||
|
||
for name,slot in pairs(disks) do
|
||
if name == message.current_disk then
|
||
UI[name]["Back"]:setBackground(colors.red)
|
||
else
|
||
UI[name]["Back"]:setBackground(colors.gray)
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
DSY = 1
|
||
on = false
|
||
|
||
-- 主循环 - 消息监听
|
||
local function main1()
|
||
while true do
|
||
-- 检查红网消息
|
||
local event, side, channel, replyChannel, message, distance = os.pullEvent("modem_message")
|
||
|
||
-- 检查是否是状态端口或响应端口的消息
|
||
if (channel == config.rednet_ports.status or channel == config.rednet_ports.response) and type(message) == "table" then
|
||
handleRednetMessage(message)
|
||
if not on then
|
||
if SY and SY[DSY] then
|
||
UI[SY[DSY]]["XZ"]:setBackground(false, "\149", colors.lime)
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
local function main2()
|
||
while true do
|
||
local event, key, is_held = os.pullEvent("key")
|
||
if keys.getName(key) == "down" then
|
||
if SY and DSY ~= #SY then
|
||
DSY = DSY + 1
|
||
end
|
||
|
||
for k,v in pairs(SY or {}) do
|
||
if k == DSY then
|
||
UI[v]["XZ"]:setBackground(false, "\149", colors.lime)
|
||
else
|
||
UI[v]["XZ"]:setBackground(false, "\149", colors.gray)
|
||
end
|
||
end
|
||
sleep(0.5)
|
||
elseif keys.getName(key) == "up" then
|
||
if DSY > 1 then
|
||
DSY = DSY -1
|
||
end
|
||
|
||
for k,v in pairs(SY or {}) do
|
||
if k == DSY then
|
||
UI[v]["XZ"]:setBackground(false, "\149", colors.lime)
|
||
else
|
||
UI[v]["XZ"]:setBackground(false, "\149", colors.gray)
|
||
end
|
||
end
|
||
sleep(0.5)
|
||
elseif keys.getName(key) == "enter" then
|
||
if SY and SY[DSY] then
|
||
sendSwitchCommand(SY[DSY])
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
|
||
parallel.waitForAny(main1, main2, basalt.autoUpdate) |