Diff
checker
Texto
Texto
Imágenes
Documentos
Excel
Carpetas
Legal
Enterprise
Aplicación de escritorio
Precios
Iniciar sesión
Descargar Diffchecker Desktop
Comparar texto
Encuentra la diferencia entre dos archivos de texto
Herramientas
Historial
Editor live
Ocultar sin cambios
Sin ajuste de línea
Vista
Dividido
Unificado
Nivel de detalle
Inteligente
Palabra
Letra
Resaltado de sintaxis
Elegir sintaxis
Ignorar
Transformar texto
Ir al primer cambio
Editar entrada
Diffchecker Desktop
La forma más segura de usar Diffchecker. ¡Obtén la app de Diffchecker Desktop: tus diffs nunca salen de tu computadora!
Obtener Desktop
otclient-master\modules\gamelib/protocollogin.lua
Creado
hace 5 años
El diff nunca expira
Borrar
Exportar
Compartir
Explicar
1 eliminación
Líneas
Total
Eliminado
Caracteres
Total
Eliminado
Para continuar usando esta función, actualice a
Diff
checker
Pro
Ver precios
275 líneas
Copiar todo
3 adiciones
Líneas
Total
Añadido
Caracteres
Total
Añadido
Para continuar usando esta función, actualice a
Diff
checker
Pro
Ver precios
277 líneas
Copiar todo
-- @docclass
-- @docclass
ProtocolLogin = extends(Protocol, "ProtocolLogin")
ProtocolLogin = extends(Protocol, "ProtocolLogin")
LoginServerError = 10
LoginServerError = 10
LoginServerTokenSuccess = 12
LoginServerTokenSuccess = 12
LoginServerTokenError = 13
LoginServerTokenError = 13
LoginServerUpdate = 17
LoginServerUpdate = 17
LoginServerMotd = 20
LoginServerMotd = 20
LoginServerUpdateNeeded = 30
LoginServerUpdateNeeded = 30
LoginServerSessionKey = 40
LoginServerSessionKey = 40
LoginServerCharacterList = 100
LoginServerCharacterList = 100
LoginServerExtendedCharacterList = 101
LoginServerExtendedCharacterList = 101
-- Since 10.76
-- Since 10.76
LoginServerRetry = 10
LoginServerRetry = 10
LoginServerErrorNew = 11
LoginServerErrorNew = 11
function ProtocolLogin:login(host, port, accountName, accountPassword, authenticatorToken, stayLogged)
function ProtocolLogin:login(host, port, accountName, accountPassword, authenticatorToken, stayLogged)
if string.len(host) == 0 or port == nil or port == 0 then
if string.len(host) == 0 or port == nil or port == 0 then
signalcall(self.onLoginError, self, tr("You must enter a valid server address and port."))
signalcall(self.onLoginError, self, tr("You must enter a valid server address and port."))
return
return
end
end
self.accountName = accountName
self.accountName = accountName
self.accountPassword = accountPassword
self.accountPassword = accountPassword
self.authenticatorToken = authenticatorToken
self.authenticatorToken = authenticatorToken
self.stayLogged = stayLogged
self.stayLogged = stayLogged
self.connectCallback = self.sendLoginPacket
self.connectCallback = self.sendLoginPacket
self:connect(host, port)
self:connect(host, port)
end
end
function ProtocolLogin:cancelLogin()
function ProtocolLogin:cancelLogin()
self:disconnect()
self:disconnect()
end
end
function ProtocolLogin:sendLoginPacket()
function ProtocolLogin:sendLoginPacket()
local msg = OutputMessage.create()
local msg = OutputMessage.create()
msg:addU8(ClientOpcodes.ClientEnterAccount)
msg:addU8(ClientOpcodes.ClientEnterAccount)
msg:addU16(g_game.getOs())
msg:addU16(g_game.getOs())
msg:addU16(g_game.getProtocolVersion())
msg:addU16(g_game.getProtocolVersion())
if g_game.getFeature(GameClientVersion) then
if g_game.getFeature(GameClientVersion) then
msg:addU32(g_game.getClientVersion())
msg:addU32(g_game.getClientVersion())
end
end
if g_game.getFeature(GameContentRevision) then
if g_game.getFeature(GameContentRevision) then
msg:addU16(g_things.getContentRevision())
msg:addU16(g_things.getContentRevision())
msg:addU16(0)
msg:addU16(0)
else
else
msg:addU32(g_things.getDatSignature())
msg:addU32(g_things.getDatSignature())
end
end
msg:addU32(g_sprites.getSprSignature())
msg:addU32(g_sprites.getSprSignature())
msg:addU32(PIC_SIGNATURE)
msg:addU32(PIC_SIGNATURE)
if g_game.getFeature(GamePreviewState) then
if g_game.getFeature(GamePreviewState) then
msg:addU8(0)
msg:addU8(0)
end
end
local offset = msg:getMessageSize()
local offset = msg:getMessageSize()
if g_game.getFeature(GameLoginPacketEncryption) then
if g_game.getFeature(GameLoginPacketEncryption) then
-- first RSA byte must be 0
-- first RSA byte must be 0
msg:addU8(0)
msg:addU8(0)
-- xtea key
-- xtea key
self:generateXteaKey()
self:generateXteaKey()
local xteaKey = self:getXteaKey()
local xteaKey = self:getXteaKey()
msg:addU32(xteaKey[1])
msg:addU32(xteaKey[1])
msg:addU32(xteaKey[2])
msg:addU32(xteaKey[2])
msg:addU32(xteaKey[3])
msg:addU32(xteaKey[3])
msg:addU32(xteaKey[4])
msg:addU32(xteaKey[4])
end
end
if g_game.getFeature(GameAccountNames) then
if g_game.getFeature(GameAccountNames) then
msg:addString(self.accountName)
msg:addString(self.accountName)
else
else
msg:addU32(tonumber(self.accountName))
msg:addU32(tonumber(self.accountName))
end
end
msg:addString(self.accountPassword)
msg:addString(self.accountPassword)
if self.getLoginExtendedData then
if self.getLoginExtendedData then
local data = self:getLoginExtendedData()
local data = self:getLoginExtendedData()
msg:addString(data)
msg:addString(data)
end
end
local paddingBytes = g_crypt.rsaGetSize() - (msg:getMessageSize() - offset)
local paddingBytes = g_crypt.rsaGetSize() - (msg:getMessageSize() - offset)
assert(paddingBytes >= 0)
assert(paddingBytes >= 0)
for i = 1, paddingBytes do
for i = 1, paddingBytes do
msg:addU8(math.random(0, 0xff))
msg:addU8(math.random(0, 0xff))
end
end
if g_game.getFeature(GameLoginPacketEncryption) then
if g_game.getFeature(GameLoginPacketEncryption) then
msg:encryptRsa()
msg:encryptRsa()
end
end
if g_game.getFeature(GameOGLInformation) then
if g_game.getFeature(GameOGLInformation) then
msg:addU8(1) --unknown
msg:addU8(1) --unknown
msg:addU8(1) --unknown
msg:addU8(1) --unknown
if g_game.getClientVersion() >= 1072 then
if g_game.getClientVersion() >= 1072 then
msg:addString(string.format('%s %s', g_graphics.getVendor(), g_graphics.getRenderer()))
msg:addString(string.format('%s %s', g_graphics.getVendor(), g_graphics.getRenderer()))
else
else
msg:addString(g_graphics.getRenderer())
msg:addString(g_graphics.getRenderer())
end
end
msg:addString(g_graphics.getVersion())
msg:addString(g_graphics.getVersion())
end
end
-- add RSA encrypted auth token
-- add RSA encrypted auth token
if g_game.getFeature(GameAuthenticator) then
if g_game.getFeature(GameAuthenticator) then
offset = msg:getMessageSize()
offset = msg:getMessageSize()
-- first RSA byte must be 0
-- first RSA byte must be 0
msg:addU8(0)
msg:addU8(0)
msg:addString(self.authenticatorToken)
msg:addString(self.authenticatorToken)
if g_game.getFeature(GameSessionKey) then
if g_game.getFeature(GameSessionKey) then
msg:addU8(booleantonumber(self.stayLogged))
msg:addU8(booleantonumber(self.stayLogged))
end
end
paddingBytes = g_crypt.rsaGetSize() - (msg:getMessageSize() - offset)
paddingBytes = g_crypt.rsaGetSize() - (msg:getMessageSize() - offset)
assert(paddingBytes >= 0)
assert(paddingBytes >= 0)
for i = 1, paddingBytes do
for i = 1, paddingBytes do
msg:addU8(math.random(0, 0xff))
msg:addU8(math.random(0, 0xff))
end
end
msg:encryptRsa()
msg:encryptRsa()
end
end
if g_game.getFeature(GameProtocolChecksum) then
if g_game.getFeature(GameProtocolChecksum) then
self:enableChecksum()
self:enableChecksum()
end
end
self:send(msg)
self:send(msg)
if g_game.getFeature(GameLoginPacketEncryption) then
if g_game.getFeature(GameLoginPacketEncryption) then
self:enableXteaEncryption()
self:enableXteaEncryption()
end
end
self:recv()
self:recv()
end
end
function ProtocolLogin:onConnect()
function ProtocolLogin:onConnect()
self.gotConnection = true
self.gotConnection = true
self:connectCallback()
self:connectCallback()
self.connectCallback = nil
self.connectCallback = nil
end
end
function ProtocolLogin:onRecv(msg)
function ProtocolLogin:onRecv(msg)
while not msg:eof() do
while not msg:eof() do
local opcode = msg:getU8()
local opcode = msg:getU8()
if opcode == LoginServerErrorNew then
if opcode == LoginServerErrorNew then
self:parseError(msg)
self:parseError(msg)
elseif opcode == LoginServerError then
elseif opcode == LoginServerError then
self:parseError(msg)
self:parseError(msg)
elseif opcode == LoginServerMotd then
elseif opcode == LoginServerMotd then
self:parseMotd(msg)
self:parseMotd(msg)
elseif opcode == LoginServerUpdateNeeded then
elseif opcode == LoginServerUpdateNeeded then
signalcall(self.onLoginError, self, tr("Client needs update."))
signalcall(self.onLoginError, self, tr("Client needs update."))
elseif opcode == LoginServerTokenSuccess then
elseif opcode == LoginServerTokenSuccess then
local unknown = msg:getU8()
local unknown = msg:getU8()
elseif opcode == LoginServerTokenError then
elseif opcode == LoginServerTokenError then
-- TODO: prompt for token here
-- TODO: prompt for token here
local unknown = msg:getU8()
local unknown = msg:getU8()
signalcall(self.onLoginError, self, tr("Invalid authentification token."))
signalcall(self.onLoginError, self, tr("Invalid authentification token."))
elseif opcode == LoginServerCharacterList then
elseif opcode == LoginServerCharacterList then
self:parseCharacterList(msg)
self:parseCharacterList(msg)
elseif opcode == LoginServerExtendedCharacterList then
elseif opcode == LoginServerExtendedCharacterList then
self:parseExtendedCharacterList(msg)
self:parseExtendedCharacterList(msg)
elseif opcode == LoginServerUpdate then
elseif opcode == LoginServerUpdate then
local signature = msg:getString()
local signature = msg:getString()
signalcall(self.onUpdateNeeded, self, signature)
signalcall(self.onUpdateNeeded, self, signature)
elseif opcode == LoginServerSessionKey then
elseif opcode == LoginServerSessionKey then
self:parseSessionKey(msg)
self:parseSessionKey(msg)
else
else
self:parseOpcode(opcode, msg)
self:parseOpcode(opcode, msg)
end
end
end
end
self:disconnect()
self:disconnect()
end
end
function ProtocolLogin:parseError(msg)
function ProtocolLogin:parseError(msg)
local errorMessage = msg:getString()
local errorMessage = msg:getString()
signalcall(self.onLoginError, self, errorMessage)
signalcall(self.onLoginError, self, errorMessage)
end
end
function ProtocolLogin:parseMotd(msg)
function ProtocolLogin:parseMotd(msg)
local motd = msg:getString()
local motd = msg:getString()
signalcall(self.onMotd, self, motd)
signalcall(self.onMotd, self, motd)
end
end
function ProtocolLogin:parseSessionKey(msg)
function ProtocolLogin:parseSessionKey(msg)
local sessionKey = msg:getString()
local sessionKey = msg:getString()
signalcall(self.onSessionKey, self, sessionKey)
signalcall(self.onSessionKey, self, sessionKey)
end
end
function ProtocolLogin:parseCharacterList(msg)
function ProtocolLogin:parseCharacterList(msg)
local characters = {}
local characters = {}
if g_game.getClientVersion() > 1010 then
if g_game.getClientVersion() > 1010 then
local worlds = {}
local worlds = {}
local worldsCount = msg:getU8()
local worldsCount = msg:getU8()
for i=1, worldsCount do
for i=1, worldsCount do
local world = {}
local world = {}
local worldId = msg:getU8()
local worldId = msg:getU8()
world.worldName = msg:getString()
world.worldName = msg:getString()
world.worldIp = msg:getString()
world.worldIp = msg:getString()
Copiar
Copiado
Copiar
Copiado
world.worldIp = "127.0.0.1"
world.worldPort = msg:getU16()
world.worldPort = msg:getU16()
world.previewState = msg:getU8()
world.previewState = msg:getU8()
worlds[worldId] = world
worlds[worldId] = world
end
end
local charactersCount = msg:getU8()
local charactersCount = msg:getU8()
for i=1, charactersCount do
for i=1, charactersCount do
local character = {}
local character = {}
local worldId = msg:getU8()
local worldId = msg:getU8()
character.name = msg:getString()
character.name = msg:getString()
character.worldName = worlds[worldId].worldName
character.worldName = worlds[worldId].worldName
character.worldIp = worlds[worldId].worldIp
character.worldIp = worlds[worldId].worldIp
Copiar
Copiado
Copiar
Copiado
character.worldIp = "127.0.0.1"
character.worldPort = worlds[worldId].worldPort
character.worldPort = worlds[worldId].worldPort
character.previewState = worlds[worldId].previewState
character.previewState = worlds[worldId].previewState
characters[i] = character
characters[i] = character
end
end
else
else
local charactersCount = msg:getU8()
local charactersCount = msg:getU8()
for i=1,charactersCount do
for i=1,charactersCount do
local character = {}
local character = {}
character.name = msg:getString()
character.name = msg:getString()
character.worldName = msg:getString()
character.worldName = msg:getString()
character.worldIp = iptostring(msg:getU32())
character.worldIp = iptostring(msg:getU32())
Copiar
Copiado
Copiar
Copiado
character.worldIp = "127.0.0.1"
character.worldPort = msg:getU16()
character.worldPort = msg:getU16()
if g_game.getFeature(GamePreviewState) then
if g_game.getFeature(GamePreviewState) then
character.previewState = msg:getU8()
character.previewState = msg:getU8()
end
end
characters[i] = character
characters[i] = character
end
end
end
end
local account = {}
local account = {}
if g_game.getProtocolVersion() > 1077 then
if g_game.getProtocolVersion() > 1077 then
account.status = msg:getU8()
account.status = msg:getU8()
account.subStatus = msg:getU8()
account.subStatus = msg:getU8()
account.premDays = msg:getU32()
account.premDays = msg:getU32()
if account.premDays ~= 0 and account.premDays ~= 65535 then
if account.premDays ~= 0 and account.premDays ~= 65535 then
account.premDays = math.floor((account.premDays - os.time()) / 86400)
account.premDays = math.floor((account.premDays - os.time()) / 86400)
end
end
else
else
account.status = AccountStatus.Ok
account.status = AccountStatus.Ok
account.premDays = msg:getU16()
account.premDays = msg:getU16()
account.subStatus = account.premDays > 0 and SubscriptionStatus.Premium or SubscriptionStatus.Free
account.subStatus = account.premDays > 0 and SubscriptionStatus.Premium or SubscriptionStatus.Free
end
end
signalcall(self.onCharacterList, self, characters, account)
signalcall(self.onCharacterList, self, characters, account)
end
end
function ProtocolLogin:parseExtendedCharacterList(msg)
function ProtocolLogin:parseExtendedCharacterList(msg)
local characters = msg:getTable()
local characters = msg:getTable()
local account = msg:getTable()
local account = msg:getTable()
local otui = msg:getString()
local otui = msg:getString()
signalcall(self.onCharacterList, self, characters, account, otui)
signalcall(self.onCharacterList, self, characters, account, otui)
end
end
function ProtocolLogin:parseOpcode(opcode, msg)
function ProtocolLogin:parseOpcode(opcode, msg)
signalcall(self.onOpcode, self, opcode, msg)
signalcall(self.onOpcode, self, opcode, msg)
end
end
function ProtocolLogin:onError(msg, code)
function ProtocolLogin:onError(msg, code)
local text = translateNetworkError(code, self:isConnecting(), msg)
local text = translateNetworkError(code, self:isConnecting(), msg)
signalcall(self.onLoginError, self, text)
signalcall(self.onLoginError, self, text)
end
end
Copiar
Copiado
Copiar
Copiado
Diferencias guardadas
Texto original
Abrir archivo
-- @docclass ProtocolLogin = extends(Protocol, "ProtocolLogin") LoginServerError = 10 LoginServerTokenSuccess = 12 LoginServerTokenError = 13 LoginServerUpdate = 17 LoginServerMotd = 20 LoginServerUpdateNeeded = 30 LoginServerSessionKey = 40 LoginServerCharacterList = 100 LoginServerExtendedCharacterList = 101 -- Since 10.76 LoginServerRetry = 10 LoginServerErrorNew = 11 function ProtocolLogin:login(host, port, accountName, accountPassword, authenticatorToken, stayLogged) if string.len(host) == 0 or port == nil or port == 0 then signalcall(self.onLoginError, self, tr("You must enter a valid server address and port.")) return end self.accountName = accountName self.accountPassword = accountPassword self.authenticatorToken = authenticatorToken self.stayLogged = stayLogged self.connectCallback = self.sendLoginPacket self:connect(host, port) end function ProtocolLogin:cancelLogin() self:disconnect() end function ProtocolLogin:sendLoginPacket() local msg = OutputMessage.create() msg:addU8(ClientOpcodes.ClientEnterAccount) msg:addU16(g_game.getOs()) msg:addU16(g_game.getProtocolVersion()) if g_game.getFeature(GameClientVersion) then msg:addU32(g_game.getClientVersion()) end if g_game.getFeature(GameContentRevision) then msg:addU16(g_things.getContentRevision()) msg:addU16(0) else msg:addU32(g_things.getDatSignature()) end msg:addU32(g_sprites.getSprSignature()) msg:addU32(PIC_SIGNATURE) if g_game.getFeature(GamePreviewState) then msg:addU8(0) end local offset = msg:getMessageSize() if g_game.getFeature(GameLoginPacketEncryption) then -- 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 if g_game.getFeature(GameAccountNames) then msg:addString(self.accountName) else msg:addU32(tonumber(self.accountName)) 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) for i = 1, paddingBytes do msg:addU8(math.random(0, 0xff)) end if g_game.getFeature(GameLoginPacketEncryption) then msg:encryptRsa() end if g_game.getFeature(GameOGLInformation) then msg:addU8(1) --unknown msg:addU8(1) --unknown if g_game.getClientVersion() >= 1072 then msg:addString(string.format('%s %s', g_graphics.getVendor(), g_graphics.getRenderer())) else msg:addString(g_graphics.getRenderer()) end msg:addString(g_graphics.getVersion()) end -- add RSA encrypted auth token if g_game.getFeature(GameAuthenticator) then offset = msg:getMessageSize() -- first RSA byte must be 0 msg:addU8(0) msg:addString(self.authenticatorToken) if g_game.getFeature(GameSessionKey) then msg:addU8(booleantonumber(self.stayLogged)) end paddingBytes = g_crypt.rsaGetSize() - (msg:getMessageSize() - offset) assert(paddingBytes >= 0) for i = 1, paddingBytes do msg:addU8(math.random(0, 0xff)) end msg:encryptRsa() end if g_game.getFeature(GameProtocolChecksum) then self:enableChecksum() end self:send(msg) if g_game.getFeature(GameLoginPacketEncryption) then self:enableXteaEncryption() end self:recv() end function ProtocolLogin:onConnect() self.gotConnection = true self:connectCallback() self.connectCallback = nil end function ProtocolLogin:onRecv(msg) while not msg:eof() do local opcode = msg:getU8() if opcode == LoginServerErrorNew then self:parseError(msg) elseif opcode == LoginServerError then self:parseError(msg) elseif opcode == LoginServerMotd then self:parseMotd(msg) elseif opcode == LoginServerUpdateNeeded then signalcall(self.onLoginError, self, tr("Client needs update.")) elseif opcode == LoginServerTokenSuccess then local unknown = msg:getU8() elseif opcode == LoginServerTokenError then -- TODO: prompt for token here local unknown = msg:getU8() signalcall(self.onLoginError, self, tr("Invalid authentification token.")) 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) elseif opcode == LoginServerSessionKey then self:parseSessionKey(msg) else self:parseOpcode(opcode, msg) end end self:disconnect() end function ProtocolLogin:parseError(msg) local errorMessage = msg:getString() signalcall(self.onLoginError, self, errorMessage) end function ProtocolLogin:parseMotd(msg) local motd = msg:getString() signalcall(self.onMotd, self, motd) end function ProtocolLogin:parseSessionKey(msg) local sessionKey = msg:getString() signalcall(self.onSessionKey, self, sessionKey) 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() world.worldIp = msg:getString() world.worldPort = msg:getU16() world.previewState = msg:getU8() 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 character.previewState = worlds[worldId].previewState 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.getFeature(GamePreviewState) then character.previewState = msg:getU8() end characters[i] = character end end local account = {} if g_game.getProtocolVersion() > 1077 then account.status = msg:getU8() account.subStatus = msg:getU8() account.premDays = msg:getU32() if account.premDays ~= 0 and account.premDays ~= 65535 then account.premDays = math.floor((account.premDays - os.time()) / 86400) end else account.status = AccountStatus.Ok account.premDays = msg:getU16() account.subStatus = account.premDays > 0 and SubscriptionStatus.Premium or SubscriptionStatus.Free end 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) end function ProtocolLogin:parseOpcode(opcode, msg) signalcall(self.onOpcode, self, opcode, msg) end function ProtocolLogin:onError(msg, code) local text = translateNetworkError(code, self:isConnecting(), msg) signalcall(self.onLoginError, self, text) end
Texto modificado
Abrir archivo
-- @docclass ProtocolLogin = extends(Protocol, "ProtocolLogin") LoginServerError = 10 LoginServerTokenSuccess = 12 LoginServerTokenError = 13 LoginServerUpdate = 17 LoginServerMotd = 20 LoginServerUpdateNeeded = 30 LoginServerSessionKey = 40 LoginServerCharacterList = 100 LoginServerExtendedCharacterList = 101 -- Since 10.76 LoginServerRetry = 10 LoginServerErrorNew = 11 function ProtocolLogin:login(host, port, accountName, accountPassword, authenticatorToken, stayLogged) if string.len(host) == 0 or port == nil or port == 0 then signalcall(self.onLoginError, self, tr("You must enter a valid server address and port.")) return end self.accountName = accountName self.accountPassword = accountPassword self.authenticatorToken = authenticatorToken self.stayLogged = stayLogged self.connectCallback = self.sendLoginPacket self:connect(host, port) end function ProtocolLogin:cancelLogin() self:disconnect() end function ProtocolLogin:sendLoginPacket() local msg = OutputMessage.create() msg:addU8(ClientOpcodes.ClientEnterAccount) msg:addU16(g_game.getOs()) msg:addU16(g_game.getProtocolVersion()) if g_game.getFeature(GameClientVersion) then msg:addU32(g_game.getClientVersion()) end if g_game.getFeature(GameContentRevision) then msg:addU16(g_things.getContentRevision()) msg:addU16(0) else msg:addU32(g_things.getDatSignature()) end msg:addU32(g_sprites.getSprSignature()) msg:addU32(PIC_SIGNATURE) if g_game.getFeature(GamePreviewState) then msg:addU8(0) end local offset = msg:getMessageSize() if g_game.getFeature(GameLoginPacketEncryption) then -- 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 if g_game.getFeature(GameAccountNames) then msg:addString(self.accountName) else msg:addU32(tonumber(self.accountName)) 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) for i = 1, paddingBytes do msg:addU8(math.random(0, 0xff)) end if g_game.getFeature(GameLoginPacketEncryption) then msg:encryptRsa() end if g_game.getFeature(GameOGLInformation) then msg:addU8(1) --unknown msg:addU8(1) --unknown if g_game.getClientVersion() >= 1072 then msg:addString(string.format('%s %s', g_graphics.getVendor(), g_graphics.getRenderer())) else msg:addString(g_graphics.getRenderer()) end msg:addString(g_graphics.getVersion()) end -- add RSA encrypted auth token if g_game.getFeature(GameAuthenticator) then offset = msg:getMessageSize() -- first RSA byte must be 0 msg:addU8(0) msg:addString(self.authenticatorToken) if g_game.getFeature(GameSessionKey) then msg:addU8(booleantonumber(self.stayLogged)) end paddingBytes = g_crypt.rsaGetSize() - (msg:getMessageSize() - offset) assert(paddingBytes >= 0) for i = 1, paddingBytes do msg:addU8(math.random(0, 0xff)) end msg:encryptRsa() end if g_game.getFeature(GameProtocolChecksum) then self:enableChecksum() end self:send(msg) if g_game.getFeature(GameLoginPacketEncryption) then self:enableXteaEncryption() end self:recv() end function ProtocolLogin:onConnect() self.gotConnection = true self:connectCallback() self.connectCallback = nil end function ProtocolLogin:onRecv(msg) while not msg:eof() do local opcode = msg:getU8() if opcode == LoginServerErrorNew then self:parseError(msg) elseif opcode == LoginServerError then self:parseError(msg) elseif opcode == LoginServerMotd then self:parseMotd(msg) elseif opcode == LoginServerUpdateNeeded then signalcall(self.onLoginError, self, tr("Client needs update.")) elseif opcode == LoginServerTokenSuccess then local unknown = msg:getU8() elseif opcode == LoginServerTokenError then -- TODO: prompt for token here local unknown = msg:getU8() signalcall(self.onLoginError, self, tr("Invalid authentification token.")) 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) elseif opcode == LoginServerSessionKey then self:parseSessionKey(msg) else self:parseOpcode(opcode, msg) end end self:disconnect() end function ProtocolLogin:parseError(msg) local errorMessage = msg:getString() signalcall(self.onLoginError, self, errorMessage) end function ProtocolLogin:parseMotd(msg) local motd = msg:getString() signalcall(self.onMotd, self, motd) end function ProtocolLogin:parseSessionKey(msg) local sessionKey = msg:getString() signalcall(self.onSessionKey, self, sessionKey) 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() world.worldIp = msg:getString() world.worldIp = "127.0.0.1" world.worldPort = msg:getU16() world.previewState = msg:getU8() 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.worldIp = "127.0.0.1" character.worldPort = worlds[worldId].worldPort character.previewState = worlds[worldId].previewState 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.worldIp = "127.0.0.1" character.worldPort = msg:getU16() if g_game.getFeature(GamePreviewState) then character.previewState = msg:getU8() end characters[i] = character end end local account = {} if g_game.getProtocolVersion() > 1077 then account.status = msg:getU8() account.subStatus = msg:getU8() account.premDays = msg:getU32() if account.premDays ~= 0 and account.premDays ~= 65535 then account.premDays = math.floor((account.premDays - os.time()) / 86400) end else account.status = AccountStatus.Ok account.premDays = msg:getU16() account.subStatus = account.premDays > 0 and SubscriptionStatus.Premium or SubscriptionStatus.Free end 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) end function ProtocolLogin:parseOpcode(opcode, msg) signalcall(self.onOpcode, self, opcode, msg) end function ProtocolLogin:onError(msg, code) local text = translateNetworkError(code, self:isConnecting(), msg) signalcall(self.onLoginError, self, text) end
Encontrar la diferencia