mcpy-core 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. mcpy_core-1.0.0/LICENSE +21 -0
  2. mcpy_core-1.0.0/PKG-INFO +253 -0
  3. mcpy_core-1.0.0/README.md +220 -0
  4. mcpy_core-1.0.0/mcpy_core.egg-info/PKG-INFO +253 -0
  5. mcpy_core-1.0.0/mcpy_core.egg-info/SOURCES.txt +56 -0
  6. mcpy_core-1.0.0/mcpy_core.egg-info/dependency_links.txt +1 -0
  7. mcpy_core-1.0.0/mcpy_core.egg-info/requires.txt +8 -0
  8. mcpy_core-1.0.0/mcpy_core.egg-info/top_level.txt +1 -0
  9. mcpy_core-1.0.0/mcpycore/__init__.py +127 -0
  10. mcpy_core-1.0.0/mcpycore/client/__init__.py +1 -0
  11. mcpy_core-1.0.0/mcpycore/client/client.py +615 -0
  12. mcpy_core-1.0.0/mcpycore/client/connection.py +262 -0
  13. mcpy_core-1.0.0/mcpycore/client/reconnect.py +118 -0
  14. mcpy_core-1.0.0/mcpycore/compression/__init__.py +1 -0
  15. mcpy_core-1.0.0/mcpycore/compression/compression.py +120 -0
  16. mcpy_core-1.0.0/mcpycore/crypto/__init__.py +1 -0
  17. mcpy_core-1.0.0/mcpycore/crypto/encryption.py +108 -0
  18. mcpy_core-1.0.0/mcpycore/debug/__init__.py +1 -0
  19. mcpy_core-1.0.0/mcpycore/debug/inspector.py +142 -0
  20. mcpy_core-1.0.0/mcpycore/events/__init__.py +1 -0
  21. mcpy_core-1.0.0/mcpycore/events/emitter.py +265 -0
  22. mcpy_core-1.0.0/mcpycore/extensions/__init__.py +1 -0
  23. mcpy_core-1.0.0/mcpycore/extensions/loader.py +159 -0
  24. mcpy_core-1.0.0/mcpycore/network/__init__.py +1 -0
  25. mcpy_core-1.0.0/mcpycore/network/stream.py +232 -0
  26. mcpy_core-1.0.0/mcpycore/protocol/__init__.py +1 -0
  27. mcpy_core-1.0.0/mcpycore/protocol/handlers/__init__.py +1 -0
  28. mcpy_core-1.0.0/mcpycore/protocol/handlers/dispatcher.py +151 -0
  29. mcpy_core-1.0.0/mcpycore/protocol/packets/__init__.py +1 -0
  30. mcpy_core-1.0.0/mcpycore/protocol/packets/base.py +173 -0
  31. mcpy_core-1.0.0/mcpycore/protocol/registry/__init__.py +1 -0
  32. mcpy_core-1.0.0/mcpycore/protocol/registry/registry.py +132 -0
  33. mcpy_core-1.0.0/mcpycore/protocol/serializers/__init__.py +1 -0
  34. mcpy_core-1.0.0/mcpycore/protocol/serializers/buffer.py +345 -0
  35. mcpy_core-1.0.0/mcpycore/protocol/serializers/nbt.py +252 -0
  36. mcpy_core-1.0.0/mcpycore/protocol/states/__init__.py +1 -0
  37. mcpy_core-1.0.0/mcpycore/protocol/states/machine.py +107 -0
  38. mcpy_core-1.0.0/mcpycore/protocol/versions/__init__.py +1 -0
  39. mcpy_core-1.0.0/mcpycore/protocol/versions/adapters/__init__.py +31 -0
  40. mcpy_core-1.0.0/mcpycore/protocol/versions/base.py +125 -0
  41. mcpy_core-1.0.0/mcpycore/protocol/versions/v1_20/__init__.py +4 -0
  42. mcpy_core-1.0.0/mcpycore/protocol/versions/v1_20/packets.py +145 -0
  43. mcpy_core-1.0.0/mcpycore/protocol/versions/v1_21/__init__.py +4 -0
  44. mcpy_core-1.0.0/mcpycore/protocol/versions/v1_21/packets.py +256 -0
  45. mcpy_core-1.0.0/mcpycore/utils/__init__.py +1 -0
  46. mcpy_core-1.0.0/mcpycore/utils/logging.py +88 -0
  47. mcpy_core-1.0.0/mcpycore/utils/metrics.py +128 -0
  48. mcpy_core-1.0.0/pyproject.toml +77 -0
  49. mcpy_core-1.0.0/setup.cfg +4 -0
  50. mcpy_core-1.0.0/tests/test_buffer.py +318 -0
  51. mcpy_core-1.0.0/tests/test_client.py +236 -0
  52. mcpy_core-1.0.0/tests/test_compression.py +139 -0
  53. mcpy_core-1.0.0/tests/test_dispatcher.py +172 -0
  54. mcpy_core-1.0.0/tests/test_encryption.py +107 -0
  55. mcpy_core-1.0.0/tests/test_events.py +257 -0
  56. mcpy_core-1.0.0/tests/test_metrics.py +111 -0
  57. mcpy_core-1.0.0/tests/test_nbt.py +173 -0
  58. mcpy_core-1.0.0/tests/test_protocol.py +323 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Mcpycore Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,253 @@
