Metadata-Version: 2.4
Name: minecraft-protocolo-py
Version: 0.1.1
Summary: Multi-version Minecraft Java Edition client/server protocol library, built on protolib + minecraft-data
Author: Xd
License: MIT
Project-URL: Homepage, https://pypi.org/project/protolib/
Keywords: minecraft,protocol,minecraft-data,protodef,protolib,bot,server,networking
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Games/Entertainment
Classifier: Topic :: Internet
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: protolib>=0.3.7

# minecraft-protocolo-py

A multi-version Minecraft Java Edition client/server protocol library
for Python, built on top of two existing pieces instead of
reinventing them:

- **[protolib](https://pypi.org/project/protolib/)** — the generic
  binary protocol engine (reads/writes packets from JSON/YAML schema
  definitions, in the `node-protodef` / `minecraft-data` format).
- **[minecraft-data](https://github.com/PrismarineJS/minecraft-data)**
  — the actual per-version packet definitions (`protocol.json`), the
  same dataset used by `node-minecraft-protocol`.

`minecraft_protocolo` is the missing glue layer: pick a Minecraft
version, get a working `Client` or `Server` that speaks that
version's wire protocol — handshake, login, compression, keep-alive,
and error handling included.

```
protolib  (generic protocol engine)
    │
minecraft-data  (per-version protocol.json definitions)
    │
minecraft_protocolo  (this library: Client / Server / version resolver)
    │
your own app  (game logic only)
```

## Install

```bash
pip install protolib
pip install pip install minecraft-protocolo-py
```

`protolib` is a separate, real dependency — it is never vendored or
copied into this package.

## Supported versions

Any Minecraft Java Edition version between **1.7** and **1.16.5**
that ships with the bundled `minecraft-data` snapshot (35 versions in
total). Well-known build aliases that people actually type — `1.8.9`,
`1.7.10` — resolve automatically to the entry minecraft-data tracks
internally (`1.8`, `1.7`), since the network protocol never changed
between those builds.

```python
from minecraft_protocolo import VersionResolver

resolver = VersionResolver()
resolver.list_versions()              # ['1.7', '1.8', ..., '1.16.5']
resolver.protocol_version_number("1.8.9")   # 47
```

## Quick start — client

```python
from minecraft_protocolo import Client

client = Client(host="localhost", port=25565, username="Xd", version="1.8.9")

@client.on("connect")
def on_connect():
    print("connected!")

@client.on("packet")
def on_packet(name, params):
    if name == "chat":
        print("chat:", params["message"])

client.on("error", lambda e: print("error:", e))
client.on("kicked", lambda reason: print("kicked:", reason))

client.connect()  # blocks; pass background=True to run in a thread
```

Keep-alive is handled automatically (the client answers the server's
`keep_alive` packets on its own — no need to do it in your handler).
Compression is detected and applied automatically as soon as the
server sends `set_compression` during login.

## Quick start — server

```python
from minecraft_protocolo import Server

server = Server(host="0.0.0.0", port=25565, version="1.8.9",
                 motd="my server", max_players=20)

@server.on("login")
def on_login(conn):
    print(conn.username, "joined —", conn.uuid)

@server.on("packet")
def on_packet(conn, name, params):
    if name == "chat":
        print(conn.username, ":", params["message"])

server.on("error", lambda e, conn=None: print("error:", e))

server.listen()  # blocks
```

The server answers server-list pings (MOTD, player count, protocol
version) and sends its own periodic `keep_alive`, kicking players who
stop responding — same defaults as `node-minecraft-protocol`
(`keepAlive=True`, 4s ping interval, 10s kick timeout).

`online_mode=True` (real Mojang/MSA authentication + encryption) is
not implemented yet; the server explicitly refuses that config
instead of pretending to support it.

## Examples

`examples/client.py` and `examples/server.py` are runnable, tested
reference implementations built on the library — game logic only,
none of the networking (that's all handled by `Client`/`Server`):

```bash
# a chat bot that responds to !hello and !ping
python examples/client.py <host> <port> <username> [version]

# a genuinely playable flat-world server: real client can log in,
# walk around, and use chat commands (!ping, !online, !spawn,
# !creative, !survival)
python examples/server.py --port 25565 --version 1.8.9 --motd "my server"
```

These are meant as a starting point to copy from, not a CLI you're
expected to use as-is — real projects put their own game logic on top
of `Client`/`Server` directly.

## Error handling

Deserialization failures are wrapped to match the format used by
`node-minecraft-protocol` (`PartialReadError`), so anyone familiar
with that library will recognize the shape immediately:

```
PartialReadError: Deserialization error for play.toClient : Read error : buffer exhausted at offset=5: needed 1 bytes, 0 remaining
```

`Client`/`Server` never raise these directly into your code — they're
emitted through the `error` event, same as Node's `EventEmitter`
convention (an unhandled `'error'` event still gets printed to
stderr instead of silently disappearing).

## Discovering the packet API

The API is the `protocol.json` for whatever version you loaded — not
a fixed list this README could show (74 packets just for `play.toClient`
in 1.8, times 35 bundled versions). Field names are also
case-sensitive and don't always match what the wiki or another bot
would lead you to expect (`gameMode` not `gamemode`, `flyingSpeed`
not `flySpeed`). Two ways to find the real name for the version
you're using:

```python
# From a live connection (Client or Server's ClientConnection) --
# always exact for whatever version was actually negotiated:
print(client.list_packet_names())          # every valid play.toServer packet name
print(conn.list_packet_names("play", "toClient"))  # play.toClient for a server connection

# Or straight from the bundled data, no connection needed (strip the
# "packet_" prefix and the internal "packet" dispatcher entry itself):
import json
with open("minecraft_protocolo/data/pc/1.8/protocol.json") as f:
    proto = json.load(f)
names = [k[len("packet_"):] for k in proto["play"]["toClient"]["types"] if k.startswith("packet_")]
print(names)
```

Sending a name that doesn't exist raises `UnknownPacketError` instead
of a confusing low-level error, and lists the valid names for that
state. A wrong or missing *field* inside otherwise-correct `params`
raises `SerializationError` with a hint pointing at `protocol.json`.

## What's implemented

- Handshake, login (offline-mode), status/server-list ping
- zlib packet compression, detected and applied automatically
- Automatic keep-alive, both directions, with timeout/kick handling
- Multi-version support in a single `Server` (`version=None`) —
  resolves each connecting client's version from its handshake
  `protocolVersion`
- `node-minecraft-protocol`-style error formatting

## What's not implemented yet

- `online_mode=True` (Mojang/MSA auth + AES encryption) — this one
  *is* a library limitation, `Server`/`Client` don't support it yet.
- Bedrock Edition (only Java/"pc" protocols are wired up) — also a
  library limitation.

None of the above is the library's job, and intentionally so — world
state, chunks, entity spawning, and physics are **game logic**, which
lives in your own code on top of `Client`/`Server`, not in
`minecraft_protocolo` itself. `examples/server.py` shows a working
approach (flat world, chunks, tab list) that a real client can
actually join and walk around in — extend that pattern for anything
beyond a flat world.

## Project layout

```
minecraft_protocolo/
├── __init__.py
├── version_resolver.py   # "1.12.2" -> a loaded protolib.Protocol
├── client.py              # Client: connect, handshake, login, events
├── server.py               # Server: accept connections, per-player events
├── errors.py                # PartialReadError and friends
├── events.py                  # small Node-style EventEmitter
└── data/                        # bundled minecraft-data (dataPaths.json + pc/)

examples/
├── client.py                     # chat bot example
└── server.py                      # playable flat-world server example

pyproject.toml
```
