Changelog¶
Major and minor releases also include the changes specified in prior development releases.
Tip
Feel free to skip the Internal Changes category if you aren't a contributor / core developer of mcproto.
#257: Added the #476: Added #300: Update CI #323: Enable various other ruff rules as a part of switching to blacklist model, where we explicitly disable the rules we don't want, rather than enabling dozens of rule groups individually.Unreleased Changes
Version v0.5.0-394-g48893 (2025-08-05)¶
Breaking Changes¶
Features¶
InvalidPacketContentError exception, raised when deserializing of a specific packet fails. This error inherits from IOError, making it backwards compatible with the original implementation.NBTag to deal with NBT data
NBTag class is the base class for all NBT tags and provides the basic functionality to serialize and deserialize NBT data from and to a Buffer object.EndNBT, ByteNBT, ShortNBT, IntNBT, LongNBT, FloatNBT, DoubleNBT, ByteArrayNBT, StringNBT, ListNBT, CompoundNBT, IntArrayNBTand LongArrayNBT were added and correspond to the NBT types described in the NBT specification.NBTag.from_object() method and a schema that describes the NBT tag structure.
Compound tags are represented as dictionaries, list tags as lists, and primitive tags as their respective Python types.
The implementation allows to add custom classes to the schema to handle custom NBT tags if they inherit the :class: NBTagConvertible class.NBTag.to_object() method can be used to convert an NBT tag back to a Python object. Use include_schema=True to include the schema in the output, and include_name=True to include the name of the tag in the output. In that case the output will be a dictionary with a single key that is the name of the tag and the value is the object representation of the tag.NBTag.serialize() can be used to serialize an NBT tag to a new Buffer object.NBTag.deserialize(buffer) can be used to deserialize an NBT tag from a Buffer object.NBTag.write_to(buffer, with_type=True, with_name=True) method can be used to write the NBT tag to the buffer (and in that case with the type and name in the right format).NBTag.read_from(buffer, with_type=True, with_name=True) method can be used to read an NBT tag from the buffer (and in that case with the type and name in the right format).NBTag.value property can be used to get the value of the NBT tag as a Python object.LoginAcknowledged packet implementationLoginStart packet to latest protocol version (uuid no longer optional)Bugfixes¶
mcproto.utils.deprecation module, which was incorrectly always using a fallback version, assuming mcproto is at version 0.0.0. This then could've meant that using a deprecated feature that is past the specified deprecation (removal) version still only resulted in a deprecation warning, as opposed to a full runtime error.Documentation Improvements¶
Internal Changes¶
typing.override decorator (see PEP 698)
gen_serializable_test function to generate tests for serializable classes, covering serialization, deserialization, validation, and error handling.Serializable class
--output-format=github for ruff check in the validation workflowpyright to basedpyright
CONTRIBUTING.md..editorconfig file, defining some basic configuration for the project, which editors can automatically pick up on (i.e. indent size).
Version 0.5.0 (2023-08-10)¶
Breaking Changes¶
-
#130: Renamed "shared_key" field to "shared_secret" in
LoginEncryptionPacket, following the official terminology.- This is a breaking change,
LoginEncryptionPacket's__init__method now uses "shared_secret" keyword only argument, not "shared_key".
- This is a breaking change,
-
#130: The
LoginStartpacket now contains a (required) UUID field (which can be explicitly set toNone).- For some reason, this field was not added when the login packets were introduced initially, and while the UUID field can indeed be omitted in some cases (it is an optional filed), in vast majority of cases, it will be present, and we should absolutely support it.
- As this is a new required field, the
__init__function ofLoginStartnow also expects thisuuidkeyword argument to be present, making this a breaking change.
-
#159: Fix packet compression handling in the interaction methods.
This fixes a bug that didn't allow for specifying an exact compression threshold that the server specified in
LoginSetCompressionpacket, and instead only allowing to toggle between compression on/off, which doesn't really work as server doesn't expect compression for packets below that threshold.sync_write_packet,async_write_pakcet,sync_read_packetandasync_read_packetfunctions now takecompression_thresholdinstead ofcompressedbool flag
-
#161:
LoginEncryptionRequestnow usescryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKeyto hold the public key, instead of just purebytes. Encoding and decoding of this key happens automatically during serialize/deserialize. This is a breaking change for anyone relying on thepublic_keyfield from this packet beingbytes, and for anyone initializing this packet directly with__init__, which now expectsRSAPublicKeyinstance instead.
Features¶
- #129: Added a system for handling Minecraft authentication
- Yggdrasil system for unmigrated i.e. non-Microsoft accounts (supportng Minecraft accounts, and the really old Mojang accounts)
- Microsoft OAuth2 system (Xbox live) for migrated i.e. Microsoft accounts
- #160: Re-export the packet classes (or any other objects) from the gamestate modules (
mcproto.packets.handshaking/mcproto.packets.login/...) directly. Allowing simpler imports (from mcproto.packets.login import LoginStartinstead offrom mcproto.packets.login.login import LoginStart) - #161: Add support for encryption. Connection classes now have
enable_encryptionmethod, and some encryption related functions were added into a newmcproto.encryptionmodule. - #168: Add multiplayer related functionalities for requesting and checking joins for original (bought) minecraft accounts. This allows us to join online servers.
- #171: Add
Account.checkfunction, to verify that the access token in use is valid, and the data the Account instance has matches the data minecraft API has.
Bugfixes¶
- #130:
LoginEncryptionResponsenow includes theserver_idfield. This field was previously hard-coded to 20 spaces (blank value), which is what all minecraft clients on minecraft 1.7.x or higher do, however with older versions, this field is set to 20 random characters, which we should respect.- This is not a breaking change, as
server_idwill default toNoneinLoginEncryptionResponse's__init__, meaning any existing code utilizing this packet will still work. It is purely an additional option.
- This is not a breaking change, as
- #167: Fix packet reading/writing when compression is enabled (use zlib as expected, instead of gzip which we were using before)
- #170: Preserve the call parameters and overloads in the typing signature of
mcproto.packets.packet_map.generate_packet_mapfunction. (This wasn't the case before, sincefunctools.lru_cachedoesn't preserve this data). Note that this loses on the typing information about the cache itself, as now it will appear to be a regular uncached function to the type-checker. We deemed this approach better to the alternative of no typing info for call arguments or overloads, but preserving cache info.
Documentation Improvements¶
- #129: Mention lack of synchronous alternatives for certain functions (see issue #128)
- #139: Add a warning in version guarantees page, explaining pre-release guarantees (breaking changes in minor versions allowed)
- #141: Move installation instructions from README to Installation docs page
-
#144: Add attributetable internal sphinx extension for showing all attributes and methods for specified classes.
- This adds
attributetablesphinx directive, which can be used before autodoc directive. This will create the attribute table, which will get dynamically moved right below the class definition from autodoc (using javascript). - This extension was implemented by discord.py, this is just re-using that code, with some modifications to fit our code style and to fit the documentation design (furo theme).
- This adds
-
Updated contributing guidelines (restructure and rewrite some categories, to make it more readable)
Internal Changes¶
- #133: Enable enforcement of some optional pyright rules
- #153: Replace flake8 linter with ruff (mostly equivalent, but much faster and configurable from pyproject.toml)
-
#154: Enforce various new ruff linter rules:
- PGH: pygrep-hooks (replaces pre-commit version)
- PL: pylint (bunch of typing related linter rules)
- UP: pyupgrade (forces use of the newest possible standards, depending on target version)
- RET: flake8-return (various linter rules related to function returns)
- Q: flake8-quotes (always use double quotes)
- ASYNC: flake8-async (report blocking operations in async functions)
- INT: flake-gettext (gettext related linting rules)
- PTH: flake8-use-pathlib (always prefer pathlib alternatives to the os ones)
- RUF: ruff custom rules (various additional rules created by the ruff linter team)
Version 0.4.0 (2023-06-11)¶
Breaking Changes¶
- #41: Rename
mcproto.packets.abctomcproto.packets.packet - #116: Restructure the project, moving to a single protocol version model
- This change does NOT have a deprecation period, and will very likely break most existing code-bases. However this change is necessary, as multi-version support was unsustainable (see issue #45 for more details)
- Any packets and types will no longer be present in versioned folders (mcproto.packets.v757.xxx), but rather be directly in the parent directory (mcproto.packets.xxx).
- This change doesn't affect manual communication with the server, connection, and basic IO writers/readers remain the same.
Version 0.3.0 (2023-06-08)¶
Features¶
- #54: Add support for LOGIN state packets
LoginStartLoginEncryptionRequestLoginEncryptionResponseLoginSuccessLoginDisconnectLoginPluginRequestLoginPluginResponseLoginSetCompression
Bugfixes¶
- #75: Increase the stack level of warnings shown on protocol version fallbacks
- #113: TCP connections now properly shut down the connection gracefully (TCP FIN)
Documentation Improvements¶
- #2: Add Sphinx and basic docs layout
- #18: Rewrite all docstrings into proper Sphinx format, instead of using markdown.
- #27: Add changelog page to docs, linking
CHANGELOG.md, including unreleased changes from fragments. - #28: Use furo theme for the documentation
- #34: Add version guarantees page
- #40: Move code of conduct to the docs.
- Improve readability of the changelog readme (changes/README.md)
- Mention taskipy
changelog-previewshorthand command - Add category headers splitting things up, for better readability
- Explain how to express multiple changes related to a single goal in a changelog fragment.
- Mention taskipy
- Include
CHANGELOG.mdfile in project's distribution files.
Internal Changes¶
- #12: Replace HassanAbouelela setup-python action with ItsDrike/setup-python in CI workflows
- #17: Start using codeclimate to monitor code coverage and it's changes
- #35: Add more tests
- #38: Replace our implementation of
SemanticVersionwith a community-maintainedsemantic-versionpackage. - #53: Mark all packet classes as
typing.final, making the type-checker enforce existence of concrete implementations for all abstract methods. - #112: Removed
codespelllinter. This proved too annoying, especially when we already have a lot of linters here. Spelling mistakes can simply be caught in the review process. - #114: Use latest poetry version in CI workflows (remove version lock - at 1.3.1)
- The
documentationcategory of changelog was renamed to shorterdocs
Version 0.2.0 (2022-12-30)¶
Features¶
- #14: Add
__slots__to most classes in the project- All connection classes are now slotted
- Classes in
mcproto.utils.abcare now slotted
- Separate packet interaction functions into
mcproto.packets.interactions, (though they're reexported inmcproto.packets, so no breaking changes)
Bugfixes¶
- #14: Add missing
__slots__toServerBoundPacketandClientBoundPacketsubclasses, which inherited from slottedPacket, but didn't themselves define__slots__, causing__dict__to be needlessly created. - The error message produced by
RequiredParamsABCMixinclass when a required no MRO class variable isn't present now includes a previously missing space, making it more readable.
Documentation Improvements¶
Internal Changes¶
- #6: Rework deprecation system
- Drop support for date-based deprecations, versions work better
- Provide
deprecation_warnfunction, which emits warnings directly, no need for a decorator - Add a
SemanticVersionclass, supporting version comparisons - If the project's version is already higher than the specified deprecation removal version, raise a DeprecationWarning as a full exception (rather than just a warning).
- #7: Add towncrier for managing changelog
- #14: Add slotscheck, ensuring
__slots__are defined properly everywhere. - #14: Make
typing-extensionsa runtime dependency and use it directly, don't rely onif typing.TYPE_CHECKINGblocks. - #15: Add codespell tool, to automatically find spelling mistakes.
- Add README file into the
tests/folder, explaining how we use unit-tests and some basics of testing. - Add
CustomMockMixininternal class, inheriting fromUnpropagatingMockMixin, but also allowing to usespec_setas class variable, as it will automatically pass it into__init__of the mock class. - Add several new flake8 extensions, and rework flake8 config file
- Add support for specifying what child mock type to propagate in
UnpropagatingMockMixinclass (for unit-tests).
The changelog was added during development of 0.2.0, so nothing prior is documented here. Try checking the GitHub releases, or git commit history directly.