Implement type 'Angle', packet 'EntityLookPacket' and fix Packet Types

Remarks: I chose to implement an angle between 0-360 degrees as opposed to -180 - 180. linear transformation, the maths was far simpler converting an UnsignedByte into positive values instead of a Byte into negative and positive
This commit is contained in:
Zachy 2019-05-15 13:51:31 +01:00
parent d7b560a9f4
commit 7361f761f5
3 changed files with 42 additions and 8 deletions

View File

@ -5,6 +5,7 @@ from minecraft.networking.packets import (
from minecraft.networking.types import ( from minecraft.networking.types import (
Integer, FixedPointInteger, UnsignedByte, Byte, Boolean, UUID, Short, Integer, FixedPointInteger, UnsignedByte, Byte, Boolean, UUID, Short,
VarInt, Double, Float, String, Enum, Difficulty, Dimension, GameMode, VarInt, Double, Float, String, Enum, Difficulty, Dimension, GameMode,
Angle
) )
from .combat_event_packet import CombatEventPacket from .combat_event_packet import CombatEventPacket
@ -40,6 +41,7 @@ def get_packets(context):
RespawnPacket, RespawnPacket,
PluginMessagePacket, PluginMessagePacket,
PlayerListHeaderAndFooterPacket, PlayerListHeaderAndFooterPacket,
EntityLookPacket
} }
if context.protocol_version <= 47: if context.protocol_version <= 47:
packets |= { packets |= {
@ -178,8 +180,8 @@ class SpawnPlayerPacket(Packet):
else {'y': FixedPointInteger}, else {'y': FixedPointInteger},
{'z': Double} if context.protocol_version >= 100 {'z': Double} if context.protocol_version >= 100
else {'z': FixedPointInteger}, else {'z': FixedPointInteger},
{'yaw': Float}, {'yaw': Angle},
{'pitch': Float}, {'pitch': Angle},
# TODO: read entity metadata # TODO: read entity metadata
{'current_item': Short} if context.protocol_version <= 49 else {} {'current_item': Short} if context.protocol_version <= 49 else {}
]) ])
@ -296,3 +298,22 @@ class PlayerListHeaderAndFooterPacket(Packet):
definition = [ definition = [
{'header': String}, {'header': String},
{'footer': String}] {'footer': String}]
class EntityLookPacket(Packet):
@staticmethod
def get_id(context):
return 0x2A if context.protocol_version >= 389 else \
0x29 if context.protocol_version >= 345 else \
0x28 if context.protocol_version >= 318 else \
0x27 if context.protocol_version >= 94 else \
0x28 if context.protocol_version >= 70 else \
0x16
packet_name = 'entity look'
definition = [
{'entity_id': VarInt},
{'yaw': Angle},
{'pitch': Angle},
{'on_ground': Boolean}
]

View File

@ -2,7 +2,7 @@ from minecraft.networking.packets import Packet
from minecraft.networking.types.utility import descriptor from minecraft.networking.types.utility import descriptor
from minecraft.networking.types import ( from minecraft.networking.types import (
VarInt, UUID, Byte, Double, Integer, UnsignedByte, Short, Enum, Vector, VarInt, UUID, Byte, Double, Integer, Angle, Short, Enum, Vector,
PositionAndLook, attribute_alias, multi_attribute_alias, PositionAndLook, attribute_alias, multi_attribute_alias,
) )
@ -103,7 +103,7 @@ class SpawnObjectPacket(Packet):
for attr in 'x', 'y', 'z': for attr in 'x', 'y', 'z':
setattr(self, attr, xyz_type.read(file_object)) setattr(self, attr, xyz_type.read(file_object))
for attr in 'pitch', 'yaw': for attr in 'pitch', 'yaw':
setattr(self, attr, UnsignedByte.read(file_object)) setattr(self, attr, Angle.read(file_object))
self.data = Integer.read(file_object) self.data = Integer.read(file_object)
if self.context.protocol_version >= 49 or self.data > 0: if self.context.protocol_version >= 49 or self.data > 0:
@ -125,7 +125,7 @@ class SpawnObjectPacket(Packet):
for coord in self.x, self.y, self.z: for coord in self.x, self.y, self.z:
xyz_type.send(coord, packet_buffer) xyz_type.send(coord, packet_buffer)
for coord in self.pitch, self.yaw: for coord in self.pitch, self.yaw:
UnsignedByte.send(coord, packet_buffer) Angle.send(coord, packet_buffer)
Integer.send(self.data, packet_buffer) Integer.send(self.data, packet_buffer)
if self.context.protocol_version >= 49 or self.data > 0: if self.context.protocol_version >= 49 or self.data > 0:

View File

@ -11,9 +11,10 @@ from .utility import Vector
__all__ = ( __all__ = (
'Type', 'Boolean', 'UnsignedByte', 'Byte', 'Short', 'UnsignedShort', 'Type', 'Boolean', 'UnsignedByte', 'Byte', 'Short', 'UnsignedShort',
'Integer', 'FixedPointInteger', 'VarInt', 'Long', 'UnsignedLong', 'Float', 'Integer', 'FixedPointInteger', 'Angle', 'VarInt', 'Long',
'Double', 'ShortPrefixedByteArray', 'VarIntPrefixedByteArray', 'UnsignedLong', 'Float', 'Double', 'ShortPrefixedByteArray',
'TrailingByteArray', 'String', 'UUID', 'Position', 'VarIntPrefixedByteArray', 'TrailingByteArray', 'String', 'UUID',
'Position',
) )
@ -117,6 +118,17 @@ class FixedPointInteger(Type):
Integer.send(int(value * 32), socket) Integer.send(int(value * 32), socket)
class Angle(Type):
@staticmethod
def read(file_object):
# Linearly transform angle in steps of 1/256 into steps of 1/360
return 360 * UnsignedByte.read(file_object) / 255
def send(value, socket):
# Normalize angle between 0 and 255 and convert to int.
UnsignedByte.send(int(255 * (value / 360)), socket)
class VarInt(Type): class VarInt(Type):
@staticmethod @staticmethod
def read(file_object): def read(file_object):
@ -311,3 +323,4 @@ class Position(Type, Vector):
if context.protocol_version >= 443 else if context.protocol_version >= 443 else
(x & 0x3FFFFFF) << 38 | (y & 0xFFF) << 26 | (z & 0x3FFFFFF)) (x & 0x3FFFFFF) << 38 | (y & 0xFFF) << 26 | (z & 0x3FFFFFF))
UnsignedLong.send(value, socket) UnsignedLong.send(value, socket)