Register for your free account! | Forgot your password?

Go Back   elitepvpers > MMORPGs > Perfect World
You last visited: Today at 21:47

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

Advertisement



Movement Packets?

Discussion on Movement Packets? within the Perfect World forum part of the MMORPGs category.

Reply
 
Old   #1
 
elite*gold: 0
Join Date: Jul 2011
Posts: 57
Received Thanks: 8
Movement Packets?

Okay, so I want to mess around with sending movement packets a little bit. Did some searching and came across this post:


but it's a bit confusing to me.

First off, for the origin...
Quote:
0000<X><Y><Z><X><Y><Z><interval><speed><moveType>< counter>
The first vec3 origin is your current origin, and the 2nd is the destination right? And you keep updating the first (current) origin every 500 ms? Also, I assume _byteswap_ulong will work fine for reversing the byte order of the origin floats?


Then the interval, I assume thats just a standard ushort, so using _byteswap_ushort should work fine there? And for the speed.. this should be treated as a float at first for calculation, than converted to a ushort??

And then the counter. Incremented with each packet sent, I get that. But does it start at 0 or 1 for the first packet? And apparently it's in the player struct? So does that have to be incremented before sending the packet or what? And do you have the offset for the counter?


And do you have the current packet ids for move / stop moving?


So in the end, if I'm correct, the packet should be something like this? note vec3_t is just float[3] pretty much.
ushort - packet id (not sure what if its 0000 )
vec3_t - current Origin (bytes x/y/z reversed)
vec3_t - dest Origin (bytes x/y/z reversed)
ushort - interval (500 ms)
ushort - speed (float for calculation, then converted to ushort)
BYTE - movement type
ushort - counter (incremented in the player struct and then copied into the packet)




The post was pretty confusing to me, so any help would be nice lol. Also, forgive me if there's typos, haven't slept yet and its noon here. xD Thanks in advance
boredsauce is offline  
Old 03/05/2012, 21:00   #2
 
Interest07's Avatar
 
elite*gold: 0
Join Date: Mar 2010
Posts: 862
Received Thanks: 576
movement counter can be found at player + 0x96C

send the packet with that value, then update it.

the movement packet structure is as follows:
Code:
class MovePkt : public Packet
{
public:
	float x1;
	float y1;
	float z1;
	float x2;
	float y2;
	float z2;
	short interval;
	short speed;
	byte moveType;
	short counter;
};


//Send function example:
void PWpacketSender::move(float x, float y, float z, short interval, float speed, byte moveType, short moveCounter )
{
	if(!movePkt)
	{
		//Initialize the packet
		movePkt = new MovePkt();
		memset(movePkt, 0, sizeof(MovePkt));
		movePkt->header = 0x00;
		loadedPackets.push_back(movePkt);
	}
	//Destination coordinates
	movePkt->x1 = x;
	movePkt->y1 = y;
	movePkt->z1 = z;
	movePkt->x2 = x;
	movePkt->y2 = y;
	movePkt->z2 = z;

	//Time since start of this movement
	movePkt->interval = interval;
	
	//Perform some magic on the speed
	short shortSpeed = (short)(speed * 256 + 0.5);
	movePkt->speed = shortSpeed;

	//Type of movement, e.g. Running or Flying
	movePkt->moveType = moveType;

	//Every movement packet this counter is increased by 1
	movePkt->counter = moveCounter;

	send(movePkt, sizeof(MovePkt));
}
coords1 and coords2 are identical and both your destination.


Quote:
Originally Posted by boredsauce View Post
Okay, so I want to mess around with sending movement packets a little bit. Did some searching and came across this post:


but it's a bit confusing to me.

First off, for the origin...


The first vec3 origin is your current origin, and the 2nd is the destination right? And you keep updating the first (current) origin every 500 ms? Also, I assume _byteswap_ulong will work fine for reversing the byte order of the origin floats?


Then the interval, I assume thats just a standard ushort, so using _byteswap_ushort should work fine there? And for the speed.. this should be treated as a float at first for calculation, than converted to a ushort??

