広告 Java Minecraft Spigot プログラミング

Spigotプラグイン開発(二段ジャンプ)①

2021年6月6日

記事の投稿が長期間開いてしまい申し訳ないです。
前回のSpigotプラグイン開発の記事でログインメッセージを実装しましたね。
ただ、やっぱりログインメッセージだけじゃ味気ないですよね?
今回の記事ではよりプラグインらしいことをやっていこうと思います。

[st-card-ex url="https://www.dice-programming-etc.com/spigot%e3%83%97%e3%83%a9%e3%82%b0%e3%82%a4%e3%83%b3%e9%96%8b%e7%99%ba%e3%83%ad%e3%82%b0%e3%82%a4%e3%83%b3%e3%83%a1%e3%83%83%e3%82%bb%e3%83%bc%e3%82%b8/" target="_blank" rel="nofollow" label="" name="" bgcolor="" color="" readmore=""]

今回のテーマ

さて、今回の開発テーマですが「コマンド」です。
Minecraftではいろいろなコマンドがありますよね?「tp」とか「give」とか。
今回はそういったコマンドを自分で実装して、オリジナルコマンドを作っていこうと言うのがこの記事の趣旨になります。
とは言っても、コマンドを実装するだけではつまらない気もしますね。
コマンドで何かを制御しつつ、実用的なプラグインを作ってみましょうか。
では、さっそくやっていきましょう!

どんなコマンドにしようか......

さて、コマンドを作成する上で重要なのがコマンドの内容です。
既に存在しているコマンドの上位互換的なコマンドを作るも良し、完全にオリジナルで作るも良し。
さて、どうしたものですかねぇ。
「既に存在しているコマンドの上位互換なんてできるの?」と聞かれそうですが、答えは「できます」。

私が過去に作ったコマンドの上位互換としては「tp」コマンドの上位互換を作りました。
tpコマンドって基本的にはオーバーワールドであればそのワールド内、ネザーであればネザー内にのみテレポートできるという内容だと思います。
ディメンション間のtpについては、tp先のプレイヤーが別ディメンションにいる場合のみディメンションをまたいでtpできる感じですね。
正直ディメンション間移動ができないのが不便だったので、既存のtpコマンドの機能はそのまま受け継ぐ形で更にディメンション間移動を追加したtpコマンドを作成しました。

まぁ、こんな感じで上位互換的なコマンドの作成は可能です。
次にオリジナルコマンドですが、そのままの意味ですね。
Minecraftには標準で実装されていないコマンドの実装です。

上位互換とオリジナルのコマンドはどっちの実装が楽なの?と疑問があるかもしれません。結論から言うと、労力はどちらも変わりません。
なので、好きな方を実装すると良いです。
少し難易度は高いですが、実践的な内容として「二段ジャンプ」を実装してみましょう。コマンドでON/OFFを切り替えられるようにします。

プロジェクトの作成

まずはプロジェクトの作成です。
前回のログインメッセージプラグインをそのまま拡張しても良いですし、新規で作成しても構いません。
プロジェクトの作成については前回の記事を参考にしてください。
新規で作成する場合のプラグイン名は「DoubleJump」としましょう。

[st-card-ex url="https://www.dice-programming-etc.com/spigot%e3%83%97%e3%83%a9%e3%82%b0%e3%82%a4%e3%83%b3%e9%96%8b%e7%99%ba%e3%83%ad%e3%82%b0%e3%82%a4%e3%83%b3%e3%83%a1%e3%83%83%e3%82%bb%e3%83%bc%e3%82%b8/" target="_blank" rel="nofollow" label="" name="" bgcolor="" color="" readmore=""]

コマンドクラスの実装

今後のことも考えてコマンドクラスとメインクラスは別々にしておきましょう。
というわけでコマンド用のクラスを作りましょう。
クラス名はそのまま「CommandClass」としましょうか。
そして、コマンドクラスには「CommandExecutor」インターフェースをクラスに実装しましょう。
「インターフェースって何?」と思ってもここではスルーしてください。
話すと長くなりそうなので...。
インターフェースはimplementsで実装します。
そうしたらコマンドを受け付けるメソッドも実装します。
メソッド名は「onCommand」としておきましょう。
準備したソースは以下のようになります。

import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;

public class CommandClass implements CommandExecutor {
    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
        return false;
    }
}

これがコマンドクラスのテンプレートとなります。
次はコマンドを登録しましょう。

コマンドの登録

これをやらないとプラグインの方から「え?そんなコマンド知らないよ?」と言われてしまいます。
コマンドの登録は「plugin.yml」にコマンドについて記述していくだけです。
「plugin.yml」はここにあります。

今回は二段ジャンプということなので、コマンド名を「wjump」として記述してみましょう。
以下の内容をコピペしてもらって構いません。
日本語文字列が原因でエラーが出た場合は翻訳などを使って英語にしてください

