• 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 7.4 Bot Development

adahum

New Member
Joined
Feb 28, 2015
Messages
23
Reaction score
3
Guys, I on way to develop my own bot for tibia client 7.4 since the actual bots are pretty expensive (like riftbot, for example).

At this moment i can handle playerinfo like mana, health, cap, name and so but i'm pretty stucked on more complex things like how to handle Backpacks, use itens....

How can i handled bp itens for example ? using CE i cant find pointer or something like that gives me struct to handle it as i need.
 
Are you looking for tibia 7.4 client? or the 7.72 one?

A good source of research is the tibia programming forum: Forums (https://tpforums.org/forum/)
It does not look to be online anymore, but you can search things by looking at wayback machine.
But anyway It looks that this link still works:
On this forum they used to post all the memory addresses.
Ascer, the owner of Rifibot, used to post some stuff on this forum when he started his bot.

I used to play with this long time ago, the structure of an open container is something like this:
C++:
 struct ContainerDef{
    int isOpen;    // this is an int that works like a boolean, if this is opened or not
    int hasParent; // this is an int that works like a boolean, this it has parent container or not
    ItemDef containerItem; // this is the container item: bag, backpack, chest, box...
    std::string containerName; // the container name
    int containerSize; // the container size
    int itemsInside; //number of items inside the container
    ItemDef items[MAX_ITEMS_PER_CONTAINER]; //array with items in container. the MAX_ITEMS_PER_CONTAINER is 36
 };

The item structure are like this in memory:
C++:
struct ItemDef{
    uint32_t id;
    uint32_t count;
    uint32_t stackPos;
};


If you are looking for 7.72 one, the memory address of open containers is 0x001CEDD8
The size of each opened container is 492 bytes. The maximum opened containers on client is 15.

EDIT: dont give up on doing this. Even if it does not works on any server, you will learn a lot on this proccess. The journey is worth ;)
 
Are you looking for tibia 7.4 client? or the 7.72 one?

A good source of research is the tibia programming forum: Forums (https://tpforums.org/forum/)
It does not look to be online anymore, but you can search things by looking at wayback machine.
But anyway It looks that this link still works:
On this forum they used to post all the memory addresses.
Ascer, the owner of Rifibot, used to post some stuff on this forum when he started his bot.

I used to play with this long time ago, the structure of an open container is something like this:
C++:
 struct ContainerDef{
    int isOpen;    // this is an int that works like a boolean, if this is opened or not
    int hasParent; // this is an int that works like a boolean, this it has parent container or not
    ItemDef containerItem; // this is the container item: bag, backpack, chest, box...
    std::string containerName; // the container name
    int containerSize; // the container size
    int itemsInside; //number of items inside the container
    ItemDef items[MAX_ITEMS_PER_CONTAINER]; //array with items in container. the MAX_ITEMS_PER_CONTAINER is 36
 };

The item structure are like this in memory:
C++:
struct ItemDef{
    uint32_t id;
    uint32_t count;
    uint32_t stackPos;
};


If you are looking for 7.72 one, the memory address of open containers is 0x001CEDD8
The size of each opened container is 492 bytes. The maximum opened containers on client is 15.

EDIT: dont give up on doing this. Even if it does not works on any server, you will learn a lot on this proccess. The journey is worth ;)
Thanks for give some time to help me. I read topics from this forum sometimes. they have a lot of content.

You're right. Its not easy. I'm about 6 mouths studing RE, python, memory injection and so.

I will take a look in your struct and see if it works.

Actually, i try to find backpack address by itemsInside. It works when i remove/add itens inside the backpack. Unfotunatelly it resests once i close my bp. It also don't bring any pointer or fixed address, what makes it harder than i think. but as you said, the way it try keep.

If you see or know more something, please, let me know. anyway, im glad for all.
Post automatically merged:

remember a bot free source crystal bot
I search about this bot but seems it's not working anymore. It could be a great source to learn too.
 
Thanks for give some time to help me. I read topics from this forum sometimes. they have a lot of content.

You're right. Its not easy. I'm about 6 mouths studing RE, python, memory injection and so.

I will take a look in your struct and see if it works.

Actually, i try to find backpack address by itemsInside. It works when i remove/add itens inside the backpack. Unfotunatelly it resests once i close my bp. It also don't bring any pointer or fixed address, what makes it harder than i think. but as you said, the way it try keep.

If you see or know more something, please, let me know. anyway, im glad for all.
Post automatically merged:


I search about this bot but seems it's not working anymore. It could be a great source to learn too.
It's I used o use y on tibianic client in war servers you need to compile it
 
Thanks for give some time to help me. I read topics from this forum sometimes. they have a lot of content.

You're right. Its not easy. I'm about 6 mouths studing RE, python, memory injection and so.

I will take a look in your struct and see if it works.

Actually, i try to find backpack address by itemsInside. It works when i remove/add itens inside the backpack. Unfotunatelly it resests once i close my bp. It also don't bring any pointer or fixed address, what makes it harder than i think. but as you said, the way it try keep.

If you see or know more something, please, let me know. anyway, im glad for all.
Post automatically merged:


I search about this bot but seems it's not working anymore. It could be a great source to learn too.
Yeah! The thing is:
You will need to always scan for this structure, with the pointer starting on the address that I provided. After you scan for all the open containers, which will always be 16, you check if it is open, if it is, you save the data to be used later.

This code may make things more clear:

C++:
std::vector<Container::ContainerDef> GetOpenContainers(){
    std::vector<ContainerDef> openContainers;
    std::vector<uint8_t> rawContainer;
    uint32_t baseAddress = 0; // put here the base address that you found
    uint32_t containerAddress = 0;
    int isOpen = 0;


    const int MAX_CONTAINERS = 16;
    const int ADDR_CONTAINER =  0x001CEDD8;
    const int ADDR_STEP = 492;
    const int ADDR_CONTAINER_SIZE = 492;
    const int IS_OPEN  = 0;

    for(uint32_t n = 0; n < MAX_CONTAINERS; n++){
        containerAddress = baseAddress + ADDR_CONTAINER + n * ADDR_STEP;

        //Check the "isOpen" flag, if it is true, continue reading
        isOpen = ReadUInt(containerAddress + IS_OPEN);

        if(isOpen){
            rawContainer = ReadBytes(containerAddress, ADDR_CONTAINER_SIZE);
            openContainers.push_back(ParseContainerDef(rawContainer));
        }

    }

    return openContainers;
}

C++:
ContainerDef ParseContainerDef(std::vector<uint8_t> &rawContainer){
  //here you parse the raw bytes into a ContainerDef
}
 
Yeah! The thing is:
You will need to always scan for this structure, with the pointer starting on the address that I provided. After you scan for all the open containers, which will always be 16, you check if it is open, if it is, you save the data to be used later.

This code may make things more clear:

C++:
std::vector<Container::ContainerDef> GetOpenContainers(){
    std::vector<ContainerDef> openContainers;
    std::vector<uint8_t> rawContainer;
    uint32_t baseAddress = 0; // put here the base address that you found
    uint32_t containerAddress = 0;
    int isOpen = 0;


    const int MAX_CONTAINERS = 16;
    const int ADDR_CONTAINER =  0x001CEDD8;
    const int ADDR_STEP = 492;
    const int ADDR_CONTAINER_SIZE = 492;
    const int IS_OPEN  = 0;

    for(uint32_t n = 0; n < MAX_CONTAINERS; n++){
        containerAddress = baseAddress + ADDR_CONTAINER + n * ADDR_STEP;

        //Check the "isOpen" flag, if it is true, continue reading
        isOpen = ReadUInt(containerAddress + IS_OPEN);

        if(isOpen){
            rawContainer = ReadBytes(containerAddress, ADDR_CONTAINER_SIZE);
            openContainers.push_back(ParseContainerDef(rawContainer));
        }

    }

    return openContainers;
}

C++:
ContainerDef ParseContainerDef(std::vector<uint8_t> &rawContainer){
  //here you parse the raw bytes into a ContainerDef
}

Thank you so much bro. This piece of code helped me a lot to undestand how to handle this struct of memory. (it really makes me remember structs in C). Anyway, let me ask you: since i'm on 64x, there's possibility to this address value change ?

I ask since because containerAddress dos not bring the value expected.

i found addresses for seccond backpack and thrid backpack but for the first (also main) the base address does not work as expected.

Maybe I'll have to try out it ultil get since i 'm trying to do in Medivia Client, what is very very diferent
 
Last edited:
Thank you so much bro. This piece of code helped me a lot to undestand how to handle this struct of memory. (it really makes me remember structs in C). Anyway, let me ask you: since i'm on 64x, there's possibility to this address value change ?

I ask since because containerAddress dos not bring the value expected.

i found addresses for seccond backpack and thrid backpack but for the first (also main) the base address does not work as expected.

Maybe I'll have to try out it ultil get since i 'm trying to do in Medivia Client, what is very very diferent

Oh, this is not the Tibia client? So this code that I mentioned will not work. Medivia is based on OTClient which has much different strucuture. You should check the edubart otclient source code for that. But, since the Medivia team has been working on that client since 2016, I can say that it will not reflect the same structure. Anyways, check this, maybe useful:

