Results 1 to 6 of 6

Thread: [OTClient] Container Structure

  1. #1
    Junior Member
    Join Date
    Jun 2016
    Posts
    3

    Question [OTClient] Container Structure

    Hello, everyone any idea to choose this structure, i read this topic i not have success.
    I understand that this is a tree, but I didn't find the head.

    https://tpforums.org/forum/showthrea...ll=1#post55943

  2. #2
    Junior Member
    Join Date
    Mar 2016
    Posts
    6
    If we look at the game.h file, we are going to see at its private members the following:

    Code:
    CreaturePtr m_attackingCreature;
    CreaturePtr m_followingCreature;
    ProtocolGamePtr m_protocolGame;
    std::map<int, ContainerPtr> m_containers;
    std::map<int, Vip> m_vips;
    Right there you can see the data structure that stores the list of all containers opened (std::map<int, ContainerPtr> m_containers). If you look above, you are going to see the following:

    Code:
    CreaturePtr m_attackingCreature;
    CreaturePtr m_followingCreature;
    Those are the data that stores the information about who is the player following or attacking, which are preatty easy to find using CE. Do the first scan looking for exact value: 0 (4 Bytes). Then go at your client and follow someone, after that do the next scan with increased value scan type, stop following the creature, then scan for 0 again. If you keep doing that you are going to find the CreaturePtr m_followingCreature. Now you just have to browser memory region and look for the m_containers address (offset from m_followingCreature: 0x8). What you just found is the head referred at the other topic. This head has a pointer to the root node of the m_containers map, that in turn has pointers to the nodes.
    Last edited by saviofcb; 01-28-2020 at 12:11 AM.

  3. #3
    Junior Member
    Join Date
    Jun 2016
    Posts
    3
    Hello, saviofcb, I did what you said, but I believe that it is not 100% OTC code, i think I forgot to comment I'm looking for Medivia client.

    Here is an image of the CE, where it shows the Follow and Attack and in yellow as you commented but it is 0.
    Code:
    CreaturePtr m_attackingCreature;
    CreaturePtr m_followingCreature;
    ProtocolGamePtr m_protocolGame;
    std::map<int, ContainerPtr> m_containers;
    std::map<int, Vip> m_vips;
    Captura de Tela 2020-01-28 às 22.39.52 1.jpg

  4. #4
    Junior Member
    Join Date
    Mar 2016
    Posts
    6
    It is easy to check that Medivia has made so many updates that its code may differ from the original Open Tibia Client source. You can do the other way around: search for some container and then back trace the path to the container's entry point. Maybe it is not even a std::map, if so the topic that you refer may not be useful. You will have to dissect the data structure to understand how to read it from memory.

    EDIT: Took a time to mess around with medivia's client a bit and check that m_containers doesn't seem to be stored in a std :: map, but apparently it is easier to read the structure. I don't have a medivia account, so I didn't have several backpacks to do a complete check. Is 17 the maximum amount of containers that can be opened at medivia?
    Last edited by saviofcb; 02-04-2020 at 05:32 PM.

  5. #5
    Junior Member
    Join Date
    Jun 2016
    Posts
    3
    Quote Originally Posted by saviofcb View Post
    It is easy to check that Medivia has made so many updates that its code may differ from the original Open Tibia Client source. You can do the other way around: search for some container and then back trace the path to the container's entry point. Maybe it is not even a std::map, if so the topic that you refer may not be useful. You will have to dissect the data structure to understand how to read it from memory.

    EDIT: Took a time to mess around with medivia's client a bit and check that m_containers doesn't seem to be stored in a std :: map, but apparently it is easier to read the structure. I don't have a medivia account, so I didn't have several backpacks to do a complete check. Is 17 the maximum amount of containers that can be opened at medivia?
    Because I tried to do what you commented, open and track, I tried with 2 different containers a bag and a backpack, to track I used the volume, opening the backpack, I searched for 20 in the CE, opened the bag inside the backpack and searched for 10, so on until I found the address, but I always found it with several offsets (5+) and every time I did something, everyone changed, not even the base address I was able to find because of these changes, I can't tell you if the maximum is 17.

  6. #6
    Junior Member
    Join Date
    Mar 2016
    Posts
    6
    The following lua code can be executed at Cheat Engine. It only works for Medivia_OGL client. It reads and prints all openned containers. I am not familiar with LUA, so it is not well written.
    It probably don't work with more than 17 containers openned. As I told I coundn't test it since I'm didn't have an account. You now can dissect a little bit more the containers data structure and improve this code. As i told, it doesnt seems to be stored in a std::map.

    Code:
    --Containers reader by: saviofcb.
    
    local baseAddress = getAddress("Medivia_OGL.exe")
    
    local containersDataStructurePtrAddress = 0x5CA8D0
    local containersCountAddress = 0x5CA8C4
    
    local containersDataStructureOffset = {
          lastContainerNodePtr = 0x44
    }
    
    local containerNodeOffset = {
          previousContainerNode = 0x0,
          id = 0x4,
          containerPtr = 0xC
    }
    
    local containerOffset = {
          capacity = 0x10,
          name = 0x18,
          isClosed = 0x31,
          itemCount = 0x4C
    }
    
    -- helper function
    function readStdString(address)
        local smallBufferSize = 0x10
        local lengthAddress = address + smallBufferSize
        local length = readInteger(lengthAddress)
        local res = nil
        if (length < smallBufferSize) then
            res = readString(address, length)
        else
            res = readString(readInteger(address), length)
        end
        return res
    end
    
    local containersDataStructureAddress = readInteger(baseAddress + containersDataStructurePtrAddress)
    local count = readInteger(baseAddress + containersCountAddress)
    
    if (count >= 0) then
       local lastContainerNode = readInteger(containersDataStructureAddress + containersDataStructureOffset.lastContainerNodePtr)
    
       local i = count - 1
       local stop = false
    
       while(not stop) do
                 local containerPtr = readInteger(lastContainerNode + containerNodeOffset.containerPtr)
    
                 -- reading and printing openned container
                 local cap = readInteger(containerPtr + containerOffset.capacity)
                 local name = readString(containerPtr + containerOffset.name)
                 local isClosed = readBytes(containerPtr + containerOffset.isClosed, 1, false)
                 local itemCount = readInteger(containerPtr + containerOffset.itemCount)
    
                 if(isClosed == 0) then
                             local msg = ("name: %s, cap: %i, item count: %i."):format(name, cap, itemCount)
                             print(msg)
                 end
                 --end of reading and printing openned container
    
                 i = i - 1
                 if (i >= 0) then
                    lastContainerNode = readInteger(lastContainerNode + containerNodeOffset.previousContainerNode)
                 else
                     stop = true
           end
       end
    end

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •