Reformat + add prefix selection for config

This commit is contained in:
Soph :3 2025-11-14 22:43:49 +02:00
parent 88f4173c8e
commit 262c0b5408
13 changed files with 1191 additions and 1141 deletions

View file

@ -21,6 +21,52 @@
- Chatbox support for withdrawing and depositing items - Chatbox support for withdrawing and depositing items
- Remote access via enderstorages - Remote access via enderstorages
## How to use
1. First, in your /config.lua file, add the following:
```lua
return {
["inventories"] = { -- REQUIRED!! Please set at least one inventory pattern.
".*barrel.*" -- Lua patterns to match all barrels
},
["import"] = { -- Not required, just don't set!
"ender_storage_156" -- A inventory I want to move all items from into our storage
},
["chatbox"] = { -- Not required, just don't set!
["prefix"] = "home",
["players"] = {
["hartbreix"] = "manipulator_42" -- Chatbox support
}
},
["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
["remotes"] = { -- Remote access
["red/green/green"] = {
["port"] = 42420,
["password"] = "test123" -- Required!
}
}
}
}
```
2. Run the following command:
```
wget run https://git.sad.ovh/sophie/storage-solution/raw/branch/main/src/.main-installer.lua
```
This will install storage-solution to /storage-solution.
To make it start every time you turn on the computer, add
```
shell.run("wget run https://git.sad.ovh/sophie/storage-solution/raw/branch/main/src/.main-installer.lua")
```
to startup.lua
### [EXTRA!]
You can also run `wget run https://files.sad.ovh/public/storage-solution/.beta-installer.lua`, which is quite unstable. You may experience issues while running the beta version, but also new juicy features :)
## RA ## RA
SiSS has a remote access system that allows you to access your items via modem. SiSS has a remote access system that allows you to access your items via modem.
To use it, first set up your config.lua correctly. After that you need to implement the tiny_ra_library into your program. To use it, first set up your config.lua correctly. After that you need to implement the tiny_ra_library into your program.
@ -57,44 +103,3 @@ sleep(2)
print("deposits 16 items from the first slot") print("deposits 16 items from the first slot")
ra.depositBySlots({1}, 16) ra.depositBySlots({1}, 16)
``` ```
## How to use
1. First, in your /config.lua file, add the following:
```lua
return {
["inventories"] = { -- REQUIRED!! Please set at least one inventory pattern.
".*barrel.*" -- Lua patterns to match all barrels
},
["import"] = { -- Not required, just don't set!
"ender_storage_156" -- A inventory I want to move all items from into our storage
},
["chatbox"] = { -- Not required, just don't set!
["hartbreix"] = "manipulator_42" -- Chatbox support
},
["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
["remotes"] = { -- Remote access
["red/green/green"] = {
["port"] = 42420,
["password"] = "test123" -- Required!
}
}
}
}
```
2. Run the following command:
```
wget run https://git.sad.ovh/sophie/storage-solution/raw/branch/main/src/.main-installer.lua
```
This will install storage-solution to /storage-solution.
To make it start every time you turn on the computer, add
```
shell.run("wget run https://git.sad.ovh/sophie/storage-solution/raw/branch/main/src/.main-installer.lua")
```
to startup.lua
### [EXTRA!]
You can also run `wget run https://files.sad.ovh/public/storage-solution/.beta-installer.lua`, which is quite unstable. You may experience issues while running the beta version, but also new juicy features :)

View file

@ -40,7 +40,8 @@ local function traverse_and_download(folder_data, prefix)
for _, dir in ipairs(folder_data.dirs or {}) do for _, dir in ipairs(folder_data.dirs or {}) do
fs.makeDir(download_root .. "/" .. prefix .. dir.href) fs.makeDir(download_root .. "/" .. prefix .. dir.href)
local new_prefix = (prefix ~= "" and (prefix .. "/") or "") .. dir.href local new_prefix = (prefix ~= "" and (prefix .. "/") or "") .. dir.href
local subdir_url = base_url .. "/" .. new_prefix .. "?ls" local response = http.get(subdir_url) local subdir_url = base_url .. "/" .. new_prefix .. "?ls"
local response = http.get(subdir_url)
if response then if response then
local body = response.readAll() local body = response.readAll()
if not body then return end if not body then return end
@ -59,7 +60,8 @@ if fs.exists(download_root) then
local currentVersion = http.get(base_url .. "/version").readAll(); local currentVersion = http.get(base_url .. "/version").readAll();
if previousVersion == currentVersion then if previousVersion == currentVersion then
print("Previous version " .. previousVersion .. " is already installed, we're on " .. currentVersion .. " aswell, so skipping installation.") print("Previous version " ..
previousVersion .. " is already installed, we're on " .. currentVersion .. " aswell, so skipping installation.")
shell.run("storage-solution/main.lua") shell.run("storage-solution/main.lua")
return return
else else

View file

@ -67,11 +67,11 @@ if fs.exists(download_root) then
local local_hash = f.readAll() local local_hash = f.readAll()
f.close() f.close()
if local_hash == remote_hash then if local_hash == remote_hash then
print("Already up to date (commit " .. remote_hash:sub(1,7) .. ").") print("Already up to date (commit " .. remote_hash:sub(1, 7) .. ").")
shell.run(download_root .. "/main.lua") shell.run(download_root .. "/main.lua")
return return
else else
print("Outdated (" .. local_hash:sub(1,7) .. " -> " .. remote_hash:sub(1,7) .. "), reinstalling...") print("Outdated (" .. local_hash:sub(1, 7) .. " -> " .. remote_hash:sub(1, 7) .. "), reinstalling...")
fs.delete(download_root) fs.delete(download_root)
end end
else else
@ -89,5 +89,5 @@ local f = fs.open(download_root .. "/version", "w")
f.write(remote_hash) f.write(remote_hash)
f.close() f.close()
print("Installed Sophie's Storage Solution (commit " .. remote_hash:sub(1,7) .. ")") print("Installed Sophie's Storage Solution (commit " .. remote_hash:sub(1, 7) .. ")")
shell.run(download_root .. "/main.lua") shell.run(download_root .. "/main.lua")

View file

