Files
CCTweaked-utils/Logistics/V5/startup.lua

947 lines
42 KiB
Lua
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- Logistics System v5.0 (Multi-Container & Cache Mode)
-- 支持带缓存的复杂容器间传输
-- 配置保存在 config.cfg
local configFile = "config.cfg"
local tasks = {}
local settings = {
logEnabled = false, -- 日志开关,默认关闭
zhlog = false, -- 中文日志开关,默认关闭
delay = 0.01 -- 轮询延迟默认0.01秒
}
local Tlist = {} -- 缓存传输列表
local lastOutput = {} -- 记录每个任务每个优先级组上次使用的输出容器
-- 加载配置
local function loadConfig()
if fs.exists(configFile) then
local file = fs.open(configFile, "r")
local data = file.readAll()
file.close()
local config = textutils.unserialize(data) or {}
-- 加载设置
if config.settings then
settings.logEnabled = config.settings.logEnabled or settings.logEnabled
settings.zhlog = config.settings.zhlog or settings.zhlog
settings.delay = config.settings.delay or settings.delay
end
-- 加载任务
tasks = config.tasks or {}
-- 加载传输列表
Tlist = config.Tlist or {}
end
end
loadConfig()
-- 保存配置
local function saveConfig()
local config = {
settings = {
logEnabled = settings.logEnabled,
zhlog = settings.zhlog,
delay = settings.delay
},
tasks = tasks,
Tlist = Tlist
}
local file = fs.open(configFile, "w")
file.write(textutils.serialize(config))
file.close()
end
if settings.zhlog then
printUtf8 = load(http.get("https://alist.liulikeji.cn/d/HFS/utf8ptrint.lua").readAll())()
term.clear()
term.setCursorPos(1,1)
else
function printUtf8(logMessage,color,bcolor)
term.setTextColour(color)
term.setBackgroundColour(bcolor)
print(logMessage)
term.setTextColour(colors.white)
term.setBackgroundColour(colors.black)
end
end
-- 日志级别定义
local LOG_LEVEL = {
SUCCESS = {name = "SUCCESS", color = colors.green},
SKIPPED = {name = "SKIPPED", color = colors.orange},
INFO = {name = "INFO", color = colors.white},
WARNING = {name = "WARNING", color = colors.yellow},
ERROR = {name = "ERROR", color = colors.red},
DEBUG = {name = "DEBUG", color = colors.lightGray}
}
-- 日志记录函数
local function log(level, zhMessage, enMessage)
if level ~= LOG_LEVEL.ERROR then
if not settings.logEnabled then return end
end
local message = settings.zhlog and zhMessage or enMessage
local timeStr = os.date("%H:%M:%S")
local levelName = level.name
local color = level.color
-- 格式化日志消息
local logMessage = string.format("[%s] %s: %s", timeStr, levelName, message)
-- 打印日志
printUtf8(logMessage, color, colors.black)
end
-- 命令输出函数(双语支持)
local function echo(zhMessage, enMessage)
local message = settings.zhlog and zhMessage or enMessage
printUtf8(message, colors.lightBlue, colors.black)
end
-- 初始化日志
log(LOG_LEVEL.INFO, "程序开始 - 物流系统 v5.0", "Program started - Turtle Logistics System v5.0")
-- 获取容器物品列表
local function getContainerItems(containerName)
local container = peripheral.wrap(containerName)
if not container then
log(LOG_LEVEL.ERROR, "错误: 容器不存在: "..containerName, "Error: Container not found: "..containerName)
return nil
end
local items = {}
local containerList = container.list()
for slot, item in pairs(containerList) do
items[tostring(slot)] = {
count = item.count,
name = item.name
}
end
return items
end
-- 比较两个物品列表是否相同
local function compareItems(items1, items2)
if not items1 or not items2 then return false end
-- 检查槽位数量
local count1 = 0
for _ in pairs(items1) do count1 = count1 + 1 end
local count2 = 0
for _ in pairs(items2) do count2 = count2 + 1 end
if count1 ~= count2 then return false end
-- 检查每个槽位
for slot, item1 in pairs(items1) do
local item2 = items2[slot]
if not item2 then return false end
if item1.name ~= item2.name or item1.count ~= item2.count then
return false
end
end
return true
end
-- 获取容器中不在Tlist中的物品
local function getNewItems(containerName)
local currentItems = getContainerItems(containerName)
if not currentItems then return nil end
local tlistItems = Tlist[containerName] or {}
local newItems = {}
for slot, item in pairs(currentItems) do
local tlistItem = tlistItems[slot]
if not tlistItem or tlistItem.name ~= item.name or tlistItem.count ~= item.count then
newItems[slot] = item
end
end
return newItems
end
-- 更新Tlist中的容器记录
local function updateTlist(containerName, items)
if not Tlist[containerName] then
Tlist[containerName] = {}
end
-- 只更新传入的物品槽位
for slot, item in pairs(items) do
Tlist[containerName][slot] = {
name = item.name,
count = item.count
}
end
end
-- 清理Tlist中缺失的物品
local function cleanTlist(containerName)
if not Tlist[containerName] then return end
local currentItems = getContainerItems(containerName)
if not currentItems then return end
local toRemove = {}
-- 找出Tlist中存在但容器中不存在的物品
for slot, tlistItem in pairs(Tlist[containerName]) do
local currentItem = currentItems[slot]
if not currentItem or currentItem.name ~= tlistItem.name or currentItem.count ~= tlistItem.count then
table.insert(toRemove, slot)
end
end
-- 移除这些物品
for _, slot in ipairs(toRemove) do
Tlist[containerName][slot] = nil
end
end
-- 辅助函数:检查物品是否通过过滤规则
local function isItemAllowed(itemName, containerConfig)
-- 如果有白名单,只允许白名单中的物品
if containerConfig.whitelist then
return containerConfig.whitelist[itemName] ~= nil
end
-- 如果有黑名单,排除黑名单中的物品
if containerConfig.blacklist then
return containerConfig.blacklist[itemName] == nil
end
-- 没有过滤规则时允许所有物品
return true
end
-- 获取物品的传输数量限制
local function getTransferLimit(itemName, containerConfig)
-- 检查白名单中是否有该物品的数量限制
if containerConfig.whitelist and containerConfig.whitelist[itemName] then
local countSetting = containerConfig.whitelist[itemName].count
if countSetting and countSetting > 0 then
return countSetting
end
end
-- 如果没有限制或限制为0则返回nil表示传输全部
return nil
end
-- 在 executeItemTask 函数中添加更多调试日志
local function executeItemTask(task, taskIndex)
log(LOG_LEVEL.INFO, "开始执行物品任务 #"..taskIndex, "Starting item transfer task #"..taskIndex)
-- 收集所有输入容器的物品
local allItemsToTransfer = {}
-- 处理输入容器
for inputName, inputConfig in pairs(task.input) do
log(LOG_LEVEL.DEBUG, "开始处理输入容器: "..inputName, "Starting processing input container: "..inputName)
local container = peripheral.wrap(inputName)
if not container then
log(LOG_LEVEL.ERROR, "错误: 输入容器不存在: "..inputName, "Error: Input container not found: "..inputName)
goto continue
end
-- 缓存容器处理
if inputConfig.cache then
log(LOG_LEVEL.DEBUG, "容器 "..inputName.." 是缓存容器", "Container "..inputName.." is a cache container")
-- 清理Tlist中缺失的物品
cleanTlist(inputName)
-- 获取当前物品状态
local currentItems = getContainerItems(inputName)
if not currentItems then
log(LOG_LEVEL.DEBUG, "无法获取容器物品: "..inputName, "Failed to get container items: "..inputName)
goto continue
end
-- 检查是否与Tlist完全相同
if compareItems(currentItems, Tlist[inputName] or {}) then
log(LOG_LEVEL.DEBUG, "容器内容与Tlist相同跳过: "..inputName, "Container contents match Tlist, skipping: "..inputName)
goto continue
end
-- 获取新物品不在Tlist中的
local newItems = getNewItems(inputName)
if not newItems or not next(newItems) then
log(LOG_LEVEL.DEBUG, "没有新物品,跳过: "..inputName, "No new items, skipping: "..inputName)
goto continue
end
-- 添加到传输列表(应用输入容器过滤)
for slot, item in pairs(newItems) do
if isItemAllowed(item.name, inputConfig) then
-- 不再在输入容器限制流量
-- -- 获取传输数量限制
-- local transferLimit = getTransferLimit(item.name, inputConfig)
-- -- 检查是否满足传输条件
-- if transferLimit and item.count < transferLimit then
-- log(LOG_LEVEL.DEBUG, "物品 "..item.name.." 数量不足("..item.count.."<"..transferLimit.."),跳过传输",
-- "Item "..item.name.." insufficient quantity ("..item.count.."<"..transferLimit.."), skipping transfer")
-- goto continue_item
-- end
-- local transferCount = transferLimit or item.count
local transferCount = item.count
-- 如果数量大于0才添加
if transferCount > 0 then
log(LOG_LEVEL.DEBUG, "添加物品到传输列表: "..item.name.." x"..transferCount.." (槽位 "..slot..")",
"Adding item to transfer list: "..item.name.." x"..transferCount.." (slot "..slot..")")
table.insert(allItemsToTransfer, {
container = inputName,
slot = tonumber(slot),
name = item.name,
count = transferCount
})
else
log(LOG_LEVEL.DEBUG, "物品 "..item.name.." 数量不足,跳过传输",
"Item "..item.name.." insufficient quantity, skipping transfer")
end
else
log(LOG_LEVEL.DEBUG, "物品 "..item.name.." 被输入容器 "..inputName.." 过滤",
"Item "..item.name.." filtered by input container "..inputName)
end
::continue_item::
end
else
log(LOG_LEVEL.DEBUG, "容器 "..inputName.." 不是缓存容器", "Container "..inputName.." is not a cache container")
local items = getContainerItems(inputName)
if not items then
log(LOG_LEVEL.DEBUG, "无法获取容器物品: "..inputName, "Failed to get container items: "..inputName)
goto continue
end
for slot, item in pairs(items) do
-- 应用输入容器过滤
if isItemAllowed(item.name, inputConfig) then
-- 不再在输入容器限制流量
-- 获取传输数量限制
-- local transferLimit = getTransferLimit(item.name, inputConfig)
-- -- 检查是否满足传输条件
-- if transferLimit and item.count < transferLimit then
-- log(LOG_LEVEL.DEBUG, "物品 "..item.name.." 数量不足("..item.count.."<"..transferLimit.."),跳过传输",
-- "Item "..item.name.." insufficient quantity ("..item.count.."<"..transferLimit.."), skipping transfer")
-- goto continue_item_non_cache
-- end
-- local transferCount = transferLimit or item.count
local transferCount = item.count
-- 如果数量大于0才添加
if transferCount > 0 then
log(LOG_LEVEL.DEBUG, "添加物品到传输列表: "..item.name.." x"..transferCount.." (槽位 "..slot..")",
"Adding item to transfer list: "..item.name.." x"..transferCount.." (slot "..slot..")")
table.insert(allItemsToTransfer, {
container = inputName,
slot = tonumber(slot),
name = item.name,
count = transferCount
})
else
log(LOG_LEVEL.DEBUG, "物品 "..item.name.." 数量不足,跳过传输",
"Item "..item.name.." insufficient quantity, skipping transfer")
end
else
log(LOG_LEVEL.DEBUG, "物品 "..item.name.." 被输入容器 "..inputName.." 过滤",
"Item "..item.name.." filtered by input container "..inputName)
end
::continue_item_non_cache::
end
end
::continue::
end
if #allItemsToTransfer == 0 then
log(LOG_LEVEL.SKIPPED, "没有物品需要传输", "No items to transfer")
return false
end
log(LOG_LEVEL.INFO, "找到 "..#allItemsToTransfer.." 个物品需要传输", "Found "..#allItemsToTransfer.." items to transfer")
-- 按优先级分组输出容器
local outputGroups = {}
for outputName, outputConfig in pairs(task.output) do
local priority = outputConfig.priority or 1
if not outputGroups[priority] then
outputGroups[priority] = {}
end
table.insert(outputGroups[priority], {
name = outputName,
config = outputConfig
})
end
-- 按优先级排序(从高到低)
local sortedPriorities = {}
for priority in pairs(outputGroups) do
table.insert(sortedPriorities, priority)
end
table.sort(sortedPriorities, function(a, b) return a > b end)
-- 传输物品
local transferred = false
for _, itemData in ipairs(allItemsToTransfer) do
log(LOG_LEVEL.DEBUG, "尝试传输物品: "..itemData.name.." x"..itemData.count.." (源容器: "..itemData.container..", 槽位: "..itemData.slot..")",
"Attempting to transfer item: "..itemData.name.." x"..itemData.count.." (source: "..itemData.container..", slot: "..itemData.slot..")")
local sourceContainer = peripheral.wrap(itemData.container)
if not sourceContainer then
log(LOG_LEVEL.ERROR, "错误: 源容器不存在: "..itemData.container, "Error: Source container not found: "..itemData.container)
goto next_item
end
-- 尝试推送到输出容器
local pushed = false
-- 按优先级尝试输出
for _, priority in ipairs(sortedPriorities) do
local group = outputGroups[priority]
-- 轮询输出
local key = taskIndex.."_"..priority -- 使用任务索引和优先级作为唯一键
log(LOG_LEVEL.DEBUG, "输出容器键: "..key, "Output container key: "..key)
local startIdx = lastOutput[key] or 1
local idx = startIdx
local attempts = 0
repeat
log(LOG_LEVEL.DEBUG, "输出容器索引: "..tostring(idx).." 容器组大小: "..tostring(#group),"Output container index: "..tostring(idx).." group size: "..tostring(#group))
local output = group[idx]
log(LOG_LEVEL.DEBUG, "尝试输出容器: "..output.name.." (优先级 "..priority..", 尝试 "..attempts.."/"..#group..")",
"Attempting output container: "..output.name.." (priority "..priority..", attempt "..attempts.."/"..#group..")")
local outputContainer = peripheral.wrap(output.name)
if outputContainer then
-- 应用输出容器过滤
if not isItemAllowed(itemData.name, output.config) then
log(LOG_LEVEL.DEBUG, "物品 "..itemData.name.." 被输出容器 "..output.name.." 过滤",
"Item "..itemData.name.." filtered by output container "..output.name)
goto next_output
end
local transferLimit = getTransferLimit(itemData.name, output.config)
-- 检查是否满足传输条件
if transferLimit and itemData.count < transferLimit then
log(LOG_LEVEL.DEBUG, "物品 "..itemData.name.." 数量不足("..itemData.count.."<"..transferLimit.."),跳过传输",
"Item "..itemData.name.." insufficient quantity ("..itemData.count.."<"..transferLimit.."), skipping transfer")
goto next_output
end
local transferCount = transferLimit or itemData.count
log(LOG_LEVEL.DEBUG, "尝试推送到 "..output.name.." (优先级 "..priority..")", "Attempting push to "..output.name.." (priority "..priority..")")
-- 推送物品
local pushedCount = sourceContainer.pushItems(
output.name,
itemData.slot,
transferCount
)
if pushedCount > 0 then
log(LOG_LEVEL.SUCCESS, "成功推送 "..pushedCount..""..itemData.name..""..output.name, "Successfully pushed "..pushedCount.." "..itemData.name.." to "..output.name)
pushed = true
transferred = true
-- 更新输出容器的Tlist如果是缓存容器
if output.config.cache then
log(LOG_LEVEL.DEBUG, "更新输出容器Tlist: "..output.name, "Updating output container Tlist: "..output.name)
if not Tlist[output.name] then
Tlist[output.name] = {}
end
-- 获取输出容器当前物品
local outputItems = getContainerItems(output.name)
if outputItems then
-- 只更新传输的物品槽位
for slot, item in pairs(outputItems) do
if item.name == itemData.name then
Tlist[output.name][slot] = {
name = item.name,
count = item.count
}
end
end
end
end
-- 更新输入容器的Tlist如果是缓存容器
if task.input[itemData.container] and task.input[itemData.container].cache then
log(LOG_LEVEL.DEBUG, "更新输入容器Tlist: "..itemData.container, "Updating input container Tlist: "..itemData.container)
updateTlist(itemData.container, {
[tostring(itemData.slot)] = {
name = itemData.name,
count = itemData.count - pushedCount
}
})
end
-- 更新轮询索引
log(LOG_LEVEL.DEBUG, "轮询: idx:" .. tostring(idx) .. " #group:" .. tostring(#group))
lastOutput[key] = idx % #group + 1
break
else
log(LOG_LEVEL.WARNING, "推送失败到 "..output.name.." (可能容器已满或无法接收)",
"Push failed to "..output.name.." (container may be full or unable to receive)")
end
else
log(LOG_LEVEL.ERROR, "输出容器不存在或无法访问: "..output.name, "Output container not found or inaccessible: "..output.name)
end
::next_output::
idx = idx % #group + 1
attempts = attempts + 1
until attempts >= #group
if pushed then break end
end
if not pushed then
log(LOG_LEVEL.WARNING, "警告: 无法传输物品 "..itemData.name.." x"..itemData.count.." (所有输出容器尝试失败)",
"Warning: Failed to transfer item "..itemData.name.." x"..itemData.count.." (all output containers failed)")
end
::next_item::
end
if not transferred then
log(LOG_LEVEL.DEBUG, "所有物品传输尝试失败", "All item transfer attempts failed")
end
return transferred
end
-- 执行流体传输任务
local function executeFluidTask(task, taskIndex)
log(LOG_LEVEL.INFO, "开始执行流体任务 #"..taskIndex, "Starting fluid transfer task #"..taskIndex)
local transferred = false
-- 处理输入容器
for inputName, inputConfig in pairs(task.input) do
log(LOG_LEVEL.INFO, "处理输入容器: "..inputName, "Processing input container: "..inputName)
local source = peripheral.wrap(inputName)
if not source then
log(LOG_LEVEL.ERROR, "错误: 源容器不存在: "..inputName, "Error: Source container not found: "..inputName)
goto continue
end
if not source.tanks then
log(LOG_LEVEL.WARNING, "警告: 容器不支持流体: "..inputName.." - 跳过", "Warning: Container does not support fluids: "..inputName.." - skipping")
goto continue
end
-- 获取流体槽 - 使用 pairs 而不是 # 来计算数量
local tanks = source.tanks()
if not tanks then
log(LOG_LEVEL.INFO, "容器中没有流体槽: "..inputName, "No fluid tanks in container: "..inputName)
goto continue
end
-- 正确计算流体槽数量
local tankCount = 0
for _ in pairs(tanks) do tankCount = tankCount + 1 end
if tankCount == 0 then
log(LOG_LEVEL.INFO, "容器中没有流体槽: "..inputName, "No fluid tanks in container: "..inputName)
goto continue
end
-- 使用 pairs 遍历所有流体槽
for tankIndex, tank in pairs(tanks) do
-- 确保 tank 是有效的表
if type(tank) == "table" and tank.name and tank.amount then
-- 应用输入容器过滤
if tank.amount > 0 and isItemAllowed(tank.name, inputConfig) then
log(LOG_LEVEL.INFO, "找到可传输流体: "..tank.name.." ("..tank.amount.."mB)", "Found transferable fluid: "..tank.name.." ("..tank.amount.."mB)")
-- 按优先级分组输出容器
local outputGroups = {}
for outputName, outputConfig in pairs(task.output) do
local priority = outputConfig.priority or 1
if not outputGroups[priority] then
outputGroups[priority] = {}
end
table.insert(outputGroups[priority], {
name = outputName,
config = outputConfig
})
end
-- 按优先级排序(从高到低)
local sortedPriorities = {}
for priority in pairs(outputGroups) do
table.insert(sortedPriorities, priority)
end
table.sort(sortedPriorities, function(a, b) return a > b end)
-- 尝试传输流体
local pushed = false
local amountToTransfer = tank.amount
for _, priority in ipairs(sortedPriorities) do
local group = outputGroups[priority]
-- 轮询输出
local key = taskIndex.."_"..priority -- 使用任务索引和优先级作为唯一键
local startIdx = lastOutput[key] or 1
local idx = startIdx
local attempts = 0
repeat
local output = group[idx]
local destination = peripheral.wrap(output.name)
if destination and destination.tanks then
-- 应用输出容器过滤
if not isItemAllowed(tank.name, output.config) then
log(LOG_LEVEL.INFO, "流体 "..tank.name.." 被输出容器 "..output.name.." 过滤",
"Fluid "..tank.name.." filtered by output container "..output.name)
goto next_output
end
log(LOG_LEVEL.INFO, "尝试推送到 "..output.name.." (优先级 "..priority..")", "Attempting push to "..output.name.." (priority "..priority..")")
-- 推送流体
local pushedAmount = source.pushFluid(
output.name,
amountToTransfer,
tank.name,
tankIndex
)
if pushedAmount > 0 then
log(LOG_LEVEL.SUCCESS, "成功推送 "..pushedAmount.."mB "..tank.name..""..output.name, "Successfully pushed "..pushedAmount.."mB "..tank.name.." to "..output.name)
pushed = true
transferred = true
amountToTransfer = amountToTransfer - pushedAmount
-- 更新输出容器的Tlist如果是缓存容器
if output.config.cache then
log(LOG_LEVEL.DEBUG, "更新输出容器Tlist: "..output.name, "Updating output container Tlist: "..output.name)
if not Tlist[output.name] then
Tlist[output.name] = {}
end
-- 获取输出容器当前流体
local destTanks = destination.tanks()
if destTanks then
for _, destTank in pairs(destTanks) do
if destTank.name == tank.name then
Tlist[output.name][tank.name] = {
amount = destTank.amount
}
end
end
end
end
-- 更新轮询索引
lastOutput[key] = idx % #group + 1
else
log(LOG_LEVEL.WARNING, "推送失败到 "..output.name, "Push failed to "..output.name)
end
else
if not destination then
log(LOG_LEVEL.ERROR, "错误: 输出容器不存在: "..output.name, "Error: Output container not found: "..output.name)
else
log(LOG_LEVEL.WARNING, "错误: 输出容器不支持流体: "..output.name, "Error: Output container does not support fluids: "..output.name)
end
end
::next_output::
idx = idx % #group + 1
attempts = attempts + 1
until attempts >= #group or amountToTransfer <= 0
if amountToTransfer <= 0 then break end
end
if amountToTransfer > 0 then
log(LOG_LEVEL.WARNING, string.format("警告: 仍有 %dmB %s 未传输", amountToTransfer, tank.name),
string.format("Warning: Still %dmB %s not transferred", amountToTransfer, tank.name))
end
else
if tank.amount == 0 then
log(LOG_LEVEL.INFO, "槽位 "..tankIndex.." 无流体", "Tank "..tankIndex.." has no fluid")
else
log(LOG_LEVEL.INFO, "流体 "..tank.name.." 被输入容器 "..inputName.." 过滤",
"Fluid "..tank.name.." filtered by input container "..inputName)
end
end
else
log(LOG_LEVEL.WARNING, "警告: 槽位 "..tankIndex.." 的数据无效", "Warning: Invalid data for tank "..tankIndex)
end
end
::continue::
end
return transferred
end
-- 执行任务
local function executeTask(task, taskIndex)
if task.type == "item" then
return executeItemTask(task, taskIndex)
elseif task.type == "fluid" then
return executeFluidTask(task, taskIndex)
else
log(LOG_LEVEL.ERROR, "错误: 未知任务类型: "..(task.type or "nil"), "Error: Unknown task type: "..(task.type or "nil"))
return false
end
end
-- 主任务循环
local function taskLoop()
log(LOG_LEVEL.INFO, "任务循环开始", "Task loop started")
while true do
for i, task in ipairs(tasks) do
log(LOG_LEVEL.INFO, "开始任务 #"..i, "Starting task #"..i)
local success, result = pcall(executeTask, task, i)
if not success then
log(LOG_LEVEL.ERROR, "任务 #"..i.." 错误: "..tostring(result), "Task #"..i.." error: "..tostring(result))
elseif result then
log(LOG_LEVEL.SUCCESS, "任务 #"..i.." 成功执行", "Task #"..i.." executed successfully")
else
log(LOG_LEVEL.SKIPPED, "任务 #"..i.." 未执行传输", "Task #"..i.." no transfer performed")
end
end
os.sleep(settings.delay)
end
end
-- 命令处理
local function processCommand(cmd)
local args = {}
for word in cmd:gmatch("%S+") do
table.insert(args, word)
end
if #args == 0 then return end
local command = args[1]:lower()
if command == "add" and #args >= 2 then
-- 合并参数为JSON字符串
local jsonStr = table.concat(args, " ", 2)
local success, task = pcall(textutils.unserializeJSON, jsonStr)
if success and type(task) == "table" then
-- 验证任务类型
if not task.type then
echo("错误: 任务缺少类型字段", "Error: Task missing type field")
return
end
if task.type ~= "item" and task.type ~= "fluid" then
echo("错误: 无效的任务类型: "..task.type, "Error: Invalid task type: "..task.type)
return
end
-- 验证输入输出
if not task.input or not task.output then
echo("错误: 任务缺少输入或输出字段", "Error: Task missing input or output fields")
return
end
table.insert(tasks, task)
saveConfig()
echo("任务添加成功", "Task added successfully")
else
echo("错误: 无效的JSON格式", "Error: Invalid JSON format")
end
elseif command == "list" then
if #tasks == 0 then
echo("没有配置任务", "No tasks configured")
else
for i, task in ipairs(tasks) do
echo("任务 #"..i.." ("..task.type..")", "Task #"..i.." ("..task.type..")")
echo(" 输入容器:", " Input containers:")
for name, config in pairs(task.input) do
local cacheStr = config.cache and "缓存" or "非缓存"
local cacheStrEn = config.cache and "cache" or "non-cache"
-- 显示过滤规则
if config.whitelist then
local items = {}
for itemName, itemConfig in pairs(config.whitelist) do
if itemConfig.count and itemConfig.count > 0 then
table.insert(items, itemName.." (count="..itemConfig.count..")")
else
table.insert(items, itemName)
end
end
echo(" "..name.." ("..cacheStr..", 白名单: "..table.concat(items, ", ")..")",
" "..name.." ("..cacheStrEn..", whitelist: "..table.concat(items, ", ")..")")
elseif config.blacklist then
local items = {}
for itemName in pairs(config.blacklist) do
table.insert(items, itemName)
end
echo(" "..name.." ("..cacheStr..", 黑名单: "..table.concat(items, ", ")..")",
" "..name.." ("..cacheStrEn..", blacklist: "..table.concat(items, ", ")..")")
else
echo(" "..name.." ("..cacheStr..")", " "..name.." ("..cacheStrEn..")")
end
end
echo(" 输出容器:", " Output containers:")
for name, config in pairs(task.output) do
local cacheStr = config.cache and "缓存" or "非缓存"
local cacheStrEn = config.cache and "cache" or "non-cache"
local priority = config.priority or 1
-- 显示过滤规则
if config.whitelist then
local items = {}
for itemName, itemConfig in pairs(config.whitelist) do
if itemConfig.count and itemConfig.count > 0 then
table.insert(items, itemName.." (count="..itemConfig.count..")")
else
table.insert(items, itemName)
end
end
echo(" "..name.." (优先级:"..priority..", "..cacheStr..", 白名单: "..table.concat(items, ", ")..")",
" "..name.." (priority:"..priority..", "..cacheStrEn..", whitelist: "..table.concat(items, ", ")..")")
elseif config.blacklist then
local items = {}
for itemName in pairs(config.blacklist) do
table.insert(items, itemName)
end
echo(" "..name.." (优先级:"..priority..", "..cacheStr..", 黑名单: "..table.concat(items, ", ")..")",
" "..name.." (priority:"..priority..", "..cacheStrEn..", blacklist: "..table.concat(items, ", ")..")")
else
echo(" "..name.." (优先级:"..priority..", "..cacheStr..")",
" "..name.." (priority:"..priority..", "..cacheStrEn..")")
end
end
end
end
elseif command == "remove" and #args >= 2 then
local index = tonumber(args[2])
if index and tasks[index] then
table.remove(tasks, index)
saveConfig()
echo("任务 "..index.." 已移除", "Task "..index.." removed")
else
echo("无效的任务索引", "Invalid task index")
end
elseif command == "log" then
if #args >= 2 then
if args[2]:lower() == "on" then
settings.logEnabled = true
saveConfig()
echo("日志已启用", "Logging enabled")
elseif args[2]:lower() == "off" then
settings.logEnabled = false
saveConfig()
echo("日志已禁用", "Logging disabled")
else
echo("无效参数,使用 'log on' 或 'log off'", "Invalid argument, use 'log on' or 'log off'")
end
else
echo("当前日志状态: "..(settings.logEnabled and "启用" or "禁用"),
"Current log status: "..(settings.logEnabled and "enabled" or "disabled"))
end
-- 添加 set 命令
elseif command == "set" and #args >= 3 then
local key = args[2]:lower()
local value = args[3]
if key == "log" then
if value == "true" then
settings.logEnabled = true
saveConfig()
echo("日志已启用", "Logging enabled")
elseif value == "false" then
settings.logEnabled = false
saveConfig()
echo("日志已禁用", "Logging disabled")
else
echo("无效值,使用 'true' 或 'false'", "Invalid value, use 'true' or 'false'")
end
elseif key == "zh" then
if value == "true" then
settings.zhlog = true
saveConfig()
echo("中文日志已启用", "Chinese log enabled")
elseif value == "false" then
settings.zhlog = false
saveConfig()
echo("中文日志已禁用", "Chinese log disabled")
else
echo("无效值,使用 'true' 或 'false'", "Invalid value, use 'true' or 'false'")
end
elseif key == "delay" then
local numValue = tonumber(value)
if numValue and numValue > 0 then
settings.delay = numValue
saveConfig()
echo("轮询延迟已设置为: "..numValue.."", "Polling delay set to: "..numValue.." seconds")
else
echo("无效值请输入大于0的数字", "Invalid value, please enter a number greater than 0")
end
else
echo("无效设置项,可用选项: logEnabled, zhlog, delay", "Invalid setting, available options: logEnabled, zhlog, delay")
end
elseif command == "help" then
echo("可用命令:", "Available commands:")
echo("add <JSON任务> - 添加新任务", "add <JSON task> - Add new task")
echo(" 示例: add {\"type\":\"item\",\"input\":{\"left\":{\"cache\":true,\"whitelist\":{\"minecraft:stone\":{\"count\":64}}}},\"output\":{\"right\":{\"priority\":1,\"blacklist\":{\"minecraft:dirt\":{}}}}",
" Example: add {\"type\":\"item\",\"input\":{\"left\":{\"cache\":true,\"whitelist\":{\"minecraft:stone\":{\"count\":64}}}},\"output\":{\"right\":{\"priority\":1,\"blacklist\":{\"minecraft:dirt\":{}}}}")
echo("list - 列出所有任务", "list - List all tasks")
echo("remove <索引> - 移除任务", "remove <index> - Remove task")
echo("log [on|off] - 启用/禁用日志", "log [on|off] - Enable/disable logging")
echo("set <key> <value> - 修改设置", "set <key> <value> - Modify settings")
echo(" 可用键: logEnabled (true/false), zhlog (true/false), delay (数字)", " Available keys: logEnabled (true/false), zhlog (true/false), delay (number)")
echo("exit - 退出程序", "exit - Exit program")
elseif command == "exit" then
echo("正在退出程序", "Exiting program")
os.sleep(0.5)
error("程序终止", 0)
end
end
-- 初始化
echo("物流系统 v5.0 已启动。输入 'help' 查看命令。",
"Turtle Logistics System v5.0 started. Type 'help' for commands.")
-- 主循环
parallel.waitForAll(
function()
while true do
write("> ")
local command = read()
processCommand(command)
end
end,
taskLoop
)