Merge pull request #153 from MathiewMay/dev
Some checks are pending
Build (Linux, x86_64) / build-linux (push) Waiting to run
Build (Linux, x86_64) / build-linux-debug (push) Waiting to run

Changed entity id from 11-bit to 16-bit for movement and motion packets.
This commit is contained in:
Tropical 2026-03-11 00:31:32 -05:00 committed by GitHub
commit 32bd586c6e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 124 additions and 194 deletions

View file

@ -4,7 +4,7 @@
#include "PacketListener.h"
#include "MoveEntityPacket.h"
MoveEntityPacket::MoveEntityPacket()
MoveEntityPacket::MoveEntityPacket()
{
hasRot = false;
@ -28,7 +28,7 @@ MoveEntityPacket::MoveEntityPacket(int id)
xRot = 0;
}
void MoveEntityPacket::read(DataInputStream *dis) //throws IOException
void MoveEntityPacket::read(DataInputStream *dis) //throws IOException
{
id = dis->readShort();
}
@ -48,7 +48,7 @@ void MoveEntityPacket::handle(PacketListener *listener)
listener->handleMoveEntity(shared_from_this());
}
int MoveEntityPacket::getEstimatedSize()
int MoveEntityPacket::getEstimatedSize()
{
return 2;
}
@ -69,66 +69,66 @@ MoveEntityPacket::PosRot::PosRot()
hasRot = true;
}
MoveEntityPacket::PosRot::PosRot(int id, char xa, char ya, char za, char yRot, char xRot) : MoveEntityPacket( id )
MoveEntityPacket::PosRot::PosRot(int id, int8_t xa, int8_t ya, int8_t za, int8_t yRot, int8_t xRot) : MoveEntityPacket( id )
{
this->xa = xa;
this->ya = ya;
this->za = za;
this->yRot = yRot;
this->xRot = xRot;
this->xa = xa;
this->ya = ya;
this->za = za;
this->yRot = yRot;
this->xRot = xRot;
hasRot = true;
}
void MoveEntityPacket::PosRot::read(DataInputStream *dis) //throws IOException
void MoveEntityPacket::PosRot::read(DataInputStream *dis) //throws IOException
{
MoveEntityPacket::read(dis);
xa = (int)dis->readByte();
ya = (int)dis->readByte();
za = (int)dis->readByte();
yRot = (int)dis->readByte();
xRot = (int)dis->readByte();
xa = (int8_t)dis->readByte();
ya = (int8_t)dis->readByte();
za = (int8_t)dis->readByte();
yRot = (int8_t)dis->readByte();
xRot = (int8_t)dis->readByte();
}
void MoveEntityPacket::PosRot::write(DataOutputStream *dos) //throws IOException
void MoveEntityPacket::PosRot::write(DataOutputStream *dos) //throws IOException
{
MoveEntityPacket::write(dos);
dos->writeByte((uint8_t)xa);
dos->writeByte((uint8_t)ya);
dos->writeByte((uint8_t)za);
dos->writeByte((uint8_t)yRot);
dos->writeByte((uint8_t)xRot);
dos->writeByte((uint8_t)(xa & 0xFF));
dos->writeByte((uint8_t)(ya & 0xFF));
dos->writeByte((uint8_t)(za & 0xFF));
dos->writeByte((uint8_t)(yRot & 0xFF));
dos->writeByte((uint8_t)(xRot & 0xFF));
}
int MoveEntityPacket::PosRot::getEstimatedSize()
int MoveEntityPacket::PosRot::getEstimatedSize()
{
return 2+5;
}
MoveEntityPacket::Pos::Pos()
MoveEntityPacket::Pos::Pos()
{
}
MoveEntityPacket::Pos::Pos(int id, char xa, char ya, char za) : MoveEntityPacket(id)
MoveEntityPacket::Pos::Pos(int id, int8_t xa, int8_t ya, int8_t za) : MoveEntityPacket(id)
{
this->xa = xa;
this->ya = ya;
this->za = za;
}
void MoveEntityPacket::Pos::read(DataInputStream *dis) //throws IOException
void MoveEntityPacket::Pos::read(DataInputStream *dis) //throws IOException
{
MoveEntityPacket::read(dis);
xa = (int)dis->readByte();
ya = (int)dis->readByte();
za = (int)dis->readByte();
xa = (int8_t)dis->readByte();
ya = (int8_t)dis->readByte();
za = (int8_t)dis->readByte();
}
void MoveEntityPacket::Pos::write(DataOutputStream *dos) //throws IOException
{
MoveEntityPacket::write(dos);
dos->writeByte((uint8_t)xa);
dos->writeByte((uint8_t)ya);
dos->writeByte((uint8_t)za);
dos->writeByte((uint8_t)(xa & 0xFF));
dos->writeByte((uint8_t)(ya & 0xFF));
dos->writeByte((uint8_t)(za & 0xFF));
}
int MoveEntityPacket::Pos::getEstimatedSize()
@ -136,30 +136,30 @@ int MoveEntityPacket::Pos::getEstimatedSize()
return 2+3;
}
MoveEntityPacket::Rot::Rot()
MoveEntityPacket::Rot::Rot()
{
hasRot = true;
}
MoveEntityPacket::Rot::Rot(int id, char yRot, char xRot) : MoveEntityPacket(id)
MoveEntityPacket::Rot::Rot(int id, int8_t yRot, int8_t xRot) : MoveEntityPacket(id)
{
this->yRot = yRot;
this->xRot = xRot;
hasRot = true;
}
void MoveEntityPacket::Rot::read(DataInputStream *dis) //throws IOException
void MoveEntityPacket::Rot::read(DataInputStream *dis) //throws IOException
{
MoveEntityPacket::read(dis);
yRot = (int)dis->readByte();
xRot = (int)dis->readByte();
yRot = (int8_t)dis->readByte();
xRot = (int8_t)dis->readByte();
}
void MoveEntityPacket::Rot::write(DataOutputStream *dos) //throws IOException
void MoveEntityPacket::Rot::write(DataOutputStream *dos) //throws IOException
{
MoveEntityPacket::write(dos);
dos->writeByte((uint8_t)yRot);
dos->writeByte((uint8_t)xRot);
dos->writeByte((uint8_t)(yRot & 0xFF));
dos->writeByte((uint8_t)(xRot & 0xFF));
}
int MoveEntityPacket::Rot::getEstimatedSize()

