mirror of
https://github.com/OTCv8/otclientv8.git
synced 2025-04-30 03:09:20 +02:00
229 lines
6.1 KiB
Lua
229 lines
6.1 KiB
Lua
EnterGameV2Protocol = {}
|
|
EnterGameV2Protocol.__index = EnterGameV2Protocol
|
|
|
|
EnterGameV2Protocol.new = function(session)
|
|
if type(session) ~= 'string' then
|
|
return error("You need to specify string session for EnterGameV2Protocol")
|
|
end
|
|
local data = {}
|
|
data.socket = nil
|
|
data.terminated = false
|
|
data.reconnectEvent = nil
|
|
data.connected = false
|
|
data.session = session
|
|
data.sendQueue = {}
|
|
data.sendQueueMsgId = 1
|
|
data.loginTimeoutEvent = nil
|
|
setmetatable(data, EnterGameV2Protocol)
|
|
return data
|
|
end
|
|
|
|
function EnterGameV2Protocol:destroy()
|
|
self.terminated = true
|
|
self.sendQueue = {}
|
|
|
|
if self.loginTimeoutEvent then
|
|
removeEvent(self.loginTimeoutEvent)
|
|
self.loginTimeoutEvent = nil
|
|
end
|
|
|
|
self:reset()
|
|
end
|
|
|
|
function EnterGameV2Protocol:reset()
|
|
self.connected = false
|
|
if self.reconnectEvent then
|
|
removeEvent(self.reconnectEvent)
|
|
self.reconnectEvent = nil
|
|
end
|
|
if self.socket then
|
|
self.socket.close()
|
|
self.socket = nil
|
|
end
|
|
end
|
|
|
|
function EnterGameV2Protocol:setUrl(url)
|
|
if self.terminated then
|
|
return false
|
|
end
|
|
self:reset()
|
|
if self.url ~= url then
|
|
self.sendQueue = {}
|
|
self.sendQueueMsgId = 1
|
|
if self.loginTimeoutEvent then
|
|
removeEvent(self.loginTimeoutEvent)
|
|
self.loginTimeoutEvent = nil
|
|
end
|
|
end
|
|
if type(url) ~= 'string' or not url:lower():find("ws") then
|
|
g_logger.error("Invalid url for EnterGameV2Protocol:\n" .. url)
|
|
return false
|
|
end
|
|
self.url = url
|
|
self.socket = HTTP.WebSocketJSON(url, {
|
|
onOpen = function(message, websocketId)
|
|
if self.terminated or not self.socket or self.socket.id ~= websocketId then return end
|
|
self.connected = true
|
|
self:sendFirstMessage()
|
|
end,
|
|
onMessage = function(message, websocketId)
|
|
if self.terminated or not self.socket or self.socket.id ~= websocketId then return end
|
|
self:onSocketMessage(message)
|
|
end,
|
|
onClose = function(message, websocketId)
|
|
if self.terminated or not self.socket or self.socket.id ~= websocketId then return end
|
|
self.connected = false
|
|
self:scheduleReconnect()
|
|
end,
|
|
onError = function(message, websocketId)
|
|
if self.terminated or not self.socket or self.socket.id ~= websocketId then return end
|
|
self.connected = false
|
|
self:scheduleReconnect()
|
|
end
|
|
})
|
|
return true
|
|
end
|
|
|
|
function EnterGameV2Protocol:isConnected()
|
|
return self.socket and self.connected
|
|
end
|
|
|
|
function EnterGameV2Protocol:scheduleReconnect()
|
|
if self.socket then
|
|
self.connected = false
|
|
self.socket.close()
|
|
self.socket = nil
|
|
end
|
|
if self.terminated then return end
|
|
if self.reconnectEvent then return end
|
|
self.reconnectEvent = scheduleEvent(function() self:reconnect() end, 500)
|
|
end
|
|
|
|
function EnterGameV2Protocol:login(account, password, token, callback)
|
|
self:send({
|
|
type="login",
|
|
account=account,
|
|
password=password,
|
|
token=token,
|
|
})
|
|
if self.loginTimeoutEvent then
|
|
removeEvent(self.loginTimeoutEvent)
|
|
end
|
|
self.loginTimeoutEvent = scheduleEvent(function()
|
|
self.loginTimeoutEvent = nil
|
|
self.onLogin({error="Connection timeout"})
|
|
end, 10000)
|
|
end
|
|
|
|
function EnterGameV2Protocol:logout()
|
|
self:send({
|
|
type="logout"
|
|
})
|
|
end
|
|
|
|
function EnterGameV2Protocol:register(name, email, password, callback)
|
|
|
|
end
|
|
|
|
function EnterGameV2Protocol:createCharacter(name, gender, vocation, town)
|
|
self:send({
|
|
type="createcharacter",
|
|
name=name,
|
|
gender=gender,
|
|
vocation=vocation,
|
|
town=town
|
|
})
|
|
end
|
|
|
|
function EnterGameV2Protocol:updateSettings(settings)
|
|
self:send({
|
|
type="settings",
|
|
settings=settings
|
|
})
|
|
end
|
|
|
|
-- private functions
|
|
function EnterGameV2Protocol:reconnect()
|
|
if #self.sendQueue > 1 then
|
|
self.sendQueue = {} -- TEMPORARY
|
|
end
|
|
self.reconnectEvent = nil
|
|
if self.terminated then return end
|
|
self:setUrl(self.url)
|
|
end
|
|
|
|
function EnterGameV2Protocol:send(data)
|
|
if type(data) ~= "table" then
|
|
return error("data should be table")
|
|
end
|
|
data["id"] = self.sendQueueMsgId
|
|
table.insert(self.sendQueue, {id=self.sendQueueMsgId, msg=json.encode(data)})
|
|
self.sendQueueMsgId = self.sendQueueMsgId + 1
|
|
if self.socket then
|
|
self.socket.send(self.sendQueue[#self.sendQueue].msg)
|
|
end
|
|
end
|
|
|
|
function EnterGameV2Protocol:sendFirstMessage()
|
|
self.socket.send({type="init", session=self.session})
|
|
for i, msg in ipairs(self.sendQueue) do
|
|
self.socket.send(msg.msg)
|
|
end
|
|
end
|
|
|
|
function EnterGameV2Protocol:onSocketMessage(message)
|
|
local lastId = message["lastId"]
|
|
if type(lastId) == 'number' then -- clear send queue
|
|
while #self.sendQueue > 0 do
|
|
local id = self.sendQueue[1].id
|
|
if id < lastId then
|
|
break
|
|
end
|
|
table.remove(self.sendQueue, 1)
|
|
end
|
|
end
|
|
if message["type"] == "ping" then
|
|
self.socket.send({type="ping"})
|
|
elseif message["type"] == "login" then
|
|
if self.loginTimeoutEvent then
|
|
removeEvent(self.loginTimeoutEvent)
|
|
self.loginTimeoutEvent = nil
|
|
end
|
|
if self.onLogin then
|
|
self.onLogin(message)
|
|
end
|
|
elseif message["type"] == "logout" then
|
|
if self.onLogout then
|
|
self.onLogout()
|
|
end
|
|
elseif message["type"] == "qauth" then
|
|
if self.onQAuth then
|
|
self.onQAuth(message["token"])
|
|
end
|
|
elseif message["type"] == "characters" then
|
|
if self.onCharacters then
|
|
self.onCharacters(message["characters"])
|
|
end
|
|
elseif message["type"] == "message" then
|
|
if self.onMessage then
|
|
self.onMessage(message["title"], message["text"])
|
|
end
|
|
elseif message["type"] == "loading" then
|
|
if self.onMessage then
|
|
self.onLoading(message["title"], message["text"])
|
|
end
|
|
elseif message["type"] == "news" then
|
|
if self.onNews then
|
|
self.onNews(message["news"])
|
|
end
|
|
elseif message["type"] == "motd" then
|
|
if self.onMotd then
|
|
self.onMotd(message["text"])
|
|
end
|
|
elseif message["type"] == "createcharacter" then
|
|
if self.onMessage then
|
|
self.onCharacterCreate(message["error"], message["message"])
|
|
end
|
|
end
|
|
end
|