Added websocket login server and botserver

This commit is contained in:
OTCv8 2019-11-28 12:14:43 +01:00
parent ddb155333d
commit cf8b21263d
12 changed files with 371 additions and 263 deletions

View File

@ -56,8 +56,11 @@ function HTTP.downloadImage(url, callback)
return operation return operation
end end
function HTTP.webSocket(url, callbacks, jsonWebsocket) function HTTP.webSocket(url, callbacks, timeout, jsonWebsocket)
local operation = g_http.ws(url, HTTP.websocketTimeout) if not timeout or timeout < 1 then
timeout = HTTP.websocketTimeout
end
local operation = g_http.ws(url, timeout)
HTTP.operations[operation] = {type="ws", json=jsonWebsocket, url=url, callbacks=callbacks} HTTP.operations[operation] = {type="ws", json=jsonWebsocket, url=url, callbacks=callbacks}
return { return {
id = operation, id = operation,
@ -75,8 +78,8 @@ function HTTP.webSocket(url, callbacks, jsonWebsocket)
end end
HTTP.WebSocket = HTTP.webSocket HTTP.WebSocket = HTTP.webSocket
function HTTP.webSocketJSON(url, callbacks) function HTTP.webSocketJSON(url, callbacks, timeout)
return HTTP.webSocket(url, callbacks, true) return HTTP.webSocket(url, callbacks, timeout, true)
end end
HTTP.WebSocketJSON = HTTP.webSocketJSON HTTP.WebSocketJSON = HTTP.webSocketJSON

View File

@ -8,6 +8,7 @@ configEditorText = nil
configList = nil configList = nil
botTabs = nil botTabs = nil
botPanel = nil botPanel = nil
local botWebSockets = {}
local botMessages = nil local botMessages = nil
local configCopy = "" local configCopy = ""
local enableButton = nil local enableButton = nil
@ -344,6 +345,11 @@ function clearConfig()
botMessages:destroyChildren() botMessages:destroyChildren()
botMessages:updateLayout() 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 for i, widget in pairs(g_ui.getRootWidget():getChildren()) do
if widget.botWidget then if widget.botWidget then
widget:destroy() widget:destroy()
@ -385,7 +391,7 @@ function refreshConfig()
end end
errorOccured = false errorOccured = false
g_game.enableTileThingLuaCallback(false) g_game.enableTileThingLuaCallback(false)
local status, result = pcall(function() return executeBot(config.script, config.storage, botTabs, botMsgCallback, saveConfig) end) local status, result = pcall(function() return executeBot(config.script, config.storage, botTabs, botMsgCallback, saveConfig, botWebSockets) end)
if not status then if not status then
errorOccured = true errorOccured = true
statusLabel:setText("Error: " .. tostring(result)) statusLabel:setText("Error: " .. tostring(result))

View File

@ -1,8 +1,9 @@
function executeBot(config, storage, tabs, msgCallback, saveConfigCallback) function executeBot(config, storage, tabs, msgCallback, saveConfigCallback, websockets)
local context = {} local context = {}
context.tabs = tabs context.tabs = tabs
context.panel = context.tabs:addTab("Main", g_ui.createWidget('BotPanel')).tabPanel context.panel = context.tabs:addTab("Main", g_ui.createWidget('BotPanel')).tabPanel
context.saveConfig = saveConfigCallback context.saveConfig = saveConfigCallback
context._websockets = websockets
context.storage = storage context.storage = storage
if context.storage._macros == nil then if context.storage._macros == nil then
@ -65,6 +66,7 @@ function executeBot(config, storage, tabs, msgCallback, saveConfigCallback)
context.StaticText = StaticText context.StaticText = StaticText
context.Config = Config context.Config = Config
context.HTTP = HTTP context.HTTP = HTTP
context.modules = modules
-- log functions -- log functions
context.info = function(text) return msgCallback("info", tostring(text)) end context.info = function(text) return msgCallback("info", tostring(text)) end

View File

@ -3,13 +3,10 @@ local context = G.botContext
-- MAIN BOT FUNCTION -- MAIN BOT FUNCTION
-- macro(timeout, callback) -- macro(timeout, callback)
-- macro(timeout, name, callback) -- macro(timeout, name, callback)
-- macro(timeout, name, callback, parent)
-- macro(timeout, name, hotkey, callback) -- macro(timeout, name, hotkey, callback)
-- macro(timeout, name, hotkey, callback, parent) -- macro(timeout, name, hotkey, callback, parent)
context.macro = function(timeout, name, hotkey, callback, parent) context.macro = function(timeout, name, hotkey, callback, parent)
if not parent then
parent = context.panel
end
if type(timeout) ~= 'number' or timeout < 1 then if type(timeout) ~= 'number' or timeout < 1 then
error("Invalid timeout for macro: " .. tostring(timeout)) error("Invalid timeout for macro: " .. tostring(timeout))
end end
@ -18,6 +15,7 @@ context.macro = function(timeout, name, hotkey, callback, parent)
name = "" name = ""
hotkey = "" hotkey = ""
elseif type(hotkey) == 'function' then elseif type(hotkey) == 'function' then
parent = callback
callback = hotkey callback = hotkey
hotkey = "" hotkey = ""
elseif type(callback) ~= 'function' then elseif type(callback) ~= 'function' then
@ -29,6 +27,9 @@ context.macro = function(timeout, name, hotkey, callback, parent)
if type(name) ~= 'string' or type(hotkey) ~= 'string' then if type(name) ~= 'string' or type(hotkey) ~= 'string' then
error("Invalid name or hotkey for macro") error("Invalid name or hotkey for macro")
end end
if not parent then
parent = context.panel
end
if hotkey:len() > 0 then if hotkey:len() > 0 then
hotkey = retranslateKeyComboDesc(hotkey) hotkey = retranslateKeyComboDesc(hotkey)
end end
@ -63,16 +64,18 @@ context.macro = function(timeout, name, hotkey, callback, parent)
end end
-- hotkey(keys, callback) -- hotkey(keys, callback)
-- hotkey(keys, callback, parent)
-- hotkey(keys, name, callback) -- hotkey(keys, name, callback)
-- hotkey(keys, name, callback, parent) -- hotkey(keys, name, callback, parent)
context.hotkey = function(keys, name, callback, single, parent) context.hotkey = function(keys, name, callback, parent, single)
if not parent then
parent = context.panel
end
if type(name) == 'function' then if type(name) == 'function' then
parent = callback
callback = name callback = name
name = "" name = ""
end end
if not parent then
parent = context.panel
end
keys = retranslateKeyComboDesc(keys) keys = retranslateKeyComboDesc(keys)
if not keys or #keys == 0 then if not keys or #keys == 0 then
return context.error("Invalid hotkey keys " .. tostring(name)) return context.error("Invalid hotkey keys " .. tostring(name))
@ -107,14 +110,16 @@ context.hotkey = function(keys, name, callback, single, parent)
end end
-- singlehotkey(keys, callback) -- singlehotkey(keys, callback)
-- singlehotkey(keys, callback, parent)
-- singlehotkey(keys, name, callback) -- singlehotkey(keys, name, callback)
-- singlehotkey(keys, name, callback, parent) -- singlehotkey(keys, name, callback, parent)
context.singlehotkey = function(keys, name, callback, parent) context.singlehotkey = function(keys, name, callback, parent)
if type(name) == 'function' then if type(name) == 'function' then
parent = callback
callback = name callback = name
name = "" name = ""
end end
return context.hotkey(keys, name, callback, true, parent) return context.hotkey(keys, name, callback, parent, true)
end end
-- schedule(timeout, callback) -- schedule(timeout, callback)

View File

@ -92,6 +92,9 @@ context.sayNPC = context.talkNpc
context.talkNPC = context.talkNpc context.talkNPC = context.talkNpc
context.saySpell = function(text, lastSpellTimeout) context.saySpell = function(text, lastSpellTimeout)
if not text or text:len() < 1 then
return
end
if context.lastSpell == nil then if context.lastSpell == nil then
context.lastSpell = 0 context.lastSpell = 0
end end

View File

@ -0,0 +1,88 @@
local context = G.botContext
context.BotServer = {}
context.BotServer.url = "ws://bot.otclient.ovh:8000/"
context.BotServer.timeout = 3
context.BotServer._callbacks = {}
context.BotServer._lastMessageId = 0
context.BotServer._wasConnected = true -- show first warning
context.BotServer.init = function(name, channel)
if not channel or not name or channel:len() < 1 or name:len() < 1 then
return context.error("Invalid params for BotServer.init")
end
if context.BotServer._websocket then
return context.error("BotServer is already initialized")
end
context.BotServer._websocket = HTTP.WebSocketJSON(context.BotServer.url, {
onMessage = function(message, socketId)
if not context._websockets[socketId] then
return g_http.cancel(socketId)
end
if not context.BotServer._websocket or context.BotServer._websocket.id ~= socketId then
return g_http.cancel(socketId)
end
context.BotServer._wasConnected = true
if message["type"] == "ping" then
return context.BotServer._websocket.send({type="ping"})
end
if message["type"] == "message" then
context.BotServer._lastMessageId = message["id"]
local topics = context.BotServer._callbacks[message["topic"]]
if topics then
for i=1,#topics do
topics[i](message["name"], message["message"], message["topic"])
end
end
topics = context.BotServer._callbacks["*"]
if topics then
for i=1,#topics do
topics[i](message["name"], message["message"], message["topic"])
end
end
return
end
end,
onClose = function(message, socketId)
if not context._websockets[socketId] then
return
end
context._websockets[socketId] = nil
if not context.BotServer._websocket or context.BotServer._websocket.id ~= socketId then
return
end
if context.BotServer._wasConnected then
context.warn("BotServer disconnected")
end
context.BotServer._wasConnected = false
context.BotServer._websocket = nil
context.BotServer.init(name, channel)
end
}, context.BotServer.timeout)
context._websockets[context.BotServer._websocket.id] = 1
context.BotServer._websocket.send({type="init", name=name, channel=channel, lastMessage=context.BotServer._lastMessageId})
end
context.BotServer.terminate = function()
if context.BotServer._websocket then
context.BotServer._websocket:close()
context.BotServer._websocket = nil
end
end
context.BotServer.listen = function(topic, callback) -- callback = function(name, message, topic) -- message is parsed json = table
if not context.BotServer._websocket then
return context.error("BotServer is not initialized")
end
if not context.BotServer._callbacks[topic] then
context.BotServer._callbacks[topic] = {}
end
table.insert(context.BotServer._callbacks[topic], callback)
end
context.BotServer.send = function(topic, message)
if not context.BotServer._websocket then
return context.error("BotServer is not initialized")
end
context.BotServer._websocket.send({type="message", topic=topic, message=message})
end

View File

@ -871,6 +871,7 @@ function refreshViewMode()
gameBottomPanel:addAnchor(AnchorRight, 'gameRightPanels', AnchorLeft) gameBottomPanel:addAnchor(AnchorRight, 'gameRightPanels', AnchorLeft)
bottomSplitter:addAnchor(AnchorLeft, 'gameLeftPanels', AnchorRight) bottomSplitter:addAnchor(AnchorLeft, 'gameLeftPanels', AnchorRight)
bottomSplitter:addAnchor(AnchorRight, 'gameRightPanels', AnchorLeft) bottomSplitter:addAnchor(AnchorRight, 'gameRightPanels', AnchorLeft)
bottomSplitter:setMarginLeft(0)
modules.client_topmenu.getTopMenu():setImageColor('white') modules.client_topmenu.getTopMenu():setImageColor('white')
gameBottomPanel:setImageColor('white') gameBottomPanel:setImageColor('white')