2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Minecraft Kotlinプラグイン開発 中級編 Part.4 コマンドの実行

Last updated at Posted at 2024-03-30

初めに

今回はプレイヤーとしてマイクラのコマンドを実行する方法と
コンソールからコマンドを実行する方法を紹介します。

バニラのコマンドをある程度知ってる人であれば、
この方法を使うと自由度が格段に広がります。

この方法はコマンドを挟んで処理してる形でコマンドを経由させてる状態なので、
処理的にはこの方法を使わないほうが軽いため非推奨です。
今後自分でいろいろな構文を覚えたらコマンドの部分を自分で変えてみましょう。
今回紹介する方法はそれまでの応急処置的なものです!

中級編 Part.3 GUIのクリック検知
番外編2 プラグインフォルダへ直接ビルドする方法

目次目次と今後の展望

プレイヤーとしてコマンドを実行

前回作成したGUIの中のクリック処理を一部変更します。

今回はダイヤモンドがクリックされた時に自分を10マス上にtpさせてみます。
具体的には"/tp @s ~ ~10 ~"というコマンドをプレイヤーから実行してみます。

EventListener.kt
package com.github.tooooowa.tutorialplugin // ここは環境によって異なります

import org.bukkit.Bukkit
import org.bukkit.GameMode
import org.bukkit.Material
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.player.PlayerJoinEvent

object EventListener: Listener {
    @EventHandler
    fun onJoin (event: PlayerJoinEvent) {
        event.joinMessage = "§e${event.player.name}がサーバーに参加しました。"
    }
    @EventHandler
    fun onInventoryClick (event: InventoryClickEvent) {
        if (TutorialPlugin.guiMap[event.whoClicked.uniqueId] == event.inventory) {
            event.isCancelled = true
            if (event.currentItem == null) return

            // ここの下の行に変数にプレイヤーを保存する処理を追加
            val player = Bukkit.getPlayer(event.whoClicked.name)

            // ダイヤモンドのときの処理 (ここも変更しました)
            if (event.currentItem!!.type == Material.DIAMOND) {
                player?.performCommand("tp @s ~ ~10 ~")
            }

            // エメラルドのときの処理
            if (event.currentItem!!.type == Material.EMERALD) {
                event.whoClicked.gameMode = GameMode.SURVIVAL
            }

        }
    }
}

クリエイティブモードに変更する処理を削除して、
プレイヤーを変数に保存する処理と
その変数に保存されているプレイヤーとしてコマンドを実行させる処理を追加しました。

val player = Bukkit.getPlayer(event.whoClicked.name)

この1行で変数playerにクリックしたプレイヤーを入れています。

プレイヤーを指定する方法で、event.whoClickedをゲームモード変更には使用していますが
プレイヤーとしてコマンドを実行するにはプレイヤーの型の変数じゃないと行けないので
このようにBukkit.getPlayer()を使用してプレイヤーを変数に取得しています。

関数Bukkit.getPlayer()は引数「()の中」に名前もしくはUUIDを入れて使用します。
今回はevent.whoClicked.namedでクリックした人の名前を入れています。

player?.performCommand("tp @s ~ ~10 ~")

この文でプレイヤーとしてコマンドを実行しています。
この関数では引数の中に実行させたいコマンドを記入します。
※最初に付ける/は省略します

普段つける . とは違い、ここでは .? を使用しています。
これはKotlinの機能で変数が空からでもnullとして実行するという意味です。
今回はplayerが空のことはないので、ビルド時のエラーを防ぐために ?. を付けます。

基本的には、IntelliJ IDEA のコードの赤い下線でエラーが出るので、
それを見ながら色々修正しています。

デバッグ

これでクリックすると以下の画像のように出ます。
image.png

この方法だとプレイヤーから実行することになるので
ログは出ますしそのプレイヤーがコマンドを実行する権限がないと実行できません

コンソールとしてコマンドを実行

今度はコンソールとしてプレイヤーにエメラルドを付与するコードを追加してみます。
具体的には /give [プレイヤー名] emerald を実行します。
プレイヤー名を使う所ではさっき使ったplayer変数を再び使用します。

エメラルドのクリック時のイベントを変更します。

EventListener.kt
package com.github.tooooowa.tutorialplugin // ここは環境によって異なります

import org.bukkit.Bukkit
import org.bukkit.GameMode
import org.bukkit.Material
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.player.PlayerJoinEvent

object EventListener: Listener {
    @EventHandler
    fun onJoin (event: PlayerJoinEvent) {
        event.joinMessage = "§e${event.player.name}がサーバーに参加しました。"
    }
    @EventHandler
    fun onInventoryClick (event: InventoryClickEvent) {
        if (TutorialPlugin.guiMap[event.whoClicked.uniqueId] == event.inventory) {
            event.isCancelled = true
            if (event.currentItem == null) return
            val player = Bukkit.getPlayer(event.whoClicked.name)

            // ダイヤモンドのときの処理
            if (event.currentItem!!.type == Material.DIAMOND) {
                player?.performCommand("tp @s ~ ~10 ~")
            }

            // エメラルドのときの処理 (ここを変更しました)
            if (event.currentItem!!.type == Material.EMERALD) {
                Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "give ${player?.name} diamond")
            }

        }
    }
}

追加したのは以下の一文のみです。

Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "give ${player?.name} diamond")

Bukkit.dispatchCommand( 引数1 , 引数2 )では引数1でコンソールを取得して、
引数2で実行させたいコマンドを記入します。

引数1のコンソールの部分は常にBukkit.getConsoleSender()固定で大丈夫です。
引数2ではプレイヤーとして実行のときと同じく 初めの / は省略します

デバッグ

実行してみるとダイヤモンドが1つ貰えます。

この画像のようにOPを持っている場合はチャットにログが出ます。
プレイヤーとして実行とは違いこの場合は
プレイヤーに /give コマンドを使う権限がなくても正常に動きます。

うまくこれらを使い分けて行きましょう!

image.png

終わりに

今回はプレイヤーとして、コンソールとしてコマンドを実行する方法を学習しました。

基本コマンドを知っている方であれば
これで自分の作りたいものを作れる段階に近づくと思うので活用していきましょう!

また、これから色んな構文を学習していき少しずつコマンドから
プラグインの機能自体で完結出来るようにしていきましょう。

次回の記事は権限に関してです。お疲れ様でした!

中級編 Part.3 GUIのクリック検知
番外編2 プラグインフォルダへ直接ビルドする方法

目次目次と今後の展望

参考

https://www.youtube.com/watch?v=hPzg4tXcu5I
https://www.spigotmc.org/threads/run-console-command.82908/

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?