452 lines
11 KiB
Markdown
452 lines
11 KiB
Markdown
# kommand-lib マイグレーションガイド
|
|
|
|
このガイドでは、旧バージョンの kommand-lib から最新の Brigadier ネイティブ対応バージョンへの移行方法を説明します。
|
|
|
|
---
|
|
|
|
## 📋 目次
|
|
|
|
1. [変更の概要](#変更の概要)
|
|
2. [破壊的変更](#破壊的変更)
|
|
3. [マイグレーション手順](#マイグレーション手順)
|
|
4. [コード例の比較](#コード例の比較)
|
|
5. [トラブルシューティング](#トラブルシューティング)
|
|
|
|
---
|
|
|
|
## 変更の概要
|
|
|
|
### 🎯 主な変更点
|
|
|
|
1. **Brigadier ネイティブ対応**
|
|
- Paper 1.21 の Lifecycle API を使用したコマンド登録
|
|
- クライアント側での構文ヒントと検証
|
|
- より正確な型システム
|
|
|
|
2. **引数の型変更**
|
|
- `coordinates()` の返り値が `Coordinates3` から `io.papermc.paper.math.Position` に変更
|
|
- Player/Entity セレクターの内部処理が改善
|
|
|
|
3. **自動登録**
|
|
- `kommand()` 関数の呼び出しで自動的にコマンドが登録されるように変更
|
|
|
|
---
|
|
|
|
## 破壊的変更
|
|
|
|
### 🔴 1. `coordinates()` 引数の型変更
|
|
|
|
#### 旧バージョン (動作しません)
|
|
```kotlin
|
|
coordinates("point") {
|
|
executes {
|
|
val coords = argument<Coordinates3>("point")
|
|
val target = coords.resolve(player.location)
|
|
// Coordinates3 型は存在しません
|
|
}
|
|
}
|
|
```
|
|
|
|
#### 新バージョン (正しい方法)
|
|
```kotlin
|
|
coordinates("point") {
|
|
executes {
|
|
val position = argument<io.papermc.paper.math.Position>("point")
|
|
val location = position.toLocation(player.world)
|
|
// Position 型を使用します
|
|
}
|
|
}
|
|
```
|
|
|
|
**理由**: Paper の Brigadier API は `io.papermc.paper.math.Position` を返します。これは Paper の公式 API に準拠しています。
|
|
|
|
---
|
|
|
|
### 🟡 2. Player/Entity セレクターの内部処理
|
|
|
|
**ユーザーコードに変更は不要です**が、内部的に以下の変更が行われました:
|
|
|
|
#### 内部処理の改善
|
|
```kotlin
|
|
// 旧: 直接キャスト (実行時エラーの原因)
|
|
val player = context.getArgument("player", Player::class.java)
|
|
|
|
// 新: Resolver を使用して解決 (正しい方法)
|
|
val resolver = context.getArgument("player", PlayerSelectorArgumentResolver::class.java)
|
|
val player = resolver.resolve(source).firstOrNull()
|
|
```
|
|
|
|
**影響**: Player/Entity 引数がより安定して動作するようになりました。
|
|
|
|
---
|
|
|
|
## マイグレーション手順
|
|
|
|
### ステップ 1: 依存関係の確認
|
|
|
|
`build.gradle.kts` で Paper API のバージョンを確認してください:
|
|
|
|
```kotlin
|
|
dependencies {
|
|
compileOnly("io.papermc.paper:paper-api:1.21.10-R0.1-SNAPSHOT")
|
|
// 1.21 以降が必要です
|
|
}
|
|
```
|
|
|
|
### ステップ 2: import 文の追加
|
|
|
|
`coordinates()` を使用している場合、import を追加してください:
|
|
|
|
```kotlin
|
|
import io.papermc.paper.math.Position
|
|
```
|
|
|
|
### ステップ 3: コードの更新
|
|
|
|
以下のパターンを検索して置換してください:
|
|
|
|
#### パターン 1: coordinates の型指定
|
|
|
|
**検索**:
|
|
```kotlin
|
|
argument<Coordinates3>("
|
|
```
|
|
|
|
**置換**:
|
|
```kotlin
|
|
argument<io.papermc.paper.math.Position>("
|
|
```
|
|
|
|
または、import を追加して:
|
|
```kotlin
|
|
argument<Position>("
|
|
```
|
|
|
|
#### パターン 2: coordinates の解決方法
|
|
|
|
**検索**:
|
|
```kotlin
|
|
val coords = argument<Coordinates3>("pos")
|
|
val location = coords.resolve(baseLocation)
|
|
```
|
|
|
|
**置換**:
|
|
```kotlin
|
|
val position = argument<Position>("pos")
|
|
val location = position.toLocation(world)
|
|
```
|
|
|
|
### ステップ 4: ビルドとテスト
|
|
|
|
```bash
|
|
./gradlew build
|
|
```
|
|
|
|
エラーがないことを確認してから、サーバーでテストしてください。
|
|
|
|
---
|
|
|
|
## コード例の比較
|
|
|
|
### 例 1: スポーン地点の設定
|
|
|
|
#### ❌ 旧バージョン
|
|
```kotlin
|
|
literal("setspawn") {
|
|
coordinates("point") {
|
|
executes {
|
|
val base = (sender as? Player)?.location ?: return@executes
|
|
val coords = argument<Coordinates3>("point")
|
|
val target = coords.resolve(base)
|
|
plugin.server.worlds.first().setSpawnLocation(target)
|
|
sender.sendMessage("Spawn set to ${target.x}, ${target.y}, ${target.z}")
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
#### ✅ 新バージョン
|
|
```kotlin
|
|
literal("setspawn") {
|
|
coordinates("point") {
|
|
executes {
|
|
val player = sender as? Player ?: return@executes
|
|
val position = argument<Position>("point")
|
|
val location = position.toLocation(player.world)
|
|
player.world.setSpawnLocation(location)
|
|
sender.sendMessage("Spawn set to ${location.x}, ${location.y}, ${location.z}")
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**変更点**:
|
|
- `Coordinates3` → `Position`
|
|
- `coords.resolve(base)` → `position.toLocation(world)`
|
|
- より明確な変数名
|
|
|
|
---
|
|
|
|
### 例 2: テレポートコマンド
|
|
|
|
#### ❌ 旧バージョン
|
|
```kotlin
|
|
literal("tp") {
|
|
coordinates("destination") {
|
|
executes {
|
|
val player = sender as? Player ?: return@executes
|
|
val coords = argument<Coordinates3>("destination")
|
|
val target = coords.resolve(player.location)
|
|
player.teleport(target)
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
#### ✅ 新バージョン
|
|
```kotlin
|
|
literal("tp") {
|
|
coordinates("destination") {
|
|
executes {
|
|
val player = sender as? Player ?: return@executes
|
|
val position = argument<Position>("destination")
|
|
val location = position.toLocation(player.world)
|
|
player.teleport(location)
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### 例 3: 範囲指定コマンド
|
|
|
|
#### ❌ 旧バージョン
|
|
```kotlin
|
|
literal("fill") {
|
|
coordinates("pos1") {
|
|
coordinates("pos2") {
|
|
executes {
|
|
val player = sender as? Player ?: return@executes
|
|
val base = player.location
|
|
val pos1 = argument<Coordinates3>("pos1").resolve(base)
|
|
val pos2 = argument<Coordinates3>("pos2").resolve(base)
|
|
// 処理...
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
#### ✅ 新バージョン
|
|
```kotlin
|
|
literal("fill") {
|
|
coordinates("pos1") {
|
|
coordinates("pos2") {
|
|
executes {
|
|
val player = sender as? Player ?: return@executes
|
|
val world = player.world
|
|
val pos1 = argument<Position>("pos1").toLocation(world)
|
|
val pos2 = argument<Position>("pos2").toLocation(world)
|
|
// 処理...
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Position API リファレンス
|
|
|
|
### Position のメソッド
|
|
|
|
```kotlin
|
|
interface Position {
|
|
fun x(): Double
|
|
fun y(): Double
|
|
fun z(): Double
|
|
|
|
fun blockX(): Int
|
|
fun blockY(): Int
|
|
fun blockZ(): Int
|
|
|
|
fun toLocation(world: World): Location
|
|
}
|
|
```
|
|
|
|
### 使用例
|
|
|
|
```kotlin
|
|
val position = argument<Position>("pos")
|
|
|
|
// 座標の取得
|
|
val x = position.x()
|
|
val y = position.y()
|
|
val z = position.z()
|
|
|
|
// ブロック座標の取得
|
|
val blockX = position.blockX()
|
|
val blockY = position.blockY()
|
|
val blockZ = position.blockZ()
|
|
|
|
// Location への変換
|
|
val location = position.toLocation(player.world)
|
|
```
|
|
|
|
---
|
|
|
|
## トラブルシューティング
|
|
|
|
### 問題 1: `Coordinates3` が見つからない
|
|
|
|
**エラー**:
|
|
```
|
|
Unresolved reference: Coordinates3
|
|
```
|
|
|
|
**解決方法**:
|
|
`Coordinates3` は存在しません。`io.papermc.paper.math.Position` を使用してください。
|
|
|
|
```kotlin
|
|
// ❌ 間違い
|
|
argument<Coordinates3>("pos")
|
|
|
|
// ✅ 正しい
|
|
argument<Position>("pos")
|
|
```
|
|
|
|
---
|
|
|
|
### 問題 2: `resolve()` メソッドが見つからない
|
|
|
|
**エラー**:
|
|
```
|
|
Unresolved reference: resolve
|
|
```
|
|
|
|
**解決方法**:
|
|
`Position` には `resolve()` メソッドはありません。`toLocation(world)` を使用してください。
|
|
|
|
```kotlin
|
|
// ❌ 間違い
|
|
val location = position.resolve(baseLocation)
|
|
|
|
// ✅ 正しい
|
|
val location = position.toLocation(world)
|
|
```
|
|
|
|
---
|
|
|
|
### 問題 3: Player セレクターが動作しない
|
|
|
|
**症状**: Player 引数を使用するとエラーが発生する
|
|
|
|
**解決方法**:
|
|
最新バージョンに更新してください。内部的に `ArgumentResolver` が自動的に処理します。
|
|
|
|
```kotlin
|
|
// これは自動的に動作します
|
|
val player = argument<Player>("target")
|
|
val players = argument<List<Player>>("targets")
|
|
```
|
|
|
|
---
|
|
|
|
### 問題 4: コマンドが登録されない
|
|
|
|
**症状**: `/help` にコマンドが表示されない
|
|
|
|
**解決方法**:
|
|
最新バージョンでは `kommand()` 関数の呼び出しで自動的に登録されます。
|
|
|
|
```kotlin
|
|
class MyPlugin : JavaPlugin() {
|
|
private lateinit var commands: KommandLib
|
|
|
|
override fun onEnable() {
|
|
// これだけで自動的に登録されます
|
|
commands = kommand(this) {
|
|
command("mycommand") {
|
|
// ...
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## よくある質問 (FAQ)
|
|
|
|
### Q1: 相対座標 (`~`) は引き続き使えますか?
|
|
|
|
**A**: はい、引き続き使えます。`Position` は相対座標を完全にサポートしています。
|
|
|
|
```kotlin
|
|
// "~ ~1 ~-2" のような入力が可能
|
|
val position = argument<Position>("pos")
|
|
```
|
|
|
|
---
|
|
|
|
### Q2: 旧バージョンとの互換性はありますか?
|
|
|
|
**A**: `coordinates()` 引数の型が変更されているため、**互換性はありません**。マイグレーションが必要です。
|
|
|
|
ただし、`player()`, `players()`, `selector()` などの他の引数は互換性があります。
|
|
|
|
---
|
|
|
|
### Q3: マイグレーションにどのくらい時間がかかりますか?
|
|
|
|
**A**: プロジェクトの規模によりますが、通常は以下の通りです:
|
|
|
|
- **小規模** (1-5 コマンド): 5-10 分
|
|
- **中規模** (5-20 コマンド): 15-30 分
|
|
- **大規模** (20+ コマンド): 30-60 分
|
|
|
|
主な作業は検索と置換なので、比較的短時間で完了します。
|
|
|
|
---
|
|
|
|
### Q4: 段階的な移行は可能ですか?
|
|
|
|
**A**: いいえ、`coordinates()` を使用している場合は一度にすべて移行する必要があります。
|
|
|
|
ただし、`coordinates()` を使用していないコマンドは変更不要です。
|
|
|
|
---
|
|
|
|
## サポート
|
|
|
|
問題が発生した場合は、以下のドキュメントを参照してください:
|
|
|
|
- [README.md](./README.md) - 基本的な使い方
|
|
- [BRIGADIER_REVIEW.md](./BRIGADIER_REVIEW.md) - 詳細なレビュー
|
|
- [Paper API Documentation](https://docs.papermc.io/paper/dev/command-api/arguments/location) - Position API の詳細
|
|
|
|
---
|
|
|
|
## まとめ
|
|
|
|
### ✅ マイグレーションチェックリスト
|
|
|
|
- [ ] Paper API 1.21 以降を使用していることを確認
|
|
- [ ] `Coordinates3` を `Position` に置換
|
|
- [ ] `coords.resolve()` を `position.toLocation()` に置換
|
|
- [ ] 必要な import を追加
|
|
- [ ] ビルドが成功することを確認
|
|
- [ ] サーバーでテストして動作を確認
|
|
|
|
### 🎉 完了!
|
|
|
|
マイグレーションが完了すると、以下のメリットが得られます:
|
|
|
|
- ✅ クライアント側での構文ヒント
|
|
- ✅ より正確な型チェック
|
|
- ✅ Paper の公式 API に準拠
|
|
- ✅ より安定した動作
|
|
|
|
ご不明な点がございましたら、お気軽にお問い合わせください。
|