Ejemplo n.º 1
0
    def get_definition(context):
        return [
            {'x': Float},
            {'y': Float},
            {'z': Float},
            {'radius': Float},

            {'records': PrefixedArray(VarInt, ExplosionPacket.Record)}
            if context.protocol_later_eq(755) else
            {'records': PrefixedArray(Integer, ExplosionPacket.Record)},

            {'player_motion_x': Float},
            {'player_motion_y': Float},
            {'player_motion_z': Float},
        ]
Ejemplo n.º 2
0
class ExplosionPacket(Packet):
    @staticmethod
    def get_id(context):
        return 0x1B if context.protocol_version >= 741 else \
               0x1C if context.protocol_version >= 721 else \
               0x1D if context.protocol_version >= 550 else \
               0x1C if context.protocol_version >= 471 else \
               0x1E if context.protocol_version >= 389 else \
               0x1D if context.protocol_version >= 345 else \
               0x1C if context.protocol_version >= 332 else \
               0x1D if context.protocol_version >= 318 else \
               0x1C if context.protocol_version >= 80 else \
               0x1B if context.protocol_version >= 67 else \
               0x27

    packet_name = 'explosion'

    class Record(Vector, Type):
        __slots__ = ()

        @classmethod
        def read(cls, file_object):
            return cls(*(Byte.read(file_object) for i in range(3)))

        @classmethod
        def send(cls, record, socket):
            for coord in record:
                Byte.send(coord, socket)

    definition = [{
        'x': Float
    }, {
        'y': Float
    }, {
        'z': Float
    }, {
        'radius': Float
    }, {
        'records': PrefixedArray(Integer, Record)
    }, {
        'player_motion_x': Float
    }, {
        'player_motion_y': Float
    }, {
        'player_motion_z': Float
    }]

    # Access the 'x', 'y', 'z' fields as a Vector tuple.
    position = multi_attribute_alias(Vector, 'x', 'y', 'z')

    # Access the 'player_motion_{x,y,z}' fields as a Vector tuple.
    player_motion = multi_attribute_alias(Vector, 'player_motion_x',
                                          'player_motion_y', 'player_motion_z')
