diff --git a/lib/itemDB.lua b/lib/itemDB.lua new file mode 100644 index 0000000..5c4f735 --- /dev/null +++ b/lib/itemDB.lua @@ -0,0 +1,114 @@ +-- lib/itemDB.lua — Item display name database +-- Learns display names from getItemDetail() and persists to disk. +-- Adapted from opus-apps core.itemDB for Inventory Manager. +-- +-- Usage: +-- local itemDB = dofile("lib/itemDB.lua") +-- itemDB.init(".item_names.db") +-- itemDB.learn("minecraft:diamond", "Diamond") +-- print(itemDB.getName("minecraft:diamond")) --> "Diamond" + +local itemDB = {} + +local nameData = {} +local DATA_FILE = nil +local dirty = false + +------------------------------------------------- +-- Initialization and persistence +------------------------------------------------- + +function itemDB.init(dataFile) + DATA_FILE = dataFile + itemDB.load() +end + +function itemDB.load() + if not DATA_FILE or not fs.exists(DATA_FILE) then return end + pcall(function() + local f = fs.open(DATA_FILE, "r") + local raw = f.readAll() + f.close() + local data = textutils.unserialise(raw) + if type(data) == "table" then + nameData = data + end + end) +end + +function itemDB.flush() + if not dirty or not DATA_FILE then return end + pcall(function() + local f = fs.open(DATA_FILE, "w") + f.write(textutils.serialise(nameData)) + f.close() + end) + dirty = false +end + +------------------------------------------------- +-- Name resolution +------------------------------------------------- + +--- Get a human-readable display name for an item. +-- Falls back to generating a name from the item ID. +-- @param itemName string or table with .name field +-- @return string +function itemDB.getName(itemName) + if type(itemName) == "table" then itemName = itemName.name end + if not itemName then return "?" end + if nameData[itemName] then return nameData[itemName] end + -- Generate readable name from item ID (e.g. "minecraft:iron_ingot" -> "Iron Ingot") + local short = itemName:gsub("^[%w_]+:", "") + return short:gsub("_", " "):gsub("(%a)([%w_']*)", function(first, rest) + return first:upper() .. rest:lower() + end) +end + +--- Learn a display name for an item. +-- @param itemName string or table with .name and optional .displayName +-- @param displayName string (optional if itemName is a table) +function itemDB.learn(itemName, displayName) + if type(itemName) == "table" then + displayName = displayName or itemName.displayName + itemName = itemName.name + end + if itemName and displayName and displayName ~= "" then + if nameData[itemName] ~= displayName then + nameData[itemName] = displayName + dirty = true + end + end +end + +--- Learn from a getItemDetail() result table. +-- @param detail table with .name and .displayName fields +function itemDB.learnFromDetail(detail) + if detail and detail.name and detail.displayName then + itemDB.learn(detail.name, detail.displayName) + end +end + +------------------------------------------------- +-- Queries +------------------------------------------------- + +--- Check if an item's display name has been learned. +function itemDB.isKnown(itemName) + if type(itemName) == "table" then itemName = itemName.name end + return nameData[itemName] ~= nil +end + +--- Get all known name mappings. +function itemDB.getAllNames() + return nameData +end + +--- Get count of known items. +function itemDB.count() + local n = 0 + for _ in pairs(nameData) do n = n + 1 end + return n +end + +return itemDB