Diff
checker
文本
文本
图像
文档
Excel
文件夹
Legal
Enterprise
桌面版
定价
登录
下载 Diffchecker 桌面版
比较文本
查找两个文本文件之间的差异
工具
历史
实时编辑器
折叠未更改行
关闭换行
视图
拆分
统一
比对精度
智能
单词
字符
语法高亮
选择语法
忽略
文本转换
转到第一个差异
编辑输入
Diffchecker Desktop
运行Diffchecker最安全的方式。获取Diffchecker桌面应用:您的差异永远不会离开您的电脑!
获取桌面版
otclient-master\modules\gamelib/protocollogin.lua
创建于
5年前
差异永不过期
清除
导出
分享
解释
1 删除
行
总计
删除
字符
总计
删除
要继续使用此功能,请升级到
Diff
checker
Pro
查看价格
275 行
全部复制
3 添加
行
总计
添加
字符
总计
添加
要继续使用此功能,请升级到
Diff
checker
Pro
查看价格
277 行
全部复制
-- @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()
复制
已复制
复制
已复制
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
复制
已复制
复制
已复制
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())
复制
已复制
复制
已复制
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
复制
已复制
复制
已复制
已保存差异
原始文本
打开文件
-- @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
更改后文本
打开文件
-- @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
查找差异