package management
This commit is contained in:
254
core/apis/meAdapter.lua
Normal file
254
core/apis/meAdapter.lua
Normal file
@@ -0,0 +1,254 @@
|
||||
local class = require('class')
|
||||
local itemDB = require('itemDB')
|
||||
local Peripheral = require('peripheral')
|
||||
local Util = require('util')
|
||||
|
||||
local os = _G.os
|
||||
|
||||
local convertNames = {
|
||||
name = 'id',
|
||||
damage = 'dmg',
|
||||
maxCount = 'max_size',
|
||||
count = 'qty',
|
||||
displayName = 'display_name',
|
||||
maxDamage = 'max_dmg',
|
||||
nbtHash = 'nbt_hash',
|
||||
}
|
||||
|
||||
-- Strip off color prefix
|
||||
local function safeString(text)
|
||||
|
||||
local val = text:byte(1)
|
||||
|
||||
if val < 32 or val > 128 then
|
||||
|
||||
local newText = {}
|
||||
for i = 4, #text do
|
||||
val = text:byte(i)
|
||||
newText[i - 3] = (val > 31 and val < 127) and val or 63
|
||||
end
|
||||
return string.char(unpack(newText))
|
||||
end
|
||||
|
||||
return text
|
||||
end
|
||||
|
||||
local function convertItem(item)
|
||||
for k,v in pairs(convertNames) do
|
||||
item[k] = item[v]
|
||||
item[v] = nil
|
||||
end
|
||||
item.displayName = safeString(item.displayName)
|
||||
end
|
||||
|
||||
local MEAdapter = class()
|
||||
|
||||
function MEAdapter:init(args)
|
||||
local defaults = {
|
||||
items = { },
|
||||
name = 'ME',
|
||||
jobList = { },
|
||||
}
|
||||
Util.merge(self, defaults)
|
||||
Util.merge(self, args)
|
||||
|
||||
local chest
|
||||
|
||||
if not self.side then
|
||||
chest = Peripheral.getByMethod('getAvailableItems')
|
||||
else
|
||||
chest = Peripheral.getBySide(self.side)
|
||||
if chest and not chest.getAvailableItems then
|
||||
chest = nil
|
||||
end
|
||||
end
|
||||
|
||||
if chest then
|
||||
Util.merge(self, chest)
|
||||
end
|
||||
end
|
||||
|
||||
function MEAdapter:isValid()
|
||||
return self.getAvailableItems and self.getAvailableItems()
|
||||
end
|
||||
|
||||
function MEAdapter:refresh()
|
||||
self.items = nil
|
||||
local hasItems, failed
|
||||
|
||||
local s, m = pcall(function()
|
||||
self.items = self.getAvailableItems('all')
|
||||
for _,v in pairs(self.items) do
|
||||
Util.merge(v, v.item)
|
||||
convertItem(v)
|
||||
|
||||
-- if power has been interrupted, the list will still be returned
|
||||
-- but all items will have a 0 quantity
|
||||
-- ensure that the list is valid
|
||||
if not hasItems then
|
||||
hasItems = v.count > 0
|
||||
end
|
||||
|
||||
if not v.fingerprint then
|
||||
failed = true
|
||||
break
|
||||
end
|
||||
|
||||
if not itemDB:get(v) then
|
||||
itemDB:add(v, v)
|
||||
end
|
||||
end
|
||||
end)
|
||||
itemDB:flush()
|
||||
|
||||
if not s and m then
|
||||
_debug(m)
|
||||
end
|
||||
|
||||
if s and not failed and hasItems and self.items and not Util.empty(self.items) then
|
||||
return self.items
|
||||
end
|
||||
self.items = nil
|
||||
end
|
||||
|
||||
function MEAdapter:listItems()
|
||||
self:refresh()
|
||||
return self.items
|
||||
end
|
||||
|
||||
function MEAdapter:getItemInfo(item)
|
||||
for _,i in pairs(self.items) do
|
||||
if item.name == i.name and
|
||||
item.damage == i.damage and
|
||||
item.nbtHash == i.nbtHash then
|
||||
return i
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function MEAdapter:isCPUAvailable()
|
||||
local cpus = self.getCraftingCPUs() or { }
|
||||
local available = false
|
||||
|
||||
for cpu,v in pairs(cpus) do
|
||||
if not v.busy then
|
||||
available = true
|
||||
elseif not self.jobList[cpu] then -- something else is crafting something (don't know what)
|
||||
return false -- return false since we are in an unknown state
|
||||
end
|
||||
end
|
||||
return available
|
||||
end
|
||||
|
||||
function MEAdapter:craft(item, count)
|
||||
if not self:isCPUAvailable() then
|
||||
return false
|
||||
end
|
||||
|
||||
self:refresh()
|
||||
|
||||
item = self:getItemInfo(item)
|
||||
if item and item.is_craftable then
|
||||
|
||||
local cpus = self.getCraftingCPUs() or { }
|
||||
for cpu,v in pairs(cpus) do
|
||||
if not v.busy then
|
||||
self.requestCrafting({
|
||||
id = item.name,
|
||||
dmg = item.damage,
|
||||
nbt_hash = item.nbtHash,
|
||||
},
|
||||
count or 1,
|
||||
v.name -- CPUs must be named ! use anvil
|
||||
)
|
||||
|
||||
os.sleep(0) -- needed ?
|
||||
cpus = self.getCraftingCPUs() or { }
|
||||
|
||||
if cpus[cpu].busy then
|
||||
self.jobList[cpu] = {
|
||||
name = item.name,
|
||||
damage = item.damage,
|
||||
nbtHash = item.nbtHash,
|
||||
count = count,
|
||||
}
|
||||
return true
|
||||
end
|
||||
break -- only need to try the first available cpu
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
function MEAdapter:getJobList()
|
||||
local cpus = self.getCraftingCPUs() or { }
|
||||
for cpu,v in pairs(cpus) do
|
||||
if not v.busy then
|
||||
self.jobList[cpu] = nil
|
||||
end
|
||||
end
|
||||
|
||||
return self.jobList
|
||||
end
|
||||
|
||||
function MEAdapter:isCrafting(item)
|
||||
for _,v in pairs(self:getJobList()) do
|
||||
if v.name == item.name and
|
||||
v.damage == item.damage and
|
||||
v.nbtHash == item.nbtHash then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function MEAdapter:craftItems(items)
|
||||
local cpus = self.getCraftingCPUs() or { }
|
||||
local count = 0
|
||||
|
||||
for _,cpu in pairs(cpus) do
|
||||
if cpu.busy then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
for _,item in pairs(items) do
|
||||
if count >= #cpus then
|
||||
break
|
||||
end
|
||||
if not self:isCrafting(item) then
|
||||
if self:craft(item, item.count) then
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function MEAdapter:provide(item, qty, slot, direction)
|
||||
return pcall(function()
|
||||
for _,stack in pairs(self.getAvailableItems('all')) do
|
||||
if stack.item.id == item.name and
|
||||
(not item.damage or stack.item.dmg == item.damage) and
|
||||
(not item.nbtHash or stack.item.nbt_hash == item.nbtHash) then
|
||||
local amount = math.min(qty, stack.item.qty)
|
||||
if amount > 0 then
|
||||
self.exportItem(stack.item, direction or self.direction, amount, slot)
|
||||
end
|
||||
qty = qty - amount
|
||||
if qty <= 0 then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function MEAdapter:insert(slot, qty, toSlot)
|
||||
local s, m = pcall(self.pullItem, self.direction, slot, qty, toSlot)
|
||||
if not s and m then
|
||||
os.sleep(1)
|
||||
pcall(self.pullItem, self.direction, slot, qty, toSlot)
|
||||
end
|
||||
end
|
||||
|
||||
return MEAdapter
|
||||
Reference in New Issue
Block a user