0. 初めに
build.gradle
や plugin.yml
の設定は終わらせた前提で進めます。
プロジェクトを作成する を参考にメインクラスを作るまで終わらせておいてください。
1. plugin.yml にコマンドを登録する
プロジェクトを作った段階で以下の5つは設定し終わっていると思います。
name: "NewCommand"
version: "1.0"
api-version: "1.15"
main: me.syari.p_2_2_new_command.Main
author: sya_ri
author
以降に コマンド登録を書いていきます。
今回は、/hello
というコマンドを登録してみましょう。
name: "NewCommand"
version: "1.0"
api-version: "1.15"
main: me.syari.p_2_2_new_command.Main
author: sya_ri
commands:
hello: # コマンドの名前
usage: "/<command>" # コマンドの短い説明
description: "挨拶します" # コマンドの説明
aliases: # コマンドの別名
- hi
commands
というセクションの中にコマンドを書いていきます。
残りは全てコメントに書いてある通りです。補足的に説明をすると、
aliases
というのを登録しておくとそのコマンドでも同じ処理をしてくれます。
今回であれば、/hello
と打っても、/hi
と打っても処理は同じです。
また、設定項目の省略も可能です。permission
や permission-message
という項目もありますが省略しています。
aliases
は無ければ省略しましょう。usage
や description
は書いておいた方がいいでしょう。
2. コマンドの処理を書く
新規ファイルで HelloCommand
というオブジェクトを作ってください。
CommandExecutor
というのを継承してください。
これを継承することで、コマンドの処理を書けるようになります。
object HelloCommand: CommandExecutor {
}
そうするとこのように赤くなると思います。Implement members
をクリックしましょう。
onCommand
が選択されていると思うので、OK
をクリックしましょう。
以下のように自動でコード生成されます。
onCommand
というのがコマンドの処理を書く関数になります。
この関数の引数について説明します。
sender: CommandSender
コマンドを実行したプレイヤーやコンソール が入っています。
command: Command
ほとんど使いません。plugin.yml
で設定したものを取得出来ます。
label: String
コマンドラベルです(/ラベル
)。 今回であれば hello
か hi
になります。
args: Array<out String>
コマンドの引数 が全て入っています(/ラベル 引数0 引数1 引数2 ...
)。
また、戻り値は Boolean
になっていますが、基本的に true
を返しておけば大丈夫です。(異常終了だったら false
)
では実際の処理を書きましょう。
とりあえず自分に挨拶を返してもらいましょう。
override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array<out String>): Boolean {
sender.sendMessage("Hello ${sender.name}")
return true
}
コマンドの処理は終わりです。
3. コマンドを登録する。
イベントの時同様に処理をしてもらう為には登録しなければなりません。
「plugin.yml
でやったじゃないか!!」と思う人もいるかもしれませんが、あれで登録したのは
「どのプラグインで処理をするか」だけです。どのクラスで処理をするか は登録してません。
イベント同様、onEnable
に書きます。
override fun onEnable() {
getCommand("hello")?.setExecutor(HelloCommand)
}
getCommand("hello")
でhelloコマンドを取得します。しかし、コマンドが存在しない可能性もありますね。
存在しないコマンドであれば null
という値が入っています。
?.
というのは存在するのであればそれ以降の処理をする。といった感覚です。
setExecutor(HelloCommand)
で実行クラスを変更しています。
さあ、プラグインをサーバーで試してましょう。
こうなっていたら成功です。
4. コマンド登録できたか通知する
このままだと、もしもタイプミスしてしまった時にコマンドが登録出来なかったことに気付くのが難しくなります。
登録できたかどうかをコンソール出力してみましょう。
さて、コマンドが登録できない場合はどういった時でしょうか?
答えは、getCommand
の戻り値が null
であった時です。
であれば、null
かどうかを比較して処理を分岐してあげればいいのです。
こんな感じになります。実際にプログラムにしましょう。
override fun onEnable() {
val helloCommand = getCommand("hello")
if(helloCommand != null){
helloCommand.setExecutor(HelloCommand)
logger.info("/hello を登録しました")
} else {
logger.severe("/hello を登録できませんでした")
}
}
getCommand
の戻り値を helloCommand
という変数で保存しています。
helloCommand
が null
でなければ 登録 & 成功メッセージ
それ以外(helloCommand
が null
)であれば 失敗メッセージ
if
は条件分岐です。括弧の中は Boolean
です。if(true)
であれば実行されます。
else
も条件分岐ですが、他・それ以外 みたいな意味です。直前の if
が false
であれば実行されます。
if(false){
// 実行されない
} else {
// 実行される
}
if
else
は基本構文なので覚えておきましょう。(else if
もありますが、Kotlin では不要。次の記事で解説します。)
さて、サーバーでテストしてみましょう。
このようにメッセージがあれば成功です。
いつも通り関数化しましょう。
class Main: JavaPlugin() {
override fun onEnable() {
registerCommand("hello", HelloCommand)
}
private fun registerCommand(label: String, executor: CommandExecutor){
val command = getCommand(label)
if(command != null){
command.setExecutor(executor)
logger.info("/$label を登録しました")
} else {
logger.severe("/$label を登録できませんでした")
}
}
}
今回は、コマンドラベルと処理クラスの2つあるので、引数は2つです。
それぞれ label
と executor
としています。
この関数は Main
でしか使わないので fun
の前に private
と付けておきます。
サーバーでテストしてみて、同じようにメッセージが出たら成功です。
また、registerCommand("hello", HelloCommand)
の "hello"
を "hell"
みたいに違うコマンドにして
「登録できませんでした」 というメッセージが出たら成功です。
これで、終了です。お疲れ様でした。
5. 【+α】 Kotlin っぽくかく
内容が難しいかもしれません。ここまでの内容で頭がパンパンの人は見ないでください。
**見てみる**
こう書けます。
private fun registerCommand(label: String, executor: CommandExecutor){
getCommand(label)?.run {
setExecutor(executor)
logger.info("/$label を登録しました")
} ?: logger.severe("/$label を登録できませんでした")
}
新しく出てきたものが2つあります。
?.run {}
は null
でなければ中括弧の中を実行する。
?:
は null
であれば別の処理をする。といった感じです。
場合分けして考えてみましょう。
1. getCommand
が null
ではなかった場合
単純に run {}
の中が実行されます。
/* null ではない getCommand(label) */.run {
setExecutor(executor)
logger.info("/$label を登録しました")
}
2. getCommand
が null
だった場合
getCommand
が null
だと ?.run {}
も null になります。
?:
の挙動は null ?: /* これが実行される */
こういう感じなので
失敗メッセージのみが残ります。
/* 全部 null になって ?: 以降だけ残る
getCommand(label)?.run {
setExecutor(executor)
logger.info("/$label を登録しました")
} ?: */ logger.severe("/$label を登録できませんでした")
Kotlin ならではの書き方というのがあります。
それを使うと変数宣言の量が減ったり、分かりやすく書けたり することもあります。
あくまで、「そういうこともある」 というだけなので、覚える必要はないです。
自分ひとりで構想を立てて、実際にプラグインを作れるようになってからで十分です。
それでも、「やったことがある」 という記憶は役に立ちます。お疲れ様でした。