MoveByPacket Function

09/29/2013 14:11 xortexx#1
Hello,

I find it difficult to do the MoveByPacket function (in SendPackets) in C # :

Code:
public enum PacketMoveType { Flying = 0x61, Jumping = 0x28, Running = 0x21, Walking = 0x20, Swimming = 0xA1 };
public void moveByPackets(Coordinates Destination, PacketMoveType MoveType)
{
	float Speed;
	short MoveCounter;

	Coordinates currentCoords = new Coordinates(InfoCharacter.CharacterCoordinates);

	switch (MoveType)
	{
		case PacketMoveType.Flying:
			Speed = InfoCharacter.CharacterSpeedFly;
			break;

		case PacketMoveType.Jumping:
			Speed = InfoCharacter.CharacterSpeedRun;
			break;

		case PacketMoveType.Running:
			Speed = InfoCharacter.CharacterSpeedRun;
			break;

		case PacketMoveType.Walking:
			Speed = InfoCharacter.CharacterSpeedWalk;
			break;

		case PacketMoveType.Swimming:
			Speed = InfoCharacter.CharacterSpeedSwim;
			break;

		default:
			Speed = InfoCharacter.CharacterSpeedRun;
			break;
	}

	short TimeInterval = 1000;
	float TimeNeeded = Destination.Range3D(currentCoords) / Speed;

	float dX = ((Destination.X - currentCoords.X) / TimeNeeded) * TimeInterval / 1000;
	float dY = ((Destination.Y - currentCoords.Y) / TimeNeeded) * TimeInterval / 1000;
	float dZ = ((Destination.Z - currentCoords.Z) / TimeNeeded) * TimeInterval / 1000;

	if (Speed > 0)
	{
		while (TimeNeeded > (float)TimeInterval / 1000)
		{
			currentCoords.X += dX;
			currentCoords.Y += dY;
			currentCoords.Z += dZ;

			MoveCounter = InfoCharacter.CharacterMoveCounter;
			MoveTo(currentCoords.X, currentCoords.Y, currentCoords.Z, TimeInterval, Speed, 0, MoveCounter);

			MoveCounter++;
			InfoCharacter.CharacterMoveCounter = MoveCounter;

			TimeNeeded -= (float)TimeInterval / 1000;
			Thread.Sleep(TimeInterval);
		}

		if (TimeNeeded > 0)
		{
			MoveCounter = InfoCharacter.CharacterMoveCounter;
			currentCoords.X += dX * TimeNeeded;
			currentCoords.Y += dY * TimeNeeded;
			currentCoords.Z += dZ * TimeNeeded;

			MoveStop(currentCoords.X, currentCoords.Y, currentCoords.Z, (short)(TimeNeeded * 1000), Speed, (byte)MoveType, MoveCounter, 0);

			MoveCounter++;
			InfoCharacter.CharacterMoveCounter = MoveCounter;
		}
	}
}

private int moveAddress;
private byte[] moveAddressRev;
private byte[] movePkt = new byte[] 
{ 
	0x00, 0x00,                 //Header
	0x00, 0x00, 0x00, 0x00,     //x coord
	0x00, 0x00, 0x00, 0x00,      //y coord
	0x00, 0x00, 0x00, 0x00,      //z coord
	0x00, 0x00, 0x00, 0x00,      //x coord
	0x00, 0x00, 0x00, 0x00,      //y coord
	0x00, 0x00, 0x00, 0x00,      //z coord
	0x00, 0x00,                 //interval
	0x00, 0x00,                 //speed
	0x00,                       //moveType
	0x00, 0x00                  //counter
};
public void MoveTo(float xCoord, float yCoord, float zCoord, short interval, float speed, byte moveType, short moveCounter)
{
	int packetSize = movePkt.Length;
	if (moveAddress == 0)
		LoadPacket(movePkt, ref moveAddress, ref moveAddressRev);

	byte[] xCoordRev = BitConverter.GetBytes(xCoord);
	xCoordRev.Reverse();
	Library.Memory.WriteBytes(moveAddress + 2, xCoordRev);
	Library.Memory.WriteBytes(moveAddress + 14, xCoordRev);
	byte[] yCoordRev = BitConverter.GetBytes(yCoord);
	yCoordRev.Reverse();
	Library.Memory.WriteBytes(moveAddress + 6, yCoordRev);
	Library.Memory.WriteBytes(moveAddress + 18, yCoordRev);
	byte[] zCoordRev = BitConverter.GetBytes(zCoord);
	zCoordRev.Reverse();
	Library.Memory.WriteBytes(moveAddress + 10, zCoordRev);
	Library.Memory.WriteBytes(moveAddress + 22, zCoordRev);
	byte[] intervalRev = BitConverter.GetBytes(interval);
	intervalRev.Reverse();
	Library.Memory.WriteBytes(moveAddress + 26, intervalRev);
	short shortSpeed = (short)(speed * 256 + 0.5);
	byte[] shortSpeedRev = BitConverter.GetBytes(shortSpeed);
	shortSpeedRev.Reverse();
	Library.Memory.WriteBytes(moveAddress + 28, shortSpeedRev);
	Library.Memory.WriteByte(moveAddress + 30, moveType);
	byte[] moveCounterRev = BitConverter.GetBytes(moveCounter);
	moveCounterRev.Reverse();
	Library.Memory.WriteBytes(moveAddress + 31, moveCounterRev);
	SendPacket(moveAddressRev, packetSize);
}