class JoinGamePacket(AbstractDimensionPacket):
    @staticmethod
    def get_id(context):
        return (
            0x24
            if context.protocol_later_eq(741)
            else 0x25
            if context.protocol_later_eq(721)
            else 0x26
            if context.protocol_later_eq(550)
            else 0x25
            if context.protocol_later_eq(389)
            else 0x24
            if context.protocol_later_eq(345)
            else 0x23
            if context.protocol_later_eq(332)
            else 0x24
            if context.protocol_later_eq(318)
            else 0x23
            if context.protocol_later_eq(107)
            else 0x01
        )

    packet_name = "join game"
    get_definition = staticmethod(
        lambda context: [
            {"entity_id": Integer},
            {"is_hardcore": Boolean} if context.protocol_later_eq(738) else {},
            {"game_mode": UnsignedByte},
            {"previous_game_mode": UnsignedByte}
            if context.protocol_later_eq(730)
            else {},
            {"world_names": PrefixedArray(VarInt, String)}
            if context.protocol_later_eq(722)
            else {},
            {"dimension_codec": NBT} if context.protocol_later_eq(718) else {},
            {
                "dimension": NBT
                if context.protocol_later_eq(748)
                else String
                if context.protocol_later_eq(718)
                else Integer
                if context.protocol_later_eq(108)
                else Byte
            },
            {"world_name": String} if context.protocol_later_eq(722) else {},
            {"hashed_seed": Long} if context.protocol_later_eq(552) else {},
            {"difficulty": UnsignedByte} if context.protocol_earlier(464) else {},
            {"max_players": VarInt if context.protocol_later_eq(749) else UnsignedByte},
            {"level_type": String} if context.protocol_earlier(716) else {},
            {"render_distance": VarInt} if context.protocol_later_eq(468) else {},
            {"reduced_debug_info": Boolean},
            {"respawn_screen": Boolean} if context.protocol_later_eq(571) else {},
            {"is_debug": Boolean} if context.protocol_later_eq(716) else {},
            {"is_flat": Boolean} if context.protocol_later_eq(716) else {},
        ]
    )

    # These aliases declare the Enum type corresponding to each field:
    Difficulty = Difficulty
    GameMode = GameMode

    # Accesses the 'game_mode' field appropriately depending on the protocol.
    # Can be set or deleted when 'context' is undefined.
    @property
    def game_mode(self):
        if self.context.protocol_later_eq(738):
            return self._game_mode_738
        else:
            return self._game_mode_0

    @game_mode.setter
    def game_mode(self, value):
        self._game_mode_738 = value
        self._game_mode_0 = value

    @game_mode.deleter
    def game_mode(self):
        del self._game_mode_738
        del self._game_mode_0

    # Accesses the 'is_hardcore' field, or its equivalent in older protocols.
    # Can be set or deleted when 'context' is undefined.
    @property
    def is_hardcore(self):
        if self.context.protocol_later_eq(738):
            return self._is_hardcore
        else:
            return bool(self._game_mode_0 & GameMode.HARDCORE)

    @is_hardcore.setter
    def is_hardcore(self, value):
        self._is_hardcore = value
        self._game_mode_0 = (
            getattr(self, "_game_mode_0", 0) | GameMode.HARDCORE
            if value
            else getattr(self, "_game_mode_0", 0) & ~GameMode.HARDCORE
        )

    @is_hardcore.deleter
    def is_hardcore(self):
        if hasattr(self, "_is_hardcore"):
            del self._is_hardcore
        if hasattr(self, "_game_mode_0"):
            self._game_mode_0 &= ~GameMode.HARDCORE

    # Accesses the component of the 'game_mode' field without any hardcore bit,
    # version-independently. Can be set or deleted when 'context' is undefined.
    @property
    def pure_game_mode(self):
        if self.context.protocol_later_eq(738):
            return self._game_mode_738
        else:
            return self._game_mode_0 & ~GameMode.HARDCORE

    @pure_game_mode.setter
    def pure_game_mode(self, value):
        self._game_mode_738 = value
        self._game_mode_0 = (
            value & ~GameMode.HARDCORE
            | getattr(self, "_game_mode_0", 0) & GameMode.HARDCORE
        )

    def field_string(self, field):
        if field == "dimension_codec":
            # pylint: disable=no-member
            return nbt_to_snbt(self.dimension_codec)
        return super(JoinGamePacket, self).field_string(field)
