mirror of
https://github.com/OTCv8/otclientv8.git
synced 2025-10-21 23:15:54 +02:00
Version 1.7
This commit is contained in:
@@ -1,86 +1,37 @@
|
||||
botWindow = nil
|
||||
botButton = nil
|
||||
botConfigFile = nil
|
||||
botConfig = nil
|
||||
contentsPanel = nil
|
||||
configWindow = nil
|
||||
configEditorText = nil
|
||||
configList = nil
|
||||
botTabs = nil
|
||||
botPanel = nil
|
||||
editWindow = nil
|
||||
|
||||
local checkEvent = nil
|
||||
|
||||
local botStorage = {}
|
||||
local botStorageFile = nil
|
||||
local botWebSockets = {}
|
||||
local botMessages = nil
|
||||
local configCopy = ""
|
||||
local botTabs = nil
|
||||
local botExecutor = nil
|
||||
|
||||
local configList = nil
|
||||
local enableButton = nil
|
||||
local executeEvent = nil
|
||||
local checkMsgsEvent = nil
|
||||
local errorOccured = false
|
||||
local statusLabel = nil
|
||||
local compiledConfig = nil
|
||||
local configTab = nil
|
||||
local tabs = {"main", "panels", "macros", "hotkeys", "callbacks", "other"}
|
||||
local mainTab = nil
|
||||
local activeTab = nil
|
||||
local editorText = {"", ""}
|
||||
|
||||
function init()
|
||||
dofile("defaultconfig")
|
||||
dofile("executor")
|
||||
|
||||
g_ui.importStyle("ui/basic.otui")
|
||||
g_ui.importStyle("ui/panels.otui")
|
||||
g_ui.importStyle("ui/config.otui")
|
||||
|
||||
connect(g_game, {
|
||||
onGameStart = online,
|
||||
onGameEnd = offline,
|
||||
onTalk = botOnTalk,
|
||||
onTextMessage = botOnTextMessage,
|
||||
onUse = botOnUse,
|
||||
onUseWith = botOnUseWith,
|
||||
onChannelList = botChannelList,
|
||||
onOpenChannel = botOpenChannel,
|
||||
onCloseChannel = botCloseChannel,
|
||||
onChannelEvent = botChannelEvent
|
||||
})
|
||||
|
||||
connect(rootWidget, { onKeyDown = botKeyDown,
|
||||
onKeyUp = botKeyUp,
|
||||
onKeyPress = botKeyPress })
|
||||
|
||||
connect(Tile, { onAddThing = botAddThing, onRemoveThing = botRemoveThing })
|
||||
|
||||
connect(Creature, {
|
||||
onAppear = botCreatureAppear,
|
||||
onDisappear = botCreatureDisappear,
|
||||
onPositionChange = botCreaturePositionChange,
|
||||
onHealthPercentChange = botCraetureHealthPercentChange
|
||||
})
|
||||
connect(LocalPlayer, {
|
||||
onPositionChange = botCreaturePositionChange,
|
||||
onHealthPercentChange = botCraetureHealthPercentChange
|
||||
})
|
||||
connect(Container, { onOpen = botContainerOpen,
|
||||
onClose = botContainerClose,
|
||||
onUpdateItem = botContainerUpdateItem })
|
||||
connect(g_map, { onMissle = botOnMissle })
|
||||
|
||||
botConfigFile = g_configs.create("/bot.otml")
|
||||
local config = botConfigFile:get("config")
|
||||
if config ~= nil and config:len() > 10 then
|
||||
local status, result = pcall(function() return json.decode(config) end)
|
||||
if not status then
|
||||
g_logger.error("Error: bot config parse error: " .. result .. "\n" .. config)
|
||||
end
|
||||
botConfig = result
|
||||
else
|
||||
botConfig = botDefaultConfig
|
||||
end
|
||||
initCallbacks()
|
||||
|
||||
botConfig.configs[1].name = botDefaultConfig.configs[1].name
|
||||
botConfig.configs[1].script = botDefaultConfig.configs[1].script
|
||||
|
||||
botButton = modules.client_topmenu.addRightGameToggleButton('botButton',
|
||||
tr('Bot'), '/images/topbuttons/bot', toggle)
|
||||
botButton = modules.client_topmenu.addRightGameToggleButton('botButton', tr('Bot'), '/images/topbuttons/bot', toggle)
|
||||
botButton:setOn(false)
|
||||
botButton:hide()
|
||||
|
||||
@@ -93,107 +44,188 @@ function init()
|
||||
statusLabel = contentsPanel.statusLabel
|
||||
botMessages = contentsPanel.messages
|
||||
botTabs = contentsPanel.botTabs
|
||||
botPanel = contentsPanel.botPanel
|
||||
botTabs:setContentWidget(botPanel)
|
||||
|
||||
configWindow = g_ui.displayUI('config')
|
||||
configWindow:hide()
|
||||
|
||||
configEditorText = configWindow.text
|
||||
configTab = configWindow.configTab
|
||||
|
||||
configTab.onTabChange = editorTabChanged
|
||||
|
||||
for i=1,#botConfig.configs do
|
||||
if botConfig.configs[i].name ~= nil then
|
||||
configList:addOption(botConfig.configs[i].name)
|
||||
else
|
||||
configList:addOption("Config #" .. i)
|
||||
end
|
||||
end
|
||||
if type(botConfig.selectedConfig) == 'number' then
|
||||
configList:setCurrentIndex(botConfig.selectedConfig)
|
||||
end
|
||||
configList.onOptionChange = modules.game_bot.refreshConfig
|
||||
|
||||
mainTab = configTab:addTab("all")
|
||||
for k, v in ipairs(tabs) do
|
||||
configTab:addTab(v, nil, nil)
|
||||
end
|
||||
botTabs:setContentWidget(contentsPanel.botPanel)
|
||||
|
||||
editWindow = g_ui.displayUI('edit')
|
||||
editWindow:hide()
|
||||
|
||||
if g_game.isOnline() then
|
||||
clear()
|
||||
online()
|
||||
end
|
||||
end
|
||||
|
||||
function saveConfig()
|
||||
local status, result = pcall(function()
|
||||
botConfigFile:set("config", json.encode(botConfig))
|
||||
botConfigFile:save()
|
||||
end)
|
||||
if not status then
|
||||
errorOccured = true
|
||||
-- try to fix it
|
||||
local extraInfo = ""
|
||||
for i = 1, #botConfig.configs do
|
||||
if botConfig.configs[i].storage then
|
||||
local status, result = pcall(function() json.encode(botConfig.configs[i].storage) end)
|
||||
if not status then
|
||||
botConfig.configs[i].storage = nil
|
||||
extraInfo = extraInfo .. "\nLocal storage of config " .. i .. " has been erased due to invalid data"
|
||||
end
|
||||
end
|
||||
end
|
||||
statusLabel:setText("Error while saving config and user storage:\n" .. result .. extraInfo .. "\n\n" .. "Try to restart bot")
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function terminate()
|
||||
saveConfig()
|
||||
clearConfig()
|
||||
|
||||
disconnect(rootWidget, { onKeyDown = botKeyDown,
|
||||
onKeyUp = botKeyUp,
|
||||
onKeyPress = botKeyPress })
|
||||
save()
|
||||
clear()
|
||||
|
||||
disconnect(g_game, {
|
||||
onGameStart = online,
|
||||
onGameEnd = offline,
|
||||
onTalk = botOnTalk,
|
||||
onTextMessage = botOnTextMessage,
|
||||
onUse = botOnUse,
|
||||
onUseWith = botOnUseWith,
|
||||
onChannelList = botChannelList,
|
||||
onOpenChannel = botOpenChannel,
|
||||
onCloseChannel = botCloseChannel,
|
||||
onChannelEvent = botChannelEvent
|
||||
})
|
||||
|
||||
disconnect(Tile, { onAddThing = botAddThing, onRemoveThing = botRemoveThing })
|
||||
terminateCallbacks()
|
||||
|
||||
disconnect(Creature, {
|
||||
onAppear = botCreatureAppear,
|
||||
onDisappear =botCreatureDisappear,
|
||||
onPositionChange = botCreaturePositionChange,
|
||||
onHealthPercentChange = botCraetureHealthPercentChange
|
||||
})
|
||||
disconnect(LocalPlayer, {
|
||||
onPositionChange = botCreaturePositionChange,
|
||||
onHealthPercentChange = botCraetureHealthPercentChange
|
||||
})
|
||||
disconnect(Container, { onOpen = botContainerOpen,
|
||||
onClose = botContainerClose,
|
||||
onUpdateItem = botContainerUpdateItem })
|
||||
disconnect(g_map, { onMissle = botOnMissle })
|
||||
removeEvent(checkEvent)
|
||||
|
||||
removeEvent(executeEvent)
|
||||
removeEvent(checkMsgsEvent)
|
||||
editWindow:destroy()
|
||||
|
||||
botWindow:destroy()
|
||||
botButton:destroy()
|
||||
configWindow:destroy()
|
||||
botButton:destroy()
|
||||
end
|
||||
|
||||
function clear()
|
||||
botExecutor = nil
|
||||
removeEvent(checkEvent)
|
||||
|
||||
-- optimization, callback is not used when not needed
|
||||
g_game.enableTileThingLuaCallback(false)
|
||||
|
||||
botTabs:clearTabs()
|
||||
botTabs:setOn(false)
|
||||
|
||||
botMessages:destroyChildren()
|
||||
botMessages:updateLayout()
|
||||
|
||||
for i, socket in pairs(botWebSockets) do
|
||||
g_http.cancel(socket)
|
||||
end
|
||||
botWebSockets = {}
|
||||
|
||||
for i, widget in pairs(g_ui.getRootWidget():getChildren()) do
|
||||
if widget.botWidget then
|
||||
widget:destroy()
|
||||
end
|
||||
end
|
||||
|
||||
local gameMapPanel = modules.game_interface.getMapPanel()
|
||||
if gameMapPanel then
|
||||
gameMapPanel:unlockVisibleFloor()
|
||||
end
|
||||
|
||||
if g_sounds then
|
||||
g_sounds.getChannel(SoundChannels.Bot):stop()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function refresh()
|
||||
save()
|
||||
clear()
|
||||
|
||||
-- create bot dir
|
||||
if not g_resources.directoryExists("/bot") then
|
||||
g_resources.makeDir("/bot")
|
||||
if not g_resources.directoryExists("/bot") then
|
||||
return onError("Can't create bot directory in " .. g_resources.getWriteDir())
|
||||
end
|
||||
end
|
||||
|
||||
-- get list of configs
|
||||
local configs = g_resources.listDirectoryFiles("/bot", false, false)
|
||||
if #configs == 0 then
|
||||
createDefaultConfig()
|
||||
configs = g_resources.listDirectoryFiles("/bot", false, false)
|
||||
end
|
||||
|
||||
-- clean
|
||||
configList.onOptionChange = nil
|
||||
enableButton.onClick = nil
|
||||
configList:clearOptions()
|
||||
|
||||
-- select active config based on settings
|
||||
local settings = g_settings.getNode('bot') or {}
|
||||
local index = g_game.getCharacterName() .. "_" .. g_game.getClientVersion()
|
||||
if settings[index] == nil then
|
||||
settings[index] = {
|
||||
enabled=false,
|
||||
config=""
|
||||
}
|
||||
end
|
||||
|
||||
-- init list and buttons
|
||||
for i=1,#configs do
|
||||
configList:addOption(configs[i])
|
||||
end
|
||||
configList:setCurrentOption(settings[index].config)
|
||||
if configList:getCurrentOption().text ~= settings[index].config then
|
||||
settings[index].enabled = false
|
||||
end
|
||||
|
||||
enableButton:setOn(settings[index].enabled)
|
||||
|
||||
configList.onOptionChange = function(widget)
|
||||
settings[index].config = widget:getCurrentOption().text
|
||||
settings[index].enabled = false
|
||||
g_settings.setNode('bot', settings)
|
||||
g_settings.save()
|
||||
refresh()
|
||||
end
|
||||
|
||||
enableButton.onClick = function(widget)
|
||||
settings[index].enabled = not settings[index].enabled
|
||||
g_settings.setNode('bot', settings)
|
||||
g_settings.save()
|
||||
refresh()
|
||||
end
|
||||
|
||||
if not g_game.isOnline() or not settings[index].enabled then
|
||||
statusLabel:setOn(true)
|
||||
statusLabel:setText("Status: disabled")
|
||||
return
|
||||
end
|
||||
|
||||
local configName = settings[index].config
|
||||
|
||||
-- storage
|
||||
botStorage = {}
|
||||
botStorageFile = "/bot/" .. configName .. "/storage.json"
|
||||
if g_resources.fileExists(botStorageFile) then
|
||||
local status, result = pcall(function()
|
||||
return json.decode(g_resources.readFileContents(botStorageFile))
|
||||
end)
|
||||
if not status then
|
||||
return onError("Error while reading storage (" .. botStorageFile .. "). To fix this problem you can delete storage.json. Details: " .. result)
|
||||
end
|
||||
botStorage = result
|
||||
end
|
||||
|
||||
-- run script
|
||||
local status, result = pcall(function()
|
||||
return executeBot(configName, botStorage, botTabs, message, save, botWebSockets) end
|
||||
)
|
||||
if not status then
|
||||
return onError(result)
|
||||
end
|
||||
|
||||
statusLabel:setOn(false)
|
||||
botExecutor = result
|
||||
check()
|
||||
end
|
||||
|
||||
function save()
|
||||
if not botExecutor then
|
||||
return
|
||||
end
|
||||
|
||||
local settings = g_settings.getNode('bot') or {}
|
||||
local index = g_game.getCharacterName() .. "_" .. g_game.getClientVersion()
|
||||
if settings[index] == nil then
|
||||
return
|
||||
end
|
||||
|
||||
local status, result = pcall(function()
|
||||
return json.encode(botStorage)
|
||||
end)
|
||||
if not status then
|
||||
return onError("Error while saving bot storage. Storage won't be saved. Details: " .. result)
|
||||
end
|
||||
|
||||
if result:len() > 100 * 1024 * 1024 then
|
||||
return onError("Storage file is too big, above 100MB, it won't be saved")
|
||||
end
|
||||
|
||||
g_resources.writeFileContents(botStorageFile, result)
|
||||
end
|
||||
|
||||
function onMiniWindowClose()
|
||||
@@ -212,228 +244,63 @@ end
|
||||
|
||||
function online()
|
||||
botButton:show()
|
||||
updateEnabled()
|
||||
if botConfig.enabled then
|
||||
scheduleEvent(refreshConfig, 20)
|
||||
else
|
||||
clearConfig()
|
||||
end
|
||||
if executeEvent == nil then
|
||||
executeEvent = scheduleEvent(executeConfig, 200)
|
||||
checkMsgsEvent = scheduleEvent(checkMsgs, 200)
|
||||
end
|
||||
scheduleEvent(refresh, 20)
|
||||
end
|
||||
|
||||
function offline()
|
||||
save()
|
||||
clear()
|
||||
botButton:hide()
|
||||
configWindow:hide()
|
||||
clearConfig()
|
||||
removeEvent(executeEvent)
|
||||
removeEvent(checkMsgsEvent)
|
||||
executeEvent = nil
|
||||
checkMsgsEvent = nil
|
||||
editWindow:hide()
|
||||
end
|
||||
|
||||
function toggleBot()
|
||||
botConfig.enabled = not botConfig.enabled
|
||||
if botConfig.enabled then
|
||||
refreshConfig()
|
||||
else
|
||||
clearConfig()
|
||||
end
|
||||
updateEnabled()
|
||||
function onError(message)
|
||||
statusLabel:setOn(true)
|
||||
statusLabel:setText("Error:\n" .. message)
|
||||
g_logger.error("[BOT] " .. message)
|
||||
end
|
||||
|
||||
function updateEnabled()
|
||||
if botConfig.enabled then
|
||||
enableButton:setText(tr('On'))
|
||||
enableButton:setColor('#00AA00FF')
|
||||
else
|
||||
enableButton:setText(tr('Off'))
|
||||
enableButton:setColor('#FF0000FF')
|
||||
statusLabel:setText(tr("Status: disabled"))
|
||||
end
|
||||
errorOccured = false
|
||||
function edit()
|
||||
editWindow:show()
|
||||
editWindow:focus()
|
||||
editWindow:raise()
|
||||
end
|
||||
|
||||
function editConfig()
|
||||
local config = configList.currentIndex
|
||||
configWindow:show()
|
||||
configWindow:raise()
|
||||
configWindow:focus()
|
||||
editorText = {botConfig.configs[config].script or "", ""}
|
||||
if #editorText[1] <= 2 then
|
||||
editorText[1] = "--config name\n\n"
|
||||
for k, v in ipairs(tabs) do
|
||||
editorText[1] = editorText[1] .. "--#" .. v .. "\n\n"
|
||||
end
|
||||
end
|
||||
configEditorText:setText(editorText[1])
|
||||
configEditorText:setEditable(true)
|
||||
activeTab = mainTab
|
||||
configTab:selectTab(mainTab)
|
||||
end
|
||||
|
||||
local function split2(str, delimiter)
|
||||
local result = { }
|
||||
local from = 1
|
||||
local delim_from, delim_to = string.find( str, delimiter, from, true)
|
||||
if delim_from then
|
||||
table.insert( result, string.sub( str, from , delim_from - 1 ) )
|
||||
from = delim_to + 1
|
||||
delim_from, delim_to = string.find( str, delimiter, from )
|
||||
table.insert( result, string.sub( str, from ) )
|
||||
else
|
||||
table.insert(result, str)
|
||||
table.insert(result, "")
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
function restoreMainTab()
|
||||
if activeTab == mainTab then
|
||||
editorText = {configEditorText:getText(), ""}
|
||||
return
|
||||
end
|
||||
local currentText = configEditorText:getText()
|
||||
if #currentText > 0 and currentText:sub(#currentText, #currentText) ~= '\n' then
|
||||
currentText = currentText .. '\n'
|
||||
end
|
||||
editorText = {editorText[1] .. "--#" .. activeTab:getText():lower() .. "\n" .. currentText .. editorText[2], ""}
|
||||
configEditorText:setText(editorText[1])
|
||||
end
|
||||
|
||||
function editorTabChanged(holder, tab)
|
||||
if activeTab == tab then
|
||||
return
|
||||
end
|
||||
restoreMainTab()
|
||||
activeTab = tab
|
||||
if tab == mainTab then
|
||||
return
|
||||
end
|
||||
|
||||
local splitted = split2(editorText[1], "--#" .. activeTab:getText():lower() .. "\n")
|
||||
local splitted2 = split2(splitted[2], "--#")
|
||||
if splitted2[2]:len() > 1 then
|
||||
splitted2[2] = "--#" .. splitted2[2]
|
||||
end
|
||||
editorText = {splitted[1], splitted2[2]}
|
||||
configEditorText:setText(splitted2[1])
|
||||
end
|
||||
|
||||
function saveEditedConfig()
|
||||
restoreMainTab()
|
||||
local config = configList.currentIndex
|
||||
local text = configEditorText:getText()
|
||||
configWindow:hide()
|
||||
botConfig.configs[config].script = text
|
||||
if text:len() > 3 and text:sub(1,2) == '--' and text:sub(3,3) ~= '#' then
|
||||
local delim_from, delim_to = string.find( text, "\n", 3, true)
|
||||
if delim_from then
|
||||
botConfig.configs[config].name = string.sub( text, 3 , delim_from - 1 ):trim()
|
||||
configList:updateCurrentOption(botConfig.configs[config].name)
|
||||
end
|
||||
end
|
||||
refreshConfig()
|
||||
end
|
||||
|
||||
function clearConfig()
|
||||
compiledConfig = nil
|
||||
|
||||
botTabs:clearTabs()
|
||||
botTabs:setOn(false)
|
||||
|
||||
botMessages:destroyChildren()
|
||||
botMessages:updateLayout()
|
||||
|
||||
for socket in pairs(botWebSockets) do
|
||||
g_http.cancel(socket)
|
||||
botWebSockets[socket] = nil
|
||||
end
|
||||
|
||||
for i, widget in pairs(g_ui.getRootWidget():getChildren()) do
|
||||
if widget.botWidget then
|
||||
widget:destroy()
|
||||
function createDefaultConfig()
|
||||
if not g_resources.directoryExists("/bot/default_config") then
|
||||
g_resources.makeDir("/bot/default_config")
|
||||
if not g_resources.directoryExists("/bot/default_config") then
|
||||
return onError("Can't create default_config directory in " .. g_resources.getWriteDir())
|
||||
end
|
||||
end
|
||||
local gameMapPanel = modules.game_interface.getMapPanel()
|
||||
if gameMapPanel then
|
||||
gameMapPanel:unlockVisibleFloor()
|
||||
end
|
||||
if g_sounds then
|
||||
local botSoundChannel = g_sounds.getChannel(SoundChannels.Bot)
|
||||
botSoundChannel:stop()
|
||||
end
|
||||
end
|
||||
|
||||
function refreshConfig()
|
||||
configWindow:hide()
|
||||
|
||||
botConfig.selectedConfig = configList.currentIndex
|
||||
if not botConfig.enabled then
|
||||
return
|
||||
end
|
||||
|
||||
if not saveConfig() then
|
||||
clearConfig()
|
||||
return
|
||||
end
|
||||
|
||||
clearConfig()
|
||||
|
||||
local config = botConfig.configs[configList.currentIndex]
|
||||
if not config.storage then
|
||||
config.storage = {}
|
||||
end
|
||||
if config.script == nil or config.script:len() < 5 then
|
||||
errorOccured = true
|
||||
statusLabel:setText(tr("Error: empty config"))
|
||||
return
|
||||
end
|
||||
errorOccured = false
|
||||
g_game.enableTileThingLuaCallback(false)
|
||||
local status, result = pcall(function() return executeBot(config.script, config.storage, botTabs, botMsgCallback, saveConfig, botWebSockets) end)
|
||||
if not status then
|
||||
errorOccured = true
|
||||
statusLabel:setText("Error: " .. tostring(result))
|
||||
return
|
||||
end
|
||||
compiledConfig = result
|
||||
statusLabel:setText(tr("Status: working"))
|
||||
end
|
||||
|
||||
function executeConfig()
|
||||
executeEvent = scheduleEvent(executeConfig, 25)
|
||||
if compiledConfig == nil then
|
||||
return
|
||||
end
|
||||
if not botConfig.enabled or errorOccured then
|
||||
if not errorOccured then
|
||||
statusLabel:setText(tr("Status: disabled"))
|
||||
local defaultConfigFiles = g_resources.listDirectoryFiles("default_config", true, false)
|
||||
for i, file in ipairs(defaultConfigFiles) do
|
||||
local baseName = file:split("/")
|
||||
baseName = baseName[#baseName]
|
||||
local contents = g_resources.readFileContents(file)
|
||||
if contents:len() > 0 then
|
||||
g_resources.writeFileContents("/bot/default_config/" .. baseName, contents)
|
||||
end
|
||||
return
|
||||
end
|
||||
local status, result = pcall(function() return compiledConfig.script() end)
|
||||
if not status then
|
||||
errorOccured = true
|
||||
statusLabel:setText("Error: " .. result)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
function botMsgCallback(category, msg)
|
||||
-- Executor
|
||||
function message(category, msg)
|
||||
local widget = g_ui.createWidget('BotLabel', botMessages)
|
||||
widget.added = g_clock.millis()
|
||||
if category == 'error' then
|
||||
widget:setText(msg)
|
||||
widget:setColor("red")
|
||||
g_logger.error("[BOT] " .. msg)
|
||||
elseif category == 'warn' then
|
||||
widget:setText(msg)
|
||||
widget:setColor("yellow")
|
||||
g_logger.warning("[BOT] " .. msg)
|
||||
elseif category == 'info' then
|
||||
widget:setText(msg)
|
||||
widget:setColor("white")
|
||||
g_logger.info("[BOT] " .. msg)
|
||||
end
|
||||
|
||||
if botMessages:getChildCount() > 5 then
|
||||
@@ -441,132 +308,233 @@ function botMsgCallback(category, msg)
|
||||
end
|
||||
end
|
||||
|
||||
function checkMsgs()
|
||||
checkMsgsEvent = scheduleEvent(checkMsgs, 200)
|
||||
function check()
|
||||
removeEvent(checkEvent)
|
||||
if not botExecutor then
|
||||
return
|
||||
end
|
||||
|
||||
checkEvent = scheduleEvent(check, 25)
|
||||
|
||||
local status, result = pcall(function()
|
||||
return botExecutor.script()
|
||||
end)
|
||||
if not status then
|
||||
botExecutor = nil -- critical
|
||||
return onError(result)
|
||||
end
|
||||
|
||||
-- remove old messages
|
||||
local widget = botMessages:getFirstChild()
|
||||
if widget and widget.added + 5000 < g_clock.millis() then
|
||||
widget:destroy()
|
||||
end
|
||||
end
|
||||
|
||||
-- Callbacks
|
||||
function initCallbacks()
|
||||
connect(rootWidget, {
|
||||
onKeyDown = botKeyDown,
|
||||
onKeyUp = botKeyUp,
|
||||
onKeyPress = botKeyPress
|
||||
})
|
||||
|
||||
connect(g_game, {
|
||||
onTalk = botOnTalk,
|
||||
onTextMessage = botOnTextMessage,
|
||||
onUse = botOnUse,
|
||||
onUseWith = botOnUseWith,
|
||||
onChannelList = botChannelList,
|
||||
onOpenChannel = botOpenChannel,
|
||||
onCloseChannel = botCloseChannel,
|
||||
onChannelEvent = botChannelEvent
|
||||
})
|
||||
|
||||
connect(Tile, {
|
||||
onAddThing = botAddThing,
|
||||
onRemoveThing = botRemoveThing
|
||||
})
|
||||
|
||||
connect(Creature, {
|
||||
onAppear = botCreatureAppear,
|
||||
onDisappear = botCreatureDisappear,
|
||||
onPositionChange = botCreaturePositionChange,
|
||||
onHealthPercentChange = botCraetureHealthPercentChange
|
||||
})
|
||||
|
||||
connect(LocalPlayer, {
|
||||
onPositionChange = botCreaturePositionChange,
|
||||
onHealthPercentChange = botCraetureHealthPercentChange
|
||||
})
|
||||
|
||||
connect(Container, {
|
||||
onOpen = botContainerOpen,
|
||||
onClose = botContainerClose,
|
||||
onUpdateItem = botContainerUpdateItem
|
||||
})
|
||||
|
||||
connect(g_map, {
|
||||
onMissle = botOnMissle
|
||||
})
|
||||
end
|
||||
|
||||
function terminateCallbacks()
|
||||
disconnect(rootWidget, {
|
||||
onKeyDown = botKeyDown,
|
||||
onKeyUp = botKeyUp,
|
||||
onKeyPress = botKeyPress
|
||||
})
|
||||
|
||||
disconnect(g_game, {
|
||||
onTalk = botOnTalk,
|
||||
onTextMessage = botOnTextMessage,
|
||||
onUse = botOnUse,
|
||||
onUseWith = botOnUseWith,
|
||||
onChannelList = botChannelList,
|
||||
onOpenChannel = botOpenChannel,
|
||||
onCloseChannel = botCloseChannel,
|
||||
onChannelEvent = botChannelEvent
|
||||
})
|
||||
|
||||
disconnect(Tile, {
|
||||
onAddThing = botAddThing,
|
||||
onRemoveThing = botRemoveThing
|
||||
})
|
||||
|
||||
disconnect(Creature, {
|
||||
onAppear = botCreatureAppear,
|
||||
onDisappear = botCreatureDisappear,
|
||||
onPositionChange = botCreaturePositionChange,
|
||||
onHealthPercentChange = botCraetureHealthPercentChange
|
||||
})
|
||||
|
||||
disconnect(LocalPlayer, {
|
||||
onPositionChange = botCreaturePositionChange,
|
||||
onHealthPercentChange = botCraetureHealthPercentChange
|
||||
})
|
||||
|
||||
disconnect(Container, {
|
||||
onOpen = botContainerOpen,
|
||||
onClose = botContainerClose,
|
||||
onUpdateItem = botContainerUpdateItem
|
||||
})
|
||||
|
||||
disconnect(g_map, {
|
||||
onMissle = botOnMissle
|
||||
})
|
||||
end
|
||||
|
||||
function safeBotCall(func)
|
||||
local status, result = pcall(func)
|
||||
if not status then
|
||||
errorOccured = true
|
||||
statusLabel:setText("Error: " .. result)
|
||||
onError(result)
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function botKeyDown(widget, keyCode, keyboardModifiers)
|
||||
if compiledConfig == nil then return false end
|
||||
if botExecutor == nil then return false end
|
||||
if keyCode == KeyUnknown then return end
|
||||
safeBotCall(function() compiledConfig.callbacks.onKeyDown(keyCode, keyboardModifiers) end)
|
||||
safeBotCall(function() botExecutor.callbacks.onKeyDown(keyCode, keyboardModifiers) end)
|
||||
end
|
||||
|
||||
function botKeyUp(widget, keyCode, keyboardModifiers)
|
||||
if compiledConfig == nil then return false end
|
||||
if botExecutor == nil then return false end
|
||||
if keyCode == KeyUnknown then return end
|
||||
safeBotCall(function() compiledConfig.callbacks.onKeyUp(keyCode, keyboardModifiers) end)
|
||||
safeBotCall(function() botExecutor.callbacks.onKeyUp(keyCode, keyboardModifiers) end)
|
||||
end
|
||||
|
||||
function botKeyPress(widget, keyCode, keyboardModifiers, autoRepeatTicks)
|
||||
if compiledConfig == nil then return false end
|
||||
if botExecutor == nil then return false end
|
||||
if keyCode == KeyUnknown then return end
|
||||
safeBotCall(function() compiledConfig.callbacks.onKeyPress(keyCode, keyboardModifiers, autoRepeatTicks) end)
|
||||
safeBotCall(function() botExecutor.callbacks.onKeyPress(keyCode, keyboardModifiers, autoRepeatTicks) end)
|
||||
end
|
||||
|
||||
function botOnTalk(name, level, mode, text, channelId, pos)
|
||||
if compiledConfig == nil then return false end
|
||||
safeBotCall(function() compiledConfig.callbacks.onTalk(name, level, mode, text, channelId, pos) end)
|
||||
if botExecutor == nil then return false end
|
||||
safeBotCall(function() botExecutor.callbacks.onTalk(name, level, mode, text, channelId, pos) end)
|
||||
end
|
||||
|
||||
function botOnTextMessage(mode, text)
|
||||
if compiledConfig == nil then return false end
|
||||
safeBotCall(function() compiledConfig.callbacks.onTextMessage(mode, text) end)
|
||||
if botExecutor == nil then return false end
|
||||
safeBotCall(function() botExecutor.callbacks.onTextMessage(mode, text) end)
|
||||
end
|
||||
|
||||
function botAddThing(tile, thing)
|
||||
if compiledConfig == nil then return false end
|
||||
safeBotCall(function() compiledConfig.callbacks.onAddThing(tile, thing) end)
|
||||
if botExecutor == nil then return false end
|
||||
safeBotCall(function() botExecutor.callbacks.onAddThing(tile, thing) end)
|
||||
end
|
||||
|
||||
function botRemoveThing(tile, thing)
|
||||
if compiledConfig == nil then return false end
|
||||
safeBotCall(function() compiledConfig.callbacks.onRemoveThing(tile, thing) end)
|
||||
if botExecutor == nil then return false end
|
||||
safeBotCall(function() botExecutor.callbacks.onRemoveThing(tile, thing) end)
|
||||
end
|
||||
|
||||
function botCreatureAppear(creature)
|
||||
if compiledConfig == nil then return false end
|
||||
safeBotCall(function() compiledConfig.callbacks.onCreatureAppear(creature) end)
|
||||
if botExecutor == nil then return false end
|
||||
safeBotCall(function() botExecutor.callbacks.onCreatureAppear(creature) end)
|
||||
end
|
||||
|
||||
function botCreatureDisappear(creature)
|
||||
if compiledConfig == nil then return false end
|
||||
safeBotCall(function() compiledConfig.callbacks.onCreatureDisappear(creature) end)
|
||||
if botExecutor == nil then return false end
|
||||
safeBotCall(function() botExecutor.callbacks.onCreatureDisappear(creature) end)
|
||||
end
|
||||
|
||||
function botCreaturePositionChange(creature, newPos, oldPos)
|
||||
if compiledConfig == nil then return false end
|
||||
safeBotCall(function() compiledConfig.callbacks.onCreaturePositionChange(creature, newPos, oldPos) end)
|
||||
if botExecutor == nil then return false end
|
||||
safeBotCall(function() botExecutor.callbacks.onCreaturePositionChange(creature, newPos, oldPos) end)
|
||||
end
|
||||
|
||||
function botCraetureHealthPercentChange(creature, healthPercent)
|
||||
if compiledConfig == nil then return false end
|
||||
safeBotCall(function() compiledConfig.callbacks.onCreatureHealthPercentChange(creature, healthPercent) end)
|
||||
if botExecutor == nil then return false end
|
||||
safeBotCall(function() botExecutor.callbacks.onCreatureHealthPercentChange(creature, healthPercent) end)
|
||||
end
|
||||
|
||||
function botOnUse(pos, itemId, stackPos, subType)
|
||||
if compiledConfig == nil then return false end
|
||||
safeBotCall(function() compiledConfig.callbacks.onUse(pos, itemId, stackPos, subType) end)
|
||||
if botExecutor == nil then return false end
|
||||
safeBotCall(function() botExecutor.callbacks.onUse(pos, itemId, stackPos, subType) end)
|
||||
end
|
||||
|
||||
function botOnUseWith(pos, itemId, target, subType)
|
||||
if compiledConfig == nil then return false end
|
||||
safeBotCall(function() compiledConfig.callbacks.onUseWith(pos, itemId, target, subType) end)
|
||||
if botExecutor == nil then return false end
|
||||
safeBotCall(function() botExecutor.callbacks.onUseWith(pos, itemId, target, subType) end)
|
||||
end
|
||||
|
||||
function botContainerOpen(container, previousContainer)
|
||||
if compiledConfig == nil then return false end
|
||||
safeBotCall(function() compiledConfig.callbacks.onContainerOpen(container, previousContainer) end)
|
||||
if botExecutor == nil then return false end
|
||||
safeBotCall(function() botExecutor.callbacks.onContainerOpen(container, previousContainer) end)
|
||||
end
|
||||
|
||||
function botContainerClose(container)
|
||||
if compiledConfig == nil then return false end
|
||||
safeBotCall(function() compiledConfig.callbacks.onContainerClose(container) end)
|
||||
if botExecutor == nil then return false end
|
||||
safeBotCall(function() botExecutor.callbacks.onContainerClose(container) end)
|
||||
end
|
||||
|
||||
function botContainerUpdateItem(container, slot, item)
|
||||
if compiledConfig == nil then return false end
|
||||
safeBotCall(function() compiledConfig.callbacks.onContainerUpdateItem(container, slot, item) end)
|
||||
if botExecutor == nil then return false end
|
||||
safeBotCall(function() botExecutor.callbacks.onContainerUpdateItem(container, slot, item) end)
|
||||
end
|
||||
|
||||
function botOnMissle(missle)
|
||||
if compiledConfig == nil then return false end
|
||||
safeBotCall(function() compiledConfig.callbacks.onMissle(missle) end)
|
||||
end
|
||||
|
||||
function botOnMissle(missle)
|
||||
if compiledConfig == nil then return false end
|
||||
safeBotCall(function() compiledConfig.callbacks.onMissle(missle) end)
|
||||
if botExecutor == nil then return false end
|
||||
safeBotCall(function() botExecutor.callbacks.onMissle(missle) end)
|
||||
end
|
||||
|
||||
function botChannelList(channels)
|
||||
if compiledConfig == nil then return false end
|
||||
safeBotCall(function() compiledConfig.callbacks.onChannelList(channels) end)
|
||||
if botExecutor == nil then return false end
|
||||
safeBotCall(function() botExecutor.callbacks.onChannelList(channels) end)
|
||||
end
|
||||
|
||||
function botOpenChannel(channelId, name)
|
||||
if compiledConfig == nil then return false end
|
||||
safeBotCall(function() compiledConfig.callbacks.onOpenChannel(channelId, name) end)
|
||||
if botExecutor == nil then return false end
|
||||
safeBotCall(function() botExecutor.callbacks.onOpenChannel(channelId, name) end)
|
||||
end
|
||||
|
||||
function botCloseChannel(channelId)
|
||||
if compiledConfig == nil then return false end
|
||||
safeBotCall(function() compiledConfig.callbacks.onCloseChannel(channelId) end)
|
||||
if botExecutor == nil then return false end
|
||||
safeBotCall(function() botExecutor.callbacks.onCloseChannel(channelId) end)
|
||||
end
|
||||
|
||||
function botChannelEvent(channelId, name, event)
|
||||
if compiledConfig == nil then return false end
|
||||
safeBotCall(function() compiledConfig.callbacks.onChannelEvent(channelId, name, event) end)
|
||||
if botExecutor == nil then return false end
|
||||
safeBotCall(function() botExecutor.callbacks.onChannelEvent(channelId, name, event) end)
|
||||
end
|
||||
|
Reference in New Issue
Block a user