So, as you mentioned you are trying to learn, I will try to share some thoughs here.
The OTClient instantiate this things dinamically in memory, so everytime you open the client it gets into some different memory address.
Check this: [OTClient] Battle List Tutorial [Archive] - Forums (https://tpforums.org/forum/archive/index.php/t-6414.html)

The difference between the Cipsoft client and OTClient is something like this snippet of code:

Please, suppose that OTClient and Tibia has exactly the same structure of Container, which is not true but just for this example. The things that I am writing below is not 100% true, but is most like to explain a little better the difference.
C++:
std::vector<ContainerDef> otClientOpenContainers;
ContainerDef[16] cipsoftOpenContainers;

otClientOpenContainers is a vector, everytime you push_back to the vector, it allocated dinamically in memory a new ContainerDef, and when you do this, the memory address that is allocated is kind of random. BUT, the otClientOpenContainers object start address is kept the same, since it is allocated statically.

cipsoftOpenContainers is a static allocated object, so it will have always the same memory address. Thats why you can always try to find on the fixed address and it will work!


so to get otClientOpenContainers data the way would be:
  • find the baseAddress
  • find the g_game address: this is a static allocated object, and this is the structure of containers is allocated
  • find the first element of otClientOpenContainers. As on my example it is a vector, it is allocated in memory as a sequence, so you would need only to step between elements. This is not 100% true since the OTClient structure is not a vector.


in other hand, to get cipsoftOpenContainers:
  • find the baseAddress
  • find the cipsoftOpenContainers address: this is a static allocated object (this value I already provided you on this thread)
  • read the first element of the cipsoftOpenContainers.

EDIT: Hey I though the reference of my learning at that time was tpforums.org but it was tibiapf.com. There you can find a lot of tutorials. Also find Ascer, @kuhi and mine postings about the bots that we are individually developing at that time.
 
Last edited:
I would like to thank you enormously. After reading the content very calmly, I was able to take the first steps, find the addresses and understand much of the structure of the container. As I already imagined, and you also mentioned, there have been many years of changes and the structure no longer seems as simple as the original OTClient.

I'll take this opportunity to ask a question:

would the private property std::deque<ItemPtr> m_items; be a pointer to a list or just a regular list? Finding the items inside the backpack was not as simple as I imagined.

Edit:

What i tryied to is search for some stacked items on dp, change them and search for new stack value. but seems its not so easy as i think.
 
Last edited:
If you can't write simple functions like using item by using packets when you have full open source how client is coded i would just give up + we are here ceating server's not bots.
 
If you can't write simple functions like using item by using packets when you have full open source how client is coded i would just give up + we are here ceating server's not bots.
It's not my fault if you're a frustrated person in life. Don't come and take your hate out on me. I'm here to learn just like anyone else. I don't see a problem with not being able to do it alone. Because if I could actually do this alone, I wouldn't be in a forum open to learning. Waste your time with a psychologist.

Furthermore, if it's something as simple as you said, wouldn't it be more useful, pleasant and intelligent for you to explain how it works? This would be more elegant and would be of public use to others.
 
Last edited:
Yeah, there shouldbe a lot of free code for leechers like you who will ruin servers based on OTC with botting, 10/10 idea i will repeat this is not of this type forum

its like on official microsoft forum u would ask for cracked windows
 
Yeah, there shouldbe a lot of free code for leechers like you who will ruin servers based on OTC with botting, 10/10 idea i will repeat this is not of this type forum

its like on official microsoft forum u would ask for cracked windows
If you're so good that you tell people to give up what they're doing, make a client so bad that the bot doesn't work. DO. Don't change the direction of a thread to give your opinion when it wasn't asked for.
 
I think you didnt understand me correctly, or missunderstand i would love to help when u would have a problem with your Client, Server, Hosting, Website, anything that is related with your OTS Project, not BOT Project, in one topic i will help ppl how to protect client from third party software, and in another topic we will give a code how to write third party programs? thats makes nonsense

if you wanna be a super cool guy who can break the rules from server that dont wanna botters without any knowledge, literaly any, then of course my response will be "give up"
ps. checked ur threads / messages history, now i am 100x more sure that u should give up with reverse enginering.

just go on forum where people enjoy destroying server's / game's with using knowledge about programming to write applications like bot or other shit that ruin fun from game and try leech them
 
Last edited:
I don't allow someone frustrated in life like you to take up my time. I will continue studying.

@danilopucci , I thank you enormously for being able to exchange a healthy idea.

@Dakos , bye frustrated.
 
Back
Top