Polish RA, make it usable.

This commit is contained in:
Soph :3 2026-01-29 18:59:52 +02:00
parent 262c0b5408
commit 6825a05778
14 changed files with 771 additions and 289 deletions

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
u2c.py
push.sh
version
.env

View file

@ -9,7 +9,8 @@ g(
g(
g(
'Sa=XbandSb=XbxWSc=XlshiftSd=unpackSe=2^32SYf(g,h)Si=g/2^hSj=i%1Ui-j+j*eVSYk(l,m)Sn=l/2^mUn-n%1VSo={0x6a09e667Tbb67ae85T3c6ef372Ta54ff53aT510e527fT9b05688cT1f83d9abT5be0cd19}Sp={0x428a2f98T71374491Tb5c0fbcfTe9b5dba5T3956c25bT59f111f1T923f82a4Tab1c5ed5Td807aa98T12835b01T243185beT550c7dc3T72be5d74T80deb1feT9bdc06a7Tc19bf174Te49b69c1Tefbe4786T0fc19dc6T240ca1ccT2de92c6fT4a7484aaT5cb0a9dcT76f988daT983e5152Ta831c66dTb00327c8Tbf597fc7Tc6e00bf3Td5a79147T06ca6351T14292967T27b70a85T2e1b2138T4d2c6dfcT53380d13T650a7354T766a0abbT81c2c92eT92722c85Ta2bfe8a1Ta81a664bTc24b8b70Tc76c51a3Td192e819Td6990624Tf40e3585T106aa070T19a4c116T1e376c08T2748774cT34b0bcb5T391c0cb3T4ed8aa4aT5b9cca4fT682e6ff3T748f82eeT78a5636fT84c87814T8cc70208T90befffaTa4506cebTbef9a3f7Tc67178f2}SYq(r,q)if e-1-r[1]<q then r[2]=r[2]+1;r[1]=q-(e-1-r[1])-1 else r[1]=r[1]+qVUrVSYs(t)Su=#t;t[#t+1]=0x80;while#t%64~=56Zt[#t+1]=0VSv=q({0,0},u*8)fWw=2,1,-1Zt[#t+1]=a(k(a(v[w]TFF000000),24)TFF)t[#t+1]=a(k(a(v[w]TFF0000),16)TFF)t[#t+1]=a(k(a(v[w]TFF00),8)TFF)t[#t+1]=a(v[w]TFF)VUtVSYx(y,w)Uc(y[w]W0,24)+c(y[w+1]W0,16)+c(y[w+2]W0,8)+(y[w+3]W0)VSYz(t,w,A)SB={}fWC=1,16ZB[C]=x(t,w+(C-1)*4)VfWC=17,64ZSD=B[C-15]SE=b(b(f(B[C-15],7),f(B[C-15],18)),k(B[C-15],3))SF=b(b(f(B[C-2],17),f(B[C-2],19)),k(B[C-2],10))B[C]=(B[C-16]+E+B[C-7]+F)%eVSG,h,H,I,J,j,K,L=d(A)fWC=1,64ZSM=b(b(f(J,6),f(J,11)),f(J,25))SN=b(a(J,j),a(Xbnot(J),K))SO=(L+M+N+p[C]+B[C])%eSP=b(b(f(G,2),f(G,13)),f(G,22))SQ=b(b(a(G,h),a(G,H)),a(h,H))SR=(P+Q)%e;L,K,j,J,I,H,h,G=K,j,J,(I+O)%e,H,h,G,(O+R)%eVA[1]=(A[1]+G)%e;A[2]=(A[2]+h)%e;A[3]=(A[3]+H)%e;A[4]=(A[4]+I)%e;A[5]=(A[5]+J)%e;A[6]=(A[6]+j)%e;A[7]=(A[7]+K)%e;A[8]=(A[8]+L)%eUAVUY(t)t=t W""t=type(t)=="string"and{t:byte(1,-1)}Wt;t=s(t)SA={d(o)}fWw=1,#t,64ZA=z(t,w,A)VU("%08x"):rep(8):format(d(A))V',
"S", " local "), "T", ",0x"), "U", " return "), "V", " end "), "W", "or "), "X", "bit32."), "Y", "function "), "Z",
"S", " local "), "T", ",0x"), "U", " return "), "V", " end "), "W", "or "), "X", "bit32."), "Y",
"function "), "Z",
" do "))()
local aead = require("lib.plc.aead_chacha_poly")
@ -151,8 +152,10 @@ local VERSION = "\1"
local KDF_ID = "\1"
local AAD = "SiSS RA rev1|chacha20poly1305"
local function u32be(n) return string.char(bit32.band(bit32.rshift(n, 24), 255), bit32.band(bit32.rshift(n, 16), 255),
bit32.band(bit32.rshift(n, 8), 255), bit32.band(n, 255)) end
local function u32be(n)
return string.char(bit32.band(bit32.rshift(n, 24), 255), bit32.band(bit32.rshift(n, 16), 255),
bit32.band(bit32.rshift(n, 8), 255), bit32.band(n, 255))
end
local function u16be(n) return string.char(bit32.band(bit32.rshift(n, 8), 255), bit32.band(n, 255)) end
local function pack_params(iter)
return u32be(iter) .. u16be(32)