And then the counter. Incremented with each packet sent, I get that. But does it start at 0 or 1 for the first packet? And apparently it's in the player struct? So does that have to be incremented before sending the packet or what? And do you have the offset for the counter?


And do you have the current packet ids for move / stop moving?


So in the end, if I'm correct, the packet should be something like this? note vec3_t is just float[3] pretty much.
ushort - packet id (not sure what if its 0000 )
vec3_t - current Origin (bytes x/y/z reversed)
vec3_t - dest Origin (bytes x/y/z reversed)
ushort - interval (500 ms)
ushort - speed (float for calculation, then converted to ushort)
BYTE - movement type
ushort - counter (incremented in the player struct and then copied into the packet)




The post was pretty confusing to me, so any help would be nice lol. Also, forgive me if there's typos, haven't slept yet and its noon here. xD Thanks in advance
Interest07 is offline  
Thanks
1 User
Old 03/06/2012, 22:51   #3
 
elite*gold: 0
Join Date: Jul 2011
Posts: 57
Received Thanks: 8
Well, that helped, thanks. But why would it want the destination origin twice? o.O
boredsauce is offline  
Old 03/07/2012, 09:49   #4
 
Interest07's Avatar
 
elite*gold: 0
Join Date: Mar 2010
Posts: 862
Received Thanks: 576
Quote:
Originally Posted by boredsauce View Post
Well, that helped, thanks. But why would it want the destination origin twice? o.O
PW works in mysterious ways. That's all I can say really; when you spend some time digging around their code you end up scratching your head quite a bit.
Interest07 is offline  
Thanks
1 User
Old 04/26/2012, 13:20   #5
 
elite*gold: 0
Join Date: Jul 2011
Posts: 57
Received Thanks: 8
So today I decided to start working on movement stuff again. I opened up the "PW Packet Sniffer" and started looking at the movement packets.


I recorded a simple movement.
Code:
>MOVE PACKETS
PID	ORIGIN1				ORIGIN2				INTRV	SPEED	TYPE	SEQUENCE
--------------------------------------------------------------------------------------------------------
0000	7CC120C5,BDDF0843,788847C5	7CC120C5,BDDF0843,788847C5	F301	0005	21	0500
0000	069C20C5,BDDF0843,749647C5	069C20C5,BDDF0843,749647C5	F301	0005	21	0600
0000	8E7620C5,BDDF0843,6EA447C5	8E7620C5,BDDF0843,6EA447C5	F401	0005	21	0700
0000	175120C5,BDDF0843,67B247C5	175120C5,BDDF0843,67B247C5	F301	0005	21	0800
0000	9F2B20C5,BDDF0843,60C047C5	9F2B20C5,BDDF0843,60C047C5	F401	0005	21	0900
0000	290620C5,BDDF0843,5CCE47C5	290620C5,BDDF0843,5CCE47C5	F301	0005	21	0A00
0000	B2E01FC5,BDDF0843,57DC47C5	B2E01FC5,BDDF0843,57DC47C5	F401	0005	21	0B00
0000	3BBB1FC5,BCDF0843,50EA47C5	3BBB1FC5,BCDF0843,50EA47C5	F301	0005	21	0C00
0000	C5951FC5,BCDF0843,4CF847C5	C5951FC5,BCDF0843,4CF847C5	F301	0005	21	0D00
0000	4E701FC5,BCDF0843,3F0648C5	4E701FC5,BCDF0843,3F0648C5	F301	FF04	21	0E00
0000	D74A1FC5,BCDF0843,331448C5	D74A1FC5,BCDF0843,331448C5	F401	FF04	21	0F00




>STOP PACKET
PID	ORIGIN				SPEED	DIR	TYPE	SEQ	INTRV
-----------------------------------------------------------------------------
0700	DA271FC5,BCDF0843,3A2148C5	FF04	F2	21	1000	D201
As you see, the destination origin changed with each packet. And the speed also changed a bit in the end, which is weird.



Why does the destination origin change with each packet? I thought the origin was supposed to stay the same? And also, why would the speed change? I also noticed if you move only a little bit - like tap W or click an inch in front of you character - it only sends a 25 byte packet.