commands:
  wjump:
    aliases: [ wj ] #コマンドの別名
    description: Toggles the double jump on and off. #プラグインの説明
    permission: プラグイン名.command.コマンド名
    permission-message: 権限が無い場合のメッセージ
    usage: コマンドの使い方 #無くても良い

続いては、Spigotサーバーに対して「このコマンドを受け付けたらこのプラグインで処理します」というお知らせをしてあげる処理を書きましょう。
これを書かないとplugin.ymlに書いたコマンドを打っても「そんなコマンドは知らんよ」と言われてしまいます。
「onEnable()」と書かれている場所に処理を書きこみます。

public final class DoubleJump extends JavaPlugin {

    @Override
    public void onEnable() {
        // Plugin startup logic
        getCommand("wjump").setExecutor(new CommandClass()); //<<ここ
    }

    @Override
    public void onDisable() {
        // Plugin shutdown logic
    }
}

これでコマンドの登録は完了です。
ではいよいよ「二段ジャンプ」の処理を実装しましょう!

二段ジャンプ(コマンド)の実装

さて、まずは二段ジャンプのオン・オフ処理についての実装ですが記述していくファイルは「CommandClass.java」になります。
まず必要な処理として、「プレイヤーが実行したコマンド」か「サーバーが実行したコマンド」かを判別する必要があります。
以下のようにしてみましょう。

@Override
    public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
        if(cmd.getName().equalsIgnoreCase("wjump")) {
            if (sender instanceof Player) {
                // プレイヤーが実行した場合の処理
            } else {
                // サーバーが実行した場合の処理
                getLogger().info("このコマンドはプレイヤーしか実行できません。");
            }
        }
        return false;
    }

これだけでOK!
サーバーに対しては「プレイヤーしか実行できないよー」といったメッセージを返すようにしましょう。

続いてプレイヤーがコマンドを実行した場合の処理の分岐です。
今回はコマンドで二段ジャンプのオン・オフを切り替えるのでその条件分岐を実装します。
こんな感じ。

        if(cmd.getName().equalsIgnoreCase("wjump")) {
            if (sender instanceof Player) {
                // プレイヤーが実行した場合の処理
                if(args[0].equalsIgnoreCase("on")){

                }
                else if(args[0].equalsIgnoreCase("off")){

                }
                else{

                }
            } else {
                // サーバーが実行した場合の処理
                getLogger().info("このコマンドはプレイヤーしか実行できません。");
            }
        }

ではどのようにしてオン・オフを切り替えるのか……。

今回はプレイヤーのメタデータを使用しましょう。
メタデータを設定するには「Plugin型」という、Spigot独自の型を要求されます。
メインクラス(extends JavaPluginを指定したクラス)のインスタンスをこの「CommandClass.java」に渡す必要があります(※1)。
更に、メタデータの設定には「Key」を使用します。
このKeyは基本的に変動しないものなので、「final static」で指定してしまいましょう(※2)。
指定する位置はここです。

public class CommandClass  implements CommandExecutor {
    DoubleJump doubleJump = DoubleJump.getPlugin(DoubleJump.class); //<< ※1
    protected final static String WJ_KEY = "wjump"; //<< ※2
    
    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {

これでメタデータを設定する準備ができました。
メタデータのセットはこのように行います。

if (sender instanceof Player) {
    // プレイヤーが実行した場合の処理
    Player player = (Player) sender;
    if(args.length > 0){  // ここで引数の有無を見ます。
        if(args[0].equalsIgnoreCase("on")){
            player.setMetadata(
                    WJ_KEY,    // Key
                    new FixedMetadataValue(
                            doubleJump, // プラグイン
                            "on" // 設定したい値
                    ));
            player.sendMessage("二段ジャンプをONにしました。");
        }
        else if(args[0].equalsIgnoreCase("off")){
            player.setMetadata(
                    WJ_KEY,    // Key
                    new FixedMetadataValue(
                            doubleJump, // プラグイン
                            "off" // 設定したい値
                    ));
            player.sendMessage("二段ジャンプをOFFにしました。");
        }
    }
    else{
        player.sendMessage(" on/off を指定してください。"); //引数の指定が無い場合に返すメッセージ
    }
} else {
    // サーバーが実行した場合の処理
    getLogger().info("このコマンドはプレイヤーしか実行できません。");
}

6~11行目、14~19行目の処理がメタデータをセットする処理になります。
メタデータは指定されたKeyとプラグインのセットごとに管理するので、指定されたKeyとプラグインが同じであればメタデータは上書きされていきます。
これでコマンド部分は完成です。

記事が長くても飽きてしまうと思うので、今回の記事はここまで!
次回の記事で内部的な処理を実装していきましょう。

まとめ

今回はコマンド部分のみ実装しました。
これでON/OFFを切り替えることができます。
次の記事では中身である二段ジャンプを実装していきます。
次回の記事

[st-card-ex url="https://www.dice-programming-etc.com/spigot_plugin_double_jump2/" target="_blank" rel="nofollow" label="" name="" bgcolor="" color="" readmore=""]

-Java, Minecraft, Spigot, プログラミング
-, , ,