@ -1,81 +1,94 @@
local g = string.gsub 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 "))() 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 aead = require("lib.plc.aead_chacha_poly") local aead = require("lib.plc.aead_chacha_poly")
local function tobytes(s) return {s:byte(1, #s)} end local function tobytes(s) return { s:byte(1, #s) } end
local function frombytes(t) return string.char(table.unpack(t)) end local function frombytes(t) return string.char(table.unpack(t)) end
local b64abc = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_' local b64abc = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'
local function b64u_encode(bin) local function b64u_encode(bin)
local t, n, out = tobytes(bin), #bin, {} local t, n, out = tobytes(bin), #bin, {}
local i=1 local i = 1
while i<=n do while i <= n do
local a=t[i] or 0; local b=t[i+1] or 0; local c=t[i+2] or 0 local a = t[i] or 0; local b = t[i + 1] or 0; local c = t[i + 2] or 0
local triple = a*65536 + b*256 + c local triple = a * 65536 + b * 256 + c
out[#out+1]=b64abc:sub(bit32.band(bit32.rshift(triple,18), 63)+1,bit32.band(bit32.rshift(triple,18), 63)+1) out[#out + 1] = b64abc:sub(bit32.band(bit32.rshift(triple, 18), 63) + 1, bit32.band(bit32.rshift(triple, 18), 63) + 1)
out[#out+1]=b64abc:sub(bit32.band(bit32.rshift(triple,12), 63)+1,bit32.band(bit32.rshift(triple,12), 63)+1) out[#out + 1] = b64abc:sub(bit32.band(bit32.rshift(triple, 12), 63) + 1, bit32.band(bit32.rshift(triple, 12), 63) + 1)
out[#out+1]= i+1<=n and b64abc:sub(bit32.band(bit32.rshift(triple,6), 63)+1,bit32.band(bit32.rshift(triple,6), 63)+1) or '' out[#out + 1] = i + 1 <= n and
out[#out+1]= i+2<=n and b64abc:sub(bit32.band(bit32.rshift(triple,0), 63)+1,bit32.band(bit32.rshift(triple,0), 63)+1) or '' b64abc:sub(bit32.band(bit32.rshift(triple, 6), 63) + 1, bit32.band(bit32.rshift(triple, 6), 63) + 1) or ''
i=i+3 out[#out + 1] = i + 2 <= n and
b64abc:sub(bit32.band(bit32.rshift(triple, 0), 63) + 1, bit32.band(bit32.rshift(triple, 0), 63) + 1) or ''
i = i + 3
end end
return table.concat(out) return table.concat(out)
end end
local function b64u_decode(txt) local function b64u_decode(txt)
local map = {} local map = {}
for i=1,#b64abc do map[b64abc:sub(i,i)] = i-1 end for i = 1, #b64abc do map[b64abc:sub(i, i)] = i - 1 end
local out = {} local out = {}
local i=1 local i = 1
while i<=#txt do while i <= #txt do
local a = map[txt:sub(i,i)]; i=i+1 local a = map[txt:sub(i, i)]; i = i + 1
local b = map[txt:sub(i,i)]; i=i+1 local b = map[txt:sub(i, i)]; i = i + 1
local c = map[txt:sub(i,i)]; i=i+1 local c = map[txt:sub(i, i)]; i = i + 1
local d = map[txt:sub(i,i)]; i=i+1 local d = map[txt:sub(i, i)]; i = i + 1
if a==nil or b==nil then break end if a == nil or b == nil then break end
local triple = bit32.bor(bit32.lshift(a,18) , bit32.lshift(b,12) , bit32.lshift(c or 0,6) , (d or 0)) local triple = bit32.bor(bit32.lshift(a, 18), bit32.lshift(b, 12), bit32.lshift(c or 0, 6), (d or 0))
out[#out+1] = string.char(bit32.band(bit32.rshift(triple,16) , 255)) out[#out + 1] = string.char(bit32.band(bit32.rshift(triple, 16), 255))
if c ~= nil then out[#out+1] = string.char(bit32.band(bit32.rshift(triple,8) , 255)) end if c ~= nil then out[#out + 1] = string.char(bit32.band(bit32.rshift(triple, 8), 255)) end
if d ~= nil then out[#out+1] = string.char(bit32.band(triple , 255)) end if d ~= nil then out[#out + 1] = string.char(bit32.band(triple, 255)) end
end end
return table.concat(out) return table.concat(out)
end end
local function hmac_sha256(key, msg) local function hmac_sha256(key, msg)
local block = 64 local block = 64
if #key > block then key = (sha256(key):gsub('..', function(h) return string.char(tonumber(h,16)) end)) end if #key > block then key = (sha256(key):gsub('..', function(h) return string.char(tonumber(h, 16)) end)) end
if #key < block then key = key .. string.rep("\0", block - #key) end if #key < block then key = key .. string.rep("\0", block - #key) end
local o_key_pad = key:gsub('.', function(c) return string.char(bit32.bxor(string.byte(c), 0x5c)) end) local o_key_pad = key:gsub('.', function(c) return string.char(bit32.bxor(string.byte(c), 0x5c)) end)
local i_key_pad = key:gsub('.', function(c) return string.char(bit32.bxor(string.byte(c) , 0x36)) end) local i_key_pad = key:gsub('.', function(c) return string.char(bit32.bxor(string.byte(c), 0x36)) end)
local inner = sha256(i_key_pad .. msg) local inner = sha256(i_key_pad .. msg)
inner = inner:gsub('..', function(h) return string.char(tonumber(h,16)) end) inner = inner:gsub('..', function(h) return string.char(tonumber(h, 16)) end)
local mac = sha256(o_key_pad .. inner) local mac = sha256(o_key_pad .. inner)
return mac:gsub('..', function(h) return string.char(tonumber(h,16)) end) return mac:gsub('..', function(h) return string.char(tonumber(h, 16)) end)
end end
local function int_be(n) -- 32-bit BE local function int_be(n) -- 32-bit BE
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)) 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 end
local function pbkdf2_sha256(password, salt, iterations, dkLen) local function pbkdf2_sha256(password, salt, iterations, dkLen)
local hLen = 32 local hLen = 32
local l = math.ceil(dkLen / hLen) local l = math.ceil(dkLen / hLen)
local r = dkLen - (l-1)*hLen local r = dkLen - (l - 1) * hLen
local dk = {} local dk = {}
for i=1,l do for i = 1, l do
local U = hmac_sha256(password, salt .. int_be(i)) local U = hmac_sha256(password, salt .. int_be(i))
local T = {U:byte(1,hLen)} local T = { U:byte(1, hLen) }
for itr=2,iterations do for itr = 2, iterations do
U = hmac_sha256(password, U) U = hmac_sha256(password, U)
local Ub = {U:byte(1,hLen)} local Ub = { U:byte(1, hLen) }
for j=1,hLen do T[j] = bit32.bxor(T[j], Ub[j]) end for j = 1, hLen do T[j] = bit32.bxor(T[j], Ub[j]) end
if itr % 500 == 0 then sleep(0) end if itr % 500 == 0 then sleep(0) end
end end
if i<l then if i < l then
dk[#dk+1] = string.char(table.unpack(T)) dk[#dk + 1] = string.char(table.unpack(T))
else else
dk[#dk+1] = string.char(table.unpack(T, 1, r)) dk[#dk + 1] = string.char(table.unpack(T, 1, r))
end end
end end
return table.concat(dk) return table.concat(dk)
@ -83,20 +96,20 @@ end
-- HMAC-DRBG -- HMAC-DRBG
local SEED_PATH = "siss_drg_seed.bin" local SEED_PATH = "siss_drg_seed.bin"
local DRBG = {K = string.rep("\0",32), V = string.rep("\1",32), inited=false} local DRBG = { K = string.rep("\0", 32), V = string.rep("\1", 32), inited = false }
local function drbg_update(provided_data) local function drbg_update(provided_data)
DRBG.K = hmac_sha256(DRBG.K, DRBG.V .. "\0" .. (provided_data or "")) DRBG.K = hmac_sha256(DRBG.K, DRBG.V .. "\0" .. (provided_data or ""))
DRBG.V = hmac_sha256(DRBG.K, DRBG.V) DRBG.V = hmac_sha256(DRBG.K, DRBG.V)
if provided_data and #provided_data>0 then if provided_data and #provided_data > 0 then
DRBG.K = hmac_sha256(DRBG.K, DRBG.V .. "\1" .. provided_data) DRBG.K = hmac_sha256(DRBG.K, DRBG.V .. "\1" .. provided_data)
DRBG.V = hmac_sha256(DRBG.K, DRBG.V) DRBG.V = hmac_sha256(DRBG.K, DRBG.V)
end end
end end
local function drbg_init(seed) local function drbg_init(seed)
DRBG.K = string.rep("\0",32) DRBG.K = string.rep("\0", 32)
DRBG.V = string.rep("\1",32) DRBG.V = string.rep("\1", 32)
drbg_update(seed) drbg_update(seed)
DRBG.inited = true DRBG.inited = true
end end
@ -106,27 +119,27 @@ local function drbg_bytes(n)
local out = {} local out = {}
while #table.concat(out) < n do while #table.concat(out) < n do
DRBG.V = hmac_sha256(DRBG.K, DRBG.V) DRBG.V = hmac_sha256(DRBG.K, DRBG.V)
out[#out+1] = DRBG.V out[#out + 1] = DRBG.V
end end
drbg_update("") drbg_update("")
local buf = table.concat(out) local buf = table.concat(out)
return buf:sub(1,n) return buf:sub(1, n)
end end
local function seed_entropy(extra_bytes) local function seed_entropy(extra_bytes)
local accum = {} local accum = {}
if fs.exists(SEED_PATH) then if fs.exists(SEED_PATH) then
local f = fs.open(SEED_PATH, "rb"); accum[#accum+1]=f.readAll(); f.close() local f = fs.open(SEED_PATH, "rb"); accum[#accum + 1] = f.readAll(); f.close()
local seed = sha256(table.concat(accum)):gsub('..', function(h) return string.char(tonumber(h,16)) end) local seed = sha256(table.concat(accum)):gsub('..', function(h) return string.char(tonumber(h, 16)) end)
drbg_init(seed) drbg_init(seed)
else else
term.write("Move around / mash keys then press Enter 4 times to seed…\n") term.write("Move around / mash keys then press Enter 4 times to seed…\n")
for i=1,4 do for i = 1, 4 do
local t1 = os.clock(); read(); local t2 = os.clock() local t1 = os.clock(); read(); local t2 = os.clock()
accum[#accum+1] = int_be(math.floor((t2 - t1)*1e9)) .. tostring({}):sub(8) accum[#accum + 1] = int_be(math.floor((t2 - t1) * 1e9)) .. tostring({}):sub(8)
end end
if extra_bytes and #extra_bytes>0 then accum[#accum+1]=extra_bytes end if extra_bytes and #extra_bytes > 0 then accum[#accum + 1] = extra_bytes end
local seed = sha256(table.concat(accum)):gsub('..', function(h) return string.char(tonumber(h,16)) end) local seed = sha256(table.concat(accum)):gsub('..', function(h) return string.char(tonumber(h, 16)) end)
drbg_init(seed) drbg_init(seed)
local f = fs.open(SEED_PATH, "wb") local f = fs.open(SEED_PATH, "wb")
f.write(drbg_bytes(48)) f.write(drbg_bytes(48))
@ -138,15 +151,16 @@ local VERSION = "\1"
local KDF_ID = "\1" local KDF_ID = "\1"
local AAD = "SiSS RA rev1|chacha20poly1305" 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),
local function u16be(n) return string.char(bit32.band(bit32.rshift(n,8),255), bit32.band(n,255)) end 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) local function pack_params(iter)
return u32be(iter) .. u16be(32) return u32be(iter) .. u16be(32)
end end
local function unpack_params(s) local function unpack_params(s)
local i1,i2,i3,i4, d1,d2 = s:byte(1,6) local i1, i2, i3, i4, d1, d2 = s:byte(1, 6)
local iters = (bit32.bor(bit32.lshift(i1,24),bit32.lshift(i2,16),bit32.lshift(i3,8),i4)) local iters = (bit32.bor(bit32.lshift(i1, 24), bit32.lshift(i2, 16), bit32.lshift(i3, 8), i4))
local dklen = (bit32.bor(bit32.lshift(d1,8),d2)) local dklen = (bit32.bor(bit32.lshift(d1, 8), d2))
return iters, dklen return iters, dklen
end end
@ -170,24 +184,24 @@ local function encrypt_with_password(password, plaintext)
local ciphertext, tag = aead.encrypt(AAD, key, iv, constant, plaintext) local ciphertext, tag = aead.encrypt(AAD, key, iv, constant, plaintext)
local params = pack_params(iters) local params = pack_params(iters)
local blob = table.concat{ VERSION, KDF_ID, params, salt, nonce12, ciphertext, tag } local blob = table.concat { VERSION, KDF_ID, params, salt, nonce12, ciphertext, tag }
return b64u_encode(blob) return b64u_encode(blob)
end end
local function decrypt_with_password(password, blob) local function decrypt_with_password(password, blob)
local bin = b64u_decode(blob) local bin = b64u_decode(blob)
if #bin < 1+1+6+16+12+16 then return nil, "ciphertext too short" end if #bin < 1 + 1 + 6 + 16 + 12 + 16 then return nil, "ciphertext too short" end
local pos = 1 local pos = 1
local ver = bin:sub(pos,pos); pos=pos+1 local ver = bin:sub(pos, pos); pos = pos + 1
if ver ~= VERSION then return nil, "version mismatch" end if ver ~= VERSION then return nil, "version mismatch" end
local kdfid = bin:sub(pos,pos); pos=pos+1 local kdfid = bin:sub(pos, pos); pos = pos + 1
if kdfid ~= KDF_ID then return nil, "kdf mismatch" end if kdfid ~= KDF_ID then return nil, "kdf mismatch" end
local params = bin:sub(pos,pos+5); pos=pos+6 local params = bin:sub(pos, pos + 5); pos = pos + 6
local iters, dklen = unpack_params(params); if dklen ~= 32 then return nil, "bad dkLen" end local iters, dklen = unpack_params(params); if dklen ~= 32 then return nil, "bad dkLen" end
local salt = bin:sub(pos,pos+15); pos=pos+16 local salt = bin:sub(pos, pos + 15); pos = pos + 16
-- read the same 12-byte nonce and split the same way -- read the same 12-byte nonce and split the same way
local nonce12 = bin:sub(pos,pos+11); pos=pos+12 local nonce12 = bin:sub(pos, pos + 11); pos = pos + 12
local iv, constant = split_nonce12(nonce12) local iv, constant = split_nonce12(nonce12)
local tag_len = 16 local tag_len = 16

View file

@ -59,7 +59,7 @@ local encrypt = function(aad, key, iv, constant, plain)
app(mt, string.pack('<I8', #aad)) app(mt, string.pack('<I8', #aad))
app(mt, string.pack('<I8', #encr)) app(mt, string.pack('<I8', #encr))
local mac_data = table.concat(mt) local mac_data = table.concat(mt)
--~ p16('mac', mac_data) --~ p16('mac', mac_data)
local tag = poly1305.auth(mac_data, otk) local tag = poly1305.auth(mac_data, otk)
return encr, tag return encr, tag
end --chacha20_aead_encrypt() end --chacha20_aead_encrypt()
@ -94,4 +94,4 @@ return {
poly_keygen = poly_keygen, poly_keygen = poly_keygen,
encrypt = encrypt, encrypt = encrypt,
decrypt = decrypt, decrypt = decrypt,
} }

View file

@ -54,8 +54,8 @@ end
-- chacha20 state and working state are allocated once and reused -- chacha20 state and working state are allocated once and reused
-- by each invocation of chacha20_block() -- by each invocation of chacha20_block()
local chacha20_state = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} local chacha20_state = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
local chacha20_working_state = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} local chacha20_working_state = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
local chacha20_block = function(key, counter, nonce) local chacha20_block = function(key, counter, nonce)
-- key: u32[8] -- key: u32[8]
@ -66,21 +66,21 @@ local chacha20_block = function(key, counter, nonce)
-- initialize state -- initialize state
st[1], st[2], st[3], st[4] = st[1], st[2], st[3], st[4] =
0x61707865, 0x3320646e, 0x79622d32, 0x6b206574 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574
for i = 1, 8 do st[i+4] = key[i] end for i = 1, 8 do st[i + 4] = key[i] end
st[13] = counter st[13] = counter
for i = 1, 3 do st[i+13] = nonce[i] end for i = 1, 3 do st[i + 13] = nonce[i] end
-- copy state to working_state -- copy state to working_state
for i = 1, 16 do wst[i] = st[i] end for i = 1, 16 do wst[i] = st[i] end
-- run 20 rounds, ie. 10 iterations of 8 quarter rounds -- run 20 rounds, ie. 10 iterations of 8 quarter rounds
for _ = 1, 10 do --RFC reference: for _ = 1, 10 do --RFC reference:
qround(wst, 1,5,9,13) --1. QUARTERROUND ( 0, 4, 8,12) qround(wst, 1, 5, 9, 13) --1. QUARTERROUND ( 0, 4, 8,12)
qround(wst, 2,6,10,14) --2. QUARTERROUND ( 1, 5, 9,13) qround(wst, 2, 6, 10, 14) --2. QUARTERROUND ( 1, 5, 9,13)
qround(wst, 3,7,11,15) --3. QUARTERROUND ( 2, 6,10,14) qround(wst, 3, 7, 11, 15) --3. QUARTERROUND ( 2, 6,10,14)
qround(wst, 4,8,12,16) --4. QUARTERROUND ( 3, 7,11,15) qround(wst, 4, 8, 12, 16) --4. QUARTERROUND ( 3, 7,11,15)
qround(wst, 1,6,11,16) --5. QUARTERROUND ( 0, 5,10,15) qround(wst, 1, 6, 11, 16) --5. QUARTERROUND ( 0, 5,10,15)
qround(wst, 2,7,12,13) --6. QUARTERROUND ( 1, 6,11,12) qround(wst, 2, 7, 12, 13) --6. QUARTERROUND ( 1, 6,11,12)
qround(wst, 3,8,9,14) --7. QUARTERROUND ( 2, 7, 8,13) qround(wst, 3, 8, 9, 14) --7. QUARTERROUND ( 2, 7, 8,13)
qround(wst, 4,5,10,15) --8. QUARTERROUND ( 3, 4, 9,14) qround(wst, 4, 5, 10, 15) --8. QUARTERROUND ( 3, 4, 9,14)
end end
-- add working_state to state -- add working_state to state
for i = 1, 16 do st[i] = bit32.band((st[i] + wst[i]), 0xffffffff) end for i = 1, 16 do st[i] = bit32.band((st[i] + wst[i]), 0xffffffff) end
@ -157,22 +157,22 @@ local function hchacha20(key, nonce16)
-- initialize state -- initialize state
st[1], st[2], st[3], st[4] = st[1], st[2], st[3], st[4] =
0x61707865, 0x3320646e, 0x79622d32, 0x6b206574 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574
for i = 1, 8 do st[i+4] = keya[i] end for i = 1, 8 do st[i + 4] = keya[i] end
for i = 1, 4 do st[i+12] = noncea[i] end for i = 1, 4 do st[i + 12] = noncea[i] end
-- run 20 rounds, ie. 10 iterations of 8 quarter rounds -- run 20 rounds, ie. 10 iterations of 8 quarter rounds
for _ = 1, 10 do --RFC reference: for _ = 1, 10 do --RFC reference:
qround(st, 1,5,9,13) --1. QUARTERROUND ( 0, 4, 8,12) qround(st, 1, 5, 9, 13) --1. QUARTERROUND ( 0, 4, 8,12)
qround(st, 2,6,10,14) --2. QUARTERROUND ( 1, 5, 9,13) qround(st, 2, 6, 10, 14) --2. QUARTERROUND ( 1, 5, 9,13)
qround(st, 3,7,11,15) --3. QUARTERROUND ( 2, 6,10,14) qround(st, 3, 7, 11, 15) --3. QUARTERROUND ( 2, 6,10,14)
qround(st, 4,8,12,16) --4. QUARTERROUND ( 3, 7,11,15) qround(st, 4, 8, 12, 16) --4. QUARTERROUND ( 3, 7,11,15)
qround(st, 1,6,11,16) --5. QUARTERROUND ( 0, 5,10,15) qround(st, 1, 6, 11, 16) --5. QUARTERROUND ( 0, 5,10,15)
qround(st, 2,7,12,13) --6. QUARTERROUND ( 1, 6,11,12) qround(st, 2, 7, 12, 13) --6. QUARTERROUND ( 1, 6,11,12)
qround(st, 3,8,9,14) --7. QUARTERROUND ( 2, 7, 8,13) qround(st, 3, 8, 9, 14) --7. QUARTERROUND ( 2, 7, 8,13)
qround(st, 4,5,10,15) --8. QUARTERROUND ( 3, 4, 9,14) qround(st, 4, 5, 10, 15) --8. QUARTERROUND ( 3, 4, 9,14)
end end
local subkey = string.pack("<I4I4I4I4I4I4I4I4", local subkey = string.pack("<I4I4I4I4I4I4I4I4",
st[1], st[2], st[3], st[4], st[1], st[2], st[3], st[4],
st[13], st[14], st[15], st[16] ) st[13], st[14], st[15], st[16])
return subkey return subkey
end --hchacha20() end --hchacha20()
@ -180,7 +180,7 @@ local function xchacha20_encrypt(key, counter, nonce, pt)
assert(#key == 32, "#key must be 32") assert(#key == 32, "#key must be 32")
assert(#nonce == 24, "#nonce must be 24") assert(#nonce == 24, "#nonce must be 24")
local subkey = hchacha20(key, nonce:sub(1, 16)) local subkey = hchacha20(key, nonce:sub(1, 16))
local nonce12 = '\0\0\0\0'..nonce:sub(17) local nonce12 = '\0\0\0\0' .. nonce:sub(17)
return chacha20_encrypt(subkey, counter, nonce12, pt) return chacha20_encrypt(subkey, counter, nonce12, pt)
end --xchacha20_encrypt() end --xchacha20_encrypt()
@ -199,6 +199,6 @@ return {
key_size = 32, key_size = 32,
nonce_size = 12, -- nonce size for chacha20_encrypt nonce_size = 12, -- nonce size for chacha20_encrypt
xnonce_size = 24, -- nonce size for xchacha20_encrypt xnonce_size = 24, -- nonce size for xchacha20_encrypt
} }
--end of chacha20 --end of chacha20

View file

@ -17,13 +17,13 @@ local function poly_init(k)
-- initialize internal state -- initialize internal state
local st = { local st = {
r = { r = {
bit32.band(sunp('<I4', k, 1) , 0x3ffffff), -- r0 bit32.band(sunp('<I4', k, 1), 0x3ffffff), -- r0
bit32.band(bit32.rshift(sunp('<I4', k, 4), 2), 0x3ffff03), -- r1 bit32.band(bit32.rshift(sunp('<I4', k, 4), 2), 0x3ffff03), -- r1
bit32.band(bit32.rshift(sunp('<I4', k, 7), 4), 0x3ffc0ff), -- r2 bit32.band(bit32.rshift(sunp('<I4', k, 7), 4), 0x3ffc0ff), -- r2
bit32.band(bit32.rshift(sunp('<I4', k, 10), 6), 0x3f03fff), -- r3 bit32.band(bit32.rshift(sunp('<I4', k, 10), 6), 0x3f03fff), -- r3
bit32.band(bit32.rshift(sunp('<I4', k, 13), 8), 0x00fffff), -- r4 bit32.band(bit32.rshift(sunp('<I4', k, 13), 8), 0x00fffff), -- r4
}, },
h = { 0,0,0,0,0 }, h = { 0, 0, 0, 0, 0 },
pad = { sunp('<I4', k, 17), -- 's' in rfc pad = { sunp('<I4', k, 17), -- 's' in rfc
sunp('<I4', k, 21), sunp('<I4', k, 21),
sunp('<I4', k, 25), sunp('<I4', k, 25),
@ -32,7 +32,7 @@ local function poly_init(k)
buffer = "", -- buffer = "", --
leftover = 0, leftover = 0,
final = false, final = false,
}--st } --st
return st return st
end --poly_init() end --poly_init()
@ -60,25 +60,25 @@ local function poly_blocks(st, m)
-- --
while bytes >= 16 do -- 16 = poly1305_block_size while bytes >= 16 do -- 16 = poly1305_block_size
-- h += m[i] (in rfc: a += n with 0x01 byte) -- h += m[i] (in rfc: a += n with 0x01 byte)
h0 = h0 + bit32.band(sunp('<I4', m, midx ), 0x3ffffff) h0 = h0 + bit32.band(sunp('<I4', m, midx), 0x3ffffff)
h1 = h1 + bit32.band(bit32.rshift(sunp('<I4', m, midx + 3), 2), 0x3ffffff) h1 = h1 + bit32.band(bit32.rshift(sunp('<I4', m, midx + 3), 2), 0x3ffffff)
h2 = h2 + bit32.band(bit32.rshift(sunp('<I4', m, midx + 6), 4), 0x3ffffff) h2 = h2 + bit32.band(bit32.rshift(sunp('<I4', m, midx + 6), 4), 0x3ffffff)
h3 = h3 + bit32.band(bit32.rshift(sunp('<I4', m, midx + 9), 6), 0x3ffffff) h3 = h3 + bit32.band(bit32.rshift(sunp('<I4', m, midx + 9), 6), 0x3ffffff)
h4 = h4 + bit32.bor(bit32.rshift(sunp('<I4', m, midx + 12), 8), hibit) -- 0x01 byte h4 = h4 + bit32.bor(bit32.rshift(sunp('<I4', m, midx + 12), 8), hibit) -- 0x01 byte
-- --
-- h *= r % p (partial) -- h *= r % p (partial)
d0 = h0*r0 + h1*s4 + h2*s3 + h3*s2 + h4*s1 d0 = h0 * r0 + h1 * s4 + h2 * s3 + h3 * s2 + h4 * s1
d1 = h0*r1 + h1*r0 + h2*s4 + h3*s3 + h4*s2 d1 = h0 * r1 + h1 * r0 + h2 * s4 + h3 * s3 + h4 * s2
d2 = h0*r2 + h1*r1 + h2*r0 + h3*s4 + h4*s3 d2 = h0 * r2 + h1 * r1 + h2 * r0 + h3 * s4 + h4 * s3
d3 = h0*r3 + h1*r2 + h2*r1 + h3*r0 + h4*s4 d3 = h0 * r3 + h1 * r2 + h2 * r1 + h3 * r0 + h4 * s4
d4 = h0*r4 + h1*r3 + h2*r2 + h3*r1 + h4*r0 d4 = h0 * r4 + h1 * r3 + h2 * r2 + h3 * r1 + h4 * r0
-- --
c = bit32.band(bit32.rshift(d0,26), 0xffffffff) ; h0 = bit32.band(d0, 0x3ffffff) c = bit32.band(bit32.rshift(d0, 26), 0xffffffff); h0 = bit32.band(d0, 0x3ffffff)
d1 = d1 + c ; c = bit32.band(bit32.rshift(d1,26), 0xffffffff) ; h1 = bit32.band(d1, 0x3ffffff) d1 = d1 + c; c = bit32.band(bit32.rshift(d1, 26), 0xffffffff); h1 = bit32.band(d1, 0x3ffffff)
d2 = d2 + c ; c = bit32.band(bit32.rshift(d2,26), 0xffffffff) ; h2 = bit32.band(d2, 0x3ffffff) d2 = d2 + c; c = bit32.band(bit32.rshift(d2, 26), 0xffffffff); h2 = bit32.band(d2, 0x3ffffff)
d3 = d3 + c ; c = bit32.band(bit32.rshift(d3,26), 0xffffffff) ; h3 = bit32.band(d3, 0x3ffffff) d3 = d3 + c; c = bit32.band(bit32.rshift(d3, 26), 0xffffffff); h3 = bit32.band(d3, 0x3ffffff)
d4 = d4 + c ; c = bit32.band(bit32.rshift(d4,26), 0xffffffff) ; h4 = bit32.band(d4, 0x3ffffff) d4 = d4 + c; c = bit32.band(bit32.rshift(d4, 26), 0xffffffff); h4 = bit32.band(d4, 0x3ffffff)
h0 = h0 + (c*5) ; c = bit32.rshift(h0,26) ; h0 = bit32.band(h0, 0x3ffffff) h0 = h0 + (c * 5); c = bit32.rshift(h0, 26); h0 = bit32.band(h0, 0x3ffffff)
h1 = h1 + c h1 = h1 + c
-- --
midx = midx + 16 -- 16 = poly1305_block_size midx = midx + 16 -- 16 = poly1305_block_size
@ -107,10 +107,10 @@ local function poly_update(st, m)
-- nothing to do? no add 0x01? - apparently not. -- nothing to do? no add 0x01? - apparently not.
else else
local buffer = string.sub(m, st.midx) local buffer = string.sub(m, st.midx)
.. '\x01' .. string.rep('\0', 16 - st.bytes -1) .. '\x01' .. string.rep('\0', 16 - st.bytes - 1)
assert(#buffer == 16) assert(#buffer == 16)
st.final = true -- this is the last block st.final = true -- this is the last block
--~ p16(buffer) --~ p16(buffer)
poly_blocks(st, buffer) poly_blocks(st, buffer)
end end
-- --
@ -128,18 +128,18 @@ local function poly_finish(st)
local h3 = st.h[4] local h3 = st.h[4]
local h4 = st.h[5] local h4 = st.h[5]
-- --
c = bit32.rshift(h1,26); h1 = bit32.band(h1, 0x3ffffff) c = bit32.rshift(h1, 26); h1 = bit32.band(h1, 0x3ffffff)
h2 = h2 + c; c = bit32.rshift(h2, 26); h2 = bit32.band(h2, 0x3ffffff) h2 = h2 + c; c = bit32.rshift(h2, 26); h2 = bit32.band(h2, 0x3ffffff)
h3 = h3 + c; c = bit32.rshift(h3, 26); h3 = bit32.band(h3, 0x3ffffff) h3 = h3 + c; c = bit32.rshift(h3, 26); h3 = bit32.band(h3, 0x3ffffff)
h4 = h4 + c; c = bit32.rshift(h4, 26); h4 = bit32.band(h4, 0x3ffffff) h4 = h4 + c; c = bit32.rshift(h4, 26); h4 = bit32.band(h4, 0x3ffffff)
h0 = h0 + (c*5); c = bit32.rshift(h0, 26); h0 = bit32.band(h0, 0x3ffffff) h0 = h0 + (c * 5); c = bit32.rshift(h0, 26); h0 = bit32.band(h0, 0x3ffffff)
h1 = h1 + c h1 = h1 + c
-- --
--compute h + -p --compute h + -p
local g0 = (h0 + 5) ; c = bit32.rshift(g0, 26); g0 = bit32.band(g0, 0x3ffffff) local g0 = (h0 + 5); c = bit32.rshift(g0, 26); g0 = bit32.band(g0, 0x3ffffff)
local g1 = (h1 + c) ; c = bit32.rshift(g1, 26); g1 = bit32.band(g1, 0x3ffffff) local g1 = (h1 + c); c = bit32.rshift(g1, 26); g1 = bit32.band(g1, 0x3ffffff)
local g2 = (h2 + c) ; c = bit32.rshift(g2, 26); g2 = bit32.band(g2, 0x3ffffff) local g2 = (h2 + c); c = bit32.rshift(g2, 26); g2 = bit32.band(g2, 0x3ffffff)
local g3 = (h3 + c) ; c = bit32.rshift(g3, 26); g3 = bit32.band(g3, 0x3ffffff) local g3 = (h3 + c); c = bit32.rshift(g3, 26); g3 = bit32.band(g3, 0x3ffffff)
local g4 = bit32.band(h4 + c - 0x4000000, 0xffffffff) -- (1 << 26) local g4 = bit32.band(h4 + c - 0x4000000, 0xffffffff) -- (1 << 26)
-- --
-- select h if h < p, or h + -p if h >= p -- select h if h < p, or h + -p if h >= p
@ -165,10 +165,10 @@ local function poly_finish(st)
h3 = bit32.band(bit32.bor(bit32.rshift(h3, 18), bit32.lshift(h4, 8)), 0xffffffff) h3 = bit32.band(bit32.bor(bit32.rshift(h3, 18), bit32.lshift(h4, 8)), 0xffffffff)
-- --
-- mac = (h + pad) % (2^128) -- mac = (h + pad) % (2^128)
f = h0 + st.pad[1] ; h0 = bit32.band(f, 0xffffffff) f = h0 + st.pad[1]; h0 = bit32.band(f, 0xffffffff)
f = h1 + st.pad[2] + bit32.rshift(f, 32) ; h1 = bit32.band(f, 0xffffffff) f = h1 + st.pad[2] + bit32.rshift(f, 32); h1 = bit32.band(f, 0xffffffff)
f = h2 + st.pad[3] + bit32.rshift(f, 32) ; h2 = bit32.band(f, 0xffffffff) f = h2 + st.pad[3] + bit32.rshift(f, 32); h2 = bit32.band(f, 0xffffffff)
f = h3 + st.pad[4] + bit32.rshift(f, 32) ; h3 = bit32.band(f, 0xffffffff) f = h3 + st.pad[4] + bit32.rshift(f, 32); h3 = bit32.band(f, 0xffffffff)
-- --
local mac = string.pack('<I4I4I4I4', h0, h1, h2, h3) local mac = string.pack('<I4I4I4I4', h0, h1, h2, h3)
-- (should zero out the state?) -- (should zero out the state?)

View file

@ -16,8 +16,8 @@ do
---@param func function The function to run, usually an `os.pullEvent` loop ---@param func function The function to run, usually an `os.pullEvent` loop
function PrimeUI.addTask(func) function PrimeUI.addTask(func)
expect(1, func, "function") expect(1, func, "function")
local t = {coro = coroutine.create(func)} local t = { coro = coroutine.create(func) }
coros[#coros+1] = t coros[#coros + 1] = t
_, t.filter = coroutine.resume(t.coro) _, t.filter = coroutine.resume(t.coro)
end end
@ -102,7 +102,8 @@ end
---@param replacement string|nil A character to replace typed characters with ---@param replacement string|nil A character to replace typed characters with
---@param history string[]|nil A list of previous entries to provide ---@param history string[]|nil A list of previous entries to provide
---@param completion function|nil A function to call to provide completion ---@param completion function|nil A function to call to provide completion
function PrimeUI.inputBox(win, x, y, width, action, placeholder, fgColor, bgColor, placeholderFg, replacement, history, completion, default) function PrimeUI.inputBox(win, x, y, width, action, placeholder, fgColor, bgColor, placeholderFg, replacement, history,
completion, default)
expect(1, win, "table") expect(1, win, "table")
expect(2, x, "number") expect(2, x, "number")
expect(3, y, "number") expect(3, y, "number")
@ -273,8 +274,11 @@ function PrimeUI.scrollBox(win, x, y, width, height, innerHeight, allowArrowKeys
-- Check for scroll events and set direction. -- Check for scroll events and set direction.
local dir local dir
if ev[1] == "key" and allowArrowKeys then if ev[1] == "key" and allowArrowKeys then
if ev[2] == keys.up then dir = -1 if ev[2] == keys.up then
elseif ev[2] == keys.down then dir = 1 end dir = -1
elseif ev[2] == keys.down then
dir = 1
end
elseif ev[1] == "mouse_scroll" and ev[3] >= x and ev[3] < x + width and ev[4] >= y and ev[4] < y + height then elseif ev[1] == "mouse_scroll" and ev[3] >= x and ev[3] < x + width and ev[4] >= y and ev[4] < y + height then
dir = ev[2] dir = ev[2]
end end
@ -315,7 +319,6 @@ function PrimeUI.scrollBox(win, x, y, width, height, innerHeight, allowArrowKeys
return inner, scroll return inner, scroll
end end
--- Creates a list of entries that can each be selected. --- Creates a list of entries that can each be selected.
---@param win window The window to draw on ---@param win window The window to draw on
---@param x number The X coordinate of the inside of the box ---@param x number The X coordinate of the inside of the box
@ -387,8 +390,11 @@ function PrimeUI.selectionBox(win, x, y, width, height, entries, action, selectC
selection = selection + 1 selection = selection + 1
if selection > scroll + height - 1 then scroll = scroll + 1 end if selection > scroll + height - 1 then scroll = scroll + 1 end
-- Send action if necessary. -- Send action if necessary.
if type(selectChangeAction) == "string" then PrimeUI.resolve("selectionBox", selectChangeAction, selection) if type(selectChangeAction) == "string" then
elseif selectChangeAction then selectChangeAction(selection) end PrimeUI.resolve("selectionBox", selectChangeAction, selection)
elseif selectChangeAction then
selectChangeAction(selection)
end
-- Redraw screen. -- Redraw screen.
drawEntries() drawEntries()
elseif key == keys.up and selection > 1 then elseif key == keys.up and selection > 1 then
@ -396,14 +402,20 @@ function PrimeUI.selectionBox(win, x, y, width, height, entries, action, selectC
selection = selection - 1 selection = selection - 1
if selection < scroll then scroll = scroll - 1 end if selection < scroll then scroll = scroll - 1 end
-- Send action if necessary. -- Send action if necessary.
if type(selectChangeAction) == "string" then PrimeUI.resolve("selectionBox", selectChangeAction, selection) if type(selectChangeAction) == "string" then
elseif selectChangeAction then selectChangeAction(selection) end PrimeUI.resolve("selectionBox", selectChangeAction, selection)
elseif selectChangeAction then
selectChangeAction(selection)
end
-- Redraw screen. -- Redraw screen.
drawEntries() drawEntries()
elseif key == keys.enter then elseif key == keys.enter then
-- Select the entry: send the action. -- Select the entry: send the action.
if type(action) == "string" then PrimeUI.resolve("selectionBox", action, entries()[selection]) if type(action) == "string" then
else action(entries()[selection]) end PrimeUI.resolve("selectionBox", action, entries()[selection])
else
action(entries()[selection])
end
end end
elseif event == "mouse_click" and key == 1 then elseif event == "mouse_click" and key == 1 then
-- Handle clicking the scroll arrows. -- Handle clicking the scroll arrows.
@ -414,8 +426,11 @@ function PrimeUI.selectionBox(win, x, y, width, height, entries, action, selectC
selection = selection - 1 selection = selection - 1
if selection < scroll then scroll = scroll - 1 end if selection < scroll then scroll = scroll - 1 end
-- Send action if necessary. -- Send action if necessary.
if type(selectChangeAction) == "string" then PrimeUI.resolve("selectionBox", selectChangeAction, selection) if type(selectChangeAction) == "string" then
elseif selectChangeAction then selectChangeAction(selection) end PrimeUI.resolve("selectionBox", selectChangeAction, selection)
elseif selectChangeAction then
selectChangeAction(selection)
end
-- Redraw screen. -- Redraw screen.
drawEntries() drawEntries()
elseif cy == wy + height - 1 and selection < #entries() then elseif cy == wy + height - 1 and selection < #entries() then
@ -423,8 +438,11 @@ function PrimeUI.selectionBox(win, x, y, width, height, entries, action, selectC
selection = selection + 1 selection = selection + 1
if selection > scroll + height - 1 then scroll = scroll + 1 end if selection > scroll + height - 1 then scroll = scroll + 1 end
-- Send action if necessary. -- Send action if necessary.
if type(selectChangeAction) == "string" then PrimeUI.resolve("selectionBox", selectChangeAction, selection) if type(selectChangeAction) == "string" then
elseif selectChangeAction then selectChangeAction(selection) end PrimeUI.resolve("selectionBox", selectChangeAction, selection)
elseif selectChangeAction then
selectChangeAction(selection)
end
-- Redraw screen. -- Redraw screen.
drawEntries() drawEntries()
end end
@ -432,13 +450,19 @@ function PrimeUI.selectionBox(win, x, y, width, height, entries, action, selectC
local sel = scroll + (cy - wy) local sel = scroll + (cy - wy)
if sel == selection then if sel == selection then
-- Select the entry: send the action. -- Select the entry: send the action.
if type(action) == "string" then PrimeUI.resolve("selectionBox", action, entries()[selection]) if type(action) == "string" then
else action(entries()[selection]) end PrimeUI.resolve("selectionBox", action, entries()[selection])
else
action(entries()[selection])
end
else else
selection = sel selection = sel
-- Send action if necessary. -- Send action if necessary.
if type(selectChangeAction) == "string" then PrimeUI.resolve("selectionBox", selectChangeAction, selection) if type(selectChangeAction) == "string" then
elseif selectChangeAction then selectChangeAction(selection) end PrimeUI.resolve("selectionBox", selectChangeAction, selection)
elseif selectChangeAction then
selectChangeAction(selection)
end
-- Redraw screen. -- Redraw screen.
drawEntries() drawEntries()
end end
@ -452,8 +476,11 @@ function PrimeUI.selectionBox(win, x, y, width, height, entries, action, selectC
selection = selection - 1 selection = selection - 1
if selection < scroll then scroll = scroll - 1 end if selection < scroll then scroll = scroll - 1 end
-- Send action if necessary. -- Send action if necessary.
if type(selectChangeAction) == "string" then PrimeUI.resolve("selectionBox", selectChangeAction, selection) if type(selectChangeAction) == "string" then
elseif selectChangeAction then selectChangeAction(selection) end PrimeUI.resolve("selectionBox", selectChangeAction, selection)
elseif selectChangeAction then
selectChangeAction(selection)
end
-- Redraw screen. -- Redraw screen.
drawEntries() drawEntries()
elseif key > 0 and selection < #entries() then elseif key > 0 and selection < #entries() then
@ -461,8 +488,11 @@ function PrimeUI.selectionBox(win, x, y, width, height, entries, action, selectC
selection = selection + 1 selection = selection + 1
if selection > scroll + height - 1 then scroll = scroll + 1 end if selection > scroll + height - 1 then scroll = scroll + 1 end
-- Send action if necessary. -- Send action if necessary.
if type(selectChangeAction) == "string" then PrimeUI.resolve("selectionBox", selectChangeAction, selection) if type(selectChangeAction) == "string" then
elseif selectChangeAction then selectChangeAction(selection) end PrimeUI.resolve("selectionBox", selectChangeAction, selection)
elseif selectChangeAction then
selectChangeAction(selection)
end
-- Redraw screen. -- Redraw screen.
drawEntries() drawEntries()
end end
@ -473,7 +503,6 @@ function PrimeUI.selectionBox(win, x, y, width, height, entries, action, selectC
return drawEntries return drawEntries
end end
return { return {
PrimeUI = PrimeUI PrimeUI = PrimeUI
} }

View file

@ -1,4 +1,3 @@
---@class InnerRemote ---@class InnerRemote
---@field port number ---@field port number
---@field password string ---@field password string
@ -8,11 +7,15 @@
---@field ender_storage string ---@field ender_storage string
---@field modem string ---@field modem string
---@field remotes table<string, InnerRemote> ---@field remotes table<string, InnerRemote>
---
---@class Chatbox
---@field players table<string, string>
---@field prefix string|nil
---@class Config ---@class Config
---@field inventories string[] ---@field inventories string[]
---@field import string[]|nil ---@field import string[]|nil
---@field chatbox table<string, string>|nil ---@field chatbox Chatbox|nil
---@field remote Remote ---@field remote Remote
local inv = require("modules.inv") local inv = require("modules.inv")

View file

@ -50,7 +50,6 @@ local function levDist(s, t)
end end
local function findBest(data, item) local function findBest(data, item)
local sorted_data = {} local sorted_data = {}
for _, z in ipairs(data) do for _, z in ipairs(data) do
@ -84,7 +83,7 @@ end
local BOT_NAME = "&cS &eI&an&3c &5S&cI&6S" local BOT_NAME = "&cS &eI&an&3c &5S&cI&6S"
function auth(user) function auth(user)
local manip = config.chatbox[user] local manip = config.chatbox.players[user]
if manip then if manip then
return true return true
else else
@ -99,11 +98,11 @@ function run()
while true do while true do
local _, user, command, args = os.pullEvent("command") local _, user, command, args = os.pullEvent("command")
if command == "sis" then if command == (config.chatbox.prefix or "sis") then
if args[1] == "whoami" then if args[1] == "whoami" then
local manip = config.chatbox[user] local manip = config.chatbox.players[user]
if manip then if manip then
chatbox.tell(user, "You are " .. user .. ", linked with `" .. manip .."`.", BOT_NAME) chatbox.tell(user, "You are " .. user .. ", linked with `" .. manip .. "`.", BOT_NAME)
else else
chatbox.tell(user, "You are not registered. Ask the creator of this SIS to be registered.", BOT_NAME) chatbox.tell(user, "You are not registered. Ask the creator of this SIS to be registered.", BOT_NAME)
end end
@ -116,7 +115,7 @@ function run()
end end
local perip = peripheral.wrap(config.chatbox[user]) local perip = peripheral.wrap(config.chatbox.players[user])
---@type ccTweaked.peripheral.Inventory ---@type ccTweaked.peripheral.Inventory
local peripInventory = perip.getInventory() local peripInventory = perip.getInventory()
@ -172,7 +171,7 @@ function run()
goto continue goto continue
end end
local perip = peripheral.wrap(config.chatbox[user]) local perip = peripheral.wrap(config.chatbox.players[user])
---@type ccTweaked.peripheral.Inventory ---@type ccTweaked.peripheral.Inventory
local peripInventory = perip.getInventory() local peripInventory = perip.getInventory()

View file

@ -89,7 +89,6 @@ local function sendItemToSelf(itemName, perip, maxAmount)
end end
end end
end end
-- sleep(0.1)
turtleMoveAllowed = true turtleMoveAllowed = true
return total return total

View file

@ -30,15 +30,13 @@ local function run()
for color, remote in pairs(config.remote.remotes) do for color, remote in pairs(config.remote.remotes) do
if remote.port == channel then if remote.port == channel then
local err, data = pcall(function()
local err, data = pcall(function ()
return hmac.decrypt_with_password(remote.password, message) return hmac.decrypt_with_password(remote.password, message)
end) end)
if not data then return end if not data then return end
if err == true then if err == true then
---@type RemoteAccess ---@type RemoteAccess
local json, errj = textutils.unserialiseJSON(data) local json, errj = textutils.unserialiseJSON(data)
if json or errj ~= nil then if json or errj ~= nil then

View file

@ -10,7 +10,7 @@ end
local function run() local function run()
local search = "" local search = ""
local win = term.current(); local win = term.current();
local w , h= term.getSize() local w, h = term.getSize()
local function getFiltered() local function getFiltered()
local filtered = {} local filtered = {}
@ -24,7 +24,8 @@ local function run()
local refiltered = {} local refiltered = {}
for i, filter in ipairs(filtered) do for i, filter in ipairs(filtered) do
refiltered[i] = filter.name .. string.rep(" ", w-(2+#filter.name+#tostring(filter.count))) .. tostring(filter.count) refiltered[i] = filter.name ..
string.rep(" ", w - (2 + #filter.name + #tostring(filter.count))) .. tostring(filter.count)
end end
return refiltered return refiltered
end end
@ -33,8 +34,8 @@ local function run()
PrimeUI.clear() PrimeUI.clear()
local updateEntries = PrimeUI.selectionBox( local updateEntries = PrimeUI.selectionBox(
win, 1, 4, w, h-7, win, 1, 4, w, h - 7,
function () function()
return com return com
end, end,
function(option) function(option)
@ -46,7 +47,7 @@ local function run()
end end
) )
PrimeUI.inputBox(win, 2, 2, w-2, function (data) PrimeUI.inputBox(win, 2, 2, w - 2, function(data)
search = data search = data
com = getFiltered() com = getFiltered()
updateEntries() updateEntries()
@ -54,8 +55,8 @@ local function run()
local ver = fs.open("storage-solution/version", "r").readAll() local ver = fs.open("storage-solution/version", "r").readAll()
PrimeUI.label(win, 2, h-1, is_beta(ver) and "you're running beta :3" or "welcome to SiSS", colors.lightGray) PrimeUI.label(win, 2, h - 1, is_beta(ver) and "you're running beta :3" or "welcome to SiSS", colors.lightGray)
PrimeUI.label(win, 2, h-2, "rev. " .. ver, colors.lightGray) PrimeUI.label(win, 2, h - 2, "rev. " .. ver, colors.lightGray)
local timer = os.startTimer(1) local timer = os.startTimer(1)
PrimeUI.addTask(function() PrimeUI.addTask(function()