|
You last visited: Today at 21:47
Advertisement
Movement Packets?
Discussion on Movement Packets? within the Perfect World forum part of the MMORPGs category.
03/05/2012, 19:49
|
#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
|
|
|
03/05/2012, 21:00
|
#2
|
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
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
|
|
|
|
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
|
|
|
03/07/2012, 09:49
|
#4
|
elite*gold: 0
Join Date: Mar 2010
Posts: 862
Received Thanks: 576
|
Quote:
Originally Posted by boredsauce
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.
|
|
|
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.
|
|
|
04/26/2012, 13:34
|
#6
|
elite*gold: 0
Join Date: Mar 2010
Posts: 862
Received Thanks: 576
|
Quote:
Originally Posted by boredsauce
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
|
|
|
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.
|
|
|
04/26/2012, 17:40
|
#8
|
elite*gold: 0
Join Date: Jul 2011
Posts: 57
Received Thanks: 8
|
Quote:
Originally Posted by Interest07
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
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
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
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.
Code:
IntPtr base_address = (IntPtr)0xA521C0;
IntPtr pointer = readint(readint(readint(base_address) + 0x1C) + 0x34);
short counter = readshort(pointer + 0x96C);
float[] currentOrigin = new float[3];
currentOrigin[0] = readfloat(pointer + 0x3C);
currentOrigin[1] = readfloat(pointer + 0x40);
currentOrigin[2] = readfloat(pointer + 0x44);
PacketSender ps = new PacketSender(PWI_procHandle);
ps.movePacketStop(currentOrigin[0]+2048,currentOrigin[1],currentOrigin[2], 500, 5.0f, 45, (byte)MTYPES.MTYPE_RUN, counter); moveCounterIncrement(counter);
Here is my "stop packet" code:
Code:
/*
* Stop Moving
*/
private int movePktStopAddress;
private byte[] movePktStopAddressRev;
private byte[] movePktStop = new byte[]
{
0x07, 0x00, // PID
0x00, 0x00, 0x00, 0x00, // origin[0]
0x00, 0x00, 0x00, 0x00, // origin[1]
0x00, 0x00, 0x00, 0x00, // origin[2]
0x00, 0x00, // speed
0x00, // direction
0x00, // move type
0x00, 0x00, // counter
0x00, 0x00 // interval
};
public void movePacketStop(float x, float y, float z, short interval, float speedMS, byte dir, byte moveType, short moveCounter)
{
int packetSize = movePktStop.Length;
if (movePktStopAddress == 0)
{
loadPacket(movePktStop, ref movePktStopAddress, ref movePktStopAddressRev);
}
int offs = 2;
//////////////////////////////////////////////////////////////////////
///////////////////// ORIGIN /////////////////////
//////////////////////////////////////////////////////////////////////
byte[] xRev = BitConverter.GetBytes(x); xRev.Reverse();
MemFunctions.MemWriteBytes(pr_processHandle, movePktStopAddress + offs, xRev);
offs += sizeof(float);
byte[] yRev = BitConverter.GetBytes(y); yRev.Reverse();
MemFunctions.MemWriteBytes(pr_processHandle, movePktStopAddress + offs, yRev);
offs += sizeof(float);
byte[] zRev = BitConverter.GetBytes(z); zRev.Reverse();
MemFunctions.MemWriteBytes(pr_processHandle, movePktStopAddress + offs, zRev);
offs += sizeof(float);
//////////////////////////////////////////////////////////////////////
///////////////////// SPEED /////////////////////
//////////////////////////////////////////////////////////////////////
short shortSpeed = (short)(speedMS * 256 + 0.5);
byte[] xSpeed = BitConverter.GetBytes(shortSpeed);
xSpeed.Reverse();
MemFunctions.MemWriteBytes(pr_processHandle, movePktStopAddress + offs, xSpeed);
offs += sizeof(short);
//////////////////////////////////////////////////////////////////////
///////////////////// DIR /////////////////////
//////////////////////////////////////////////////////////////////////
MemFunctions.MemWriteByte(pr_processHandle, movePktStopAddress + offs, dir);
offs += sizeof(byte);
//////////////////////////////////////////////////////////////////////
///////////////////// MTYPE /////////////////////
//////////////////////////////////////////////////////////////////////
MemFunctions.MemWriteByte(pr_processHandle, movePktStopAddress + offs, moveType);
offs += sizeof(byte);
//////////////////////////////////////////////////////////////////////
///////////////////// SEQUENCE /////////////////////
//////////////////////////////////////////////////////////////////////
byte[] xSeq = BitConverter.GetBytes(moveCounter);
xSeq.Reverse();
MemFunctions.MemWriteBytes(pr_processHandle, movePktStopAddress + offs, xSeq);
offs += sizeof(short);
//////////////////////////////////////////////////////////////////////
///////////////////// INTERVAL /////////////////////
//////////////////////////////////////////////////////////////////////
byte[] xInterval = BitConverter.GetBytes(interval);
xInterval.Reverse();
MemFunctions.MemWriteBytes(pr_processHandle, movePktStopAddress + offs, xInterval);
offs += sizeof(short);
// send it
sendPacket(movePktStopAddressRev, movePktStop.Length);
}
|
|
|
04/26/2012, 18:20
|
#9
|
elite*gold: 0
Join Date: Mar 2009
Posts: 112
Received Thanks: 123
|
Quote:
Originally Posted by boredsauce
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.
|
|
|
04/26/2012, 19:35
|
#10
|
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;
}
}
}
|
|
|
04/27/2012, 01:53
|
#11
|
elite*gold: 0
Join Date: Jul 2011
Posts: 57
Received Thanks: 8
|
Quote:
Originally Posted by Interest07
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.
|
|
|
04/27/2012, 07:57
|
#12
|
elite*gold: 0
Join Date: Mar 2010
Posts: 862
Received Thanks: 576
|
Quote:
Originally Posted by boredsauce
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.
|
|
|
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.
|
|