View file

@ -13,7 +13,7 @@ public:
class Rot;
int id;
char xa, ya, za, yRot, xRot;
int8_t xa, ya, za, yRot, xRot;
bool hasRot;
MoveEntityPacket();
@ -35,7 +35,7 @@ class MoveEntityPacket::PosRot : public MoveEntityPacket
{
public:
PosRot();
PosRot(int id, char xa, char ya, char za, char yRot, char xRot);
PosRot(int id, int8_t xa, int8_t ya, int8_t za, int8_t yRot, int8_t xRot);
virtual void read(DataInputStream *dis);
virtual void write(DataOutputStream *dos);
@ -50,7 +50,7 @@ class MoveEntityPacket::Pos : public MoveEntityPacket
{
public:
Pos();
Pos(int id, char xa, char ya, char za);
Pos(int id, int8_t xa, int8_t ya, int8_t za);
virtual void read(DataInputStream *dis);
virtual void write(DataOutputStream *dos);
@ -65,7 +65,7 @@ class MoveEntityPacket::Rot : public MoveEntityPacket
{
public:
Rot();
Rot(int id, char yRot, char xRot);
Rot(int id, int8_t yRot, int8_t xRot);
virtual void read(DataInputStream *dis);
virtual void write(DataOutputStream *dos);

View file

@ -1,5 +1,6 @@
#include "../../Platform/stdafx.h"
#include <iostream>
#include <limits>
#include "../../IO/Streams/InputOutputStream.h"
#include "PacketListener.h"
#include "MoveEntityPacketSmall.h"
@ -19,30 +20,19 @@ MoveEntityPacketSmall::MoveEntityPacketSmall()
MoveEntityPacketSmall::MoveEntityPacketSmall(int id)
{
if( (id < 0 ) || (id >= 2048 ) )
{
// We shouln't be tracking an entity that doesn't have a short type of id
__debugbreak();
}
this->id = id;
hasRot = false;
xa = 0;
ya = 0;
za = 0;
yRot = 0;
xRot = 0;
xa = ya = za = yRot = xRot = 0;
}
void MoveEntityPacketSmall::read(DataInputStream *dis) //throws IOException
void MoveEntityPacketSmall::read(DataInputStream *dis) //throws IOException
{
id = dis->readShort();
}
void MoveEntityPacketSmall::write(DataOutputStream *dos) //throws IOException
{
if( (id < 0 ) || (id >= 2048 ) )
if(id < 0 || id > std::numeric_limits<int16_t>::max() )
{
// We shouln't be tracking an entity that doesn't have a short type of id
__debugbreak();
@ -55,7 +45,7 @@ void MoveEntityPacketSmall::handle(PacketListener *listener)
listener->handleMoveEntitySmall(shared_from_this());
}
int MoveEntityPacketSmall::getEstimatedSize()
int MoveEntityPacketSmall::getEstimatedSize()
{
return 2;
}
@ -76,7 +66,7 @@ MoveEntityPacketSmall::PosRot::PosRot()
hasRot = true;
}
MoveEntityPacketSmall::PosRot::PosRot(int id, char xa, char ya, char za, char yRot, char xRot) : MoveEntityPacketSmall( id )
MoveEntityPacketSmall::PosRot::PosRot(int id, int8_t xa, int8_t ya, int8_t za, int8_t yRot, int8_t xRot) : MoveEntityPacketSmall( id )
{
this->xa = xa;
this->ya = ya;
@ -86,80 +76,69 @@ MoveEntityPacketSmall::PosRot::PosRot(int id, char xa, char ya, char za, char yR
hasRot = true;
}
void MoveEntityPacketSmall::PosRot::read(DataInputStream *dis) //throws IOException
void MoveEntityPacketSmall::PosRot::read(DataInputStream *dis) //throws IOException
{
int idAndRot = dis->readShort();
this->id = idAndRot & 0x07ff;
this->yRot = idAndRot >> 11;
int xAndYAndZ = (int)dis->readShort();
this->xa = xAndYAndZ >> 11;
this->ya = (xAndYAndZ << 21 ) >> 26;
this->za = (xAndYAndZ << 27 ) >> 27;
MoveEntityPacketSmall::read(dis);
xa = (int8_t)dis->readByte();
ya = (int8_t)dis->readByte();
za = (int8_t)dis->readByte();
yRot = (int8_t)dis->readByte();
xRot = (int8_t)dis->readByte();
}
void MoveEntityPacketSmall::PosRot::write(DataOutputStream *dos) //throws IOException
void MoveEntityPacketSmall::PosRot::write(DataOutputStream *dos) //throws IOException
{
if( (id < 0 ) || (id >= 2048 ) )
{
// We shouln't be tracking an entity that doesn't have a short type of id
__debugbreak();
}
short idAndRot = id | yRot << 11;
dos->writeShort(idAndRot);
short xAndYAndZ = ( xa << 11 ) | ( ( ya & 0x3f ) << 5 ) | ( za & 0x1f );
dos->writeShort(xAndYAndZ);
MoveEntityPacketSmall::write(dos);
dos->writeByte((uint8_t)(xa & 0xFF));
dos->writeByte((uint8_t)(ya & 0xFF));
dos->writeByte((uint8_t)(za & 0xFF));
dos->writeByte((uint8_t)(yRot & 0xFF));
dos->writeByte((uint8_t)(xRot & 0xFF));
}
int MoveEntityPacketSmall::PosRot::getEstimatedSize()
int MoveEntityPacketSmall::PosRot::getEstimatedSize()
{
return 4;
return 2+5;
}
MoveEntityPacketSmall::Pos::Pos()
MoveEntityPacketSmall::Pos::Pos()
{
}
MoveEntityPacketSmall::Pos::Pos(int id, char xa, char ya, char za) : MoveEntityPacketSmall(id)
MoveEntityPacketSmall::Pos::Pos(int id, int8_t xa, int8_t ya, int8_t za) : MoveEntityPacketSmall(id)
{
this->xa = xa;
this->ya = ya;
this->za = za;
}
void MoveEntityPacketSmall::Pos::read(DataInputStream *dis) //throws IOException
void MoveEntityPacketSmall::Pos::read(DataInputStream *dis) //throws IOException
{
int idAndY = dis->readShort();
this->id = idAndY & 0x07ff;
this->ya = idAndY >> 11;
int XandZ = (int)((signed char)(dis->readByte()));
xa = XandZ >> 4;
za = ( XandZ << 28 ) >> 28;
MoveEntityPacketSmall::read(dis);
xa = (int8_t)dis->readByte();
ya = (int8_t)dis->readByte();
za = (int8_t)dis->readByte();
}
void MoveEntityPacketSmall::Pos::write(DataOutputStream *dos) //throws IOException
{
if( (id < 0 ) || (id >= 2048 ) )
{
// We shouln't be tracking an entity that doesn't have a short type of id
__debugbreak();
}
short idAndY = id | ya << 11;
dos->writeShort(idAndY);
char XandZ = ( xa << 4 ) | ( za & 0x0f );
dos->writeByte((uint8_t)XandZ);
MoveEntityPacketSmall::write(dos);
dos->writeByte((uint8_t)(xa & 0xFF));
dos->writeByte((uint8_t)(ya & 0xFF));
dos->writeByte((uint8_t)(za & 0xFF));
}
int MoveEntityPacketSmall::Pos::getEstimatedSize()
{
return 3;
return 2+3;
}
MoveEntityPacketSmall::Rot::Rot()
MoveEntityPacketSmall::Rot::Rot()
{
hasRot = true;
}
MoveEntityPacketSmall::Rot::Rot(int id, char yRot, char xRot) : MoveEntityPacketSmall(id)
MoveEntityPacketSmall::Rot::Rot(int id, int8_t yRot, int8_t xRot) : MoveEntityPacketSmall(id)
{
this->yRot = yRot;
@ -167,25 +146,19 @@ MoveEntityPacketSmall::Rot::Rot(int id, char yRot, char xRot) : MoveEntityPacket
hasRot = true;
}
void MoveEntityPacketSmall::Rot::read(DataInputStream *dis) //throws IOException
void MoveEntityPacketSmall::Rot::read(DataInputStream *dis) //throws IOException
{
int idAndRot = (int)dis->readShort();
this->id = idAndRot & 0x07ff;
this->yRot = idAndRot >> 11;
MoveEntityPacketSmall::read(dis);
yRot = (int8_t)dis->readByte();
}
void MoveEntityPacketSmall::Rot::write(DataOutputStream *dos) //throws IOException
void MoveEntityPacketSmall::Rot::write(DataOutputStream *dos) //throws IOException
{
if( (id < 0 ) || (id >= 2048 ) )
{
// We shouln't be tracking an entity that doesn't have a short type of id
__debugbreak();
}
short idAndRot = id | yRot << 11;
dos->writeShort(idAndRot);
MoveEntityPacketSmall::write(dos);
dos->writeByte((uint8_t)(yRot & 0xFF));
}
int MoveEntityPacketSmall::Rot::getEstimatedSize()
{
return 2;
return 2+1;
}

View file

@ -13,8 +13,8 @@ public:
class Rot;
int id;
char xa, ya, za, yRot, xRot;
bool hasRot;
int8_t xa, ya, za, yRot, xRot;
bool hasRot;
MoveEntityPacketSmall();
MoveEntityPacketSmall(int id);
@ -34,8 +34,8 @@ public:
class MoveEntityPacketSmall::PosRot : public MoveEntityPacketSmall
{
public:
PosRot();
PosRot(int id, char xa, char ya, char za, char yRot, char xRot);
PosRot();
PosRot(int id, int8_t xa, int8_t ya, int8_t za, int8_t yRot, int8_t xRot);
virtual void read(DataInputStream *dis);
virtual void write(DataOutputStream *dos);
@ -50,7 +50,7 @@ class MoveEntityPacketSmall::Pos : public MoveEntityPacketSmall
{
public:
Pos();
Pos(int id, char xa, char ya, char za);
Pos(int id, int8_t xa, int8_t ya, int8_t za);
virtual void read(DataInputStream *dis);
virtual void write(DataOutputStream *dos);
@ -66,7 +66,7 @@ class MoveEntityPacketSmall::Rot : public MoveEntityPacketSmall
{
public:
Rot();
Rot(int id, char yRot, char xRot);
Rot(int id, int8_t yRot, int8_t xRot);
virtual void read(DataInputStream *dis);
virtual void write(DataOutputStream *dos);

View file

@ -17,22 +17,14 @@ void SetEntityMotionPacket::_init(int id, double xd, double yd, double zd)
if (xd > m) xd = m;
if (yd > m) yd = m;
if (zd > m) zd = m;
xa = (int) (xd * 8000.0);
ya = (int) (yd * 8000.0);
za = (int) (zd * 8000.0);
// 4J - if we could transmit this as bytes (in 1/16 accuracy) then flag to do so
if( ( xa >= (-128 * 16 ) ) && ( ya >= (-128 * 16 ) ) && ( za >= (-128 * 16 ) ) &&
( xa < (128 * 16 ) ) && ( ya < (128 * 16 ) ) && ( za < (128 * 16 ) ) )
{
useBytes = true;
}
else
{
useBytes = false;
}
xa = (int16_t) (xd * 8000.0);
ya = (int16_t) (yd * 8000.0);
za = (int16_t) (zd * 8000.0);
useBytes = false;
}
SetEntityMotionPacket::SetEntityMotionPacket()
SetEntityMotionPacket::SetEntityMotionPacket()
{
_init(0, 0.0f, 0.0f, 0.0f);
}
@ -44,56 +36,27 @@ SetEntityMotionPacket::SetEntityMotionPacket(std::shared_ptr<Entity> e)
SetEntityMotionPacket::SetEntityMotionPacket(int id, double xd, double yd, double zd)
{
_init(id, xd, yd, zd);
_init(id, xd, yd, zd);
}
void SetEntityMotionPacket::read(DataInputStream *dis) //throws IOException
void SetEntityMotionPacket::read(DataInputStream *dis) //throws IOException
{
short idAndFlag = dis->readShort();
id = idAndFlag & 0x07ff;
if( idAndFlag & 0x0800 )
{
xa = (int)dis->readByte();
ya = (int)dis->readByte();
za = (int)dis->readByte();
xa = ( xa << 24 ) >> 24;
ya = ( ya << 24 ) >> 24;
za = ( za << 24 ) >> 24;
xa *= 16;
ya *= 16;
za *= 16;
useBytes = true;
}
else
{
xa = dis->readShort();
ya = dis->readShort();
za = dis->readShort();
useBytes = false;
}
id = dis->readShort();
xa = dis->readShort();
ya = dis->readShort();
za = dis->readShort();
useBytes = false;
}
void SetEntityMotionPacket::write(DataOutputStream *dos) //throws IOException
{
if( useBytes )
{
// 4jcraft: masking the id to 11 bits before writing to account for entity ids > 4095.
// This fixes a connection drop when loading the tutorial world on linux.
//
// FIXME: find the root cause of this, since there shouldn't be more than 4095 entities.
dos->writeShort((id & 0x07FF) | 0x800);
dos->writeByte(xa/16);
dos->writeByte(ya/16);
dos->writeByte(za/16);
}
else
{
// 4jcraft: same thing as line 80 here
dos->writeShort((id & 0x07FF));
dos->writeShort(xa);
dos->writeShort(ya);
dos->writeShort(za);
}
dos->writeShort(id);
dos->writeShort(xa);
dos->writeShort(ya);
dos->writeShort(za);
}
void SetEntityMotionPacket::handle(PacketListener *listener)
@ -103,7 +66,7 @@ void SetEntityMotionPacket::handle(PacketListener *listener)
int SetEntityMotionPacket::getEstimatedSize()
{
return useBytes ? 5 : 8;
return 8;
}
bool SetEntityMotionPacket::canBeInvalidated()

View file

@ -7,7 +7,7 @@ class SetEntityMotionPacket : public Packet, public std::enable_shared_from_this
{
public:
int id;
int xa, ya, za;
int16_t xa, ya, za;
bool useBytes; // 4J added
private:

View file

@ -17,7 +17,7 @@ TeleportEntityPacket::TeleportEntityPacket()
xRot = 0;
}
TeleportEntityPacket::TeleportEntityPacket(std::shared_ptr<Entity> e)
TeleportEntityPacket::TeleportEntityPacket(std::shared_ptr<Entity> e)
{
id = e->entityId;
x = Mth::floor(e->x * 32);
@ -27,7 +27,7 @@ TeleportEntityPacket::TeleportEntityPacket(std::shared_ptr<Entity> e)
xRot = (uint8_t) (e->xRot * 256 / 360);
}
TeleportEntityPacket::TeleportEntityPacket(int id, int x, int y, int z, uint8_t yRot, uint8_t xRot)
TeleportEntityPacket::TeleportEntityPacket(int id, int32_t x, int32_t y, int32_t z, uint8_t yRot, uint8_t xRot)
{
this->id = id;
this->x = x;
@ -53,28 +53,22 @@ void TeleportEntityPacket::read(DataInputStream *dis) //throws IOException
xRot = (uint8_t) dis->read();
}
void TeleportEntityPacket::write(DataOutputStream *dos) //throws IOException
void TeleportEntityPacket::write(DataOutputStream *dos) //throws IOException
{
dos->writeShort(id);
#ifdef _LARGE_WORLDS
dos->writeShort((short)id);
dos->writeInt(x);
dos->writeInt(y);
dos->writeInt(z);
#else
dos->writeShort(x);
dos->writeShort(y);
dos->writeShort(z);
#endif
dos->write(yRot);
dos->write(xRot);
}
void TeleportEntityPacket::handle(PacketListener *listener)
void TeleportEntityPacket::handle(PacketListener *listener)
{
listener->handleTeleportEntity(shared_from_this());
}
int TeleportEntityPacket::getEstimatedSize()
int TeleportEntityPacket::getEstimatedSize()
{
return 2 + 2 + 2 + 2 + 1 + 1;
}

View file

@ -7,19 +7,19 @@ class TeleportEntityPacket : public Packet, public std::enable_shared_from_this<
{
public:
int id;
int x, y, z;
uint8_t yRot, xRot;
int32_t x, y, z;
uint8_t yRot, xRot;
TeleportEntityPacket();
TeleportEntityPacket(std::shared_ptr<Entity> e);
TeleportEntityPacket(int id, int x, int y, int z, uint8_t yRot, uint8_t xRot);
TeleportEntityPacket(int id, int32_t x, int32_t y, int32_t z, uint8_t yRot, uint8_t xRot);
virtual void read(DataInputStream *dis);
virtual void write(DataOutputStream *dos);
virtual void handle(PacketListener *listener);
virtual int getEstimatedSize();
virtual bool canBeInvalidated();
virtual bool isInvalidatedBy(std::shared_ptr<Packet> packet);
virtual bool isInvalidatedBy(std::shared_ptr<Packet> packet);
public:
static std::shared_ptr<Packet> create() { return std::shared_ptr<Packet>(new TeleportEntityPacket()); }