Skip to main content

A Python-first Mineflayer SDK with a synchronous, IDE-friendly callback API.

Project description

Banner License Python Node.js

總覽

minethon 是教學導向的 Python mineflayer SDK。

底層透過 JSPyBridge 驅動 mineflayer,但公開 API 收斂成同步 callback、薄門面、完整 stub — 讓學生不需要先學 Node.js、EventEmitter、asyncio,也能一行一行看懂並自己仿寫。

特色

  • 同步 callback API@bot.on_chat decorator 直接註冊處理函式,沒有 await 也沒有 event loop
  • 完整型別層bot.pyi 由 mineflayer 官方 index.d.ts 自動生成,IDE hover 顯示中文說明
  • 兩種事件寫法@bot.on_<event> sugar、@bot.on(BotEvent.CHAT) enum,任選其一
  • Class-based handler — 繼承 BotHandlers、override 想要的 on_<event>bot.bind(instance) 一次綁完
  • Pathfinding — 內建 typed 支援的 mineflayer-pathfinderbot.pathfinder.goto(...) 直接可用
  • 顯式版本釘選 — 非內建 plugin 必須傳版本字串,避免 JSPyBridge 在 runtime 偷裝 latest

前置需求

項目 需求
Python 3.14+
Node.js 22+
Minecraft Server Java Edition

安裝

./setup.sh

setup.sh 會:

  • uv sync 安裝 Python 依賴
  • 檢查 Node.js 22+
  • 預裝 pinned 的 mineflayervec3mineflayer-pathfinder

Node.js 必須在 PATH 中可用。setup.sh 啟動時會自動檢查。

快速開始

from minethon import BotEvent, create_bot
from minethon.models import ChatMessage

bot = create_bot(host="localhost", username="pybot")


@bot.on_spawn
def on_spawn() -> None:
    bot.chat("hello")


@bot.on_chat
def on_chat(
    username: str,
    message: str,
    translate: str | None,
    json_msg: ChatMessage,
    matches: list[str] | None,
) -> None:
    if username == bot.username:
        return
    if message == "quit":
        bot.quit("bye")


@bot.on(BotEvent.END)
def on_end(reason: str) -> None:
    print(f"Disconnected: {reason}")


bot.run_forever()

事件 API

以下兩種寫法都支援:

@bot.on_chat
def on_chat(...): ...


@bot.on(BotEvent.CHAT)
def on_chat(...): ...

JetBrains / Pylance 的 completion 體驗:

  • @bot.on_chat 是最直接的 decorator,IDE 會跳出完整參數列
  • @bot.on(BotEvent.CHAT) 適合想保留顯式 event enum 的寫法
  • @bot.on("chat") 字串形式已移除,不再是公開 API

Class-based handler

偏好 OOP 的學生可以繼承 BotHandlers、覆寫想關心的事件、一次 bind:

from minethon import BotHandlers, create_bot


class My(BotHandlers):
    def on_spawn(self) -> None:
        print(f"Spawned as {bot.username}")

    def on_chat(self, username, message, *_):
        if message == "quit":
            bot.quit("bye")


bot = create_bot(host="localhost", username="pybot")
bot.bind(My())
bot.run_forever()

型別與匯入

常用型別可從 minethon.models 匯入:

from minethon.models import Block, ChatMessage, Entity, Item, Player, Vec3

這些是公開型別 shell,實際成員面以 src/minethon/bot.pyi 為準。

版本規則

  • create_bot(...) 內部固定使用 pinned 的 mineflayer
  • bot.load_plugin("mineflayer-pathfinder") 可省略版本,會用內建 pin
  • 其他 npm 套件必須顯式版本:
viewer = bot.require("prismarine-viewer", "1.33.0")
tool = bot.load_plugin("mineflayer-tool", "1.5.0", export_key="plugin")

這是刻意設計,用來避免 JSPyBridge 在 runtime 偷裝 latest,確保教學範例在學生環境可重現。

範例

範例 說明
drasl_auth 透過自建 Drasl 驗證伺服器連線並回應聊天

專案結構

