Register for your free account! | Forgot your password?

Go Back   elitepvpers > MMORPGs > Atlantica Online
You last visited: Today at 11:10

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



[HELP] Calling ingame function

Discussion on [HELP] Calling ingame function within the Atlantica Online forum part of the MMORPGs category.

Reply
 
Old   #1
 
elite*gold: 0
Join Date: Feb 2011
Posts: 19
Received Thanks: 5
Post [HELP] Calling ingame function

First of all I wanna apologize if the owner or the private server is on here.
Due my curiosity I decide to build bot for AO V3.
but I got several problem or maybe a lot of problem
what I did so far is I already found the entity list (or similar) it contains
  • Monster/NPC ID
  • Current X Coordinate (on Map not Screen)
  • Current Y Coordinate (same as above)
  • Current Map ID
  • Name as unicode string
  • The rest is idk because the stride offset between entity is large like 0xFB68

Now the problem is, I cannot find the 'world2screen' or camera function that translate from 'Map' to X and Y coordinate screen. or maybe wanna try different approach like the title of this thread "CALLING IN GAME FUNCTION"
AFAIK the MMORPG game is using packet to communicate between client and server right?
but when I hook WSASend function to log packet that sent to server, its encrypted, I try do tracing function that encrypt packet but no luck or maybe I just suck at this.
or maybe someone can give me a clue instead rebuilding packets just find a function that move to certain XY Coordinate and MapID? back again I'm suck at this tracing function , and yes I already tried that and guess what? I stuck at event loop on WM_TranslateMessage or similar (forgot the right term)
any advice that what to do next?
Attached Images
File Type: png Screenshot 2025-07-08 135631.png (1.61 MB, 98 views)
geol88 is offline  
Old 07/10/2025, 01:07   #2
 
HighGamer.'s Avatar
 
elite*gold: 50
Join Date: May 2014
Posts: 1,910
Received Thanks: 941
Why don't you use the bot I attached it works on v3.xx.xx servers.

Run uMod or Texmod whichever works and open texture/package (atlantica.tpf) it's in the AO_TextMod folder. Then simply run AutoGrinder_08C.au3 or AutoGrinder_08C.exe

Password for archive is: 12345
Attached Files
File Type: zip AutoGrinder_V08C_SpainAO_V3.16.47.zip (3.81 MB, 49 views)
HighGamer. is offline  
Old 07/10/2025, 05:26   #3
 
elite*gold: 0
Join Date: Feb 2011
Posts: 19
Received Thanks: 5
Quote:
Originally Posted by HighGamer. View Post
Why don't you use the bot I attached it works on v3.xx.xx servers.

Run uMod or Texmod whichever works and open texture/package (atlantica.tpf) it's in the AO_TextMod folder. Then simply run AutoGrinder_08C.au3 or AutoGrinder_08C.exe

Password for archive is: 12345
hey, thanks for your reply, your Bot is amazing.
is this autogrinder based on autoit right?
so the feature is limited like "simulate" user input then?
back again my goals is due "curiosity" on calling in game function
so I wanna "simulate" the function that run under the hood.
thanks again for references.
geol88 is offline  
Old 07/11/2025, 18:02   #4
 
HighGamer.'s Avatar
 
elite*gold: 50
Join Date: May 2014
Posts: 1,910
Received Thanks: 941
yes its autoit bundled into exe it only does user inputs and memory reads..

calling function of game you need to unpack the game, then run IDA PRO to find the function you need.
HighGamer. is offline  
Old 08/06/2025, 09:47   #5
 
elite*gold: 0
Join Date: Feb 2011
Posts: 19
Received Thanks: 5
Quote:
Originally Posted by HighGamer. View Post
yes its autoit bundled into exe it only does user inputs and memory reads..

calling function of game you need to unpack the game, then run IDA PRO to find the function you need.
can you guide me? or give me a clue?
Like how to tracing move to X and Y coordinate? since I've obtained the monster X and Y coordinate.
geol88 is offline  
Old 08/07/2025, 17:15   #6
 
HighGamer.'s Avatar
 
elite*gold: 50
Join Date: May 2014
Posts: 1,910
Received Thanks: 941
Here is what I use in my bot

Here is Atlantica Thailand unpacked EXE current version came out yesterday


