185 lines
5.9 KiB
Lua
185 lines
5.9 KiB
Lua
-- ATM10 Greenhouse inventory diagnostic
|
|
-- Read-only: detects a connected drawer/storage controller and writes its contents.
|
|
|
|
local OUTPUT_FILE = "greenhouse_inventory_debug.txt"
|
|
local requestedName = ({ ... })[1]
|
|
|
|
local function containsMethod(methods, wanted)
|
|
for _, method in ipairs(methods or {}) do
|
|
if method == wanted then return true end
|
|
end
|
|
return false
|
|
end
|
|
|
|
local function allTypes(name)
|
|
local types = { peripheral.getType(name) }
|
|
local result = {}
|
|
for _, value in ipairs(types) do
|
|
if type(value) == "string" then result[#result + 1] = value end
|
|
end
|
|
return result
|
|
end
|
|
|
|
local function joinedTypes(name)
|
|
return table.concat(allTypes(name), ", ")
|
|
end
|
|
|
|
local function isInventory(name)
|
|
if peripheral.hasType and peripheral.hasType(name, "inventory") then return true end
|
|
local methods = peripheral.getMethods(name) or {}
|
|
return containsMethod(methods, "list") and containsMethod(methods, "size")
|
|
end
|
|
|
|
local function safeCall(name, method, ...)
|
|
local result = table.pack(pcall(peripheral.call, name, method, ...))
|
|
if not result[1] then return false, tostring(result[2]) end
|
|
return true, table.unpack(result, 2, result.n)
|
|
end
|
|
|
|
local function itemCount(contents)
|
|
local total, occupied = 0, 0
|
|
for _, item in pairs(contents or {}) do
|
|
if type(item) == "table" and item.name then
|
|
total = total + (tonumber(item.count) or 0)
|
|
occupied = occupied + 1
|
|
end
|
|
end
|
|
return total, occupied
|
|
end
|
|
|
|
local function scoreCandidate(candidate)
|
|
local text = (candidate.name .. " " .. candidate.types):lower()
|
|
local score = candidate.occupied
|
|
if text:find("functionalstorage", 1, true) then score = score + 10000 end
|
|
if text:find("storage_controller", 1, true) then score = score + 5000 end
|
|
if text:find("controller", 1, true) then score = score + 2000 end
|
|
if text:find("drawer", 1, true) then score = score + 1000 end
|
|
return score
|
|
end
|
|
|
|
local candidates = {}
|
|
for _, name in ipairs(peripheral.getNames()) do
|
|
if isInventory(name) then
|
|
local okList, contents = safeCall(name, "list")
|
|
if okList and type(contents) == "table" then
|
|
local total, occupied = itemCount(contents)
|
|
local okSize, size = safeCall(name, "size")
|
|
candidates[#candidates + 1] = {
|
|
name = name,
|
|
types = joinedTypes(name),
|
|
contents = contents,
|
|
total = total,
|
|
occupied = occupied,
|
|
size = okSize and tonumber(size) or 0,
|
|
}
|
|
end
|
|
end
|
|
end
|
|
|
|
table.sort(candidates, function(left, right)
|
|
local leftScore, rightScore = scoreCandidate(left), scoreCandidate(right)
|
|
if leftScore == rightScore then return left.name < right.name end
|
|
return leftScore > rightScore
|
|
end)
|
|
|
|
local selected
|
|
if requestedName then
|
|
for _, candidate in ipairs(candidates) do
|
|
if candidate.name == requestedName then selected = candidate break end
|
|
end
|
|
if not selected then error("Inventar-Peripheral nicht gefunden: " .. requestedName, 0) end
|
|
else
|
|
selected = candidates[1]
|
|
end
|
|
|
|
if not selected then
|
|
error("Kein verbundenes Inventar gefunden. Wired Modem am Drawer Controller pruefen.", 0)
|
|
end
|
|
|
|
local aggregate = {}
|
|
for slot, item in pairs(selected.contents) do
|
|
if type(item) == "table" and item.name then
|
|
local entry = aggregate[item.name]
|
|
if not entry then
|
|
entry = { name = item.name, displayName = item.displayName, count = 0, slots = {} }
|
|
aggregate[item.name] = entry
|
|
end
|
|
entry.count = entry.count + (tonumber(item.count) or 0)
|
|
entry.slots[#entry.slots + 1] = tonumber(slot) or slot
|
|
end
|
|
end
|
|
|
|
local items = {}
|
|
for _, item in pairs(aggregate) do items[#items + 1] = item end
|
|
table.sort(items, function(left, right) return left.name < right.name end)
|
|
|
|
local function isEssence(item)
|
|
return item.name:find("_essence", 1, true) ~= nil
|
|
end
|
|
|
|
local function isSeed(item)
|
|
return item.name:find("_seeds", 1, true) ~= nil or item.name:find("_seed", 1, true) ~= nil
|
|
end
|
|
|
|
local file = fs.open(OUTPUT_FILE, "w")
|
|
if not file then error("Kann " .. OUTPUT_FILE .. " nicht schreiben", 0) end
|
|
|
|
local function line(text)
|
|
file.writeLine(tostring(text or ""))
|
|
end
|
|
|
|
line("ATM10 GREENHOUSE INVENTORY DEBUG")
|
|
line("Computer ID: " .. os.getComputerID())
|
|
line("Selected peripheral: " .. selected.name)
|
|
line("Types: " .. selected.types)
|
|
line("Slots reported: " .. tostring(selected.size))
|
|
line("Occupied entries: " .. selected.occupied)
|
|
line("Total items: " .. selected.total)
|
|
line("")
|
|
line("INVENTORY CANDIDATES")
|
|
for index, candidate in ipairs(candidates) do
|
|
line(string.format("%d. %s | %s | slots=%d occupied=%d items=%d%s",
|
|
index, candidate.name, candidate.types, candidate.size, candidate.occupied,
|
|
candidate.total, candidate == selected and " | SELECTED" or ""))
|
|
end
|
|
|
|
line("")
|
|
line("ESSENCES")
|
|
local essenceCount = 0
|
|
for _, item in ipairs(items) do
|
|
if isEssence(item) then
|
|
essenceCount = essenceCount + 1
|
|
line(string.format("%s | count=%d | slots=%s",
|
|
item.name, item.count, table.concat(item.slots, ",")))
|
|
end
|
|
end
|
|
line("Essence types: " .. essenceCount)
|
|
|
|
line("")
|
|
line("SEEDS")
|
|
local seedCount = 0
|
|
for _, item in ipairs(items) do
|
|
if isSeed(item) then
|
|
seedCount = seedCount + 1
|
|
line(string.format("%s | count=%d | slots=%s",
|
|
item.name, item.count, table.concat(item.slots, ",")))
|
|
end
|
|
end
|
|
line("Seed types: " .. seedCount)
|
|
|
|
line("")
|
|
line("ALL ITEMS")
|
|
for _, item in ipairs(items) do
|
|
line(string.format("%s | count=%d | slots=%s",
|
|
item.name, item.count, table.concat(item.slots, ",")))
|
|
end
|
|
line("Unique item types: " .. #items)
|
|
file.close()
|
|
|
|
print("Greenhouse-Dump erstellt:")
|
|
print(OUTPUT_FILE)
|
|
print("Controller: " .. selected.name)
|
|
print("Items: " .. #items .. " | Essenzen: " .. essenceCount .. " | Seeds: " .. seedCount)
|
|
print("Falls der falsche Controller gewaehlt wurde:")
|
|
print("greenhouse_inventory_debug <peripheral_name>")
|