215 lines
5.2 KiB
Lua
215 lines
5.2 KiB
Lua
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 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, peripInventory, 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)
|
|
|
|
chatbox.tell(user, "Moved `" .. tostring(moved) .. "` items.", BOT_NAME)
|
|
end
|
|
end
|
|
::continue::
|
|
end
|
|
end
|
|
|
|
return {
|
|
run = run
|
|
}
|