storage-solution/src/modules/chatbox.lua
2026-01-31 14:16:01 +02:00

210 lines
5.1 KiB
Lua

local config = require("../../config") ---@type Config
local inv = require("modules.inv")
local function levDist(s, t)
local n = #s
local m = #t
if n == 0 then return m end
if m == 0 then return n end
-- create matrix
local d = {}
for i = 0, n do
d[i] = {}
end
-- initialize
for i = 0, n do d[i][0] = i end
for j = 0, m do d[0][j] = j end
-- main loop
for i = 1, n do
local s_i = s:sub(i, i)
for j = 1, m do
-- safeguard shortcut
if i == j and d[i][j] and d[i][j] > 4 then
return n
end
local t_j = t:sub(j, j)
local cost = (s_i == t_j) and 0 or 1
local mi = math.min(
d[i - 1][j] + 1,
d[i][j - 1] + 1,
d[i - 1][j - 1] + cost
)
d[i][j] = mi
-- Damerau transposition
if i > 1 and j > 1 and s_i == t:sub(j - 1, j - 1) and s:sub(i - 1, i - 1) == t_j then
d[i][j] = math.min(d[i][j], d[i - 2][j - 2] + cost)
end
end
end
return d[n][m]
end
local function findBest(data, item)
local sorted_data = {}
for _, z in ipairs(data) do
local parts = {}
for part in string.gmatch(z, "([^:]+)") do
table.insert(parts, part)
end
local key = parts[1] .. ":" .. (parts[2] or "")
local dist = levDist(item, parts[2] or "")
table.insert(sorted_data, { key, dist })
end
table.sort(sorted_data, function(a, b)
return a[2] < b[2]
end)
local best = {}
local best_dist = sorted_data[1][2]
for _, z in ipairs(sorted_data) do
if z[2] == best_dist then
table.insert(best, z)
else
break
end
end
return best
end
local BOT_NAME = "&cS &eI&an&3c &5S&cI&6S"
function auth(user)
local manip = config.chatbox.players[user]
if manip then
return true
else
chatbox.tell(user, "You are not authorized to use this command.", BOT_NAME)
return false
end
end
function run()
if config.chatbox == nil then return end
while true do
local _, user, command, args = os.pullEvent("command")
if command == (config.chatbox.prefix or "sis") then
if args[1] == "whoami" then
local manip = config.chatbox.players[user]
if manip then
chatbox.tell(user, "You are " .. user .. ", linked with `" .. manip .. "`.", BOT_NAME)
else
chatbox.tell(user, "You are not registered. Ask the creator of this SIS to be registered.", BOT_NAME)
end
elseif args[1] == "deposit" then
if not auth(user) then goto continue end
if not args[2] then
chatbox.tell(user, "Supply a item (minecraft:`diamond` part) to deposit it!", BOT_NAME)
goto continue
end
local perip = peripheral.wrap(config.chatbox.players[user])
---@type ccTweaked.peripheral.Inventory
local peripInventory = perip.getInventory()
local invList = peripInventory.list()
local allItems = {}
local seen = {}
for _, stack in pairs(invList) do
local name = stack and stack.name
if name and not seen[name] then
seen[name] = true
allItems[#allItems + 1] = name
end
end
local best = findBest(allItems, args[2])
local itemName = ""
if #best > 1 then
itemName = best[1][1]
if string.find(":", args[2]) then
itemName = args[2]
end
chatbox.tell(user, "`WARNING`: Item most likely inaccurate. Assuming " .. itemName, BOT_NAME)
else
itemName = best[1][1]
end
local slots = {}
for slot, item in pairs(peripInventory.list()) do
if item.name == itemName then
table.insert(slots, slot)
end
end
local amount = nil
if args[3] then
amount = tonumber(args[3], 10)
end
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
if not auth(user) then goto continue end
if not args[2] then
chatbox.tell(user, "Supply a item (minecraft:`diamond` part) to withdraw it!", BOT_NAME)
goto continue
end
local perip = peripheral.wrap(config.chatbox.players[user])
---@type ccTweaked.peripheral.Inventory
local peripInventory = perip.getInventory()
local best = findBest(inv:listNames(), args[2])
local itemName = ""
if #best > 1 then
itemName = best[1][1]
if string.find(":", args[2]) then
itemName = args[2]
end
chatbox.tell(user, "`WARNING`: Item most likely inaccurate. Assuming " .. itemName, BOT_NAME)
else
itemName = best[1][1]
end
local amount = nil
if args[3] then
amount = tonumber(args[3], 10)
end
local moved = inv:sendItemToSelf(itemName, peripInventory, amount, config.chatbox.players[user])
chatbox.tell(user, "Moved `" .. tostring(moved) .. "` items.", BOT_NAME)
end
end
::continue::
end
end
return {
run = run
}