mirror of
https://github.com/ammaraskar/pyCraft.git
synced 2024-11-22 02:08:56 +01:00
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`.
This commit is contained in:
parent
4052136d30
commit
969419da3f
@ -3,312 +3,531 @@ A modern, Python3-compatible, well-documented library for communicating
|
|||||||
with a MineCraft server.
|
with a MineCraft server.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from collections import OrderedDict, namedtuple
|
||||||
|
import re
|
||||||
|
|
||||||
# The version number of the most recent pyCraft release.
|
# The version number of the most recent pyCraft release.
|
||||||
__version__ = "0.7.0"
|
__version__ = "0.7.0"
|
||||||
|
|
||||||
# A dict mapping the ID string of each Minecraft version supported by pyCraft
|
# This bit occurs in the protocol numbers of pre-release versions after 1.16.3.
|
||||||
# to the corresponding protocol version number. The ID string of a version is
|
PRE = 1 << 30
|
||||||
# the key used to identify it in
|
|
||||||
|
# A record representing a Minecraft version in the following list.
|
||||||
|
Version = namedtuple('Version', ('id', 'protocol', 'supported'))
|
||||||
|
|
||||||
|
# A list of Minecraft versions known to pyCraft, including all supported
|
||||||
|
# versions as well as some unsupported versions (used by certain forward-
|
||||||
|
# compatible code: e.g. when comparing the current protocol version with that
|
||||||
|
# of an unsupported version), in chronological order of publication.
|
||||||
|
#
|
||||||
|
# The ID string of a version is the key used to identify it in
|
||||||
# <https://launchermeta.mojang.com/mc/game/version_manifest.json>, or the 'id'
|
# <https://launchermeta.mojang.com/mc/game/version_manifest.json>, or the 'id'
|
||||||
# key in "version.json" in the corresponding ".jar" file distributed by Mojang.
|
# key in "version.json" in the corresponding ".jar" file distributed by Mojang.
|
||||||
SUPPORTED_MINECRAFT_VERSIONS = {
|
KNOWN_MINECRAFT_VERSION_RECORDS = [
|
||||||
'1.8': 47,
|
# id protocol supported
|
||||||
'1.8.1': 47,
|
Version('13w41a', 0, False),
|
||||||
'1.8.2': 47,
|
Version('13w41b', 0, False),
|
||||||
'1.8.3': 47,
|
Version('13w42a', 1, False),
|
||||||
'1.8.4': 47,
|
Version('13w42b', 1, False),
|
||||||
'1.8.5': 47,
|
Version('13w43a', 2, False),
|
||||||
'1.8.6': 47,
|
Version('1.7-pre', 3, False),
|
||||||
'1.8.7': 47,
|
Version('1.7.1-pre', 3, False),
|
||||||
'1.8.8': 47,
|
Version('1.7.2', 4, True),
|
||||||
'1.8.9': 47,
|
Version('13w47a', 4, False),
|
||||||
'1.9': 107,
|
Version('13w47b', 4, False),
|
||||||
'1.9.1': 108,
|
Version('13w47c', 4, False),
|
||||||
'1.9.2': 109,
|
Version('13w47d', 4, False),
|
||||||
'1.9.3': 110,
|
Version('13w47e', 4, False),
|
||||||
'1.9.4': 110,
|
Version('13w48a', 4, False),
|
||||||
'1.10': 210,
|
Version('13w48b', 4, False),
|
||||||
'1.10.1': 210,
|
Version('13w49a', 4, False),
|
||||||
'1.10.2': 210,
|
Version('1.7.3-pre', 4, False),
|
||||||
'16w32a': 301,
|
Version('1.7.4', 4, True),
|
||||||
'16w32b': 302,
|
Version('1.7.5', 4, True),
|
||||||
'16w33a': 303,
|
Version('1.7.6-pre1', 5, False),
|
||||||
'16w35a': 304,
|
Version('1.7.6-pre2', 5, False),
|
||||||
'16w36a': 305,
|
Version('1.7.6', 5, True),
|
||||||
'16w38a': 306,
|
Version('1.7.7', 5, True),
|
||||||
'16w39a': 307,
|
Version('1.7.8', 5, True),
|
||||||
'16w39b': 308,
|
Version('1.7.9', 5, True),
|
||||||
'16w39c': 309,
|
Version('1.7.10-pre1', 5, False),
|
||||||
'16w40a': 310,
|
Version('1.7.10-pre2', 5, False),
|
||||||
'16w41a': 311,
|
Version('1.7.10-pre3', 5, False),
|
||||||
'16w42a': 312,
|
Version('1.7.10-pre4', 5, False),
|
||||||
'16w43a': 313,
|
Version('1.7.10', 5, True),
|
||||||
'16w44a': 313,
|
Version('14w02a', 5, False),
|
||||||
'1.11-pre1': 314,
|
Version('14w02b', 5, False),
|
||||||
'1.11': 315,
|
Version('14w02c', 5, False),
|
||||||
'16w50a': 316,
|
Version('14w03a', 6, False),
|
||||||
'1.11.1': 316,
|
Version('14w03b', 6, False),
|
||||||
'1.11.2': 316,
|
Version('14w04a', 7, False),
|
||||||
'17w06a': 317,
|
Version('14w04b', 8, False),
|
||||||
'17w13a': 318,
|
Version('14w05a', 9, False),
|
||||||
'17w13b': 319,
|
Version('14w05b', 9, False),
|
||||||
'17w14a': 320,
|
Version('14w06a', 10, False),
|
||||||
'17w15a': 321,
|
Version('14w06b', 10, False),
|
||||||
'17w16a': 322,
|
Version('14w07a', 11, False),
|
||||||
'17w16b': 323,
|
Version('14w08a', 12, False),
|
||||||
'17w17a': 324,
|
Version('14w10a', 13, False),
|
||||||
'17w17b': 325,
|
Version('14w10b', 13, False),
|
||||||
'17w18a': 326,
|
Version('14w10c', 13, False),
|
||||||
'17w18b': 327,
|
Version('14w11a', 14, False),
|
||||||
'1.12-pre1': 328,
|
Version('14w11b', 14, False),
|
||||||
'1.12-pre2': 329,
|
Version('14w17a', 15, False),
|
||||||
'1.12-pre3': 330,
|
Version('14w18a', 16, False),
|
||||||
'1.12-pre4': 331,
|
Version('14w18b', 16, False),
|
||||||
'1.12-pre5': 332,
|
Version('14w19a', 17, False),
|
||||||
'1.12-pre6': 333,
|
Version('14w20a', 18, False),
|
||||||
'1.12-pre7': 334,
|
Version('14w20b', 18, False),
|
||||||
'1.12': 335,
|
Version('14w21a', 19, False),
|
||||||
'17w31a': 336,
|
Version('14w21b', 20, False),
|
||||||
'1.12.1-pre1': 337,
|
Version('14w25a', 21, False),
|
||||||
'1.12.1': 338,
|
Version('14w25b', 22, False),
|
||||||
'1.12.2-pre1': 339,
|
Version('14w26a', 23, False),
|
||||||
'1.12.2-pre2': 339,
|
Version('14w26b', 24, False),
|
||||||
'1.12.2': 340,
|
Version('14w26c', 25, False),
|
||||||
'17w43a': 341,
|
Version('14w27a', 26, False),
|
||||||
'17w43b': 342,
|
Version('14w27b', 26, False),
|
||||||
'17w45a': 343,
|
Version('14w28a', 27, False),
|
||||||
'17w45b': 344,
|
Version('14w28b', 28, False),
|
||||||
'17w46a': 345,
|
Version('14w29a', 29, False),
|
||||||
'17w47a': 346,
|
Version('14w29a', 29, False),
|
||||||
'17w47b': 347,
|
Version('14w30a', 30, False),
|
||||||
'17w48a': 348,
|
Version('14w30b', 30, False),
|
||||||
'17w49a': 349,
|
Version('14w30c', 31, False),
|
||||||
'17w49b': 350,
|
Version('14w31a', 32, False),
|
||||||
'17w50a': 351,
|
Version('14w32a', 33, False),
|
||||||
'18w01a': 352,
|
Version('14w32b', 34, False),
|
||||||
'18w02a': 353,
|
Version('14w32c', 35, False),
|
||||||
'18w03a': 354,
|
Version('14w32d', 36, False),
|
||||||
'18w03b': 355,
|
Version('14w33a', 37, False),
|
||||||
'18w05a': 356,
|
Version('14w33b', 38, False),
|
||||||
'18w06a': 357,
|
Version('14w33c', 39, False),
|
||||||
'18w07a': 358,
|
Version('14w34a', 40, False),
|
||||||
'18w07b': 359,
|
Version('14w34b', 41, False),
|
||||||
'18w07c': 360,
|
Version('14w34c', 42, False),
|
||||||
'18w08a': 361,
|
Version('14w34d', 43, False),
|
||||||
'18w08b': 362,
|
Version('1.8-pre1', 44, False),
|
||||||
'18w09a': 363,
|
Version('1.8-pre2', 45, False),
|
||||||
'18w10a': 364,
|
Version('1.8-pre3', 46, False),
|
||||||
'18w10b': 365,
|
Version('1.8', 47, True),
|
||||||
'18w10c': 366,
|
Version('1.8.1-pre1', 47, False),
|
||||||
'18w10d': 367,
|
Version('1.8.1-pre2', 47, False),
|
||||||
'18w11a': 368,
|
Version('1.8.1-pre3', 47, False),
|
||||||
'18w14a': 369,
|
Version('1.8.1-pre4', 47, False),
|
||||||
'18w14b': 370,
|
Version('1.8.1-pre5', 47, False),
|
||||||
'18w15a': 371,
|
Version('1.8.1', 47, True),
|
||||||
'18w16a': 372,
|
Version('1.8.2-pre1', 47, False),
|
||||||
'18w19a': 373,
|
Version('1.8.2-pre2', 47, False),
|
||||||
'18w19b': 374,
|
Version('1.8.2-pre3', 47, False),
|
||||||
'18w20a': 375,
|
Version('1.8.2-pre4', 47, False),
|
||||||
'18w20b': 376,
|
Version('1.8.2-pre5', 47, False),
|
||||||
'18w20c': 377,
|
Version('1.8.2-pre6', 47, False),
|
||||||
'18w21a': 378,
|
Version('1.8.2-pre7', 47, False),
|
||||||
'18w21b': 379,
|
Version('1.8.2', 47, True),
|
||||||
'18w22a': 380,
|
Version('1.8.3', 47, True),
|
||||||
'18w22b': 381,
|
Version('1.8.4', 47, True),
|
||||||
'18w22c': 382,
|
Version('1.8.5', 47, True),
|
||||||
'1.13-pre1': 383,
|
Version('1.8.6', 47, True),
|
||||||
'1.13-pre2': 384,
|
Version('1.8.7', 47, True),
|
||||||
'1.13-pre3': 385,
|
Version('1.8.8', 47, True),
|
||||||
'1.13-pre4': 386,
|
Version('1.8.9', 47, True),
|
||||||
'1.13-pre5': 387,
|
Version('15w14a', 48, False),
|
||||||
'1.13-pre6': 388,
|
Version('15w31a', 49, False),
|
||||||
'1.13-pre7': 389,
|
Version('15w31b', 50, False),
|
||||||
'1.13-pre8': 390,
|
Version('15w31c', 51, False),
|
||||||
'1.13-pre9': 391,
|
Version('15w32a', 52, False),
|
||||||
'1.13-pre10': 392,
|
Version('15w32b', 53, False),
|
||||||
'1.13': 393,
|
Version('15w32c', 54, False),
|
||||||
'18w30a': 394,
|
Version('15w33a', 55, False),
|
||||||
'18w30b': 395,
|
Version('15w33b', 56, False),
|
||||||
'18w31a': 396,
|
Version('15w33c', 57, False),
|
||||||
'18w32a': 397,
|
Version('15w34a', 58, False),
|
||||||
'18w33a': 398,
|
Version('15w34b', 59, False),
|
||||||
'1.13.1-pre1': 399,
|
Version('15w34c', 60, False),
|
||||||
'1.13.1-pre2': 400,
|
Version('15w34d', 61, False),
|
||||||
'1.13.1': 401,
|
Version('15w35a', 62, False),
|
||||||
'1.13.2-pre1': 402,
|
Version('15w35b', 63, False),
|
||||||
'1.13.2-pre2': 403,
|
Version('15w35c', 64, False),
|
||||||
'1.13.2': 404,
|
Version('15w35d', 65, False),
|
||||||
'18w43a': 441,
|
Version('15w35e', 66, False),
|
||||||
'18w43b': 441,
|
Version('15w36a', 67, False),
|
||||||
'18w43c': 442,
|
Version('15w36b', 68, False),
|
||||||
'18w44a': 443,
|
Version('15w36c', 69, False),
|
||||||
'18w45a': 444,
|
Version('15w36d', 70, False),
|
||||||
'18w46a': 445,
|
Version('15w37a', 71, False),
|
||||||
'18w47a': 446,
|
Version('15w38a', 72, False),
|
||||||
'18w47b': 447,
|
Version('15w38b', 73, False),
|
||||||
'18w48a': 448,
|
Version('15w39a', 74, False),
|
||||||
'18w48b': 449,
|
Version('15w39b', 74, False),
|
||||||
'18w49a': 450,
|
Version('15w39c', 74, False),
|
||||||
'18w50a': 451,
|
Version('15w40a', 75, False),
|
||||||
'19w02a': 452,
|
Version('15w40b', 76, False),
|
||||||
'19w03a': 453,
|
Version('15w41a', 77, False),
|
||||||
'19w03b': 454,
|
Version('15w41b', 78, False),
|
||||||
'19w03c': 455,
|
Version('15w42a', 79, False),
|
||||||
'19w04a': 456,
|
Version('15w43a', 80, False),
|
||||||
'19w04b': 457,
|
Version('15w43b', 81, False),
|
||||||
'19w05a': 458,
|
Version('15w43c', 82, False),
|
||||||
'19w06a': 459,
|
Version('15w44a', 83, False),
|
||||||
'19w07a': 460,
|
Version('15w44b', 84, False),
|
||||||
'19w08a': 461,
|
Version('15w45a', 85, False),
|
||||||
'19w08b': 462,
|
Version('15w46a', 86, False),
|
||||||
'19w09a': 463,
|
Version('15w47a', 87, False),
|
||||||
'19w11a': 464,
|
Version('15w47b', 88, False),
|
||||||
'19w11b': 465,
|
Version('15w47c', 89, False),
|
||||||
'19w12a': 466,
|
Version('15w49a', 90, False),
|
||||||
'19w12b': 467,
|
Version('15w49b', 91, False),
|
||||||
'19w13a': 468,
|
Version('15w50a', 92, False),
|
||||||
'19w13b': 469,
|
Version('15w51a', 93, False),
|
||||||
'19w14a': 470,
|
Version('15w51b', 94, False),
|
||||||
'19w14b': 471,
|
Version('16w02a', 95, False),
|
||||||
'1.14 Pre-Release 1': 472,
|
Version('16w03a', 96, False),
|
||||||
'1.14 Pre-Release 2': 473,
|
Version('16w04a', 97, False),
|
||||||
'1.14 Pre-Release 3': 474,
|
Version('16w05a', 98, False),
|
||||||
'1.14 Pre-Release 4': 475,
|
Version('16w05b', 99, False),
|
||||||
'1.14 Pre-Release 5': 476,
|
Version('16w06a', 100, False),
|
||||||
'1.14': 477,
|
Version('16w07a', 101, False),
|
||||||
'1.14.1 Pre-Release 1': 478,
|
Version('16w07b', 102, False),
|
||||||
'1.14.1 Pre-Release 2': 479,
|
Version('1.9-pre1', 103, False),
|
||||||
'1.14.1': 480,
|
Version('1.9-pre2', 104, False),
|
||||||
'1.14.2 Pre-Release 1': 481,
|
Version('1.9-pre3', 105, False),
|
||||||
'1.14.2 Pre-Release 2': 482,
|
Version('1.9-pre4', 106, False),
|
||||||
'1.14.2 Pre-Release 3': 483,
|
Version('1.9', 107, True),
|
||||||
'1.14.2 Pre-Release 4': 484,
|
Version('1.9.1-pre1', 107, False),
|
||||||
'1.14.2': 485,
|
Version('1.9.1-pre2', 108, False),
|
||||||
'1.14.3-pre1': 486,
|
Version('1.9.1-pre3', 108, False),
|
||||||
'1.14.3-pre2': 487,
|
Version('1.9.1', 108, True),
|
||||||
'1.14.3-pre3': 488,
|
Version('1.RV-Pre1', 108, False),
|
||||||
'1.14.3-pre4': 489,
|
Version('1.9.2', 109, True),
|
||||||
'1.14.3': 490,
|
Version('16w14a', 109, False),
|
||||||
'1.14.4-pre1': 491,
|
Version('16w15a', 109, False),
|
||||||
'1.14.4-pre2': 492,
|
Version('16w15b', 109, False),
|
||||||
'1.14.4-pre3': 493,
|
Version('1.9.3-pre1', 109, False),
|
||||||
'1.14.4-pre4': 494,
|
Version('1.9.3-pre2', 110, False),
|
||||||
'1.14.4-pre5': 495,
|
Version('1.9.3-pre3', 110, False),
|
||||||
'1.14.4-pre6': 496,
|
Version('1.9.3', 110, True),
|
||||||
'1.14.4-pre7': 497,
|
Version('1.9.4', 110, True),
|
||||||
'1.14.4': 498,
|
Version('16w20a', 201, False),
|
||||||
'19w34a': 550,
|
Version('16w21a', 202, False),
|
||||||
'19w35a': 551,
|
Version('16w21b', 203, False),
|
||||||
'19w36a': 552,
|
Version('1.10-pre1', 204, False),
|
||||||
'19w37a': 553,
|
Version('1.10-pre2', 205, False),
|
||||||
'19w38a': 554,
|
Version('1.10', 210, True),
|
||||||
'19w38b': 555,
|
Version('1.10.1', 210, True),
|
||||||
'19w39a': 556,
|
Version('1.10.2', 210, True),
|
||||||
'19w40a': 557,
|
Version('16w32a', 301, True),
|
||||||
'19w41a': 558,
|
Version('16w32b', 302, True),
|
||||||
'19w42a': 559,
|
Version('16w33a', 303, True),
|
||||||
'19w44a': 560,
|
Version('16w35a', 304, True),
|
||||||
'19w45a': 561,
|
Version('16w36a', 305, True),
|
||||||
'19w45b': 562,
|
Version('16w38a', 306, True),
|
||||||
'19w46a': 563,
|
Version('16w39a', 307, True),
|
||||||
'19w46b': 564,
|
Version('16w39b', 308, True),
|
||||||
'1.15-pre1': 565,
|
Version('16w39c', 309, True),
|
||||||
'1.15-pre2': 566,
|
Version('16w40a', 310, True),
|
||||||
'1.15-pre3': 567,
|
Version('16w41a', 311, True),
|
||||||
'1.15-pre4': 569,
|
Version('16w42a', 312, True),
|
||||||
'1.15-pre5': 570,
|
Version('16w43a', 313, True),
|
||||||
'1.15-pre6': 571,
|
Version('16w44a', 313, True),
|
||||||
'1.15-pre7': 572,
|
Version('1.11-pre1', 314, True),
|
||||||
'1.15': 573,
|
Version('1.11', 315, True),
|
||||||
'1.15.1-pre1': 574,
|
Version('16w50a', 316, True),
|
||||||
'1.15.1': 575,
|
Version('1.11.1', 316, True),
|
||||||
'1.15.2-pre1': 576,
|
Version('1.11.2', 316, True),
|
||||||
'1.15.2-pre2': 577,
|
Version('17w06a', 317, True),
|
||||||
'1.15.2': 578,
|
Version('17w13a', 318, True),
|
||||||
'20w06a': 701,
|
Version('17w13b', 319, True),
|
||||||
'20w07a': 702,
|
Version('17w14a', 320, True),
|
||||||
'20w08a': 703,
|
Version('17w15a', 321, True),
|
||||||
'20w09a': 704,
|
Version('17w16a', 322, True),
|
||||||
'20w10a': 705,
|
Version('17w16b', 323, True),
|
||||||
'20w11a': 706,
|
Version('17w17a', 324, True),
|
||||||
'20w12a': 707,
|
Version('17w17b', 325, True),
|
||||||
'20w13a': 708,
|
Version('17w18a', 326, True),
|
||||||
'20w13b': 709,
|
Version('17w18b', 327, True),
|
||||||
'20w14a': 710,
|
Version('1.12-pre1', 328, True),
|
||||||
'20w15a': 711,
|
Version('1.12-pre2', 329, True),
|
||||||
'20w16a': 712,
|
Version('1.12-pre3', 330, True),
|
||||||
'20w17a': 713,
|
Version('1.12-pre4', 331, True),
|
||||||
'20w18a': 714,
|
Version('1.12-pre5', 332, True),
|
||||||
'20w19a': 715,
|
Version('1.12-pre6', 333, True),
|
||||||
'20w20a': 716,
|
Version('1.12-pre7', 334, True),
|
||||||
'20w20b': 717,
|
Version('1.12', 335, True),
|
||||||
'20w21a': 718,
|
Version('17w31a', 336, True),
|
||||||
'20w22a': 719,
|
Version('1.12.1-pre1', 337, True),
|
||||||
'1.16-pre1': 721,
|
Version('1.12.1', 338, True),
|
||||||
'1.16-pre2': 722,
|
Version('1.12.2-pre1', 339, True),
|
||||||
'1.16-pre3': 725,
|
Version('1.12.2-pre2', 339, True),
|
||||||
'1.16-pre4': 727,
|
Version('1.12.2', 340, True),
|
||||||
'1.16-pre5': 729,
|
Version('17w43a', 341, True),
|
||||||
'1.16-pre6': 730,
|
Version('17w43b', 342, True),
|
||||||
'1.16-pre7': 732,
|
Version('17w45a', 343, True),
|
||||||
'1.16-pre8': 733,
|
Version('17w45b', 344, True),
|
||||||
'1.16-rc1': 734,
|
Version('17w46a', 345, True),
|
||||||
'1.16': 735,
|
Version('17w47a', 346, True),
|
||||||
'1.16.1': 736,
|
Version('17w47b', 347, True),
|
||||||
'20w27a': 738,
|
Version('17w48a', 348, True),
|
||||||
'20w28a': 740,
|
Version('17w49a', 349, True),
|
||||||
'20w29a': 741,
|
Version('17w49b', 350, True),
|
||||||
'20w30a': 743,
|
Version('17w50a', 351, True),
|
||||||
'1.16.2-pre1': 744,
|
Version('18w01a', 352, True),
|
||||||
'1.16.2-pre2': 746,
|
Version('18w02a', 353, True),
|
||||||
'1.16.2-pre3': 748,
|
Version('18w03a', 354, True),
|
||||||
'1.16.2-rc1': 749,
|
Version('18w03b', 355, True),
|
||||||
'1.16.2-rc2': 750,
|
Version('18w05a', 356, True),
|
||||||
'1.16.2': 751,
|
Version('18w06a', 357, True),
|
||||||
'1.16.3-rc1': 752,
|
Version('18w07a', 358, True),
|
||||||
'1.16.3': 753,
|
Version('18w07b', 359, True),
|
||||||
'1.16.4-pre1': 1073741825,
|
Version('18w07c', 360, True),
|
||||||
'1.16.4-pre2': 1073741826,
|
Version('18w08a', 361, True),
|
||||||
'1.16.4-rc1': 1073741827,
|
Version('18w08b', 362, True),
|
||||||
'1.16.4': 754,
|
Version('18w09a', 363, True),
|
||||||
}
|
Version('18w10a', 364, True),
|
||||||
|
Version('18w10b', 365, True),
|
||||||
|
Version('18w10c', 366, True),
|
||||||
|
Version('18w10d', 367, True),
|
||||||
|
Version('18w11a', 368, True),
|
||||||
|
Version('18w14a', 369, True),
|
||||||
|
Version('18w14b', 370, True),
|
||||||
|
Version('18w15a', 371, True),
|
||||||
|
Version('18w16a', 372, True),
|
||||||
|
Version('18w19a', 373, True),
|
||||||
|
Version('18w19b', 374, True),
|
||||||
|
Version('18w20a', 375, True),
|
||||||
|
Version('18w20b', 376, True),
|
||||||
|
Version('18w20c', 377, True),
|
||||||
|
Version('18w21a', 378, True),
|
||||||
|
Version('18w21b', 379, True),
|
||||||
|
Version('18w22a', 380, True),
|
||||||
|
Version('18w22b', 381, True),
|
||||||
|
Version('18w22c', 382, True),
|
||||||
|
Version('1.13-pre1', 383, True),
|
||||||
|
Version('1.13-pre2', 384, True),
|
||||||
|
Version('1.13-pre3', 385, True),
|
||||||
|
Version('1.13-pre4', 386, True),
|
||||||
|
Version('1.13-pre5', 387, True),
|
||||||
|
Version('1.13-pre6', 388, True),
|
||||||
|
Version('1.13-pre7', 389, True),
|
||||||
|
Version('1.13-pre8', 390, True),
|
||||||
|
Version('1.13-pre9', 391, True),
|
||||||
|
Version('1.13-pre10', 392, True),
|
||||||
|
Version('1.13', 393, True),
|
||||||
|
Version('18w30a', 394, True),
|
||||||
|
Version('18w30b', 395, True),
|
||||||
|
Version('18w31a', 396, True),
|
||||||
|
Version('18w32a', 397, True),
|
||||||
|
Version('18w33a', 398, True),
|
||||||
|
Version('1.13.1-pre1', 399, True),
|
||||||
|
Version('1.13.1-pre2', 400, True),
|
||||||
|
Version('1.13.1', 401, True),
|
||||||
|
Version('1.13.2-pre1', 402, True),
|
||||||
|
Version('1.13.2-pre2', 403, True),
|
||||||
|
Version('1.13.2', 404, True),
|
||||||
|
Version('18w43a', 441, True),
|
||||||
|
Version('18w43b', 441, True),
|
||||||
|
Version('18w43c', 442, True),
|
||||||
|
Version('18w44a', 443, True),
|
||||||
|
Version('18w45a', 444, True),
|
||||||
|
Version('18w46a', 445, True),
|
||||||
|
Version('18w47a', 446, True),
|
||||||
|
Version('18w47b', 447, True),
|
||||||
|
Version('18w48a', 448, True),
|
||||||
|
Version('18w48b', 449, True),
|
||||||
|
Version('18w49a', 450, True),
|
||||||
|
Version('18w50a', 451, True),
|
||||||
|
Version('19w02a', 452, True),
|
||||||
|
Version('19w03a', 453, True),
|
||||||
|
Version('19w03b', 454, True),
|
||||||
|
Version('19w03c', 455, True),
|
||||||
|
Version('19w04a', 456, True),
|
||||||
|
Version('19w04b', 457, True),
|
||||||
|
Version('19w05a', 458, True),
|
||||||
|
Version('19w06a', 459, True),
|
||||||
|
Version('19w07a', 460, True),
|
||||||
|
Version('19w08a', 461, True),
|
||||||
|
Version('19w08b', 462, True),
|
||||||
|
Version('19w09a', 463, True),
|
||||||
|
Version('19w11a', 464, True),
|
||||||
|
Version('19w11b', 465, True),
|
||||||
|
Version('19w12a', 466, True),
|
||||||
|
Version('19w12b', 467, True),
|
||||||
|
Version('19w13a', 468, True),
|
||||||
|
Version('19w13b', 469, True),
|
||||||
|
Version('19w14a', 470, True),
|
||||||
|
Version('19w14b', 471, True),
|
||||||
|
Version('1.14 Pre-Release 1', 472, True),
|
||||||
|
Version('1.14 Pre-Release 2', 473, True),
|
||||||
|
Version('1.14 Pre-Release 3', 474, True),
|
||||||
|
Version('1.14 Pre-Release 4', 475, True),
|
||||||
|
Version('1.14 Pre-Release 5', 476, True),
|
||||||
|
Version('1.14', 477, True),
|
||||||
|
Version('1.14.1 Pre-Release 1', 478, True),
|
||||||
|
Version('1.14.1 Pre-Release 2', 479, True),
|
||||||
|
Version('1.14.1', 480, True),
|
||||||
|
Version('1.14.2 Pre-Release 1', 481, True),
|
||||||
|
Version('1.14.2 Pre-Release 2', 482, True),
|
||||||
|
Version('1.14.2 Pre-Release 3', 483, True),
|
||||||
|
Version('1.14.2 Pre-Release 4', 484, True),
|
||||||
|
Version('1.14.2', 485, True),
|
||||||
|
Version('1.14.3-pre1', 486, True),
|
||||||
|
Version('1.14.3-pre2', 487, True),
|
||||||
|
Version('1.14.3-pre3', 488, True),
|
||||||
|
Version('1.14.3-pre4', 489, True),
|
||||||
|
Version('1.14.3', 490, True),
|
||||||
|
Version('1.14.4-pre1', 491, True),
|
||||||
|
Version('1.14.4-pre2', 492, True),
|
||||||
|
Version('1.14.4-pre3', 493, True),
|
||||||
|
Version('1.14.4-pre4', 494, True),
|
||||||
|
Version('1.14.4-pre5', 495, True),
|
||||||
|
Version('1.14.4-pre6', 496, True),
|
||||||
|
Version('1.14.4-pre7', 497, True),
|
||||||
|
Version('1.14.4', 498, True),
|
||||||
|
Version('19w34a', 550, True),
|
||||||
|
Version('19w35a', 551, True),
|
||||||
|
Version('19w36a', 552, True),
|
||||||
|
Version('19w37a', 553, True),
|
||||||
|
Version('19w38a', 554, True),
|
||||||
|
Version('19w38b', 555, True),
|
||||||
|
Version('19w39a', 556, True),
|
||||||
|
Version('19w40a', 557, True),
|
||||||
|
Version('19w41a', 558, True),
|
||||||
|
Version('19w42a', 559, True),
|
||||||
|
Version('19w44a', 560, True),
|
||||||
|
Version('19w45a', 561, True),
|
||||||
|
Version('19w45b', 562, True),
|
||||||
|
Version('19w46a', 563, True),
|
||||||
|
Version('19w46b', 564, True),
|
||||||
|
Version('1.15-pre1', 565, True),
|
||||||
|
Version('1.15-pre2', 566, True),
|
||||||
|
Version('1.15-pre3', 567, True),
|
||||||
|
Version('1.15-pre4', 569, True),
|
||||||
|
Version('1.15-pre5', 570, True),
|
||||||
|
Version('1.15-pre6', 571, True),
|
||||||
|
Version('1.15-pre7', 572, True),
|
||||||
|
Version('1.15', 573, True),
|
||||||
|
Version('1.15.1-pre1', 574, True),
|
||||||
|
Version('1.15.1', 575, True),
|
||||||
|
Version('1.15.2-pre1', 576, True),
|
||||||
|
Version('1.15.2-pre2', 577, True),
|
||||||
|
Version('1.15.2', 578, True),
|
||||||
|
Version('20w06a', 701, True),
|
||||||
|
Version('20w07a', 702, True),
|
||||||
|
Version('20w08a', 703, True),
|
||||||
|
Version('20w09a', 704, True),
|
||||||
|
Version('20w10a', 705, True),
|
||||||
|
Version('20w11a', 706, True),
|
||||||
|
Version('20w12a', 707, True),
|
||||||
|
Version('20w13a', 708, True),
|
||||||
|
Version('20w13b', 709, True),
|
||||||
|
Version('20w14a', 710, True),
|
||||||
|
Version('20w15a', 711, True),
|
||||||
|
Version('20w16a', 712, True),
|
||||||
|
Version('20w17a', 713, True),
|
||||||
|
Version('20w18a', 714, True),
|
||||||
|
Version('20w19a', 715, True),
|
||||||
|
Version('20w20a', 716, True),
|
||||||
|
Version('20w20b', 717, True),
|
||||||
|
Version('20w21a', 718, True),
|
||||||
|
Version('20w22a', 719, True),
|
||||||
|
Version('1.16-pre1', 721, True),
|
||||||
|
Version('1.16-pre2', 722, True),
|
||||||
|
Version('1.16-pre3', 725, True),
|
||||||
|
Version('1.16-pre4', 727, True),
|
||||||
|
Version('1.16-pre5', 729, True),
|
||||||
|
Version('1.16-pre6', 730, True),
|
||||||
|
Version('1.16-pre7', 732, True),
|
||||||
|
Version('1.16-pre8', 733, True),
|
||||||
|
Version('1.16-rc1', 734, True),
|
||||||
|
Version('1.16', 735, True),
|
||||||
|
Version('1.16.1', 736, True),
|
||||||
|
Version('20w27a', 738, True),
|
||||||
|
Version('20w28a', 740, True),
|
||||||
|
Version('20w29a', 741, True),
|
||||||
|
Version('20w30a', 743, True),
|
||||||
|
Version('1.16.2-pre1', 744, True),
|
||||||
|
Version('1.16.2-pre2', 746, True),
|
||||||
|
Version('1.16.2-pre3', 748, True),
|
||||||
|
Version('1.16.2-rc1', 749, True),
|
||||||
|
Version('1.16.2-rc2', 750, True),
|
||||||
|
Version('1.16.2', 751, True),
|
||||||
|
Version('1.16.3-rc1', 752, True),
|
||||||
|
Version('1.16.3', 753, True),
|
||||||
|
Version('1.16.4-pre1', PRE | 1, True),
|
||||||
|
Version('1.16.4-pre2', PRE | 2, True),
|
||||||
|
Version('1.16.4-rc1', PRE | 3, True),
|
||||||
|
Version('1.16.4', 754, True),
|
||||||
|
Version('20w45a', PRE | 5, False),
|
||||||
|
Version('20w46a', PRE | 6, False),
|
||||||
|
Version('20w48a', PRE | 7, False),
|
||||||
|
]
|
||||||
|
|
||||||
# Those Minecraft versions supported by pyCraft which are "release" versions,
|
# An OrderedDict mapping the id string of each known Minecraft version to its
|
||||||
# i.e. not development snapshots or pre-release versions.
|
# protocol version number, in chronological order of release.
|
||||||
RELEASE_MINECRAFT_VERSIONS = {}
|
KNOWN_MINECRAFT_VERSIONS = OrderedDict()
|
||||||
|
|
||||||
# The protocol versions of SUPPORTED_MINECRAFT_VERSIONS, without duplicates,
|
# As KNOWN_MINECRAFT_VERSIONS, but only contains versions supported by pyCraft.
|
||||||
# in ascending numerical (and hence chronological) order.
|
SUPPORTED_MINECRAFT_VERSIONS = OrderedDict()
|
||||||
|
|
||||||
|
# As SUPPORTED_MINECRAFT_VERSIONS, but only contains release versions.
|
||||||
|
RELEASE_MINECRAFT_VERSIONS = OrderedDict()
|
||||||
|
|
||||||
|
# A list of the protocol version numbers in KNOWN_MINECRAFT_VERSIONS
|
||||||
|
# in the same order (chronological) but without duplicates.
|
||||||
|
KNOWN_PROTOCOL_VERSIONS = []
|
||||||
|
|
||||||
|
# A list of the protocol version numbers in SUPPORTED_MINECRAFT_VERSIONS
|
||||||
|
# in the same order (chronological) but without duplicates.
|
||||||
SUPPORTED_PROTOCOL_VERSIONS = []
|
SUPPORTED_PROTOCOL_VERSIONS = []
|
||||||
|
|
||||||
# The protocol versions of RELEASE_MINECRAFT_VERSIONS, without duplicates,
|
# A list of the protocol version numbers in RELEASE_MINECRAFT_VERSIONS
|
||||||
# in ascending numerical (and hence chronological) order.
|
# in the same order (chronological) but without duplicates.
|
||||||
RELEASE_PROTOCOL_VERSIONS = []
|
RELEASE_PROTOCOL_VERSIONS = []
|
||||||
|
|
||||||
|
# A dict mapping each protocol version number in KNOWN_PROTOCOL_VERSIONS to
|
||||||
|
# its index within this list (used for efficient comparison of protocol
|
||||||
|
# versions according to chronological release order).
|
||||||
|
PROTOCOL_VERSION_INDICES = {}
|
||||||
|
|
||||||
def initglobals():
|
|
||||||
'''Init the globals from the SUPPORTED_MINECRAFT_VERSIONS dict
|
|
||||||
|
|
||||||
This allows the SUPPORTED_MINECRAFT_VERSIONS dict to be updated, then the
|
def initglobals(use_known_records=False):
|
||||||
other globals can be updated as well, to allow for dynamic version support.
|
'''Initialise the above global variables, using
|
||||||
All updates are done by reference to allow this to work else where in the
|
'SUPPORTED_MINECRAFT_VERSIONS' as the source if 'use_known_records' is
|
||||||
code.
|
False (for backward compatibility, this is the default behaviour), or
|
||||||
|
otherwise using 'KNOWN_MINECRAFT_VERSION_RECORDS' as the source.
|
||||||
|
|
||||||
|
This allows 'SUPPORTED_MINECRAFT_VERSIONS' or, respectively,
|
||||||
|
'KNOWN_MINECRAFT_VERSION_RECORDS' to be updated by the library user
|
||||||
|
during runtime and then the derived data to be updated as well, to allow
|
||||||
|
for dynamic version support. All updates are done by reference to allow
|
||||||
|
this to work elsewhere in the code.
|
||||||
'''
|
'''
|
||||||
global RELEASE_MINECRAFT_VERSIONS, SUPPORTED_PROTOCOL_VERSIONS
|
if use_known_records:
|
||||||
global RELEASE_PROTOCOL_VERSIONS
|
# Update the variables that depend on KNOWN_MINECRAFT_VERSION_RECORDS.
|
||||||
|
KNOWN_MINECRAFT_VERSIONS.clear()
|
||||||
|
KNOWN_PROTOCOL_VERSIONS.clear()
|
||||||
|
SUPPORTED_MINECRAFT_VERSIONS.clear()
|
||||||
|
PROTOCOL_VERSION_INDICES.clear()
|
||||||
|
for version in KNOWN_MINECRAFT_VERSION_RECORDS:
|
||||||
|
KNOWN_MINECRAFT_VERSIONS[version.id] = version.protocol
|
||||||
|
if version.protocol not in KNOWN_PROTOCOL_VERSIONS:
|
||||||
|
PROTOCOL_VERSION_INDICES[version.protocol] \
|
||||||
|
= len(KNOWN_PROTOCOL_VERSIONS)
|
||||||
|
KNOWN_PROTOCOL_VERSIONS.append(version.protocol)
|
||||||
|
if version.supported:
|
||||||
|
SUPPORTED_MINECRAFT_VERSIONS[version.id] = version.protocol
|
||||||
|
|
||||||
import re
|
# Update the variables that depend on SUPPORTED_MINECRAFT_VERSIONS.
|
||||||
|
SUPPORTED_PROTOCOL_VERSIONS.clear()
|
||||||
for (vid, protocol) in SUPPORTED_MINECRAFT_VERSIONS.items():
|
RELEASE_MINECRAFT_VERSIONS.clear()
|
||||||
if re.match(r"\d+(\.\d+)+$", vid):
|
RELEASE_PROTOCOL_VERSIONS.clear()
|
||||||
RELEASE_MINECRAFT_VERSIONS[vid] = protocol
|
for (version_id, protocol) in SUPPORTED_MINECRAFT_VERSIONS.items():
|
||||||
|
if re.match(r'\d+(\.\d+)+$', version_id):
|
||||||
|
RELEASE_MINECRAFT_VERSIONS[version_id] = protocol
|
||||||
if protocol not in RELEASE_PROTOCOL_VERSIONS:
|
if protocol not in RELEASE_PROTOCOL_VERSIONS:
|
||||||
RELEASE_PROTOCOL_VERSIONS.append(protocol)
|
RELEASE_PROTOCOL_VERSIONS.append(protocol)
|
||||||
if protocol not in SUPPORTED_PROTOCOL_VERSIONS:
|
if protocol not in SUPPORTED_PROTOCOL_VERSIONS:
|
||||||
SUPPORTED_PROTOCOL_VERSIONS.append(protocol)
|
SUPPORTED_PROTOCOL_VERSIONS.append(protocol)
|
||||||
|
|
||||||
SUPPORTED_PROTOCOL_VERSIONS.sort()
|
|
||||||
RELEASE_PROTOCOL_VERSIONS.sort()
|
|
||||||
|
|
||||||
|
initglobals(use_known_records=True)
|
||||||
initglobals()
|
|
||||||
|
@ -11,9 +11,11 @@ import re
|
|||||||
|
|
||||||
from .types import VarInt
|
from .types import VarInt
|
||||||
from .packets import clientbound, serverbound
|
from .packets import clientbound, serverbound
|
||||||
from . import packets
|
from . import packets, encryption
|
||||||
from . import encryption
|
from .. import (
|
||||||
from .. import SUPPORTED_PROTOCOL_VERSIONS, SUPPORTED_MINECRAFT_VERSIONS
|
utility, KNOWN_MINECRAFT_VERSIONS, SUPPORTED_MINECRAFT_VERSIONS,
|
||||||
|
SUPPORTED_PROTOCOL_VERSIONS, PROTOCOL_VERSION_INDICES
|
||||||
|
)
|
||||||
from ..exceptions import (
|
from ..exceptions import (
|
||||||
VersionMismatch, LoginDisconnect, IgnorePacket, InvalidState
|
VersionMismatch, LoginDisconnect, IgnorePacket, InvalidState
|
||||||
)
|
)
|
||||||
@ -31,6 +33,26 @@ class ConnectionContext(object):
|
|||||||
def __init__(self, **kwds):
|
def __init__(self, **kwds):
|
||||||
self.protocol_version = kwds.get('protocol_version')
|
self.protocol_version = kwds.get('protocol_version')
|
||||||
|
|
||||||
|
def protocol_earlier(self, other_pv):
|
||||||
|
"""Returns True if the protocol version of this context was published
|
||||||
|
earlier than 'other_pv', or else False."""
|
||||||
|
return utility.protocol_earlier(self.protocol_version, other_pv)
|
||||||
|
|
||||||
|
def protocol_earlier_eq(self, other_pv):
|
||||||
|
"""Returns True if the protocol version of this context was published
|
||||||
|
earlier than, or is equal to, 'other_pv', or else False."""
|
||||||
|
return utility.protocol_earlier_eq(self.protocol_version, other_pv)
|
||||||
|
|
||||||
|
def protocol_later(self, other_pv):
|
||||||
|
"""Returns True if the protocol version of this context was published
|
||||||
|
later than 'other_pv', or else False."""
|
||||||
|
return utility.protocol_earlier(other_pv, self.protocol_version)
|
||||||
|
|
||||||
|
def protocol_later_eq(self, other_pv):
|
||||||
|
"""Returns True if the protocol version of this context was published
|
||||||
|
later than, or is equal to, 'other_pv', or else False."""
|
||||||
|
return utility.protocol_earlier_eq(other_pv, self.protocol_version)
|
||||||
|
|
||||||
|
|
||||||
class _ConnectionOptions(object):
|
class _ConnectionOptions(object):
|
||||||
def __init__(self, address=None, port=None, compression_threshold=-1,
|
def __init__(self, address=None, port=None, compression_threshold=-1,
|
||||||
@ -129,13 +151,15 @@ class Connection(object):
|
|||||||
allowed_versions = set(map(proto_version, allowed_versions))
|
allowed_versions = set(map(proto_version, allowed_versions))
|
||||||
self.allowed_proto_versions = allowed_versions
|
self.allowed_proto_versions = allowed_versions
|
||||||
|
|
||||||
|
latest_allowed_proto = max(self.allowed_proto_versions,
|
||||||
|
key=PROTOCOL_VERSION_INDICES.get)
|
||||||
|
|
||||||
if initial_version is None:
|
if initial_version is None:
|
||||||
self.default_proto_version = max(self.allowed_proto_versions)
|
self.default_proto_version = latest_allowed_proto
|
||||||
else:
|
else:
|
||||||
self.default_proto_version = proto_version(initial_version)
|
self.default_proto_version = proto_version(initial_version)
|
||||||
|
|
||||||
self.context = ConnectionContext(
|
self.context = ConnectionContext(protocol_version=latest_allowed_proto)
|
||||||
protocol_version=max(self.allowed_proto_versions))
|
|
||||||
|
|
||||||
self.options = _ConnectionOptions()
|
self.options = _ConnectionOptions()
|
||||||
self.options.address = address
|
self.options.address = address
|
||||||
@ -362,7 +386,9 @@ class Connection(object):
|
|||||||
# It is important that this is set correctly even when connecting
|
# It is important that this is set correctly even when connecting
|
||||||
# in status mode, as some servers, e.g. SpigotMC with the
|
# in status mode, as some servers, e.g. SpigotMC with the
|
||||||
# ProtocolSupport plugin, use it to determine the correct response.
|
# ProtocolSupport plugin, use it to determine the correct response.
|
||||||
self.context.protocol_version = max(self.allowed_proto_versions)
|
self.context.protocol_version \
|
||||||
|
= max(self.allowed_proto_versions,
|
||||||
|
key=PROTOCOL_VERSION_INDICES.get)
|
||||||
|
|
||||||
self.spawned = False
|
self.spawned = False
|
||||||
self._connect()
|
self._connect()
|
||||||
@ -496,7 +522,7 @@ class Connection(object):
|
|||||||
|
|
||||||
def _version_mismatch(self, server_protocol=None, server_version=None):
|
def _version_mismatch(self, server_protocol=None, server_version=None):
|
||||||
if server_protocol is None:
|
if server_protocol is None:
|
||||||
server_protocol = SUPPORTED_MINECRAFT_VERSIONS.get(server_version)
|
server_protocol = KNOWN_MINECRAFT_VERSIONS.get(server_version)
|
||||||
|
|
||||||
if server_protocol is None:
|
if server_protocol is None:
|
||||||
vs = 'version' if server_version is None else \
|
vs = 'version' if server_version is None else \
|
||||||
@ -751,7 +777,7 @@ class PlayingReactor(PacketReactor):
|
|||||||
self.connection.write_packet(keep_alive_packet)
|
self.connection.write_packet(keep_alive_packet)
|
||||||
|
|
||||||
elif packet.packet_name == "player position and look":
|
elif packet.packet_name == "player position and look":
|
||||||
if self.connection.context.protocol_version >= 107:
|
if self.connection.context.protocol_later_eq(107):
|
||||||
teleport_confirm = serverbound.play.TeleportConfirmPacket()
|
teleport_confirm = serverbound.play.TeleportConfirmPacket()
|
||||||
teleport_confirm.teleport_id = packet.teleport_id
|
teleport_confirm.teleport_id = packet.teleport_id
|
||||||
self.connection.write_packet(teleport_confirm)
|
self.connection.write_packet(teleport_confirm)
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
'''
|
'''
|
||||||
NOTE: The packet classes in __all_legacy_packets__ exported by this
|
NOTE: The packet classes exported by this module are included only for backward
|
||||||
module are included only for backward compatibility, and should not
|
compatibility, and should not be used in new code, as (1) they do not include
|
||||||
be used in new code, as (1) they do not include all packets present
|
all packets present in pyCraft, and (2) some are named oddly, for historical
|
||||||
in pyCraft, and (2) some are named oddly, for historical reasons.
|
reasons.
|
||||||
|
|
||||||
Use the packet classes under packets.clientbound.* and
|
Use the packet classes under packets.clientbound.* and
|
||||||
packets.serverbound.* instead.
|
packets.serverbound.* instead.
|
||||||
@ -60,26 +60,3 @@ from .serverbound.play import PositionAndLookPacket
|
|||||||
from .serverbound.play import TeleportConfirmPacket
|
from .serverbound.play import TeleportConfirmPacket
|
||||||
from .serverbound.play import AnimationPacket as AnimationPacketServerbound
|
from .serverbound.play import AnimationPacket as AnimationPacketServerbound
|
||||||
from .serverbound.play import get_packets as state_playing_serverbound
|
from .serverbound.play import get_packets as state_playing_serverbound
|
||||||
|
|
||||||
__all_legacy_packets__ = (
|
|
||||||
state_handshake_clientbound, HandShakePacket,
|
|
||||||
state_handshake_serverbound, ResponsePacket,
|
|
||||||
PingPacketResponse, state_status_clientbound,
|
|
||||||
RequestPacket, PingPacket, state_status_serverbound,
|
|
||||||
DisconnectPacket, EncryptionRequestPacket, LoginSuccessPacket,
|
|
||||||
SetCompressionPacket, state_login_clientbound,
|
|
||||||
LoginStartPacket, EncryptionResponsePacket,
|
|
||||||
state_login_serverbound, KeepAlivePacketClientbound,
|
|
||||||
KeepAlivePacketServerbound, JoinGamePacket, ChatMessagePacket,
|
|
||||||
PlayerPositionAndLookPacket, DisconnectPacketPlayState,
|
|
||||||
SetCompressionPacketPlayState, PlayerListItemPacket,
|
|
||||||
MapPacket, state_playing_clientbound, ChatPacket,
|
|
||||||
PositionAndLookPacket, TeleportConfirmPacket,
|
|
||||||
AnimationPacketServerbound, state_playing_serverbound,
|
|
||||||
KeepAlivePacket,
|
|
||||||
)
|
|
||||||
|
|
||||||
__all_other__ = (
|
|
||||||
Packet, PacketBuffer, PacketListener,
|
|
||||||
AbstractKeepAlivePacket, AbstractPluginMessagePacket,
|
|
||||||
)
|
|
||||||
|
@ -13,7 +13,7 @@ def get_packets(context):
|
|||||||
LoginSuccessPacket,
|
LoginSuccessPacket,
|
||||||
SetCompressionPacket,
|
SetCompressionPacket,
|
||||||
}
|
}
|
||||||
if context.protocol_version >= 385:
|
if context.protocol_later_eq(385):
|
||||||
packets |= {
|
packets |= {
|
||||||
PluginRequestPacket,
|
PluginRequestPacket,
|
||||||
}
|
}
|
||||||
@ -23,8 +23,8 @@ def get_packets(context):
|
|||||||
class DisconnectPacket(Packet):
|
class DisconnectPacket(Packet):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x00 if context.protocol_version >= 391 else \
|
return 0x00 if context.protocol_later_eq(391) else \
|
||||||
0x01 if context.protocol_version >= 385 else \
|
0x01 if context.protocol_later_eq(385) else \
|
||||||
0x00
|
0x00
|
||||||
|
|
||||||
packet_name = "disconnect"
|
packet_name = "disconnect"
|
||||||
@ -35,8 +35,8 @@ class DisconnectPacket(Packet):
|
|||||||
class EncryptionRequestPacket(Packet):
|
class EncryptionRequestPacket(Packet):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x01 if context.protocol_version >= 391 else \
|
return 0x01 if context.protocol_later_eq(391) else \
|
||||||
0x02 if context.protocol_version >= 385 else \
|
0x02 if context.protocol_later_eq(385) else \
|
||||||
0x01
|
0x01
|
||||||
|
|
||||||
packet_name = "encryption request"
|
packet_name = "encryption request"
|
||||||
@ -49,13 +49,13 @@ class EncryptionRequestPacket(Packet):
|
|||||||
class LoginSuccessPacket(Packet):
|
class LoginSuccessPacket(Packet):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x02 if context.protocol_version >= 391 else \
|
return 0x02 if context.protocol_later_eq(391) else \
|
||||||
0x03 if context.protocol_version >= 385 else \
|
0x03 if context.protocol_later_eq(385) else \
|
||||||
0x02
|
0x02
|
||||||
|
|
||||||
packet_name = "login success"
|
packet_name = "login success"
|
||||||
get_definition = staticmethod(lambda context: [
|
get_definition = staticmethod(lambda context: [
|
||||||
{'UUID': UUID if context.protocol_version >= 707 else String},
|
{'UUID': UUID if context.protocol_later_eq(707) else String},
|
||||||
{'Username': String}
|
{'Username': String}
|
||||||
])
|
])
|
||||||
|
|
||||||
@ -63,8 +63,8 @@ class LoginSuccessPacket(Packet):
|
|||||||
class SetCompressionPacket(Packet):
|
class SetCompressionPacket(Packet):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x03 if context.protocol_version >= 391 else \
|
return 0x03 if context.protocol_later_eq(391) else \
|
||||||
0x04 if context.protocol_version >= 385 else \
|
0x04 if context.protocol_later_eq(385) else \
|
||||||
0x03
|
0x03
|
||||||
|
|
||||||
packet_name = "set compression"
|
packet_name = "set compression"
|
||||||
@ -89,7 +89,7 @@ class PluginRequestPacket(Packet):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x04 if context.protocol_version >= 391 else \
|
return 0x04 if context.protocol_later_eq(391) else \
|
||||||
0x00
|
0x00
|
||||||
|
|
||||||
packet_name = 'login plugin request'
|
packet_name = 'login plugin request'
|
||||||
|
@ -46,15 +46,15 @@ def get_packets(context):
|
|||||||
PlayerListHeaderAndFooterPacket,
|
PlayerListHeaderAndFooterPacket,
|
||||||
EntityLookPacket
|
EntityLookPacket
|
||||||
}
|
}
|
||||||
if context.protocol_version <= 47:
|
if context.protocol_earlier_eq(47):
|
||||||
packets |= {
|
packets |= {
|
||||||
SetCompressionPacket,
|
SetCompressionPacket,
|
||||||
}
|
}
|
||||||
if context.protocol_version >= 94:
|
if context.protocol_later_eq(94):
|
||||||
packets |= {
|
packets |= {
|
||||||
SoundEffectPacket,
|
SoundEffectPacket,
|
||||||
}
|
}
|
||||||
if context.protocol_version >= 352:
|
if context.protocol_later_eq(352):
|
||||||
packets |= {
|
packets |= {
|
||||||
FacePlayerPacket
|
FacePlayerPacket
|
||||||
}
|
}
|
||||||
@ -64,32 +64,32 @@ def get_packets(context):
|
|||||||
class KeepAlivePacket(AbstractKeepAlivePacket):
|
class KeepAlivePacket(AbstractKeepAlivePacket):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x1F if context.protocol_version >= 741 else \
|
return 0x1F if context.protocol_later_eq(741) else \
|
||||||
0x20 if context.protocol_version >= 721 else \
|
0x20 if context.protocol_later_eq(721) else \
|
||||||
0x21 if context.protocol_version >= 550 else \
|
0x21 if context.protocol_later_eq(550) else \
|
||||||
0x20 if context.protocol_version >= 471 else \
|
0x20 if context.protocol_later_eq(471) else \
|
||||||
0x21 if context.protocol_version >= 389 else \
|
0x21 if context.protocol_later_eq(389) else \
|
||||||
0x20 if context.protocol_version >= 345 else \
|
0x20 if context.protocol_later_eq(345) else \
|
||||||
0x1F if context.protocol_version >= 332 else \
|
0x1F if context.protocol_later_eq(332) else \
|
||||||
0x20 if context.protocol_version >= 318 else \
|
0x20 if context.protocol_later_eq(318) else \
|
||||||
0x1F if context.protocol_version >= 107 else \
|
0x1F if context.protocol_later_eq(107) else \
|
||||||
0x00
|
0x00
|
||||||
|
|
||||||
|
|
||||||
class ServerDifficultyPacket(Packet):
|
class ServerDifficultyPacket(Packet):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x0D if context.protocol_version >= 721 else \
|
return 0x0D if context.protocol_later_eq(721) else \
|
||||||
0x0E if context.protocol_version >= 550 else \
|
0x0E if context.protocol_later_eq(550) else \
|
||||||
0x0D if context.protocol_version >= 332 else \
|
0x0D if context.protocol_later_eq(332) else \
|
||||||
0x0E if context.protocol_version >= 318 else \
|
0x0E if context.protocol_later_eq(318) else \
|
||||||
0x0D if context.protocol_version >= 70 else \
|
0x0D if context.protocol_later_eq(70) else \
|
||||||
0x41
|
0x41
|
||||||
|
|
||||||
packet_name = 'server difficulty'
|
packet_name = 'server difficulty'
|
||||||
get_definition = staticmethod(lambda context: [
|
get_definition = staticmethod(lambda context: [
|
||||||
{'difficulty': UnsignedByte},
|
{'difficulty': UnsignedByte},
|
||||||
{'is_locked': Boolean} if context.protocol_version >= 464 else {},
|
{'is_locked': Boolean} if context.protocol_later_eq(464) else {},
|
||||||
])
|
])
|
||||||
|
|
||||||
# These aliases declare the Enum type corresponding to each field:
|
# These aliases declare the Enum type corresponding to each field:
|
||||||
@ -99,19 +99,19 @@ class ServerDifficultyPacket(Packet):
|
|||||||
class ChatMessagePacket(Packet):
|
class ChatMessagePacket(Packet):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x0E if context.protocol_version >= 721 else \
|
return 0x0E if context.protocol_later_eq(721) else \
|
||||||
0x0F if context.protocol_version >= 550 else \
|
0x0F if context.protocol_later_eq(550) else \
|
||||||
0x0E if context.protocol_version >= 343 else \
|
0x0E if context.protocol_later_eq(343) else \
|
||||||
0x0F if context.protocol_version >= 332 else \
|
0x0F if context.protocol_later_eq(332) else \
|
||||||
0x10 if context.protocol_version >= 317 else \
|
0x10 if context.protocol_later_eq(317) else \
|
||||||
0x0F if context.protocol_version >= 107 else \
|
0x0F if context.protocol_later_eq(107) else \
|
||||||
0x02
|
0x02
|
||||||
|
|
||||||
packet_name = "chat message"
|
packet_name = "chat message"
|
||||||
get_definition = staticmethod(lambda context: [
|
get_definition = staticmethod(lambda context: [
|
||||||
{'json_data': String},
|
{'json_data': String},
|
||||||
{'position': Byte},
|
{'position': Byte},
|
||||||
{'sender': UUID} if context.protocol_version >= 718 else {},
|
{'sender': UUID} if context.protocol_later_eq(718) else {},
|
||||||
])
|
])
|
||||||
|
|
||||||
class Position(Enum):
|
class Position(Enum):
|
||||||
@ -123,14 +123,14 @@ class ChatMessagePacket(Packet):
|
|||||||
class DisconnectPacket(Packet):
|
class DisconnectPacket(Packet):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x19 if context.protocol_version >= 741 else \
|
return 0x19 if context.protocol_later_eq(741) else \
|
||||||
0x1A if context.protocol_version >= 721 else \
|
0x1A if context.protocol_later_eq(721) else \
|
||||||
0x1B if context.protocol_version >= 550 else \
|
0x1B if context.protocol_later_eq(550) else \
|
||||||
0x1A if context.protocol_version >= 471 else \
|
0x1A if context.protocol_later_eq(471) else \
|
||||||
0x1B if context.protocol_version >= 345 else \
|
0x1B if context.protocol_later_eq(345) else \
|
||||||
0x1A if context.protocol_version >= 332 else \
|
0x1A if context.protocol_later_eq(332) else \
|
||||||
0x1B if context.protocol_version >= 318 else \
|
0x1B if context.protocol_later_eq(318) else \
|
||||||
0x1A if context.protocol_version >= 107 else \
|
0x1A if context.protocol_later_eq(107) else \
|
||||||
0x40
|
0x40
|
||||||
|
|
||||||
packet_name = "disconnect"
|
packet_name = "disconnect"
|
||||||
@ -150,23 +150,23 @@ class SetCompressionPacket(Packet):
|
|||||||
class SpawnPlayerPacket(Packet):
|
class SpawnPlayerPacket(Packet):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x04 if context.protocol_version >= 721 else \
|
return 0x04 if context.protocol_later_eq(721) else \
|
||||||
0x05 if context.protocol_version >= 67 else \
|
0x05 if context.protocol_later_eq(67) else \
|
||||||
0x0C
|
0x0C
|
||||||
|
|
||||||
packet_name = 'spawn player'
|
packet_name = 'spawn player'
|
||||||
get_definition = staticmethod(lambda context: [
|
get_definition = staticmethod(lambda context: [
|
||||||
{'entity_id': VarInt},
|
{'entity_id': VarInt},
|
||||||
{'player_UUID': UUID},
|
{'player_UUID': UUID},
|
||||||
{'x': Double} if context.protocol_version >= 100
|
{'x': Double} if context.protocol_later_eq(100)
|
||||||
else {'x': FixedPoint(Integer)},
|
else {'x': FixedPoint(Integer)},
|
||||||
{'y': Double} if context.protocol_version >= 100
|
{'y': Double} if context.protocol_later_eq(100)
|
||||||
else {'y': FixedPoint(Integer)},
|
else {'y': FixedPoint(Integer)},
|
||||||
{'z': Double} if context.protocol_version >= 100
|
{'z': Double} if context.protocol_later_eq(100)
|
||||||
else {'z': FixedPoint(Integer)},
|
else {'z': FixedPoint(Integer)},
|
||||||
{'yaw': Angle},
|
{'yaw': Angle},
|
||||||
{'pitch': Angle},
|
{'pitch': Angle},
|
||||||
{'current_item': Short} if context.protocol_version <= 49 else {},
|
{'current_item': Short} if context.protocol_earlier_eq(49) else {},
|
||||||
# TODO: read entity metadata (protocol < 550)
|
# TODO: read entity metadata (protocol < 550)
|
||||||
])
|
])
|
||||||
|
|
||||||
@ -186,20 +186,20 @@ class SpawnPlayerPacket(Packet):
|
|||||||
class EntityVelocityPacket(Packet):
|
class EntityVelocityPacket(Packet):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x46 if context.protocol_version >= 721 else \
|
return 0x46 if context.protocol_later_eq(721) else \
|
||||||
0x47 if context.protocol_version >= 707 else \
|
0x47 if context.protocol_later_eq(707) else \
|
||||||
0x46 if context.protocol_version >= 550 else \
|
0x46 if context.protocol_later_eq(550) else \
|
||||||
0x45 if context.protocol_version >= 471 else \
|
0x45 if context.protocol_later_eq(471) else \
|
||||||
0x41 if context.protocol_version >= 461 else \
|
0x41 if context.protocol_later_eq(461) else \
|
||||||
0x42 if context.protocol_version >= 451 else \
|
0x42 if context.protocol_later_eq(451) else \
|
||||||
0x41 if context.protocol_version >= 389 else \
|
0x41 if context.protocol_later_eq(389) else \
|
||||||
0x40 if context.protocol_version >= 352 else \
|
0x40 if context.protocol_later_eq(352) else \
|
||||||
0x3F if context.protocol_version >= 345 else \
|
0x3F if context.protocol_later_eq(345) else \
|
||||||
0x3E if context.protocol_version >= 336 else \
|
0x3E if context.protocol_later_eq(336) else \
|
||||||
0x3D if context.protocol_version >= 332 else \
|
0x3D if context.protocol_later_eq(332) else \
|
||||||
0x3B if context.protocol_version >= 86 else \
|
0x3B if context.protocol_later_eq(86) else \
|
||||||
0x3C if context.protocol_version >= 77 else \
|
0x3C if context.protocol_later_eq(77) else \
|
||||||
0x3B if context.protocol_version >= 67 else \
|
0x3B if context.protocol_later_eq(67) else \
|
||||||
0x12
|
0x12
|
||||||
|
|
||||||
packet_name = 'entity velocity'
|
packet_name = 'entity velocity'
|
||||||
@ -214,14 +214,14 @@ class EntityVelocityPacket(Packet):
|
|||||||
class EntityPositionDeltaPacket(Packet):
|
class EntityPositionDeltaPacket(Packet):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x27 if context.protocol_version >= 741 else \
|
return 0x27 if context.protocol_later_eq(741) else \
|
||||||
0x28 if context.protocol_version >= 721 else \
|
0x28 if context.protocol_later_eq(721) else \
|
||||||
0x29 if context.protocol_version >= 550 else \
|
0x29 if context.protocol_later_eq(550) else \
|
||||||
0x28 if context.protocol_version >= 389 else \
|
0x28 if context.protocol_later_eq(389) else \
|
||||||
0x27 if context.protocol_version >= 345 else \
|
0x27 if context.protocol_later_eq(345) else \
|
||||||
0x26 if context.protocol_version >= 318 else \
|
0x26 if context.protocol_later_eq(318) else \
|
||||||
0x25 if context.protocol_version >= 94 else \
|
0x25 if context.protocol_later_eq(94) else \
|
||||||
0x26 if context.protocol_version >= 70 else \
|
0x26 if context.protocol_later_eq(70) else \
|
||||||
0x15
|
0x15
|
||||||
|
|
||||||
packet_name = "entity position delta"
|
packet_name = "entity position delta"
|
||||||
@ -229,7 +229,7 @@ class EntityPositionDeltaPacket(Packet):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def get_definition(context):
|
def get_definition(context):
|
||||||
delta_type = FixedPoint(Short, 12) \
|
delta_type = FixedPoint(Short, 12) \
|
||||||
if context.protocol_version >= 106 else \
|
if context.protocol_later_eq(106) else \
|
||||||
FixedPoint(Byte)
|
FixedPoint(Byte)
|
||||||
return [
|
return [
|
||||||
{'entity_id': VarInt},
|
{'entity_id': VarInt},
|
||||||
@ -253,18 +253,18 @@ class EntityPositionDeltaPacket(Packet):
|
|||||||
class TimeUpdatePacket(Packet):
|
class TimeUpdatePacket(Packet):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x4E if context.protocol_version >= 721 else \
|
return 0x4E if context.protocol_later_eq(721) else \
|
||||||
0x4F if context.protocol_version >= 550 else \
|
0x4F if context.protocol_later_eq(550) else \
|
||||||
0x4E if context.protocol_version >= 471 else \
|
0x4E if context.protocol_later_eq(471) else \
|
||||||
0x4A if context.protocol_version >= 461 else \
|
0x4A if context.protocol_later_eq(461) else \
|
||||||
0x4B if context.protocol_version >= 451 else \
|
0x4B if context.protocol_later_eq(451) else \
|
||||||
0x4A if context.protocol_version >= 389 else \
|
0x4A if context.protocol_later_eq(389) else \
|
||||||
0x49 if context.protocol_version >= 352 else \
|
0x49 if context.protocol_later_eq(352) else \
|
||||||
0x48 if context.protocol_version >= 345 else \
|
0x48 if context.protocol_later_eq(345) else \
|
||||||
0x47 if context.protocol_version >= 336 else \
|
0x47 if context.protocol_later_eq(336) else \
|
||||||
0x46 if context.protocol_version >= 318 else \
|
0x46 if context.protocol_later_eq(318) else \
|
||||||
0x44 if context.protocol_version >= 94 else \
|
0x44 if context.protocol_later_eq(94) else \
|
||||||
0x43 if context.protocol_version >= 70 else \
|
0x43 if context.protocol_later_eq(70) else \
|
||||||
0x03
|
0x03
|
||||||
|
|
||||||
packet_name = "time update"
|
packet_name = "time update"
|
||||||
@ -277,20 +277,20 @@ class TimeUpdatePacket(Packet):
|
|||||||
class UpdateHealthPacket(Packet):
|
class UpdateHealthPacket(Packet):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x49 if context.protocol_version >= 721 else \
|
return 0x49 if context.protocol_later_eq(721) else \
|
||||||
0x4A if context.protocol_version >= 707 else \
|
0x4A if context.protocol_later_eq(707) else \
|
||||||
0x49 if context.protocol_version >= 550 else \
|
0x49 if context.protocol_later_eq(550) else \
|
||||||
0x48 if context.protocol_version >= 471 else \
|
0x48 if context.protocol_later_eq(471) else \
|
||||||
0x44 if context.protocol_version >= 461 else \
|
0x44 if context.protocol_later_eq(461) else \
|
||||||
0x45 if context.protocol_version >= 451 else \
|
0x45 if context.protocol_later_eq(451) else \
|
||||||
0x44 if context.protocol_version >= 389 else \
|
0x44 if context.protocol_later_eq(389) else \
|
||||||
0x43 if context.protocol_version >= 352 else \
|
0x43 if context.protocol_later_eq(352) else \
|
||||||
0x42 if context.protocol_version >= 345 else \
|
0x42 if context.protocol_later_eq(345) else \
|
||||||
0x41 if context.protocol_version >= 336 else \
|
0x41 if context.protocol_later_eq(336) else \
|
||||||
0x40 if context.protocol_version >= 318 else \
|
0x40 if context.protocol_later_eq(318) else \
|
||||||
0x3E if context.protocol_version >= 86 else \
|
0x3E if context.protocol_later_eq(86) else \
|
||||||
0x3F if context.protocol_version >= 77 else \
|
0x3F if context.protocol_later_eq(77) else \
|
||||||
0x3E if context.protocol_version >= 67 else \
|
0x3E if context.protocol_later_eq(67) else \
|
||||||
0x06
|
0x06
|
||||||
|
|
||||||
packet_name = 'update health'
|
packet_name = 'update health'
|
||||||
@ -304,31 +304,31 @@ class UpdateHealthPacket(Packet):
|
|||||||
class PluginMessagePacket(AbstractPluginMessagePacket):
|
class PluginMessagePacket(AbstractPluginMessagePacket):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x17 if context.protocol_version >= 741 else \
|
return 0x17 if context.protocol_later_eq(741) else \
|
||||||
0x18 if context.protocol_version >= 721 else \
|
0x18 if context.protocol_later_eq(721) else \
|
||||||
0x19 if context.protocol_version >= 550 else \
|
0x19 if context.protocol_later_eq(550) else \
|
||||||
0x18 if context.protocol_version >= 471 else \
|
0x18 if context.protocol_later_eq(471) else \
|
||||||
0x19 if context.protocol_version >= 345 else \
|
0x19 if context.protocol_later_eq(345) else \
|
||||||
0x18 if context.protocol_version >= 332 else \
|
0x18 if context.protocol_later_eq(332) else \
|
||||||
0x19 if context.protocol_version >= 318 else \
|
0x19 if context.protocol_later_eq(318) else \
|
||||||
0x18 if context.protocol_version >= 70 else \
|
0x18 if context.protocol_later_eq(70) else \
|
||||||
0x3F
|
0x3F
|
||||||
|
|
||||||
|
|
||||||
class PlayerListHeaderAndFooterPacket(Packet):
|
class PlayerListHeaderAndFooterPacket(Packet):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x53 if context.protocol_version >= 721 else \
|
return 0x53 if context.protocol_later_eq(721) else \
|
||||||
0x54 if context.protocol_version >= 550 else \
|
0x54 if context.protocol_later_eq(550) else \
|
||||||
0x53 if context.protocol_version >= 471 else \
|
0x53 if context.protocol_later_eq(471) else \
|
||||||
0x5F if context.protocol_version >= 461 else \
|
0x5F if context.protocol_later_eq(461) else \
|
||||||
0x50 if context.protocol_version >= 451 else \
|
0x50 if context.protocol_later_eq(451) else \
|
||||||
0x4F if context.protocol_version >= 441 else \
|
0x4F if context.protocol_later_eq(441) else \
|
||||||
0x4E if context.protocol_version >= 393 else \
|
0x4E if context.protocol_later_eq(393) else \
|
||||||
0x4A if context.protocol_version >= 338 else \
|
0x4A if context.protocol_later_eq(338) else \
|
||||||
0x49 if context.protocol_version >= 335 else \
|
0x49 if context.protocol_later_eq(335) else \
|
||||||
0x47 if context.protocol_version >= 110 else \
|
0x47 if context.protocol_later_eq(110) else \
|
||||||
0x48 if context.protocol_version >= 107 else \
|
0x48 if context.protocol_later_eq(107) else \
|
||||||
0x47
|
0x47
|
||||||
|
|
||||||
packet_name = 'player list header and footer'
|
packet_name = 'player list header and footer'
|
||||||
@ -340,14 +340,14 @@ class PlayerListHeaderAndFooterPacket(Packet):
|
|||||||
class EntityLookPacket(Packet):
|
class EntityLookPacket(Packet):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x29 if context.protocol_version >= 741 else \
|
return 0x29 if context.protocol_later_eq(741) else \
|
||||||
0x2A if context.protocol_version >= 721 else \
|
0x2A if context.protocol_later_eq(721) else \
|
||||||
0x2B if context.protocol_version >= 550 else \
|
0x2B if context.protocol_later_eq(550) else \
|
||||||
0x2A if context.protocol_version >= 389 else \
|
0x2A if context.protocol_later_eq(389) else \
|
||||||
0x29 if context.protocol_version >= 345 else \
|
0x29 if context.protocol_later_eq(345) else \
|
||||||
0x28 if context.protocol_version >= 318 else \
|
0x28 if context.protocol_later_eq(318) else \
|
||||||
0x27 if context.protocol_version >= 94 else \
|
0x27 if context.protocol_later_eq(94) else \
|
||||||
0x28 if context.protocol_version >= 70 else \
|
0x28 if context.protocol_later_eq(70) else \
|
||||||
0x16
|
0x16
|
||||||
|
|
||||||
packet_name = 'entity look'
|
packet_name = 'entity look'
|
||||||
|
@ -9,12 +9,12 @@ from minecraft.networking.types import (
|
|||||||
class BlockChangePacket(Packet):
|
class BlockChangePacket(Packet):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x0B if context.protocol_version >= 721 else \
|
return 0x0B if context.protocol_later_eq(721) else \
|
||||||
0x0C if context.protocol_version >= 550 else \
|
0x0C if context.protocol_later_eq(550) else \
|
||||||
0x0B if context.protocol_version >= 332 else \
|
0x0B if context.protocol_later_eq(332) else \
|
||||||
0x0C if context.protocol_version >= 318 else \
|
0x0C if context.protocol_later_eq(318) else \
|
||||||
0x0B if context.protocol_version >= 67 else \
|
0x0B if context.protocol_later_eq(67) else \
|
||||||
0x24 if context.protocol_version >= 62 else \
|
0x24 if context.protocol_later_eq(62) else \
|
||||||
0x23
|
0x23
|
||||||
|
|
||||||
packet_name = 'block change'
|
packet_name = 'block change'
|
||||||
@ -23,7 +23,7 @@ class BlockChangePacket(Packet):
|
|||||||
{'block_state_id': VarInt}]
|
{'block_state_id': VarInt}]
|
||||||
block_state_id = 0
|
block_state_id = 0
|
||||||
|
|
||||||
# For protocols < 347: an accessor for (block_state_id >> 4).
|
# For protocols before 347: an accessor for (block_state_id >> 4).
|
||||||
@property
|
@property
|
||||||
def blockId(self):
|
def blockId(self):
|
||||||
return self.block_state_id >> 4
|
return self.block_state_id >> 4
|
||||||
@ -32,7 +32,7 @@ class BlockChangePacket(Packet):
|
|||||||
def blockId(self, block_id):
|
def blockId(self, block_id):
|
||||||
self.block_state_id = (self.block_state_id & 0xF) | (block_id << 4)
|
self.block_state_id = (self.block_state_id & 0xF) | (block_id << 4)
|
||||||
|
|
||||||
# For protocols < 347: an accessor for (block_state_id & 0xF).
|
# For protocols before 347: an accessor for (block_state_id & 0xF).
|
||||||
@property
|
@property
|
||||||
def blockMeta(self):
|
def blockMeta(self):
|
||||||
return self.block_state_id & 0xF
|
return self.block_state_id & 0xF
|
||||||
@ -48,13 +48,13 @@ class BlockChangePacket(Packet):
|
|||||||
class MultiBlockChangePacket(Packet):
|
class MultiBlockChangePacket(Packet):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x3B if context.protocol_version >= 741 else \
|
return 0x3B if context.protocol_later_eq(741) else \
|
||||||
0x0F if context.protocol_version >= 721 else \
|
0x0F if context.protocol_later_eq(721) else \
|
||||||
0x10 if context.protocol_version >= 550 else \
|
0x10 if context.protocol_later_eq(550) else \
|
||||||
0x0F if context.protocol_version >= 343 else \
|
0x0F if context.protocol_later_eq(343) else \
|
||||||
0x10 if context.protocol_version >= 332 else \
|
0x10 if context.protocol_later_eq(332) else \
|
||||||
0x11 if context.protocol_version >= 318 else \
|
0x11 if context.protocol_later_eq(318) else \
|
||||||
0x10 if context.protocol_version >= 67 else \
|
0x10 if context.protocol_later_eq(67) else \
|
||||||
0x22
|
0x22
|
||||||
|
|
||||||
packet_name = 'multi block change'
|
packet_name = 'multi block change'
|
||||||
@ -87,7 +87,7 @@ class MultiBlockChangePacket(Packet):
|
|||||||
# Access the 'x', 'y', 'z' fields as a Vector of ints.
|
# Access the 'x', 'y', 'z' fields as a Vector of ints.
|
||||||
position = multi_attribute_alias(Vector, 'x', 'y', 'z')
|
position = multi_attribute_alias(Vector, 'x', 'y', 'z')
|
||||||
|
|
||||||
# For protocols < 347: an accessor for (block_state_id >> 4).
|
# For protocols before 347: an accessor for (block_state_id >> 4).
|
||||||
@property
|
@property
|
||||||
def blockId(self):
|
def blockId(self):
|
||||||
return self.block_state_id >> 4
|
return self.block_state_id >> 4
|
||||||
@ -96,7 +96,7 @@ class MultiBlockChangePacket(Packet):
|
|||||||
def blockId(self, block_id):
|
def blockId(self, block_id):
|
||||||
self.block_state_id = self.block_state_id & 0xF | block_id << 4
|
self.block_state_id = self.block_state_id & 0xF | block_id << 4
|
||||||
|
|
||||||
# For protocols < 347: an accessor for (block_state_id & 0xF).
|
# For protocols before 347: an accessor for (block_state_id & 0xF).
|
||||||
@property
|
@property
|
||||||
def blockMeta(self):
|
def blockMeta(self):
|
||||||
return self.block_state_id & 0xF
|
return self.block_state_id & 0xF
|
||||||
@ -111,7 +111,7 @@ class MultiBlockChangePacket(Packet):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def read_with_context(cls, file_object, context):
|
def read_with_context(cls, file_object, context):
|
||||||
record = cls()
|
record = cls()
|
||||||
if context.protocol_version >= 741:
|
if context.protocol_later_eq(741):
|
||||||
value = VarLong.read(file_object)
|
value = VarLong.read(file_object)
|
||||||
record.block_state_id = value >> 12
|
record.block_state_id = value >> 12
|
||||||
record.x = (value >> 8) & 0xF
|
record.x = (value >> 8) & 0xF
|
||||||
@ -127,7 +127,7 @@ class MultiBlockChangePacket(Packet):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def send_with_context(self, record, socket, context):
|
def send_with_context(self, record, socket, context):
|
||||||
if context.protocol_version >= 741:
|
if context.protocol_later_eq(741):
|
||||||
value = record.block_state_id << 12 | \
|
value = record.block_state_id << 12 | \
|
||||||
(record.x & 0xF) << 8 | \
|
(record.x & 0xF) << 8 | \
|
||||||
(record.z & 0xF) << 4 | \
|
(record.z & 0xF) << 4 | \
|
||||||
@ -141,9 +141,9 @@ class MultiBlockChangePacket(Packet):
|
|||||||
get_definition = staticmethod(lambda context: [
|
get_definition = staticmethod(lambda context: [
|
||||||
{'chunk_section_pos': MultiBlockChangePacket.ChunkSectionPos},
|
{'chunk_section_pos': MultiBlockChangePacket.ChunkSectionPos},
|
||||||
{'invert_trust_edges': Boolean}
|
{'invert_trust_edges': Boolean}
|
||||||
if context.protocol_version >= 748 else {}, # Provisional field name.
|
if context.protocol_later_eq(748) else {}, # Provisional field name.
|
||||||
{'records': PrefixedArray(VarInt, MultiBlockChangePacket.Record)},
|
{'records': PrefixedArray(VarInt, MultiBlockChangePacket.Record)},
|
||||||
] if context.protocol_version >= 741 else [
|
] if context.protocol_later_eq(741) else [
|
||||||
{'chunk_x': Integer},
|
{'chunk_x': Integer},
|
||||||
{'chunk_z': Integer},
|
{'chunk_z': Integer},
|
||||||
{'records': PrefixedArray(VarInt, MultiBlockChangePacket.Record)},
|
{'records': PrefixedArray(VarInt, MultiBlockChangePacket.Record)},
|
||||||
|
@ -8,19 +8,19 @@ from minecraft.networking.types import (
|
|||||||
class CombatEventPacket(Packet):
|
class CombatEventPacket(Packet):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x31 if context.protocol_version >= 741 else \
|
return 0x31 if context.protocol_later_eq(741) else \
|
||||||
0x32 if context.protocol_version >= 721 else \
|
0x32 if context.protocol_later_eq(721) else \
|
||||||
0x33 if context.protocol_version >= 550 else \
|
0x33 if context.protocol_later_eq(550) else \
|
||||||
0x32 if context.protocol_version >= 471 else \
|
0x32 if context.protocol_later_eq(471) else \
|
||||||
0x30 if context.protocol_version >= 451 else \
|
0x30 if context.protocol_later_eq(451) else \
|
||||||
0x2F if context.protocol_version >= 389 else \
|
0x2F if context.protocol_later_eq(389) else \
|
||||||
0x2E if context.protocol_version >= 345 else \
|
0x2E if context.protocol_later_eq(345) else \
|
||||||
0x2D if context.protocol_version >= 336 else \
|
0x2D if context.protocol_later_eq(336) else \
|
||||||
0x2C if context.protocol_version >= 332 else \
|
0x2C if context.protocol_later_eq(332) else \
|
||||||
0x2D if context.protocol_version >= 318 else \
|
0x2D if context.protocol_later_eq(318) else \
|
||||||
0x2C if context.protocol_version >= 86 else \
|
0x2C if context.protocol_later_eq(86) else \
|
||||||
0x2D if context.protocol_version >= 80 else \
|
0x2D if context.protocol_later_eq(80) else \
|
||||||
0x2C if context.protocol_version >= 67 else \
|
0x2C if context.protocol_later_eq(67) else \
|
||||||
0x42
|
0x42
|
||||||
|
|
||||||
packet_name = 'combat event'
|
packet_name = 'combat event'
|
||||||
|
@ -7,16 +7,16 @@ from minecraft.networking.packets import Packet
|
|||||||
class ExplosionPacket(Packet):
|
class ExplosionPacket(Packet):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x1B if context.protocol_version >= 741 else \
|
return 0x1B if context.protocol_later_eq(741) else \
|
||||||
0x1C if context.protocol_version >= 721 else \
|
0x1C if context.protocol_later_eq(721) else \
|
||||||
0x1D if context.protocol_version >= 550 else \
|
0x1D if context.protocol_later_eq(550) else \
|
||||||
0x1C if context.protocol_version >= 471 else \
|
0x1C if context.protocol_later_eq(471) else \
|
||||||
0x1E if context.protocol_version >= 389 else \
|
0x1E if context.protocol_later_eq(389) else \
|
||||||
0x1D if context.protocol_version >= 345 else \
|
0x1D if context.protocol_later_eq(345) else \
|
||||||
0x1C if context.protocol_version >= 332 else \
|
0x1C if context.protocol_later_eq(332) else \
|
||||||
0x1D if context.protocol_version >= 318 else \
|
0x1D if context.protocol_later_eq(318) else \
|
||||||
0x1C if context.protocol_version >= 80 else \
|
0x1C if context.protocol_later_eq(80) else \
|
||||||
0x1B if context.protocol_version >= 67 else \
|
0x1B if context.protocol_later_eq(67) else \
|
||||||
0x27
|
0x27
|
||||||
|
|
||||||
packet_name = 'explosion'
|
packet_name = 'explosion'
|
||||||
|
@ -8,12 +8,12 @@ from minecraft.networking.packets import Packet
|
|||||||
class FacePlayerPacket(Packet):
|
class FacePlayerPacket(Packet):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x33 if context.protocol_version >= 741 else \
|
return 0x33 if context.protocol_later_eq(741) else \
|
||||||
0x34 if context.protocol_version >= 721 else \
|
0x34 if context.protocol_later_eq(721) else \
|
||||||
0x35 if context.protocol_version >= 550 else \
|
0x35 if context.protocol_later_eq(550) else \
|
||||||
0x34 if context.protocol_version >= 471 else \
|
0x34 if context.protocol_later_eq(471) else \
|
||||||
0x32 if context.protocol_version >= 451 else \
|
0x32 if context.protocol_later_eq(451) else \
|
||||||
0x31 if context.protocol_version >= 389 else \
|
0x31 if context.protocol_later_eq(389) else \
|
||||||
0x30
|
0x30
|
||||||
|
|
||||||
packet_name = 'face player'
|
packet_name = 'face player'
|
||||||
@ -21,14 +21,14 @@ class FacePlayerPacket(Packet):
|
|||||||
@property
|
@property
|
||||||
def fields(self):
|
def fields(self):
|
||||||
return ('origin', 'x', 'y', 'z', 'entity_id', 'entity_origin') \
|
return ('origin', 'x', 'y', 'z', 'entity_id', 'entity_origin') \
|
||||||
if self.context.protocol_version >= 353 else \
|
if self.context.protocol_later_eq(353) else \
|
||||||
('entity_id', 'x', 'y', 'z')
|
('entity_id', 'x', 'y', 'z')
|
||||||
|
|
||||||
# Access the 'x', 'y', 'z' fields as a Vector tuple.
|
# Access the 'x', 'y', 'z' fields as a Vector tuple.
|
||||||
target = multi_attribute_alias(Vector, 'x', 'y', 'z')
|
target = multi_attribute_alias(Vector, 'x', 'y', 'z')
|
||||||
|
|
||||||
def read(self, file_object):
|
def read(self, file_object):
|
||||||
if self.context.protocol_version >= 353:
|
if self.context.protocol_later_eq(353):
|
||||||
self.origin = VarInt.read(file_object)
|
self.origin = VarInt.read(file_object)
|
||||||
self.x = Double.read(file_object)
|
self.x = Double.read(file_object)
|
||||||
self.y = Double.read(file_object)
|
self.y = Double.read(file_object)
|
||||||
@ -51,7 +51,7 @@ class FacePlayerPacket(Packet):
|
|||||||
self.z = Double.read(file_object)
|
self.z = Double.read(file_object)
|
||||||
|
|
||||||
def write_fields(self, packet_buffer):
|
def write_fields(self, packet_buffer):
|
||||||
if self.context.protocol_version >= 353:
|
if self.context.protocol_later_eq(353):
|
||||||
VarInt.send(self.origin, packet_buffer)
|
VarInt.send(self.origin, packet_buffer)
|
||||||
Double.send(self.x, packet_buffer)
|
Double.send(self.x, packet_buffer)
|
||||||
Double.send(self.y, packet_buffer)
|
Double.send(self.y, packet_buffer)
|
||||||
|
@ -48,9 +48,9 @@ class AbstractDimensionPacket(Packet):
|
|||||||
'''
|
'''
|
||||||
def field_string(self, field):
|
def field_string(self, field):
|
||||||
# pylint: disable=no-member
|
# pylint: disable=no-member
|
||||||
if self.context.protocol_version >= 748 and field == 'dimension':
|
if self.context.protocol_later_eq(748) and field == 'dimension':
|
||||||
return nbt_to_snbt(self.dimension)
|
return nbt_to_snbt(self.dimension)
|
||||||
elif self.context.protocol_version < 718 and field == 'dimension':
|
elif self.context.protocol_earlier(718) and field == 'dimension':
|
||||||
return Dimension.name_from_value(self.dimension)
|
return Dimension.name_from_value(self.dimension)
|
||||||
return super(AbstractDimensionPacket, self).field_string(field)
|
return super(AbstractDimensionPacket, self).field_string(field)
|
||||||
|
|
||||||
@ -58,43 +58,43 @@ class AbstractDimensionPacket(Packet):
|
|||||||
class JoinGamePacket(AbstractDimensionPacket):
|
class JoinGamePacket(AbstractDimensionPacket):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x24 if context.protocol_version >= 741 else \
|
return 0x24 if context.protocol_later_eq(741) else \
|
||||||
0x25 if context.protocol_version >= 721 else \
|
0x25 if context.protocol_later_eq(721) else \
|
||||||
0x26 if context.protocol_version >= 550 else \
|
0x26 if context.protocol_later_eq(550) else \
|
||||||
0x25 if context.protocol_version >= 389 else \
|
0x25 if context.protocol_later_eq(389) else \
|
||||||
0x24 if context.protocol_version >= 345 else \
|
0x24 if context.protocol_later_eq(345) else \
|
||||||
0x23 if context.protocol_version >= 332 else \
|
0x23 if context.protocol_later_eq(332) else \
|
||||||
0x24 if context.protocol_version >= 318 else \
|
0x24 if context.protocol_later_eq(318) else \
|
||||||
0x23 if context.protocol_version >= 107 else \
|
0x23 if context.protocol_later_eq(107) else \
|
||||||
0x01
|
0x01
|
||||||
|
|
||||||
packet_name = "join game"
|
packet_name = "join game"
|
||||||
get_definition = staticmethod(lambda context: [
|
get_definition = staticmethod(lambda context: [
|
||||||
{'entity_id': Integer},
|
{'entity_id': Integer},
|
||||||
{'is_hardcore': Boolean} if context.protocol_version >= 738 else {},
|
{'is_hardcore': Boolean} if context.protocol_later_eq(738) else {},
|
||||||
{'game_mode': UnsignedByte},
|
{'game_mode': UnsignedByte},
|
||||||
{'previous_game_mode': UnsignedByte}
|
{'previous_game_mode': UnsignedByte}
|
||||||
if context.protocol_version >= 730 else {},
|
if context.protocol_later_eq(730) else {},
|
||||||
{'world_names': PrefixedArray(VarInt, String)}
|
{'world_names': PrefixedArray(VarInt, String)}
|
||||||
if context.protocol_version >= 722 else {},
|
if context.protocol_later_eq(722) else {},
|
||||||
{'dimension_codec': NBT}
|
{'dimension_codec': NBT}
|
||||||
if context.protocol_version >= 718 else {},
|
if context.protocol_later_eq(718) else {},
|
||||||
{'dimension':
|
{'dimension':
|
||||||
NBT if context.protocol_version >= 748 else
|
NBT if context.protocol_later_eq(748) else
|
||||||
String if context.protocol_version >= 718 else
|
String if context.protocol_later_eq(718) else
|
||||||
Integer if context.protocol_version >= 108 else
|
Integer if context.protocol_later_eq(108) else
|
||||||
Byte},
|
Byte},
|
||||||
{'world_name': String} if context.protocol_version >= 722 else {},
|
{'world_name': String} if context.protocol_later_eq(722) else {},
|
||||||
{'hashed_seed': Long} if context.protocol_version >= 552 else {},
|
{'hashed_seed': Long} if context.protocol_later_eq(552) else {},
|
||||||
{'difficulty': UnsignedByte} if context.protocol_version < 464 else {},
|
{'difficulty': UnsignedByte} if context.protocol_earlier(464) else {},
|
||||||
{'max_players':
|
{'max_players':
|
||||||
VarInt if context.protocol_version >= 749 else UnsignedByte},
|
VarInt if context.protocol_later_eq(749) else UnsignedByte},
|
||||||
{'level_type': String} if context.protocol_version < 716 else {},
|
{'level_type': String} if context.protocol_earlier(716) else {},
|
||||||
{'render_distance': VarInt} if context.protocol_version >= 468 else {},
|
{'render_distance': VarInt} if context.protocol_later_eq(468) else {},
|
||||||
{'reduced_debug_info': Boolean},
|
{'reduced_debug_info': Boolean},
|
||||||
{'respawn_screen': Boolean} if context.protocol_version >= 571 else {},
|
{'respawn_screen': Boolean} if context.protocol_later_eq(571) else {},
|
||||||
{'is_debug': Boolean} if context.protocol_version >= 716 else {},
|
{'is_debug': Boolean} if context.protocol_later_eq(716) else {},
|
||||||
{'is_flat': Boolean} if context.protocol_version >= 716 else {},
|
{'is_flat': Boolean} if context.protocol_later_eq(716) else {},
|
||||||
])
|
])
|
||||||
|
|
||||||
# These aliases declare the Enum type corresponding to each field:
|
# These aliases declare the Enum type corresponding to each field:
|
||||||
@ -105,7 +105,7 @@ class JoinGamePacket(AbstractDimensionPacket):
|
|||||||
# Can be set or deleted when 'context' is undefined.
|
# Can be set or deleted when 'context' is undefined.
|
||||||
@property
|
@property
|
||||||
def game_mode(self):
|
def game_mode(self):
|
||||||
if self.context.protocol_version >= 738:
|
if self.context.protocol_later_eq(738):
|
||||||
return self._game_mode_738
|
return self._game_mode_738
|
||||||
else:
|
else:
|
||||||
return self._game_mode_0
|
return self._game_mode_0
|
||||||
@ -124,7 +124,7 @@ class JoinGamePacket(AbstractDimensionPacket):
|
|||||||
# Can be set or deleted when 'context' is undefined.
|
# Can be set or deleted when 'context' is undefined.
|
||||||
@property
|
@property
|
||||||
def is_hardcore(self):
|
def is_hardcore(self):
|
||||||
if self.context.protocol_version >= 738:
|
if self.context.protocol_later_eq(738):
|
||||||
return self._is_hardcore
|
return self._is_hardcore
|
||||||
else:
|
else:
|
||||||
return bool(self._game_mode_0 & GameMode.HARDCORE)
|
return bool(self._game_mode_0 & GameMode.HARDCORE)
|
||||||
@ -148,7 +148,7 @@ class JoinGamePacket(AbstractDimensionPacket):
|
|||||||
# version-independently. Can be set or deleted when 'context' is undefined.
|
# version-independently. Can be set or deleted when 'context' is undefined.
|
||||||
@property
|
@property
|
||||||
def pure_game_mode(self):
|
def pure_game_mode(self):
|
||||||
if self.context.protocol_version >= 738:
|
if self.context.protocol_later_eq(738):
|
||||||
return self._game_mode_738
|
return self._game_mode_738
|
||||||
else:
|
else:
|
||||||
return self._game_mode_0 & ~GameMode.HARDCORE
|
return self._game_mode_0 & ~GameMode.HARDCORE
|
||||||
@ -170,37 +170,37 @@ class JoinGamePacket(AbstractDimensionPacket):
|
|||||||
class RespawnPacket(AbstractDimensionPacket):
|
class RespawnPacket(AbstractDimensionPacket):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x39 if context.protocol_version >= 741 else \
|
return 0x39 if context.protocol_later_eq(741) else \
|
||||||
0x3A if context.protocol_version >= 721 else \
|
0x3A if context.protocol_later_eq(721) else \
|
||||||
0x3B if context.protocol_version >= 550 else \
|
0x3B if context.protocol_later_eq(550) else \
|
||||||
0x3A if context.protocol_version >= 471 else \
|
0x3A if context.protocol_later_eq(471) else \
|
||||||
0x38 if context.protocol_version >= 461 else \
|
0x38 if context.protocol_later_eq(461) else \
|
||||||
0x39 if context.protocol_version >= 451 else \
|
0x39 if context.protocol_later_eq(451) else \
|
||||||
0x38 if context.protocol_version >= 389 else \
|
0x38 if context.protocol_later_eq(389) else \
|
||||||
0x37 if context.protocol_version >= 352 else \
|
0x37 if context.protocol_later_eq(352) else \
|
||||||
0x36 if context.protocol_version >= 345 else \
|
0x36 if context.protocol_later_eq(345) else \
|
||||||
0x35 if context.protocol_version >= 336 else \
|
0x35 if context.protocol_later_eq(336) else \
|
||||||
0x34 if context.protocol_version >= 332 else \
|
0x34 if context.protocol_later_eq(332) else \
|
||||||
0x35 if context.protocol_version >= 318 else \
|
0x35 if context.protocol_later_eq(318) else \
|
||||||
0x33 if context.protocol_version >= 70 else \
|
0x33 if context.protocol_later_eq(70) else \
|
||||||
0x07
|
0x07
|
||||||
|
|
||||||
packet_name = 'respawn'
|
packet_name = 'respawn'
|
||||||
get_definition = staticmethod(lambda context: [
|
get_definition = staticmethod(lambda context: [
|
||||||
{'dimension':
|
{'dimension':
|
||||||
NBT if context.protocol_version >= 748 else
|
NBT if context.protocol_later_eq(748) else
|
||||||
String if context.protocol_version >= 718 else
|
String if context.protocol_later_eq(718) else
|
||||||
Integer},
|
Integer},
|
||||||
{'world_name': String} if context.protocol_version >= 719 else {},
|
{'world_name': String} if context.protocol_later_eq(719) else {},
|
||||||
{'difficulty': UnsignedByte} if context.protocol_version < 464 else {},
|
{'difficulty': UnsignedByte} if context.protocol_earlier(464) else {},
|
||||||
{'hashed_seed': Long} if context.protocol_version >= 552 else {},
|
{'hashed_seed': Long} if context.protocol_later_eq(552) else {},
|
||||||
{'game_mode': UnsignedByte},
|
{'game_mode': UnsignedByte},
|
||||||
{'previous_game_mode': UnsignedByte}
|
{'previous_game_mode': UnsignedByte}
|
||||||
if context.protocol_version >= 730 else {},
|
if context.protocol_later_eq(730) else {},
|
||||||
{'level_type': String} if context.protocol_version < 716 else {},
|
{'level_type': String} if context.protocol_earlier(716) else {},
|
||||||
{'is_debug': Boolean} if context.protocol_version >= 716 else {},
|
{'is_debug': Boolean} if context.protocol_later_eq(716) else {},
|
||||||
{'is_flat': Boolean} if context.protocol_version >= 716 else {},
|
{'is_flat': Boolean} if context.protocol_later_eq(716) else {},
|
||||||
{'copy_metadata': Boolean} if context.protocol_version >= 714 else {},
|
{'copy_metadata': Boolean} if context.protocol_later_eq(714) else {},
|
||||||
])
|
])
|
||||||
|
|
||||||
# These aliases declare the Enum type corresponding to each field:
|
# These aliases declare the Enum type corresponding to each field:
|
||||||
|
@ -8,14 +8,14 @@ from minecraft.networking.types import (
|
|||||||
class MapPacket(Packet):
|
class MapPacket(Packet):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x25 if context.protocol_version >= 741 else \
|
return 0x25 if context.protocol_later_eq(741) else \
|
||||||
0x26 if context.protocol_version >= 721 else \
|
0x26 if context.protocol_later_eq(721) else \
|
||||||
0x27 if context.protocol_version >= 550 else \
|
0x27 if context.protocol_later_eq(550) else \
|
||||||
0x26 if context.protocol_version >= 389 else \
|
0x26 if context.protocol_later_eq(389) else \
|
||||||
0x25 if context.protocol_version >= 345 else \
|
0x25 if context.protocol_later_eq(345) else \
|
||||||
0x24 if context.protocol_version >= 334 else \
|
0x24 if context.protocol_later_eq(334) else \
|
||||||
0x25 if context.protocol_version >= 318 else \
|
0x25 if context.protocol_later_eq(318) else \
|
||||||
0x24 if context.protocol_version >= 107 else \
|
0x24 if context.protocol_later_eq(107) else \
|
||||||
0x34
|
0x34
|
||||||
|
|
||||||
packet_name = 'map'
|
packet_name = 'map'
|
||||||
@ -23,9 +23,9 @@ class MapPacket(Packet):
|
|||||||
@property
|
@property
|
||||||
def fields(self):
|
def fields(self):
|
||||||
fields = 'id', 'scale', 'icons', 'width', 'height', 'pixels'
|
fields = 'id', 'scale', 'icons', 'width', 'height', 'pixels'
|
||||||
if self.context.protocol_version >= 107:
|
if self.context.protocol_later_eq(107):
|
||||||
fields += 'is_tracking_position',
|
fields += 'is_tracking_position',
|
||||||
if self.context.protocol_version >= 452:
|
if self.context.protocol_later_eq(452):
|
||||||
fields += 'is_locked',
|
fields += 'is_locked',
|
||||||
return fields
|
return fields
|
||||||
|
|
||||||
@ -71,12 +71,12 @@ class MapPacket(Packet):
|
|||||||
self.map_id = VarInt.read(file_object)
|
self.map_id = VarInt.read(file_object)
|
||||||
self.scale = Byte.read(file_object)
|
self.scale = Byte.read(file_object)
|
||||||
|
|
||||||
if self.context.protocol_version >= 107:
|
if self.context.protocol_later_eq(107):
|
||||||
self.is_tracking_position = Boolean.read(file_object)
|
self.is_tracking_position = Boolean.read(file_object)
|
||||||
else:
|
else:
|
||||||
self.is_tracking_position = True
|
self.is_tracking_position = True
|
||||||
|
|
||||||
if self.context.protocol_version >= 452:
|
if self.context.protocol_later_eq(452):
|
||||||
self.is_locked = Boolean.read(file_object)
|
self.is_locked = Boolean.read(file_object)
|
||||||
else:
|
else:
|
||||||
self.is_locked = False
|
self.is_locked = False
|
||||||
@ -84,15 +84,15 @@ class MapPacket(Packet):
|
|||||||
icon_count = VarInt.read(file_object)
|
icon_count = VarInt.read(file_object)
|
||||||
self.icons = []
|
self.icons = []
|
||||||
for i in range(icon_count):
|
for i in range(icon_count):
|
||||||
if self.context.protocol_version >= 373:
|
if self.context.protocol_later_eq(373):
|
||||||
type = VarInt.read(file_object)
|
type = VarInt.read(file_object)
|
||||||
else:
|
else:
|
||||||
type, direction = divmod(UnsignedByte.read(file_object), 16)
|
type, direction = divmod(UnsignedByte.read(file_object), 16)
|
||||||
x = Byte.read(file_object)
|
x = Byte.read(file_object)
|
||||||
z = Byte.read(file_object)
|
z = Byte.read(file_object)
|
||||||
if self.context.protocol_version >= 373:
|
if self.context.protocol_later_eq(373):
|
||||||
direction = UnsignedByte.read(file_object)
|
direction = UnsignedByte.read(file_object)
|
||||||
if self.context.protocol_version >= 364:
|
if self.context.protocol_later_eq(364):
|
||||||
has_name = Boolean.read(file_object)
|
has_name = Boolean.read(file_object)
|
||||||
display_name = String.read(file_object) if has_name else None
|
display_name = String.read(file_object) if has_name else None
|
||||||
else:
|
else:
|
||||||
@ -134,12 +134,12 @@ class MapPacket(Packet):
|
|||||||
def write_fields(self, packet_buffer):
|
def write_fields(self, packet_buffer):
|
||||||
VarInt.send(self.map_id, packet_buffer)
|
VarInt.send(self.map_id, packet_buffer)
|
||||||
Byte.send(self.scale, packet_buffer)
|
Byte.send(self.scale, packet_buffer)
|
||||||
if self.context.protocol_version >= 107:
|
if self.context.protocol_later_eq(107):
|
||||||
Boolean.send(self.is_tracking_position, packet_buffer)
|
Boolean.send(self.is_tracking_position, packet_buffer)
|
||||||
|
|
||||||
VarInt.send(len(self.icons), packet_buffer)
|
VarInt.send(len(self.icons), packet_buffer)
|
||||||
for icon in self.icons:
|
for icon in self.icons:
|
||||||
if self.context.protocol_version >= 373:
|
if self.context.protocol_later_eq(373):
|
||||||
VarInt.send(icon.type, packet_buffer)
|
VarInt.send(icon.type, packet_buffer)
|
||||||
else:
|
else:
|
||||||
type_and_direction = (icon.type << 4) & 0xF0
|
type_and_direction = (icon.type << 4) & 0xF0
|
||||||
@ -147,9 +147,9 @@ class MapPacket(Packet):
|
|||||||
UnsignedByte.send(type_and_direction, packet_buffer)
|
UnsignedByte.send(type_and_direction, packet_buffer)
|
||||||
Byte.send(icon.location[0], packet_buffer)
|
Byte.send(icon.location[0], packet_buffer)
|
||||||
Byte.send(icon.location[1], packet_buffer)
|
Byte.send(icon.location[1], packet_buffer)
|
||||||
if self.context.protocol_version >= 373:
|
if self.context.protocol_later_eq(373):
|
||||||
UnsignedByte.send(icon.direction, packet_buffer)
|
UnsignedByte.send(icon.direction, packet_buffer)
|
||||||
if self.context.protocol_version >= 364:
|
if self.context.protocol_later_eq(364):
|
||||||
Boolean.send(icon.display_name is not None, packet_buffer)
|
Boolean.send(icon.display_name is not None, packet_buffer)
|
||||||
if icon.display_name is not None:
|
if icon.display_name is not None:
|
||||||
String.send(icon.display_name, packet_buffer)
|
String.send(icon.display_name, packet_buffer)
|
||||||
|
@ -9,17 +9,17 @@ from minecraft.networking.types import (
|
|||||||
class PlayerListItemPacket(Packet):
|
class PlayerListItemPacket(Packet):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x32 if context.protocol_version >= 741 else \
|
return 0x32 if context.protocol_later_eq(741) else \
|
||||||
0x33 if context.protocol_version >= 721 else \
|
0x33 if context.protocol_later_eq(721) else \
|
||||||
0x34 if context.protocol_version >= 550 else \
|
0x34 if context.protocol_later_eq(550) else \
|
||||||
0x33 if context.protocol_version >= 471 else \
|
0x33 if context.protocol_later_eq(471) else \
|
||||||
0x31 if context.protocol_version >= 451 else \
|
0x31 if context.protocol_later_eq(451) else \
|
||||||
0x30 if context.protocol_version >= 389 else \
|
0x30 if context.protocol_later_eq(389) else \
|
||||||
0x2F if context.protocol_version >= 345 else \
|
0x2F if context.protocol_later_eq(345) else \
|
||||||
0x2E if context.protocol_version >= 336 else \
|
0x2E if context.protocol_later_eq(336) else \
|
||||||
0x2D if context.protocol_version >= 332 else \
|
0x2D if context.protocol_later_eq(332) else \
|
||||||
0x2E if context.protocol_version >= 318 else \
|
0x2E if context.protocol_later_eq(318) else \
|
||||||
0x2D if context.protocol_version >= 107 else \
|
0x2D if context.protocol_later_eq(107) else \
|
||||||
0x38
|
0x38
|
||||||
|
|
||||||
packet_name = "player list item"
|
packet_name = "player list item"
|
||||||
|
@ -9,18 +9,18 @@ from minecraft.networking.types import (
|
|||||||
class PlayerPositionAndLookPacket(Packet, BitFieldEnum):
|
class PlayerPositionAndLookPacket(Packet, BitFieldEnum):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x34 if context.protocol_version >= 741 else \
|
return 0x34 if context.protocol_later_eq(741) else \
|
||||||
0x35 if context.protocol_version >= 721 else \
|
0x35 if context.protocol_later_eq(721) else \
|
||||||
0x36 if context.protocol_version >= 550 else \
|
0x36 if context.protocol_later_eq(550) else \
|
||||||
0x35 if context.protocol_version >= 471 else \
|
0x35 if context.protocol_later_eq(471) else \
|
||||||
0x33 if context.protocol_version >= 451 else \
|
0x33 if context.protocol_later_eq(451) else \
|
||||||
0x32 if context.protocol_version >= 389 else \
|
0x32 if context.protocol_later_eq(389) else \
|
||||||
0x31 if context.protocol_version >= 352 else \
|
0x31 if context.protocol_later_eq(352) else \
|
||||||
0x30 if context.protocol_version >= 345 else \
|
0x30 if context.protocol_later_eq(345) else \
|
||||||
0x2F if context.protocol_version >= 336 else \
|
0x2F if context.protocol_later_eq(336) else \
|
||||||
0x2E if context.protocol_version >= 332 else \
|
0x2E if context.protocol_later_eq(332) else \
|
||||||
0x2F if context.protocol_version >= 318 else \
|
0x2F if context.protocol_later_eq(318) else \
|
||||||
0x2E if context.protocol_version >= 70 else \
|
0x2E if context.protocol_later_eq(70) else \
|
||||||
0x08
|
0x08
|
||||||
|
|
||||||
packet_name = "player position and look"
|
packet_name = "player position and look"
|
||||||
@ -31,7 +31,7 @@ class PlayerPositionAndLookPacket(Packet, BitFieldEnum):
|
|||||||
{'yaw': Float},
|
{'yaw': Float},
|
||||||
{'pitch': Float},
|
{'pitch': Float},
|
||||||
{'flags': Byte},
|
{'flags': Byte},
|
||||||
{'teleport_id': VarInt} if context.protocol_version >= 107 else {},
|
{'teleport_id': VarInt} if context.protocol_later_eq(107) else {},
|
||||||
])
|
])
|
||||||
|
|
||||||
# Access the 'x', 'y', 'z' fields as a Vector tuple.
|
# Access the 'x', 'y', 'z' fields as a Vector tuple.
|
||||||
|
@ -9,18 +9,18 @@ __all__ = 'SoundEffectPacket',
|
|||||||
class SoundEffectPacket(Packet):
|
class SoundEffectPacket(Packet):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x51 if context.protocol_version >= 721 else \
|
return 0x51 if context.protocol_later_eq(721) else \
|
||||||
0x52 if context.protocol_version >= 550 else \
|
0x52 if context.protocol_later_eq(550) else \
|
||||||
0x51 if context.protocol_version >= 471 else \
|
0x51 if context.protocol_later_eq(471) else \
|
||||||
0x4D if context.protocol_version >= 461 else \
|
0x4D if context.protocol_later_eq(461) else \
|
||||||
0x4E if context.protocol_version >= 451 else \
|
0x4E if context.protocol_later_eq(451) else \
|
||||||
0x4D if context.protocol_version >= 389 else \
|
0x4D if context.protocol_later_eq(389) else \
|
||||||
0x4C if context.protocol_version >= 352 else \
|
0x4C if context.protocol_later_eq(352) else \
|
||||||
0x4B if context.protocol_version >= 345 else \
|
0x4B if context.protocol_later_eq(345) else \
|
||||||
0x4A if context.protocol_version >= 343 else \
|
0x4A if context.protocol_later_eq(343) else \
|
||||||
0x49 if context.protocol_version >= 336 else \
|
0x49 if context.protocol_later_eq(336) else \
|
||||||
0x48 if context.protocol_version >= 318 else \
|
0x48 if context.protocol_later_eq(318) else \
|
||||||
0x46 if context.protocol_version >= 110 else \
|
0x46 if context.protocol_later_eq(110) else \
|
||||||
0x47
|
0x47
|
||||||
|
|
||||||
packet_name = 'sound effect'
|
packet_name = 'sound effect'
|
||||||
@ -29,13 +29,16 @@ class SoundEffectPacket(Packet):
|
|||||||
def get_definition(context):
|
def get_definition(context):
|
||||||
return [
|
return [
|
||||||
({'sound_category': VarInt}
|
({'sound_category': VarInt}
|
||||||
if 326 > context.protocol_version >= 321 else {}),
|
if context.protocol_later_eq(321)
|
||||||
|
and context.protocol_earlier(326) else {}),
|
||||||
{'sound_id': VarInt},
|
{'sound_id': VarInt},
|
||||||
({'sound_category': VarInt}
|
({'sound_category': VarInt}
|
||||||
if 95 <= context.protocol_version < 321
|
if context.protocol_later_eq(95)
|
||||||
or context.protocol_version >= 326 else {}),
|
and context.protocol_earlier(321)
|
||||||
|
or context.protocol_later_eq(326) else {}),
|
||||||
({'parroted_entity_type': String}
|
({'parroted_entity_type': String}
|
||||||
if 326 > context.protocol_version >= 321 else {}),
|
if context.protocol_later_eq(321)
|
||||||
|
and context.protocol_earlier(326) else {}),
|
||||||
{'effect_position': SoundEffectPacket.EffectPosition},
|
{'effect_position': SoundEffectPacket.EffectPosition},
|
||||||
{'volume': Float},
|
{'volume': Float},
|
||||||
{'pitch': SoundEffectPacket.Pitch},
|
{'pitch': SoundEffectPacket.Pitch},
|
||||||
@ -66,19 +69,19 @@ class SoundEffectPacket(Packet):
|
|||||||
class Pitch(Type):
|
class Pitch(Type):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def read_with_context(file_object, context):
|
def read_with_context(file_object, context):
|
||||||
if context.protocol_version >= 201:
|
if context.protocol_later_eq(201):
|
||||||
value = Float.read(file_object)
|
value = Float.read(file_object)
|
||||||
else:
|
else:
|
||||||
value = Byte.read(file_object)
|
value = Byte.read(file_object)
|
||||||
if context.protocol_version < 204:
|
if context.protocol_earlier(204):
|
||||||
value /= 63.5
|
value /= 63.5
|
||||||
return value
|
return value
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def send_with_context(value, socket, context):
|
def send_with_context(value, socket, context):
|
||||||
if context.protocol_version < 204:
|
if context.protocol_earlier(204):
|
||||||
value *= 63.5
|
value *= 63.5
|
||||||
if context.protocol_version >= 201:
|
if context.protocol_later_eq(201):
|
||||||
Float.send(value, socket)
|
Float.send(value, socket)
|
||||||
else:
|
else:
|
||||||
Byte.send(int(value), socket)
|
Byte.send(int(value), socket)
|
||||||
|
@ -10,7 +10,7 @@ from minecraft.networking.types import (
|
|||||||
class SpawnObjectPacket(Packet):
|
class SpawnObjectPacket(Packet):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x00 if context.protocol_version >= 67 else \
|
return 0x00 if context.protocol_later_eq(67) else \
|
||||||
0x0E
|
0x0E
|
||||||
|
|
||||||
packet_name = 'spawn object'
|
packet_name = 'spawn object'
|
||||||
@ -43,43 +43,44 @@ class SpawnObjectPacket(Packet):
|
|||||||
if field != 'type_id' or context is None:
|
if field != 'type_id' or context is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
pv = context.protocol_version
|
name = 'EntityType_%d' % context.protocol_version
|
||||||
name = 'EntityType_%d' % pv
|
|
||||||
if hasattr(cls, name):
|
if hasattr(cls, name):
|
||||||
return getattr(cls, name)
|
return getattr(cls, name)
|
||||||
|
|
||||||
|
era = 0 if context.protocol_earlier(458) else 1
|
||||||
|
|
||||||
class EntityType(Enum):
|
class EntityType(Enum):
|
||||||
# XXX This has not been updated for >= v1.15
|
# XXX This has not been updated for >= v1.15
|
||||||
ACTIVATED_TNT = 50 if pv < 458 else 55 # PrimedTnt
|
ACTIVATED_TNT = (50, 55)[era] # PrimedTnt
|
||||||
AREA_EFFECT_CLOUD = 3 if pv < 458 else 0
|
AREA_EFFECT_CLOUD = ( 3, 0)[era]
|
||||||
ARMORSTAND = 78 if pv < 458 else 1
|
ARMORSTAND = (78, 1)[era]
|
||||||
ARROW = 60 if pv < 458 else 2
|
ARROW = (60, 2)[era]
|
||||||
BOAT = 1 if pv < 458 else 5
|
BOAT = ( 1, 5)[era]
|
||||||
DRAGON_FIREBALL = 93 if pv < 458 else 13
|
DRAGON_FIREBALL = (93, 13)[era]
|
||||||
EGG = 62 if pv < 458 else 74 # ThrownEgg
|
EGG = (62, 74)[era] # ThrownEgg
|
||||||
ENDERCRYSTAL = 51 if pv < 458 else 16
|
ENDERCRYSTAL = (51, 16)[era]
|
||||||
ENDERPEARL = 65 if pv < 458 else 75 # ThrownEnderpearl
|
ENDERPEARL = (65, 75)[era] # ThrownEnderpearl
|
||||||
EVOCATION_FANGS = 79 if pv < 458 else 20
|
EVOCATION_FANGS = (79, 20)[era]
|
||||||
EXP_BOTTLE = 75 if pv < 458 else 76 # ThrownExpBottle
|
EXP_BOTTLE = (75, 76)[era] # ThrownExpBottle
|
||||||
EYE_OF_ENDER = 72 if pv < 458 else 23 # EyeOfEnderSignal
|
EYE_OF_ENDER = (72, 23)[era] # EyeOfEnderSignal
|
||||||
FALLING_OBJECT = 70 if pv < 458 else 24 # FallingSand
|
FALLING_OBJECT = (70, 24)[era] # FallingSand
|
||||||
FIREBALL = 63 if pv < 458 else 34 # Fireball (ghast)
|
FIREBALL = (63, 34)[era] # Fireball (ghast)
|
||||||
FIRECHARGE = 64 if pv < 458 else 65 # SmallFireball (blaze)
|
FIRECHARGE = (64, 65)[era] # SmallFireball (blaze)
|
||||||
FIREWORK_ROCKET = 76 if pv < 458 else 25 # FireworksRocketEntity
|
FIREWORK_ROCKET = (76, 25)[era] # FireworksRocketEntity
|
||||||
FISHING_HOOK = 90 if pv < 458 else 93 # Fishing bobber
|
FISHING_HOOK = (90, 93)[era] # Fishing bobber
|
||||||
ITEM_FRAMES = 71 if pv < 458 else 33 # ItemFrame
|
ITEM_FRAMES = (71, 33)[era] # ItemFrame
|
||||||
ITEM_STACK = 2 if pv < 458 else 32 # Item
|
ITEM_STACK = ( 2, 32)[era] # Item
|
||||||
LEASH_KNOT = 77 if pv < 458 else 35
|
LEASH_KNOT = (77, 35)[era]
|
||||||
LLAMA_SPIT = 68 if pv < 458 else 37
|
LLAMA_SPIT = (68, 37)[era]
|
||||||
MINECART = 10 if pv < 458 else 39 # MinecartRideable
|
MINECART = (10, 39)[era] # MinecartRideable
|
||||||
POTION = 73 if pv < 458 else 77 # ThrownPotion
|
POTION = (73, 77)[era] # ThrownPotion
|
||||||
SHULKER_BULLET = 67 if pv < 458 else 60
|
SHULKER_BULLET = (67, 60)[era]
|
||||||
SNOWBALL = 61 if pv < 458 else 67
|
SNOWBALL = (61, 67)[era]
|
||||||
SPECTRAL_ARROW = 91 if pv < 458 else 68
|
SPECTRAL_ARROW = (91, 68)[era]
|
||||||
WITHER_SKULL = 66 if pv < 458 else 85
|
WITHER_SKULL = (66, 85)[era]
|
||||||
if pv >= 393:
|
if context.protocol_later_eq(393):
|
||||||
TRIDENT = 94
|
TRIDENT = 94
|
||||||
if pv >= 458:
|
if context.protocol_later_eq(458):
|
||||||
MINECART_CHEST = 40
|
MINECART_CHEST = 40
|
||||||
MINECART_COMMAND_BLOCK = 41
|
MINECART_COMMAND_BLOCK = 41
|
||||||
MINECART_FURNACE = 42
|
MINECART_FURNACE = 42
|
||||||
@ -92,44 +93,44 @@ class SpawnObjectPacket(Packet):
|
|||||||
|
|
||||||
def read(self, file_object):
|
def read(self, file_object):
|
||||||
self.entity_id = VarInt.read(file_object)
|
self.entity_id = VarInt.read(file_object)
|
||||||
if self.context.protocol_version >= 49:
|
if self.context.protocol_later_eq(49):
|
||||||
self.object_uuid = UUID.read(file_object)
|
self.object_uuid = UUID.read(file_object)
|
||||||
|
|
||||||
if self.context.protocol_version >= 458:
|
if self.context.protocol_later_eq(458):
|
||||||
self.type_id = VarInt.read(file_object)
|
self.type_id = VarInt.read(file_object)
|
||||||
else:
|
else:
|
||||||
self.type_id = Byte.read(file_object)
|
self.type_id = Byte.read(file_object)
|
||||||
|
|
||||||
xyz_type = Double if self.context.protocol_version >= 100 else Integer
|
xyz_type = Double if self.context.protocol_later_eq(100) else Integer
|
||||||
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, Angle.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_later_eq(49) or self.data > 0:
|
||||||
for attr in 'velocity_x', 'velocity_y', 'velocity_z':
|
for attr in 'velocity_x', 'velocity_y', 'velocity_z':
|
||||||
setattr(self, attr, Short.read(file_object))
|
setattr(self, attr, Short.read(file_object))
|
||||||
|
|
||||||
def write_fields(self, packet_buffer):
|
def write_fields(self, packet_buffer):
|
||||||
VarInt.send(self.entity_id, packet_buffer)
|
VarInt.send(self.entity_id, packet_buffer)
|
||||||
if self.context.protocol_version >= 49:
|
if self.context.protocol_later_eq(49):
|
||||||
UUID.send(self.object_uuid, packet_buffer)
|
UUID.send(self.object_uuid, packet_buffer)
|
||||||
|
|
||||||
if self.context.protocol_version >= 458:
|
if self.context.protocol_later_eq(458):
|
||||||
VarInt.send(self.type_id, packet_buffer)
|
VarInt.send(self.type_id, packet_buffer)
|
||||||
else:
|
else:
|
||||||
Byte.send(self.type_id, packet_buffer)
|
Byte.send(self.type_id, packet_buffer)
|
||||||
|
|
||||||
# pylint: disable=no-member
|
# pylint: disable=no-member
|
||||||
xyz_type = Double if self.context.protocol_version >= 100 else Integer
|
xyz_type = Double if self.context.protocol_later_eq(100) else Integer
|
||||||
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:
|
||||||
Angle.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_later_eq(49) or self.data > 0:
|
||||||
for coord in self.velocity_x, self.velocity_y, self.velocity_z:
|
for coord in self.velocity_x, self.velocity_y, self.velocity_z:
|
||||||
Short.send(coord, packet_buffer)
|
Short.send(coord, packet_buffer)
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ from minecraft.networking.types import (
|
|||||||
class AbstractKeepAlivePacket(Packet):
|
class AbstractKeepAlivePacket(Packet):
|
||||||
packet_name = "keep alive"
|
packet_name = "keep alive"
|
||||||
get_definition = staticmethod(lambda context: [
|
get_definition = staticmethod(lambda context: [
|
||||||
{'keep_alive_id': Long} if context.protocol_version >= 339
|
{'keep_alive_id': Long} if context.protocol_later_eq(339)
|
||||||
else {'keep_alive_id': VarInt}
|
else {'keep_alive_id': VarInt}
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ def get_packets(context):
|
|||||||
LoginStartPacket,
|
LoginStartPacket,
|
||||||
EncryptionResponsePacket
|
EncryptionResponsePacket
|
||||||
}
|
}
|
||||||
if context.protocol_version >= 385:
|
if context.protocol_later_eq(385):
|
||||||
packets |= {
|
packets |= {
|
||||||
PluginResponsePacket
|
PluginResponsePacket
|
||||||
}
|
}
|
||||||
@ -21,8 +21,8 @@ def get_packets(context):
|
|||||||
class LoginStartPacket(Packet):
|
class LoginStartPacket(Packet):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x00 if context.protocol_version >= 391 else \
|
return 0x00 if context.protocol_later_eq(391) else \
|
||||||
0x01 if context.protocol_version >= 385 else \
|
0x01 if context.protocol_later_eq(385) else \
|
||||||
0x00
|
0x00
|
||||||
|
|
||||||
packet_name = "login start"
|
packet_name = "login start"
|
||||||
@ -33,8 +33,8 @@ class LoginStartPacket(Packet):
|
|||||||
class EncryptionResponsePacket(Packet):
|
class EncryptionResponsePacket(Packet):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x01 if context.protocol_version >= 391 else \
|
return 0x01 if context.protocol_later_eq(391) else \
|
||||||
0x02 if context.protocol_version >= 385 else \
|
0x02 if context.protocol_later_eq(385) else \
|
||||||
0x01
|
0x01
|
||||||
|
|
||||||
packet_name = "encryption response"
|
packet_name = "encryption response"
|
||||||
@ -50,7 +50,7 @@ class PluginResponsePacket(Packet):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x02 if context.protocol_version >= 391 else \
|
return 0x02 if context.protocol_later_eq(391) else \
|
||||||
0x00
|
0x00
|
||||||
|
|
||||||
packet_name = 'login plugin response'
|
packet_name = 'login plugin response'
|
||||||
|
@ -23,11 +23,11 @@ def get_packets(context):
|
|||||||
PluginMessagePacket,
|
PluginMessagePacket,
|
||||||
PlayerBlockPlacementPacket,
|
PlayerBlockPlacementPacket,
|
||||||
}
|
}
|
||||||
if context.protocol_version >= 69:
|
if context.protocol_later_eq(69):
|
||||||
packets |= {
|
packets |= {
|
||||||
UseItemPacket,
|
UseItemPacket,
|
||||||
}
|
}
|
||||||
if context.protocol_version >= 107:
|
if context.protocol_later_eq(107):
|
||||||
packets |= {
|
packets |= {
|
||||||
TeleportConfirmPacket,
|
TeleportConfirmPacket,
|
||||||
}
|
}
|
||||||
@ -37,33 +37,33 @@ def get_packets(context):
|
|||||||
class KeepAlivePacket(AbstractKeepAlivePacket):
|
class KeepAlivePacket(AbstractKeepAlivePacket):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x10 if context.protocol_version >= 712 else \
|
return 0x10 if context.protocol_later_eq(712) else \
|
||||||
0x0F if context.protocol_version >= 471 else \
|
0x0F if context.protocol_later_eq(471) else \
|
||||||
0x10 if context.protocol_version >= 464 else \
|
0x10 if context.protocol_later_eq(464) else \
|
||||||
0x0E if context.protocol_version >= 389 else \
|
0x0E if context.protocol_later_eq(389) else \
|
||||||
0x0C if context.protocol_version >= 386 else \
|
0x0C if context.protocol_later_eq(386) else \
|
||||||
0x0B if context.protocol_version >= 345 else \
|
0x0B if context.protocol_later_eq(345) else \
|
||||||
0x0A if context.protocol_version >= 343 else \
|
0x0A if context.protocol_later_eq(343) else \
|
||||||
0x0B if context.protocol_version >= 336 else \
|
0x0B if context.protocol_later_eq(336) else \
|
||||||
0x0C if context.protocol_version >= 318 else \
|
0x0C if context.protocol_later_eq(318) else \
|
||||||
0x0B if context.protocol_version >= 107 else \
|
0x0B if context.protocol_later_eq(107) else \
|
||||||
0x00
|
0x00
|
||||||
|
|
||||||
|
|
||||||
class ChatPacket(Packet):
|
class ChatPacket(Packet):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x03 if context.protocol_version >= 464 else \
|
return 0x03 if context.protocol_later_eq(464) else \
|
||||||
0x02 if context.protocol_version >= 389 else \
|
0x02 if context.protocol_later_eq(389) else \
|
||||||
0x01 if context.protocol_version >= 343 else \
|
0x01 if context.protocol_later_eq(343) else \
|
||||||
0x02 if context.protocol_version >= 336 else \
|
0x02 if context.protocol_later_eq(336) else \
|
||||||
0x03 if context.protocol_version >= 318 else \
|
0x03 if context.protocol_later_eq(318) else \
|
||||||
0x02 if context.protocol_version >= 107 else \
|
0x02 if context.protocol_later_eq(107) else \
|
||||||
0x01
|
0x01
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_max_length(context):
|
def get_max_length(context):
|
||||||
return 256 if context.protocol_version >= 306 else \
|
return 256 if context.protocol_later_eq(306) else \
|
||||||
100
|
100
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -79,17 +79,17 @@ class ChatPacket(Packet):
|
|||||||
class PositionAndLookPacket(Packet):
|
class PositionAndLookPacket(Packet):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x13 if context.protocol_version >= 712 else \
|
return 0x13 if context.protocol_later_eq(712) else \
|
||||||
0x12 if context.protocol_version >= 471 else \
|
0x12 if context.protocol_later_eq(471) else \
|
||||||
0x13 if context.protocol_version >= 464 else \
|
0x13 if context.protocol_later_eq(464) else \
|
||||||
0x11 if context.protocol_version >= 389 else \
|
0x11 if context.protocol_later_eq(389) else \
|
||||||
0x0F if context.protocol_version >= 386 else \
|
0x0F if context.protocol_later_eq(386) else \
|
||||||
0x0E if context.protocol_version >= 345 else \
|
0x0E if context.protocol_later_eq(345) else \
|
||||||
0x0D if context.protocol_version >= 343 else \
|
0x0D if context.protocol_later_eq(343) else \
|
||||||
0x0E if context.protocol_version >= 336 else \
|
0x0E if context.protocol_later_eq(336) else \
|
||||||
0x0F if context.protocol_version >= 332 else \
|
0x0F if context.protocol_later_eq(332) else \
|
||||||
0x0E if context.protocol_version >= 318 else \
|
0x0E if context.protocol_later_eq(318) else \
|
||||||
0x0D if context.protocol_version >= 107 else \
|
0x0D if context.protocol_later_eq(107) else \
|
||||||
0x06
|
0x06
|
||||||
|
|
||||||
packet_name = "position and look"
|
packet_name = "position and look"
|
||||||
@ -126,22 +126,22 @@ class TeleportConfirmPacket(Packet):
|
|||||||
class AnimationPacket(Packet):
|
class AnimationPacket(Packet):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x2C if context.protocol_version >= 738 else \
|
return 0x2C if context.protocol_later_eq(738) else \
|
||||||
0x2B if context.protocol_version >= 712 else \
|
0x2B if context.protocol_later_eq(712) else \
|
||||||
0x2A if context.protocol_version >= 468 else \
|
0x2A if context.protocol_later_eq(468) else \
|
||||||
0x29 if context.protocol_version >= 464 else \
|
0x29 if context.protocol_later_eq(464) else \
|
||||||
0x27 if context.protocol_version >= 389 else \
|
0x27 if context.protocol_later_eq(389) else \
|
||||||
0x25 if context.protocol_version >= 386 else \
|
0x25 if context.protocol_later_eq(386) else \
|
||||||
0x1D if context.protocol_version >= 345 else \
|
0x1D if context.protocol_later_eq(345) else \
|
||||||
0x1C if context.protocol_version >= 343 else \
|
0x1C if context.protocol_later_eq(343) else \
|
||||||
0x1D if context.protocol_version >= 332 else \
|
0x1D if context.protocol_later_eq(332) else \
|
||||||
0x1C if context.protocol_version >= 318 else \
|
0x1C if context.protocol_later_eq(318) else \
|
||||||
0x1A if context.protocol_version >= 107 else \
|
0x1A if context.protocol_later_eq(107) else \
|
||||||
0x0A
|
0x0A
|
||||||
|
|
||||||
packet_name = "animation"
|
packet_name = "animation"
|
||||||
get_definition = staticmethod(lambda context: [
|
get_definition = staticmethod(lambda context: [
|
||||||
{'hand': VarInt} if context.protocol_version >= 107 else {}])
|
{'hand': VarInt} if context.protocol_later_eq(107) else {}])
|
||||||
|
|
||||||
Hand = RelativeHand
|
Hand = RelativeHand
|
||||||
HAND_MAIN, HAND_OFF = Hand.MAIN, Hand.OFF # For backward compatibility.
|
HAND_MAIN, HAND_OFF = Hand.MAIN, Hand.OFF # For backward compatibility.
|
||||||
@ -150,14 +150,14 @@ class AnimationPacket(Packet):
|
|||||||
class ClientStatusPacket(Packet, Enum):
|
class ClientStatusPacket(Packet, Enum):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x04 if context.protocol_version >= 464 else \
|
return 0x04 if context.protocol_later_eq(464) else \
|
||||||
0x03 if context.protocol_version >= 389 else \
|
0x03 if context.protocol_later_eq(389) else \
|
||||||
0x02 if context.protocol_version >= 343 else \
|
0x02 if context.protocol_later_eq(343) else \
|
||||||
0x03 if context.protocol_version >= 336 else \
|
0x03 if context.protocol_later_eq(336) else \
|
||||||
0x04 if context.protocol_version >= 318 else \
|
0x04 if context.protocol_later_eq(318) else \
|
||||||
0x03 if context.protocol_version >= 80 else \
|
0x03 if context.protocol_later_eq(80) else \
|
||||||
0x02 if context.protocol_version >= 67 else \
|
0x02 if context.protocol_later_eq(67) else \
|
||||||
0x17 if context.protocol_version >= 49 else \
|
0x17 if context.protocol_later_eq(49) else \
|
||||||
0x16
|
0x16
|
||||||
|
|
||||||
packet_name = "client status"
|
packet_name = "client status"
|
||||||
@ -175,13 +175,13 @@ class ClientStatusPacket(Packet, Enum):
|
|||||||
class PluginMessagePacket(AbstractPluginMessagePacket):
|
class PluginMessagePacket(AbstractPluginMessagePacket):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x0B if context.protocol_version >= 464 else \
|
return 0x0B if context.protocol_later_eq(464) else \
|
||||||
0x0A if context.protocol_version >= 389 else \
|
0x0A if context.protocol_later_eq(389) else \
|
||||||
0x09 if context.protocol_version >= 345 else \
|
0x09 if context.protocol_later_eq(345) else \
|
||||||
0x08 if context.protocol_version >= 343 else \
|
0x08 if context.protocol_later_eq(343) else \
|
||||||
0x09 if context.protocol_version >= 336 else \
|
0x09 if context.protocol_later_eq(336) else \
|
||||||
0x0A if context.protocol_version >= 317 else \
|
0x0A if context.protocol_later_eq(317) else \
|
||||||
0x09 if context.protocol_version >= 94 else \
|
0x09 if context.protocol_later_eq(94) else \
|
||||||
0x17
|
0x17
|
||||||
|
|
||||||
|
|
||||||
@ -201,17 +201,17 @@ class PlayerBlockPlacementPacket(Packet):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x2E if context.protocol_version >= 738 else \
|
return 0x2E if context.protocol_later_eq(738) else \
|
||||||
0x2D if context.protocol_version >= 712 else \
|
0x2D if context.protocol_later_eq(712) else \
|
||||||
0x2C if context.protocol_version >= 468 else \
|
0x2C if context.protocol_later_eq(468) else \
|
||||||
0x2B if context.protocol_version >= 464 else \
|
0x2B if context.protocol_later_eq(464) else \
|
||||||
0x29 if context.protocol_version >= 389 else \
|
0x29 if context.protocol_later_eq(389) else \
|
||||||
0x27 if context.protocol_version >= 386 else \
|
0x27 if context.protocol_later_eq(386) else \
|
||||||
0x1F if context.protocol_version >= 345 else \
|
0x1F if context.protocol_later_eq(345) else \
|
||||||
0x1E if context.protocol_version >= 343 else \
|
0x1E if context.protocol_later_eq(343) else \
|
||||||
0x1F if context.protocol_version >= 332 else \
|
0x1F if context.protocol_later_eq(332) else \
|
||||||
0x1E if context.protocol_version >= 318 else \
|
0x1E if context.protocol_later_eq(318) else \
|
||||||
0x1C if context.protocol_version >= 94 else \
|
0x1C if context.protocol_later_eq(94) else \
|
||||||
0x08
|
0x08
|
||||||
|
|
||||||
packet_name = 'player block placement'
|
packet_name = 'player block placement'
|
||||||
@ -219,15 +219,15 @@ class PlayerBlockPlacementPacket(Packet):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def get_definition(context):
|
def get_definition(context):
|
||||||
return [
|
return [
|
||||||
{'hand': VarInt} if context.protocol_version >= 453 else {},
|
{'hand': VarInt} if context.protocol_later_eq(453) else {},
|
||||||
{'location': Position},
|
{'location': Position},
|
||||||
{'face': VarInt if context.protocol_version >= 69 else Byte},
|
{'face': VarInt if context.protocol_later_eq(69) else Byte},
|
||||||
{'hand': VarInt} if context.protocol_version < 453 else {},
|
{'hand': VarInt} if context.protocol_earlier(453) else {},
|
||||||
{'x': Float if context.protocol_version >= 309 else Byte},
|
{'x': Float if context.protocol_later_eq(309) else Byte},
|
||||||
{'y': Float if context.protocol_version >= 309 else Byte},
|
{'y': Float if context.protocol_later_eq(309) else Byte},
|
||||||
{'z': Float if context.protocol_version >= 309 else Byte},
|
{'z': Float if context.protocol_later_eq(309) else Byte},
|
||||||
({'inside_block': Boolean}
|
({'inside_block': Boolean}
|
||||||
if context.protocol_version >= 453 else {}),
|
if context.protocol_later_eq(453) else {}),
|
||||||
]
|
]
|
||||||
|
|
||||||
# PlayerBlockPlacementPacket.Hand is an alias for RelativeHand.
|
# PlayerBlockPlacementPacket.Hand is an alias for RelativeHand.
|
||||||
@ -240,18 +240,18 @@ class PlayerBlockPlacementPacket(Packet):
|
|||||||
class UseItemPacket(Packet):
|
class UseItemPacket(Packet):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x2F if context.protocol_version >= 738 else \
|
return 0x2F if context.protocol_later_eq(738) else \
|
||||||
0x2E if context.protocol_version >= 712 else \
|
0x2E if context.protocol_later_eq(712) else \
|
||||||
0x2D if context.protocol_version >= 468 else \
|
0x2D if context.protocol_later_eq(468) else \
|
||||||
0x2C if context.protocol_version >= 464 else \
|
0x2C if context.protocol_later_eq(464) else \
|
||||||
0x2A if context.protocol_version >= 389 else \
|
0x2A if context.protocol_later_eq(389) else \
|
||||||
0x28 if context.protocol_version >= 386 else \
|
0x28 if context.protocol_later_eq(386) else \
|
||||||
0x20 if context.protocol_version >= 345 else \
|
0x20 if context.protocol_later_eq(345) else \
|
||||||
0x1F if context.protocol_version >= 343 else \
|
0x1F if context.protocol_later_eq(343) else \
|
||||||
0x20 if context.protocol_version >= 332 else \
|
0x20 if context.protocol_later_eq(332) else \
|
||||||
0x1F if context.protocol_version >= 318 else \
|
0x1F if context.protocol_later_eq(318) else \
|
||||||
0x1D if context.protocol_version >= 94 else \
|
0x1D if context.protocol_later_eq(94) else \
|
||||||
0x1A if context.protocol_version >= 70 else \
|
0x1A if context.protocol_later_eq(70) else \
|
||||||
0x08
|
0x08
|
||||||
|
|
||||||
packet_name = "use item"
|
packet_name = "use item"
|
||||||
|
@ -8,12 +8,12 @@ from minecraft.networking.types import (
|
|||||||
class ClientSettingsPacket(Packet):
|
class ClientSettingsPacket(Packet):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_id(context):
|
def get_id(context):
|
||||||
return 0x05 if context.protocol_version >= 464 else \
|
return 0x05 if context.protocol_later_eq(464) else \
|
||||||
0x04 if context.protocol_version >= 389 else \
|
0x04 if context.protocol_later_eq(389) else \
|
||||||
0x03 if context.protocol_version >= 343 else \
|
0x03 if context.protocol_later_eq(343) else \
|
||||||
0x04 if context.protocol_version >= 336 else \
|
0x04 if context.protocol_later_eq(336) else \
|
||||||
0x05 if context.protocol_version >= 318 else \
|
0x05 if context.protocol_later_eq(318) else \
|
||||||
0x04 if context.protocol_version >= 94 else \
|
0x04 if context.protocol_later_eq(94) else \
|
||||||
0x15
|
0x15
|
||||||
|
|
||||||
packet_name = 'client settings'
|
packet_name = 'client settings'
|
||||||
@ -21,10 +21,10 @@ class ClientSettingsPacket(Packet):
|
|||||||
get_definition = staticmethod(lambda context: [
|
get_definition = staticmethod(lambda context: [
|
||||||
{'locale': String},
|
{'locale': String},
|
||||||
{'view_distance': Byte},
|
{'view_distance': Byte},
|
||||||
{'chat_mode': VarInt if context.protocol_version > 47 else Byte},
|
{'chat_mode': VarInt if context.protocol_later(47) else Byte},
|
||||||
{'chat_colors': Boolean},
|
{'chat_colors': Boolean},
|
||||||
{'displayed_skin_parts': UnsignedByte},
|
{'displayed_skin_parts': UnsignedByte},
|
||||||
{'main_hand': VarInt} if context.protocol_version > 49 else {}])
|
{'main_hand': VarInt} if context.protocol_later(49) else {}])
|
||||||
|
|
||||||
field_enum = classmethod(
|
field_enum = classmethod(
|
||||||
lambda cls, field, context: {
|
lambda cls, field, context: {
|
||||||
|
@ -314,7 +314,7 @@ class Position(Type, Vector):
|
|||||||
location = UnsignedLong.read(file_object)
|
location = UnsignedLong.read(file_object)
|
||||||
x = int(location >> 38) # 26 most significant bits
|
x = int(location >> 38) # 26 most significant bits
|
||||||
|
|
||||||
if context.protocol_version >= 443:
|
if context.protocol_later_eq(443):
|
||||||
z = int((location >> 12) & 0x3FFFFFF) # 26 intermediate bits
|
z = int((location >> 12) & 0x3FFFFFF) # 26 intermediate bits
|
||||||
y = int(location & 0xFFF) # 12 least signficant bits
|
y = int(location & 0xFFF) # 12 least signficant bits
|
||||||
else:
|
else:
|
||||||
@ -337,7 +337,7 @@ class Position(Type, Vector):
|
|||||||
# 'position' can be either a tuple or Position object.
|
# 'position' can be either a tuple or Position object.
|
||||||
x, y, z = position
|
x, y, z = position
|
||||||
value = ((x & 0x3FFFFFF) << 38 | (z & 0x3FFFFFF) << 12 | (y & 0xFFF)
|
value = ((x & 0x3FFFFFF) << 38 | (z & 0x3FFFFFF) << 12 | (y & 0xFFF)
|
||||||
if context.protocol_version >= 443 else
|
if context.protocol_later_eq(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)
|
||||||
|
|
||||||
|
@ -1,16 +1,12 @@
|
|||||||
"""Minecraft data types that are used by packets, but don't have a specific
|
"""Minecraft data types that are used by packets, but don't have a specific
|
||||||
network representation.
|
network representation.
|
||||||
"""
|
"""
|
||||||
import types
|
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from itertools import chain
|
|
||||||
|
|
||||||
|
# These aliases are retained for backward compatibility
|
||||||
__all__ = (
|
from minecraft.utility import ( # noqa: F401
|
||||||
'Vector', 'MutableRecord', 'Direction', 'PositionAndLook', 'descriptor',
|
descriptor, overridable_descriptor, overridable_property, attribute_alias,
|
||||||
'overridable_descriptor', 'overridable_property', 'attribute_alias',
|
multi_attribute_alias, attribute_transform, class_and_instancemethod,
|
||||||
'multi_attribute_alias', 'attribute_transform',
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -92,161 +88,6 @@ class MutableRecord(object):
|
|||||||
yield slot
|
yield slot
|
||||||
|
|
||||||
|
|
||||||
def attribute_transform(name, from_orig, to_orig):
|
|
||||||
"""An attribute descriptor that provides a view of a different attribute
|
|
||||||
with a given name via a given transformation and its given inverse."""
|
|
||||||
return property(
|
|
||||||
fget=(lambda self: from_orig(getattr(self, name))),
|
|
||||||
fset=(lambda self, value: setattr(self, name, to_orig(value))),
|
|
||||||
fdel=(lambda self: delattr(self, name)))
|
|
||||||
|
|
||||||
|
|
||||||
def attribute_alias(name):
|
|
||||||
"""An attribute descriptor that redirects access to a different attribute
|
|
||||||
with a given name.
|
|
||||||
"""
|
|
||||||
return attribute_transform(name, lambda x: x, lambda x: x)
|
|
||||||
|
|
||||||
|
|
||||||
def multi_attribute_alias(container, *arg_names, **kwd_names):
|
|
||||||
"""A descriptor for an attribute whose value is a container of a given type
|
|
||||||
with several fields, each of which is aliased to a different attribute
|
|
||||||
of the parent object.
|
|
||||||
|
|
||||||
The 'n'th name in 'arg_names' is the parent attribute that will be
|
|
||||||
aliased to the field of 'container' settable by the 'n'th positional
|
|
||||||
argument to its constructor, and accessible as its 'n'th iterable
|
|
||||||
element.
|
|
||||||
|
|
||||||
As a special case, 'tuple' may be given as the 'container' when there
|
|
||||||
are positional arguments, and (even though the tuple constructor does
|
|
||||||
not take positional arguments), the arguments will be aliased to the
|
|
||||||
corresponding positions in a tuple.
|
|
||||||
|
|
||||||
The name in 'kwd_names' mapped to by the key 'k' is the parent attribute
|
|
||||||
that will be aliased to the field of 'container' settable by the keyword
|
|
||||||
argument 'k' to its constructor, and accessible as its 'k' attribute.
|
|
||||||
"""
|
|
||||||
if container is tuple:
|
|
||||||
container = lambda *args: args # noqa: E731
|
|
||||||
|
|
||||||
@property
|
|
||||||
def alias(self):
|
|
||||||
return container(
|
|
||||||
*(getattr(self, name) for name in arg_names),
|
|
||||||
**{kwd: getattr(self, name) for (kwd, name) in kwd_names.items()})
|
|
||||||
|
|
||||||
@alias.setter
|
|
||||||
def alias(self, values):
|
|
||||||
if arg_names:
|
|
||||||
for name, value in zip(arg_names, values):
|
|
||||||
setattr(self, name, value)
|
|
||||||
for kwd, name in kwd_names.items():
|
|
||||||
setattr(self, name, getattr(values, kwd))
|
|
||||||
|
|
||||||
@alias.deleter
|
|
||||||
def alias(self):
|
|
||||||
for name in chain(arg_names, kwd_names.values()):
|
|
||||||
delattr(self, name)
|
|
||||||
|
|
||||||
return alias
|
|
||||||
|
|
||||||
|
|
||||||
class overridable_descriptor:
|
|
||||||
"""As 'descriptor' (defined below), except that only a getter can be
|
|
||||||
defined, and the resulting descriptor has no '__set__' or '__delete__'
|
|
||||||
methods defined; hence, attributes defined via this class can be
|
|
||||||
overridden by attributes of instances of the class in which it occurs.
|
|
||||||
"""
|
|
||||||
__slots__ = '_fget',
|
|
||||||
|
|
||||||
def __init__(self, fget=None):
|
|
||||||
self._fget = fget if fget is not None else self._default_get
|
|
||||||
|
|
||||||
def getter(self, fget):
|
|
||||||
self._fget = fget
|
|
||||||
return self
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _default_get(instance, owner):
|
|
||||||
raise AttributeError('unreadable attribute')
|
|
||||||
|
|
||||||
def __get__(self, instance, owner):
|
|
||||||
return self._fget(self, instance, owner)
|
|
||||||
|
|
||||||
|
|
||||||
class overridable_property(overridable_descriptor):
|
|
||||||
"""As the builtin 'property' decorator of Python, except that only
|
|
||||||
a getter is defined and the resulting descriptor is a non-data
|
|
||||||
descriptor, overridable by attributes of instances of the class
|
|
||||||
in which the property occurs. See also 'overridable_descriptor' above.
|
|
||||||
"""
|
|
||||||
def __get__(self, instance, _owner):
|
|
||||||
return self._fget(instance)
|
|
||||||
|
|
||||||
|
|
||||||
class descriptor(overridable_descriptor):
|
|
||||||
"""Behaves identically to the builtin 'property' decorator of Python,
|
|
||||||
except that the getter, setter and deleter functions given by the
|
|
||||||
user are used as the raw __get__, __set__ and __delete__ functions
|
|
||||||
as defined in Python's descriptor protocol.
|
|
||||||
|
|
||||||
Since an instance of this class always havs '__set__' and '__delete__'
|
|
||||||
defined, it is a "data descriptor", so its binding behaviour cannot be
|
|
||||||
overridden in instances of the class in which it occurs. See
|
|
||||||
https://docs.python.org/3/reference/datamodel.html#descriptor-invocation
|
|
||||||
for more information. See also 'overridable_descriptor' above.
|
|
||||||
"""
|
|
||||||
__slots__ = '_fset', '_fdel'
|
|
||||||
|
|
||||||
def __init__(self, fget=None, fset=None, fdel=None):
|
|
||||||
super(descriptor, self).__init__(fget=fget)
|
|
||||||
self._fset = fset if fset is not None else self._default_set
|
|
||||||
self._fdel = fdel if fdel is not None else self._default_del
|
|
||||||
|
|
||||||
def setter(self, fset):
|
|
||||||
self._fset = fset
|
|
||||||
return self
|
|
||||||
|
|
||||||
def deleter(self, fdel):
|
|
||||||
self._fdel = fdel
|
|
||||||
return self
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _default_set(instance, value):
|
|
||||||
raise AttributeError("can't set attribute")
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _default_del(instance):
|
|
||||||
raise AttributeError("can't delete attribute")
|
|
||||||
|
|
||||||
def __set__(self, instance, value):
|
|
||||||
return self._fset(self, instance, value)
|
|
||||||
|
|
||||||
def __delete__(self, instance):
|
|
||||||
return self._fdel(self, instance)
|
|
||||||
|
|
||||||
|
|
||||||
class class_and_instancemethod:
|
|
||||||
""" A decorator for functions defined in a class namespace which are to be
|
|
||||||
accessed as both class and instance methods: retrieving the method from
|
|
||||||
a class will return a bound class method (like the built-in
|
|
||||||
'classmethod' decorator), but retrieving the method from an instance
|
|
||||||
will return a bound instance method (as if the function were not
|
|
||||||
decorated). Therefore, the first argument of the decorated function may
|
|
||||||
be either a class or an instance, depending on how it was called.
|
|
||||||
"""
|
|
||||||
|
|
||||||
__slots__ = '_func',
|
|
||||||
|
|
||||||
def __init__(self, func):
|
|
||||||
self._func = func
|
|
||||||
|
|
||||||
def __get__(self, inst, owner=None):
|
|
||||||
bind_to = owner if inst is None else inst
|
|
||||||
return types.MethodType(self._func, bind_to)
|
|
||||||
|
|
||||||
|
|
||||||
Direction = namedtuple('Direction', ('yaw', 'pitch'))
|
Direction = namedtuple('Direction', ('yaw', 'pitch'))
|
||||||
|
|
||||||
|
|
||||||
|
175
minecraft/utility.py
Normal file
175
minecraft/utility.py
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
""" Miscellaneous general utilities.
|
||||||
|
"""
|
||||||
|
import types
|
||||||
|
from itertools import chain
|
||||||
|
|
||||||
|
from . import PROTOCOL_VERSION_INDICES
|
||||||
|
|
||||||
|
|
||||||
|
def protocol_earlier(pv1, pv2):
|
||||||
|
""" Returns True if protocol version 'pv1' was published before 'pv2',
|
||||||
|
or else returns False.
|
||||||
|
"""
|
||||||
|
return PROTOCOL_VERSION_INDICES[pv1] < PROTOCOL_VERSION_INDICES[pv2]
|
||||||
|
|
||||||
|
|
||||||
|
def protocol_earlier_eq(pv1, pv2):
|
||||||
|
""" Returns True if protocol versions 'pv1' and 'pv2' are the same or if
|
||||||
|
'pv1' was published before 'pv2', or else returns False.
|
||||||
|
"""
|
||||||
|
return PROTOCOL_VERSION_INDICES[pv1] <= PROTOCOL_VERSION_INDICES[pv2]
|
||||||
|
|
||||||
|
|
||||||
|
def attribute_transform(name, from_orig, to_orig):
|
||||||
|
"""An attribute descriptor that provides a view of a different attribute
|
||||||
|
with a given name via a given transformation and its given inverse."""
|
||||||
|
return property(
|
||||||
|
fget=(lambda self: from_orig(getattr(self, name))),
|
||||||
|
fset=(lambda self, value: setattr(self, name, to_orig(value))),
|
||||||
|
fdel=(lambda self: delattr(self, name)))
|
||||||
|
|
||||||
|
|
||||||
|
def attribute_alias(name):
|
||||||
|
"""An attribute descriptor that redirects access to a different attribute
|
||||||
|
with a given name.
|
||||||
|
"""
|
||||||
|
return attribute_transform(name, lambda x: x, lambda x: x)
|
||||||
|
|
||||||
|
|
||||||
|
def multi_attribute_alias(container, *arg_names, **kwd_names):
|
||||||
|
"""A descriptor for an attribute whose value is a container of a given type
|
||||||
|
with several fields, each of which is aliased to a different attribute
|
||||||
|
of the parent object.
|
||||||
|
|
||||||
|
The 'n'th name in 'arg_names' is the parent attribute that will be
|
||||||
|
aliased to the field of 'container' settable by the 'n'th positional
|
||||||
|
argument to its constructor, and accessible as its 'n'th iterable
|
||||||
|
element.
|
||||||
|
|
||||||
|
As a special case, 'tuple' may be given as the 'container' when there
|
||||||
|
are positional arguments, and (even though the tuple constructor does
|
||||||
|
not take positional arguments), the arguments will be aliased to the
|
||||||
|
corresponding positions in a tuple.
|
||||||
|
|
||||||
|
The name in 'kwd_names' mapped to by the key 'k' is the parent attribute
|
||||||
|
that will be aliased to the field of 'container' settable by the keyword
|
||||||
|
argument 'k' to its constructor, and accessible as its 'k' attribute.
|
||||||
|
"""
|
||||||
|
if container is tuple:
|
||||||
|
container = lambda *args: args # noqa: E731
|
||||||
|
|
||||||
|
@property
|
||||||
|
def alias(self):
|
||||||
|
return container(
|
||||||
|
*(getattr(self, name) for name in arg_names),
|
||||||
|
**{kwd: getattr(self, name) for (kwd, name) in kwd_names.items()})
|
||||||
|
|
||||||
|
@alias.setter
|
||||||
|
def alias(self, values):
|
||||||
|
if arg_names:
|
||||||
|
for name, value in zip(arg_names, values):
|
||||||
|
setattr(self, name, value)
|
||||||
|
for kwd, name in kwd_names.items():
|
||||||
|
setattr(self, name, getattr(values, kwd))
|
||||||
|
|
||||||
|
@alias.deleter
|
||||||
|
def alias(self):
|
||||||
|
for name in chain(arg_names, kwd_names.values()):
|
||||||
|
delattr(self, name)
|
||||||
|
|
||||||
|
return alias
|
||||||
|
|
||||||
|
|
||||||
|
class overridable_descriptor:
|
||||||
|
"""As 'descriptor' (defined below), except that only a getter can be
|
||||||
|
defined, and the resulting descriptor has no '__set__' or '__delete__'
|
||||||
|
methods defined; hence, attributes defined via this class can be
|
||||||
|
overridden by attributes of instances of the class in which it occurs.
|
||||||
|
"""
|
||||||
|
__slots__ = '_fget',
|
||||||
|
|
||||||
|
def __init__(self, fget=None):
|
||||||
|
self._fget = fget if fget is not None else self._default_get
|
||||||
|
|
||||||
|
def getter(self, fget):
|
||||||
|
self._fget = fget
|
||||||
|
return self
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _default_get(instance, owner):
|
||||||
|
raise AttributeError('unreadable attribute')
|
||||||
|
|
||||||
|
def __get__(self, instance, owner):
|
||||||
|
return self._fget(self, instance, owner)
|
||||||
|
|
||||||
|
|
||||||
|
class overridable_property(overridable_descriptor):
|
||||||
|
"""As the builtin 'property' decorator of Python, except that only
|
||||||
|
a getter is defined and the resulting descriptor is a non-data
|
||||||
|
descriptor, overridable by attributes of instances of the class
|
||||||
|
in which the property occurs. See also 'overridable_descriptor' above.
|
||||||
|
"""
|
||||||
|
def __get__(self, instance, _owner):
|
||||||
|
return self._fget(instance)
|
||||||
|
|
||||||
|
|
||||||
|
class descriptor(overridable_descriptor):
|
||||||
|
"""Behaves identically to the builtin 'property' decorator of Python,
|
||||||
|
except that the getter, setter and deleter functions given by the
|
||||||
|
user are used as the raw __get__, __set__ and __delete__ functions
|
||||||
|
as defined in Python's descriptor protocol.
|
||||||
|
|
||||||
|
Since an instance of this class always havs '__set__' and '__delete__'
|
||||||
|
defined, it is a "data descriptor", so its binding behaviour cannot be
|
||||||
|
overridden in instances of the class in which it occurs. See
|
||||||
|
https://docs.python.org/3/reference/datamodel.html#descriptor-invocation
|
||||||
|
for more information. See also 'overridable_descriptor' above.
|
||||||
|
"""
|
||||||
|
__slots__ = '_fset', '_fdel'
|
||||||
|
|
||||||
|
def __init__(self, fget=None, fset=None, fdel=None):
|
||||||
|
super(descriptor, self).__init__(fget=fget)
|
||||||
|
self._fset = fset if fset is not None else self._default_set
|
||||||
|
self._fdel = fdel if fdel is not None else self._default_del
|
||||||
|
|
||||||
|
def setter(self, fset):
|
||||||
|
self._fset = fset
|
||||||
|
return self
|
||||||
|
|
||||||
|
def deleter(self, fdel):
|
||||||
|
self._fdel = fdel
|
||||||
|
return self
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _default_set(instance, value):
|
||||||
|
raise AttributeError("can't set attribute")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _default_del(instance):
|
||||||
|
raise AttributeError("can't delete attribute")
|
||||||
|
|
||||||
|
def __set__(self, instance, value):
|
||||||
|
return self._fset(self, instance, value)
|
||||||
|
|
||||||
|
def __delete__(self, instance):
|
||||||
|
return self._fdel(self, instance)
|
||||||
|
|
||||||
|
|
||||||
|
class class_and_instancemethod:
|
||||||
|
""" A decorator for functions defined in a class namespace which are to be
|
||||||
|
accessed as both class and instance methods: retrieving the method from
|
||||||
|
a class will return a bound class method (like the built-in
|
||||||
|
'classmethod' decorator), but retrieving the method from an instance
|
||||||
|
will return a bound instance method (as if the function were not
|
||||||
|
decorated). Therefore, the first argument of the decorated function may
|
||||||
|
be either a class or an instance, depending on how it was called.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = '_func',
|
||||||
|
|
||||||
|
def __init__(self, func):
|
||||||
|
self._func = func
|
||||||
|
|
||||||
|
def __get__(self, inst, owner=None):
|
||||||
|
bind_to = owner if inst is None else inst
|
||||||
|
return types.MethodType(self._func, bind_to)
|
@ -24,9 +24,6 @@ import hashlib
|
|||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
|
|
||||||
VERSIONS = sorted(SUPPORTED_MINECRAFT_VERSIONS.items(), key=lambda i: i[1])
|
|
||||||
VERSIONS = [v for (v, p) in VERSIONS]
|
|
||||||
|
|
||||||
THREAD_TIMEOUT_S = 2
|
THREAD_TIMEOUT_S = 2
|
||||||
|
|
||||||
|
|
||||||
@ -108,7 +105,7 @@ class FakeClientHandler(object):
|
|||||||
level_type='default', reduced_debug_info=False, render_distance=9,
|
level_type='default', reduced_debug_info=False, render_distance=9,
|
||||||
respawn_screen=False, is_debug=False, is_flat=False)
|
respawn_screen=False, is_debug=False, is_flat=False)
|
||||||
|
|
||||||
if self.server.context.protocol_version >= 748:
|
if self.server.context.protocol_later_eq(748):
|
||||||
packet.dimension = pynbt.TAG_Compound({
|
packet.dimension = pynbt.TAG_Compound({
|
||||||
'natural': pynbt.TAG_Byte(1),
|
'natural': pynbt.TAG_Byte(1),
|
||||||
'effects': pynbt.TAG_String('minecraft:overworld'),
|
'effects': pynbt.TAG_String('minecraft:overworld'),
|
||||||
@ -134,7 +131,7 @@ class FakeClientHandler(object):
|
|||||||
]),
|
]),
|
||||||
}),
|
}),
|
||||||
}, '')
|
}, '')
|
||||||
elif self.server.context.protocol_version >= 718:
|
elif self.server.context.protocol_later_eq(718):
|
||||||
packet.dimension = 'minecraft:overworld'
|
packet.dimension = 'minecraft:overworld'
|
||||||
else:
|
else:
|
||||||
packet.dimension = types.Dimension.OVERWORLD
|
packet.dimension = types.Dimension.OVERWORLD
|
||||||
@ -232,13 +229,13 @@ class FakeClientHandler(object):
|
|||||||
# Prepare to transition from handshaking to play state (via login),
|
# Prepare to transition from handshaking to play state (via login),
|
||||||
# using the given serverbound HandShakePacket to perform play-specific
|
# using the given serverbound HandShakePacket to perform play-specific
|
||||||
# processing.
|
# processing.
|
||||||
if packet.protocol_version == self.server.context.protocol_version:
|
if self.server.context.protocol_version == packet.protocol_version:
|
||||||
return self._run_login()
|
return self._run_login()
|
||||||
if packet.protocol_version < self.server.context.protocol_version:
|
elif self.server.context.protocol_earlier(packet.protocol_version):
|
||||||
msg = 'Outdated client! Please use %s' \
|
msg = "Outdated server! I'm still on %s" \
|
||||||
% self.server.minecraft_version
|
% self.server.minecraft_version
|
||||||
else:
|
else:
|
||||||
msg = "Outdated server! I'm still on %s" \
|
msg = 'Outdated client! Please use %s' \
|
||||||
% self.server.minecraft_version
|
% self.server.minecraft_version
|
||||||
self.handle_login_server_disconnect(msg)
|
self.handle_login_server_disconnect(msg)
|
||||||
|
|
||||||
@ -372,7 +369,7 @@ class FakeServer(object):
|
|||||||
client_handler_type=FakeClientHandler, private_key=None,
|
client_handler_type=FakeClientHandler, private_key=None,
|
||||||
public_key_bytes=None, test_case=None):
|
public_key_bytes=None, test_case=None):
|
||||||
if minecraft_version is None:
|
if minecraft_version is None:
|
||||||
minecraft_version = VERSIONS[-1][0]
|
minecraft_version = list(SUPPORTED_MINECRAFT_VERSIONS.keys())[-1]
|
||||||
|
|
||||||
if isinstance(minecraft_version, Integral):
|
if isinstance(minecraft_version, Integral):
|
||||||
proto = minecraft_version
|
proto = minecraft_version
|
||||||
@ -458,8 +455,9 @@ class _FakeServerTest(unittest.TestCase):
|
|||||||
must raise a 'FakeServerTestSuccess' exception.
|
must raise a 'FakeServerTestSuccess' exception.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
server_version = VERSIONS[-1]
|
server_version = None
|
||||||
# The Minecraft version ID that the server will support.
|
# The Minecraft version ID that the server will support.
|
||||||
|
# If None, the latest supported version will be used.
|
||||||
|
|
||||||
client_versions = None
|
client_versions = None
|
||||||
# The set of Minecraft version IDs or protocol version numbers that the
|
# The set of Minecraft version IDs or protocol version numbers that the
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from minecraft import SUPPORTED_PROTOCOL_VERSIONS
|
from minecraft import SUPPORTED_PROTOCOL_VERSIONS
|
||||||
|
from minecraft import utility
|
||||||
from minecraft.networking.connection import ConnectionContext
|
from minecraft.networking.connection import ConnectionContext
|
||||||
from minecraft.networking import packets
|
from minecraft.networking import packets
|
||||||
from minecraft.networking import types
|
from minecraft.networking import types
|
||||||
@ -87,6 +88,12 @@ class LegacyTypesTest(unittest.TestCase):
|
|||||||
self.assertIsInstance(types.FixedPointInteger, types.FixedPoint)
|
self.assertIsInstance(types.FixedPointInteger, types.FixedPoint)
|
||||||
self.assertEqual(types.FixedPointInteger.denominator, 32)
|
self.assertEqual(types.FixedPointInteger.denominator, 32)
|
||||||
|
|
||||||
|
for attr in ('descriptor', 'overridable_descriptor',
|
||||||
|
'overridable_property', 'attribute_alias',
|
||||||
|
'multi_attribute_alias', 'attribute_transform',
|
||||||
|
'class_and_instancemethod'):
|
||||||
|
self.assertEqual(getattr(types, attr), getattr(utility, attr))
|
||||||
|
|
||||||
|
|
||||||
class ClassMemberAliasesTest(unittest.TestCase):
|
class ClassMemberAliasesTest(unittest.TestCase):
|
||||||
def test_alias_values(self):
|
def test_alias_values(self):
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
from minecraft import SUPPORTED_MINECRAFT_VERSIONS
|
from minecraft import (
|
||||||
from minecraft import SUPPORTED_PROTOCOL_VERSIONS
|
SUPPORTED_MINECRAFT_VERSIONS, SUPPORTED_PROTOCOL_VERSIONS,
|
||||||
|
PROTOCOL_VERSION_INDICES,
|
||||||
|
)
|
||||||
from minecraft.networking.packets import clientbound, serverbound
|
from minecraft.networking.packets import clientbound, serverbound
|
||||||
from minecraft.networking.connection import Connection
|
from minecraft.networking.connection import Connection
|
||||||
from minecraft.exceptions import (
|
from minecraft.exceptions import (
|
||||||
@ -119,26 +121,22 @@ class ConnectCompressionHighTest(ConnectTest):
|
|||||||
|
|
||||||
|
|
||||||
class AllowedVersionsTest(fake_server._FakeServerTest):
|
class AllowedVersionsTest(fake_server._FakeServerTest):
|
||||||
versions = sorted(SUPPORTED_MINECRAFT_VERSIONS.items(), key=lambda p: p[1])
|
versions = list(SUPPORTED_MINECRAFT_VERSIONS.items())
|
||||||
versions = dict((versions[0], versions[len(versions)//2], versions[-1]))
|
test_indices = (0, len(versions) // 2, len(versions) - 1)
|
||||||
|
|
||||||
client_handler_type = ConnectTest.client_handler_type
|
client_handler_type = ConnectTest.client_handler_type
|
||||||
|
|
||||||
def test_with_version_names(self):
|
def test_with_version_names(self):
|
||||||
for version, proto in AllowedVersionsTest.versions.items():
|
for index in self.test_indices:
|
||||||
client_versions = {
|
|
||||||
v for (v, p) in SUPPORTED_MINECRAFT_VERSIONS.items()
|
|
||||||
if p <= proto}
|
|
||||||
self._test_connect(
|
self._test_connect(
|
||||||
server_version=version, client_versions=client_versions)
|
server_version=self.versions[index][0],
|
||||||
|
client_versions={v[0] for v in self.versions[:index+1]})
|
||||||
|
|
||||||
def test_with_protocol_numbers(self):
|
def test_with_protocol_numbers(self):
|
||||||
for version, proto in AllowedVersionsTest.versions.items():
|
for index in self.test_indices:
|
||||||
client_versions = {
|
|
||||||
p for (v, p) in SUPPORTED_MINECRAFT_VERSIONS.items()
|
|
||||||
if p <= proto}
|
|
||||||
self._test_connect(
|
self._test_connect(
|
||||||
server_version=version, client_versions=client_versions)
|
server_version=self.versions[index][0],
|
||||||
|
client_versions={v[1] for v in self.versions[:index+1]})
|
||||||
|
|
||||||
|
|
||||||
class LoginDisconnectTest(fake_server._FakeServerTest):
|
class LoginDisconnectTest(fake_server._FakeServerTest):
|
||||||
@ -363,12 +361,22 @@ class HandleExceptionTest(ConnectTest):
|
|||||||
|
|
||||||
|
|
||||||
class VersionNegotiationEdgeCases(fake_server._FakeServerTest):
|
class VersionNegotiationEdgeCases(fake_server._FakeServerTest):
|
||||||
lowest_version = min(SUPPORTED_PROTOCOL_VERSIONS)
|
earliest_version = SUPPORTED_PROTOCOL_VERSIONS[0]
|
||||||
highest_version = max(SUPPORTED_PROTOCOL_VERSIONS)
|
latest_version = SUPPORTED_PROTOCOL_VERSIONS[-1]
|
||||||
impossible_version = highest_version + 1
|
|
||||||
|
fake_version = max(PROTOCOL_VERSION_INDICES.keys()) + 1
|
||||||
|
fake_version_index = max(PROTOCOL_VERSION_INDICES.values()) + 1
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
PROTOCOL_VERSION_INDICES[self.fake_version] = self.fake_version_index
|
||||||
|
super(VersionNegotiationEdgeCases, self).setUp()
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
super(VersionNegotiationEdgeCases, self).tearDown()
|
||||||
|
del PROTOCOL_VERSION_INDICES[self.fake_version]
|
||||||
|
|
||||||
def test_client_protocol_unsupported(self):
|
def test_client_protocol_unsupported(self):
|
||||||
self._test_client_protocol(version=self.impossible_version)
|
self._test_client_protocol(version=self.fake_version)
|
||||||
|
|
||||||
def test_client_protocol_unknown(self):
|
def test_client_protocol_unknown(self):
|
||||||
self._test_client_protocol(version='surprise me!')
|
self._test_client_protocol(version='surprise me!')
|
||||||
@ -383,21 +391,21 @@ class VersionNegotiationEdgeCases(fake_server._FakeServerTest):
|
|||||||
def test_server_protocol_unsupported(self, client_versions=None):
|
def test_server_protocol_unsupported(self, client_versions=None):
|
||||||
with self.assertRaisesRegexp(VersionMismatch, 'not supported'):
|
with self.assertRaisesRegexp(VersionMismatch, 'not supported'):
|
||||||
self._test_connect(client_versions=client_versions,
|
self._test_connect(client_versions=client_versions,
|
||||||
server_version=self.impossible_version)
|
server_version=self.fake_version)
|
||||||
|
|
||||||
def test_server_protocol_unsupported_direct(self):
|
def test_server_protocol_unsupported_direct(self):
|
||||||
self.test_server_protocol_unsupported({self.highest_version})
|
self.test_server_protocol_unsupported({self.latest_version})
|
||||||
|
|
||||||
def test_server_protocol_disallowed(self, client_versions=None):
|
def test_server_protocol_disallowed(self, client_versions=None):
|
||||||
if client_versions is None:
|
if client_versions is None:
|
||||||
client_versions = set(SUPPORTED_PROTOCOL_VERSIONS) \
|
client_versions = set(SUPPORTED_PROTOCOL_VERSIONS) \
|
||||||
- {self.highest_version}
|
- {self.latest_version}
|
||||||
with self.assertRaisesRegexp(VersionMismatch, 'not allowed'):
|
with self.assertRaisesRegexp(VersionMismatch, 'not allowed'):
|
||||||
self._test_connect(client_versions={self.lowest_version},
|
self._test_connect(client_versions={self.earliest_version},
|
||||||
server_version=self.highest_version)
|
server_version=self.latest_version)
|
||||||
|
|
||||||
def test_server_protocol_disallowed_direct(self):
|
def test_server_protocol_disallowed_direct(self):
|
||||||
self.test_server_protocol_disallowed({self.lowest_version})
|
self.test_server_protocol_disallowed({self.earliest_version})
|
||||||
|
|
||||||
def test_default_protocol_version(self, status_response=None):
|
def test_default_protocol_version(self, status_response=None):
|
||||||
if status_response is None:
|
if status_response is None:
|
||||||
@ -414,10 +422,10 @@ class VersionNegotiationEdgeCases(fake_server._FakeServerTest):
|
|||||||
raise fake_server.FakeServerDisconnect('Test complete.')
|
raise fake_server.FakeServerDisconnect('Test complete.')
|
||||||
|
|
||||||
def make_connection(*args, **kwds):
|
def make_connection(*args, **kwds):
|
||||||
kwds['initial_version'] = self.lowest_version
|
kwds['initial_version'] = self.earliest_version
|
||||||
return Connection(*args, **kwds)
|
return Connection(*args, **kwds)
|
||||||
|
|
||||||
self._test_connect(server_version=self.lowest_version,
|
self._test_connect(server_version=self.earliest_version,
|
||||||
client_handler_type=ClientHandler,
|
client_handler_type=ClientHandler,
|
||||||
connection_type=make_connection)
|
connection_type=make_connection)
|
||||||
|
|
||||||
@ -436,9 +444,9 @@ class VersionNegotiationEdgeCases(fake_server._FakeServerTest):
|
|||||||
raise fake_server.FakeServerDisconnect('Test complete.')
|
raise fake_server.FakeServerDisconnect('Test complete.')
|
||||||
|
|
||||||
def make_connection(*args, **kwds):
|
def make_connection(*args, **kwds):
|
||||||
kwds['initial_version'] = self.lowest_version
|
kwds['initial_version'] = self.earliest_version
|
||||||
return Connection(*args, **kwds)
|
return Connection(*args, **kwds)
|
||||||
|
|
||||||
self._test_connect(server_version=self.lowest_version,
|
self._test_connect(server_version=self.earliest_version,
|
||||||
client_handler_type=ClientHandler,
|
client_handler_type=ClientHandler,
|
||||||
connection_type=make_connection)
|
connection_type=make_connection)
|
||||||
|
@ -209,7 +209,7 @@ class TestReadWritePackets(unittest.TestCase):
|
|||||||
context.protocol_version = protocol_version
|
context.protocol_version = protocol_version
|
||||||
packet = clientbound.play.MultiBlockChangePacket(context)
|
packet = clientbound.play.MultiBlockChangePacket(context)
|
||||||
|
|
||||||
if protocol_version >= 741:
|
if context.protocol_later_eq(741):
|
||||||
packet.chunk_section_pos = Vector(167, 17, 33)
|
packet.chunk_section_pos = Vector(167, 17, 33)
|
||||||
packet.invert_trust_edges = False
|
packet.invert_trust_edges = False
|
||||||
else:
|
else:
|
||||||
@ -239,8 +239,9 @@ class TestReadWritePackets(unittest.TestCase):
|
|||||||
'type_id', context)
|
'type_id', context)
|
||||||
|
|
||||||
pos_look = PositionAndLook(
|
pos_look = PositionAndLook(
|
||||||
position=(Vector(68.0, 38.0, 76.0) if protocol_version >= 100
|
position=(Vector(68.0, 38.0, 76.0)
|
||||||
else Vector(68, 38, 76)),
|
if context.protocol_later_eq(100) else
|
||||||
|
Vector(68, 38, 76)),
|
||||||
yaw=263.494, pitch=180)
|
yaw=263.494, pitch=180)
|
||||||
velocity = Vector(21, 55, 41)
|
velocity = Vector(21, 55, 41)
|
||||||
entity_id, type_name, type_id = 49846, 'EGG', EntityType.EGG
|
entity_id, type_name, type_id = 49846, 'EGG', EntityType.EGG
|
||||||
@ -252,7 +253,7 @@ class TestReadWritePackets(unittest.TestCase):
|
|||||||
velocity_x=velocity.x, velocity_y=velocity.y,
|
velocity_x=velocity.x, velocity_y=velocity.y,
|
||||||
velocity_z=velocity.z,
|
velocity_z=velocity.z,
|
||||||
entity_id=entity_id, type_id=type_id, data=1)
|
entity_id=entity_id, type_id=type_id, data=1)
|
||||||
if protocol_version >= 49:
|
if context.protocol_later_eq(49):
|
||||||
object_uuid = 'd9568851-85bc-4a10-8d6a-261d130626fa'
|
object_uuid = 'd9568851-85bc-4a10-8d6a-261d130626fa'
|
||||||
packet.object_uuid = object_uuid
|
packet.object_uuid = object_uuid
|
||||||
self.assertEqual(packet.objectUUID, object_uuid)
|
self.assertEqual(packet.objectUUID, object_uuid)
|
||||||
@ -267,12 +268,12 @@ class TestReadWritePackets(unittest.TestCase):
|
|||||||
"object_uuid='d9568851-85bc-4a10-8d6a-261d130626fa', "
|
"object_uuid='d9568851-85bc-4a10-8d6a-261d130626fa', "
|
||||||
"type_id=EGG, x=68.0, y=38.0, z=76.0, pitch=180, yaw=263.494, "
|
"type_id=EGG, x=68.0, y=38.0, z=76.0, pitch=180, yaw=263.494, "
|
||||||
"data=1, velocity_x=21, velocity_y=55, velocity_z=41)"
|
"data=1, velocity_x=21, velocity_y=55, velocity_z=41)"
|
||||||
% packet.id if protocol_version >= 100 else
|
% packet.id if context.protocol_later_eq(100) else
|
||||||
"0x%02X SpawnObjectPacket(entity_id=49846, "
|
"0x%02X SpawnObjectPacket(entity_id=49846, "
|
||||||
"object_uuid='d9568851-85bc-4a10-8d6a-261d130626fa', "
|
"object_uuid='d9568851-85bc-4a10-8d6a-261d130626fa', "
|
||||||
"type_id=EGG, x=68, y=38, z=76, pitch=180, yaw=263.494, "
|
"type_id=EGG, x=68, y=38, z=76, pitch=180, yaw=263.494, "
|
||||||
"data=1, velocity_x=21, velocity_y=55, velocity_z=41)"
|
"data=1, velocity_x=21, velocity_y=55, velocity_z=41)"
|
||||||
% packet.id if protocol_version >= 49 else
|
% packet.id if context.protocol_later_eq(49) else
|
||||||
"0x%02X SpawnObjectPacket(entity_id=49846, type_id=EGG, "
|
"0x%02X SpawnObjectPacket(entity_id=49846, type_id=EGG, "
|
||||||
"x=68, y=38, z=76, pitch=180, yaw=263.494, data=1, "
|
"x=68, y=38, z=76, pitch=180, yaw=263.494, data=1, "
|
||||||
"velocity_x=21, velocity_y=55, velocity_z=41)" % packet.id
|
"velocity_x=21, velocity_y=55, velocity_z=41)" % packet.id
|
||||||
@ -282,7 +283,7 @@ class TestReadWritePackets(unittest.TestCase):
|
|||||||
context=context, position_and_look=pos_look,
|
context=context, position_and_look=pos_look,
|
||||||
velocity=velocity, type=type_name,
|
velocity=velocity, type=type_name,
|
||||||
entity_id=entity_id, data=1)
|
entity_id=entity_id, data=1)
|
||||||
if protocol_version >= 49:
|
if context.protocol_later_eq(49):
|
||||||
packet2.object_uuid = object_uuid
|
packet2.object_uuid = object_uuid
|
||||||
self.assertEqual(packet.__dict__, packet2.__dict__)
|
self.assertEqual(packet.__dict__, packet2.__dict__)
|
||||||
|
|
||||||
@ -290,7 +291,7 @@ class TestReadWritePackets(unittest.TestCase):
|
|||||||
self.assertEqual(packet.position, packet2.position)
|
self.assertEqual(packet.position, packet2.position)
|
||||||
|
|
||||||
packet2.data = 0
|
packet2.data = 0
|
||||||
if protocol_version < 49:
|
if context.protocol_earlier(49):
|
||||||
del packet2.velocity
|
del packet2.velocity
|
||||||
self._test_read_write_packet(packet, context,
|
self._test_read_write_packet(packet, context,
|
||||||
yaw=360/256, pitch=360/256)
|
yaw=360/256, pitch=360/256)
|
||||||
@ -304,11 +305,11 @@ class TestReadWritePackets(unittest.TestCase):
|
|||||||
packet = clientbound.play.SoundEffectPacket(
|
packet = clientbound.play.SoundEffectPacket(
|
||||||
sound_id=545, effect_position=Vector(0.125, 300.0, 50.5),
|
sound_id=545, effect_position=Vector(0.125, 300.0, 50.5),
|
||||||
volume=0.75)
|
volume=0.75)
|
||||||
if protocol_version >= 201:
|
if context.protocol_later_eq(201):
|
||||||
packet.pitch = struct.unpack('f', struct.pack('f', 1.5))[0]
|
packet.pitch = struct.unpack('f', struct.pack('f', 1.5))[0]
|
||||||
else:
|
else:
|
||||||
packet.pitch = int(1.5 / 63.5) * 63.5
|
packet.pitch = int(1.5 / 63.5) * 63.5
|
||||||
if context.protocol_version >= 95:
|
if context.protocol_later_eq(95):
|
||||||
packet.sound_category = \
|
packet.sound_category = \
|
||||||
clientbound.play.SoundEffectPacket.SoundCategory.NEUTRAL
|
clientbound.play.SoundEffectPacket.SoundCategory.NEUTRAL
|
||||||
|
|
||||||
@ -321,19 +322,20 @@ class TestReadWritePackets(unittest.TestCase):
|
|||||||
packet = clientbound.play.FacePlayerPacket(context)
|
packet = clientbound.play.FacePlayerPacket(context)
|
||||||
packet.target = 1.0, -2.0, 3.5
|
packet.target = 1.0, -2.0, 3.5
|
||||||
packet.entity_id = None
|
packet.entity_id = None
|
||||||
if protocol_version >= 353:
|
if context.protocol_later_eq(353):
|
||||||
packet.origin = OriginPoint.EYES
|
packet.origin = OriginPoint.EYES
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
str(packet),
|
str(packet),
|
||||||
"0x%02X FacePlayerPacket(origin=EYES, x=1.0, y=-2.0, z=3.5, "
|
"0x%02X FacePlayerPacket(origin=EYES, x=1.0, y=-2.0, z=3.5, "
|
||||||
"entity_id=None)" % packet.id if protocol_version >= 353 else
|
"entity_id=None)" % packet.id
|
||||||
|
if context.protocol_later_eq(353) else
|
||||||
"0x%02X FacePlayerPacket(entity_id=None, x=1.0, y=-2.0, z=3.5)"
|
"0x%02X FacePlayerPacket(entity_id=None, x=1.0, y=-2.0, z=3.5)"
|
||||||
% packet.id
|
% packet.id
|
||||||
)
|
)
|
||||||
self._test_read_write_packet(packet, context)
|
self._test_read_write_packet(packet, context)
|
||||||
|
|
||||||
packet.entity_id = 123
|
packet.entity_id = 123
|
||||||
if protocol_version >= 353:
|
if context.protocol_later_eq(353):
|
||||||
packet.entity_origin = OriginPoint.FEET
|
packet.entity_origin = OriginPoint.FEET
|
||||||
else:
|
else:
|
||||||
del packet.target
|
del packet.target
|
||||||
@ -341,7 +343,7 @@ class TestReadWritePackets(unittest.TestCase):
|
|||||||
str(packet),
|
str(packet),
|
||||||
"0x%02X FacePlayerPacket(origin=EYES, x=1.0, y=-2.0, z=3.5, "
|
"0x%02X FacePlayerPacket(origin=EYES, x=1.0, y=-2.0, z=3.5, "
|
||||||
"entity_id=123, entity_origin=FEET)" % packet.id
|
"entity_id=123, entity_origin=FEET)" % packet.id
|
||||||
if protocol_version >= 353 else
|
if context.protocol_later_eq(353) else
|
||||||
"0x%02X FacePlayerPacket(entity_id=123)" % packet.id
|
"0x%02X FacePlayerPacket(entity_id=123)" % packet.id
|
||||||
)
|
)
|
||||||
self._test_read_write_packet(packet, context)
|
self._test_read_write_packet(packet, context)
|
||||||
|
@ -55,7 +55,7 @@ class MapPacketTest(unittest.TestCase):
|
|||||||
packet.is_tracking_position = True
|
packet.is_tracking_position = True
|
||||||
packet.is_locked = False
|
packet.is_locked = False
|
||||||
packet.icons = []
|
packet.icons = []
|
||||||
d_name = u'Marshmallow' if context.protocol_version >= 364 else None
|
d_name = u'Marshmallow' if context.protocol_later_eq(364) else None
|
||||||
packet.icons.append(MapPacket.MapIcon(
|
packet.icons.append(MapPacket.MapIcon(
|
||||||
type=2, direction=2, location=(1, 1), display_name=d_name
|
type=2, direction=2, location=(1, 1), display_name=d_name
|
||||||
))
|
))
|
||||||
|
@ -11,7 +11,7 @@ from minecraft.networking.connection import (
|
|||||||
from minecraft.networking.packets import clientbound
|
from minecraft.networking.packets import clientbound
|
||||||
|
|
||||||
|
|
||||||
max_proto_ver = max(SUPPORTED_PROTOCOL_VERSIONS)
|
latest_proto = SUPPORTED_PROTOCOL_VERSIONS[-1]
|
||||||
|
|
||||||
|
|
||||||
class LoginReactorTest(unittest.TestCase):
|
class LoginReactorTest(unittest.TestCase):
|
||||||
@ -19,7 +19,7 @@ class LoginReactorTest(unittest.TestCase):
|
|||||||
@mock.patch('minecraft.networking.connection.encryption')
|
@mock.patch('minecraft.networking.connection.encryption')
|
||||||
def test_encryption_online_server(self, encrypt):
|
def test_encryption_online_server(self, encrypt):
|
||||||
connection = mock.MagicMock()
|
connection = mock.MagicMock()
|
||||||
connection.context = ConnectionContext(protocol_version=max_proto_ver)
|
connection.context = ConnectionContext(protocol_version=latest_proto)
|
||||||
reactor = LoginReactor(connection)
|
reactor = LoginReactor(connection)
|
||||||
|
|
||||||
packet = clientbound.login.EncryptionRequestPacket()
|
packet = clientbound.login.EncryptionRequestPacket()
|
||||||
@ -43,7 +43,7 @@ class LoginReactorTest(unittest.TestCase):
|
|||||||
@mock.patch('minecraft.networking.connection.encryption')
|
@mock.patch('minecraft.networking.connection.encryption')
|
||||||
def test_encryption_offline_server(self, encrypt):
|
def test_encryption_offline_server(self, encrypt):
|
||||||
connection = mock.MagicMock()
|
connection = mock.MagicMock()
|
||||||
connection.context = ConnectionContext(protocol_version=max_proto_ver)
|
connection.context = ConnectionContext(protocol_version=latest_proto)
|
||||||
reactor = LoginReactor(connection)
|
reactor = LoginReactor(connection)
|
||||||
|
|
||||||
packet = clientbound.login.EncryptionRequestPacket()
|
packet = clientbound.login.EncryptionRequestPacket()
|
||||||
|
3
tox.ini
3
tox.ini
@ -50,7 +50,8 @@ deps =
|
|||||||
|
|
||||||
[flake8]
|
[flake8]
|
||||||
per-file-ignores =
|
per-file-ignores =
|
||||||
*/clientbound/play/spawn_object_packet.py:E221,E222,E271,E272
|
*/clientbound/play/spawn_object_packet.py:E221,E222,E271,E272,E201
|
||||||
|
minecraft/networking/packets/__init__.py:F401
|
||||||
|
|
||||||
[testenv:pylint-errors]
|
[testenv:pylint-errors]
|
||||||
basepython = python3.8
|
basepython = python3.8
|
||||||
|
Loading…
Reference in New Issue
Block a user