Offsets for Current Atlantica Thailand
Code:
[MainBaseAddress]
Address=0x335EE94
[AutoClickMonster]
Offset1=0x828
Offset2=0x2C
EntityOffset=0x28
Offset3=0x140
Offset4=0xBAC
Offset5=0x40
Offset6=0xA8
Offset7=0x158
Offset8=0x15C
Offset9=0x244
Offset10=0x3C
Code:
void ClickOnMonster(int EntityIndex)
{
	DWORD monsterClickPointer = ReadDWordPointer(MainBaseAddress, 2, AutoClickMonster_Offset_1, AutoClickMonster_Offset_2);
	if (monsterClickPointer)
	{
		// Monster ID
		DWORD monsterId = ReadDWordPointer(MainBaseAddress, 3, AutoClickMonster_Offset_1, 4 * EntityIndex + AutoClickMonster_EntityOffset, AutoClickMonster_Offset_3);
		
		if (monsterId) {
			//(Active Attack Clock)
			DWORD ActiveAttackClock = ReadDWordPointer(MainBaseAddress, 1, AutoClickMonster_Offset_4);// old = 0xB94 new = 0xBA4
			//myprintf(true, false, false, TextColor::RED, "Clicking on Monster %X, monsterId = %X entity index = %d \n", monsterClickPointer, monsterId, EntityIndex);
			WritePointer(monsterClickPointer + AutoClickMonster_Offset_5, monsterId, 4, 0);          //Monster Id
			WritePointer(monsterClickPointer + AutoClickMonster_Offset_6, 5, 1, 0);                  // (5 = walk to monster) (4 = arrived to monster) (2 = fight starting)
			WritePointer(monsterClickPointer + AutoClickMonster_Offset_7, EntityIndex, 1, 0);        // 0x154 = old 0x21C = new
			WritePointer(monsterClickPointer + AutoClickMonster_Offset_8, GetMapId(), 2, 0);         // 0x158 = old 0x220 = new (Map ID)
			WritePointer(monsterClickPointer + AutoClickMonster_Offset_9, ActiveAttackClock, 4, 0);  // 0x244 is old = 0x30C = new (Attack Clock)
			WritePointer(monsterClickPointer + AutoClickMonster_Offset_10, 30, 1, 0);                // Change this value to 30.. when you click a monster [29 = walk][30 = click on monster][1 = stand still]
		}
		else {
			myprintf(true, false, false, TextColor::RED, "Failed to attack monster! (trying next monster)\n");
		}
	}
}
HighGamer. is offline  
Old 08/09/2025, 06:21   #7
 
elite*gold: 0
Join Date: Feb 2011
Posts: 19
Received Thanks: 5
Quote:
Originally Posted by HighGamer. View Post
Here is what I use in my bot

Here is Atlantica Thailand unpacked EXE current version came out yesterday


Offsets for Current Atlantica Thailand
Code:
[MainBaseAddress]
Address=0x335EE94
[AutoClickMonster]
Offset1=0x828
Offset2=0x2C
EntityOffset=0x28
Offset3=0x140
Offset4=0xBAC
Offset5=0x40
Offset6=0xA8
Offset7=0x158
Offset8=0x15C
Offset9=0x244
Offset10=0x3C
Code:
void ClickOnMonster(int EntityIndex)
{
	DWORD monsterClickPointer = ReadDWordPointer(MainBaseAddress, 2, AutoClickMonster_Offset_1, AutoClickMonster_Offset_2);
	if (monsterClickPointer)
	{
		// Monster ID
		DWORD monsterId = ReadDWordPointer(MainBaseAddress, 3, AutoClickMonster_Offset_1, 4 * EntityIndex + AutoClickMonster_EntityOffset, AutoClickMonster_Offset_3);
		
		if (monsterId) {
			//(Active Attack Clock)
			DWORD ActiveAttackClock = ReadDWordPointer(MainBaseAddress, 1, AutoClickMonster_Offset_4);// old = 0xB94 new = 0xBA4
			//myprintf(true, false, false, TextColor::RED, "Clicking on Monster %X, monsterId = %X entity index = %d \n", monsterClickPointer, monsterId, EntityIndex);
			WritePointer(monsterClickPointer + AutoClickMonster_Offset_5, monsterId, 4, 0);          //Monster Id
			WritePointer(monsterClickPointer + AutoClickMonster_Offset_6, 5, 1, 0);                  // (5 = walk to monster) (4 = arrived to monster) (2 = fight starting)
			WritePointer(monsterClickPointer + AutoClickMonster_Offset_7, EntityIndex, 1, 0);        // 0x154 = old 0x21C = new
			WritePointer(monsterClickPointer + AutoClickMonster_Offset_8, GetMapId(), 2, 0);         // 0x158 = old 0x220 = new (Map ID)
			WritePointer(monsterClickPointer + AutoClickMonster_Offset_9, ActiveAttackClock, 4, 0);  // 0x244 is old = 0x30C = new (Attack Clock)
			WritePointer(monsterClickPointer + AutoClickMonster_Offset_10, 30, 1, 0);                // Change this value to 30.. when you click a monster [29 = walk][30 = click on monster][1 = stand still]
		}
		else {
			myprintf(true, false, false, TextColor::RED, "Failed to attack monster! (trying next monster)\n");
		}
	}
}
Hey thanks its very helpfull.
So my approach from start is on wrong direction then? I mean I was thinking like Aimbot so I messing up with NiCamera object to determine w2s function. But from what I see from you source code it calling internal function to move on monster address that stored in array of entity list right? Or it just write to correct value on pointer to match event loop on mainthread?
geol88 is offline  
Old 08/10/2025, 20:20   #8
 
HighGamer.'s Avatar
 
elite*gold: 50
Join Date: May 2014
Posts: 1,910
Received Thanks: 941
using NiCamera and World2Screen function is the old way of doing it that's how AOBot v1.0 was.. it involved hooking DirectX but it wasn't as fast with clicking mouse coordinates on screen, this one can move to monster without even seeing the monster on screen which is faster..

EntityIndex I believe is just a number index in a array of all monsters it starts from 6 I believe and goes very high, EntityIndex = 1 is your character.

I think max is 510 monsters in one area is limit.

Here is my code how I find closest monster to attack

Code:
signed int GetClosestMonsterInArea(float MaxDistance)
{
	float myX;
	float myY;
	float mobX;
	float mobY;

	int EntityIndex = 6;
	int closestEntityIndex = -1;

	int index = 0;
	int entityOffset = 0x40;

	while (index < 510) //old value was 2040 and entityOffset was 0x40 going by 4 every loop.
	{
		entityOffset = ((index * 4) + 0x40);

		//Skip the monsters that you already tried to attack.
		std::unordered_set<DWORD>::const_iterator alreadyAttackedBeforeMonster = LastAttackedMonsters.find(EntityIndex);
		if (alreadyAttackedBeforeMonster != LastAttackedMonsters.end()) {
			++index;
			++EntityIndex;
			continue; //Skip the monsters that you already tried to attack.
		}

		if (lastTargetedMonsterIndexCached != EntityIndex //Avoid attacking the last monster you targeted before.
			&& isGoodNpcId(EntityIndex, entityOffset) == 1) // Is good Npc Id (bad skins could mean it will click on players etc..)
		{
			myX = (float)MapX(1);
			myY = (float)MapY(1);
			mobX = (float)MapX(EntityIndex);
			mobY = (float)MapY(EntityIndex);
			// (33 = attacked monster)
			// (34 = monster dead)
			// (35 = probably also something like dead but unknown)
			// (28 = Walking Monster)
			// (1 = Standing Still Monster)
			//&& (ReadMemory(MainBaseAddress, "byte", 3, 0x828, entityOffset, 0x38) == 1 // (1 = Standing Still Monster?)
			//|| ReadMemory(MainBaseAddress, "byte", 3, 0x828, entityOffset, 0x38) == 28))

			if (GetDistance(mobX, mobY, myX, myY) < MaxDistance
				&& (ReadBytePointer(MainBaseAddress, 3, AutoClickMonster_Offset_1, entityOffset, AutoClickMonster_Offset_10) == 1 // (1 = Standing Still Monster)
					|| ReadBytePointer(MainBaseAddress, 3, AutoClickMonster_Offset_1, entityOffset, AutoClickMonster_Offset_10) == 28)) //(28 = Walking Monster)
			{
				if (Fix_AttackMerc) {
					DWORD isAttackablePlayerOrMonsterId = ReadDWordPointer(MainBaseAddress, 4, isMonsterAttackable_Offset_1, entityOffset, isMonsterAttackable_Offset_2, isMonsterAttackable_Offset_3);
					myprintf(true, false, false, TextColor::RED, XorStr("isAttackablePlayerOrMonsterId = %X\n"), isAttackablePlayerOrMonsterId);

					DWORD addressNpcOrMonster = (DWORD)(*(DWORD*)(*(DWORD*)((*(DWORD*)((*(DWORD*)(MainBaseAddress)) + (isMonsterAttackable_Offset_1))) + (entityOffset)) + (isMonsterAttackable_Offset_2)) + (isMonsterAttackable_Offset_3));
					myprintf(true, false, false, TextColor::RED, XorStr("Attacking Address = [%X]\n"), addressNpcOrMonster);
					DWORD npcCheck = getNpcId(EntityIndex);
					DWORD npcIdsSize = sizeof(NpcIds) / sizeof(NpcIds[0]);
					if (npcCheck < npcIdsSize)
						myprintf(true, false, false, TextColor::RED, XorStr("Attacking = [%d] %s\n"), npcCheck, NpcIds[npcCheck].c_str());
					else
						myprintf(true, false, false, TextColor::RED, XorStr("Bug: Attacking unknown npc [%d]\n"), npcCheck);
				}
				closestEntityIndex = EntityIndex;
			}
		}
		++index;
		++EntityIndex;
	}
        return closestEntityIndex;
}
Here is my code to call both functions.

