• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Tibia OTClient 7.4 with Real Tibia features

Danger II

tibiara.com
Joined
Nov 21, 2012
Messages
1,709
Solutions
13
Reaction score
642
Location
Germany
I am planing to delete everything that has to do with Tibia from my harddisk therefore I will publish files, I do not need anymore but the community.

I just packed them quickly, maybe they contain any copied files or wont even work at all (I doubt that).
I won't support help at all.
If you don't know how to work with them, do not download it.

This Client should contain files from this thread:
Gaming - OTClient vs Real Tibia Client 7.x

MEGA
 
How to use it to enter my server? I can not make it work. Thanks for share
 
@Danger II
First of all, thank you for this release!

I have compiled this perfectly in msvs in OpenGL/DX9 without errors in logs.

The .exe OGL works fine, .exe DX9 dont open.

I have used the preprocessor OPENGL_ES=2. This parameter is correctly for compile your client in DX9?

Thank you!!!!
 
I cant login, it said:

Login Error
Your connection has been lost.
Either your network or the server went down. (ERROR 2)

RSA ? how to fix it please
 
I cant login with OTHIRE, what server can i use with this client ?
 
I hate to bump an old thread but is it possible too make it work for 860 ive tried it a few times and getting errors in my TFS RSA related.
 
yopu have to change the rsa at const..lua
and change the ip and protocol inside entergame.lua, otmod or otui i don't rememeber

for those one that want to use it at 772 the client has spoofed protocol
so you can revert it following this tutorial
Spoof otclient version (https://otland.net/threads/spoof-otclient-version.251915/)

I want to use this with the nostalrius 7.72. I changed the RSA in const.lua

Code:
OTSERV_RSA  = "124657562281096214728670002485200877832442343707438205084477397996314331558950970278630804642443947209357197128937773341700187097389682681927983111817101958221407635774810784838823216970764471679903942275983502592654814340829400819408719991995991389058242262577000896205686954783449675132494875272433261196821"

But still can't connect. Your talking about having to do some work in protocollogin.lua because of spoofed protocol for 7.72
i tried following the tutorial. but i can't seem to make it work or understand it. If anyone know what im doing wrong and would like to help I would really appreciate it.

Code:
-- @docclass
ProtocolLogin = extends(Protocol, "ProtocolLogin")

LoginServerError = 10
LoginServerUpdate = 17
LoginServerMotd = 20
LoginServerUpdateNeeded = 30
LoginServerCharacterList = 100
LoginServerExtendedCharacterList = 101

function ProtocolLogin:login(host, port, accountName, accountPassword)
  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.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(6453)
  msg:addU16(8678)
  msg:addU16(CLIENT_VERSION)
 
  if g_game.getClientVersion() >= 980 then
    msg:addU32(g_game.getClientVersion())
  end

  msg:addU32(g_things.getDatSignature())
  msg:addU32(g_sprites.getSprSignature())
  msg:addU32(PIC_SIGNATURE)

  if g_game.getClientVersion() >= 980 then
    msg:addU8(0) -- clientType
  end

  local offset = msg:getMessageSize()

  if g_game.getClientVersion() >= 770 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)
  msg:addPaddingBytes(paddingBytes, 0)
  if g_game.getClientVersion() >= 770 then
    msg:encryptRsa()
  end

  if g_game.getFeature(GameProtocolChecksum) then
    self:enableChecksum()
  end

  self:send(msg)
  if g_game.getClientVersion() >= 770 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 == LoginServerError then
      self:parseError(msg)
    elseif opcode == LoginServerMotd then
      self:parseMotd(msg)
    elseif opcode == LoginServerUpdateNeeded then
      signalcall(EnterGame.onUpdateNeeded, self)
    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)
    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: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()
      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
  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)
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
 
Compare to original files.

These two lines were added for extra encryption so nobody could easily login with standard otclient.
 
I want to use this with the nostalrius 7.72. I changed the RSA in const.lua

Code:
OTSERV_RSA  = "124657562281096214728670002485200877832442343707438205084477397996314331558950970278630804642443947209357197128937773341700187097389682681927983111817101958221407635774810784838823216970764471679903942275983502592654814340829400819408719991995991389058242262577000896205686954783449675132494875272433261196821"

But still can't connect. Your talking about having to do some work in protocollogin.lua because of spoofed protocol for 7.72
i tried following the tutorial. but i can't seem to make it work or understand it. If anyone know what im doing wrong and would like to help I would really appreciate it.

Code:
-- @docclass
ProtocolLogin = extends(Protocol, "ProtocolLogin")

LoginServerError = 10
LoginServerUpdate = 17
LoginServerMotd = 20
LoginServerUpdateNeeded = 30
LoginServerCharacterList = 100
LoginServerExtendedCharacterList = 101

function ProtocolLogin:login(host, port, accountName, accountPassword)
  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.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(6453)
  msg:addU16(8678)
  msg:addU16(CLIENT_VERSION)

  if g_game.getClientVersion() >= 980 then
    msg:addU32(g_game.getClientVersion())
  end

  msg:addU32(g_things.getDatSignature())
  msg:addU32(g_sprites.getSprSignature())
  msg:addU32(PIC_SIGNATURE)

  if g_game.getClientVersion() >= 980 then
    msg:addU8(0) -- clientType
  end

  local offset = msg:getMessageSize()

  if g_game.getClientVersion() >= 770 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)
  msg:addPaddingBytes(paddingBytes, 0)
  if g_game.getClientVersion() >= 770 then
    msg:encryptRsa()
  end

  if g_game.getFeature(GameProtocolChecksum) then
    self:enableChecksum()
  end

  self:send(msg)
  if g_game.getClientVersion() >= 770 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 == LoginServerError then
      self:parseError(msg)
    elseif opcode == LoginServerMotd then
      self:parseMotd(msg)
    elseif opcode == LoginServerUpdateNeeded then
      signalcall(EnterGame.onUpdateNeeded, self)
    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)
    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: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()
      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
  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)
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

I have the same problem, dude.
 
I'm trying to set this client working with my server IP
Any ideas?
Thank you
 
Back
Top