So anyway, when I tried sending some movement packets, it didn't work. My character seemed to lag a little and that's it.
boredsauce is offline  
Old 04/26/2012, 13:34   #6
 
Interest07's Avatar
 
elite*gold: 0
Join Date: Mar 2010
Posts: 862
Received Thanks: 576
Quote:
Originally Posted by boredsauce View Post
So today I decided to start working on movement stuff again. I opened up the "PW Packet Sniffer" and started looking at the movement packets.


I recorded a simple movement.
Code:
>MOVE PACKETS
PID	ORIGIN1				ORIGIN2				INTRV	SPEED	TYPE	SEQUENCE
--------------------------------------------------------------------------------------------------------
0000	7CC120C5,BDDF0843,788847C5	7CC120C5,BDDF0843,788847C5	F301	0005	21	0500
0000	069C20C5,BDDF0843,749647C5	069C20C5,BDDF0843,749647C5	F301	0005	21	0600
0000	8E7620C5,BDDF0843,6EA447C5	8E7620C5,BDDF0843,6EA447C5	F401	0005	21	0700
0000	175120C5,BDDF0843,67B247C5	175120C5,BDDF0843,67B247C5	F301	0005	21	0800
0000	9F2B20C5,BDDF0843,60C047C5	9F2B20C5,BDDF0843,60C047C5	F401	0005	21	0900
0000	290620C5,BDDF0843,5CCE47C5	290620C5,BDDF0843,5CCE47C5	F301	0005	21	0A00
0000	B2E01FC5,BDDF0843,57DC47C5	B2E01FC5,BDDF0843,57DC47C5	F401	0005	21	0B00
0000	3BBB1FC5,BCDF0843,50EA47C5	3BBB1FC5,BCDF0843,50EA47C5	F301	0005	21	0C00
0000	C5951FC5,BCDF0843,4CF847C5	C5951FC5,BCDF0843,4CF847C5	F301	0005	21	0D00
0000	4E701FC5,BCDF0843,3F0648C5	4E701FC5,BCDF0843,3F0648C5	F301	FF04	21	0E00
0000	D74A1FC5,BCDF0843,331448C5	D74A1FC5,BCDF0843,331448C5	F401	FF04	21	0F00




>STOP PACKET
PID	ORIGIN				SPEED	DIR	TYPE	SEQ	INTRV
-----------------------------------------------------------------------------
0700	DA271FC5,BCDF0843,3A2148C5	FF04	F2	21	1000	D201
As you see, the destination origin changed with each packet. And the speed also changed a bit in the end, which is weird.



Why does the destination origin change with each packet? I thought the origin was supposed to stay the same? And also, why would the speed change? I also noticed if you move only a little bit - like tap W or click an inch in front of you character - it only sends a 25 byte packet.




So anyway, when I tried sending some movement packets, it didn't work. My character seemed to lag a little and that's it.
The first and second locations you send should always be equal, not sure what you mean with destination origin. They're both your destination for this packet. There are two types of movement packets: 0x00, and 0x07.

At the end of a series of movement packets you send a 0x07 packet, or as I call it a 'stop packet'. This packet only contains the destination once and also has a byte reserved for the direction in which you are facing at the end of the movement.

for example, when you want to move from 0,0,0 to 0, 0, 9 with movement speed 2 m/s, you'd send packets as follows:

sendpacket 0x00(0,0,2) (0,0,2) rest of crap
sendpacket 0x00(0,0,4) (0,0,4) rest of crap
sendpacket 0x00(0,0,6) (0,0,6) rest of crap
sendpacket 0x00(0,0,8) (0,0,8) rest of crap
sendpacket 0x07(0,0,9)rest of crap for this packet (so direction for example)


In c++ these functions & packets can be defined as follows:

Code:
class MovePkt : public Packet
{
public:
	float x1;
	float y1;
	float z1;
	float x2;
	float y2;
	float z2;
	short interval;
	short speed;
	byte moveType;
	short counter;
};

class MoveStopPkt : public Packet
{
public:
	float x;
	float y;
	float z;
	short speed;
	byte direction;
	byte moveType;
	short counter;
	short interval;
};