80
src/lib/encryption.lua Normal file
View file

@ -0,0 +1,80 @@
local g = string.gsub
sha256 = loadstring(g(
g(
g(
g(
g(
g(
g(
g(
'Sa=XbandSb=XbxWSc=XlshiftSd=unpackSe=2^32SYf(g,h)Si=g/2^hSj=i%1Ui-j+j*eVSYk(l,m)Sn=l/2^mUn-n%1VSo={0x6a09e667Tbb67ae85T3c6ef372Ta54ff53aT510e527fT9b05688cT1f83d9abT5be0cd19}Sp={0x428a2f98T71374491Tb5c0fbcfTe9b5dba5T3956c25bT59f111f1T923f82a4Tab1c5ed5Td807aa98T12835b01T243185beT550c7dc3T72be5d74T80deb1feT9bdc06a7Tc19bf174Te49b69c1Tefbe4786T0fc19dc6T240ca1ccT2de92c6fT4a7484aaT5cb0a9dcT76f988daT983e5152Ta831c66dTb00327c8Tbf597fc7Tc6e00bf3Td5a79147T06ca6351T14292967T27b70a85T2e1b2138T4d2c6dfcT53380d13T650a7354T766a0abbT81c2c92eT92722c85Ta2bfe8a1Ta81a664bTc24b8b70Tc76c51a3Td192e819Td6990624Tf40e3585T106aa070T19a4c116T1e376c08T2748774cT34b0bcb5T391c0cb3T4ed8aa4aT5b9cca4fT682e6ff3T748f82eeT78a5636fT84c87814T8cc70208T90befffaTa4506cebTbef9a3f7Tc67178f2}SYq(r,q)if e-1-r[1]<q then r[2]=r[2]+1;r[1]=q-(e-1-r[1])-1 else r[1]=r[1]+qVUrVSYs(t)Su=#t;t[#t+1]=0x80;while#t%64~=56Zt[#t+1]=0VSv=q({0,0},u*8)fWw=2,1,-1Zt[#t+1]=a(k(a(v[w]TFF000000),24)TFF)t[#t+1]=a(k(a(v[w]TFF0000),16)TFF)t[#t+1]=a(k(a(v[w]TFF00),8)TFF)t[#t+1]=a(v[w]TFF)VUtVSYx(y,w)Uc(y[w]W0,24)+c(y[w+1]W0,16)+c(y[w+2]W0,8)+(y[w+3]W0)VSYz(t,w,A)SB={}fWC=1,16ZB[C]=x(t,w+(C-1)*4)VfWC=17,64ZSD=B[C-15]SE=b(b(f(B[C-15],7),f(B[C-15],18)),k(B[C-15],3))SF=b(b(f(B[C-2],17),f(B[C-2],19)),k(B[C-2],10))B[C]=(B[C-16]+E+B[C-7]+F)%eVSG,h,H,I,J,j,K,L=d(A)fWC=1,64ZSM=b(b(f(J,6),f(J,11)),f(J,25))SN=b(a(J,j),a(Xbnot(J),K))SO=(L+M+N+p[C]+B[C])%eSP=b(b(f(G,2),f(G,13)),f(G,22))SQ=b(b(a(G,h),a(G,H)),a(h,H))SR=(P+Q)%e;L,K,j,J,I,H,h,G=K,j,J,(I+O)%e,H,h,G,(O+R)%eVA[1]=(A[1]+G)%e;A[2]=(A[2]+h)%e;A[3]=(A[3]+H)%e;A[4]=(A[4]+I)%e;A[5]=(A[5]+J)%e;A[6]=(A[6]+j)%e;A[7]=(A[7]+K)%e;A[8]=(A[8]+L)%eUAVUY(t)t=t W""t=type(t)=="string"and{t:byte(1,-1)}Wt;t=s(t)SA={d(o)}fWw=1,#t,64ZA=z(t,w,A)VU("%08x"):rep(8):format(d(A))V',
"S", " local "), "T", ",0x"), "U", " return "), "V", " end "), "W", "or "), "X", "bit32."), "Y",
"function "), "Z",
" do "))()
local chacha20 = require("lib.chacha20")
local function hex_to_bytes(hex)
return (hex:gsub("..", function(cc)
return string.char(tonumber(cc, 16))
end))
end
-- hash a human string into a 32-byte key
---@param key string
---@return string -- 32 bytes
local function hashKey(key)
return hex_to_bytes(sha256(key)) -- MUST return raw bytes
end
-- generate secure random bytes
local function random_bytes(n)
local t = {}
for i = 1, n do
t[i] = string.char(math.random(0, 255))
end
return table.concat(t)
end
---@param hashed_key string -- 32 bytes
---@param plaintext string
---@return string -- nonce || ciphertext
local function encrypt(hashed_key, plaintext)
assert(#hashed_key == 32, "key must be 32 bytes")
local nonce = random_bytes(24) -- XChaCha20 nonce
local counter = 0
local ciphertext = chacha20.xchacha20_encrypt(
hashed_key,
counter,
nonce,
plaintext
)
-- prepend nonce so it can be used for decryption
return nonce .. ciphertext
end
---@param hashed_key string
---@param data string -- nonce || ciphertext
---@return string plaintext
local function decrypt(hashed_key, data)
local nonce = data:sub(1, 24)
local ciphertext = data:sub(25)
local counter = 0
return chacha20.xchacha20_encrypt(
hashed_key,
counter,
nonce,
ciphertext
)
end
return {
hashKey = hashKey,
encrypt = encrypt,
decrypt = decrypt
}

View file

@ -2,28 +2,38 @@
---@field port number
---@field password string
---@class ConectionRemote : InnerRemote
---@field remote string
---@class Remote
---@field ender_storage string
---@field modem string
---@field remotes table<string, InnerRemote>
---@field remotes table<string, InnerRemote>|nil
---@field connection InnerRemote|nil
---@class Chatbox
---@field players table<string, string>
---@field prefix string|nil
---@class Config
---@field inventories string[]
---@field inventories string[]|nil
---@field import string[]|nil
---@field chatbox Chatbox|nil
---@field remote Remote
---@field remote Remote|nil
local inv = require("modules.inv")
local config = require("../config") ---@type Config
local inv;
if config.inventories == nil and config.remote.connection then
inv = require("modules.inv_ra")
else
inv = require("modules.inv")
end
local ui = require("modules.ui")
local chatbox = require("modules.chatbox")
local ra = require("modules.ra")
local config = require("../config") ---@type Config
local function importMechanism()
if config.import == nil then
@ -55,4 +65,6 @@ local function importMechanism()
end
inv.sync()
parallel.waitForAll(inv.getAIL().run, chatbox.run, ra.run, ui.run, importMechanism, inv.detectPlayerInsert)
parallel.waitForAll(inv.run(), chatbox.run, ra.run,
ui.run,
importMechanism, inv.detectPlayerInsert)

View file

@ -1,6 +1,11 @@
local config = require("../../config") ---@type Config
local inv = require("modules.inv")
local inv;
if config.inventories == nil and config.remote.connection then
inv = require("modules.inv_ra")
else
inv = require("modules.inv")
end
local function levDist(s, t)
local n = #s
local m = #t
@ -176,7 +181,7 @@ function run()
---@type ccTweaked.peripheral.Inventory
local peripInventory = perip.getInventory()
local best = findBest(inv.getAIL().listNames(), args[2])
local best = findBest(inv.listNames(), args[2])
local itemName = ""

View file

@ -25,16 +25,7 @@ local function sync()
end
end
ail = abstractInventoryLib(foundInventories, true, {
--[[cache = true,
optimal = true,
unoptimal = true,
api = true,
defrag = true,
redirect = function (e)
print(e)
end,]]
})
ail = abstractInventoryLib(foundInventories, true, {})
print("Synced.");
end
@ -166,6 +157,7 @@ local function getTurtleInventory()
end
local function detectPlayerInsert()
if turtle then
previousInventory = getTurtleInventory()
while true do
@ -193,17 +185,32 @@ local function detectPlayerInsert()
previousInventory = currentInventory
end
end
local function getAIL()
return ail
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,
getAIL = getAIL,
run = run
}