Code:
	float CheckDistances[] = { 5, 10, 15, 20, 25, 30, 35, 40, 45, 50 };
	DWORD WalkTimes[] = { 2000, 2000, 3000, 3000, 4000, 5000, 6000, 6000, 7000, 8000 }; //2 to 8 seconds.

	int distanceCheckIndex = 0;

	while (distanceCheckIndex < 10) {
		checkTargetedMonsterEntityId= GetClosestMonsterInArea(CheckDistances[distanceCheckIndex]);

		if (checkTargetedMonsterEntityId!= -1)
			break;
		distanceCheckIndex++;
	}

	if (checkTargetedMonsterEntityId== -1) {
		//No monsters were found for all Distances, clear the monster queue list to atleast get some action.
		LastAttackedMonsters.clear();
		return;
	}

	if ((clock() - TimmerClick) > WalkTimes[distanceCheckIndex]) //2 to 8 seconds.
	{
		//Cannot attack monster for 15 seconds, force teleport to monster.
		if (conf_use_avoid_collisions && (clock() - TimmerLastTargetMonsterToAttack) > 30000) {
			if (GetMapId() != 0 || (MapX(checkTargetedMonsterEntityId) != 0 && MapY(checkTargetedMonsterEntityId) != 0))
				Teleport(GetMapId(), MapX(checkTargetedMonsterEntityId), MapY(checkTargetedMonsterEntityId));
			TimmerLastTargetMonsterToAttack = clock();
		}

		ClickOnMonster(checkTargetedMonsterEntityId);
		LastAttackedMonsters.insert(checkTargetedMonsterEntityId); //add to queue of monsters it checked.
		as_action = CLOSE_WINDOWS; //fix to stop clicking non-stop this caused lag.
		lastTargetedMonsterReset = true;
		TimmerClick = clock();
	}
HighGamer. is offline  
Old 08/11/2025, 14:20   #9
 
elite*gold: 0
Join Date: Feb 2011
Posts: 19
Received Thanks: 5
Quote:
Originally Posted by HighGamer. View Post
using NiCamera and World2Screen function is the old way of doing it that's how AOBot v1.0 was.. it involved hooking DirectX but it wasn't as fast with clicking mouse coordinates on screen, this one can move to monster without even seeing the monster on screen which is faster..

EntityIndex I believe is just a number index in a array of all monsters it starts from 6 I believe and goes very high, EntityIndex = 1 is your character.

I think max is 510 monsters in one area is limit.

Here is my code how I find closest monster to attack

Code:
signed int GetClosestMonsterInArea(float MaxDistance)
{
	float myX;
	float myY;
	float mobX;
	float mobY;

	int EntityIndex = 6;
	int closestEntityIndex = -1;

	int index = 0;
	int entityOffset = 0x40;

	while (index < 510) //old value was 2040 and entityOffset was 0x40 going by 4 every loop.
	{
		entityOffset = ((index * 4) + 0x40);

		//Skip the monsters that you already tried to attack.
		std::unordered_set<DWORD>::const_iterator alreadyAttackedBeforeMonster = LastAttackedMonsters.find(EntityIndex);
		if (alreadyAttackedBeforeMonster != LastAttackedMonsters.end()) {
			++index;
			++EntityIndex;
			continue; //Skip the monsters that you already tried to attack.
		}

		if (lastTargetedMonsterIndexCached != EntityIndex //Avoid attacking the last monster you targeted before.
			&& isGoodNpcId(EntityIndex, entityOffset) == 1) // Is good Npc Id (bad skins could mean it will click on players etc..)
		{
			myX = (float)MapX(1);
			myY = (float)MapY(1);
			mobX = (float)MapX(EntityIndex);
			mobY = (float)MapY(EntityIndex);
			// (33 = attacked monster)
			// (34 = monster dead)
			// (35 = probably also something like dead but unknown)
			// (28 = Walking Monster)
			// (1 = Standing Still Monster)
			//&& (ReadMemory(MainBaseAddress, "byte", 3, 0x828, entityOffset, 0x38) == 1 // (1 = Standing Still Monster?)
			//|| ReadMemory(MainBaseAddress, "byte", 3, 0x828, entityOffset, 0x38) == 28))

			if (GetDistance(mobX, mobY, myX, myY) < MaxDistance
				&& (ReadBytePointer(MainBaseAddress, 3, AutoClickMonster_Offset_1, entityOffset, AutoClickMonster_Offset_10) == 1 // (1 = Standing Still Monster)
					|| ReadBytePointer(MainBaseAddress, 3, AutoClickMonster_Offset_1, entityOffset, AutoClickMonster_Offset_10) == 28)) //(28 = Walking Monster)
			{
				if (Fix_AttackMerc) {
					DWORD isAttackablePlayerOrMonsterId = ReadDWordPointer(MainBaseAddress, 4, isMonsterAttackable_Offset_1, entityOffset, isMonsterAttackable_Offset_2, isMonsterAttackable_Offset_3);
					myprintf(true, false, false, TextColor::RED, XorStr("isAttackablePlayerOrMonsterId = %X\n"), isAttackablePlayerOrMonsterId);

					DWORD addressNpcOrMonster = (DWORD)(*(DWORD*)(*(DWORD*)((*(DWORD*)((*(DWORD*)(MainBaseAddress)) + (isMonsterAttackable_Offset_1))) + (entityOffset)) + (isMonsterAttackable_Offset_2)) + (isMonsterAttackable_Offset_3));
					myprintf(true, false, false, TextColor::RED, XorStr("Attacking Address = [%X]\n"), addressNpcOrMonster);
					DWORD npcCheck = getNpcId(EntityIndex);
					DWORD npcIdsSize = sizeof(NpcIds) / sizeof(NpcIds[0]);
					if (npcCheck < npcIdsSize)
						myprintf(true, false, false, TextColor::RED, XorStr("Attacking = [%d] %s\n"), npcCheck, NpcIds[npcCheck].c_str());
					else
						myprintf(true, false, false, TextColor::RED, XorStr("Bug: Attacking unknown npc [%d]\n"), npcCheck);
				}
				closestEntityIndex = EntityIndex;
			}
		}
		++index;
		++EntityIndex;
	}
        return closestEntityIndex;
}
Here is my code to call both functions.

