• 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!

C++ tibia 10.90 login protocol, how it works ?

sailorv5

Member
Joined
Oct 31, 2009
Messages
82
Reaction score
17
i created a Qt network project (using network-chat exemple)
and set its server to listen on port 7171

when i try to connect to it using tibia Client (username:1/password:1) i get the following anwser (from the tibia client, also may change)
Code:
buffer.size() -> 166

buffer.toHex() -> "5a01248d7c18010200420442040000263f000071e15e560ca730560047fc19d77bf2480763d6904155b1e61375bbc54a9d2991d8a5f7601f1630cec778ffb195a21776a9af3262f9eab34c64093cfdd17fcf6ce7c80457ea2b8fa61d4b2dac48115b54a26cab2d82e05711eb57aaf6a129c23efa822612fde0195cbd092c9d14fc9bcf29d75b777ab1e83f95439cac52721887d5adb4f65853eff97b01011f00496e74656c20"

by doing buffer.mid() i can get/cut any part of that buffer ex.
Code:
QByteArray x("Five pineapples");
QByteArray y = x.mid(5, 4);     // y == "pine"

my question is how can i decode this login request ?
and if possible how to send back a FakeList of character with one character.
i would love if the anwser ( looks like this format )

Code:
// "5a01
//    248d 7c18
//    0102 0042
//    0442 0400
//    0026 3f00
//    00
//    71e15e560ca730560047fc19d77bf2480763d6904155b1e61375bbc54a9d2991d8a5f7601f1630cec778ffb195a21776a9af3262f9eab34c64093cfdd17fcf6ce7c80457ea2b8fa61d4b2dac48115b54a26cab2d82e05711eb57aaf6a129c23efa822612fde0195cbd092c9d14fc9bcf29d75b777ab1e83f95439cac52721887d5adb4f65853eff97b01011f00496e74656c20"
 
     QByteArray os = x.mid(0, 4);                   // [5a01]         2bytes client OS
     QByteArray protocolVersion = x.mid(4, 8);      // [248d 7c18]    4bytes protocolVersion
     QByteArray dat = x.mid(12, 8);                 // [0102 0042]    4bytes client dat
     QByteArray spr = x.mid(20, 8);                 // [0442 0400]    4bytes client spr
     QByteArray pic = x.mid(28, 8);                 // [0026 3f00]    4bytes client pic
 
     QByteArray unknow = x.mid(36, 2);              // [00]       1byte  suposed to be zero?
//    buffer = QByteArray::fromHex( x) ;
1HEX = 4bits, 8bits = 1Byte, 1Byte = 2HEX
using HEX to make it easy to be undestand by me final result will use only bytes without any conversion.

 
Last edited:
Solution
is Adlers checksum just to confirm is it the sum of the tibia signature ( dat,spr,pic) ?
checksum of buffer are usually used to check integrity of packets that client sent to you, then client write also their checksum then you can compare to check if both client and server are talking about the same thing, after that you need also to decrypt your buffer with RSA.
Although you are using QNetwork, which are a cool framework to work with, but you skipped the basics of networking, i suggest you get some time to read basics of networking, if helps you i've wrote a parser only for first packet login request, also i tried to comment everything i could, if something wasn't clear just let me know.
login_parser.c · GitHub
ps: if you...
. Thank you for your time and help.
I sure hope you understand that the ot client and server was the first thing I downloaded using Google search.
But some how it isn't very clear how they are implemented, and having 4 classes to handle packet/network and any indication to follow makes something very simple become a very hard puzzle.

_____
Later I ll update the post with what I managed to discover after a few nights of nightmare.
---------
[EDIT:1]
Code:
_________________________________________________________________________________________________
Credits to Blaster_89
TcpClient (Tibia 7.6)   Login
-------------------------------------------------------------------------------------------------
2 byets packet length
1 byte packet type
2 bytes OS (1=linux, 2=windows)
2 bytes tibia client version (i.e. 7.4=740, 7.6=760)
12 bytes files version (tibia.dat, tibia.spr, tibia.pic)
4 bytes account number
2 bytes password length
x bytes password

_________________________________________________________________________________________________

PHP:
_________________________________________________________________________________________________
Blaster_89
TcpClient (Tibia 7.6)   Character List
-------------------------------------------------------------------------------------------------
2 bytes packet length
1 byte packet type (0x14)
2 bytes motd length
x bytes motd (id:0-255 + message, example: 123 + "\n\nyaddayadda")
0x64 (not sure what this is)
1 byte amount of characters
--- loop this
---2 bytes character name length
---x bytes character name
---2 bytes server name length
---x bytes server name
---4 bytes server ip
---2 bytes server port
2 bytes premium days
-------------------------------------------------------------------------------------------------
Still looking for anything about 10.90.
 
Last edited:
But some how it isn't very clear how they are implemented, and having 4 classes to handle packet/network and any indication to follow makes something very simple become a very hard puzzle.
tfs has these different parsers because there is a apart login server, just like vanilla game, login server has nothing to do with game server, then tfs needs to emulate it
my question is how can i decode this login request ?
i don't get it, where you're stuck?
 
i don't get it, where you're stuck?
FIRST: i want to know Everything. ( i am trying to port otClient to my symbian Phone)
_________________________________________________________________________
THEN:
thank you for you Will to help me, after a lot of ?ReSearch? i found a usefull article that explain very good how it works (it is for an old tibia version 8.2) ONE of the point i was missing when i tryed to decript the packet was the size is short indian Format and that is not ever said in otsource.
Code:
// From ot source
        uint16_t getLengthHeader() const {
            return static_cast<uint16_t>(buffer[0] | buffer[1] << 8);
        }

// From my QT Source
return
                (((unsigned char)buffer[1]) << 8) +
                  (unsigned char)buffer[0];
for some unknow raison i need to cast char to (unsigned char) using + or bitwise | (or) did the same result is one faster than the other?
_________________________________________________________________________

NEXT STEP:
is Adlers checksum just to confirm is it the sum of the tibia signature ( dat,spr,pic) ?

_________________________________________________________________________
not sure if i can post Links to others Forum.
 
You want to decode the login request, to do this, you need to know what is the format of the request (like people mentioned already, check TFS source code for the answer) and convert parts of your buffer to appropriate data types. Then process them according to their meaning :)
 
is Adlers checksum just to confirm is it the sum of the tibia signature ( dat,spr,pic) ?
checksum of buffer are usually used to check integrity of packets that client sent to you, then client write also their checksum then you can compare to check if both client and server are talking about the same thing, after that you need also to decrypt your buffer with RSA.
Although you are using QNetwork, which are a cool framework to work with, but you skipped the basics of networking, i suggest you get some time to read basics of networking, if helps you i've wrote a parser only for first packet login request, also i tried to comment everything i could, if something wasn't clear just let me know.
login_parser.c · GitHub
ps: if you want to compile it you need GNU Multiple Precision library, if you have compiled tfs before you already have it, just tell the linker you're using it,
gcc -g -o login_parser login_parser.c -lgmp
 
Solution
Back
Top