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