171
src/modules/inv_ra.lua Normal file
View file

@ -0,0 +1,171 @@
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
}

View file

@ -1,6 +1,12 @@
local inv = require("modules.inv");
local config = require("../../config") ---@type Config
local hmac = require("lib.hmac-pbkdf2-aead")
if config.inventories == nil and config.remote.connection then
inv = require("modules.inv_ra")
else
inv = require("modules.inv")
end
local encryption = require("lib.encryption")
---@class RemoteAccess
---@field type string
---@field data RemoteAccessData
@ -10,13 +16,34 @@ local hmac = require("lib.hmac-pbkdf2-aead")
---@field amount number|nil
---@field slots number[]|nil
local function sendResponse(modem, port, hashedPassword, id, ok, data, err)
modem.transmit(
port,
port,
encryption.encrypt(hashedPassword,
textutils.serialiseJSON({
type = "response",
id = id,
ok = ok,
data = data,
error = err
})
)
)
end
local function run()
if config.remote == nil then return end
if config.remote == nil or config.remote.remotes == nil then return end
local modem = peripheral.wrap(config.remote.modem)
if not modem then return end
for _, remote in pairs(config.remote.remotes) do
local remotes = config.remote.remotes or { config.remote.connection }
for _, remote in pairs(remotes) do
if not modem.isOpen(remote.port) then
modem.open(remote.port)
end
@ -28,10 +55,11 @@ local function run()
while true do
local _, _, channel, _, message, _ = os.pullEvent("modem_message")
for color, remote in pairs(config.remote.remotes) do
for color, remote in pairs(remotes) do
if remote.port == channel then
local hashed = encryption.hashKey(remote.password)
local err, data = pcall(function()
return hmac.decrypt_with_password(remote.password, message)
return encryption.decrypt(hashed, message)
end)
if not data then return end
@ -51,8 +79,17 @@ local function run()
colors[parts[3]]
)
if json.type == "withdraw" then
inv.sendItemToSelf(json.data.itemName, config.remote.ender_storage, json.data.amount)
local ok, err = pcall(function()
inv.sendItemToSelf(
json.data.itemName,
config.remote.ender_storage,
json.data.amount
)
end)
sendResponse(modem, remote.port, hashed, json.id, ok, nil, err)
elseif json.type == "deposit" then
local ok, err = pcall(function()
if json.data.itemName then
local move = {}
for s, i in pairs(ender_storage.list()) do
@ -60,14 +97,64 @@ local function run()
table.insert(move, s)
end
end
inv.sendItemAwayMultiple(move, ender_storage, config.remote.ender_storage, json.data.amount)
inv.sendItemAwayMultiple(
move,
ender_storage,
config.remote.ender_storage,
json.data.amount
)
elseif json.data.slots then
if type(json.data.slots) ~= 'table' then
return
inv.sendItemAwayMultiple(
json.data.slots,
ender_storage,
config.remote.ender_storage,
json.data.amount
)
end
end)
inv.sendItemAwayMultiple(json.data.slots, ender_storage, config.remote.ender_storage, json.data.amount)
end
sendResponse(modem, remote.port, hashed, json.id, ok, nil, err)
elseif json.type == "list_names" then
local ok, result = pcall(function()
return inv.listNames()
end)
sendResponse(
modem,
remote.port,
hashed,
json.id,
ok,
ok and result or nil,
not ok and result or nil
)
elseif json.type == "list_item_amounts" then
local ok, result = pcall(function()
return inv.listItemAmounts()
end)
sendResponse(
modem,
remote.port,
hashed,
json.id,
ok,
ok and result or nil,
not ok and result or nil
)
elseif json.type == "get_item" then
local ok, result = pcall(function()
return inv.getItem(json.data.index)
end)
sendResponse(
modem,
remote.port,
hashed,
json.id,
ok,
ok and result or nil,
not ok and result or nil
)
end
end
end