void PWpacketSender::move(float x, float y, float z, short interval, float speed, byte moveType, short moveCounter )
{
	if(!movePkt)
	{
		//Initialize the packet
		movePkt = new MovePkt();
		memset(movePkt, 0, sizeof(MovePkt));
		movePkt->header = 0x00;
		loadedPackets.push_back(movePkt);
	}
	//Destination coordinates
	movePkt->x1 = x;
	movePkt->y1 = y;
	movePkt->z1 = z;
	movePkt->x2 = x;
	movePkt->y2 = y;
	movePkt->z2 = z;

	//Time since the last packet
	movePkt->interval = interval;
	
	//Perform some magic on the speed
	short shortSpeed = (short)(speed * 256 + 0.5);
	movePkt->speed = shortSpeed;

	//Type of movement, e.g. Running or Flying
	movePkt->moveType = moveType;

	//Every movement packet this counter is increased by 1
	movePkt->counter = moveCounter;

	send(movePkt, sizeof(MovePkt));
}

//Last packet when moving
void PWpacketSender::moveStop(float x, float y, float z, short interval, float speed, byte moveType, short moveCounter, byte direction)
{
	if(!moveStopPkt)
	{
		//Initialize the packet
		moveStopPkt = new MoveStopPkt();
		memset(moveStopPkt, 0, sizeof(MoveStopPkt));
		moveStopPkt->header = 0x07;
		loadedPackets.push_back(moveStopPkt);
	}
	//Destination coordinates
	moveStopPkt->x = x;
	moveStopPkt->y = y;
	moveStopPkt->z = z;

	//Time since the last packet
	moveStopPkt->interval = interval;
	
	//Perform some magic on the speed
	short shortSpeed = (short)(speed * 256 + 0.5);
	moveStopPkt->speed = shortSpeed;

	//Type of movement, e.g. Running or Flying
	moveStopPkt->moveType = moveType;

	//Every movement packet this counter is increased by 1
	moveStopPkt->counter = moveCounter;

	//Direction in which your character is facing at the end of the movement
	moveStopPkt->direction = direction;

	send(moveStopPkt, sizeof(MoveStopPkt));
}
So when moving with packets you'd basically do in pseudocode:

Code:
while(timeNeeded > packetTimeIntervalMax)
{
	sendMovePacket(interval := packetTimeIntervalMax);
	timeNeeded-=packetTimeIntervalMax;
}
sendStopMovePacket(interval := timeNeeded);
When you tap W it moves less than packetTimeIntervalMax worth of time, so directly sends a stop movement packet.

Speed changes don't really matter Sucha little difference

Wait, a 25 byte packet?? What header does that have Oo
Interest07 is offline  
Thanks
1 User
Old 04/26/2012, 15:26   #7
 
elite*gold: 0
Join Date: Mar 2009
Posts: 112
Received Thanks: 123
Destination isn't final destination, ie the far point in the distance you want to reach.

It is destination to the first step you need to take, which is the distance you can travel in approximately 500ms at your current running (edit: or flying, depending on your move type) speed.

Entire "travel" or move is a combination of many steps in approximately 500ms intervals, each with it's own "destination".

Server is extremely touchy about the accuracy of these packets, a simple stab will most likely not produce results. Flying might be easier, since you can eliminate terrain problems however.
Shareen is offline  
Thanks
1 User
Old 04/26/2012, 17:40   #8
 
elite*gold: 0
Join Date: Jul 2011
Posts: 57
Received Thanks: 8
Quote:
Originally Posted by Interest07 View Post
The first and second locations you send should always be equal, not sure what you mean with destination origin. They're both your destination for this packet. There are two types of movement packets: 0x00, and 0x07.
I thought the vec3's in the packet were supposed to be your final destination at first.


Quote:
Originally Posted by Interest07 View Post
At the end of a series of movement packets you send a 0x07 packet, or as I call it a 'stop packet'. This packet only contains the destination once and also has a byte reserved for the direction in which you are facing at the end of the movement.

for example, when you want to move from 0,0,0 to 0, 0, 9 with movement speed 2 m/s, you'd send packets as follows:

