More multiprotocol support

This commit is contained in:
Eduardo Bart
2012-07-26 03:10:28 -03:00
parent e393bc245d
commit c795eb91ab
43 changed files with 421 additions and 341 deletions

View File

@@ -71,6 +71,9 @@ CIPSOFT_RSA = "1321277432058722840622950990822933849527763264961655079678763618"
"2907336840325241747827401343576296990629870233111328210165697754" ..
"88792221429527047321331896351555606801473202394175817"
-- set to the latest Tibia.pic signature to make otclient compatible with official tibia
PIC_SIGNATURE = 1337606793
OsTypes = {
Linux = 1,
Windows = 2,

View File

@@ -11,6 +11,7 @@ InventorySlotLeg = 7
InventorySlotFeet = 8
InventorySlotFinger = 9
InventorySlotAmmo = 10
InventorySlotPurse = 11
InventorySlotFirst = 1
InventorySlotLast = 10

View File

@@ -1,89 +1,11 @@
-- @docclass
ProtocolLogin = extends(Protocol)
-- set to the latest Tibia.pic signature to make otclient compatible with official tibia
local PIC_SIGNATURE = 1337606793
LoginServerError = 10
LoginServerMotd = 20
LoginServerUpdateNeeded = 30
LoginServerCharacterList = 100
-- private functions
local function sendLoginPacket(protocol)
local msg = OutputMessage.create()
msg:addU8(ClientOpcodes.ClientEnterAccount)
msg:addU16(g_game.getOsType())
msg:addU16(g_game.getProtocolVersion())
msg:addU32(g_things.getDatSignature())
msg:addU32(g_sprites.getSprSignature())
msg:addU32(PIC_SIGNATURE)
local paddingBytes = 128
msg:addU8(0) -- first RSA byte must be 0
paddingBytes = paddingBytes - 1
-- xtea key
protocol:generateXteaKey()
local xteaKey = protocol:getXteaKey()
msg:addU32(xteaKey[1])
msg:addU32(xteaKey[2])
msg:addU32(xteaKey[3])
msg:addU32(xteaKey[4])
paddingBytes = paddingBytes - 16
if g_game.getFeature(GameProtocolChecksum) then
protocol:enableChecksum()
end
if g_game.getFeature(GameAccountNames) then
msg:addString(protocol.accountName)
msg:addString(protocol.accountPassword)
paddingBytes = paddingBytes - (4 + string.len(protocol.accountName) + string.len(protocol.accountPassword))
else
msg:addU32(tonumber(protocol.accountName))
msg:addString(protocol.accountPassword)
paddingBytes = paddingBytes - (6 + string.len(protocol.accountPassword))
end
msg:addPaddingBytes(paddingBytes, 0)
msg:encryptRsa(128, g_game.getRsa())
protocol:send(msg)
protocol:enableXteaEncryption()
protocol:recv()
end
-- events
function ProtocolLogin:onConnect()
self:connectCallback(self)
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
signalcall(self.onError, self, tr("Client needs update."))
elseif opcode == LoginServerCharacterList then
self:parseCharacterList(msg)
else
self:parseOpcode(opcode, msg)
end
end
self:disconnect()
end
-- public functions
function ProtocolLogin.create()
return ProtocolLogin.internalCreate()
end
function ProtocolLogin:login(host, port, accountName, accountPassword)
if string.len(accountName) == 0 or string.len(accountPassword) == 0 then
signalcall(self.onError, self, tr("You must enter an account name and password."))
@@ -105,6 +27,73 @@ function ProtocolLogin:cancelLogin()
self:disconnect()
end
function ProtocolLogin:sendLoginPacket()
local msg = OutputMessage.create()
msg:addU8(ClientOpcodes.ClientEnterAccount)
msg:addU16(g_game.getOsType())
msg:addU16(g_game.getClientVersion())
msg:addU32(g_things.getDatSignature())
msg:addU32(g_sprites.getSprSignature())
msg:addU32(PIC_SIGNATURE)
local paddingBytes = 128
msg:addU8(0) -- first RSA byte must be 0
paddingBytes = paddingBytes - 1
-- xtea key
self:generateXteaKey()
local xteaKey = self:getXteaKey()
msg:addU32(xteaKey[1])
msg:addU32(xteaKey[2])
msg:addU32(xteaKey[3])
msg:addU32(xteaKey[4])
paddingBytes = paddingBytes - 16
if g_game.getFeature(GameProtocolChecksum) then
self:enableChecksum()
end
if g_game.getFeature(GameAccountNames) then
msg:addString(self.accountName)
msg:addString(self.accountPassword)
paddingBytes = paddingBytes - (4 + string.len(self.accountName) + string.len(self.accountPassword))
else
msg:addU32(tonumber(self.accountName))
msg:addString(self.accountPassword)
paddingBytes = paddingBytes - (6 + string.len(self.accountPassword))
end
msg:addPaddingBytes(paddingBytes, 0)
msg:encryptRsa(128, g_game.getRsa())
self:send(msg)
self:enableXteaEncryption()
self:recv()
end
function ProtocolLogin:onConnect()
self:sendLoginPacket()
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
signalcall(self.onError, self, tr("Client needs update."))
elseif opcode == LoginServerCharacterList then
self:parseCharacterList(msg)
else
self:parseOpcode(opcode, msg)
end
end
self:disconnect()
end
function ProtocolLogin:parseError(msg)
local errorMessage = msg:getString()
signalcall(self.onError, self, errorMessage)