View file

@ -1,4 +1,11 @@
local inv = require("modules.inv");
local config = require("../../config") ---@type Config
local inv;
if config.inventories == nil and config.remote.connection then
inv = require("modules.inv_ra")
else
inv = require("modules.inv")
end
local PrimeUI = require("lib.primeui").PrimeUI;
local function is_beta(ver)
if ver:match("^[0-9a-f]+$") and #ver >= 8 then
@ -12,9 +19,18 @@ local function run()
local win = term.current();
local w, h = term.getSize()
local items = inv.listItemAmounts()
local x = 0
local function getFiltered()
local filtered = {}
for name, count in pairs(inv.getAIL().listItemAmounts()) do
x = x + 1
if x % 3 == 0 then
items = inv.listItemAmounts()
end
for name, count in pairs(items) do
if search == "" or string.find(name:lower(), search:lower(), 1, true) then
table.insert(filtered, { name = name, count = count })
end
@ -40,8 +56,7 @@ local function run()
end,
function(option)
local z = option:match("^(%S+)")
if inv.getAIL().getItem(z) then
if inv.getItem(z) then
inv.sendItemToSelf(z)
end
end

198
src/tiny_ra_library.lua Normal file
View file

@ -0,0 +1,198 @@
local encryption = require("lib.encryption")
---@type string
local password
---@type number
local port
---@type string
local hashedPassword
---@type ccTweaked.peripheral.Modem
local modem
local function sendRequest(reqType, data, wait)
if wait == nil then
wait = true
end
local id = tostring(math.random(1, 1e9))
modem.transmit(
port,
port,
encryption.encrypt(hashedPassword,
textutils.serialiseJSON({
type = reqType,
id = id,
data = data
})
)
)
if wait then
-- wait for response
while true do
local event, side, senderChannel, replyChannel, message = os.pullEvent("modem_message")
local ok, decrypted = pcall(encryption.decrypt, hashedPassword, message)
if not ok then goto continue end
local resp = textutils.unserialiseJSON(decrypted)
if resp and resp.type == "response" and resp.id == id then
return resp.ok, resp.data or resp.error
end
::continue::
end
end
end
local function init(modemI, portI, passwordI)
port = portI
password = passwordI
hashedPassword = encryption.hashKey(passwordI)
modem = modemI
modem.open(port)
end
---@param wait boolean|nil
local function listNames(wait)
if not port or not modem or not password then
error("tiny_ra_library: init was never ran")
end
if wait == nil then
wait = true
end
local ok, data = sendRequest("list_names", nil, wait)
if wait then
if not ok then
error("Failed to list names: " .. tostring(data))
end
return data
end
end
---@param itemName string
---@param count number|nil
---@param wait boolean|nil
local function withdraw(itemName, count, wait)
if not port or not modem or not password then
error("tiny_ra_library: init was never ran")
end
if wait == nil then
wait = true
end
local ok, data = sendRequest("withdraw", {
itemName = itemName,
count = count
}, wait)
if wait then
if not ok then
error("Failed to withdraw: " .. tostring(data))
end
return data
end
end
---@param slots number[]
---@param count number|nil
---@param wait boolean|nil
local function depositBySlots(slots, count, wait)
if not port or not modem or not password then
error("tiny_ra_library: init was never ran")
end
if wait == nil then
wait = true
end
local data = {
slots = slots
}
if count then
data["count"] = count
end
local ok, response = sendRequest("deposit", data, wait)
if wait then
if not ok then
error("Failed to deposit by slots: " .. tostring(response))
end
return response
end
end
---@param wait boolean|nil
local function listItemAmounts(wait)
if wait == nil then
wait = true
end
local ok, response = sendRequest("list_item_amounts", nil, wait)
if wait then
if not ok then
error("Failed to list names: " .. tostring(response))
end
return response
end
end
---@param itemName string
---@param wait boolean|nil
local function getItem(itemName, wait)
if wait == nil then
wait = true
end
local ok, data = sendRequest("get_item", { index = itemName }, wait)
if wait then
if not ok then
error("Failed to list names: " .. tostring(data))
end
return data
end
end
---@param itemName string
---@param count number|nil
---@param wait boolean|nil
local function depositByItemName(itemName, count, wait)
if not port or not modem or not password then
error("tiny_ra_library: init was never ran")
end
local data = {
itemName = itemName
}
if count then
data["count"] = count
end
local ok, response = sendRequest("deposit", data, wait)
if wait then
if not ok then
error("Failed to list names: " .. tostring(response))
end
return response
end
end
return {
init = init,
listItemAmounts = listItemAmounts,
getItem = getItem,
listNames = listNames,
withdraw = withdraw,
depositByItemName = depositByItemName,
depositBySlots = depositBySlots
}

File diff suppressed because one or more lines are too long