Code:
	float CheckDistances[] = { 5, 10, 15, 20, 25, 30, 35, 40, 45, 50 };
	DWORD WalkTimes[] = { 2000, 2000, 3000, 3000, 4000, 5000, 6000, 6000, 7000, 8000 }; //2 to 8 seconds.

	int distanceCheckIndex = 0;

	while (distanceCheckIndex < 10) {
		checkTargetedMonsterEntityId= GetClosestMonsterInArea(CheckDistances[distanceCheckIndex]);

		if (checkTargetedMonsterEntityId!= -1)
			break;
		distanceCheckIndex++;
	}

	if (checkTargetedMonsterEntityId== -1) {
		//No monsters were found for all Distances, clear the monster queue list to atleast get some action.
		LastAttackedMonsters.clear();
		return;
	}

	if ((clock() - TimmerClick) > WalkTimes[distanceCheckIndex]) //2 to 8 seconds.
	{
		//Cannot attack monster for 15 seconds, force teleport to monster.
		if (conf_use_avoid_collisions && (clock() - TimmerLastTargetMonsterToAttack) > 30000) {
			if (GetMapId() != 0 || (MapX(checkTargetedMonsterEntityId) != 0 && MapY(checkTargetedMonsterEntityId) != 0))
				Teleport(GetMapId(), MapX(checkTargetedMonsterEntityId), MapY(checkTargetedMonsterEntityId));
			TimmerLastTargetMonsterToAttack = clock();
		}

		ClickOnMonster(checkTargetedMonsterEntityId);
		LastAttackedMonsters.insert(checkTargetedMonsterEntityId); //add to queue of monsters it checked.
		as_action = CLOSE_WINDOWS; //fix to stop clicking non-stop this caused lag.
		lastTargetedMonsterReset = true;
		TimmerClick = clock();
	}
Ah I see thats why the NiCamera approach is need zoom bound.

Yes I was able to determine nearest monster approximate to character using my first entity list (with large stride)
Because when I use offset of entity list from your examples in aoth it just contains monsterId and it just one pointer not two like yours.
And it just contains monsterId not pointer to target or maybe different structure? Because aoth is v16 and mine is v3? Idk either.
Also I was able to replicate the click function based on your example via cheat engine, but I wasn't able to find AttackClock and AutoclickMonster_Offset_5 is not monsterId on V3 but something else in memory, Idk like 2 bytes.
But again when I click the random monster first then I set value of entity index (monsterClickPointer + AutoClickMonster_Offset_7), currentMapId (monsterClickPointer + AutoClickMonster_Offset_8) and actionState (monsterClickPointer + AutoClickMonster_Offset_10) to 30
It gonna click the monster BUT the problem is it must click at random monster first. Maybe you can help me again 😂

Ps: I cannot find what attackClock is because maybe its different struct or login when it comes to v3 or v16. Maybe its like flag by timestamp to determine that event sent by user input is "fresh" or idk
geol88 is offline  
Old 08/13/2025, 00:06   #10
 
HighGamer.'s Avatar
 
elite*gold: 50
Join Date: May 2014
Posts: 1,910
Received Thanks: 941
v3 atlantica should have the same AttackClock etc to find it mess around with IDA PRO on the unpacked Thailand game.. then find same pattern in v3 client too.

To get random monster first, use (rand() % 510) + 1 and check if its a valid monster in a loop like so

Code:
    while(1) {
       random_monster = (rand() % 510) + 1;
       if(!isValidEntity(random_monster)) continue;
       Attack(random_monster);
       break;
    }
Use Plugin BinDiff to find it quickly in less then 5 minutes.



I PM'd you with a download link to IDA PRO 9.2 Beta 1 and Plugins I use.

Found the clock for you in V3 in less then a minute


0xBAC in Thailand
0xB4C in Atlantica V3.
HighGamer. is offline  
Old 08/13/2025, 05:57   #11
 
elite*gold: 0
Join Date: Feb 2011
Posts: 19
Received Thanks: 5
Quote:
Originally Posted by HighGamer. View Post
v3 atlantica should have the same AttackClock etc to find it mess around with IDA PRO on the unpacked Thailand game.. then find same pattern in v3 client too.

To get random monster first, use (rand() % 510) + 1 and check if its a valid monster in a loop like so

Code:
    while(1) {
       random_monster = (rand() % 510) + 1;
       if(!isValidEntity(random_monster)) continue;
       Attack(random_monster);
       break;
    }
Use Plugin BinDiff to find it quickly in less then 5 minutes.



I PM'd you with a download link to IDA PRO 9.2 Beta 1 and Plugins I use.

Found the clock for you in V3 in less then a minute


0xBAC in Thailand
0xB4C in Atlantica V3.
Hey I already done with Attack Monster on world map thanks to you.
And also I already done with attack and loot monster on Battle Map/Room (just attack not magic, im too lazy too mapping magic order)

Now I have question on teleport
Is the teleport is calling in game function or direct changing value like move to target? Or its by Sending WSASend packet? I already found the encrypt/decrypt packets function using your IDA.
So where to start if I wanna do teleport with assigning MapId, X and Y?
Thanks
geol88 is offline  
Old 09/02/2025, 10:16   #12
 
elite*gold: 0
Join Date: Sep 2025
Posts: 1
Received Thanks: 0
Quote:
Originally Posted by HighGamer. View Post
v3 atlantica should have the same AttackClock etc to find it mess around with IDA PRO on the unpacked Thailand game.. then find same pattern in v3 client too.

To get random monster first, use (rand() % 510) + 1 and check if its a valid monster in a loop like so

Code:
    while(1) {
       random_monster = (rand() % 510) + 1;
       if(!isValidEntity(random_monster)) continue;
       Attack(random_monster);
       break;
    }
Use Plugin BinDiff to find it quickly in less then 5 minutes.



I PM'd you with a download link to IDA PRO 9.2 Beta 1 and Plugins I use.

Found the clock for you in V3 in less then a minute


0xBAC in Thailand
0xB4C in Atlantica V3.
thank you for your tips, it really helps understanding the mechanic
now I have another question, how do you do battle speed in game?
monsterkikuk is offline  
Old 09/05/2025, 02:57   #13
 
HighGamer.'s Avatar
 
elite*gold: 50
Join Date: May 2014
Posts: 1,910
Received Thanks: 941
Quote:
Originally Posted by monsterkikuk View Post
thank you for your tips, it really helps understanding the mechanic
now I have another question, how do you do battle speed in game?
battlespeed is written down in my update notes as so.

Code:
	00856E3E   55               PUSH EBP
	00856E3F   8BEC             MOV EBP,ESP
	00856E41   51               PUSH ECX
	00856E42   53               PUSH EBX
	00856E43   56               PUSH ESI
	00856E44   8B35 AC04C901    MOV ESI,DWORD PTR DS:[0x1C904AC]
	00856E4A   57               PUSH EDI
	00856E4B   8BD9             MOV EBX,ECX
	00856E4D   8B8E 84100000    MOV ECX,DWORD PTR DS:[ESI+0x1084]
	00856E53   6A 00            PUSH 0x0
	00856E55   E8 C0C4D2FF      CALL 0058331A
	00856E5A   6A 02            PUSH 0x2
	00856E5C   E8 FFA61200      CALL 00981560
	00856E61   59               POP ECX
	00856E62   E8 25A71200      CALL 0098158C
	00856E67   8B78 18          MOV EDI,DWORD PTR DS:[EAX+0x18]
	00856E6A   8BCF             MOV ECX,EDI
	00856E6C   E8 12B21300      CALL 00992083
	00856E71   DB05 C47F4902    FILD DWORD PTR DS:[0x2497FC4]        //THIS IS SPEED ADDRESS
	00856E77   51               PUSH ECX
	00856E78   8BCF             MOV ECX,EDI
	00856E7A   DC05 88928501    FADD QWORD PTR DS:[0x1859288]
	00856E80   D95D FC          FSTP DWORD PTR SS:[EBP-0x4]
	00856E83   D945 FC          FLD DWORD PTR SS:[EBP-0x4]
	00856E86   DC35 A8928501    FDIV QWORD PTR DS:[0x18592A8]
	00856E8C   D95D FC          FSTP DWORD PTR SS:[EBP-0x4]
	00856E8F   D945 FC          FLD DWORD PTR SS:[EBP-0x4]
	00856E92   D91C24           FSTP DWORD PTR SS:[ESP]
	00856E95   E8 85A11300      CALL 0099101F
	00856E9A   6A 02            PUSH 0x2
	00856E9C   B9 487F4902      MOV ECX,0x2497F48
	00856EA1   E8 6FD5D0FF      CALL 00564415
	00856EA6   8BCB             MOV ECX,EBX
	00856EA8   E8 01F3FFFF      CALL 008561AE
	00856EAD   8BCB             MOV ECX,EBX
	00856EAF   E8 C6D9FFFF      CALL 0085487A
	00856EB4   8B86 BC100000    MOV EAX,DWORD PTR DS:[ESI+0x10BC]
	00856EBA   5F               POP EDI
	00856EBB   5E               POP ESI
	00856EBC   C640 01 01       MOV BYTE PTR DS:[EAX+0x1],0x1
	00856EC0   5B               POP EBX
	00856EC1   C9               LEAVE
	00856EC2   C3               RETN

	//The speed value is always set to 0x82 in this area good place to steal the address from.
	005D8F5F   50                        PUSH EAX
	005D8F60   E8 831AFCFF               CALL 0059A9E8
	005D8F65   85C0                      TEST EAX,EAX
	005D8F67   74 0A                     JE SHORT 005D8F73
	005D8F69   C705 C47F4902 82000000    MOV DWORD PTR DS:[0x2497FC4],0x82        //Speed address.
	005D8F73   5F                        POP EDI
	005D8F74   5E                        POP ESI
	005D8F75   C2 1000                   RETN 0x10

	C7 05 ?? ?? ?? ?? 82 00 00 00  works perfectly to find it.

	//System->Settings->System->Set Battle Speed = Very Slow = 80
	//System->Settings->System->Set Battle Speed = Medium = 100
	Default speed is 130
HighGamer. is offline  
Old 10/04/2025, 09:06   #14
 
elite*gold: 0
Join Date: Feb 2011
Posts: 19
Received Thanks: 5
Teleport

Quote:
Originally Posted by HighGamer. View Post
battlespeed is written down in my update notes as so.