//Move Stop
private int moveStopAddress;
private byte[] moveStopAddressRev;

private byte[] moveStopPkt = new byte[] 
{ 
	0x07, 0x00,                 //Header
	0x00, 0x00, 0x00, 0x00,     //x coord
	0x00, 0x00, 0x00, 0x00,     //y coord
	0x00, 0x00, 0x00, 0x00,     //z coord
	0x00, 0x00,                 //speed
	0x00,                       //direction
	0x00,                       //moveType
	0x00, 0x00,                 //counter
	0x00, 0x00                  //interval

};

public void MoveStop(float xCoord, float yCoord, float zCoord, short interval, float speed, byte moveType, short moveCounter, byte direction)
{
	int packetSize = moveStopPkt.Length;
	if (moveStopAddress == 0)
		LoadPacket(moveStopPkt, ref moveStopAddress, ref moveStopAddressRev);

	byte[] xCoordRev = BitConverter.GetBytes(xCoord);
	xCoordRev.Reverse();
	Library.Memory.WriteBytes(moveStopAddress + 2, xCoordRev);

	byte[] yCoordRev = BitConverter.GetBytes(yCoord);
	yCoordRev.Reverse();
	Library.Memory.WriteBytes(moveStopAddress + 6, yCoordRev);

	byte[] zCoordRev = BitConverter.GetBytes(zCoord);
	zCoordRev.Reverse();
	Library.Memory.WriteBytes(moveStopAddress + 10, zCoordRev);

	byte[] intervalRev = BitConverter.GetBytes(interval);
	intervalRev.Reverse();
	Library.Memory.WriteBytes(moveStopAddress + 20, intervalRev);

	short shortSpeed = (short)(speed * 256 + 0.5);
	byte[] shortSpeedRev = BitConverter.GetBytes(shortSpeed);
	shortSpeedRev.Reverse();
	Library.Memory.WriteBytes(moveStopAddress + 14, shortSpeedRev);

	Library.Memory.WriteByte(moveStopAddress + 16, direction);
	Library.Memory.WriteByte(moveStopAddress + 17, moveType);

	byte[] moveCounterRev = BitConverter.GetBytes(moveCounter);
	moveCounterRev.Reverse();
	Library.Memory.WriteBytes(moveStopAddress + 18, moveCounterRev);

	SendPacket(moveStopAddressRev, packetSize);
}
BaseAddress = 12817100
CharStruct = 52

(Short) InfoCharacter.CharacterMoveCounter = ((BaseAddress + CharStruct) + 2564)
(Float) InfoCharacter.CharacterSpeedFly = ((BaseAddress + CharStruct) + 1292)
(Float) InfoCharacter.CharacterSpeedRun = ((BaseAddress + CharStruct) + 1284)
(Float) InfoCharacter.CharacterSpeedWalk = ((BaseAddress + CharStruct) + 1280)
(Float) InfoCharacter.CharacterSpeedSwim = ((BaseAddress + CharStruct) + 1288)

(Coordinates) InfoCharacter.CharacterCoordinates And Destination are used like this:

Code:
public class Coordinates
{
	public float X;
	public float Y;
	public float Z;

	public float DisplayX { get { return (float)Math.Round((X + 4000) / 10, 1); } }
	public float DisplayY { get { return (float)Math.Round((Y + 5500) / 10, 1); } }
	public float DisplayZ { get { return (float)Math.Round(Z / 10, 1); } }

	public Coordinates()
	{
		X = 0;
		Y = 0;
		Z = 0;
	}

	public Coordinates(float x, float y, float z)
	{
		this.X = x;
		this.Y = y;
		this.Z = z;
	}

	public Coordinates(Coordinates Coords)
	{
		this.X = Coords.X;
		this.Y = Coords.Y;
		this.Z = Coords.Z;
	}

	public float Range3D(Coordinates Dest)
	{
		float dX = X - Dest.X;
		float dY = Y - Dest.Y;
		float dZ = Z - Dest.Z;
		return (float)Math.Round(Math.Sqrt(dX * dX + dY * dY + dZ * dZ), 1);
	}

