mirror of
https://github.com/OTCv8/otclientv8.git
synced 2025-10-19 14:13:27 +02:00
Version 2.1 - imbuements, wrap/unwrap, 4 byte header, packet compression and other features
This commit is contained in:
@@ -24,6 +24,7 @@ function init()
|
||||
g_ui.importStyle("ui/panels.otui")
|
||||
g_ui.importStyle("ui/config.otui")
|
||||
g_ui.importStyle("ui/icons.otui")
|
||||
g_ui.importStyle("ui/container.otui")
|
||||
|
||||
connect(g_game, {
|
||||
onGameStart = online,
|
||||
@@ -195,7 +196,7 @@ function refresh()
|
||||
|
||||
-- run script
|
||||
local status, result = pcall(function()
|
||||
return executeBot(configName, botStorage, botTabs, message, save, botWebSockets) end
|
||||
return executeBot(configName, botStorage, botTabs, message, save, refresh, botWebSockets) end
|
||||
)
|
||||
if not status then
|
||||
return onError(result)
|
||||
|
@@ -1,4 +1,4 @@
|
||||
function executeBot(config, storage, tabs, msgCallback, saveConfigCallback, websockets)
|
||||
function executeBot(config, storage, tabs, msgCallback, saveConfigCallback, reloadCallback, websockets)
|
||||
-- load lua and otui files
|
||||
local configFiles = g_resources.listDirectoryFiles("/bot/" .. config, true, false)
|
||||
local luaFiles = {}
|
||||
@@ -21,16 +21,18 @@ function executeBot(config, storage, tabs, msgCallback, saveConfigCallback, webs
|
||||
local context = {}
|
||||
context.configDir = "/bot/".. config
|
||||
context.tabs = tabs
|
||||
context.panel = context.tabs:addTab("Main", g_ui.createWidget('BotPanel')).tabPanel.content
|
||||
context.mainTab = context.tabs:addTab("Main", g_ui.createWidget('BotPanel')).tabPanel.content
|
||||
context.panel = context.mainTab
|
||||
context.saveConfig = saveConfigCallback
|
||||
context._websockets = websockets
|
||||
context.reload = reloadCallback
|
||||
|
||||
context.storage = storage
|
||||
if context.storage._macros == nil then
|
||||
context.storage._macros = {} -- active macros
|
||||
end
|
||||
|
||||
-- macros, hotkeys, scheduler, icons, callbacks
|
||||
-- websockets, macros, hotkeys, scheduler, icons, callbacks
|
||||
context._websockets = websockets
|
||||
context._macros = {}
|
||||
context._hotkeys = {}
|
||||
context._scheduler = {}
|
||||
@@ -71,9 +73,10 @@ function executeBot(config, storage, tabs, msgCallback, saveConfigCallback, webs
|
||||
context.tonumber = tonumber
|
||||
context.type = type
|
||||
context.pcall = pcall
|
||||
context.load = function(str) return load(str, nil, nil, context) end
|
||||
context.load = function(str) return assert(load(str, nil, nil, context)) end
|
||||
context.loadstring = context.load
|
||||
context.assert = assert
|
||||
context.dofile = function(file) assert(load(g_resources.readFileContents("/bot/" .. config .. "/" .. file), file, nil, context))() end
|
||||
context.gcinfo = gcinfo
|
||||
context.tr = tr
|
||||
context.json = json
|
||||
@@ -129,7 +132,8 @@ function executeBot(config, storage, tabs, msgCallback, saveConfigCallback, webs
|
||||
|
||||
-- run lua script
|
||||
for i, file in ipairs(luaFiles) do
|
||||
assert(load(g_resources.readFileContents(file), file, nil, context))()
|
||||
assert(load(g_resources.readFileContents(file), file, nil, context))()
|
||||
context.panel = context.mainTab -- reset default tab
|
||||
end
|
||||
|
||||
return {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
--[[
|
||||
Config. create. load and save config file (.json)
|
||||
Config - create, load and save config file (.json / .cfg)
|
||||
Used by cavebot and other things
|
||||
]]--
|
||||
|
||||
@@ -22,7 +22,32 @@ Config.list = function(dir)
|
||||
return contex.error("Can't create config dir: " .. context.configDir .. "/" .. dir)
|
||||
end
|
||||
end
|
||||
return g_resources.listDirectoryFiles(context.configDir .. "/" .. dir)
|
||||
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)
|
||||
@@ -31,63 +56,154 @@ Config.load = function(dir, name)
|
||||
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)
|
||||
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 type(value) == 'string' then -- cfg
|
||||
g_resources.writeFileContents(file .. ".cfg", value)
|
||||
elseif type(value) == 'table' then -- json
|
||||
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 context.error("Invalid config value type: " .. type(value))
|
||||
return true
|
||||
end
|
||||
|
||||
Config.remove = function(dir, name)
|
||||
local file = context.configDir .. "/" .. dir .. "/" .. name .. ".json"
|
||||
local ret = false
|
||||
if g_resources.fileExists(file) then
|
||||
return g_resources.deleteFile(file)
|
||||
g_resources.deleteFile(file)
|
||||
ret = true
|
||||
end
|
||||
file = context.configDir .. "/" .. dir .. "/" .. name .. ".cfg"
|
||||
if g_resources.fileExists(file) then
|
||||
return g_resources.deleteFile(file)
|
||||
g_resources.deleteFile(file)
|
||||
ret = true
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
-- setup is used for BotConfig widget
|
||||
-- not done yet
|
||||
Config.setup = function(dir, widget, callback)
|
||||
local refresh = function()
|
||||
--
|
||||
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 = function()
|
||||
|
||||
widget.add.onClick = function()
|
||||
context.UI.SinglelineEditorWindow("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 = function()
|
||||
|
||||
widget.edit.onClick = function()
|
||||
local name = context.storage._configs[dir].selected
|
||||
if not name then return end
|
||||
context.UI.MultilineEditorWindow("Config editor - " .. name .. " in " .. dir,
|
||||
Config.loadRaw(dir, name), function(newValue)
|
||||
local data = Config.parse(newValue)
|
||||
Config.save(dir, name, data, configExtension)
|
||||
refresh()
|
||||
end)
|
||||
end
|
||||
|
||||
widget.remove = function()
|
||||
|
||||
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
|
||||
|
||||
--local configs = Config.list(dir)
|
||||
--widget.list.
|
||||
refresh()
|
||||
|
||||
return {
|
||||
isOn = function()
|
||||
@@ -96,18 +212,35 @@ Config.setup = function(dir, widget, callback)
|
||||
isOff = function()
|
||||
return not widget.switch:isOn()
|
||||
end,
|
||||
enable = function()
|
||||
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,
|
||||
disable = function()
|
||||
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()
|
||||
|
||||
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
|
@@ -31,6 +31,7 @@ context.addIcon = function(id, options, callback)
|
||||
local config = context.storage._icons[id]
|
||||
local widget = g_ui.createWidget("BotIcon", panel)
|
||||
widget.botWidget = true
|
||||
widget.botIcon = true
|
||||
|
||||
if type(config.x) ~= 'number' and type(config.y) ~= 'number' then
|
||||
if type(options.x) == 'number' and type(options.y) == 'number' then
|
||||
@@ -138,22 +139,22 @@ context.addIcon = function(id, options, callback)
|
||||
|
||||
config.x = math.min(1, math.max(0, x / width))
|
||||
config.y = math.min(1, math.max(0, y / height))
|
||||
|
||||
widget:addAnchor(AnchorHorizontalCenter, 'parent', AnchorHorizontalCenter)
|
||||
widget:addAnchor(AnchorVerticalCenter, 'parent', AnchorVerticalCenter)
|
||||
|
||||
widget:setMarginTop(height * (-0.5 + config.y))
|
||||
widget:setMarginTop(math.max(height * (-0.5) - parent:getMarginTop(), height * (-0.5 + config.y)))
|
||||
widget:setMarginLeft(width * (-0.5 + config.x))
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
widget.onGeometryChange = function(widget, oldRect, newRect)
|
||||
widget.onGeometryChange = function(widget)
|
||||
if widget:isDragging() then return end
|
||||
local parent = widget:getParent()
|
||||
local parentRect = parent:getRect()
|
||||
local width = parentRect.width - widget:getWidth()
|
||||
local height = parentRect.height - widget:getHeight()
|
||||
widget:setMarginTop(-parent:getMarginTop() + height * (-0.5 + config.y))
|
||||
widget:setMarginTop(math.max(height * (-0.5) - parent:getMarginTop(), height * (-0.5 + config.y)))
|
||||
widget:setMarginLeft(width * (-0.5 + config.x))
|
||||
end
|
||||
|
||||
|
@@ -183,7 +183,13 @@ context.findPath = function(startPos, destPos, maxDist, params)
|
||||
end
|
||||
context.getPath = context.findPath
|
||||
|
||||
-- also works as autoWalk(dirs) where dirs is a list eg.: {1,2,3,0,1,1,2,}
|
||||
context.autoWalk = function(destination, maxDist, params)
|
||||
if type(destination) == "table" and table.isList(destination) and not maxDist and not params then
|
||||
g_game.autoWalk(destination, {x=0,y=0,z=0})
|
||||
return true
|
||||
end
|
||||
|
||||
-- Available params same as for findPath
|
||||
local path = context.findPath(context.player:getPosition(), destination, maxDist, params)
|
||||
if not path then
|
||||
|
@@ -1,114 +1,12 @@
|
||||
local context = G.botContext
|
||||
if type(context.UI) ~= "table" then
|
||||
context.UI = {}
|
||||
end
|
||||
local UI = context.UI
|
||||
|
||||
context.setupUI = function(otml, parent)
|
||||
UI.createWidget = function(name, parent)
|
||||
if parent == nil then
|
||||
parent = context.panel
|
||||
end
|
||||
local widget = g_ui.loadUIFromString(otml, parent)
|
||||
widget.botWidget = true
|
||||
return widget
|
||||
return g_ui.createWidget(name, parent)
|
||||
end
|
||||
|
||||
context.importStyle = function(otml)
|
||||
return g_ui.importStyleFromString(otml)
|
||||
end
|
||||
|
||||
context.addTab = function(name)
|
||||
local tab = context.tabs:getTab(name)
|
||||
if tab then -- return existing tab
|
||||
return tab.tabPanel.content
|
||||
end
|
||||
|
||||
context.tabs:setOn(true)
|
||||
local newTab = context.tabs:addTab(name, g_ui.createWidget('BotPanel')).tabPanel.content
|
||||
if #(context.tabs.tabs) > 5 then
|
||||
for k,tab in pairs(context.tabs.tabs) do
|
||||
tab:setPadding(3)
|
||||
tab:setFont('small-9px')
|
||||
end
|
||||
end
|
||||
|
||||
return newTab
|
||||
end
|
||||
context.getTab = context.addTab
|
||||
|
||||
context.addSwitch = function(id, text, onClickCallback, parent)
|
||||
if not parent then
|
||||
parent = context.panel
|
||||
end
|
||||
local switch = g_ui.createWidget('BotSwitch', parent)
|
||||
switch:setId(id)
|
||||
switch:setText(text)
|
||||
switch.onClick = onClickCallback
|
||||
return switch
|
||||
end
|
||||
|
||||
context.addButton = function(id, text, onClickCallback, parent)
|
||||
if not parent then
|
||||
parent = context.panel
|
||||
end
|
||||
local button = g_ui.createWidget('BotButton', parent)
|
||||
button:setId(id)
|
||||
button:setText(text)
|
||||
button.onClick = onClickCallback
|
||||
return button
|
||||
end
|
||||
|
||||
context.addLabel = function(id, text, parent)
|
||||
if not parent then
|
||||
parent = context.panel
|
||||
end
|
||||
local label = g_ui.createWidget('BotLabel', parent)
|
||||
label:setId(id)
|
||||
label:setText(text)
|
||||
return label
|
||||
end
|
||||
|
||||
context.addTextEdit = function(id, text, onTextChangeCallback, parent)
|
||||
if not parent then
|
||||
parent = context.panel
|
||||
end
|
||||
local widget = g_ui.createWidget('BotTextEdit', parent)
|
||||
widget:setId(id)
|
||||
widget.onTextChange = onTextChangeCallback
|
||||
widget:setText(text)
|
||||
return widget
|
||||
end
|
||||
|
||||
context.addSeparator = function(id, parent)
|
||||
if not parent then
|
||||
parent = context.panel
|
||||
end
|
||||
local separator = g_ui.createWidget('BotSeparator', parent)
|
||||
separator:setId(id)
|
||||
return separator
|
||||
end
|
||||
|
||||
context._addMacroSwitch = function(name, keys, parent)
|
||||
if not parent then
|
||||
parent = context.panel
|
||||
end
|
||||
local text = name
|
||||
if keys:len() > 0 then
|
||||
text = name .. " [" .. keys .. "]"
|
||||
end
|
||||
local switch = context.addSwitch("macro_" .. #context._macros, text, function(widget)
|
||||
context.storage._macros[name] = not context.storage._macros[name]
|
||||
widget:setOn(context.storage._macros[name])
|
||||
end, parent)
|
||||
switch:setOn(context.storage._macros[name])
|
||||
return switch
|
||||
end
|
||||
|
||||
context._addHotkeySwitch = function(name, keys, parent)
|
||||
if not parent then
|
||||
parent = context.panel
|
||||
end
|
||||
local text = name
|
||||
if keys:len() > 0 then
|
||||
text = name .. " [" .. keys .. "]"
|
||||
end
|
||||
local switch = context.addSwitch("hotkey_" .. #context._hotkeys, text, nil, parent)
|
||||
switch:setOn(false)
|
||||
return switch
|
||||
end
|
81
modules/game_bot/functions/ui_elements.lua
Normal file
81
modules/game_bot/functions/ui_elements.lua
Normal file
@@ -0,0 +1,81 @@
|
||||
local context = G.botContext
|
||||
if type(context.UI) ~= "table" then
|
||||
context.UI = {}
|
||||
end
|
||||
local UI = context.UI
|
||||
|
||||
UI.Config = function(parent)
|
||||
return UI.createWidget("BotConfig", parent)
|
||||
end
|
||||
|
||||
-- call :setItems(table) to set items, call :getItems() to get them
|
||||
-- unique if true, won't allow duplicates
|
||||
-- callback (can be nil) gets table with new item list, eg: {{id=2160, count=1}, {id=268, count=100}, {id=269, count=20}}
|
||||
UI.Container = function(callback, unique, parent)
|
||||
local widget = UI.createWidget("BotContainer", parent)
|
||||
local oldItems = {}
|
||||
|
||||
local updateItems = function()
|
||||
local items = widget:getItems()
|
||||
widget:setItems(items)
|
||||
|
||||
-- callback part
|
||||
if not callback then return end
|
||||
local somethingNew = false
|
||||
for i, item in ipairs(items) do
|
||||
if type(oldItems[i]) ~= "table" then
|
||||
somethingNew = true
|
||||
break
|
||||
end
|
||||
if oldItems[i].id ~= item.id or oldItems[i].count ~= item.count then
|
||||
somethingNew = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if somethingNew then
|
||||
oldItems = items
|
||||
callback(items)
|
||||
end
|
||||
end
|
||||
|
||||
widget.setItems = function(self, items)
|
||||
if type(self) == 'table' then
|
||||
items = self
|
||||
end
|
||||
local itemsToShow = math.max(10, #items + 2)
|
||||
if itemsToShow % 5 ~= 0 then
|
||||
itemsToShow = itemsToShow + 5 - itemsToShow % 5
|
||||
end
|
||||
widget.items:destroyChildren()
|
||||
for i = 1, itemsToShow do
|
||||
local widget = g_ui.createWidget("BotItem", widget.items)
|
||||
if type(items[i]) == 'number' then
|
||||
items[i] = {id=items[i], count=1}
|
||||
end
|
||||
if type(items[i]) == 'table' then
|
||||
widget:setItem(Item.create(items[i].id, items[i].count))
|
||||
end
|
||||
end
|
||||
oldItems = items
|
||||
for i, child in ipairs(widget.items:getChildren()) do
|
||||
child.onItemChange = updateItems
|
||||
end
|
||||
end
|
||||
|
||||
widget.getItems = function()
|
||||
local items = {}
|
||||
local duplicates = {}
|
||||
for i, child in ipairs(widget.items:getChildren()) do
|
||||
if child:getItemId() >= 100 then
|
||||
if not duplicates[child:getItemId()] or not unique then
|
||||
table.insert(items, {id=child:getItemId(), count=child:getItemCount()})
|
||||
duplicates[child:getItemId()] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
return items
|
||||
end
|
||||
|
||||
return widget
|
||||
end
|
||||
|
132
modules/game_bot/functions/ui_legacy.lua
Normal file
132
modules/game_bot/functions/ui_legacy.lua
Normal file
@@ -0,0 +1,132 @@
|
||||
local context = G.botContext
|
||||
|
||||
context.createWidget = function(name, parent)
|
||||
if parent == nil then
|
||||
parent = context.panel
|
||||
end
|
||||
g_ui.createWidget(name, parent)
|
||||
end
|
||||
|
||||
context.setupUI = function(otml, parent)
|
||||
if parent == nil then
|
||||
parent = context.panel
|
||||
end
|
||||
local widget = g_ui.loadUIFromString(otml, parent)
|
||||
widget.botWidget = true
|
||||
return widget
|
||||
end
|
||||
|
||||
context.importStyle = function(otml)
|
||||
if type(otml) ~= "string" then
|
||||
return error("Invalid parameter for importStyle, should be string")
|
||||
end
|
||||
if otml:find(".otui") and not otml:find("\n") then
|
||||
return g_ui.importStyle(context.configDir .. "/" .. otml)
|
||||
end
|
||||
return g_ui.importStyleFromString(otml)
|
||||
end
|
||||
|
||||
context.addTab = function(name)
|
||||
local tab = context.tabs:getTab(name)
|
||||
if tab then -- return existing tab
|
||||
return tab.tabPanel.content
|
||||
end
|
||||
|
||||
context.tabs:setOn(true)
|
||||
local newTab = context.tabs:addTab(name, g_ui.createWidget('BotPanel')).tabPanel.content
|
||||
if #(context.tabs.tabs) > 5 then
|
||||
for k,tab in pairs(context.tabs.tabs) do
|
||||
tab:setPadding(3)
|
||||
tab:setFont('small-9px')
|
||||
end
|
||||
end
|
||||
|
||||
return newTab
|
||||
end
|
||||
context.getTab = context.addTab
|
||||
|
||||
context.setDefaultTab = function(name)
|
||||
local tab = context.addTab(name)
|
||||
context.panel = tab
|
||||
end
|
||||
|
||||
context.addSwitch = function(id, text, onClickCallback, parent)
|
||||
if not parent then
|
||||
parent = context.panel
|
||||
end
|
||||
local switch = g_ui.createWidget('BotSwitch', parent)
|
||||
switch:setId(id)
|
||||
switch:setText(text)
|
||||
switch.onClick = onClickCallback
|
||||
return switch
|
||||
end
|
||||
|
||||
context.addButton = function(id, text, onClickCallback, parent)
|
||||
if not parent then
|
||||
parent = context.panel
|
||||
end
|
||||
local button = g_ui.createWidget('BotButton', parent)
|
||||
button:setId(id)
|
||||
button:setText(text)
|
||||
button.onClick = onClickCallback
|
||||
return button
|
||||
end
|
||||
|
||||
context.addLabel = function(id, text, parent)
|
||||
if not parent then
|
||||
parent = context.panel
|
||||
end
|
||||
local label = g_ui.createWidget('BotLabel', parent)
|
||||
label:setId(id)
|
||||
label:setText(text)
|
||||
return label
|
||||
end
|
||||
|
||||
context.addTextEdit = function(id, text, onTextChangeCallback, parent)
|
||||
if not parent then
|
||||
parent = context.panel
|
||||
end
|
||||
local widget = g_ui.createWidget('BotTextEdit', parent)
|
||||
widget:setId(id)
|
||||
widget.onTextChange = onTextChangeCallback
|
||||
widget:setText(text)
|
||||
return widget
|
||||
end
|
||||
|
||||
context.addSeparator = function(id, parent)
|
||||
if not parent then
|
||||
parent = context.panel
|
||||
end
|
||||
local separator = g_ui.createWidget('BotSeparator', parent)
|
||||
separator:setId(id)
|
||||
return separator
|
||||
end
|
||||
|
||||
context._addMacroSwitch = function(name, keys, parent)
|
||||
if not parent then
|
||||
parent = context.panel
|
||||
end
|
||||
local text = name
|
||||
if keys:len() > 0 then
|
||||
text = name .. " [" .. keys .. "]"
|
||||
end
|
||||
local switch = context.addSwitch("macro_" .. #context._macros, text, function(widget)
|
||||
context.storage._macros[name] = not context.storage._macros[name]
|
||||
widget:setOn(context.storage._macros[name])
|
||||
end, parent)
|
||||
switch:setOn(context.storage._macros[name])
|
||||
return switch
|
||||
end
|
||||
|
||||
context._addHotkeySwitch = function(name, keys, parent)
|
||||
if not parent then
|
||||
parent = context.panel
|
||||
end
|
||||
local text = name
|
||||
if keys:len() > 0 then
|
||||
text = name .. " [" .. keys .. "]"
|
||||
end
|
||||
local switch = context.addSwitch("hotkey_" .. #context._hotkeys, text, nil, parent)
|
||||
switch:setOn(false)
|
||||
return switch
|
||||
end
|
30
modules/game_bot/functions/ui_windows.lua
Normal file
30
modules/game_bot/functions/ui_windows.lua
Normal file
@@ -0,0 +1,30 @@
|
||||
local context = G.botContext
|
||||
if type(context.UI) ~= "table" then
|
||||
context.UI = {}
|
||||
end
|
||||
local UI = context.UI
|
||||
|
||||
UI.SinglelineEditorWindow = function(text, callback)
|
||||
return modules.game_textedit.singlelineEditor(text, callback)
|
||||
end
|
||||
|
||||
UI.MultilineEditorWindow = function(description, test, callback)
|
||||
return modules.game_textedit.multilineEditor(description, test, callback)
|
||||
end
|
||||
|
||||
UI.ConfirmationWindow = function(title, question, callback)
|
||||
local window = nil
|
||||
local onConfirm = function()
|
||||
window:destroy()
|
||||
callback()
|
||||
end
|
||||
local closeWindow = function()
|
||||
window:destroy()
|
||||
end
|
||||
window = context.displayGeneralBox(title, question, {
|
||||
{ text=tr('Yes'), callback=onConfirm },
|
||||
{ text=tr('No'), callback=closeWindow },
|
||||
anchor=AnchorHorizontalCenter}, onConfirm, closeWindow)
|
||||
window.botWidget = true
|
||||
return window
|
||||
end
|
@@ -1,8 +1,6 @@
|
||||
BotConfig < Panel
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
height: 40
|
||||
id: botConfig
|
||||
height: 45
|
||||
|
||||
ComboBox
|
||||
id: list
|
||||
@@ -31,21 +29,21 @@ BotConfig < Panel
|
||||
anchors.top: prev.bottom
|
||||
anchors.left: parent.left
|
||||
text: Add
|
||||
width: 58
|
||||
height: 17
|
||||
width: 59
|
||||
height: 20
|
||||
|
||||
Button
|
||||
id: edit
|
||||
anchors.top: prev.top
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: Edit
|
||||
width: 58
|
||||
height: 17
|
||||
width: 59
|
||||
height: 20
|
||||
|
||||
Button
|
||||
id: remove
|
||||
anchors.top: prev.top
|
||||
anchors.right: parent.right
|
||||
text: Remove
|
||||
width: 58
|
||||
height: 17
|
||||
width: 59
|
||||
height: 20
|
19
modules/game_bot/ui/container.otui
Normal file
19
modules/game_bot/ui/container.otui
Normal file
@@ -0,0 +1,19 @@
|
||||
BotContainer < Panel
|
||||
height: 68
|
||||
|
||||
ScrollablePanel
|
||||
id: items
|
||||
anchors.fill: parent
|
||||
vertical-scrollbar: scroll
|
||||
layout:
|
||||
type: grid
|
||||
cell-size: 34 34
|
||||
flow: true
|
||||
|
||||
BotSmallScrollBar
|
||||
id: scroll
|
||||
anchors.top: prev.top
|
||||
anchors.bottom: prev.bottom
|
||||
anchors.right: parent.right
|
||||
step: 10
|
||||
pixels-scroll: true
|
Reference in New Issue
Block a user