sendpacket 0x00(0,0,2) (0,0,2) rest of crap
sendpacket 0x00(0,0,4) (0,0,4) rest of crap
sendpacket 0x00(0,0,6) (0,0,6) rest of crap
sendpacket 0x00(0,0,8) (0,0,8) rest of crap
sendpacket 0x07(0,0,9)rest of crap for this packet (so direction for example)
So wait. How do you determine the 'origin' to place in the packet? Is it something like
origin[ axis ] = currentOrigin[ axis ] + speed?



Quote:
Originally Posted by Interest07 View Post
So when moving with packets you'd basically do in pseudocode:

Code:
while(timeNeeded > packetTimeIntervalMax)
{
	sendMovePacket(interval := packetTimeIntervalMax);
	timeNeeded-=packetTimeIntervalMax;
}
sendStopMovePacket(interval := timeNeeded);
When you tap W it moves less than packetTimeIntervalMax worth of time, so directly sends a stop movement packet.
Don't think I understand your example.
packetTimeIntervalMax = time between sending packets? ex. 500 ms
interval = ?
timeNeeded = total time needed to send out all packets to complete the movement?

Also, not sure what ":=" is or does, don't know the language. I'm familiar with C and C# but I don't know what that operator is.



Quote:
Originally Posted by Interest07 View Post
Wait, a 25 byte packet?? What header does that have Oo
When I open up "PW Packet Sniff", the movements look like this:
Code:
move packet:
222221000083971AC5C91F0643258E44C583971AC5C91F0643258E44C5F601FE04210A04

stop packet:
2217160700B4AF1AC57E3A06430D8E44C5FC047F210B043001
As you can see, there's 3 bytes at the start of each packet. No idea what they are though.




--

Right now my goal is to make a simple function to move my character a few units in the direction it's facing, for X milliseconds. That is, for a simple "wall hack" - like walk through a door in a dungeon for example.




I tried sending a "stop packet" to move my character a little ways on the X axis... nothing happened.
boredsauce is offline  
Old 04/26/2012, 18:20   #9
 
elite*gold: 0
Join Date: Mar 2009
Posts: 112
Received Thanks: 123
Quote:
Originally Posted by boredsauce View Post
When I open up "PW Packet Sniff", the movements look like this:
Code:
move packet:
222221000083971AC5C91F0643258E44C583971AC5C91F0643258E44C5F601FE04210A04

stop packet:
2217160700B4AF1AC57E3A06430D8E44C5FC047F210B043001
As you can see, there's 3 bytes at the start of each packet. No idea what they are though.
Container op codes.
22 - client container, C->S
17 - length of the rest of data, bytes
16 - again, length of the rest of data, bytes
... data ...

It's designed so that each container can hold more than one "packet", but client, as far as I know, only ever uses it to send one "packet" per container.

Edit: Not that you'd ever had to use this, if you are sending packets trought client sendPacket function, since client wraps it into container for you. I just wanted to explain what those "extra" 3 bytes were in sniffer.
Shareen is offline  
Thanks
2 Users
Old 04/26/2012, 19:35   #10
 
Interest07's Avatar
 
elite*gold: 0
Join Date: Mar 2010
Posts: 862
Received Thanks: 576
I suppose my explanation wasn't very clear. By pseudo code I meant not really any specific syntax from any language, but ignore that bit for now, I'll give a more thorough explanation.

I wrote a bit of C# code and put in extensive commenting to better explain:

Code:

