wyvern/backend-chests.lua

125 lines
3.7 KiB
Lua
Raw Normal View History

2018-07-26 09:48:51 +00:00
-- Chest backend
-- Currently just the one for Dragon. Will not actually work yet.
2018-07-26 14:56:42 +00:00
local w = require "lib"
local d = require "luadash"
2018-07-26 09:28:37 +00:00
2018-07-26 14:56:42 +00:00
local conf = w.load_config({
"buffer_internal",
"buffer_external"
})
local BUFFER_OUT_SLOT = 1
local BUFFER_IN_SLOT = 2
2018-07-26 09:28:37 +00:00
-- Find all chests or shulker boxes
2018-07-26 14:56:42 +00:00
local inventories = w.find_peripherals(function(type, name, wrapped)
return string.find(name, "chest") or string.find(name, "shulker")
end)
2018-07-26 09:28:37 +00:00
local nameCache = {}
2018-07-26 15:25:42 +00:00
-- Get the name for an item in the cache
2018-07-26 14:56:42 +00:00
local function get_cache_name(item)
local n = item.name .. ":" .. item.damage
2018-07-26 15:25:42 +00:00
if item.nbtHash then n = n .. "#" .. item.nbtHash end
return n
2018-07-26 14:56:42 +00:00
end
2018-07-26 09:28:37 +00:00
-- Gets the display name of the given item (in the given chest peripheral & slot)
-- If its name is not cached, cache it.
-- If it is, just return the cached name
2018-07-26 14:56:42 +00:00
local function cache(item, chest, slot)
2018-07-26 15:25:42 +00:00
local idx = get_cache_name(item)
2018-07-26 09:28:37 +00:00
if nameCache[idx] then
return nameCache[idx]
else
2018-07-26 14:56:42 +00:00
local n = chest.getItemMeta(slot).display_name
2018-07-26 09:28:37 +00:00
nameCache[idx] = n
return n
end
end
local index = {}
2018-07-26 14:56:42 +00:00
-- Update the index for the given peripheral
local function update_index_for(name)
2018-07-26 09:28:37 +00:00
local inv = inventories[name]
local data = inv.list()
for slot, item in pairs(data) do
2018-07-26 14:56:42 +00:00
data[slot].display_name = cache(item, inv, slot)
2018-07-26 09:28:37 +00:00
end
index[name] = data
end
2018-07-26 14:56:42 +00:00
-- Reindex all connected inventories
local function update_index()
2018-07-26 09:28:37 +00:00
for n in pairs(inventories) do
2018-07-26 15:17:41 +00:00
update_index_for(n)
2018-07-26 09:28:37 +00:00
sleep()
end
print "Indexing complete."
end
2018-07-26 14:56:42 +00:00
-- Finds all items matching a certain predicate.
-- Returns a table of tables of { name, slot, item }
local function find(predicate)
local ret = {}
for inventory, items in pairs(index) do
2018-07-26 09:28:37 +00:00
for slot, item in pairs(items) do
2018-07-26 14:56:42 +00:00
local ok, extra = predicate(item) -- allow predicates to return some extra data which will come out in resulting results
if ok then
table.insert(ret, { location = { inventory = inventory, slot = slot }, item = item, extra = extra })
2018-07-26 09:28:37 +00:00
end
end
end
2018-07-26 14:56:42 +00:00
return ret
2018-07-26 09:28:37 +00:00
end
2018-07-26 14:56:42 +00:00
-- Finds space in the chest system. Returns the name of an inventory which has space.
local function find_space()
2018-07-26 09:28:37 +00:00
for name, items in pairs(index) do
if #items < inventories[name].size() then
return name
end
end
end
2018-07-26 14:56:42 +00:00
local function find_by_ID_meta(id, meta)
2018-07-26 09:28:37 +00:00
return find(function(item)
return
2018-07-26 14:56:42 +00:00
(not meta or item.damage == meta) and -- if metadata provided, ensure match
(not id or item.name == id) -- if internal name provided, ensure match
2018-07-26 09:28:37 +00:00
end)
end
2018-07-26 14:56:42 +00:00
local function search(query, threshold)
local threshold = threshold or 4
local results = find(function(item)
local distance = d.distance(query, item.display_name)
if distance < threshold then
return true, distance
else return false end
end)
return d.sort(results, function(x) return x.extra end) -- sort returned results by closeness to query
2018-07-26 09:28:37 +00:00
end
2018-07-26 15:15:48 +00:00
local function fetch_by_location(loc, limit)
2018-07-26 14:56:42 +00:00
local peripheral_name, slot, limit = loc.inventory, loc.slot, limit or 64
return peripheral.call(conf.buffer_internal, "pullItems", peripheral_name, slot, limit, BUFFER_OUT_SLOT)
end
2018-07-26 09:28:37 +00:00
2018-07-26 14:56:42 +00:00
local function server(command)
if command.type == "buffers" then -- Sends the external address of the buffer
return conf.buffer_external
elseif command.type == "reindex" then
updateIndex()
elseif command.type == "extract" then
local result = find_by_ID_meta(command.ID, command.meta)
2018-07-26 09:28:37 +00:00
end
end
2018-07-26 14:56:42 +00:00
update_index()
serve(server, "storage")