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

Feature [TFS 1.x+] Print all send network packets in server console

Gesior.pl

Mega Noob&LOL 2012
Senator
Joined
Sep 18, 2007
Messages
2,955
Solutions
98
Reaction score
3,351
Location
Poland
GitHub
gesior
If you are working on protocol downgrade and get client debugs, you may want to view what bytes were send to Tibia Client before debug.
Tibia Client 'error report' after crash shows only few last bytes.

Only way to view all send bytes is to print them in server console or write to some file.
Here is code that print all bytes to server console.

In connection.cpp replace:
C++:
void Connection::send(const OutputMessage_ptr& msg)
{
   std::lock_guard<std::recursive_mutex> lockClass(connectionLock);
   if (closed) {
      return;
   }

   bool noPendingWrite = messageQueue.empty();
   messageQueue.emplace_back(msg);
   if (noPendingWrite) {
      internalSend(msg);
   }
}
with:
C++:
void Connection::send(const OutputMessage_ptr& msg)
{
   std::lock_guard<std::recursive_mutex> lockClass(connectionLock);
   if (closed) {
      return;
   }

   uint8_t* tmpOutputBuffer = msg->getOutputBuffer();
   std::cout << "PACKET: ";
   for (int i = 0; i < msg->getLength(); i++) {
      std::cout << (int) tmpOutputBuffer[i] << " ";
   }
   std::cout << std::endl;

   bool noPendingWrite = messageQueue.empty();
   messageQueue.emplace_back(msg);
   if (noPendingWrite) {
      internalSend(msg);
   }
}

Tested on Nekiro 1.5 downgrade.

Example server console:
Code:
PACKET: 107 253 3 1 4 7 1 99 0 2 0 0 64 2
PACKET: 109 0 4 3 4 7 1 255 3 3 4 7
PACKET: 109 252 3 2 4 7 4 253 3 2 4 7
PACKET: 134 0 0 0 64 0 131 254 3 2 4 7 4
PACKET: 134 1 0 0 64 0 108 254 3 2 4 7 2 105 254 3 2 4 7 253 3 237 17 98 0 7 0 0 16 76 0 136 0 0 0 0 0 0 0 220 0 0 0 151 16 151 16 151 16 151 16 151 16 151 16 0 255 106 254 3 2 4 7 73 11 2 131 254 3 2 4 7 1 180 20 48 0 89 111 117 32 108 111 115 101 32 51 32 104 105 116 112 111 105 110 116 115 32 100 117 101 32 116 111 32 97 110 32 97 116 116 97 99 107 32 98 121 32 97 32 98 101 97 114 46 132 254 3 2 4 7 180 1 0 51 160 111 0 150 0 77 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 160 111 0 150 0 77 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 140 7 0 0 16 74
PACKET: 107 253 3 1 4 7 1 99 0 2 0 0 64 1 134 2 0 0 64 0 108 254 3 2 4 7 2 105 254 3 2 4 7 253 3 237 17 98 0 7 0 0 16 74 0 136 0 0 0 0 0 0 0 220 0 0 0 151 16 151 16 151 16 151 16 151 16 151 16 0 255 106 254 3 2 4 7 73 11 2 131 254 3 2 4 7 1 180 20 47 0 89 111 117 32 108 111 115 101 32 56 32 104 105 116 112 111 105 110 116 115 32 100 117 101 32 116 111 32 97 110 32 97 116 116 97 99 107 32 98 121 32 97 32 98 117 103 46 132 254 3 2 4 7 180 1 0 56 160 103 0 150 0 77 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 160 103 0 150 0 77 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 140 7 0 0 16 69