Ejemplo n.º 4
0
class MultiBlockChangePacket(Packet):
    @staticmethod
    def get_id(context):
        return (0x3B if context.protocol_version >= 741 else
                0x0F if context.protocol_version >= 721 else
                0x10 if context.protocol_version >= 550 else
                0x0F if context.protocol_version >= 343 else 0x10 if context.
                protocol_version >= 332 else 0x11 if context.protocol_version
                >= 318 else 0x10 if context.protocol_version >= 67 else 0x22)

    packet_name = "multi block change"

    # Only used in protocol 741 and later.
    class ChunkSectionPos(Vector, Type):
        @classmethod
        def read(cls, file_object):
            value = Long.read(file_object)
            x = value >> 42
            z = (value >> 20) & 0x3FFFFF
            y = value & 0xFFFFF
            return cls(x, y, z)

        @classmethod
        def send(cls, pos, socket):
            x, y, z = pos
            value = (x & 0x3FFFFF) << 42 | (z & 0x3FFFFF) << 20 | y & 0xFFFFF
            Long.send(value, socket)

    class Record(MutableRecord, Type):
        __slots__ = "x", "y", "z", "block_state_id"

        def __init__(self, **kwds):
            self.block_state_id = 0
            super(MultiBlockChangePacket.Record, self).__init__(**kwds)

        # Access the 'x', 'y', 'z' fields as a Vector of ints.
        position = multi_attribute_alias(Vector, "x", "y", "z")

        # For protocols < 347: an accessor for (block_state_id >> 4).
        @property
        def blockId(self):
            return self.block_state_id >> 4

        @blockId.setter
        def blockId(self, block_id):
            self.block_state_id = self.block_state_id & 0xF | block_id << 4

        # For protocols < 347: an accessor for (block_state_id & 0xF).
        @property
        def blockMeta(self):
            return self.block_state_id & 0xF

        @blockMeta.setter
        def blockMeta(self, meta):
            self.block_state_id = self.block_state_id & ~0xF | meta & 0xF

        # This alias is retained for backward compatibility.
        blockStateId = attribute_alias("block_state_id")

        @classmethod
        def read_with_context(cls, file_object, context):
            record = cls()
            if context.protocol_version >= 741:
                value = VarLong.read(file_object)
                record.block_state_id = value >> 12
                record.x = (value >> 8) & 0xF
                record.z = (value >> 4) & 0xF
                record.y = value & 0xF
            else:
                h_position = UnsignedByte.read(file_object)
                record.x = h_position >> 4
                record.z = h_position & 0xF
                record.y = UnsignedByte.read(file_object)
                record.block_state_id = VarInt.read(file_object)
            return record

        @classmethod
        def send_with_context(self, record, socket, context):
            if context.protocol_version >= 741:
                value = (record.block_state_id << 12
                         | (record.x & 0xF) << 8
                         | (record.z & 0xF) << 4
                         | record.y & 0xF)
                VarLong.send(value, socket)
            else:
                UnsignedByte.send(record.x << 4 | record.z & 0xF, socket)
                UnsignedByte.send(record.y, socket)
                VarInt.send(record.block_state_id, socket)

    get_definition = staticmethod(lambda context: [
        {
            "chunk_section_pos": MultiBlockChangePacket.ChunkSectionPos
        },
        {
            "invert_trust_edges": Boolean
        }
        if context.protocol_version >= 748 else {},  # Provisional field name.
        {
            "records": PrefixedArray(VarInt, MultiBlockChangePacket.Record)
        },
    ] if context.protocol_version >= 741 else [
        {
            "chunk_x": Integer
        },
        {
            "chunk_z": Integer
        },
        {
            "records": PrefixedArray(VarInt, MultiBlockChangePacket.Record)
        },
    ])

    # Access the 'chunk_x' and 'chunk_z' fields as a tuple.
    # Only used prior to protocol 741.
    chunk_pos = multi_attribute_alias(tuple, "chunk_x", "chunk_z")