	public float Range2D(Coordinates Dest)
	{
		float dX = X - Dest.X;
		float dZ = Z - Dest.Z;
		return (float)Math.Sqrt(dX * dX + dZ * dZ);
	}
}
The problem is that the MoveByPackets does nothing. I thought i had the wrong offset on SendPacket_Adress and SendPacket_Adress, but not since i use functions SelectTarget, RegularAttack, PickUpItem they work.
If you have an idea of the problem or if you have any questions do not hesitate to post.

For Perfect World International
09/29/2013 18:17 Interest07#2
Are you updating your moveCounter and player coordinates properly after every packet sent(manually changing their values in memory to the new values)?
09/29/2013 23:43 xortexx#3
Thank ank you for your answer Interest07 ;)

I'm too stupid :facepalm: , it's obvious, I add the update values ​​moveCounter and player send coordinates to each request packet, like this:

Code:
public enum PacketMoveType { Flying = 0x61, Jumping = 0x28, Running = 0x21, Walking = 0x20, Swimming = 0xA1 };
public void moveByPackets(Coordinates Destination, PacketMoveType MoveType)
{
	float Speed;
	short MoveCounter;

	Coordinates currentCoords = new Coordinates(InfoCharacter.CharacterCoordinates);

	switch (MoveType)
	{
		case PacketMoveType.Flying:
			Speed = InfoCharacter.CharacterSpeedFly;
			break;

		case PacketMoveType.Jumping:
			Speed = InfoCharacter.CharacterSpeedRun;
			break;

		case PacketMoveType.Running:
			Speed = InfoCharacter.CharacterSpeedRun;
			break;

		case PacketMoveType.Walking:
			Speed = InfoCharacter.CharacterSpeedWalk;
			break;

		case PacketMoveType.Swimming:
			Speed = InfoCharacter.CharacterSpeedSwim;
			break;

		default:
			Speed = InfoCharacter.CharacterSpeedRun;
			break;
	}

	short TimeInterval = 1000;
	float TimeNeeded = Destination.Range3D(currentCoords) / Speed;

	float dX = ((Destination.X - currentCoords.X) / TimeNeeded) * TimeInterval / 1000;
	float dY = ((Destination.Y - currentCoords.Y) / TimeNeeded) * TimeInterval / 1000;
	float dZ = ((Destination.Z - currentCoords.Z) / TimeNeeded) * TimeInterval / 1000;

	if (Speed > 0)
	{
		while (TimeNeeded > (float)TimeInterval / 1000)
		{
			MoveCounter = InfoCharacter.CharacterMoveCounter;
			currentCoords.X += dX;
			currentCoords.Y += dY;
			currentCoords.Z += dZ;

			MoveTo(currentCoords.X, currentCoords.Y, currentCoords.Z, TimeInterval, Speed, 0, MoveCounter);
			
			InfoCharacter.CharacterCoordinates = currentCoords;

			MoveCounter++;
			InfoCharacter.CharacterMoveCounter = MoveCounter;

			TimeNeeded -= (float)TimeInterval / 1000;
			Thread.Sleep(TimeInterval);
		}

		if (TimeNeeded > 0)
		{
			MoveCounter = InfoCharacter.CharacterMoveCounter;
			currentCoords.X += dX * TimeNeeded;
			currentCoords.Y += dY * TimeNeeded;
			currentCoords.Z += dZ * TimeNeeded;

			MoveStop(currentCoords.X, currentCoords.Y, currentCoords.Z, (short)(TimeNeeded * 1000), Speed, (byte)MoveType, MoveCounter, 0);
			
			InfoCharacter.CharacterCoordinates = currentCoords;

			MoveCounter++;
			InfoCharacter.CharacterMoveCounter = MoveCounter;
		}
	}
}
(Coordinates) InfoCharacter.CharacterCoordinates = currentCoords;

MemoryWriteFloat(CharacterBase + 60, InfoCharacter.CharacterCoordinates.X);
MemoryWriteFloat(CharacterBase + 68, InfoCharacter.CharacterCoordinates.Y);
MemoryWriteFloat(CharacterBase + 64, InfoCharacter.CharacterCoordinates.Z);


(Short) InfoCharacter.CharacterMoveCounter = MoveCounter;

MemoryWriteShort(CharacterBase + 2564), InfoCharacter.CharacterMoveCounter);


But it does not change much, except that the camera view moves as change of displacement but not the character. :rtfm:

I still make a mistake somewhere but I do not know where.
09/30/2013 00:58 Sᴡoosh#4
Well obviously you won't see a smooth movement, except for your camera - but others do.
09/30/2013 22:21 xortexx#5
I'm just looking to move the character by MoveByPacket function .... Maybe it's just a dream :D
10/02/2013 11:33 xortexx#6
Nobody has a suggestion to the problem?
I think the structure of the packets is bad