//Function to move from your current location to some specified location 'destination' in a straight line
//Only really useful for swimming or flying
private void moveByPackets(Coordinates destination, PacketMoveType moveType)
{
	float speed = 0;
	short moveCounter = 0;

	//Get our current location from the player struct
	Coordinates currentCoords = new Coordinates(player.coordinates);

	//Depending on the type of movement we get the speed from the player struct
	switch (moveType)
	{
		case PacketMoveType.Flying:
			speed = player.flySpeed;
			break;

		case PacketMoveType.Jumping:
			speed = player.runSpeed;
			break;

		case PacketMoveType.Running:
			speed = player.runSpeed;
			break;

		case PacketMoveType.Walking:
			speed = player.walkSpeed;
			break;

		case PacketMoveType.Swimming:
			speed = player.swimSpeed;
			break;

		default:
			//Something else
			Debug.WriteLine("Invalid moveType");
			speed = player.runSpeed;
			break;
	}

	/*Lets define the interval we use between packets. 
	The client sends movement packets as follows:
		It updates your position on the screen every time it renders the screen
		Every time it updates your position it checks how long it has been since 
		it has sent	a movement packet. If this time is more than 500 ms, it will 
		send a packet to update your position on the server.
		If your client is lagging (graphical lag, not bad ping), this time will 
		exceed the default 500 by a bit. Up to approximately 1000 ms is allowed
		by the server before you start experiencing rubberbanding.
		The higher the time between packets, the likelier it is that you do not 
		end up moving into some tree branch by accident as you travel further 
		each packet.
		This is why we set the timeInterval to a 'max' value of 1000 ms.
	*/
	short timeInterval = 1000; // in ms
	
	//Determine the distance between your current location and the destination.
	double distance = destination.distance(currentCoords);

	//Determine the time needed to travel this distance at the previously determined speed.
	float timeNeeded = destination.distance(currentCoords) / speed; //time in seconds

	//Determine the distance we travel in each direction in our time interval of 1000 ms.
	float dX = ((destination.x - currentCoords.x) / timeNeeded) * timeInterval / 1000; //distance in xDirection in 1 second * time traveled
	float dY = ((destination.y - currentCoords.y) / timeNeeded) * timeInterval / 1000; //distance in yDirection in 1 second * time traveled
	float dZ = ((destination.z - currentCoords.z) / timeNeeded) * timeInterval / 1000; //distance in zDirection in 1 second * time traveled

	//Lets send the packets now
	if (speed > 0)
	{
		//While the time we need exceeds the 1000 ms, we send regular move packets, once it's smaller we send a stopMove packet.
		while (timeNeeded > (float)timeInterval / 1000)
		{
			//Get the current move counter from the player struct.
			moveCounter = player.moveCounter;
			
			//Update the coordinates in the player struct by the amount we will travel this packet (so in 1000 ms)
			currentCoords.x += dX;
			currentCoords.y += dY;
			currentCoords.z += dZ;

			//Send a packet with the values we've previously determined
			sendPacket.move(currentCoords.x, currentCoords.y, currentCoords.z, timeInterval, speed, (byte)moveType, moveCounter);

			//There are several other coordinates in the player struct that determine the drawing of some part of the character.
			//The most well known location at 0x3C, 0x40, 0x44 is the point the camera looks at
			player.coordinates = currentCoords;
			//There are a couple of other locations though, for example the actual mesh of the character, your name, etc.
			//This is not important for getting the movement packets to work, just eye candy.
			player.coordinates2 = currentCoords;
			player.coordinates3 = currentCoords;
			player.coordinates4 = currentCoords;

			//Update the movecounter.
			moveCounter++;
			player.moveCounter = moveCounter;

			//Subtract the amount of time used this packet (1000 ms) from the total time needed
			timeNeeded -= (float)timeInterval / 1000;
			
			//Sleep for 1000 ms before sending the next packet.
			Thread.Sleep(timeInterval);
		}

		//We now need less than 1000 ms to reach our destination, send a stop packet for the remaining part.
		if (timeNeeded > 0)
		{
			moveCounter = player.moveCounter;
			currentCoords.x += dX * timeNeeded;
			currentCoords.y += dY * timeNeeded;
			currentCoords.z += dZ * timeNeeded;

			sendPacket.moveStop(currentCoords.x, currentCoords.y, currentCoords.z, (short)(timeNeeded * 1000), speed, (byte)moveType, moveCounter, 0);

			player.coordinates = currentCoords;
			player.coordinates2 = currentCoords;
			player.coordinates3 = currentCoords;
			player.coordinates4 = currentCoords;

			moveCounter++;
			player.moveCounter = moveCounter;
		}
	}
}
Interest07 is offline  
Thanks
1 User
Old 04/27/2012, 01:53   #11
 
