Diff
checker
Text
Text
Bilder
Dokumente
Excel
Ordner
Legal
Enterprise
Desktop-App
Preise
Einloggen
Diffchecker Desktop herunterladen
Texte vergleichen
Finde den Unterschied zwischen zwei Textdateien
Werkzeuge
Verlauf
Live-Editor
Gleiches ausblenden
Zeilenumbruch aus
Ansicht
Zweispaltig
Einspaltig
Vergleichsgenauigkeit
Intelligent
Wort
Zeichen
Syntaxhervorhebung
Syntax auswählen
Ignorieren
Text umwandeln
Zur ersten Änderung
Eingabe bearbeiten
Diffchecker Desktop
Der sicherste Weg, Diffchecker zu nutzen. Hol dir die Desktop-App: Deine Diffs verlassen nie deinen Computer!
Desktop holen
otclient-master\modules\gamelib/protocollogin.lua
Erstellt
vor 5 Jahren
Diff läuft nie ab
Löschen
Exportieren
Teilen
Erklären
1 Entfernung
Zeilen
Gesamt
Entfernt
Zeichen
Gesamt
Entfernt
Um diese Funktion weiterhin zu nutzen, aktualisiere auf
Diff
checker
Pro
Preise anzeigen
275 Zeilen
Kopieren
3 Hinzufügungen
Zeilen
Gesamt
Hinzugefügt
Zeichen
Gesamt
Hinzugefügt
Um diese Funktion weiterhin zu nutzen, aktualisiere auf
Diff
checker
Pro
Preise anzeigen
277 Zeilen
Kopieren
-- @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()
Kopieren
Kopiert
Kopieren
Kopiert
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
Kopieren
Kopiert
Kopieren
Kopiert
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())
Kopieren
Kopiert
Kopieren
Kopiert
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
Kopieren
Kopiert
Kopieren
Kopiert
Gespeicherte Diffs
Originaltext
Datei öffnen
-- @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
Bearbeitung
Datei öffnen
-- @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
Unterschied finden