117 lines
4.2 KiB
Markdown
117 lines
4.2 KiB
Markdown
# minego
|
||
|
||
go-mc with command-line-only bot client.
|
||
|
||
# 建議目錄結構
|
||
|
||
```
|
||
minego/
|
||
├─ cmd/
|
||
│ ├─ minectl/ # 範例 CLI:連線、發包、抓封包
|
||
│ │ └─ main.go
|
||
│ └─ proxy/ # 範例:簡易協議代理/抓包器
|
||
│ └─ main.go
|
||
│
|
||
├─ pkg/ # 對外公開 API(庫)
|
||
│ ├─ client/ # 高階 Client SDK(使用者只需要這個)
|
||
│ │ ├─ client.go # Client 對外介面、New(...)、Connect(...)
|
||
│ │ ├─ options.go # 可選項:代理、壓縮、密碼學、登入方式
|
||
│ │ ├─ session.go # 與伺服器的一次連線(狀態機)
|
||
│ │ ├─ pipeline.go # 封包處理管線(decode -> route -> handler)
|
||
│ │ ├─ dispatcher.go # 事件/封包分發與訂閱
|
||
│ │ ├─ keepalive.go
|
||
│ │ ├─ reconnect.go
|
||
│ │ └─ errors.go
|
||
│ │
|
||
│ ├─ transport/ # 可替換傳輸層(TCP wrapper)
|
||
│ │ ├─ tcp/
|
||
│ │ │ └─ conn.go
|
||
│ │ └─ transport.go # 抽象介面:Dial(ctx, addr) (Conn, error)
|
||
│ │
|
||
│ ├─ auth/ # 登入/加密/密鑰交換(mojang、離線、自訂yggdrasil)
|
||
│ │ ├─ offline.go
|
||
│ │ ├─ mojang.go
|
||
│ │ └─ encrypt.go
|
||
│ │
|
||
│ ├─ handler/ # 封包與事件處理(基於協議的 client 方向)
|
||
│ │ ├─ login.go
|
||
│ │ ├─ play_entities.go
|
||
│ │ ├─ play_world.go
|
||
│ │ ├─ chat.go
|
||
│ │ └─ registry.go # 封包 -> handler 的綁定註冊
|
||
│ │
|
||
│ ├─ game/ # 遊戲狀態(抽象,不與 GUI 綁死)
|
||
│ │ ├─ world/
|
||
│ │ │ ├─ chunk.go
|
||
│ │ │ ├─ palette.go
|
||
│ │ │ └─ biome.go
|
||
│ │ ├─ entity/
|
||
│ │ │ └─ entity.go
|
||
│ │ └─ inventory/
|
||
│ │ └─ slots.go
|
||
│ │
|
||
│ ├─ data/ # 協議資料&對照(版本表、映射、assets)
|
||
│ │ ├─ versions/
|
||
│ │ │ └─ 1_21.json
|
||
│ │ └─ registries/
|
||
│ │ └─ packets.json
|
||
│ │
|
||
│ ├─ protocol/ # 你現有的 codec/packet/metadata 可移到這
|
||
│ │ ├─ codec/…
|
||
│ │ ├─ packet/…
|
||
│ │ └─ nbt/…
|
||
│ │
|
||
│ └─ util/ # 小工具:varint、zlib、pool、log
|
||
│ └─ …
|
||
│
|
||
└─ go.mod
|
||
```
|
||
|
||
> 原則:
|
||
>
|
||
> * `pkg/` 對外公開、穩定 API;`internal/` 只給本專案使用。
|
||
> * `protocol` 保持「與傳輸無關」;`transport` 抽象連線;`client` 串起狀態機與 handler。
|
||
> * `handler` 專心處理「已解碼封包」到「遊戲狀態/事件」的映射。
|
||
> * `game` 做資料模型(世界、實體、物品),不要直接依賴 UI。
|
||
|
||
---
|
||
|
||
# 模組邏輯切分(設計重點)
|
||
|
||
1. **狀態機(State Machine)**
|
||
|
||
* `Handshake -> Status/Login -> Play -> (Disconnected)`
|
||
* 在 `session.go` 以 goroutine + channel 管理讀寫,使用 `context.Context` 控制生命週期。
|
||
2. **封包管線(Pipeline)**
|
||
|
||
* `reader` 取得原始 bytes → `protocol/codec` 解碼 → `dispatcher` 依封包 ID 分派到 handler。
|
||
* 可在管線節點插中介:壓縮、加密、記錄、度量。
|
||
3. **事件導向 API**
|
||
|
||
* 對外提供:
|
||
|
||
```go
|
||
type Client interface {
|
||
On(event Event, fn any) Unsub
|
||
Send(ctx context.Context, p protocol.Packet) error
|
||
State() client.State
|
||
}
|
||
```
|
||
* `On(PacketPlayChat, func(*ChatMessage){…})` 這種型別安全的註冊可以用泛型或介面實作。
|
||
4. **錯誤與可觀測性**
|
||
|
||
* 統一 `errors.go`;在 pipeline/handler 位置加可選的 `WithLogger / WithMetrics`。
|
||
|
||
---
|
||
|
||
# 命名與風格小訣竅
|
||
|
||
* 套件名短小、名詞為主:`client`, `auth`, `transport`, `handler`, `game`, `protocol`.
|
||
* 檔名以職責分組,不以每個封包獨立檔案(容易爆量難找)。
|
||
* 對外只匯出 `pkg/client` 的型別;其餘盡量小寫封裝。
|
||
* 盡量用 `context.Context`、`io.Reader/Writer` 介面做邊界。
|
||
|
||
---
|
||
|
||
> MCProtocol(新wiki.vg) https://minecraft.wiki/w/Java_Edition_protocol
|
||
> 使用套件: github.com/Tnze/go-mc |