tibia-client/modules/gamelib/protocollogin.lua

195 lines
5.1 KiB
Lua
Raw Normal View History

2012-06-26 00:13:30 +02:00
-- @docclass
ProtocolLogin = extends(Protocol, "ProtocolLogin")
2012-06-05 23:27:37 +02:00
LoginServerError = 10
LoginServerUpdate = 17
LoginServerMotd = 20
LoginServerUpdateNeeded = 30
LoginServerCharacterList = 100
LoginServerExtendedCharacterList = 101
function ProtocolLogin:login(host, port, accountName, accountPassword)
2012-07-26 08:10:28 +02:00
if string.len(host) == 0 or port == nil or port == 0 then
2013-02-21 21:31:47 +01:00
signalcall(self.onLoginError, self, tr("You must enter a valid server address and port."))
2012-07-26 08:10:28 +02:00
return
end
self.accountName = accountName
self.accountPassword = accountPassword
self.connectCallback = self.sendLoginPacket
2012-07-26 08:10:28 +02:00
self:connect(host, port)
end
2012-07-26 08:10:28 +02:00
function ProtocolLogin:cancelLogin()
self:disconnect()
end
function ProtocolLogin:sendLoginPacket()
2012-06-05 23:27:37 +02:00
local msg = OutputMessage.create()
2013-12-23 23:42:58 +01:00
msg:addU8(ClientOpcodes.ClientEnterAccount)
msg:addU16(g_game.getOs())
msg:addU16(g_game.getProtocolVersion())
if g_game.getClientVersion() >= 980 then
msg:addU32(g_game.getClientVersion())
end
2012-06-05 23:27:37 +02:00
2012-06-21 19:54:20 +02:00
msg:addU32(g_things.getDatSignature())
msg:addU32(g_sprites.getSprSignature())
msg:addU32(PIC_SIGNATURE)
2012-06-05 23:27:37 +02:00
if g_game.getClientVersion() >= 980 then
msg:addU8(0) -- clientType
end
local offset = msg:getMessageSize()
if g_game.getClientVersion() >= 770 then
2013-12-23 23:42:58 +01:00
-- first RSA byte must be 0
msg:addU8(0)
-- xtea key
self:generateXteaKey()
local xteaKey = self:getXteaKey()
msg:addU32(xteaKey[1])
msg:addU32(xteaKey[2])
msg:addU32(xteaKey[3])
msg:addU32(xteaKey[4])
end
2012-06-05 23:27:37 +02:00
if g_game.getFeature(GameAccountNames) then
2012-07-26 08:10:28 +02:00
msg:addString(self.accountName)
2012-06-05 23:27:37 +02:00
else
2012-07-26 08:10:28 +02:00
msg:addU32(tonumber(self.accountName))
2012-06-05 23:27:37 +02:00
end
msg:addString(self.accountPassword)
if self.getLoginExtendedData then
local data = self:getLoginExtendedData()
msg:addString(data)
end
local paddingBytes = g_crypt.rsaGetSize() - (msg:getMessageSize() - offset)
assert(paddingBytes >= 0)
2012-06-05 23:27:37 +02:00
msg:addPaddingBytes(paddingBytes, 0)
if g_game.getClientVersion() >= 770 then
msg:encryptRsa()
end
if g_game.getFeature(GameProtocolChecksum) then
self:enableChecksum()
end
2012-06-05 23:27:37 +02:00
2012-07-26 08:10:28 +02:00
self:send(msg)
if g_game.getClientVersion() >= 770 then
self:enableXteaEncryption()
end
2012-07-26 08:10:28 +02:00
self:recv()
2012-06-05 23:27:37 +02:00
end
function ProtocolLogin:onConnect()
2013-02-22 22:49:36 +01:00
self.gotConnection = true
self:connectCallback()
self.connectCallback = nil
2012-06-05 23:27:37 +02:00
end
function ProtocolLogin:onRecv(msg)
while not msg:eof() do
local opcode = msg:getU8()
if opcode == LoginServerError then
self:parseError(msg)
elseif opcode == LoginServerMotd then
self:parseMotd(msg)
elseif opcode == LoginServerUpdateNeeded then
2013-02-21 21:31:47 +01:00
signalcall(self.onLoginError, self, tr("Client needs update."))
2012-06-05 23:27:37 +02:00
elseif opcode == LoginServerCharacterList then
self:parseCharacterList(msg)
elseif opcode == LoginServerExtendedCharacterList then
self:parseExtendedCharacterList(msg)
elseif opcode == LoginServerUpdate then
local signature = msg:getString()
signalcall(self.onUpdateNeeded, self, signature)
2012-06-05 23:27:37 +02:00
else
self:parseOpcode(opcode, msg)
end
end
self:disconnect()
end
function ProtocolLogin:parseError(msg)
local errorMessage = msg:getString()
2013-02-21 21:31:47 +01:00
signalcall(self.onLoginError, self, errorMessage)
2012-06-05 23:27:37 +02:00
end
function ProtocolLogin:parseMotd(msg)
local motd = msg:getString()
signalcall(self.onMotd, self, motd)
end
function ProtocolLogin:parseCharacterList(msg)
local characters = {}
if g_game.getClientVersion() > 1010 then
local worlds = {}
local worldsCount = msg:getU8()
for i=1, worldsCount do
local world = {}
local worldId = msg:getU8()
world.worldName = msg:getString()
2013-11-10 06:17:49 +01:00
world.worldIp = msg:getString()
world.worldPort = msg:getU16()
msg:getU8() -- unknow byte?
worlds[worldId] = world
end
local charactersCount = msg:getU8()
for i=1, charactersCount do
local character = {}
local worldId = msg:getU8()
character.name = msg:getString()
character.worldName = worlds[worldId].worldName
character.worldIp = worlds[worldId].worldIp
character.worldPort = worlds[worldId].worldPort
characters[i] = character
end
else
local charactersCount = msg:getU8()
for i=1,charactersCount do
local character = {}
character.name = msg:getString()
character.worldName = msg:getString()
character.worldIp = iptostring(msg:getU32())
character.worldPort = msg:getU16()
if g_game.getClientVersion() >= 980 then
character.unknown = msg:getU8()
end
characters[i] = character
end
2012-06-05 23:27:37 +02:00
end
local account = {}
account.premDays = msg:getU16()
signalcall(self.onCharacterList, self, characters, account)
end
function ProtocolLogin:parseExtendedCharacterList(msg)
local characters = msg:getTable()
local account = msg:getTable()
local otui = msg:getString()
signalcall(self.onCharacterList, self, characters, account, otui)
2012-06-05 23:27:37 +02:00
end
function ProtocolLogin:parseOpcode(opcode, msg)
signalcall(self.onOpcode, self, opcode, msg)
end
2013-02-21 21:31:47 +01:00
function ProtocolLogin:onError(msg, code)
2013-02-27 20:24:32 +01:00
local text = translateNetworkError(code, self:isConnecting(), msg)
2013-02-22 22:49:36 +01:00
signalcall(self.onLoginError, self, text)
2013-02-21 21:31:47 +01:00
end