EDIT:
Version that prints single OTS packets, not network packets send to client, which may contain multiple OTS packets.
It also prints packets in hex format.
In protocolgame.cpp under:
C++:
void ProtocolGame::writeToOutputBuffer(const NetworkMessage& msg)
{
Paste:
C++:
const uint8_t *tmpOutputBuffer = msg.getBuffer();
std::cout << std::hex;
for (int i = 0; i < msg.getLength(); i++) {
   std::cout << (int) (tmpOutputBuffer[i] / 16) << (int) tmpOutputBuffer[i] % 16;
}
std::cout << std::endl;
std::cout << std::dec;
Example output:
Code:
6dfb0300040701fc03000407
aa0300000004005445737401fe0302040705003132333435
 
Last edited:
Exceptionally useful, thank you very much for this!
 
Nice!... and how to know the new bytes from the latest tibia version?
This feature helps only in downgrading protocols. When your server sends packets from new tibia version and old (ex. 8.6) Tibia Client crashes.

@Nottinghster is trying to convert his old datapack to work with Nekiro 1.5 8.60 protocol. He gets client debug, when monster die. He sent me his packet log and I did analysis using protocolgame.cpp:
Code:
PACKET: 160 80 8 195 20 1 237 0 0 8 3 223 41 94 1 0 17 3 8 7 11 0 115 204 9 180 24 34 0 89 111 117 32 103 97 105 110 101 100 32 49 54 53 48 32 101 120 112 101 114 105 101 110 99 101 32 112 111 105 110 116 115 46 132 187 129 150 123 13 215 4 0 49 54 53 48 160 80 8 195 20 1 237 0 0 122 9 223 41 94 1 0 17 3 8 7 11 0 115 204 9 106 187 129 149 123 13 2 205 31 180 0 33 0 76 111 111 116 32 111 102 32 97 32 102 105 114 101 32 101 108 101 109 101 110 116 97 108 58 32 110 111 116 104 105 110 103 108 187 129 149 123 13 1 163 0 0 0 0

160  // AddPlayerStats
80 8 
195 20
 1 237 0 0 
 8 3 223 41 
 94 1 
 0 
 17 3
 8 7 // mana max
 11 
 0 
 115
 204 9 
 
 180 // sendTextMessage
 24 - message type (default -white in console)
 34  0 // length
 89 111 117 32
 103 97 105 110
 101 100 32 49 
 54 53 48 32 
 101 120 112  101 
 114 105 101  110 
 99 101 32 112 
 111 105 110  116
 115  46 
message: "You gained 1650 experience points."
 
 132 // sendAnimatedText
 187 129 150 123 13 - position
 215 - color
 4 0 - length
 49 54 53 48  - value '1650'
 
 160 // AddPlayerStats
 80 8 
 195 20 
 1 237 0 0 
 122 9 223 41
 94 1 
 0 
 17 3 
 8 7 
 11 
 0 
 115 
 204 9 
 
 106 // sendAddTileItem
 187 129 149 123 13 - position
 2 - stack pos
 205 31 - item id 8141 (.dat ID, not items.xml)
 
 180 // sendTextMessage
 0 - type: 0
 33 0 - length 33 letters
 76 111 111 116 
 32 111 102 32 
 97 32 102 105 
 114 101 32 101 
 108 101 109 101 
 110 116 97 108 
 58 32 110 111 
 116 104 105 110 
 103 
 message: "Loot of a fire elemental: nothing"
 
 108 // RemoveTileThing
 187 129 149 123 13 - position
 1 - stack
 
 163 // sendCancelTarget
 0 0 0 0 - set target to '0'

With packet log I found out that there is loot message with type set to 0 (type like orange text in console, blue text in console) which is invalid:
Code:
 180 // sendTextMessage
 0 - type: 0
 33 0 - length 33 letters
 76 111 111 116 
 32 111 102 32 
 97 32 102 105 
 114 101 32 101 
 108 101 109 101 
 110 116 97 108 
 58 32 110 111 
 116 104 105 110 
 103 
 message: "Loot of a fire elemental: nothing"

If you know how to find out which bytes are 'text', you can use my PHP tool to convert decimal bytes to readable text. I split it into 4 bytes per line, to make it easier to count 33 letters, but tool can handle it in any format. You can event put whole packet in it.
PHP:
<?php

$s = ' 76 111 111 116 
 32 111 102 32 
 97 32 102 105 
 114 101 32 101 
 108 101 109 101 
 110 116 97 108 
 58 32 110 111 
 116 104 105 110 
 103 ';
 
 $s = trim($s);
 $s = str_replace("\n", " ", $s);
 $s = str_replace("\r", " ", $s);
 for ($i = 0; $i < 10; $i++) {
     $s = str_replace("  ", " ", $s);
 }

 $e = explode(' ', $s);

 foreach($e as $l) {
     echo chr($l);
 }
echo PHP_EOL;
 
As I said to you in Discord, with your help, I figured out the problem, and it was so easy to fix it.
The problem was in function default_onDropLoot, the message type was defined to MESSAGE_LOOT, wich wasn't defined anywhere, just changed to MESSAGE_INFO_DESCR and works again, it was my own mistake 😅

Really appreciate your help, you're the best @Gesior.pl
 
So an example, I have this PACKET:

Code:
00000f00
PACKET: 20 42 0 65 99 99 111 117 110 116 32 110 117 109 98 101 114 32 111 114 32 112 97 115 115 119 111 114 100 32 105 115 32 110 111 116 32 99 111 114 114 101 99 116 46

If i understood well, to know WHAT this decimals want to say me i need to convert to hex, right?
Using your example:
Code:
 132 // sendAnimatedText
you know that this is ANIMATEDTEXT because
Code:
132 = 0x84
that's it?

Code:
ERROR: invalid message size
at:
    [C++]: ?onRecv@ProtocolGame@@MAEXABV?$shared_object_ptr@VInputMessage@@@stdext@@@Z

So yeah, probably I get this error for bad code, but still want to learn how to solve this
 
Last edited:
Would it be possible to save it to a log file? Sometimes it is not possible to identify the package because of so many numbers, especially when the debug is when logging in.
 
Would it be possible to save it to a log file? Sometimes it is not possible to identify the package because of so many numbers, especially when the debug is when logging in.
I made a repo with some very basic cam system added to server TFS 1.4 protocol 8.0 (nekiro downgrade). It records all send/received packets for each player online:
It's called tmp-cams-system as it was not tested yet on any big server :(

Cams recorded are compatible with OTCv8 cam system. How to record and play '.cam' files in OTCv8 I've described here:
 
I've had this implemented but disabled in production for about a year I guess - i'll finally enable it shortly and see how it goes.
Some minor changes were made on implementation, including changing the naming convention to something like: YYYY-MM-DD_HH-MM-SS_PLAYERID_PLAYERNAME
As the total size of accumulated cams will get very large very fast, i'll probably add something to archive each cam after creation too - or offload them directly to an S3 bucket.
 
Back
Top