elite*gold: 0
Join Date: Jul 2011
Posts: 57
Received Thanks: 8
Quote:
Originally Posted by Interest07 View Post
I suppose my explanation wasn't very clear. By pseudo code I meant not really any specific syntax from any language, but ignore that bit for now, I'll give a more thorough explanation.

I wrote a bit of C# code and put in extensive commenting to better explain:

Code:

//Function to move from your current location to some specified location 'destination' in a straight line
//Only really useful for swimming or flying
private void moveByPackets(Coordinates destination, PacketMoveType moveType)
{
	float speed = 0;
	short moveCounter = 0;

	//Get our current location from the player struct
	Coordinates currentCoords = new Coordinates(player.coordinates);

	//Depending on the type of movement we get the speed from the player struct
	switch (moveType)
	{
		case PacketMoveType.Flying:
			speed = player.flySpeed;
			break;

		case PacketMoveType.Jumping:
			speed = player.runSpeed;
			break;

		case PacketMoveType.Running:
			speed = player.runSpeed;
			break;

		case PacketMoveType.Walking:
			speed = player.walkSpeed;
			break;

		case PacketMoveType.Swimming:
			speed = player.swimSpeed;
			break;

		default:
			//Something else
			Debug.WriteLine("Invalid moveType");
			speed = player.runSpeed;
			break;
	}

	/*Lets define the interval we use between packets. 
	The client sends movement packets as follows:
		It updates your position on the screen every time it renders the screen
		Every time it updates your position it checks how long it has been since 
		it has sent	a movement packet. If this time is more than 500 ms, it will 
		send a packet to update your position on the server.
		If your client is lagging (graphical lag, not bad ping), this time will 
		exceed the default 500 by a bit. Up to approximately 1000 ms is allowed
		by the server before you start experiencing rubberbanding.
		The higher the time between packets, the likelier it is that you do not 
		end up moving into some tree branch by accident as you travel further 
		each packet.
		This is why we set the timeInterval to a 'max' value of 1000 ms.
	*/
	short timeInterval = 1000; // in ms
	
	//Determine the distance between your current location and the destination.
	double distance = destination.distance(currentCoords);

	//Determine the time needed to travel this distance at the previously determined speed.
	float timeNeeded = destination.distance(currentCoords) / speed; //time in seconds

	//Determine the distance we travel in each direction in our time interval of 1000 ms.
	float dX = ((destination.x - currentCoords.x) / timeNeeded) * timeInterval / 1000; //distance in xDirection in 1 second * time traveled
	float dY = ((destination.y - currentCoords.y) / timeNeeded) * timeInterval / 1000; //distance in yDirection in 1 second * time traveled
	float dZ = ((destination.z - currentCoords.z) / timeNeeded) * timeInterval / 1000; //distance in zDirection in 1 second * time traveled

	//Lets send the packets now
	if (speed > 0)
	{
		//While the time we need exceeds the 1000 ms, we send regular move packets, once it's smaller we send a stopMove packet.
		while (timeNeeded > (float)timeInterval / 1000)
		{
			//Get the current move counter from the player struct.
			moveCounter = player.moveCounter;
			
			//Update the coordinates in the player struct by the amount we will travel this packet (so in 1000 ms)
			currentCoords.x += dX;
			currentCoords.y += dY;
			currentCoords.z += dZ;

			//Send a packet with the values we've previously determined
			sendPacket.move(currentCoords.x, currentCoords.y, currentCoords.z, timeInterval, speed, (byte)moveType, moveCounter);

			//There are several other coordinates in the player struct that determine the drawing of some part of the character.
			//The most well known location at 0x3C, 0x40, 0x44 is the point the camera looks at
			player.coordinates = currentCoords;
			//There are a couple of other locations though, for example the actual mesh of the character, your name, etc.
			//This is not important for getting the movement packets to work, just eye candy.
			player.coordinates2 = currentCoords;
			player.coordinates3 = currentCoords;
			player.coordinates4 = currentCoords;

			//Update the movecounter.
			moveCounter++;
			player.moveCounter = moveCounter;

			//Subtract the amount of time used this packet (1000 ms) from the total time needed
			timeNeeded -= (float)timeInterval / 1000;
			
			//Sleep for 1000 ms before sending the next packet.
			Thread.Sleep(timeInterval);
		}

		//We now need less than 1000 ms to reach our destination, send a stop packet for the remaining part.
		if (timeNeeded > 0)
		{
			moveCounter = player.moveCounter;
			currentCoords.x += dX * timeNeeded;
			currentCoords.y += dY * timeNeeded;
			currentCoords.z += dZ * timeNeeded;

			sendPacket.moveStop(currentCoords.x, currentCoords.y, currentCoords.z, (short)(timeNeeded * 1000), speed, (byte)moveType, moveCounter, 0);

			player.coordinates = currentCoords;
			player.coordinates2 = currentCoords;
			player.coordinates3 = currentCoords;
			player.coordinates4 = currentCoords;

			moveCounter++;
			player.moveCounter = moveCounter;
		}
	}
}
Well, I just checked out the struct in reclass again... there certainly is a bunch of locations/origins xD