src/minethon/
├── __init__.py         # 使用者入口(re-export create_bot / Bot / BotEvent / BotHandlers / 錯誤類)
├── bot.py              # runtime façade:event decorator、plugin loading、版本 guard
├── bot.pyi             # 生成的 IDE 型別層(由 scripts/generate_stubs.py 產出)
├── _events.py          # 生成的 BotEvent StrEnum
├── _handlers.py        # 生成的 BotHandlers 基底類別
├── _bridge.py          # JSPyBridge 封裝:callback thread、emitter 注入、handler 正規化
├── _type_shells.py     # 內部型別 shell 實作
├── errors.py           # 公開錯誤類(MinethonError、NotSpawnedError、VersionPinRequiredError 等)
├── py.typed            # PEP 561 型別支援標記
└── models/             # 可匯入的公開型別 shell
    ├── __init__.py
    └── __init__.pyi

scripts/
├── generate_stubs.py   # 從 mineflayer / pathfinder d.ts 生成 bot.pyi / _events.py / _handlers.py
└── format.sh           # 一鍵 regen → ruff → pyright → pytest

docs/
└── stubs_zh_tw.md      # 中文 hover 說明來源(供 generator 注入 docstring)

開發

一鍵跑完(regen stubs → format → lint → type-check → test):

./scripts/format.sh            # 寫回格式修正
./scripts/format.sh --check    # 只檢查不寫入(CI 模式)

對應的個別指令:

uv run python scripts/generate_stubs.py
uv run ruff format src scripts tests
uv run ruff check src scripts tests
uv run pyright src/
uv run pytest -m "not integration" --tb=short -q

IntelliJ / PyCharm 使用者注意

uv sync 會以 editable 模式安裝本專案,導致 IDEA 的 Python SDK 將專案目錄同時視為外部 library,可能使整個專案被標記為 excluded。

解法: File → Project Structure → SDKs → 選擇 Python interpreter → Paths 頁籤,移除指向本專案以及本專案 src/ 的路徑,然後 Apply。

貢獻

歡迎 PR 與 Issue!

送出前請確認:

  1. 遵循現有的程式碼風格與架構慣例(細節見 AGENTS.md
  2. 通過所有檢查
    • ./scripts/format.sh --check
  3. feature/your-featurefix/your-fix 命名分支
  4. 發布 PR 時,目標分支為 dev

授權

本專案採用 GNU Affero General Public License v3.0 授權。

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

minethon-0.3.0a1.tar.gz (2.3 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

minethon-0.3.0a1-py3-none-any.whl (66.3 kB view details)

Uploaded Python 3

File details

Details for the file minethon-0.3.0a1.tar.gz.

File metadata

  • Download URL: minethon-0.3.0a1.tar.gz
  • Upload date:
  • Size: 2.3 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for minethon-0.3.0a1.tar.gz
Algorithm Hash digest
SHA256 ec3228842d3fe937bb64cc9d824e79bf3d7aa7fad5b28910e57fef8fd42c798f
MD5 a985ad275bfa5f8886456a7b0bedd9af
BLAKE2b-256 f17709e5e4f2a0cf5884d8ec11340780fd3fbfd0eaa1cd59476d970ab4dee934

See more details on using hashes here.

Provenance

The following attestation bundles were made for minethon-0.3.0a1.tar.gz:

Publisher: publish.yml on Hack-the-SDGs/minethon

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file minethon-0.3.0a1-py3-none-any.whl.

File metadata

  • Download URL: minethon-0.3.0a1-py3-none-any.whl
  • Upload date:
  • Size: 66.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for minethon-0.3.0a1-py3-none-any.whl
Algorithm Hash digest
SHA256 87ce879f331515c3c2954afa7c4b22670ec514bb0df5a97e84ffb0736ef774ea
MD5 f9415aacb2022503213f21ad097bbd3d
BLAKE2b-256 99083d3603a066e817dbc00f05913e3cbd3893ee4b837f9c8518e8d8a0ef1e73

See more details on using hashes here.

Provenance

The following attestation bundles were made for minethon-0.3.0a1-py3-none-any.whl:

Publisher: publish.yml on Hack-the-SDGs/minethon

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page