2021-12-16 19:39:13 +01:00
|
|
|
from minecraft import PRE
|
2018-05-27 14:28:01 +02:00
|
|
|
from minecraft.networking.packets import Packet
|
2017-08-08 15:07:33 +02:00
|
|
|
from minecraft.networking.types import (
|
2018-05-27 16:36:13 +02:00
|
|
|
VarInt, Byte, Boolean, UnsignedByte, VarIntPrefixedByteArray, String,
|
|
|
|
MutableRecord
|
2017-08-08 15:07:33 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
class MapPacket(Packet):
|
|
|
|
@staticmethod
|
|
|
|
def get_id(context):
|
2021-06-12 19:38:15 +02:00
|
|
|
return 0x27 if context.protocol_later_eq(755) else \
|
|
|
|
0x25 if context.protocol_later_eq(741) else \
|
Fix: non-monotonic protocol versions are not correctly handled
After 1.16.3, Mojang started publishing snapshot, pre-release and release
candidate versions of Minecraft with protocol version numbers of the form
`(1 << 30) | n' where 'n' is a small non-negative integer increasing with each
such version; the release versions continued to use the old format. For
example, these are the last 8 published Minecraft versions as of this commit:
release 1.16.3 uses protocol version 753
pre-release 1.16.4-pre1 uses protocol version 1073741825 == (1 << 30) | 1
pre-release 1.16.4-pre2 uses protocol version 1073741826 == (1 << 30) | 2
release candidate 1.16.4-rc1 uses protocol version 1073741827 == (1 << 30) | 3
release 1.16.4 uses protocol version 754
snapshot 20w45a uses protocol version 1073741829 == (1 << 30) | 5
snapshot 20w46a uses protocol version 1073741830 == (1 << 30) | 6
snapshot 20w48a uses protocol version 1073741831 == (1 << 30) | 7
This means that protocol versions no longer increase monotonically with respect
to publication history, a property that was assumed to hold in much of
pyCraft's code relating to support of multiple protocol versions. This commit
rectifies the issue by replacing any comparison of protocol versions by their
numerical value with a comparison based on their publication time.
Newly defined is the dictionary `minecraft.PROTOCOL_VERSION_INDICES', which
maps each known protocol version to its index in the protocol chronology. As
such, the bound method `minecraft.PROTOCOL_VERSION_INDICES.get` can be used as
a key function for the built-in `sorted`, `min` and `max` functions to collate
protocol versions chronologically.
Two utility functions are provided for direct comparison of protocol versions:
`minecraft.utility.protocol_earlier` and
`minecraft.utility.protocol_earlier_eq`.
Additionally, four methods are added to the `ConnectionContext` type to ease
the most common cases where the protocol of a given context must be compared to
a given version number:
`minecraft.connection.ConnectionContext.protocol_earlier`,
`minecraft.connection.ConnectionContext.protocol_earlier_eq`,
`minecraft.connection.ConnectionContext.protocol_later` and
`minecraft.connection.ConnectionContext.protocol_later_eq`.
2020-12-02 14:30:40 +01:00
|
|
|
0x26 if context.protocol_later_eq(721) else \
|
|
|
|
0x27 if context.protocol_later_eq(550) else \
|
|
|
|
0x26 if context.protocol_later_eq(389) else \
|
|
|
|
0x25 if context.protocol_later_eq(345) else \
|
|
|
|
0x24 if context.protocol_later_eq(334) else \
|
|
|
|
0x25 if context.protocol_later_eq(318) else \
|
|
|
|
0x24 if context.protocol_later_eq(107) else \
|
2017-08-08 15:07:33 +02:00
|
|
|
0x34
|
|
|
|
|
|
|
|
packet_name = 'map'
|
|
|
|
|
2019-06-08 15:38:20 +02:00
|
|
|
@property
|
|
|
|
def fields(self):
|
|
|
|
fields = 'id', 'scale', 'icons', 'width', 'height', 'pixels'
|
Fix: non-monotonic protocol versions are not correctly handled
After 1.16.3, Mojang started publishing snapshot, pre-release and release
candidate versions of Minecraft with protocol version numbers of the form
`(1 << 30) | n' where 'n' is a small non-negative integer increasing with each
such version; the release versions continued to use the old format. For
example, these are the last 8 published Minecraft versions as of this commit:
release 1.16.3 uses protocol version 753
pre-release 1.16.4-pre1 uses protocol version 1073741825 == (1 << 30) | 1
pre-release 1.16.4-pre2 uses protocol version 1073741826 == (1 << 30) | 2
release candidate 1.16.4-rc1 uses protocol version 1073741827 == (1 << 30) | 3
release 1.16.4 uses protocol version 754
snapshot 20w45a uses protocol version 1073741829 == (1 << 30) | 5
snapshot 20w46a uses protocol version 1073741830 == (1 << 30) | 6
snapshot 20w48a uses protocol version 1073741831 == (1 << 30) | 7
This means that protocol versions no longer increase monotonically with respect
to publication history, a property that was assumed to hold in much of
pyCraft's code relating to support of multiple protocol versions. This commit
rectifies the issue by replacing any comparison of protocol versions by their
numerical value with a comparison based on their publication time.
Newly defined is the dictionary `minecraft.PROTOCOL_VERSION_INDICES', which
maps each known protocol version to its index in the protocol chronology. As
such, the bound method `minecraft.PROTOCOL_VERSION_INDICES.get` can be used as
a key function for the built-in `sorted`, `min` and `max` functions to collate
protocol versions chronologically.
Two utility functions are provided for direct comparison of protocol versions:
`minecraft.utility.protocol_earlier` and
`minecraft.utility.protocol_earlier_eq`.
Additionally, four methods are added to the `ConnectionContext` type to ease
the most common cases where the protocol of a given context must be compared to
a given version number:
`minecraft.connection.ConnectionContext.protocol_earlier`,
`minecraft.connection.ConnectionContext.protocol_earlier_eq`,
`minecraft.connection.ConnectionContext.protocol_later` and
`minecraft.connection.ConnectionContext.protocol_later_eq`.
2020-12-02 14:30:40 +01:00
|
|
|
if self.context.protocol_later_eq(107):
|
2019-06-08 15:38:20 +02:00
|
|
|
fields += 'is_tracking_position',
|
Fix: non-monotonic protocol versions are not correctly handled
After 1.16.3, Mojang started publishing snapshot, pre-release and release
candidate versions of Minecraft with protocol version numbers of the form
`(1 << 30) | n' where 'n' is a small non-negative integer increasing with each
such version; the release versions continued to use the old format. For
example, these are the last 8 published Minecraft versions as of this commit:
release 1.16.3 uses protocol version 753
pre-release 1.16.4-pre1 uses protocol version 1073741825 == (1 << 30) | 1
pre-release 1.16.4-pre2 uses protocol version 1073741826 == (1 << 30) | 2
release candidate 1.16.4-rc1 uses protocol version 1073741827 == (1 << 30) | 3
release 1.16.4 uses protocol version 754
snapshot 20w45a uses protocol version 1073741829 == (1 << 30) | 5
snapshot 20w46a uses protocol version 1073741830 == (1 << 30) | 6
snapshot 20w48a uses protocol version 1073741831 == (1 << 30) | 7
This means that protocol versions no longer increase monotonically with respect
to publication history, a property that was assumed to hold in much of
pyCraft's code relating to support of multiple protocol versions. This commit
rectifies the issue by replacing any comparison of protocol versions by their
numerical value with a comparison based on their publication time.
Newly defined is the dictionary `minecraft.PROTOCOL_VERSION_INDICES', which
maps each known protocol version to its index in the protocol chronology. As
such, the bound method `minecraft.PROTOCOL_VERSION_INDICES.get` can be used as
a key function for the built-in `sorted`, `min` and `max` functions to collate
protocol versions chronologically.
Two utility functions are provided for direct comparison of protocol versions:
`minecraft.utility.protocol_earlier` and
`minecraft.utility.protocol_earlier_eq`.
Additionally, four methods are added to the `ConnectionContext` type to ease
the most common cases where the protocol of a given context must be compared to
a given version number:
`minecraft.connection.ConnectionContext.protocol_earlier`,
`minecraft.connection.ConnectionContext.protocol_earlier_eq`,
`minecraft.connection.ConnectionContext.protocol_later` and
`minecraft.connection.ConnectionContext.protocol_later_eq`.
2020-12-02 14:30:40 +01:00
|
|
|
if self.context.protocol_later_eq(452):
|
2019-06-08 15:38:20 +02:00
|
|
|
fields += 'is_locked',
|
|
|
|
return fields
|
|
|
|
|
|
|
|
def field_string(self, field):
|
|
|
|
if field == 'pixels' and isinstance(self.pixels, bytearray):
|
|
|
|
return 'bytearray(...)'
|
|
|
|
return super(MapPacket, self).field_string(field)
|
|
|
|
|
2018-05-27 16:36:13 +02:00
|
|
|
class MapIcon(MutableRecord):
|
2018-05-19 19:04:48 +02:00
|
|
|
__slots__ = 'type', 'direction', 'location', 'display_name'
|
2017-08-08 15:07:33 +02:00
|
|
|
|
2018-05-19 19:04:48 +02:00
|
|
|
def __init__(self, type, direction, location, display_name=None):
|
2017-08-08 15:07:33 +02:00
|
|
|
self.type = type
|
|
|
|
self.direction = direction
|
|
|
|
self.location = location
|
2018-05-19 19:04:48 +02:00
|
|
|
self.display_name = display_name
|
2017-08-08 15:07:33 +02:00
|
|
|
|
2018-05-27 16:36:13 +02:00
|
|
|
class Map(MutableRecord):
|
2017-08-08 15:07:33 +02:00
|
|
|
__slots__ = ('id', 'scale', 'icons', 'pixels', 'width', 'height',
|
2019-05-11 08:43:08 +02:00
|
|
|
'is_tracking_position', 'is_locked')
|
2017-08-08 15:07:33 +02:00
|
|
|
|
|
|
|
def __init__(self, id=None, scale=None, width=128, height=128):
|
|
|
|
self.id = id
|
|
|
|
self.scale = scale
|
|
|
|
self.icons = []
|
|
|
|
self.width = width
|
|
|
|
self.height = height
|
|
|
|
self.pixels = bytearray(0 for i in range(width*height))
|
|
|
|
self.is_tracking_position = True
|
2019-05-11 08:43:08 +02:00
|
|
|
self.is_locked = False
|
2017-08-08 15:07:33 +02:00
|
|
|
|
|
|
|
class MapSet(object):
|
|
|
|
__slots__ = 'maps_by_id'
|
|
|
|
|
2019-06-08 15:38:20 +02:00
|
|
|
def __init__(self, *maps):
|
|
|
|
self.maps_by_id = {map.id: map for map in maps}
|
2017-08-08 15:07:33 +02:00
|
|
|
|
|
|
|
def __repr__(self):
|
2019-06-08 15:38:20 +02:00
|
|
|
maps = (repr(map) for map in self.maps_by_id.values())
|
2017-08-08 15:07:33 +02:00
|
|
|
return 'MapSet(%s)' % ', '.join(maps)
|
|
|
|
|
|
|
|
def read(self, file_object):
|
|
|
|
self.map_id = VarInt.read(file_object)
|
|
|
|
self.scale = Byte.read(file_object)
|
|
|
|
|
2021-12-16 19:39:13 +01:00
|
|
|
if self.context.protocol_in_range(107, PRE | 6):
|
2017-08-08 15:07:33 +02:00
|
|
|
self.is_tracking_position = Boolean.read(file_object)
|
2021-12-16 19:39:13 +01:00
|
|
|
elif self.context.protocol_earlier(107):
|
2017-08-08 15:07:33 +02:00
|
|
|
self.is_tracking_position = True
|
|
|
|
|
Fix: non-monotonic protocol versions are not correctly handled
After 1.16.3, Mojang started publishing snapshot, pre-release and release
candidate versions of Minecraft with protocol version numbers of the form
`(1 << 30) | n' where 'n' is a small non-negative integer increasing with each
such version; the release versions continued to use the old format. For
example, these are the last 8 published Minecraft versions as of this commit:
release 1.16.3 uses protocol version 753
pre-release 1.16.4-pre1 uses protocol version 1073741825 == (1 << 30) | 1
pre-release 1.16.4-pre2 uses protocol version 1073741826 == (1 << 30) | 2
release candidate 1.16.4-rc1 uses protocol version 1073741827 == (1 << 30) | 3
release 1.16.4 uses protocol version 754
snapshot 20w45a uses protocol version 1073741829 == (1 << 30) | 5
snapshot 20w46a uses protocol version 1073741830 == (1 << 30) | 6
snapshot 20w48a uses protocol version 1073741831 == (1 << 30) | 7
This means that protocol versions no longer increase monotonically with respect
to publication history, a property that was assumed to hold in much of
pyCraft's code relating to support of multiple protocol versions. This commit
rectifies the issue by replacing any comparison of protocol versions by their
numerical value with a comparison based on their publication time.
Newly defined is the dictionary `minecraft.PROTOCOL_VERSION_INDICES', which
maps each known protocol version to its index in the protocol chronology. As
such, the bound method `minecraft.PROTOCOL_VERSION_INDICES.get` can be used as
a key function for the built-in `sorted`, `min` and `max` functions to collate
protocol versions chronologically.
Two utility functions are provided for direct comparison of protocol versions:
`minecraft.utility.protocol_earlier` and
`minecraft.utility.protocol_earlier_eq`.
Additionally, four methods are added to the `ConnectionContext` type to ease
the most common cases where the protocol of a given context must be compared to
a given version number:
`minecraft.connection.ConnectionContext.protocol_earlier`,
`minecraft.connection.ConnectionContext.protocol_earlier_eq`,
`minecraft.connection.ConnectionContext.protocol_later` and
`minecraft.connection.ConnectionContext.protocol_later_eq`.
2020-12-02 14:30:40 +01:00
|
|
|
if self.context.protocol_later_eq(452):
|
2019-05-11 08:43:08 +02:00
|
|
|
self.is_locked = Boolean.read(file_object)
|
|
|
|
else:
|
|
|
|
self.is_locked = False
|
|
|
|
|
2021-12-16 19:39:13 +01:00
|
|
|
if self.context.protocol_later_eq(PRE | 6):
|
|
|
|
self.is_tracking_position = Boolean.read(file_object)
|
|
|
|
|
2017-08-08 15:07:33 +02:00
|
|
|
icon_count = VarInt.read(file_object)
|
|
|
|
self.icons = []
|
|
|
|
for i in range(icon_count):
|
Fix: non-monotonic protocol versions are not correctly handled
After 1.16.3, Mojang started publishing snapshot, pre-release and release
candidate versions of Minecraft with protocol version numbers of the form
`(1 << 30) | n' where 'n' is a small non-negative integer increasing with each
such version; the release versions continued to use the old format. For
example, these are the last 8 published Minecraft versions as of this commit:
release 1.16.3 uses protocol version 753
pre-release 1.16.4-pre1 uses protocol version 1073741825 == (1 << 30) | 1
pre-release 1.16.4-pre2 uses protocol version 1073741826 == (1 << 30) | 2
release candidate 1.16.4-rc1 uses protocol version 1073741827 == (1 << 30) | 3
release 1.16.4 uses protocol version 754
snapshot 20w45a uses protocol version 1073741829 == (1 << 30) | 5
snapshot 20w46a uses protocol version 1073741830 == (1 << 30) | 6
snapshot 20w48a uses protocol version 1073741831 == (1 << 30) | 7
This means that protocol versions no longer increase monotonically with respect
to publication history, a property that was assumed to hold in much of
pyCraft's code relating to support of multiple protocol versions. This commit
rectifies the issue by replacing any comparison of protocol versions by their
numerical value with a comparison based on their publication time.
Newly defined is the dictionary `minecraft.PROTOCOL_VERSION_INDICES', which
maps each known protocol version to its index in the protocol chronology. As
such, the bound method `minecraft.PROTOCOL_VERSION_INDICES.get` can be used as
a key function for the built-in `sorted`, `min` and `max` functions to collate
protocol versions chronologically.
Two utility functions are provided for direct comparison of protocol versions:
`minecraft.utility.protocol_earlier` and
`minecraft.utility.protocol_earlier_eq`.
Additionally, four methods are added to the `ConnectionContext` type to ease
the most common cases where the protocol of a given context must be compared to
a given version number:
`minecraft.connection.ConnectionContext.protocol_earlier`,
`minecraft.connection.ConnectionContext.protocol_earlier_eq`,
`minecraft.connection.ConnectionContext.protocol_later` and
`minecraft.connection.ConnectionContext.protocol_later_eq`.
2020-12-02 14:30:40 +01:00
|
|
|
if self.context.protocol_later_eq(373):
|
2018-05-19 19:04:48 +02:00
|
|
|
type = VarInt.read(file_object)
|
|
|
|
else:
|
|
|
|
type, direction = divmod(UnsignedByte.read(file_object), 16)
|
2017-08-08 15:07:33 +02:00
|
|
|
x = Byte.read(file_object)
|
|
|
|
z = Byte.read(file_object)
|
Fix: non-monotonic protocol versions are not correctly handled
After 1.16.3, Mojang started publishing snapshot, pre-release and release
candidate versions of Minecraft with protocol version numbers of the form
`(1 << 30) | n' where 'n' is a small non-negative integer increasing with each
such version; the release versions continued to use the old format. For
example, these are the last 8 published Minecraft versions as of this commit:
release 1.16.3 uses protocol version 753
pre-release 1.16.4-pre1 uses protocol version 1073741825 == (1 << 30) | 1
pre-release 1.16.4-pre2 uses protocol version 1073741826 == (1 << 30) | 2
release candidate 1.16.4-rc1 uses protocol version 1073741827 == (1 << 30) | 3
release 1.16.4 uses protocol version 754
snapshot 20w45a uses protocol version 1073741829 == (1 << 30) | 5
snapshot 20w46a uses protocol version 1073741830 == (1 << 30) | 6
snapshot 20w48a uses protocol version 1073741831 == (1 << 30) | 7
This means that protocol versions no longer increase monotonically with respect
to publication history, a property that was assumed to hold in much of
pyCraft's code relating to support of multiple protocol versions. This commit
rectifies the issue by replacing any comparison of protocol versions by their
numerical value with a comparison based on their publication time.
Newly defined is the dictionary `minecraft.PROTOCOL_VERSION_INDICES', which
maps each known protocol version to its index in the protocol chronology. As
such, the bound method `minecraft.PROTOCOL_VERSION_INDICES.get` can be used as
a key function for the built-in `sorted`, `min` and `max` functions to collate
protocol versions chronologically.
Two utility functions are provided for direct comparison of protocol versions:
`minecraft.utility.protocol_earlier` and
`minecraft.utility.protocol_earlier_eq`.
Additionally, four methods are added to the `ConnectionContext` type to ease
the most common cases where the protocol of a given context must be compared to
a given version number:
`minecraft.connection.ConnectionContext.protocol_earlier`,
`minecraft.connection.ConnectionContext.protocol_earlier_eq`,
`minecraft.connection.ConnectionContext.protocol_later` and
`minecraft.connection.ConnectionContext.protocol_later_eq`.
2020-12-02 14:30:40 +01:00
|
|
|
if self.context.protocol_later_eq(373):
|
2018-05-19 19:04:48 +02:00
|
|
|
direction = UnsignedByte.read(file_object)
|
Fix: non-monotonic protocol versions are not correctly handled
After 1.16.3, Mojang started publishing snapshot, pre-release and release
candidate versions of Minecraft with protocol version numbers of the form
`(1 << 30) | n' where 'n' is a small non-negative integer increasing with each
such version; the release versions continued to use the old format. For
example, these are the last 8 published Minecraft versions as of this commit:
release 1.16.3 uses protocol version 753
pre-release 1.16.4-pre1 uses protocol version 1073741825 == (1 << 30) | 1
pre-release 1.16.4-pre2 uses protocol version 1073741826 == (1 << 30) | 2
release candidate 1.16.4-rc1 uses protocol version 1073741827 == (1 << 30) | 3
release 1.16.4 uses protocol version 754
snapshot 20w45a uses protocol version 1073741829 == (1 << 30) | 5
snapshot 20w46a uses protocol version 1073741830 == (1 << 30) | 6
snapshot 20w48a uses protocol version 1073741831 == (1 << 30) | 7
This means that protocol versions no longer increase monotonically with respect
to publication history, a property that was assumed to hold in much of
pyCraft's code relating to support of multiple protocol versions. This commit
rectifies the issue by replacing any comparison of protocol versions by their
numerical value with a comparison based on their publication time.
Newly defined is the dictionary `minecraft.PROTOCOL_VERSION_INDICES', which
maps each known protocol version to its index in the protocol chronology. As
such, the bound method `minecraft.PROTOCOL_VERSION_INDICES.get` can be used as
a key function for the built-in `sorted`, `min` and `max` functions to collate
protocol versions chronologically.
Two utility functions are provided for direct comparison of protocol versions:
`minecraft.utility.protocol_earlier` and
`minecraft.utility.protocol_earlier_eq`.
Additionally, four methods are added to the `ConnectionContext` type to ease
the most common cases where the protocol of a given context must be compared to
a given version number:
`minecraft.connection.ConnectionContext.protocol_earlier`,
`minecraft.connection.ConnectionContext.protocol_earlier_eq`,
`minecraft.connection.ConnectionContext.protocol_later` and
`minecraft.connection.ConnectionContext.protocol_later_eq`.
2020-12-02 14:30:40 +01:00
|
|
|
if self.context.protocol_later_eq(364):
|
2018-05-19 19:04:48 +02:00
|
|
|
has_name = Boolean.read(file_object)
|
|
|
|
display_name = String.read(file_object) if has_name else None
|
|
|
|
else:
|
|
|
|
display_name = None
|
|
|
|
icon = MapPacket.MapIcon(type, direction, (x, z), display_name)
|
2017-08-08 15:07:33 +02:00
|
|
|
self.icons.append(icon)
|
2018-05-19 19:04:48 +02:00
|
|
|
|
2021-12-16 19:39:13 +01:00
|
|
|
self.width = UnsignedByte.read(file_object)
|
2017-08-08 15:07:33 +02:00
|
|
|
if self.width:
|
|
|
|
self.height = UnsignedByte.read(file_object)
|
|
|
|
x = Byte.read(file_object)
|
|
|
|
z = Byte.read(file_object)
|
|
|
|
self.offset = (x, z)
|
|
|
|
self.pixels = VarIntPrefixedByteArray.read(file_object)
|
|
|
|
else:
|
|
|
|
self.height = 0
|
|
|
|
self.offset = None
|
|
|
|
self.pixels = None
|
|
|
|
|
|
|
|
def apply_to_map(self, map):
|
|
|
|
map.id = self.map_id
|
|
|
|
map.scale = self.scale
|
|
|
|
map.icons[:] = self.icons
|
|
|
|
if self.pixels is not None:
|
|
|
|
for i in range(len(self.pixels)):
|
|
|
|
x = self.offset[0] + i % self.width
|
|
|
|
z = self.offset[1] + i // self.width
|
|
|
|
map.pixels[x + map.width * z] = self.pixels[i]
|
|
|
|
map.is_tracking_position = self.is_tracking_position
|
2019-05-11 08:43:08 +02:00
|
|
|
map.is_locked = self.is_locked
|
2017-08-08 15:07:33 +02:00
|
|
|
|
|
|
|
def apply_to_map_set(self, map_set):
|
|
|
|
map = map_set.maps_by_id.get(self.map_id)
|
|
|
|
if map is None:
|
|
|
|
map = MapPacket.Map(self.map_id)
|
|
|
|
map_set.maps_by_id[self.map_id] = map
|
|
|
|
self.apply_to_map(map)
|
|
|
|
|
2018-05-27 14:28:01 +02:00
|
|
|
def write_fields(self, packet_buffer):
|
2017-08-08 15:07:33 +02:00
|
|
|
VarInt.send(self.map_id, packet_buffer)
|
|
|
|
Byte.send(self.scale, packet_buffer)
|
Fix: non-monotonic protocol versions are not correctly handled
After 1.16.3, Mojang started publishing snapshot, pre-release and release
candidate versions of Minecraft with protocol version numbers of the form
`(1 << 30) | n' where 'n' is a small non-negative integer increasing with each
such version; the release versions continued to use the old format. For
example, these are the last 8 published Minecraft versions as of this commit:
release 1.16.3 uses protocol version 753
pre-release 1.16.4-pre1 uses protocol version 1073741825 == (1 << 30) | 1
pre-release 1.16.4-pre2 uses protocol version 1073741826 == (1 << 30) | 2
release candidate 1.16.4-rc1 uses protocol version 1073741827 == (1 << 30) | 3
release 1.16.4 uses protocol version 754
snapshot 20w45a uses protocol version 1073741829 == (1 << 30) | 5
snapshot 20w46a uses protocol version 1073741830 == (1 << 30) | 6
snapshot 20w48a uses protocol version 1073741831 == (1 << 30) | 7
This means that protocol versions no longer increase monotonically with respect
to publication history, a property that was assumed to hold in much of
pyCraft's code relating to support of multiple protocol versions. This commit
rectifies the issue by replacing any comparison of protocol versions by their
numerical value with a comparison based on their publication time.
Newly defined is the dictionary `minecraft.PROTOCOL_VERSION_INDICES', which
maps each known protocol version to its index in the protocol chronology. As
such, the bound method `minecraft.PROTOCOL_VERSION_INDICES.get` can be used as
a key function for the built-in `sorted`, `min` and `max` functions to collate
protocol versions chronologically.
Two utility functions are provided for direct comparison of protocol versions:
`minecraft.utility.protocol_earlier` and
`minecraft.utility.protocol_earlier_eq`.
Additionally, four methods are added to the `ConnectionContext` type to ease
the most common cases where the protocol of a given context must be compared to
a given version number:
`minecraft.connection.ConnectionContext.protocol_earlier`,
`minecraft.connection.ConnectionContext.protocol_earlier_eq`,
`minecraft.connection.ConnectionContext.protocol_later` and
`minecraft.connection.ConnectionContext.protocol_later_eq`.
2020-12-02 14:30:40 +01:00
|
|
|
if self.context.protocol_later_eq(107):
|
2017-08-08 15:07:33 +02:00
|
|
|
Boolean.send(self.is_tracking_position, packet_buffer)
|
|
|
|
|
|
|
|
VarInt.send(len(self.icons), packet_buffer)
|
|
|
|
for icon in self.icons:
|
Fix: non-monotonic protocol versions are not correctly handled
After 1.16.3, Mojang started publishing snapshot, pre-release and release
candidate versions of Minecraft with protocol version numbers of the form
`(1 << 30) | n' where 'n' is a small non-negative integer increasing with each
such version; the release versions continued to use the old format. For
example, these are the last 8 published Minecraft versions as of this commit:
release 1.16.3 uses protocol version 753
pre-release 1.16.4-pre1 uses protocol version 1073741825 == (1 << 30) | 1
pre-release 1.16.4-pre2 uses protocol version 1073741826 == (1 << 30) | 2
release candidate 1.16.4-rc1 uses protocol version 1073741827 == (1 << 30) | 3
release 1.16.4 uses protocol version 754
snapshot 20w45a uses protocol version 1073741829 == (1 << 30) | 5
snapshot 20w46a uses protocol version 1073741830 == (1 << 30) | 6
snapshot 20w48a uses protocol version 1073741831 == (1 << 30) | 7
This means that protocol versions no longer increase monotonically with respect
to publication history, a property that was assumed to hold in much of
pyCraft's code relating to support of multiple protocol versions. This commit
rectifies the issue by replacing any comparison of protocol versions by their
numerical value with a comparison based on their publication time.
Newly defined is the dictionary `minecraft.PROTOCOL_VERSION_INDICES', which
maps each known protocol version to its index in the protocol chronology. As
such, the bound method `minecraft.PROTOCOL_VERSION_INDICES.get` can be used as
a key function for the built-in `sorted`, `min` and `max` functions to collate
protocol versions chronologically.
Two utility functions are provided for direct comparison of protocol versions:
`minecraft.utility.protocol_earlier` and
`minecraft.utility.protocol_earlier_eq`.
Additionally, four methods are added to the `ConnectionContext` type to ease
the most common cases where the protocol of a given context must be compared to
a given version number:
`minecraft.connection.ConnectionContext.protocol_earlier`,
`minecraft.connection.ConnectionContext.protocol_earlier_eq`,
`minecraft.connection.ConnectionContext.protocol_later` and
`minecraft.connection.ConnectionContext.protocol_later_eq`.
2020-12-02 14:30:40 +01:00
|
|
|
if self.context.protocol_later_eq(373):
|
2018-05-27 18:12:50 +02:00
|
|
|
VarInt.send(icon.type, packet_buffer)
|
|
|
|
else:
|
|
|
|
type_and_direction = (icon.type << 4) & 0xF0
|
|
|
|
type_and_direction |= (icon.direction & 0xF)
|
|
|
|
UnsignedByte.send(type_and_direction, packet_buffer)
|
2017-08-08 15:07:33 +02:00
|
|
|
Byte.send(icon.location[0], packet_buffer)
|
|
|
|
Byte.send(icon.location[1], packet_buffer)
|
Fix: non-monotonic protocol versions are not correctly handled
After 1.16.3, Mojang started publishing snapshot, pre-release and release
candidate versions of Minecraft with protocol version numbers of the form
`(1 << 30) | n' where 'n' is a small non-negative integer increasing with each
such version; the release versions continued to use the old format. For
example, these are the last 8 published Minecraft versions as of this commit:
release 1.16.3 uses protocol version 753
pre-release 1.16.4-pre1 uses protocol version 1073741825 == (1 << 30) | 1
pre-release 1.16.4-pre2 uses protocol version 1073741826 == (1 << 30) | 2
release candidate 1.16.4-rc1 uses protocol version 1073741827 == (1 << 30) | 3
release 1.16.4 uses protocol version 754
snapshot 20w45a uses protocol version 1073741829 == (1 << 30) | 5
snapshot 20w46a uses protocol version 1073741830 == (1 << 30) | 6
snapshot 20w48a uses protocol version 1073741831 == (1 << 30) | 7
This means that protocol versions no longer increase monotonically with respect
to publication history, a property that was assumed to hold in much of
pyCraft's code relating to support of multiple protocol versions. This commit
rectifies the issue by replacing any comparison of protocol versions by their
numerical value with a comparison based on their publication time.
Newly defined is the dictionary `minecraft.PROTOCOL_VERSION_INDICES', which
maps each known protocol version to its index in the protocol chronology. As
such, the bound method `minecraft.PROTOCOL_VERSION_INDICES.get` can be used as
a key function for the built-in `sorted`, `min` and `max` functions to collate
protocol versions chronologically.
Two utility functions are provided for direct comparison of protocol versions:
`minecraft.utility.protocol_earlier` and
`minecraft.utility.protocol_earlier_eq`.
Additionally, four methods are added to the `ConnectionContext` type to ease
the most common cases where the protocol of a given context must be compared to
a given version number:
`minecraft.connection.ConnectionContext.protocol_earlier`,
`minecraft.connection.ConnectionContext.protocol_earlier_eq`,
`minecraft.connection.ConnectionContext.protocol_later` and
`minecraft.connection.ConnectionContext.protocol_later_eq`.
2020-12-02 14:30:40 +01:00
|
|
|
if self.context.protocol_later_eq(373):
|
2018-05-27 18:12:50 +02:00
|
|
|
UnsignedByte.send(icon.direction, packet_buffer)
|
Fix: non-monotonic protocol versions are not correctly handled
After 1.16.3, Mojang started publishing snapshot, pre-release and release
candidate versions of Minecraft with protocol version numbers of the form
`(1 << 30) | n' where 'n' is a small non-negative integer increasing with each
such version; the release versions continued to use the old format. For
example, these are the last 8 published Minecraft versions as of this commit:
release 1.16.3 uses protocol version 753
pre-release 1.16.4-pre1 uses protocol version 1073741825 == (1 << 30) | 1
pre-release 1.16.4-pre2 uses protocol version 1073741826 == (1 << 30) | 2
release candidate 1.16.4-rc1 uses protocol version 1073741827 == (1 << 30) | 3
release 1.16.4 uses protocol version 754
snapshot 20w45a uses protocol version 1073741829 == (1 << 30) | 5
snapshot 20w46a uses protocol version 1073741830 == (1 << 30) | 6
snapshot 20w48a uses protocol version 1073741831 == (1 << 30) | 7
This means that protocol versions no longer increase monotonically with respect
to publication history, a property that was assumed to hold in much of
pyCraft's code relating to support of multiple protocol versions. This commit
rectifies the issue by replacing any comparison of protocol versions by their
numerical value with a comparison based on their publication time.
Newly defined is the dictionary `minecraft.PROTOCOL_VERSION_INDICES', which
maps each known protocol version to its index in the protocol chronology. As
such, the bound method `minecraft.PROTOCOL_VERSION_INDICES.get` can be used as
a key function for the built-in `sorted`, `min` and `max` functions to collate
protocol versions chronologically.
Two utility functions are provided for direct comparison of protocol versions:
`minecraft.utility.protocol_earlier` and
`minecraft.utility.protocol_earlier_eq`.
Additionally, four methods are added to the `ConnectionContext` type to ease
the most common cases where the protocol of a given context must be compared to
a given version number:
`minecraft.connection.ConnectionContext.protocol_earlier`,
`minecraft.connection.ConnectionContext.protocol_earlier_eq`,
`minecraft.connection.ConnectionContext.protocol_later` and
`minecraft.connection.ConnectionContext.protocol_later_eq`.
2020-12-02 14:30:40 +01:00
|
|
|
if self.context.protocol_later_eq(364):
|
2018-05-27 18:12:50 +02:00
|
|
|
Boolean.send(icon.display_name is not None, packet_buffer)
|
|
|
|
if icon.display_name is not None:
|
|
|
|
String.send(icon.display_name, packet_buffer)
|
2017-08-08 15:07:33 +02:00
|
|
|
|
|
|
|
UnsignedByte.send(self.width, packet_buffer)
|
|
|
|
if self.width:
|
|
|
|
UnsignedByte.send(self.height, packet_buffer)
|
|
|
|
UnsignedByte.send(self.offset[0], packet_buffer) # x
|
|
|
|
UnsignedByte.send(self.offset[1], packet_buffer) # z
|
|
|
|
VarIntPrefixedByteArray.send(self.pixels, packet_buffer)
|