Metadata-Version: 2.4
Name: pymcbotlite
Version: 0.2.0
Summary: A lightweight async Python Minecraft bot library for background bots, AFK sessions, and chat relays.
Author: PyMCBotLite contributors
Maintainer: PyMCBotLite contributors
License-Expression: MIT
License-File: LICENSE
Keywords: afk,asyncio,bedrock,bot,chat,discord,minecraft,mineflayer,relay
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet
Classifier: Topic :: Software Development :: Libraries
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: aiohttp>=3.9
Requires-Dist: cryptography>=42
Requires-Dist: dnspython>=2.6
Requires-Dist: typer>=0.12
Provides-Extra: bedrock
Requires-Dist: prompt-toolkit>=3.0; extra == 'bedrock'
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: twine>=5.1; extra == 'dev'
Provides-Extra: discord
Requires-Dist: discord-py>=2.3; extra == 'discord'
Provides-Extra: docs
Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
Requires-Dist: mkdocs>=1.6; extra == 'docs'
Provides-Extra: websocket
Requires-Dist: websockets>=12; extra == 'websocket'
Description-Content-Type: text/markdown

# PyMCBotLite

PyMCBotLite is a lightweight async Python library for Minecraft background bots, chat relays, AFK bots, and simple server-control automation.

It is designed for small bots that need to log in, stay connected, receive chat, send chat/commands, relay messages, and integrate with web or Discord applications. Java Edition support is native Python. Bedrock Edition status pings are native Python; full Bedrock bot sessions are provided through an optional PrismarineJS `bedrock-protocol` bridge so RakNet, Xbox auth, encryption, compression, and packet schemas stay current.

It is not a Mineflayer replacement for pathfinding, full physics, full inventory management, or anti-cheat bypassing.

## Quickstart

Install the library:

```bash
pip install pymcbotlite
```

Ping a Java server:

```bash
pymcbot ping mc.example.com
```

Add a Microsoft/Minecraft account for Java online-mode servers:

```bash
pymcbot auth add main
pymcbot auth list
```

Run a foreground Java chat bot:

```bash
pymcbot run --host mc.example.com --account main
```

Minimal Java bot:

```python
from pymcbotlite import Bot

bot = Bot(host="mc.example.com", account="main")

@bot.event
async def on_ready():
    print(f"Logged in as {bot.username}")
    await bot.chat("Hello from PyMCBotLite!")

@bot.event
async def on_chat(message):
    print("[CHAT]", message.clean)

bot.run()
```

Ping a Bedrock server without Node.js:

```bash
pymcbot bedrock-ping bedrock.example.com
```

Full Bedrock login/chat sessions need the optional Node bridge:

```bash
npm install bedrock-protocol
```

Then use `BedrockBot`:

```python
from pymcbotlite import BedrockBot

bot = BedrockBot(host="bedrock.example.com", username="XboxGamertag")

@bot.event
async def on_auth_code(code):
    print(code.message or f"Open {code.verification_uri} and enter {code.user_code}")

@bot.event
async def on_ready():
    print(f"Logged in as {bot.username}")
    await bot.chat("Hello from PyMCBotLite Bedrock!")

bot.run()
```

Run the Java fight bot example:

```bash
python examples/fight_bot.py mc.example.com main TargetPlayer
```

Run the Bedrock/PE fight bot example:

```bash
python examples/pe/bedrock_fight_bot.py bedrock.example.com XboxGamertag TargetPlayer
```

## Features

- Async-first `Bot` API
- Microsoft paid-account authentication
- Multiple named accounts with local token storage
- Minecraft Java `1.21.5` protocol target
- Native Minecraft Bedrock status ping
- Experimental Minecraft Bedrock `1.26.30` / protocol `1001` bridge
- SRV record discovery for domains like `play.example.com`
- Online-mode login, encryption, compression, keepalive, and resource-pack responses
- Chat receive/send support for compatible servers
- Basic aiming, direct movement, attack, swing, and block-mining controls
- Bounded A* waypoint pathfinding helpers for Java and Bedrock bots
- Java pathfinding can use cached chunk/block data for player clearance, step-up/drop handling, diagonal corner checks, and water/lava avoidance
- Script task controller with `clear_scripts()` helpers
- Health, death, disconnect, kick, reconnect, packet, and chat events
- Basic auto-reconnect and auto-respawn helpers
- CLI tool: `pymcbot`
- Discord, websocket, FastAPI, and multi-account examples
- Pluggable token storage for future database-backed account managers

## Installation

```bash
pip install pymcbotlite
```

Optional extras:

```bash
pip install "pymcbotlite[websocket]"
pip install "pymcbotlite[discord]"
```

Native Bedrock status ping does not require Node.js:

```bash
pymcbot bedrock-ping bedrock.example.com
```

Full Bedrock bot sessions require Node.js and the PrismarineJS Bedrock protocol package in the application environment:

```bash
npm install
```

or, outside this checkout:

```bash
npm install bedrock-protocol
```

From a source checkout:

```bash
python -m pip install -e ".[dev]"
```

## Authentication

Add a Microsoft/Minecraft account:

```bash
pymcbot auth add main
pymcbot auth list
```

If the console script is not on PATH:

```bash
python -m pymcbotlite auth add main
```