Code:
        private byte[] movePkt = new byte[] 
        { 
            0x00, 0x00,                 //Header
            0x00, 0x00, 0x00, 0x00,     //x coord
            0x00, 0x00, 0x00, 0x00,      //y coord
            0x00, 0x00, 0x00, 0x00,      //z coord
            0x00, 0x00, 0x00, 0x00,      //x coord
            0x00, 0x00, 0x00, 0x00,      //y coord
            0x00, 0x00, 0x00, 0x00,      //z coord
            0x00, 0x00,                 //interval
            0x00, 0x00,                 //speed
            0x00,                       //moveType
            0x00, 0x00                  //counter
        };
But how can i check if the structure is good?
10/12/2013 05:14 Stark77#7
I cannot realy help you but i got a question to that topic aswell.

Like Interest said in an other post ([Only registered and activated users can see links. Click Here To Register...]) the structure is like this:

0000<X><Y><Z><X><Y><Z><interval><speed><moveType>< counter>

I would be interest in just performing a simple "jump". I tried to use this structure with current coordinates and 28 as movetype...but i dont know the speed and counter so i guess thats why its not working.

Does anyone know how to do a simple "jump" just by sending a packet like this?
10/12/2013 10:55 Interest07#8
Quote:
Originally Posted by Stark77 View Post
I cannot realy help you but i got a question to that topic aswell.

Like Interest said in an other post ([Only registered and activated users can see links. Click Here To Register...]) the structure is like this:

0000<X><Y><Z><X><Y><Z><interval><speed><moveType>< counter>

I would be interest in just performing a simple "jump". I tried to use this structure with current coordinates and 28 as movetype...but i dont know the speed and counter so i guess thats why its not working.

Does anyone know how to do a simple "jump" just by sending a packet like this?
If you mean an actual ingame jump, it's actually several movement packets and it's prolly easier to do by calling the jump function. If you just mean going 'speed' meters up into the air, you will definitely need the counter or the packet will never be processed. Speed is generally just 5 m/s when unbuffed.
10/12/2013 17:11 Stark77#9
I just mean an ingame jump - so u say there is a simple packet to call the jump function or do u mean something else?
10/12/2013 18:36 Interest07#10
Quote:
Originally Posted by Stark77 View Post
I just mean an ingame jump - so u say there is a simple packet to call the jump function or do u mean something else?
I'm saying the exact opposite, there's an easy function to call, but it's tough with sending packets.
10/12/2013 19:32 Stark77#11
Oh i see - i read that wrong sry.

Guess with my programming abilities atm this wont work out but thanks alot for your help =)
10/12/2013 20:17 Sᴡoosh#12
I actually hate the jump function. You need 3 static addresses, and action struct. It's a bitch to maintain, and it's not very stable when I tested it. Packets would be the way to go.
10/13/2013 01:30 Shareen#13
Quote:
Originally Posted by Stark77 View Post
Oh i see - i read that wrong sry.

Guess with my programming abilities atm this wont work out but thanks alot for your help =)
It's more a thing of maths (or rather physics) than programming.

What you need to do is calculate points on trajectory path for a projectile.

It's not the easiest thing to do, however real world examples can be greatly simplified for PW, since you can exclude air drag, wind and some other forces associated with projectiles in real world.

What you should take into account is gravity (PW uses roughly same gravitational acceleration as objects on Earth, which is about 9.8m/ss).

Points on trajectory path should be calculated for each time T where T2-T1 (or delta T) is about 500ms, since that's how often motion packets are sent.

You will also need to know initial speed of a projectile (character) and the angle at which it is thrown (jumps).

I should also point out, that my tests with packets for free falling objects indicate that while there is no terminal velocity for falling objects, server is very accurate regarding speed an object is allowed to reach in free fall as well as acceleration.
For this reason I find using gravitational acceleration of less than 9.8m/ss is beneficial for higher lags (150-250ms), for example I had good results with 9.0-9.4 m/ss, depending on lag.
This is something to be weary of when calculating second part of trajectory (free fall part).

It is entirely possible that you can further simplify trajectory and still be ok with server, but that's down to trial and error.

Check below wiki link and research form there.
Trajectory - Wikipedia, the free encyclopedia
10/13/2013 02:17 Stark77#14
Thanks for your input =)
I will try this out a bit tomorrow - i also think there is a different in gravity if u are in an instance like frost or outside in worldmap.
If i manage to get something to work i will repost it.
10/16/2013 18:55 afropanda#15
do you have a bot that breakdowns the items in your inventory?