Log in

View Full Version : Tibia 11 - The structure of containers and items



Morse
12-11-2016, 20:36
Here's what I've learned so far: Tibia 11 uses two collections to keep track of open containers. One collection stores information about the containers and its items. The other one stores UI information (related to each container's window). To access these collections, traverse the following paths:


// Tibia 11.02.4171
// Container collection start
{qt5core_dll + 0x004555C8, 0x8, 0x1E4, 0x124, 0x20 };

// Container UI collection start
{qt5core_dll + 0x004555C8, 0x8, 0x114, 0x034 };

Both collections use one byte, the container ID, as keys. Due to alignment, however, keys end up taking 4 bytes in memory. The other 3 should be disregarded (or so I think). Each collection item has also a pointer to a structure, (A) or (D), containing useful data, exactly like in the battle list example (http://www.blackdtools.net/showthread.php?62991-Tibia-11-The-Battle-list/page2). For more information on how to navigate these collections, see Daniel's posts (http://www.blackdtools.net/showthread.php?62980-Code-to-read-Tibia-11-collections-(skills-server-info-etc)).

(A) Each item in the first collection has a pointer to a structure that looks like this:
0x08: pointer to the container item information structure (C). That is, if the container is a backpack, this should point to a structure that contains information about a backpack item.
0x14: pointer to a QString (http://www.blackdtools.net/showthread.php?62992-Tibia-11-Understanding-QStrings-in-memory) containing the container name.
0x18: number of slots in the container. Looks like 4 bytes long, but one byte should be enough.
0x20: number of occupied slots in the container. One byte should be enough.
0x28: pointer to a list (B). May be null if this container is empty. Each element in the list has a pointer to one item information structure (C).

(B) Item list:
0x00: pointer to the 1st item's information structure.
0x08: pointer to the 2nd item's information structure.
0x10: pointer to the 3rd item's information structure.
...

(C) Item information structure:
0x08: pointer to the item's ID. 2 bytes should be enough.
0x38: item count, exactly one byte. When the item isn't stackable, this byte should be disregarded.

(D) Each item in the second collection, the one about container windows, has a pointer to a structure that looks like:
0x04: a pointer to a pointer to... ultimately leads to a structure with data about the container window (E). (See examples below).
0x40: a 4 byte integer indicating the container slot your mouse is currently hovering. If you're not hovering one of this container's slots, this number is -1 (that is, 0xFFFFFFFF).

(E) Container window info structure:
0x08C: height of the window's interior. Doesn't include the window's borders measurements.
0x1F4: 1 byte long. 0 means the window is minimized, 1 means it isn't.
0x23C: duplicated minimized flag?
0x284: window's relative position index. (2/4 bytes long?) (Example: Suppose there are two containers open: a backpack and, below it, a bag. The bag's relative position index should be bigger than the backpack's. These number are not necessarily consecutive, and are exchanged when the windows positions are exchanged.)

It is important to note that some of these structures are immutable: The item structure (C), for instance. If you have a stack of coins inside your backpack, and you throw one of them into the sea, your old stack of coins gets invalidated and a new one is allocated. Meaning you must frequently retraverse some paths. Also, when a container is closed, the corresponding window collection item might not be deleted immediately.

Here are some examples of how to navigate this mess. Suppose now that you have just one open backpack. It's first item is a stack of coins and its second item is a rope. You can use the following paths:


// Tibia 11.02.4171
// Backpack item ID:
{qt5core_dll + 0x004555C8, 0x8, 0x1E4, 0x124, 0x20, 0x04, 0x14, 0x08, 0x8, 0x00 };

// Coins item ID:
{qt5core_dll + 0x004555C8, 0x8, 0x1E4, 0x124, 0x20, 0x04, 0x14, 0x28, 0x0, 0x08, 0x0 };

// Ammount of coins:
{qt5core_dll + 0x004555C8, 0x8, 0x1E4, 0x124, 0x20, 0x04, 0x14, 0x28, 0x0, 0x38 };

// Rope item ID:
{qt5core_dll + 0x004555C8, 0x8, 0x1E4, 0x124, 0x20, 0x04, 0x14, 0x28, 0x8, 0x08, 0x0 };

// Backpack hovered slot:
{qt5core_dll + 0x004555C8, 0x8, 0x114, 0x034, 0x00, 0x14, 0x40 };

// Backpack's interior height:
{qt5core_dll + 0x004555C8, 0x8, 0x114, 0x034, 0x00, 0x14, 0x04, 0x38, 0x40, 0x8C };

We're lacking a lot of information about the aforementioned structures. Contributions and corrections of any kind are welcome. Thank you.

blackd
12-12-2016, 11:06
Thank you for sharing. It might be usefull for advanced cheats.

Morse
12-16-2016, 02:20
Thank you, Daniel. My mouse and keyboard bot is working (somewhat), partly due to all the information available in this forum. So it's my turn to share more information. I hope somebody finds it useful.

So far, we know how big each container window is, and their relative positions. In order to send mouse clicks for a looting routine, we need to know each container window's absolute position. Here's what I used to achieve that:


// Tibia 11.03.4221
// Height of the free space below the last open container.
{ qt5core_dll + 0x004555C8, 0x8, 0x108, 0x14, 0x4, 0x18, 0x38, 0x4 };

What if the player opened their battle/VIP/skills/unjust windows in some random order, messing up the container windows' positions? We're in luck, because there is an (E) structure for each one of these non-container windows, storing their heights, relative positions and minimized flags. The start of paths to these structures are stored in an array:


// Array of path starts to battle/VIP/skills/unjust windows (in this order)
{ qt5core_dll + 0x004555C8, 0x8, 0x12C, 0x5C };

Usage examples:

// Battle window internal height
{ qt5core_dll + 0x004555C8, 0x8, 0x12C, 0x5C, 0x04, 0x38, 0x40, 0x8C };

// VIP window internal height
{ qt5core_dll + 0x004555C8, 0x8, 0x12C, 0x60, 0x04, 0x38, 0x40, 0x8C };

Beware though: if a certain window is closed, it's corresponding array entry is null.

Combining all information so far, it is possible to make a mouse-only looter. We're still lacking information about each container's scrollbar value (it is stored as a double somewhere).

Another path that I find useful is the one to the height of the area with tiles in it (where the actual game is shown):

// Looks like a 4-byte integer.
{ qt5core_dll + 0x004555C8, 0x8, 0x24, 0x64 };

Maps are useful when caveboting. As explained here (https://tibiamaps.io/guides/minimap-file-format), each Tibia map piece has two corresponding .png files: the pathfinding file and the color one. I like reading these maps from Tibia memory instead of externally opening the .png files, because the memory maps get updated as you walk around. As always, these maps are kept in a collection.


// Map pieces collection start.
{ qt5core_dll + 0x004555C8, 0x8, 0xAC, 0x1C };

Each collection item looks like:

(F) Map piece collection item:
0x14: Map piece start X.
0x18: Map piece start Y.
0x1C: Map piece Z.
0x24: Pointer structure containing useful information (G).

(G) Structure that holds useful pointers:
0x14: Map piece start X.
0x18: Map piece start Y.
0x1C: Map piece Z.
0x2C: Pointer to a color-map related structure (H).
0x3C: Pointer to a pathfinding map related structure (H).

(H) Structure that holds pointer to the 8BPP pixel data:
0x24: Pointer to map image data.

Usage example:


// Path to pathfinding map pixels, 8BPP
{ qt5core_dll + 0x004555C8, 0x8, 0xAC, 0x1C, 0x0, 0x24, 0x3C, 0x24, 0 }

Since each piece stores 256 rows and 256 columns, at 8BPP, each image has 65536 bytes. Depending on how your programming language treats arrays (column- vs row-major), you might have to exchange x and y coordinate to access this data. When your character gets near the border to another map piece, Tibia will put it in the collection. When you change your Z coordinate (by going up and down ladders, for example), Tibia will unload every map piece, then load the ones corresponding to the floor you just entered.

And that's all I know. Hope it helps, thank you.