Tokens are stored locally:

```txt
~/.pymcbotlite/accounts/main.json
```

Treat account files as secrets. They contain refresh tokens.

## Simple Bot

```python
from pymcbotlite import Bot

bot = Bot(host="mc.example.com", account="main", version="1.21.5")

@bot.event
async def on_ready():
    print(f"Logged in as {bot.username}")
    await bot.chat("Hello from PyMCBotLite!")

@bot.event
async def on_chat(message):
    print("[CHAT]", message.clean)

bot.run()
```

## Bedrock Bot

No-Node status ping:

```python
from pymcbotlite import ping_bedrock

status = await ping_bedrock("bedrock.example.com")
print(status.motd, status.players_online, status.players_max)
```

Full session bridge:

```python
from pymcbotlite import BedrockBot

bot = BedrockBot(
    host="bedrock.example.com",
    port=19132,
    username="XboxGamertag",
)

@bot.event
async def on_auth_code(code):
    print(code.message or f"Open {code.verification_uri} and enter {code.user_code}")

@bot.event
async def on_ready():
    print(f"Logged in as {bot.username}")
    await bot.chat("Hello from PyMCBotLite Bedrock!")

bot.run()
```

Explicit async control:

```python
await bot.login()
await bot.connect("mc.example.com")
await bot.chat("hello")
await bot.disconnect("bye")
```

## Movement, Combat, And Mining

Java `Bot` and Bedrock `BedrockBot` expose the same basic control methods:

```python
await bot.look(90, 0)
await bot.look_at(10.5, 65.5, -2.5)
await bot.move_to(10, 64, -2, stop_distance=1.5)
await bot.move_path_to(10, 64, -2, stop_distance=1.5)  # bounded A*, water-aware on cached Java chunks
await bot.swing_arm()
await bot.attack(target_entity_or_runtime_id)
await bot.mine_block(10, 64, -2)
```

Try the offline water-avoidance pathfinding demo:

```bash
python examples/water_avoidance_pathfinding.py
```

For a simple chase loop, pass a target id, a target dict from `player_visible`, or a callable that returns the current target:

```python
bot.start_fighting(lambda: current_target, reach=3.2, attack_interval=0.7)
bot.stop_fighting()
```

Java examples are in `examples/`; Bedrock/PE examples are in `examples/pe/`.

## Scripts

Use script tasks for cancellable background actions:

```python
task = bot.create_script_task("patrol", patrol_loop(bot))
bot.clear_scripts()
```

## CLI

```bash
pymcbot ping mc.example.com
pymcbot run --host mc.example.com --account main
pymcbot chat --host mc.example.com --account main
```

PATH-free form:

```bash
python -m pymcbotlite ping mc.example.com
python -m pymcbotlite run --host mc.example.com --account main
```

## Events

Decorator style:

```python
@bot.event
async def on_chat(message):
    ...
```

Listener style:

```python
bot.on("chat", callback)
```

Events:

```txt
ready
disconnect
error
chat
system_message
kick
login
reconnect
resource_pack
death
health
packet
entity_visible
player_visible
```

## Web Integration

```python
from fastapi import FastAPI
from pymcbotlite import Bot

app = FastAPI()
bot = Bot(host="mc.example.com", account="main")

@app.on_event("startup")
async def startup():
    await bot.login()
    await bot.connect()

@app.on_event("shutdown")
async def shutdown():
    await bot.disconnect()

@app.post("/chat")
async def send_chat(data: dict):
    await bot.chat(data["message"])
    return {"ok": True}
```

## Discord Relay

```python
@mc_bot.event
async def on_chat(message):
    channel = discord_bot.get_channel(CHANNEL_ID)
    await channel.send(f"[MC] {message.clean}")

@discord_bot.event
async def on_message(message):
    if message.channel.id == CHANNEL_ID and not message.author.bot:
        await mc_bot.chat(f"[Discord] {message.author.name}: {message.content}")
```

## Multi-Account

```python
from pymcbotlite import BotManager

manager = BotManager()
manager.add_bot("main", host="mc.example.com", account="main")
manager.add_bot("alt1", host="mc.example.com", account="alt1")

await manager.start_all()
await manager.broadcast_chat("All bots online.")
await manager.disconnect_all()
```

## Documentation

The `docs/` directory includes:

- Authentication guide
- CLI reference
- API guide
- Relay examples
- Limitations
- Publishing checklist

Bedrock/PE examples live in `examples/pe/` with their own setup guide.

## Limitations

- Native Java target protocol is Minecraft Java `1.21.5`.
- Bedrock status ping is native Python.
- Full Bedrock bot sessions are experimental and require Node.js plus `bedrock-protocol`.
- Basic chat send may fail on servers requiring full signed-chat/session-key behavior.
- Movement is direct packet movement with bounded A* waypoint planning; Java pathfinding uses cached chunks when available but there is still no full physics simulation.
- Combat/mining controls are basic packet helpers and are not anti-cheat bypasses.
- Inventory support is intentionally minimal.
- No full physics or anti-cheat bypassing.

## Development

```bash
python -m pip install -e ".[dev,websocket,discord]"
python -B -m unittest discover -s tests
python -m build
python -m twine check dist/*
```

## License

MIT