And yeah, that helps a lot. I had trouble trying to calculate the travel distance in the interval but I see how to do that now.


But 1 more thing. For calculating the travel distance, I'm using this sqrt:
Code:
d.x = x - _vec.x;
            d.y = y - _vec.y;
            d.z = z - _vec.z;


            return Math.Sqrt( d.x*d.x + d.y*d.y + d.z*d.z );
Works like a charm, however people say that using sqrt to calculate the distance between 2 points can be slow. Is there any other way of calculating the distance? I mean it's not really an issue here, but still if there's a better way I'd like to know lol.
boredsauce is offline  
Old 04/27/2012, 07:57   #12
 
Interest07's Avatar
 
elite*gold: 0
Join Date: Mar 2010
Posts: 862
Received Thanks: 576
Quote:
Originally Posted by boredsauce View Post
Well, I just checked out the struct in reclass again... there certainly is a bunch of locations/origins xD


And yeah, that helps a lot. I had trouble trying to calculate the travel distance in the interval but I see how to do that now.


But 1 more thing. For calculating the travel distance, I'm using this sqrt:
Code:
d.x = x - _vec.x;
            d.y = y - _vec.y;
            d.z = z - _vec.z;


            return Math.Sqrt( d.x*d.x + d.y*d.y + d.z*d.z );
Works like a charm, however people say that using sqrt to calculate the distance between 2 points can be slow. Is there any other way of calculating the distance? I mean it's not really an issue here, but still if there's a better way I'd like to know lol.
If you'd only need to compute the distance in order to compare distances (e.g which mob is further away) then you can do it by only multiplying and not using the square root part. In this case however you will want to use the sqrt as you need the actual distance.

I wouldn't worry about it though, as long as you have a sleep built into your main logic loop your bot won't use too much resources and still remain very responsive.
Interest07 is offline  
Thanks
1 User
Reply


Similar Threads Similar Threads
Movement Packets(Need Help)
08/18/2011 - SRO Coding Corner - 8 Replies
Hey all im making bot . i have problems with movement packets.I can't get posZ coordinat(Height) .Anyone have formule?
[Packets] Wie änder ich flyff packets?
07/16/2011 - Flyff Private Server - 19 Replies
HeyHo, Ich würde sehr gerne wissen wie man die Flyff Packets ändert... ich denke mal Zahlen ändern werden nicht ausreichen oder?
3d movement? how?
06/21/2009 - General Coding - 7 Replies
Hi guys, Well, i can use... 1. Autoscript 2. a packet bot 3. direct ingame manipulation ( the way i wanna try ) Any method has its benefits. 1.
Packets: Movement while flying
03/15/2006 - Conquer Online 2 - 4 Replies
Hi Just wondering if anyone knew what packet you use to move while flying. Do you just send the walk packet or the jump? An help would be apreciated, thanks. Hojo



All times are GMT +1. The time now is 21:48.


Powered by vBulletin®
Copyright ©2000 - 2026, 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 ©2026 elitepvpers All Rights Reserved.