Ejemplo n.º 5
0
class MultiBlockChangePacket(Packet):
    @staticmethod
    def get_id(context):
        return 0x3F if context.protocol_later_eq(755) else \
               0x3B if context.protocol_later_eq(741) else \
               0x0F if context.protocol_later_eq(721) else \
               0x10 if context.protocol_later_eq(550) else \
               0x0F if context.protocol_later_eq(343) else \
               0x10 if context.protocol_later_eq(332) else \
               0x11 if context.protocol_later_eq(318) else \
               0x10 if context.protocol_later_eq(67) else \
               0x22

    packet_name = 'multi block change'

    # Only used in protocol 741 and later.
    class ChunkSectionPos(Vector, Type):
        @classmethod
        def read(cls, file_object):
            value = UnsignedLong.read(file_object)
            y = value | ~0xFFFFF if value & 0x80000 else value & 0xFFFFF
            value >>= 20
            z = value | ~0x3FFFFF if value & 0x200000 else value & 0x3FFFFF
            value >>= 22
            x = value | ~0x3FFFFF if value & 0x200000 else value
            return cls(x, y, z)

        @classmethod
        def send(cls, pos, socket):
            x, y, z = pos
            value = (x & 0x3FFFFF) << 42 | (z & 0x3FFFFF) << 20 | y & 0xFFFFF
            UnsignedLong.send(value, socket)

    class Record(MutableRecord, Type):
        __slots__ = 'x', 'y', 'z', 'block_state_id'

        def __init__(self, **kwds):
            self.block_state_id = 0
            super(MultiBlockChangePacket.Record, self).__init__(**kwds)

        # Access the 'x', 'y', 'z' fields as a Vector of ints.
        position = multi_attribute_alias(Vector, 'x', 'y', 'z')

        # For protocols before 347: an accessor for (block_state_id >> 4).
        @property
        def blockId(self):
            return self.block_state_id >> 4

        @blockId.setter
        def blockId(self, block_id):
            self.block_state_id = self.block_state_id & 0xF | block_id << 4

        # For protocols before 347: an accessor for (block_state_id & 0xF).
        @property
        def blockMeta(self):
            return self.block_state_id & 0xF

        @blockMeta.setter
        def blockMeta(self, meta):
            self.block_state_id = self.block_state_id & ~0xF | meta & 0xF

        # This alias is retained for backward compatibility.
        blockStateId = attribute_alias('block_state_id')

        @classmethod
        def read_with_context(cls, file_object, context):
            record = cls()
            if context.protocol_later_eq(741):
                value = VarLong.read(file_object)
                record.block_state_id = value >> 12
                record.x = (value >> 8) & 0xF
                record.z = (value >> 4) & 0xF
                record.y = value & 0xF
            else:
                h_position = UnsignedByte.read(file_object)
                record.x = h_position >> 4
                record.z = h_position & 0xF
                record.y = UnsignedByte.read(file_object)
                record.block_state_id = VarInt.read(file_object)
            return record

        @classmethod
        def send_with_context(self, record, socket, context):
            if context.protocol_later_eq(741):
                value = record.block_state_id << 12 | \
                        (record.x & 0xF) << 8 | \
                        (record.z & 0xF) << 4 | \
                        record.y & 0xF
                VarLong.send(value, socket)
            else:
                UnsignedByte.send(record.x << 4 | record.z & 0xF, socket)
                UnsignedByte.send(record.y, socket)
                VarInt.send(record.block_state_id, socket)

    get_definition = staticmethod(lambda context: [
        {
            'chunk_section_pos': MultiBlockChangePacket.ChunkSectionPos
        },
        {
            'invert_trust_edges': Boolean
        } if context.protocol_later_eq(748) else {},  # Provisional field name.
        {
            'records': PrefixedArray(VarInt, MultiBlockChangePacket.Record)
        },
    ] if context.protocol_later_eq(741) else [
        {
            'chunk_x': Integer
        },
        {
            'chunk_z': Integer
        },
        {
            'records': PrefixedArray(VarInt, MultiBlockChangePacket.Record)
        },
    ])

    # Access the 'chunk_x' and 'chunk_z' fields as a tuple.
    # Only used prior to protocol 741.
    chunk_pos = multi_attribute_alias(tuple, 'chunk_x', 'chunk_z')
Ejemplo n.º 6
0
class ExplosionPacket(Packet):
    @staticmethod
    def get_id(context):
        return (
            0x1B if context.protocol_later_eq(741) else
            0x1C if context.protocol_later_eq(721) else
            0x1D if context.protocol_later_eq(550) else 0x1C if context.
            protocol_later_eq(471) else 0x1E if context.protocol_later_eq(389)
            else 0x1D if context.protocol_later_eq(345) else 0x1C if context.
            protocol_later_eq(332) else 0x1D if context.
            protocol_later_eq(318) else 0x1C if context.
            protocol_later_eq(80) else 0x1B if context.
            protocol_later_eq(67) else 0x27)

    packet_name = "explosion"

    class Record(Vector, Type):
        __slots__ = ()

        @classmethod
        def read(cls, file_object):
            return cls(*(Byte.read(file_object) for i in range(3)))

        @classmethod
        def send(cls, record, socket):
            for coord in record:
                Byte.send(coord, socket)

    definition = [
        {
            "x": Float
        },
        {
            "y": Float
        },
        {
            "z": Float
        },
        {
            "radius": Float
        },
        {
            "records": PrefixedArray(Integer, Record)
        },
        {
            "player_motion_x": Float
        },
        {
            "player_motion_y": Float
        },
        {
            "player_motion_z": Float
        },
    ]

    # Access the 'x', 'y', 'z' fields as a Vector tuple.
    position = multi_attribute_alias(Vector, "x", "y", "z")

    # Access the 'player_motion_{x,y,z}' fields as a Vector tuple.
    player_motion = multi_attribute_alias(Vector, "player_motion_x",
                                          "player_motion_y", "player_motion_z")
