115 lines
3.3 KiB
Lua
115 lines
3.3 KiB
Lua
-- 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
|