jo3bingham
Excellent OT User
This information only applies to the Tibia 11 client since these features were only implemented on that client. I think I covered everything. If I missed anything, please feel free to let me know. If you have any questions, I'll try my best to answer them.
Client Packets
Inspect Item
Info: 6 bytes. First byte seems to always be 0 in my tests. The last 5 bytes are the position of the item.
Psuedo-code:
Inspect Player
Info: 1 or 5 bytes. First byte is 'inspection state'. The last 4 bytes are available only if 'inspection state' is <= 5. If available, the last 4 bytes are the target player's id. After you log in, the client will send this packet to the server with either 6 or 7 depending on your client settings (not sure which value, if any, the Tibia 10 client sends).
Pseudo-code:
Modified
Edit VIP
Info: Bytes equal to the number of groups, and their IDs, the VIP is part of were added to the end of the packet.
Pseudo-code:
Server Packets
Inspection List
Info: First byte indicates whether the inspection is for a player or item (0 = item, 1 = player). Next byte is the number of items in the inspection list (items only contain 1 item, players can contain up to 10 [one for each slot]). Item data starts with the item's name, then, if inspection is for a player, the next byte will indicate the slot id of the item, followed by 2 bytes for the item's id, then (always in my tests) 0xFF, then, if the item is stackable, 1 byte for the count. Next we have 1 byte for the number of imbuement slots followed by 2 bytes for each slot which contains the imbuement's id. Now we get to the details. The first byte is the number of details then you have two strings for each detail. First string is the detail (e.g., Weight), and the second is the description (e.g., 2.5 oz). Now, if applicable, we get the player data. First thing is the player's name. Next is the outfit information (first 2 bytes are the outfit id, then 1 byte for head color, then 1 byte for body color, then 1 byte for legs color, then 1 byte for feet color, and, lastly, 1 byte for addons). Finally, we have the player's details. Just like with items, the first byte is the number of details then you have two strings for each detail. First string is the detail (e.g., Level), and the second is the description (e.g., 100).
Pseudo-code:
Inspection State
Info: 5 bytes. First 4 bytes are the player's id who's 'inspection state' has changed. Last byte is their new 'inspection state'.
Pseudo-code:
VIP Group Data
Info: Pretty simple. Just the data for each VIP group.
Pseudo-code:
Modified
sendVIP()
Info: Bytes equal to the number of groups, and their IDs, the VIP is part of were added to the end of the packet.
Pseudo-code:
AddCreature()
Info: While not exactly a packet, this is the message information for a creature. The modification only applies to 'Unknown' (0x61) and 'Outdated' (0x62) creatures. It's a single byte after the creature's 'mark' that indicates 'inspection state'. Most creatures will have the value 0 (always true if they're on Flash or Tibia 10 client), or 4 if their "Allow All to Inspect Me" setting is enabled (Tibia 11 only). Otherwise, they'll have a value depending on your last 'inspect' interaction with them.
Pseudo-code:
Client Packets
New
NEW- Inspect Item - 0xCD
- Inspect Player - 0xCE
- Edit VIP - 0xDE
- N/A
Inspect Item
Info: 6 bytes. First byte seems to always be 0 in my tests. The last 5 bytes are the position of the item.
Psuedo-code:
C++:
auto unknown = msg.getByte();
auto x = msg.get<uint16_t>();
if (x == 0xFFFF) {
auto slotOrContainerId = msg.get<uint16_t>();
auto index = msg.getByte();
} else {
auto y = msg.get<uint16_t>();
auto z = msg.getByte();
// As you can see, there isn't a byte for stack position,
// so the server probably just determines the top takeable
// item based on the x, y, z coordinates.
}
Inspect Player
Info: 1 or 5 bytes. First byte is 'inspection state'. The last 4 bytes are available only if 'inspection state' is <= 5. If available, the last 4 bytes are the target player's id. After you log in, the client will send this packet to the server with either 6 or 7 depending on your client settings (not sure which value, if any, the Tibia 10 client sends).
Pseudo-code:
C++:
// Inspection States
// These are the only values I was able to see in my tests.
// 1 = Grant player permission to inspect you.
// 2 = Ask to inspect player.
// 3 = Allow player to inspect you.
// 4 = Inspect player.
// 5 = Revoke player's permission to inspect you.
// 6 = "Allow All to Inspect Me" setting is enabled.
// 7 = "Allow All to Inspect Me" setting is disabled.
auto inspection_state = msg.getByte();
if (inspection_state <= 5) {
auto creature_id = msg.get<uint32_t>();
}
Modified
Edit VIP
Info: Bytes equal to the number of groups, and their IDs, the VIP is part of were added to the end of the packet.
Pseudo-code:
C++:
ProtocolGame::parseEditVip()
{
...
auto number_of_groups = msg.getByte();
for (size_t i = 0; i < number_of_groups; ++i) {
auto group_id = msg.get<uint8_t>();
}
}
Server Packets
New
New- Inspection List - 0x76
- Inspection State - 0x77
- VIP Group Data - 0xD4
- sendVIP()
- AddCreature()
- N/A
Inspection List
Info: First byte indicates whether the inspection is for a player or item (0 = item, 1 = player). Next byte is the number of items in the inspection list (items only contain 1 item, players can contain up to 10 [one for each slot]). Item data starts with the item's name, then, if inspection is for a player, the next byte will indicate the slot id of the item, followed by 2 bytes for the item's id, then (always in my tests) 0xFF, then, if the item is stackable, 1 byte for the count. Next we have 1 byte for the number of imbuement slots followed by 2 bytes for each slot which contains the imbuement's id. Now we get to the details. The first byte is the number of details then you have two strings for each detail. First string is the detail (e.g., Weight), and the second is the description (e.g., 2.5 oz). Now, if applicable, we get the player data. First thing is the player's name. Next is the outfit information (first 2 bytes are the outfit id, then 1 byte for head color, then 1 byte for body color, then 1 byte for legs color, then 1 byte for feet color, and, lastly, 1 byte for addons). Finally, we have the player's details. Just like with items, the first byte is the number of details then you have two strings for each detail. First string is the detail (e.g., Level), and the second is the description (e.g., 100).
Pseudo-code:
C++:
msg.addByte(is_player ? 0x01 : 0x00);
msg.addByte(number_of_items);
for (size_t i = 0; i < number_of_items; ++i) {
msg.addString(item_name);
if (is_player) {
msg.addByte(slot_id);
}
msg.add<uint16_t>(item_id);
msg.addByte(0xFF);
if (item_is_stackable) {
msg.addByte(item_count);
}
msg.addByte(number_of_imbuement_slots);
for (size_t i = 0; i < number_of_imbuement_slots; ++i) {
msg.add<uint16_t>(imbuement_id);
}
msg.addByte(number_of_item_details);
for (size_t i = 0; i < number_of_item_details; ++i) {
msg.addString(item_detail);
msg.addString(item_description);
}
}
if (is_player) {
msg.addString(player_name);
msg.add<uint16_t>(outfit_id);
msg.addByte(head_color);
msg.addByte(body_color);
msg.addByte(legs_color);
msg.addByte(feet_color);
msg.addByte(addons);
msg.addByte(number_of_player_details);
for (size_t i = 0; i < number_of_player_details; ++i) {
msg.addString(player_detail);
msg.addString(player_description);
}
}
Inspection State
Info: 5 bytes. First 4 bytes are the player's id who's 'inspection state' has changed. Last byte is their new 'inspection state'.
Pseudo-code:
C++:
// Inspection States
// These are the only values I was able to see in my tests.
// 0 = Player is not allowed to inspect you.
// 1 = Player is allowed to inspect you.
// 2 = You have requested player's permission to inspect them.
// 4 = Player has given you permission to inspect them.
// 5 = Player has permission to inspect you.
// 8 = Player has sent a request to inspect you.
msg.add<uint32_t>(creature_id);
msg.addByte(inspection_state);
VIP Group Data
Info: Pretty simple. Just the data for each VIP group.
Pseudo-code:
C++:
msg.addByte(number_of_groups);
for (size_t i = 0; i < number_of_groups; ++i) {
msg.addByte(group_id);
msg.addString(group_name);
// The next value always turned up as 0 in my tests.
// I don't have a premium account to test with, but
// my guess is that it's a boolean value indicating
// whether or not the group was added by the player,
// and, therefore, can be edited/removed.
msg.addByte(unknown);
}
// Always 0 in my tests. Not sure what it could be.
msg.addByte(unknown);
Modified
sendVIP()
Info: Bytes equal to the number of groups, and their IDs, the VIP is part of were added to the end of the packet.
Pseudo-code:
C++:
ProtocolGame::sendVIP()
{
...
msg.addByte(status);
msg.addByte(number_of_groups);
for (size_t i = 0; i < number_of_groups; ++i) {
msg.addByte(group_id);
}
...
}
AddCreature()
Info: While not exactly a packet, this is the message information for a creature. The modification only applies to 'Unknown' (0x61) and 'Outdated' (0x62) creatures. It's a single byte after the creature's 'mark' that indicates 'inspection state'. Most creatures will have the value 0 (always true if they're on Flash or Tibia 10 client), or 4 if their "Allow All to Inspect Me" setting is enabled (Tibia 11 only). Otherwise, they'll have a value depending on your last 'inspect' interaction with them.
Pseudo-code:
C++:
ProtocolGame::AddCreature()
{
...
msg.addByte(0xFF); // MARK_UNMARKED
msg.addByte(0x00); // INSPECTION_STATE
...
}
Last edited: