mirror of
https://github.com/OTCv8/otclientv8.git
synced 2025-10-20 22:53:26 +02:00
Version 2.1 - imbuements, wrap/unwrap, 4 byte header, packet compression and other features
This commit is contained in:
228
modules/client_entergamev2/protocol.lua
Normal file
228
modules/client_entergamev2/protocol.lua
Normal file
@@ -0,0 +1,228 @@
|
||||
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
|
Reference in New Issue
Block a user