class JoinGamePacket(AbstractDimensionPacket):
    @staticmethod
    def get_id(context):
        return 0x24 if context.protocol_version >= 741 else \
               0x25 if context.protocol_version >= 721 else \
               0x26 if context.protocol_version >= 550 else \
               0x25 if context.protocol_version >= 389 else \
               0x24 if context.protocol_version >= 345 else \
               0x23 if context.protocol_version >= 332 else \
               0x24 if context.protocol_version >= 318 else \
               0x23 if context.protocol_version >= 107 else \
               0x01

    packet_name = "join game"
    get_definition = staticmethod(lambda context: [
        {
            'entity_id': Integer
        },
        {
            'is_hardcore': Boolean
        } if context.protocol_version >= 738 else {},
        {
            'game_mode': UnsignedByte
        },
        {
            'previous_game_mode': UnsignedByte
        } if context.protocol_version >= 730 else {},
        {
            'world_names': PrefixedArray(VarInt, String)
        } if context.protocol_version >= 722 else {},
        {
            'dimension_codec': NBT
        } if context.protocol_version >= 718 else {},
        {
            'dimension':
            NBT if context.protocol_version >= 748 else String
            if context.protocol_version >= 718 else Integer
            if context.protocol_version >= 108 else Byte
        },
        {
            'world_name': String
        } if context.protocol_version >= 722 else {},
        {
            'hashed_seed': Long
        } if context.protocol_version >= 552 else {},
        {
            'difficulty': UnsignedByte
        } if context.protocol_version < 464 else {},
        {
            'max_players':
            VarInt if context.protocol_version >= 749 else UnsignedByte
        },
        {
            'level_type': String
        } if context.protocol_version < 716 else {},
        {
            'render_distance': VarInt
        } if context.protocol_version >= 468 else {},
        {
            'reduced_debug_info': Boolean
        },
        {
            'respawn_screen': Boolean
        } if context.protocol_version >= 571 else {},
        {
            'is_debug': Boolean
        } if context.protocol_version >= 716 else {},
        {
            'is_flat': Boolean
        } if context.protocol_version >= 716 else {},
    ])

    # These aliases declare the Enum type corresponding to each field:
    Difficulty = Difficulty
    GameMode = GameMode

    # Accesses the 'game_mode' field appropriately depending on the protocol.
    # Can be set or deleted when 'context' is undefined.
    @property
    def game_mode(self):
        if self.context.protocol_version >= 738:
            return self._game_mode_738
        else:
            return self._game_mode_0

    @game_mode.setter
    def game_mode(self, value):
        self._game_mode_738 = value
        self._game_mode_0 = value

    @game_mode.deleter
    def game_mode(self):
        del self._game_mode_738
        del self._game_mode_0

    # Accesses the 'is_hardcore' field, or its equivalent in older protocols.
    # Can be set or deleted when 'context' is undefined.
    @property
    def is_hardcore(self):
        if self.context.protocol_version >= 738:
            return self._is_hardcore
        else:
            return bool(self._game_mode_0 & GameMode.HARDCORE)

    @is_hardcore.setter
    def is_hardcore(self, value):
        self._is_hardcore = value
        self._game_mode_0 = \
            getattr(self, '_game_mode_0', 0) | GameMode.HARDCORE \
            if value else \
            getattr(self, '_game_mode_0', 0) & ~GameMode.HARDCORE

    @is_hardcore.deleter
    def is_hardcore(self):
        if hasattr(self, '_is_hardcore'):
            del self._is_hardcore
        if hasattr(self, '_game_mode_0'):
            self._game_mode_0 &= ~GameMode.HARDCORE

    # Accesses the component of the 'game_mode' field without any hardcore bit,
    # version-independently. Can be set or deleted when 'context' is undefined.
    @property
    def pure_game_mode(self):
        if self.context.protocol_version >= 738:
            return self._game_mode_738
        else:
            return self._game_mode_0 & ~GameMode.HARDCORE

    @pure_game_mode.setter
    def pure_game_mode(self, value):
        self._game_mode_738 = value
        self._game_mode_0 = \
            value & ~GameMode.HARDCORE | \
            getattr(self, '_game_mode_0', 0) & GameMode.HARDCORE

    def field_string(self, field):
        if field == 'dimension_codec':
            # pylint: disable=no-member
            return nbt_to_snbt(self.dimension_codec)
        return super(JoinGamePacket, self).field_string(field)