Polish backend system (types), fix error with exporting, write
documentation for experimental hopper backend
This commit is contained in:
parent
d367bf0f8d
commit
00c612c005
13 changed files with 562 additions and 554 deletions
13
readme.md
13
readme.md
|
|
@ -16,10 +16,11 @@
|
|||
</table>
|
||||
|
||||
## Features
|
||||
- Lua matching for inventories that are passed into AIL
|
||||
- Lua matching for inventories that are passed into AIL/Hopper
|
||||
- Import all items from certain inventories (like ender storages for all of your farms)
|
||||
- Chatbox support for withdrawing and depositing items
|
||||
- Remote access via enderstorages
|
||||
- Complete remote access via Modem (RA) and a enderstorage with a UI and everything
|
||||
|
||||
## How to use
|
||||
1. First, in your /config.lua file, add the following:
|
||||
|
|
@ -31,6 +32,10 @@ return {
|
|||
["import"] = { -- Not required, just don't set!
|
||||
"ender_storage_156" -- A inventory I want to move all items from into our storage
|
||||
},
|
||||
--- Enable the experimental hopper.lua backend.
|
||||
-- ["beta"] = {
|
||||
-- ["hopper"] = true
|
||||
-- },
|
||||
["chatbox"] = { -- Not required, just don't set!
|
||||
["prefix"] = "home",
|
||||
["players"] = {
|
||||
|
|
@ -40,6 +45,12 @@ return {
|
|||
["remote"] = { -- Access your items via modem, not required, just don't set!
|
||||
["ender_storage"] = "ender_storage_493", -- Enderstorage that will be changed (set this to owner-only and computer-chanagable!)
|
||||
["modem"] = "modem_1277", -- Modem to recieve messages
|
||||
--- Uses RA backend. Connects with a already running SiSS instance. Not required!
|
||||
-- ["connection"] = {
|
||||
-- ["port"] = 32000,
|
||||
-- ["password"] = "test123",
|
||||
-- ["connection"] = "white/white/white"
|
||||
-- },
|
||||
["remotes"] = { -- Remote access
|
||||
["red/green/green"] = {
|
||||
["port"] = 42420,
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ local function importMechanism()
|
|||
end
|
||||
end
|
||||
if #slotsToSend > 0 then
|
||||
inv.sendItemAwayMultiple(slotsToSend, perip, import_from_inv)
|
||||
inv:sendItemAwayMultiple(slotsToSend, perip, import_from_inv)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -58,7 +58,7 @@ local function importMechanism()
|
|||
end
|
||||
end
|
||||
|
||||
inv.sync()
|
||||
parallel.waitForAll(inv.run(), chatbox.run, ra.run,
|
||||
inv:sync()
|
||||
parallel.waitForAll(inv:run(), chatbox.run, ra.run,
|
||||
ui.run,
|
||||
importMechanism, inv.detectPlayerInsert)
|
||||
importMechanism, function() inv:detectPlayerInsert() end)
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ function run()
|
|||
amount = tonumber(args[3], 10)
|
||||
end
|
||||
|
||||
local moved = inv.sendItemAwayMultiple(slots, peripInventory, config.chatbox.players[user], amount)
|
||||
local moved = inv:sendItemAwayMultiple(slots, peripInventory, config.chatbox.players[user], amount)
|
||||
|
||||
chatbox.tell(user, "Moved `" .. tostring(moved) .. "` items.", BOT_NAME)
|
||||
elseif args[1] == "withdraw" then
|
||||
|
|
@ -176,7 +176,7 @@ function run()
|
|||
---@type ccTweaked.peripheral.Inventory
|
||||
local peripInventory = perip.getInventory()
|
||||
|
||||
local best = findBest(inv.listNames(), args[2])
|
||||
local best = findBest(inv:listNames(), args[2])
|
||||
|
||||
local itemName = ""
|
||||
|
||||
|
|
@ -196,7 +196,7 @@ function run()
|
|||
amount = tonumber(args[3], 10)
|
||||
end
|
||||
|
||||
local moved = inv.sendItemToSelf(itemName, peripInventory, amount, config.chatbox.players[user])
|
||||
local moved = inv:sendItemToSelf(itemName, peripInventory, amount, config.chatbox.players[user])
|
||||
|
||||
chatbox.tell(user, "Moved `" .. tostring(moved) .. "` items.", BOT_NAME)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
local config = require("../../config") ---@type Config
|
||||
local config = require("../../config")
|
||||
|
||||
if config.inventories == nil and config.remote.connection then
|
||||
return require("modules.inventory_layers.inv_ra")
|
||||
else
|
||||
if config.beta and config.beta.hopper ~= nil then
|
||||
return require("modules.inventory_layers.inv_hopper")
|
||||
if config.remote and config.remote.connection then
|
||||
return require("modules.inventory.inv_ra")()
|
||||
end
|
||||
return require("modules.inventory_layers.inv_ail")
|
||||
|
||||
if config.beta and config.beta.hopper then
|
||||
return require("modules.inventory.inv_hopper")()
|
||||
end
|
||||
|
||||
return require("modules.inventory.inv_ail")()
|
||||
|
|
|
|||
124
src/modules/inventory/base.lua
Normal file
124
src/modules/inventory/base.lua
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
---@class TurtleItemDetail
|
||||
---@field name string
|
||||
---@field count integer
|
||||
---@field nbt string|nil
|
||||
|
||||
---@alias TurtleInventory table<TurtleSlot, TurtleItemDetail|nil>
|
||||
|
||||
---@class InventoryBase
|
||||
---@field previousInventory TurtleInventory
|
||||
---@field turtleMoveAllowed boolean
|
||||
local Base = {}
|
||||
Base.__index = Base
|
||||
|
||||
---Create a new inventory layer instance
|
||||
---@generic T : InventoryBase
|
||||
---@param self T
|
||||
---@return T
|
||||
function Base.new(self)
|
||||
---@type T
|
||||
local o = setmetatable({}, self)
|
||||
|
||||
---@type TurtleInventory
|
||||
o.previousInventory = {}
|
||||
|
||||
---@type boolean
|
||||
o.turtleMoveAllowed = true
|
||||
|
||||
return o
|
||||
end
|
||||
|
||||
---Reads turtle inventory into a slot->item map
|
||||
---@return TurtleInventory
|
||||
function Base:getTurtleInventory()
|
||||
---@type TurtleInventory
|
||||
local inv = {}
|
||||
|
||||
for slot = 1, 16 do
|
||||
inv[slot] = turtle.getItemDetail(slot, false)
|
||||
end
|
||||
|
||||
return inv
|
||||
end
|
||||
|
||||
---Automatically detects items inserted by player and exports them
|
||||
function Base:detectPlayerInsert()
|
||||
if not turtle then
|
||||
return
|
||||
end
|
||||
|
||||
self.previousInventory = self:getTurtleInventory()
|
||||
|
||||
while true do
|
||||
os.pullEvent("turtle_inventory")
|
||||
|
||||
local current = self:getTurtleInventory()
|
||||
|
||||
if self.turtleMoveAllowed then
|
||||
---@type TurtleSlot[]
|
||||
local newlyAdded = {}
|
||||
|
||||
for slot = 1, 16 do
|
||||
if not self.previousInventory[slot] and current[slot] then
|
||||
table.insert(newlyAdded, slot)
|
||||
end
|
||||
end
|
||||
|
||||
if #newlyAdded > 0 then
|
||||
---@diagnostic disable-next-line: param-type-mismatch
|
||||
self:sendItemAwayMultiple(newlyAdded)
|
||||
end
|
||||
end
|
||||
|
||||
self.previousInventory = current
|
||||
end
|
||||
end
|
||||
|
||||
---Executes fn while preventing turtle moves
|
||||
---@generic R
|
||||
---@param fn fun():R
|
||||
---@return R
|
||||
function Base:_withMoveLock(fn)
|
||||
self.turtleMoveAllowed = false
|
||||
|
||||
local ok, result = pcall(fn)
|
||||
|
||||
self.turtleMoveAllowed = true
|
||||
|
||||
if ok then
|
||||
return result
|
||||
end
|
||||
|
||||
error(result)
|
||||
end
|
||||
|
||||
---@param itemName string
|
||||
---@param perip ccTweaked.peripheral.Inventory|string|nil
|
||||
---@param maxAmount integer|nil
|
||||
---@param id string|nil
|
||||
---@return integer
|
||||
function Base:sendItemToSelf(itemName, perip, maxAmount, id) end
|
||||
|
||||
---@param slots TurtleSlot[]
|
||||
---@param perip ccTweaked.peripheral.Inventory|nil
|
||||
---@param id string|nil
|
||||
---@param maxAmount integer|nil
|
||||
---@return integer
|
||||
function Base:sendItemAwayMultiple(slots, perip, id, maxAmount) end
|
||||
|
||||
---@return string[]
|
||||
function Base:listNames() end
|
||||
|
||||
---@return table<string, integer>
|
||||
function Base:listItemAmounts() end
|
||||
|
||||
---@param name string
|
||||
---@return table
|
||||
function Base:getItem(name) end
|
||||
|
||||
---@return fun()
|
||||
function Base:run() end
|
||||
|
||||
function Base:sync() end
|
||||
|
||||
return Base
|
||||
177
src/modules/inventory/inv_ail.lua
Normal file
177
src/modules/inventory/inv_ail.lua
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
---@class InventoryLayerAIL : InventoryBase
|
||||
local Base = require("modules.inventory.base")
|
||||
|
||||
---@class InventoryLayerAIL : InventoryBase
|
||||
local AIL = setmetatable({}, Base)
|
||||
AIL.__index = AIL
|
||||
|
||||
local config = require("../../config")
|
||||
|
||||
---@type fun(list:string[], boolean, table): AbstractInventory
|
||||
local abstractInventoryLib = require("lib.abstractInventoryLib")
|
||||
|
||||
---@type ccTweaked.peripheral.WiredModem
|
||||
local modem = peripheral.find("modem")
|
||||
|
||||
local turtleId = modem and modem.getNameLocal() or "self"
|
||||
|
||||
---@alias TurtleSlot integer
|
||||
|
||||
---@return InventoryLayerAIL
|
||||
function AIL:new()
|
||||
---@type InventoryLayerAIL
|
||||
local o = Base.new(self)
|
||||
|
||||
---@type AbstractInventory|nil
|
||||
o.ail = nil
|
||||
|
||||
return o
|
||||
end
|
||||
|
||||
function AIL:sync()
|
||||
print("Syncing AIL...")
|
||||
|
||||
---@type string[]
|
||||
local found = {}
|
||||
|
||||
local peripherals = peripheral.getNames()
|
||||
|
||||
for _, pattern in ipairs(config.inventories) do
|
||||
for _, name in ipairs(peripherals) do
|
||||
if string.find(name, pattern) then
|
||||
table.insert(found, name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self.ail = abstractInventoryLib(found, true, {})
|
||||
|
||||
print("AIL synced:", #found, "inventories")
|
||||
end
|
||||
|
||||
---@return fun()
|
||||
function AIL:run()
|
||||
if not self.ail then
|
||||
return function() end
|
||||
end
|
||||
|
||||
return self.ail.run
|
||||
end
|
||||
|
||||
---@param itemName string
|
||||
---@param perip ccTweaked.peripheral.Inventory|string|nil
|
||||
---@param maxAmount integer|nil
|
||||
---@param id string|nil
|
||||
---@return integer
|
||||
function AIL:sendItemToSelf(itemName, perip, maxAmount, id)
|
||||
if not self.ail then return 0 end
|
||||
|
||||
local target = perip or id or turtleId
|
||||
local remaining = maxAmount or 64
|
||||
local total = 0
|
||||
|
||||
return self:_withMoveLock(function()
|
||||
if remaining <= 0 then
|
||||
return 0
|
||||
end
|
||||
|
||||
local nbtList = self.ail.listNBT(itemName)
|
||||
if not nbtList or #nbtList == 0 then
|
||||
return 0
|
||||
end
|
||||
|
||||
---@type string|nil
|
||||
local chosen = nbtList[math.random(1, #nbtList)]
|
||||
if chosen == "NONE" then chosen = nil end
|
||||
|
||||
while remaining > 0 do
|
||||
local toSend = math.min(64, remaining)
|
||||
|
||||
self.ail.performTransfer()
|
||||
|
||||
local moved = self.ail.pushItems(
|
||||
target,
|
||||
itemName,
|
||||
toSend,
|
||||
nil,
|
||||
chosen,
|
||||
{
|
||||
allowBadTransfers = true,
|
||||
optimal = false
|
||||
}
|
||||
) or 0
|
||||
|
||||
self.ail.performTransfer()
|
||||
|
||||
if moved <= 0 then break end
|
||||
|
||||
remaining = remaining - moved
|
||||
total = total + moved
|
||||
end
|
||||
|
||||
return total
|
||||
end) or 0
|
||||
end
|
||||
|
||||
---@param slots TurtleSlot[]
|
||||
---@param perip ccTweaked.peripheral.Inventory|nil
|
||||
---@param id string|nil
|
||||
---@param maxAmount integer|nil
|
||||
---@return integer
|
||||
function AIL:sendItemAwayMultiple(slots, perip, id, maxAmount)
|
||||
if not self.ail then return 0 end
|
||||
|
||||
local src = perip or id or turtleId
|
||||
local remaining = maxAmount or math.huge
|
||||
local total = 0
|
||||
|
||||
for _, slot in ipairs(slots) do
|
||||
if remaining <= 0 then break end
|
||||
|
||||
self.ail.performTransfer()
|
||||
|
||||
local moved = self.ail.pullItems(
|
||||
src,
|
||||
slot,
|
||||
math.min(64, remaining),
|
||||
nil,
|
||||
nil,
|
||||
{
|
||||
allowBadTransfers = true,
|
||||
optimal = false
|
||||
}
|
||||
) or 0
|
||||
|
||||
self.ail.performTransfer()
|
||||
|
||||
if moved > 0 then
|
||||
remaining = remaining - moved
|
||||
total = total + moved
|
||||
end
|
||||
end
|
||||
|
||||
if total > 0 then
|
||||
os.queueEvent("update_ui")
|
||||
end
|
||||
|
||||
return total
|
||||
end
|
||||
|
||||
---@return string[]
|
||||
function AIL:listNames()
|
||||
return self.ail and self.ail.listNames() or {}
|
||||
end
|
||||
|
||||
---@return table<string, integer>
|
||||
function AIL:listItemAmounts()
|
||||
return self.ail and self.ail.listItemAmounts() or {}
|
||||
end
|
||||
|
||||
---@param name string
|
||||
function AIL:getItem(name)
|
||||
return self.ail and self.ail.getItem(name) or {}
|
||||
end
|
||||
|
||||
return function()
|
||||
return AIL:new()
|
||||
end
|
||||
100
src/modules/inventory/inv_hopper.lua
Normal file
100
src/modules/inventory/inv_hopper.lua
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
---@class InventoryLayerHopper : InventoryBase
|
||||
local Base = require("modules.inventory.base")
|
||||
|
||||
---@class InventoryLayerHopper : InventoryBase
|
||||
local Hopper = setmetatable({}, Base)
|
||||
Hopper.__index = Hopper
|
||||
|
||||
local config = require("../../config")
|
||||
|
||||
---@class HopperLib
|
||||
---@field list fun(mode:string):table<string, integer>
|
||||
---@overload fun(cmd:string):integer
|
||||
local hopper = require("lib.hopper")
|
||||
|
||||
---@return InventoryLayerHopper
|
||||
function Hopper:new()
|
||||
---@type InventoryLayerHopper
|
||||
local o = Base.new(self)
|
||||
|
||||
---@type string
|
||||
o.patterns = table.concat(config.inventories or {}, "|")
|
||||
|
||||
return o
|
||||
end
|
||||
|
||||
function Hopper:sync()
|
||||
print("syncing hopper")
|
||||
hopper("-scan-threads 32 -storage store " .. self.patterns)
|
||||
print("synced")
|
||||
end
|
||||
|
||||
---@return fun()
|
||||
function Hopper:run()
|
||||
return function()end
|
||||
end
|
||||
|
||||
---@param itemName string
|
||||
---@param perip ccTweaked.peripheral.Inventory|string|nil
|
||||
---@param maxAmount integer|nil
|
||||
---@param id string|nil
|
||||
---@return integer
|
||||
function Hopper:sendItemToSelf(itemName, perip, maxAmount, id)
|
||||
return self:_withMoveLock(function()
|
||||
return hopper(
|
||||
"store self "
|
||||
.. itemName
|
||||
.. " -transfer-limit "
|
||||
.. tostring(maxAmount or 64)
|
||||
)
|
||||
end) or 0
|
||||
end
|
||||
|
||||
---@param slots TurtleSlot[]
|
||||
---@param perip ccTweaked.peripheral.Inventory|nil
|
||||
---@param id string|nil
|
||||
---@param maxAmount integer|nil
|
||||
---@return integer
|
||||
function Hopper:sendItemAwayMultiple(slots, perip, id, maxAmount)
|
||||
local hopslots = ""
|
||||
|
||||
for _, slot in ipairs(slots) do
|
||||
hopslots = hopslots .. " -from-slot " .. tostring(slot)
|
||||
end
|
||||
|
||||
return hopper(
|
||||
"self store -from-limit-max "
|
||||
.. tostring(maxAmount or 64)
|
||||
.. hopslots
|
||||
.. " -per-slot"
|
||||
) or 0
|
||||
end
|
||||
|
||||
---@return table<string, integer>
|
||||
function Hopper:listItemAmounts()
|
||||
return hopper.list("store") or {}
|
||||
end
|
||||
|
||||
---@return string[]
|
||||
function Hopper:listNames()
|
||||
---@type string[]
|
||||
local out = {}
|
||||
|
||||
for name in pairs(self:listItemAmounts()) do
|
||||
table.insert(out, name)
|
||||
end
|
||||
|
||||
return out
|
||||
end
|
||||
|
||||
---@param name string
|
||||
---@return table
|
||||
function Hopper:getItem(name)
|
||||
-- Hopper cannot query single items precisely
|
||||
return {}
|
||||
end
|
||||
|
||||
---@return InventoryLayerHopper
|
||||
return function()
|
||||
return Hopper:new()
|
||||
end
|
||||
125
src/modules/inventory/inv_ra.lua
Normal file
125
src/modules/inventory/inv_ra.lua
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
---@class InventoryLayerRA : InventoryBase
|
||||
local Base = require("modules.inventory.base")
|
||||
|
||||
---@class InventoryLayerRA : InventoryBase
|
||||
local RA = setmetatable({}, Base)
|
||||
RA.__index = RA
|
||||
|
||||
local config = require("../../config")
|
||||
|
||||
---@alias TurtleSlot integer
|
||||
|
||||
local ra = require("tiny_ra_library")
|
||||
|
||||
---@class EnderStoragePeripheral : ccTweaked.peripheral.Inventory
|
||||
---@field list fun():table<TurtleSlot, table>
|
||||
---@field pushItems fun(to:string|table, fromSlot:integer, amount?:integer, toSlot?:integer):integer
|
||||
---@field pullItems fun(from:string|table, fromSlot:integer, amount?:integer, toSlot?:integer):integer
|
||||
|
||||
---@return InventoryLayerRA
|
||||
function RA:new()
|
||||
---@type InventoryLayerRA
|
||||
local o = Base.new(self)
|
||||
|
||||
---@type ccTweaked.peripheral.WiredModem|nil
|
||||
o.modem = peripheral.wrap(config.remote.modem)
|
||||
|
||||
---@type EnderStoragePeripheral|nil
|
||||
o.ender = peripheral.wrap(config.remote.ender_storage)
|
||||
|
||||
---@type string
|
||||
o.turtleId = peripheral.find("modem").getNameLocal()
|
||||
|
||||
return o
|
||||
end
|
||||
|
||||
function RA:sync()
|
||||
print("RA already synced")
|
||||
end
|
||||
|
||||
---@return fun()
|
||||
function RA:run()
|
||||
return function()
|
||||
ra.init(
|
||||
self.modem,
|
||||
config.remote.connection.port,
|
||||
config.remote.connection.password
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
---@param itemName string
|
||||
---@param perip ccTweaked.peripheral.Inventory|string|nil
|
||||
---@param maxAmount integer|nil
|
||||
---@param id string|nil
|
||||
---@return integer
|
||||
function RA:sendItemToSelf(itemName, perip, maxAmount, id)
|
||||
if not self.ender then return 0 end
|
||||
|
||||
return self:_withMoveLock(function()
|
||||
ra.withdraw(itemName, maxAmount, true)
|
||||
|
||||
---@type string
|
||||
local target =
|
||||
(type(perip) == "string" and perip)
|
||||
or id
|
||||
or self.turtleId
|
||||
|
||||
local total = 0
|
||||
|
||||
for slot in pairs(self.ender.list()) do
|
||||
local moved = self.ender.pushItems(target, slot) or 0
|
||||
total = total + moved
|
||||
end
|
||||
|
||||
return total
|
||||
end) or 0
|
||||
end
|
||||
|
||||
---@param slots TurtleSlot[]
|
||||
---@param perip ccTweaked.peripheral.Inventory|nil
|
||||
---@param id string|nil
|
||||
---@param maxAmount integer|nil
|
||||
---@return integer
|
||||
function RA:sendItemAwayMultiple(slots, perip, id, maxAmount)
|
||||
if not self.ender then return 0 end
|
||||
|
||||
local srcId = id or self.turtleId
|
||||
local remaining = maxAmount or math.huge
|
||||
local total = 0
|
||||
|
||||
for _, slot in ipairs(slots) do
|
||||
if remaining <= 0 then break end
|
||||
|
||||
local pulled =
|
||||
self.ender.pullItems(srcId, slot, math.min(64, remaining)) or 0
|
||||
|
||||
remaining = remaining - pulled
|
||||
total = total + pulled
|
||||
end
|
||||
|
||||
ra.depositBySlots(self.ender.list(), nil, false)
|
||||
|
||||
return total
|
||||
end
|
||||
|
||||
---@return string[]
|
||||
function RA:listNames()
|
||||
return ra.listNames()
|
||||
end
|
||||
|
||||
---@return table<string, integer>
|
||||
function RA:listItemAmounts()
|
||||
return ra.listItemAmounts()
|
||||
end
|
||||
|
||||
---@param name string
|
||||
---@return table
|
||||
function RA:getItem(name)
|
||||
return ra.getItem(name)
|
||||
end
|
||||
|
||||
---@return InventoryLayerRA
|
||||
return function()
|
||||
return RA:new()
|
||||
end
|
||||
|
|
@ -1,217 +0,0 @@
|
|||
local previousInventory = {}
|
||||
---@type ccTweaked.peripheral.WiredModem
|
||||
local modem = peripheral.find("modem");
|
||||
local turtleId = modem.getNameLocal()
|
||||
local turtleMoveAllowed = true
|
||||
local config = require("../../config") ---@type Config
|
||||
|
||||
local abstractInventoryLib = require("lib.abstractInventoryLib")
|
||||
|
||||
local peripherals = peripheral.getNames();
|
||||
|
||||
---@type AbstractInventory
|
||||
local ail = nil
|
||||
|
||||
local function sync()
|
||||
print("Syncing..")
|
||||
---@type string[]
|
||||
local foundInventories = {}
|
||||
|
||||
for _, invPattern in ipairs(config.inventories) do
|
||||
for _, inv in ipairs(peripherals) do
|
||||
if string.find(inv, invPattern) then
|
||||
table.insert(foundInventories, inv)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ail = abstractInventoryLib(foundInventories, true, {})
|
||||
|
||||
print("Synced.");
|
||||
end
|
||||
---@param itemName string
|
||||
---@param perip ccTweaked.peripheral.Inventory|string|nil
|
||||
---@param maxAmount number|nil
|
||||
---@param id string|nil
|
||||
local function sendItemToSelf(itemName, perip, maxAmount, id)
|
||||
if perip == nil then
|
||||
perip = turtleId
|
||||
end
|
||||
turtleMoveAllowed = false
|
||||
|
||||
local remaining = maxAmount or 64
|
||||
local total = 0
|
||||
|
||||
if remaining <= 0 then
|
||||
turtleMoveAllowed = true
|
||||
return
|
||||
end
|
||||
|
||||
if #ail.listNBT(itemName) ~= 0 then
|
||||
local nbtList = ail.listNBT(itemName)
|
||||
local chosenNBT = nil
|
||||
if nbtList and #nbtList > 0 then
|
||||
chosenNBT = nbtList[math.random(1, #nbtList)]
|
||||
end
|
||||
|
||||
if chosenNBT == "NONE" then
|
||||
chosenNBT = nil
|
||||
end
|
||||
|
||||
while remaining > 0 do
|
||||
local toSend = math.min(64, remaining)
|
||||
|
||||
local ok, moved = pcall(function()
|
||||
ail.performTransfer()
|
||||
|
||||
local amount = ail.pushItems(perip, itemName, toSend, nil, chosenNBT, {
|
||||
["allowBadTransfers"] = true,
|
||||
["optimal"] = false
|
||||
})
|
||||
|
||||
ail.performTransfer()
|
||||
|
||||
return amount
|
||||
end)
|
||||
total = total + moved
|
||||
if ok and moved and moved > 0 then
|
||||
remaining = remaining - moved
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
turtleMoveAllowed = true
|
||||
|
||||
return total
|
||||
end
|
||||
|
||||
---@param slots ccTweaked.turtle.turtleSlot[]
|
||||
---@param perip ccTweaked.peripheral.Inventory|nil
|
||||
---@param id string|nil
|
||||
---@param maxAmount number|nil
|
||||
local function sendItemAwayMultiple(slots, perip, id, maxAmount)
|
||||
if perip == nil then
|
||||
perip = turtle
|
||||
end
|
||||
local srcId = id or turtleId
|
||||
|
||||
if srcId == nil then return end
|
||||
|
||||
local itemsInSlots = {}
|
||||
for _, slot in ipairs(slots) do
|
||||
local item = perip.getItemDetail(slot)
|
||||
if item then
|
||||
itemsInSlots[slot] = item
|
||||
end
|
||||
end
|
||||
|
||||
local totalMoved = 0
|
||||
local remaining = maxAmount or math.huge
|
||||
|
||||
if remaining <= 0 then
|
||||
return 0
|
||||
end
|
||||
|
||||
for _, slot in ipairs(slots) do
|
||||
if remaining <= 0 then break end
|
||||
|
||||
local toSend = math.min(64, remaining)
|
||||
|
||||
local ok, pulled = pcall(function()
|
||||
ail.performTransfer()
|
||||
|
||||
local moved = ail.pullItems(srcId, slot, toSend, nil, nil, {
|
||||
["allowBadTransfers"] = true,
|
||||
["optimal"] = false
|
||||
})
|
||||
|
||||
ail.performTransfer()
|
||||
return moved
|
||||
end)
|
||||
|
||||
if ok and pulled and pulled > 0 then
|
||||
totalMoved = totalMoved + pulled
|
||||
remaining = remaining - pulled
|
||||
end
|
||||
end
|
||||
|
||||
local numItems = 0
|
||||
for _, _ in pairs(itemsInSlots) do
|
||||
numItems = numItems + 1
|
||||
end
|
||||
|
||||
if numItems > 0 then
|
||||
os.queueEvent("update_ui")
|
||||
end
|
||||
|
||||
return totalMoved
|
||||
end
|
||||
|
||||
local function getTurtleInventory()
|
||||
local inventory = {}
|
||||
for slot = 1, 16 do
|
||||
local item = turtle.getItemDetail(slot, false)
|
||||
inventory[slot] = item
|
||||
end
|
||||
return inventory
|
||||
end
|
||||
|
||||
local function detectPlayerInsert()
|
||||
if turtle then
|
||||
previousInventory = getTurtleInventory()
|
||||
|
||||
while true do
|
||||
os.pullEvent("turtle_inventory")
|
||||
|
||||
local currentInventory = getTurtleInventory()
|
||||
|
||||
if turtleMoveAllowed then
|
||||
local newlyAddedSlots = {}
|
||||
|
||||
for slot = 1, 16 do
|
||||
local prev = previousInventory[slot]
|
||||
local curr = currentInventory[slot]
|
||||
|
||||
if not prev and curr then
|
||||
table.insert(newlyAddedSlots, slot)
|
||||
end
|
||||
end
|
||||
|
||||
if #newlyAddedSlots > 0 then
|
||||
sendItemAwayMultiple(newlyAddedSlots)
|
||||
end
|
||||
end
|
||||
|
||||
previousInventory = currentInventory
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function run()
|
||||
return ail.run
|
||||
end
|
||||
|
||||
local function listNames()
|
||||
return ail.listNames()
|
||||
end
|
||||
|
||||
local function listItemAmounts()
|
||||
return ail.listItemAmounts()
|
||||
end
|
||||
|
||||
local function getItem(z)
|
||||
return ail.getItem(z)
|
||||
end
|
||||
|
||||
return {
|
||||
detectPlayerInsert = detectPlayerInsert,
|
||||
sendItemAwayMultiple = sendItemAwayMultiple,
|
||||
sendItemToSelf = sendItemToSelf,
|
||||
getTurtleInventory = getTurtleInventory,
|
||||
listItemAmounts = listItemAmounts,
|
||||
listNames = listNames,
|
||||
getItem = getItem,
|
||||
sync = sync,
|
||||
run = run
|
||||
}
|
||||
|
|
@ -1,142 +0,0 @@
|
|||
local previousInventory = {}
|
||||
local turtleMoveAllowed = true
|
||||
local config = require("../../config") ---@type Config
|
||||
|
||||
local hopper = require("lib.hopper")
|
||||
|
||||
local hopperInventories = table.concat(config.inventories, "|");
|
||||
|
||||
local function sync()
|
||||
hopper("-storage store " .. hopperInventories)
|
||||
print("Synced.");
|
||||
end
|
||||
|
||||
---@param itemName string
|
||||
---@param perip ccTweaked.peripheral.Inventory|string|nil
|
||||
---@param maxAmount number|nil
|
||||
---@param id string|nil
|
||||
local function sendItemToSelf(itemName, perip, maxAmount, id)
|
||||
if perip == nil then
|
||||
perip = "self"
|
||||
end
|
||||
local rid = ""
|
||||
if id == nil then
|
||||
if type(perip) ~= "string" then
|
||||
return
|
||||
else
|
||||
rid = perip
|
||||
end
|
||||
else
|
||||
rid = id;
|
||||
end
|
||||
turtleMoveAllowed = false
|
||||
|
||||
local moved = hopper("store " .. rid .. " " .. itemName .. " -transfer-limit " .. tostring(maxAmount or 64))
|
||||
turtleMoveAllowed = true
|
||||
|
||||
return moved
|
||||
end
|
||||
|
||||
---@param slots ccTweaked.turtle.turtleSlot[]
|
||||
---@param perip ccTweaked.peripheral.Inventory|nil
|
||||
---@param id string|nil
|
||||
---@param maxAmount number|nil
|
||||
local function sendItemAwayMultiple(slots, perip, id, maxAmount)
|
||||
if perip == nil then
|
||||
perip = turtle
|
||||
end
|
||||
local srcId = id or "self"
|
||||
|
||||
if srcId == nil then return end
|
||||
|
||||
local hopslots = ""
|
||||
|
||||
for _, slot in pairs(slots) do
|
||||
hopslots = hopslots .. " -from-slot " .. tostring(slot)
|
||||
end
|
||||
|
||||
return hopper(srcId .. " store -from-limit-max " .. (maxAmount or 64) .. hopslots .. " -per-slot")
|
||||
end
|
||||
|
||||
local function getTurtleInventory()
|
||||
local inventory = {}
|
||||
for slot = 1, 16 do
|
||||
local item = turtle.getItemDetail(slot, false)
|
||||
inventory[slot] = item
|
||||
end
|
||||
return inventory
|
||||
end
|
||||
|
||||
local function detectPlayerInsert()
|
||||
if turtle then
|
||||
previousInventory = getTurtleInventory()
|
||||
|
||||
while true do
|
||||
os.pullEvent("turtle_inventory")
|
||||
|
||||
local currentInventory = getTurtleInventory()
|
||||
|
||||
if turtleMoveAllowed then
|
||||
local newlyAddedSlots = {}
|
||||
|
||||
for slot = 1, 16 do
|
||||
local prev = previousInventory[slot]
|
||||
local curr = currentInventory[slot]
|
||||
|
||||
if not prev and curr then
|
||||
table.insert(newlyAddedSlots, slot)
|
||||
end
|
||||
end
|
||||
|
||||
if #newlyAddedSlots > 0 then
|
||||
sendItemAwayMultiple(newlyAddedSlots)
|
||||
end
|
||||
end
|
||||
|
||||
previousInventory = currentInventory
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function run()
|
||||
return function()
|
||||
-- this needs to do something
|
||||
print("inv.run ran")
|
||||
while true do
|
||||
sleep(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function listItemAmounts()
|
||||
return hopper.list("store")
|
||||
end
|
||||
|
||||
|
||||
local function listNames()
|
||||
local aa = listItemAmounts()
|
||||
local names = {}
|
||||
|
||||
for name, _ in pairs(aa) do
|
||||
table.insert(names, name)
|
||||
end
|
||||
|
||||
return names
|
||||
end
|
||||
|
||||
local function getItem(z)
|
||||
return {} -- can't implement this well enough sadly, just expect every item exists
|
||||
end
|
||||
|
||||
return {
|
||||
detectPlayerInsert = detectPlayerInsert,
|
||||
sendItemAwayMultiple = sendItemAwayMultiple,
|
||||
sendItemToSelf = sendItemToSelf,
|
||||
getTurtleInventory = getTurtleInventory,
|
||||
listItemAmounts = listItemAmounts,
|
||||
listNames = listNames,
|
||||
getItem = getItem,
|
||||
sync = sync,
|
||||
run = run
|
||||
}
|
||||
|
|
@ -1,171 +0,0 @@
|
|||
local previousInventory = {}
|
||||
---@type ccTweaked.peripheral.WiredModem
|
||||
local modem = peripheral.find("modem");
|
||||
local turtleId = modem.getNameLocal()
|
||||
local turtleMoveAllowed = true
|
||||
local config = require("../../config") ---@type Config
|
||||
|
||||
local ra = require("tiny_ra_library")
|
||||
|
||||
local function sync()
|
||||
print("inv_ra does not require syncing (it is already synced!)")
|
||||
end
|
||||
|
||||
---@param itemName string
|
||||
---@param perip ccTweaked.peripheral.Inventory|string|nil
|
||||
---@param maxAmount number|nil
|
||||
local function sendItemToSelf(itemName, perip, maxAmount)
|
||||
local enderstorage = peripheral.wrap(config.remote.ender_storage);
|
||||
if enderstorage == nil then return end
|
||||
turtleMoveAllowed = false
|
||||
|
||||
local id = turtleId;
|
||||
|
||||
ra.withdraw(itemName, maxAmount, true) -- make sure to wait so we can push to turtle once waited
|
||||
|
||||
if type(perip) == "string" then
|
||||
id = perip
|
||||
end
|
||||
|
||||
for key, _ in pairs(enderstorage.list()) do
|
||||
enderstorage.pushItems(id, key)
|
||||
end
|
||||
|
||||
sleep(0.2)
|
||||
turtleMoveAllowed = true
|
||||
end
|
||||
|
||||
---@param slots ccTweaked.turtle.turtleSlot[]
|
||||
---@param perip ccTweaked.peripheral.Inventory|nil
|
||||
---@param id string|nil
|
||||
---@param maxAmount number|nil
|
||||
local function sendItemAwayMultiple(slots, perip, id, maxAmount)
|
||||
if perip == nil then
|
||||
perip = turtle
|
||||
end
|
||||
local srcId = id or turtleId
|
||||
|
||||
if srcId == nil then return end
|
||||
|
||||
local itemsInSlots = {}
|
||||
for _, slot in ipairs(slots) do
|
||||
local item = perip.getItemDetail(slot)
|
||||
if item then
|
||||
itemsInSlots[slot] = item
|
||||
end
|
||||
end
|
||||
|
||||
local enderstorage = peripheral.wrap(config.remote.ender_storage);
|
||||
if enderstorage == nil then return end
|
||||
local totalMoved = 0
|
||||
local remaining = maxAmount or math.huge
|
||||
|
||||
if remaining <= 0 then
|
||||
return 0
|
||||
end
|
||||
|
||||
for _, slot in ipairs(slots) do
|
||||
if remaining <= 0 then break end
|
||||
|
||||
local toSend = math.min(64, remaining)
|
||||
|
||||
local ok, pulled = pcall(function()
|
||||
return enderstorage.pullItems(srcId, slot, toSend)
|
||||
end)
|
||||
|
||||
if ok and pulled and pulled > 0 then
|
||||
totalMoved = totalMoved + pulled
|
||||
remaining = remaining - pulled
|
||||
end
|
||||
end
|
||||
|
||||
local numItems = 0
|
||||
for _, _ in pairs(itemsInSlots) do
|
||||
numItems = numItems + 1
|
||||
end
|
||||
|
||||
if numItems > 0 then
|
||||
os.queueEvent("update_ui")
|
||||
end
|
||||
|
||||
local keys = {}
|
||||
|
||||
for key, _ in pairs(enderstorage.list()) do
|
||||
if key ~= nil then
|
||||
table.insert(keys, key)
|
||||
end
|
||||
end
|
||||
|
||||
ra.depositBySlots(keys, nil, false)
|
||||
return totalMoved
|
||||
end
|
||||
|
||||
local function getTurtleInventory()
|
||||
local inventory = {}
|
||||
for slot = 1, 16 do
|
||||
local item = turtle.getItemDetail(slot, false)
|
||||
inventory[slot] = item
|
||||
end
|
||||
return inventory
|
||||
end
|
||||
|
||||
local function detectPlayerInsert()
|
||||
if turtle then
|
||||
previousInventory = getTurtleInventory()
|
||||
|
||||
while true do
|
||||
os.pullEvent("turtle_inventory")
|
||||
|
||||
local currentInventory = getTurtleInventory()
|
||||
|
||||
if turtleMoveAllowed then
|
||||
local newlyAddedSlots = {}
|
||||
|
||||
for slot = 1, 16 do
|
||||
local prev = previousInventory[slot]
|
||||
local curr = currentInventory[slot]
|
||||
|
||||
if not prev and curr then
|
||||
table.insert(newlyAddedSlots, slot)
|
||||
end
|
||||
end
|
||||
|
||||
if #newlyAddedSlots > 0 then
|
||||
sendItemAwayMultiple(newlyAddedSlots)
|
||||
end
|
||||
end
|
||||
|
||||
previousInventory = currentInventory
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function run()
|
||||
return function()
|
||||
ra.init(peripheral.wrap(config.remote.modem), config.remote.connection.port, config.remote.connection.password)
|
||||
end
|
||||
end
|
||||
|
||||
local function listNames()
|
||||
return ra.listNames()
|
||||
end
|
||||
|
||||
local function listItemAmounts()
|
||||
return ra.listItemAmounts()
|
||||
end
|
||||
|
||||
local function getItem(z)
|
||||
return ra.getItem(z)
|
||||
end
|
||||
|
||||
return {
|
||||
detectPlayerInsert = detectPlayerInsert,
|
||||
sendItemAwayMultiple = sendItemAwayMultiple,
|
||||
sendItemToSelf = sendItemToSelf,
|
||||
getTurtleInventory = getTurtleInventory,
|
||||
listItemAmounts = listItemAmounts,
|
||||
listNames = listNames,
|
||||
getItem = getItem,
|
||||
sync = sync,
|
||||
run = run
|
||||
}
|
||||
|
|
@ -76,7 +76,7 @@ local function run()
|
|||
)
|
||||
if json.type == "withdraw" then
|
||||
local ok, err = pcall(function()
|
||||
inv.sendItemToSelf(
|
||||
inv:sendItemToSelf(
|
||||
json.data.itemName,
|
||||
config.remote.ender_storage,
|
||||
json.data.amount
|
||||
|
|
@ -112,7 +112,7 @@ local function run()
|
|||
sendResponse(modem, remote.port, hashed, json.id, ok, nil, err)
|
||||
elseif json.type == "list_names" then
|
||||
local ok, result = pcall(function()
|
||||
return inv.listNames()
|
||||
return inv:listNames()
|
||||
end)
|
||||
sendResponse(
|
||||
modem,
|
||||
|
|
@ -125,7 +125,7 @@ local function run()
|
|||
)
|
||||
elseif json.type == "list_item_amounts" then
|
||||
local ok, result = pcall(function()
|
||||
return inv.listItemAmounts()
|
||||
return inv:listItemAmounts()
|
||||
end)
|
||||
|
||||
sendResponse(
|
||||
|
|
@ -139,7 +139,7 @@ local function run()
|
|||
)
|
||||
elseif json.type == "get_item" then
|
||||
local ok, result = pcall(function()
|
||||
return inv.getItem(json.data.index)
|
||||
return inv:getItem(json.data.index)
|
||||
end)
|
||||
|
||||
sendResponse(
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ local function run()
|
|||
local win = term.current();
|
||||
local w, h = term.getSize()
|
||||
|
||||
local items = inv.listItemAmounts()
|
||||
local items = inv:listItemAmounts()
|
||||
local x = 0
|
||||
|
||||
local function getFiltered()
|
||||
|
|
@ -21,7 +21,7 @@ local function run()
|
|||
|
||||
x = x + 1
|
||||
if x % 3 == 0 then
|
||||
items = inv.listItemAmounts()
|
||||
items = inv:listItemAmounts()
|
||||
end
|
||||
|
||||
for name, count in pairs(items) do
|
||||
|
|
@ -53,8 +53,8 @@ local function run()
|
|||
|
||||
if key == keys.enter then
|
||||
local z = option:match("^(%S+)")
|
||||
if inv.getItem(z) then
|
||||
inv.sendItemToSelf(z)
|
||||
if inv:getItem(z) then
|
||||
inv:sendItemToSelf(z)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue