[Release] Get Height

01/29/2011 13:15 ILikeItEasy#1
So many releases lately. I thought it was time to make a contribution as well.

A couple of years ago, Bakabug released KalHack11. I don't think he likes to be reminded on the way he wrote code back then, but even so... his code has been the base of many sources till today.

Basically his method to get the height in KalHack11 was:

PHP Code:
DWORD OrigHeight      SearchPattern("55 8B EC 81 EC 94 00 00 00 D9 45 08 D8 35 ? ? ? ? D9 5D 08",0x00400000,0x007FFFFF);
DWORD MyHeightBack    OrigHeight 9;

float Naked MyHeightDetour(DWORD x,DWORD y,...)
{
    
__asm
    
{
        
push ebp
        mov ebp
esp
        sub esp
94h
        jmp     MyHeightBack 
    
}
}

DWORD Naked Something(DWORD some,DWORD some2,...)
{
    
_asm
    
{
        
push ebp
        mov ebp
esp
        push ecx
        fild 
[ebp+0x08]
        
mov eax, [ebp+0x0C]
        
shl eax0Dh
        mov 
[ebp-0x04], eax
        fisub 
[ebp-0x04]
        
mov espebp
        pop ebp
        fstp 
[ebp-0x04]
        
mov     eax,[ebp-0x04]
        
retn
    
}
}

int Height(int Xint Y)
{
    return (int)
MyHeightDetour(Something(X,0x20),Something(Y,0x20))*10;


While working with this, I found out it was kinda buggy. My knowledge of asm is.... well, to be honost, I have no knowledge about asm at all xD. So I tried to figure out what this Something function did and succeeded.

So.. here it is: Height calculation :P

PHP Code:
DWORD pHeight         SearchPattern("55 8B EC 81 EC 94 00 00 00 D9 45 08 D8 35 x x x x D9 5D 08",0x00400000,0x007FFFFF);

typedef float (__cdecl oHeight)(float Xfloat Y);

int Height(int Xint Y)
{
    return (int)(((
oHeight)pHeight)(X-262144,Y-262144)*10);

Few hours of work for this little code :D

Remarks:
This function does not work inside a dungeon and on emok.. It will return 0 there.
Other thing is, it also returns 0 if the 3D map isn't loaded in your kalclient! (when you walk with packets, you can get outside the area where the client has loaded the landscape for and that will cause this Height function to fail)

If anyone has a suggestion on how to force the client to load the 3D map/landscape, feel free to post here or send me a PM ;)

My thanks go to Bakabug for his help :)
01/30/2011 15:45 ILikeItEasy#2
I've had an idea about how to make the client force to load the landscape and it worked...

Big thanks syntex for your help with this :)
01/30/2011 20:08 DrogenViech#3
Why does it take X and Y as arguments? Doesn't it return your characters actual Z position? I'm a bit puzzled at what this function actually does :confused:
01/30/2011 21:39 MoepMeep#4
Quote:
Originally Posted by DrogenViech View Post
Why does it take X and Y as arguments? Doesn't it return your characters actualy Z position? I'm a bit puzzled at what this function actually does :confused:
What else should it take? <.<
01/30/2011 21:47 ILikeItEasy#5
It returns the corresponding Z for each X/Y, as long as it is on the map that is loaded into the memory of the client.

The X and Y coordinates as you get from /coordinates and from packets are different from the X and Y that the client uses for the calculation of height. I've made the function Height so that you can give the X/Y coords as provided for by the packets.

Usage example:

Current location: x,y,z = 2000, 2000, 1000
Destination: x,y,z = 4000,5000,1200

calc distance (disregard z) = sqrt((4000-2000)^2+(5000-2000)^2)
calc number of steps to take = (distance/myspeed) +1 (myspeed = 11 + grade of speedup, +1 for roundup)
make steps loop:
CurX=PlayerList[0]->x
CurY=PlayerList[0]->y
CurZ=PlayerList[0]->z
NextX=CurX+(DestinationX-CurX)/steps
NextY=CurY+(DestinationY-CurY)/steps
NextZ=Height(NextX,NextY)
if(steps>1) SendPacket(0x11,"bbb",NextX-CurX,NextY-CurY,NextZ-CurZ)
if(steps==1) SendPacket(0x12,"bbb",NextX-CurX,NextY-CurY,NextZ-CurZ)


This is an indication of how you can use it.
Carefull with max Z per packet.. if the value gets to high, you need to cut the step in 2 till it's ok.
Can be wise to check inbetween steps if you're not luring the whole area if you're on normal speed ^^

[edit] forgot this.. the client sends about 4 walk packets per sec if you are walking like a normal player.
01/30/2011 22:16 DrogenViech#6
Quote:
Originally Posted by MoepMeep View Post
What else should it take? <.<
Thanks for your deep, insightful explaination of this function :awesome:


Quote:
Originally Posted by ILikeItEasy View Post
It returns the corresponding Z for each X/Y, as long as it is on the map that is loaded into the memory of the client.

The X and Y coordinates as you get from /coordinates and from packets are different from the X and Y that the client uses for the calculation of height. I've made the function Height so that you can give the X/Y coords as provided for by the packets.

Usage example:

Current location: x,y,z = 2000, 2000, 1000
Destination: x,y,z = 4000,5000,1200

calc distance (disregard z) = sqrt((4000-2000)^2+(5000-2000)^2)
calc number of steps to take = (distance/myspeed) +1 (myspeed = 11 + grade of speedup, +1 for roundup)
make steps loop:
CurX=PlayerList[0]->x
CurY=PlayerList[0]->y
CurZ=PlayerList[0]->z
NextX=CurX+(DestinationX-CurX)/steps
NextY=CurY+(DestinationY-CurY)/steps
NextZ=Height(NextX,NextY)
if(steps>1) SendPacket(0x11,"bbb",NextX-CurX,NextY-CurY,NextZ-CurZ)
if(steps==1) SendPacket(0x12,"bbb",NextX-CurX,NextY-CurY,NextZ-CurZ)


This is an indication of how you can use it.
Carefull with max Z per packet.. if the value gets to high, you need to cut the step in 2 till it's ok.
Can be wise to check inbetween steps if you're not luring the whole area if you're on normal speed ^^

[edit] forgot this.. the client sends about 4 walk packets per sec if you are walking like a normal player.
Awesome, thank you :D
01/30/2011 22:40 Doofy#7
Quote:
forgot this.. the client sends about 4 walk packets per sec if you are walking like a normal player.
depends on the steps in each packet?!
01/31/2011 00:31 ILikeItEasy#8
No, "steps" in my explenation means 1 packet. Per packet at G0 speed you cover a distance of 11, G1=12, G2=13, G3=14.

distance is sqrt(difx * difx + dify * dify).

Increased speed does not mean increased rate of packets send.

What we do with "teleport to next mob" is make abuse of the ability of the server to coop with lag next to using the max difx and dify per packet (+/- 44). Sending the walk packets needed to go to the next mob all at once pretending our client to have had lag.
01/31/2011 00:50 ILikeItEasy#9
General warning:
If you plan on using this to make a bot walk on the ground... You really have to understand the math. The walk-with-packets-tut somewhere else on this forum will make you walk in curves most of the time.
The descriptive usage will let you walk in a straight line, but you will walk right through objects.
Furthermore.. you will walk on the ground all the time. You won't walk over a bridge, but you will walk on the bottom of the river to get to the other side.
01/31/2011 01:17 meak1#10
or u use OnMapClick.

Bakabugs HeightDetour was working ever but u needed to change a little...
Use it like the old just Change the _asm of Something..i marked

Just look why those function crash if u use the old...Learn by doing =/
PHP Code:
DWORD Naked Something(DWORD some,DWORD some2,...)
{
_asm
{
push ebp
mov ebp
esp
push ecx
fild 
[ebp+0x08]
mov eax, [ebp+0x0C]
shl eax0Dh
mov 
[ebp-0x04], eax
fisub 
[ebp-0x04]
mov espebp
/////////////////////////
fstp [ebp-0x04]
mov eax,[ebp-0x04]
pop ebp
/////////////////////////
retn
}

PHP Code:
MyHeightDetour(Something(Player[0].X+tempx,0x20),Something(Player[0].Y+tempy,0x20))*10
And urs not Correct =P

--> return (int)((oHeight)pHeight)(X-262143,Y-262143)*10; <-- Correct
01/31/2011 01:31 RunzelEier#11
für nen player like bot ist onmapclick wahrscheinlich wirklich das beste
01/31/2011 08:33 ILikeItEasy#12
LOL at Meak..
262143 or 262142 doesn't make the difference, but I will recheck and correct it ;)

I could very well have made an error. I have to say I didn't really check the asm since I have a really hard time understanding it. When I look at it now though, I do notice a lot of -0x04. Looks to me like a shift that cuts off the first 4 bytes i.c. lowering the INT value with 0x4000. 0x4000 = 262144

Now I start to get confused... :D

k.. will have to do some checking. For now I advise all to use 262143 since I'm pretty sure Meak1 has a much better understanding of asm then me :handsdown:
01/31/2011 16:56 meak1#13
i found "262143" with onmapclick

MapClick(0,Mob[target].X-262143,0,Mob[target].Y-262143)

KalOnline client coordinates != server/map coords, its the same with the Z calculate from Baka

If u walk to Y:0 on mapclick, ur client Coordinates Y:262143, i think 262143,6 or so

Jeah my english is best =D

This Something() func is in engine to calculate it(u can find the func if u search in engine "fisub [ebp-0x04]"),
what i marked was added from Baka

i Just breakpointed on this Function in Kal and saw why it crash, the pop ebp changed the stack and eax cant handle some other value as pointer or so, argh someone else explain better pls =P

PHP Code:
DWORD Naked Something(DWORD some,DWORD some2,...)
{
_asm
{
push ebp
mov ebp
esp
push ecx
fild 
[ebp+0x08]
mov eax, [ebp+0x0C]
shl eax0Dh
mov 
[ebp-0x04], eax
fisub 
[ebp-0x04]
mov espebp
////////////////////////////////////////////////////////
fstp [ebp-0x04// <- fstp first stack to pointer or so
mov eax,[ebp-0x04// <- mov eax, pointer(eax = arg1 to return)
////////////////////////////////////////////////////////
pop ebp
retn
}

But i not understand why HeightDetour Return something...
PHP Code:
float Naked MyHeightDetour(DWORD x,DWORD y,...)
{
__asm
{
push ebp
mov ebp
esp
sub esp
94h
jmp MyHeightBack 
//back to original
}

Explain me pls why, no return there oO
Why i get Z if i call the func ? there is only a jump =x

Edit: ah i think it jumps back to func and there is a retn =P
01/31/2011 18:43 ILikeItEasy#14
I checked and it is exactly 262144
(equals to hex: 0x00040000 or binairy: 0000 0000 0000 0100 0000 0000 0000)
The engine substract this from the int X and Y before it recasts it to float.

Respect for not just deleting the thingy about "Why i get Z if i call the func ? there is only a jump =x". But HOW COULD YOU FORGET???? :D :D
Back in the old days all functions where hooked like this instead of "re-using" excisting functions like we do now with: ((OrigFunction)PointerToOrigFunction)(args...)

At least you show that even experienced people like you can make mistakes or forget smth :)
01/31/2011 18:55 syntex#15
((OrigFunction)PointerToOrigFunction)(args...)

ZeroTen showed me how to hook with function ptrs.

credits go to him.