1
+ Metadata-Version: 2.4
2
+ Name: mcpy-core
3
+ Version: 1.0.0
4
+ Summary: Professional async-first Minecraft Java Edition protocol framework (1.20.2 – 1.21.11)
5
+ Author: McPy-Core Contributors
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/your-org/mcpy-core
8
+ Project-URL: Documentation, https://github.com/your-org/mcpy-core/blob/main/docs/quickstart.md
9
+ Project-URL: Issues, https://github.com/your-org/mcpy-core/issues
10
+ Project-URL: Changelog, https://github.com/your-org/mcpy-core/blob/main/CHANGELOG.md
11
+ Keywords: minecraft,protocol,client,bot,async,asyncio,java-edition,mc,framework
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Framework :: AsyncIO
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Games/Entertainment
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Classifier: Typing :: Typed
22
+ Requires-Python: >=3.11
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: cryptography>=41.0.0
26
+ Provides-Extra: dev
27
+ Requires-Dist: pytest>=8.0; extra == "dev"
28
+ Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
29
+ Requires-Dist: black>=24.0; extra == "dev"
30
+ Requires-Dist: mypy>=1.8; extra == "dev"
31
+ Requires-Dist: ruff>=0.3; extra == "dev"
32
+ Dynamic: license-file
33
+
34
+ # McPy-Core
35
+
36
+ **Professional async-first Minecraft Java Edition protocol library.**
37
+
38
+ [![Python 3.12+](https://img.shields.io/badge/python-3.12%2B-blue.svg)](https://www.python.org/)
39
+ [![Protocol](https://img.shields.io/badge/MC%20protocol-764–775-green.svg)](https://wiki.vg/Protocol)
40
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
41
+
42
+ McPy-Core is a clean, scalable, production-quality Minecraft protocol framework for Python 3.12+. Build bots, automation tools, custom clients, protocol research tools, and servers with a modern async API.
43
+
44
+ ```python
45
+ import asyncio
46
+ from mcpycore import MinecraftClient
47
+
48
+ async def main():
49
+ client = MinecraftClient("play.example.com", username="BotName")
50
+
51
+ @client.event
52
+ async def on_chat(message, sender):
53
+ print(f"[{sender}] {message}")
54
+ if message == "ping":
55
+ await client.send_chat("pong!")
56
+
57
+ await client.start()
58
+
59
+ asyncio.run(main())
60
+ ```
61
+
62
+ ---
63
+
64
+ ## Features
65
+
66
+ | Feature | Details |
67
+ |---|---|
68
+ | **Async-first** | Built on `asyncio` — no threads, no blocking calls |
69
+ | **Event-driven API** | `@client.event` decorators or `client.on(event, handler)` |
70
+ | **Multi-version** | Minecraft 1.20.2 → 1.21.11 (protocols 764–775 + snapshots) |
71
+ | **Packet system** | Typed packets with `@packet` decorator + auto-registration |
72
+ | **Encryption** | AES-128-CFB8 (online & offline mode) |
73
+ | **Compression** | zlib with configurable threshold |
74
+ | **Reconnect policies** | Fixed delay, exponential back-off, infinite retry |
75
+ | **Extension system** | Plugin modules with `setup()` / `teardown()` |
76
+ | **Packet inspector** | Real-time `[RECV]`/`[SEND]` logging + hex dump |
77
+ | **Metrics** | Latency tracking, packet counters, uptime |
78
+ | **NBT parser** | All 13 tag types, nested compounds, `nbt_to_dict()` |
79
+ | **Strong typing** | Full type hints throughout |
80
+ | **Test suite** | 200+ tests with zero external dependencies |
81
+
82
+ ---
83
+
84
+ ## Installation
85
+
86
+ ```bash
87
+ pip install mcpy-core
88
+ ```
89
+
90
+ Or from source:
91
+
92
+ ```bash
93
+ git clone https://github.com/your-org/mcpy-core.git
94
+ cd mcpy-core
95
+ pip install -e ".[dev]"
96
+ ```
97
+
98
+ **Requirements:** Python 3.12+, `cryptography`
99
+
100
+ ---
101
+
102
+ ## Quick Examples
103
+
104
+ ### Server status ping (no login required)
105
+
106
+ ```python
107
+ from examples.server_status import ping
108
+ import asyncio
109
+
110
+ data = asyncio.run(ping("play.hypixel.net"))
111
+ print(data["version"]["name"]) # "Paper 1.21.1"
112
+ print(data["players"]["online"]) # 45000
113
+ print(f"{data['latency_ms']}ms")
114
+ ```
115
+
116
+ ### Position + movement
117
+
118
+ ```python
119
+ @client.event
120
+ async def on_spawn(x, y, z):
121
+ print(f"Spawned at ({x:.1f}, {y:.1f}, {z:.1f})")
122
+ await client.move(x + 5, y, z)
123
+ await client.look(yaw=90.0, pitch=-20.0)
124
+ ```
125
+
126
+ ### Auto-reconnect
127
+
128
+ ```python
129
+ from mcpycore.client.reconnect import ExponentialBackoff
130
+
131
+ client = MinecraftClient(
132
+ "play.example.com",
133
+ reconnect_policy=ExponentialBackoff(base_delay=1.0, max_delay=60.0),
134
+ )
135
+ ```
136
+
137
+ ### Custom packets
138
+
139
+ ```python
140
+ from mcpycore import Packet, packet, PacketBuffer, State
141
+ from mcpycore.protocol.registry.registry import Direction
142
+
143
+ @packet(packet_id=0x05, state=State.PLAY, direction=Direction.SERVERBOUND)
144
+ class ChatMessage(Packet):
145
+ message: str = ""
146
+
147
+ def encode(self) -> bytes:
148
+ buf = PacketBuffer()
149
+ buf.write_string(self.message)
150
+ return buf.flush()
151
+ ```
152
+
153
+ ### Extensions / plugins
154
+
155
+ ```python
156
+ # greet_extension.py
157
+ async def setup(client):
158
+ @client.on("spawn")
159
+ async def on_spawn(x, y, z):
160
+ await client.send_chat("Hello from my extension!")
161
+
162
+ async def teardown(client):
163
+ print("Extension unloaded")
164
+ ```
165
+
166
+ ```python
167
+ client.load_extension("greet_extension")
168
+ client.unload_extension("greet_extension")
169
+ ```
170
+
171
+ ---
172
+
173
+ ## Project Structure
174
+
175
+ ```
176
+ mcpycore/
177
+ ├── client/
178
+ │ ├── client.py ← MinecraftClient — high-level async API
179
+ │ ├── connection.py ← TCP handshake → login → play lifecycle
180
+ │ └── reconnect.py ← Reconnect policy hierarchy
181
+ ├── protocol/
182
+ │ ├── packets/
183
+ │ │ └── base.py ← Packet base + @packet decorator
184
+ │ ├── serializers/
185
+ │ │ ├── buffer.py ← PacketBuffer (all primitives)
186
+ │ │ └── nbt.py ← NBT parser
187
+ │ ├── registry/
188
+ │ │ └── registry.py ← PacketRegistry (version-aware)
189
+ │ ├── states/
190
+ │ │ └── machine.py ← Protocol state machine
191
+ │ ├── handlers/
192
+ │ │ └── dispatcher.py ← PacketDispatcher + middleware
193
+ │ └── versions/
194
+ │ ├── base.py ← VersionAdapter + version constants
195
+ │ ├── v1_20/ ← ID tables for protocols 764–766
196
+ │ └── v1_21/ ← ID tables for protocols 767–775
197
+ ├── network/
198
+ │ └── stream.py ← AsyncStream (framing/crypto/compression)
199
+ ├── events/
200
+ │ └── emitter.py ← AsyncEventEmitter + Events constants
201
+ ├── crypto/
202
+ │ └── encryption.py ← EncryptionManager (AES-128-CFB8)
203
+ ├── compression/
204
+ │ └── compression.py ← CompressionManager (zlib)
205
+ ├── debug/
206
+ │ └── inspector.py ← PacketInspector (debug logging)
207
+ ├── extensions/
208
+ │ └── loader.py ← ExtensionLoader (plugin system)
209
+ └── utils/
210
+ ├── logging.py ← Structured colour logging
211
+ └── metrics.py ← MetricsCollector
212
+ tests/ ← pytest suite (200+ tests)
213
+ examples/ ← Runnable example scripts
214
+ docs/ ← quickstart.md, architecture.md
215
+ ```
216
+
217
+ ---
218
+
219
+ ## Supported Versions
220
+
221
+ | Minecraft Version | Protocol |
222
+ |---|---|
223
+ | 1.20.2 | 764 |
224
+ | 1.20.4 | 765 |
225
+ | 1.20.6 | 766 |
226
+ | 1.21 / 1.21.1 | 767 |
227
+ | 1.21.2 / 1.21.3 | 768 |
228
+ | 1.21.4 | 769 |
229
+ | 1.21.5–1.21.11 | 770–775 |
230
+ | Snapshots | Auto-fallback to nearest stable |
231
+
232
+ ---
233
+
234
+ ## Testing
235
+
236
+ ```bash
237
+ pytest tests/ -v
238
+ ```
239
+
240
+ The suite covers: `PacketBuffer`, NBT, events, compression, encryption, state machine, registry, dispatcher, client, and metrics.
241
+
242
+ ---
243
+
244
+ ## Documentation
245
+
246
+ - [`docs/quickstart.md`](docs/quickstart.md) — getting started guide
247
+ - [`docs/architecture.md`](docs/architecture.md) — design overview and layer diagram
248
+
249
+ ---
250
+
251
+ ## License
252
+
253
+ MIT
@@ -0,0 +1,220 @@
1
+ # McPy-Core
2
+
3
+ **Professional async-first Minecraft Java Edition protocol library.**
4
+
5
+ [![Python 3.12+](https://img.shields.io/badge/python-3.12%2B-blue.svg)](https://www.python.org/)
6
+ [![Protocol](https://img.shields.io/badge/MC%20protocol-764–775-green.svg)](https://wiki.vg/Protocol)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
8
+
9
+ McPy-Core is a clean, scalable, production-quality Minecraft protocol framework for Python 3.12+. Build bots, automation tools, custom clients, protocol research tools, and servers with a modern async API.
10
+
11
+ ```python
12
+ import asyncio
13
+ from mcpycore import MinecraftClient
14
+
15
+ async def main():
16
+ client = MinecraftClient("play.example.com", username="BotName")
17
+
18
+ @client.event
19
+ async def on_chat(message, sender):
20
+ print(f"[{sender}] {message}")
21
+ if message == "ping":
22
+ await client.send_chat("pong!")
23
+
24
+ await client.start()
25
+
26
+ asyncio.run(main())
27
+ ```
28
+
29
+ ---
30
+
31
+ ## Features
32
+
33
+ | Feature | Details |
34
+ |---|---|
35
+ | **Async-first** | Built on `asyncio` — no threads, no blocking calls |
36
+ | **Event-driven API** | `@client.event` decorators or `client.on(event, handler)` |
37
+ | **Multi-version** | Minecraft 1.20.2 → 1.21.11 (protocols 764–775 + snapshots) |
38
+ | **Packet system** | Typed packets with `@packet` decorator + auto-registration |
39
+ | **Encryption** | AES-128-CFB8 (online & offline mode) |
40
+ | **Compression** | zlib with configurable threshold |
41
+ | **Reconnect policies** | Fixed delay, exponential back-off, infinite retry |
42
+ | **Extension system** | Plugin modules with `setup()` / `teardown()` |
43
+ | **Packet inspector** | Real-time `[RECV]`/`[SEND]` logging + hex dump |
44
+ | **Metrics** | Latency tracking, packet counters, uptime |
45
+ | **NBT parser** | All 13 tag types, nested compounds, `nbt_to_dict()` |
46
+ | **Strong typing** | Full type hints throughout |
47
+ | **Test suite** | 200+ tests with zero external dependencies |
48
+
49
+ ---
50
+
51
+ ## Installation
52
+
53
+ ```bash
54
+ pip install mcpy-core
55
+ ```
56
+
57
+ Or from source:
58
+
59
+ ```bash
60
+ git clone https://github.com/your-org/mcpy-core.git
61
+ cd mcpy-core
62
+ pip install -e ".[dev]"
63
+ ```
64
+
65
+ **Requirements:** Python 3.12+, `cryptography`
66
+
67
+ ---
68
+
69
+ ## Quick Examples
70
+
71
+ ### Server status ping (no login required)
72
+
73
+ ```python
74
+ from examples.server_status import ping
75
+ import asyncio
76
+
77
+ data = asyncio.run(ping("play.hypixel.net"))
78
+ print(data["version"]["name"]) # "Paper 1.21.1"
79
+ print(data["players"]["online"]) # 45000
80
+ print(f"{data['latency_ms']}ms")
81
+ ```
82
+
83
+ ### Position + movement
84
+
85
+ ```python
86
+ @client.event
87
+ async def on_spawn(x, y, z):
88
+ print(f"Spawned at ({x:.1f}, {y:.1f}, {z:.1f})")
89
+ await client.move(x + 5, y, z)
90
+ await client.look(yaw=90.0, pitch=-20.0)
91
+ ```
92
+
93
+ ### Auto-reconnect
94
+
95
+ ```python
96
+ from mcpycore.client.reconnect import ExponentialBackoff
97
+
98
+ client = MinecraftClient(
99
+ "play.example.com",
100
+ reconnect_policy=ExponentialBackoff(base_delay=1.0, max_delay=60.0),
101
+ )
102
+ ```
103
+
104
+ ### Custom packets
105
+
106
+ ```python
107
+ from mcpycore import Packet, packet, PacketBuffer, State
108
+ from mcpycore.protocol.registry.registry import Direction
109
+
110
+ @packet(packet_id=0x05, state=State.PLAY, direction=Direction.SERVERBOUND)
111
+ class ChatMessage(Packet):
112
+ message: str = ""
113
+
114
+ def encode(self) -> bytes:
115
+ buf = PacketBuffer()
116
+ buf.write_string(self.message)
117
+ return buf.flush()
118
+ ```
119
+
120
+ ### Extensions / plugins
121
+
122
+ ```python
123
+ # greet_extension.py
124
+ async def setup(client):
125
+ @client.on("spawn")
126
+ async def on_spawn(x, y, z):
127
+ await client.send_chat("Hello from my extension!")
128
+
129
+ async def teardown(client):
130
+ print("Extension unloaded")
131
+ ```
132
+
133
+ ```python
134
+ client.load_extension("greet_extension")
135
+ client.unload_extension("greet_extension")
136
+ ```
137
+
138
+ ---
139
+
140
+ ## Project Structure
141
+
142
+ ```
143
+ mcpycore/
144
+ ├── client/
145
+ │ ├── client.py ← MinecraftClient — high-level async API
146
+ │ ├── connection.py ← TCP handshake → login → play lifecycle
147
+ │ └── reconnect.py ← Reconnect policy hierarchy
148
+ ├── protocol/
149
+ │ ├── packets/
150
+ │ │ └── base.py ← Packet base + @packet decorator
151
+ │ ├── serializers/
152
+ │ │ ├── buffer.py ← PacketBuffer (all primitives)
153
+ │ │ └── nbt.py ← NBT parser
154
+ │ ├── registry/
155
+ │ │ └── registry.py ← PacketRegistry (version-aware)
156
+ │ ├── states/
157
+ │ │ └── machine.py ← Protocol state machine
158
+ │ ├── handlers/
159
+ │ │ └── dispatcher.py ← PacketDispatcher + middleware
160
+ │ └── versions/
161
+ │ ├── base.py ← VersionAdapter + version constants
162
+ │ ├── v1_20/ ← ID tables for protocols 764–766
163
+ │ └── v1_21/ ← ID tables for protocols 767–775
164
+ ├── network/
165
+ │ └── stream.py ← AsyncStream (framing/crypto/compression)
166
+ ├── events/
167
+ │ └── emitter.py ← AsyncEventEmitter + Events constants
168
+ ├── crypto/
169
+ │ └── encryption.py ← EncryptionManager (AES-128-CFB8)
170
+ ├── compression/
171
+ │ └── compression.py ← CompressionManager (zlib)
172
+ ├── debug/
173
+ │ └── inspector.py ← PacketInspector (debug logging)
174
+ ├── extensions/
175
+ │ └── loader.py ← ExtensionLoader (plugin system)
176
+ └── utils/
177
+ ├── logging.py ← Structured colour logging
178
+ └── metrics.py ← MetricsCollector
179
+ tests/ ← pytest suite (200+ tests)
180
+ examples/ ← Runnable example scripts
181
+ docs/ ← quickstart.md, architecture.md
182
+ ```
183
+
184
+ ---
185
+
186
+ ## Supported Versions
187
+
188
+ | Minecraft Version | Protocol |
189
+ |---|---|
190
+ | 1.20.2 | 764 |
191
+ | 1.20.4 | 765 |
192
+ | 1.20.6 | 766 |
193
+ | 1.21 / 1.21.1 | 767 |
194
+ | 1.21.2 / 1.21.3 | 768 |
195
+ | 1.21.4 | 769 |
196
+ | 1.21.5–1.21.11 | 770–775 |
197
+ | Snapshots | Auto-fallback to nearest stable |
198
+
199
+ ---
200
+
201
+ ## Testing
202
+
203
+ ```bash
204
+ pytest tests/ -v
205
+ ```
206
+
207
+ The suite covers: `PacketBuffer`, NBT, events, compression, encryption, state machine, registry, dispatcher, client, and metrics.
208
+
209
+ ---
210
+
211
+ ## Documentation
212
+
213
+ - [`docs/quickstart.md`](docs/quickstart.md) — getting started guide
214
+ - [`docs/architecture.md`](docs/architecture.md) — design overview and layer diagram
215
+
216
+ ---
217
+
218
+ ## License
219
+
220
+ MIT