This commit is contained in:
OTCv8
2020-07-23 02:37:11 +02:00
parent a65844f182
commit 929ab400ed
19 changed files with 489 additions and 84 deletions

View File

@@ -17,6 +17,8 @@ local enableButton = nil
local executeEvent = nil
local statusLabel = nil
local configManagerUrl = "http://otclient.ovh/configs.php"
function init()
dofile("executor")
@@ -263,6 +265,13 @@ function onError(message)
end
function edit()
local configs = g_resources.listDirectoryFiles("/bot", false, false)
editWindow.manager.upload.config:clearOptions()
for i=1,#configs do
editWindow.manager.upload.config:addOption(configs[i])
end
editWindow.manager.download.config:setText("")
editWindow:show()
editWindow:focus()
editWindow:raise()
@@ -306,6 +315,102 @@ function createDefaultConfigs()
end
end
function uploadConfig()
local config = editWindow.manager.upload.config:getCurrentOption().text
local archive = compressConfig(config)
if not archive then
return displayErrorBox(tr("Config upload failed"), tr("Config %s is invalid (can't be compressed)", config))
end
if archive:len() > 64 * 1024 then
return displayErrorBox(tr("Config upload failed"), tr("Config %s is too big, maximum size is 64KB. Now it has %s KB.", config, math.floor(archive / 1024)))
end
local infoBox = displayInfoBox(tr("Uploading config"), tr("Uploading config %s. Please wait.", config))
HTTP.postJSON(configManagerUrl .. "?config=" .. config:gsub("%s+", "_"), archive, function(data, err)
if infoBox then
infoBox:destroy()
end
if err or data["error"] then
return displayErrorBox(tr("Config upload failed"), tr("Error while upload config %s:\n%s", config, err or data["error"]))
end
displayInfoBox(tr("Succesful config upload"), tr("Config %s has been uploaded.\n%s", config, data["message"]))
end)
end
function downloadConfig()
local hash = editWindow.manager.download.config:getText()
if hash:len() == 0 then
return displayErrorBox(tr("Config download error"), tr("Enter correct config hash"))
end
local infoBox = displayInfoBox(tr("Downloading config"), tr("Downloading config with hash %s. Please wait.", hash))
HTTP.download(configManagerUrl .. "?hash=" .. hash, hash .. ".zip", function(path, checksum, err)
if infoBox then
infoBox:destroy()
end
if err then
return displayErrorBox(tr("Config download error"), tr("Config with hash %s cannot be downloaded", hash))
end
modules.client_textedit.show("", {
title="Enter name for downloaded config",
description="Config with hash " .. hash .. " has been downloaded. Enter name for new config.\nWarning: if config with same name already exist, it will be overwritten!",
width=500
}, function(configName)
decompressConfig(configName, "/downloads/" .. path)
refresh()
edit()
end)
end)
end
function compressConfig(configName)
if not g_resources.directoryExists("/bot/" .. configName) then
return onError("Config " .. configName .. " doesn't exist")
end
local forArchive = {}
for _, file in ipairs(g_resources.listDirectoryFiles("/bot/" .. configName)) do
local fullPath = "/bot/" .. configName .. "/" .. file
if g_resources.fileExists(fullPath) then -- regular file
forArchive[file] = g_resources.readFileContents(fullPath)
else -- dir
for __, file2 in ipairs(g_resources.listDirectoryFiles(fullPath)) do
local fullPath2 = fullPath .. "/" .. file2
if g_resources.fileExists(fullPath2) then -- regular file
forArchive[file .. "/" .. file2] = g_resources.readFileContents(fullPath2)
end
end
end
end
return g_resources.createArchive(forArchive)
end
function decompressConfig(configName, archive)
if g_resources.directoryExists("/bot/" .. configName) then
g_resources.deleteFile("/bot/" .. configName) -- also delete dirs
end
local files = g_resources.decompressArchive(archive)
g_resources.makeDir("/bot/" .. configName)
if not g_resources.directoryExists("/bot/" .. configName) then
return onError("Can't create /bot/" .. configName .. " directory in " .. g_resources.getWriteDir())
end
for file, contents in pairs(files) do
local split = file:split("/")
split[#split] = nil -- remove file name
local dirPath = "/bot/" .. configName
for _, s in ipairs(split) do
dirPath = dirPath .. "/" .. s
if not g_resources.directoryExists(dirPath) then
g_resources.makeDir(dirPath)
if not g_resources.directoryExists(dirPath) then
return onError("Can't create " .. dirPath .. " directory in " .. g_resources.getWriteDir())
end
end
end
g_resources.writeFileContents("/bot/" .. configName .. file, contents)
end
end
-- Executor
function message(category, msg)
local widget = g_ui.createWidget('BotLabel', botMessages)

View File

@@ -1,85 +1,210 @@
MainWindow
id: editWindow
size: 550 580
!text: tr("Config editor")
!text: tr("Config editor & manager")
@onEscape: self:hide()
@onEnter: self:hide()
size: 550 570
$mobile:
size: 550 240
Label
Panel
id: manager
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
text-auto-resize: true
text-align: center
text-wrap: true
!text: tr("Bot configs are stored in:")
height: 152
Label
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
text-auto-resize: true
text-align: center
text-wrap: true
!text: tr("Config Manager\nYou can use config manager to share configs between different machines, especially smartphones. After you configure your config, you can upload it, then you'll get unique hash code which you can use on diffent machinge (for eg. mobile phone) to download it.")
HorizontalSeparator
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.right
margin-top: 3
height: 2
Panel
id: upload
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.horizontalCenter
anchors.bottom: parent.bottom
margin-top: 3
TextEdit
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: prev.bottom
height: 20
width: 400
margin-top: 5
editable: false
!text: g_resources.getWriteDir() .. "bot"
text-align: center
Label
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
text-auto-resize: true
text-align: center
text-wrap: true
!text: tr("Upload config")
Button
id: documentationButton
!text: tr('Click here to open bot directory')
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: prev.bottom
margin-top: 5
width: 250
@onClick: g_platform.openDir(g_resources.getWriteDir() .. "bot")
Label
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.right
margin-top: 7
text-auto-resize: true
text-align: center
text-wrap: true
!text: tr("Select config to upload")
Label
margin-top: 5
ComboBox
id: config
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.right
margin-top: 4
margin-left: 20
margin-right: 20
text-offset: 3 0
Button
id: submit
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.right
!text: tr('Upload config')
margin-top: 4
margin-left: 40
margin-right: 40
@onClick: modules.game_bot.uploadConfig()
Panel
id: download
anchors.top: prev.top
anchors.left: parent.horizontalCenter
anchors.right: parent.right
anchors.bottom: parent.bottom
Label
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
text-auto-resize: true
text-align: center
text-wrap: true
!text: tr("Download config")
Label
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.right
margin-top: 7
text-auto-resize: true
text-align: center
text-wrap: true
!text: tr("Enter config hash code")
TextEdit
id: config
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.right
margin-top: 4
margin-left: 20
margin-right: 20
Button
id: submit
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.right
!text: tr('Download config')
margin-top: 4
margin-left: 40
margin-right: 40
@onClick: modules.game_bot.downloadConfig()
HorizontalSeparator
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.right
text-auto-resize: true
text-align: center
text-wrap: true
!text: tr("Every directory in bot directory is treated as different config.\nTo create new config just create new directory.")
Label
margin-top: 5
anchors.top: prev.bottom
anchors.horizontalCenter: parent.horizontalCenter
height: 175
image-source: configs.png
image-fixed-ratio: true
image-size: 500 175
Label
margin-top: 5
margin-top: 3
height: 2
Panel
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.right
text-auto-resize: true
text-align: center
text-wrap: true
!text: tr("Inside config directory put .lua and .otui files.\nEvery file will be loaded and executed in alphabetical order, .otui first and then .lua.")
Label
anchors.right: parent.right
margin-top: 5
anchors.top: prev.bottom
anchors.horizontalCenter: parent.horizontalCenter
height: 150
image-source: scripts.png
image-fixed-ratio: true
image-size: 500 150
height: 330
$mobile:
visible: false
Label
margin-top: 5
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.right
text-auto-resize: true
text-align: center
text-wrap: true
!text: tr("To reload configs just press On and Off in bot window.\nTo learn more about bot click Tutorials button.")
Label
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
text-auto-resize: true
text-align: center
text-wrap: true
!text: tr("Bot configs are stored in:")
TextEdit
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: prev.bottom
height: 20
width: 400
margin-top: 5
editable: false
!text: g_resources.getWriteDir() .. "bot"
text-align: center
Button
id: documentationButton
!text: tr('Click here to open bot directory')
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: prev.bottom
margin-top: 5
width: 250
@onClick: g_platform.openDir(g_resources.getWriteDir() .. "bot")
Label
margin-top: 5
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.right
text-auto-resize: true
text-align: center
text-wrap: true
!text: tr("Every directory in bot directory is treated as different config.\nTo create new config just create new directory.")
Label
margin-top: 5
anchors.top: prev.bottom
anchors.horizontalCenter: parent.horizontalCenter
height: 175
image-source: configs.png
image-fixed-ratio: true
image-size: 500 175
Label
margin-top: 3
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.right
text-auto-resize: true
text-align: center
text-wrap: true
!text: tr("Inside config directory put .lua and .otui files.\nEvery file will be loaded and executed in alphabetical order, .otui first and then .lua.")
Label
margin-top: 3
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.right
text-auto-resize: true
text-align: center
text-wrap: true
!text: tr("To reload configs just press On and Off in bot window.\nTo learn more about bot click Tutorials button.")
Button
!text: tr('Documentation')

View File

@@ -86,17 +86,22 @@ function executeBot(config, storage, tabs, msgCallback, saveConfigCallback, relo
context.getDistanceBetween = function(p1, p2)
return math.max(math.abs(p1.x - p2.x), math.abs(p1.y - p2.y))
end
context.isMobile = g_app.isMobile
context.getVersion = g_app.getVersion
-- classes
context.g_resources = g_resources
context.g_game = g_game
context.g_map = g_map
context.g_ui = g_ui
context.g_platform = g_platform
context.g_sounds = g_sounds
context.g_window = g_window
context.g_mouse = g_mouse
context.g_things = g_things
context.g_platform = {
openUrl = g_platform.openUrl,
openDir = g_platform.openDir,
}
context.Item = Item
context.Creature = Creature

View File

@@ -8,17 +8,25 @@ context.zoomOut = function() modules.game_interface.getMapPanel():zoomOut() end
context.getSpectators = function(param1, param2)
--[[
if param1 is table (position) then it's used for central position, then param2 is used as param1
if param1 is creature, then creature position and direction of creature is used, then param2 is used as param1
if param1 is true/false then it's used for multifloor, example: getSpectators(true)
if param1 is string then it's used for getSpectatorsByPattern
]]--
local pos = context.player:getPosition()
local direction = context.player:getDirection()
if type(param1) == 'table' then
pos = param1
direction = 8 -- invalid direction
param1 = param2
end
if type(param1) == 'userdata' then
pos = param1:getPosition()
direction = param1:getDirection()
param1 = param2
end
if type(param1) == 'string' then
return g_map.getSpectatorsByPattern(pos, param1)
return g_map.getSpectatorsByPattern(pos, param1, direction)
end
local multifloor = false
@@ -221,4 +229,13 @@ end
context.getTileUnderCursor = function()
if not modules.game_interface.gameMapPanel.mousePos then return end
return modules.game_interface.gameMapPanel:getTile(modules.game_interface.gameMapPanel.mousePos)
end
context.canShoot = function(pos, distance)
if not distance then distance = 5 end
local tile = g_map.getTile(pos, distance)
if tile then
return tile:canShoot(distance)
end
return false
end