Code:
	00856E3E   55               PUSH EBP
	00856E3F   8BEC             MOV EBP,ESP
	00856E41   51               PUSH ECX
	00856E42   53               PUSH EBX
	00856E43   56               PUSH ESI
	00856E44   8B35 AC04C901    MOV ESI,DWORD PTR DS:[0x1C904AC]
	00856E4A   57               PUSH EDI
	00856E4B   8BD9             MOV EBX,ECX
	00856E4D   8B8E 84100000    MOV ECX,DWORD PTR DS:[ESI+0x1084]
	00856E53   6A 00            PUSH 0x0
	00856E55   E8 C0C4D2FF      CALL 0058331A
	00856E5A   6A 02            PUSH 0x2
	00856E5C   E8 FFA61200      CALL 00981560
	00856E61   59               POP ECX
	00856E62   E8 25A71200      CALL 0098158C
	00856E67   8B78 18          MOV EDI,DWORD PTR DS:[EAX+0x18]
	00856E6A   8BCF             MOV ECX,EDI
	00856E6C   E8 12B21300      CALL 00992083
	00856E71   DB05 C47F4902    FILD DWORD PTR DS:[0x2497FC4]        //THIS IS SPEED ADDRESS
	00856E77   51               PUSH ECX
	00856E78   8BCF             MOV ECX,EDI
	00856E7A   DC05 88928501    FADD QWORD PTR DS:[0x1859288]
	00856E80   D95D FC          FSTP DWORD PTR SS:[EBP-0x4]
	00856E83   D945 FC          FLD DWORD PTR SS:[EBP-0x4]
	00856E86   DC35 A8928501    FDIV QWORD PTR DS:[0x18592A8]
	00856E8C   D95D FC          FSTP DWORD PTR SS:[EBP-0x4]
	00856E8F   D945 FC          FLD DWORD PTR SS:[EBP-0x4]
	00856E92   D91C24           FSTP DWORD PTR SS:[ESP]
	00856E95   E8 85A11300      CALL 0099101F
	00856E9A   6A 02            PUSH 0x2
	00856E9C   B9 487F4902      MOV ECX,0x2497F48
	00856EA1   E8 6FD5D0FF      CALL 00564415
	00856EA6   8BCB             MOV ECX,EBX
	00856EA8   E8 01F3FFFF      CALL 008561AE
	00856EAD   8BCB             MOV ECX,EBX
	00856EAF   E8 C6D9FFFF      CALL 0085487A
	00856EB4   8B86 BC100000    MOV EAX,DWORD PTR DS:[ESI+0x10BC]
	00856EBA   5F               POP EDI
	00856EBB   5E               POP ESI
	00856EBC   C640 01 01       MOV BYTE PTR DS:[EAX+0x1],0x1
	00856EC0   5B               POP EBX
	00856EC1   C9               LEAVE
	00856EC2   C3               RETN

	//The speed value is always set to 0x82 in this area good place to steal the address from.
	005D8F5F   50                        PUSH EAX
	005D8F60   E8 831AFCFF               CALL 0059A9E8
	005D8F65   85C0                      TEST EAX,EAX
	005D8F67   74 0A                     JE SHORT 005D8F73
	005D8F69   C705 C47F4902 82000000    MOV DWORD PTR DS:[0x2497FC4],0x82        //Speed address.
	005D8F73   5F                        POP EDI
	005D8F74   5E                        POP ESI
	005D8F75   C2 1000                   RETN 0x10

	C7 05 ?? ?? ?? ?? 82 00 00 00  works perfectly to find it.

	//System->Settings->System->Set Battle Speed = Very Slow = 80
	//System->Settings->System->Set Battle Speed = Medium = 100
	Default speed is 130
Hey, thanks again. I was able to create bot on version 3 with some basic feature using ImGui for creating form.
but I was struggle to replicate your teleport function

my current bot can do teleport or automove using send packet teleport. but I cannot bypass Will Requirement and Map Information restrictions.
can you also give me help on that?
or just clue is fine.
also on my current bot, on TBS/Skirmish its limited to do guard or skip. I was wondering if I can move to tile X? or its too much to do? because the function of move to tile X is also passing parameter that have like "valid tile to move" etc.
thanks
geol88 is offline  
Reply


Similar Threads Similar Threads
Calling ingame function through C++? [Question]
01/25/2022 - Last Chaos - 3 Replies
Hello! I have a question. I know, that C++ can call ingame functions through pushing register to it. But when I was debugging LC through x64dbg, I noticed that every ingame function get called from packet sending through messageDispatcher (but I'mm not sure..). So here is a question: Can I execute call ingame functions not through packets? Or the only way to it - packet sending?
std::function of a function returning an std::function
11/11/2013 - C/C++ - 19 Replies
Nun muss ich nach langer Zeit auch mal wieder einen Thread erstellen, weil mir Google nicht mehr weiterhelfen kann. Ich verzweifle an Folgendem Vorhaben: #include <Windows.h> #include <string> #include <iostream> using namespace std;
Need some help calling function for height
07/27/2011 - Perfect World - 2 Replies
Hey there, for some reason I keep crashing upon trying to call this function and it's really pissing me off. I was wondering if somebody could give me some advice as to what I'm doing wrong :( The function is being called inside a function starting at address 0x465730 in PWI The function I'm looking for is called twice here, namely at 0x4657C7 and 0x465879. The code where it is called looks something like this: http://img94.imageshack.us/img94/9867/coordfuncti on.png Now, I'm...
Help, calling an ingame function
03/13/2010 - General Coding - 2 Replies
Im trying with my dll to set off the "set stat function". The one that u press when you add a stat point to str, dex or what ever. My goal is to make players able to set there Stats to whatever they use to have from an earlier saved point. So if you play against different sort of mobs or players you reform your stats to be suetable for that sertan task in just 1 second right where you stand. Im thinking this is very useful for many ppl here. So now i could use help with the actuall call of...
Help with calling this function!
03/13/2010 - 12Sky2 - 6 Replies
First off: sorry for my poor english! Im trying with my dll to set off the "set stat function". The one that u press when you add a stat point to str, dex or what ever. My goal is to make players able to set there Stats to whatever they use to have from an earlier saved point. So if you play against different sort of mobs or players you reform your stats to be suetable for that sertan task in just 1 second right where you stand. Im thinking this is very useful for many ppl here. So now i...



All times are GMT +1. The time now is 11:10.


Powered by vBulletin®
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2025 elitepvpers All Rights Reserved.