• 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 11][Protocol 11.10] Inspect and VIP Groups

jo3bingham

Excellent OT User
Joined
Mar 3, 2008
Messages
1,103
Solutions
14
Reaction score
772
GitHub
jo3bingham
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
New
  • Inspect Item - 0xCD
  • Inspect Player - 0xCE
Modified
  • Edit VIP - 0xDE
Removed
  • N/A
NEW
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
  • Inspection List - 0x76
  • Inspection State - 0x77
  • VIP Group Data - 0xD4
Modified
  • sendVIP()
  • AddCreature()
Removed
  • N/A
New
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:
Thank you for share those codes with us. Too bad that nowadays everyone are just copying codes without respecting people who does it.
If I know how I would like to help you, but I've got no knowledge about tibia packets.

Again, thank you:)
 
hello, i have some questions

first, will I need to implement inspect player if I want to use tibia 10.10?
And I only need the vip new stuff right?

If so, then should we (in tfs implementation) store number_of_groups, group_id, and group_name in SQL? like tfs is doing it atm.

C++:
query << "SELECT `player_id`, (SELECT `name` FROM `players` WHERE `id` = `player_id`) AS `name`, `description`, `icon`, `notify`, `number_of_groups`, `group_id` FROM `account_viplist` WHERE `account_id` = " << accountId;

also, how should we implement the VIP group data? have a new method send it?

thankful for more clear information how i would implement this in tfs. Thanks in advance :)
 
in sendVip why would i send the whole groups instead of the current group ONLY.
in parseEditVip why would I recieve the whole groups instead of just the group id of the player.

-- Edit, as I read it seems like the character can be assigned to different groups at the same time, that's the reason why number of groups is sent.

-- Edit, the last byte in (vip groups) that was 0 in all tests because you were free account. It identifies the amount of user-created groups that you can create.
 
Last edited:
-- Completion to the thread,

New Client Packets:
Set VIP Group: 0xDF

C++:
uint8_t type = msg.getByte();
// type 0 : remove, type 1 : add
std::string groupName = msg.getString()
 
Well, thanks joe, but you missed the point of naming server inspection states. The point of them, is what does they show in client? i.e If you sent: 1 it will show "Ask to inspect + Invite to inspect me" while 2 will show "Ask to inspect + Revoke allowance" and so on. I made a quick list until i figure how is it working,
C++:
enum ServerInspectionStates_t {
    ASK_TO_INSPECT__INVITE_TO_INSPECT_ME = 0,
    ASK_TO_INSPECT__REVOKE_PERMISSION = 1,
    ASK_TO_INSPECT__ALLOW_TO_INSPECT_ME = 8,

    INSPECT_PLAYER__INVITE_TO_INSPECT_ME = 4,
    INSPECT_PLAYER__REVOKE_PERMISSION = 5,
    INSPECT_PLAYER__ALLOW_TO_INSPECT_ME = 12,
}

I don't really care what tibia named them, but those names make sense so that it works fine.
 
I know this post is kinda old, but no one had issues (client crash) using the inspection item on certain items?
loudly-crying-face_1f62d.png
 
I still checking this thread so imma bump because (maybe) someone needs it also.
 
  1. // Always 0 in my tests. Not sure what it could be.
  2. msg.addByte(unknown);
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);

[/CODE]

That last unkown byte is how many more groups the player can add.
There are 3 default groups on RL Tibia and premium players can add 5 more.
 
hehe idk how i forgot to add this, but for those developing vip groups
Joe mentioned in VipGroups (server packet)

// Always 0 in my tests. Not sure what it could be. msg.addByte(unknown);

this is amout of vip groups you can create (tibia's value is 0 for free players, 5 for premmy players)
this is usually (5 - groups you already created), i.e if you created a vip group, then this value will be 4 (5 - 1)
 
Back
Top