245 lines
7.6 KiB
Lua

--[[
Config - create, load and save config file (.json / .cfg)
Used by cavebot and other things
]]--
local context = G.botContext
context.Config = {}
local Config = context.Config
Config.exist = function(dir)
return g_resources.directoryExists(context.configDir .. "/" .. dir)
end
Config.create = function(dir)
g_resources.makeDir(context.configDir .. "/" .. dir)
return Config.exist(dir)
end
Config.list = function(dir)
if not Config.exist(dir) then
if not Config.create(dir) then
return contex.error("Can't create config dir: " .. context.configDir .. "/" .. dir)
end
end
local list = g_resources.listDirectoryFiles(context.configDir .. "/" .. dir)
local correctList = {}
for k,v in ipairs(list) do -- filter files
local nv = v:gsub(".json", ""):gsub(".cfg", "")
if nv ~= v then
table.insert(correctList, nv)
end
end
return correctList
end
-- load config from string insteaf of dile
Config.parse = function(data)
local status, result = pcall(function()
return json.decode(data)
end)
if status and type(result) == 'table' then
return result
end
local status, result = pcall(function()
return table.decodeStringPairList(data)
end)
if status and type(result) == 'table' then
return result
end
return context.error("Invalid config format")
end
Config.load = function(dir, name)
local file = context.configDir .. "/" .. dir .. "/" .. name .. ".json"
if g_resources.fileExists(file) then -- load json
return json.decode(g_resources.readFileContents(file))
end
file = context.configDir .. "/" .. dir .. "/" .. name .. ".cfg"
if g_resources.fileExists(file) then -- load cfg
return table.decodeStringPairList(g_resources.readFileContents(file))
end
return context.error("Config " .. file .. " doesn't exist")
end
Config.loadRaw = function(dir, name)
local file = context.configDir .. "/" .. dir .. "/" .. name .. ".json"
if g_resources.fileExists(file) then -- load json
return g_resources.readFileContents(file)
end
file = context.configDir .. "/" .. dir .. "/" .. name .. ".cfg"
if g_resources.fileExists(file) then -- load cfg
return g_resources.readFileContents(file)
end
return context.error("Config " .. file .. " doesn't exist")
end
Config.save = function(dir, name, value, forcedExtension)
if not Config.exist(dir) then
if not Config.create(dir) then
return contex.error("Can't create config dir: " .. context.configDir .. "/" .. dir)
end
end
if type(value) ~= 'table' then
return context.error("Invalid config value type: " .. type(value) .. ", should be table")
end
local file = context.configDir .. "/" .. dir .. "/" .. name
if (table.isStringPairList(value) and forcedExtension ~= "json") or forcedExtension == "cfg" then -- cfg
g_resources.writeFileContents(file .. ".cfg", table.encodeStringPairList(value))
else
g_resources.writeFileContents(file .. ".json", json.encode(value))
end
return true
end
Config.remove = function(dir, name)
local file = context.configDir .. "/" .. dir .. "/" .. name .. ".json"
local ret = false
if g_resources.fileExists(file) then
g_resources.deleteFile(file)
ret = true
end
file = context.configDir .. "/" .. dir .. "/" .. name .. ".cfg"
if g_resources.fileExists(file) then
g_resources.deleteFile(file)
ret = true
end
return ret
end
-- setup is used for BotConfig widget
-- not done yet
Config.setup = function(dir, widget, configExtension, callback)
if type(dir) ~= 'string' or dir:len() == 0 then
return context.error("Invalid config dir")
end
if not Config.exist(dir) and not Config.create(dir) then
return context.error("Can't create config dir: " .. dir)
end
if type(context.storage._configs) ~= "table" then
context.storage._configs = {}
end
if type(context.storage._configs[dir]) ~= "table" then
context.storage._configs[dir] = {
enabled = false,
selected = ""
}
else
widget.switch:setOn(context.storage._configs[dir].enabled)
end
local isRefreshing = false
local refresh = function()
isRefreshing = true
local configs = Config.list(dir)
local configIndex = 1
widget.list:clear()
for v,k in ipairs(configs) do
widget.list:addOption(k)
if k == context.storage._configs[dir].selected then
configIndex = v
end
end
local data = nil
if #configs > 0 then
widget.list:setCurrentIndex(configIndex)
context.storage._configs[dir].selected = widget.list:getCurrentOption().text
data = Config.load(dir, configs[configIndex])
else
context.storage._configs[dir].selected = nil
end
context.storage._configs[dir].enabled = widget.switch:isOn()
isRefreshing = false
callback(context.storage._configs[dir].selected, widget.switch:isOn(), data)
end
widget.list.onOptionChange = function(widget)
if not isRefreshing then
context.storage._configs[dir].selected = widget:getCurrentOption().text
refresh()
end
end
widget.switch.onClick = function()
widget.switch:setOn(not widget.switch:isOn())
refresh()
end
widget.add.onClick = function()
context.UI.SinglelineEditorWindow("config_name", {title="Enter config name"}, function(name)
name = name:gsub("%s+", "_")
if name:len() == 0 or name:len() >= 30 or name:find("/") or name:find("\\") then
return context.error("Invalid config name")
end
local file = context.configDir .. "/" .. dir .. "/" .. name .. "." .. configExtension
if g_resources.fileExists(file) then
return context.error("Config " .. name .. " already exist")
end
g_resources.writeFileContents(file, "")
context.storage._configs[dir].selected = name
widget.switch:setOn(false)
refresh()
end)
end
widget.edit.onClick = function()
local name = context.storage._configs[dir].selected
if not name then return end
context.UI.MultilineEditorWindow(Config.loadRaw(dir, name), {title="Config editor - " .. name .. " in " .. dir}, function(newValue)
local data = Config.parse(newValue)
Config.save(dir, name, data, configExtension)
refresh()
end)
end
widget.remove.onClick = function()
local name = context.storage._configs[dir].selected
if not name then return end
context.UI.ConfirmationWindow("Config removal", "Do you want to remove config " .. name .. " from " .. dir .. "?", function()
Config.remove(dir, name)
widget.switch:setOn(false)
refresh()
end)
end
refresh()
return {
isOn = function()
return widget.switch:isOn()
end,
isOff = function()
return not widget.switch:isOn()
end,
setOn = function(val)
if val == false then
if widget.switch:isOn() then
widget.switch:onClick()
end
return
end
if not widget.switch:isOn() then
widget.switch:onClick()
end
end,
setOff = function(val)
if val == false then
if not widget.switch:isOn() then
widget.switch:onClick()
end
return
end
if widget.switch:isOn() then
widget.switch:onClick()
end
end,
save = function(data)
Config.save(dir, context.storage._configs[dir].selected, data, configExtension)
end,
refresh = refresh,
reload = refresh,
getActiveConfigName = function()
return context.storage._configs[dir].selected
end
}
end