【Spigot】Bukkitプラグインの作り方講座 - サーバーの操作とConsoleCommandSender
サーバー
サーバーはJavaPluginのgetServer()
で取得できます。
getServer().addRecipe(Recipe)
でレシピを追加したり、
getServer().banIP("192.168.1.1")
などでIPBANをしたり、
getServer().broadcastMessage("こんにちは")
でサーバー全体にメッセージを送信したり、
getServer().clearRecipes()
でレシピを全削除したりなど、いろいろなことができます。
その他、仮想インベントリの作成、地図の作成、ワールドの作成、各種サーバーの設定、サーバーのシャットダウン、ワールドのアンロードなどができます。
ミニゲームサーバーなどで画面右にScoreboardというものを表示することができるのですが、当方で動作しなかったためここでは紹介しません。
また、バージョンにより実装方法が異なります。
オフラインプレイヤーとオンラインプレイヤー
getServer().getOfflinePlayers()
でオフラインプレイヤー、つまり一度ログインしたプレイヤーの情報が取得できます。
ただし、オフラインプレイヤーのインベントリを操作したり確認することができません。
getServer().getOnlinePlayers()
でオンラインのプレイヤーを取得できます。
プレイヤーは体力やエフェクトを設定したり、インベントリを操作することができます。
getServer().getBannedPlayers()
でBANされているオフラインプレイヤーのリストを取得できます。
getServer().getMaxPlayers()
で最大プレイヤー数を取得できます。
BANリスト
getServer().getBanList(Type.IP)
あるいはgetServer().getIPBans()
でIPBANのリスト、
getServer().getBanList(Type.NAME)
でプレイヤー名でのBANリストを取得できます。
サーバーの情報
getServer().getMotd()
でサーバーの説明を取得できます。
getServer().getName()
で"CraftBukkit"という文字列を取得できます。
getServer().getBukkitVersion()
でBukkitのバージョンを取得できます。
私の環境では"1.12.2-R0.1-SNAPSHOT"という文字列を取得しました。
getServer().getVersion()
で私の環境では"git-Spigot-4bd94dc-1c40a81 (MC: 1.12.2)"という文字列を取得しました。
ConsoleCommandSender
getServer().getConsoleSender()
でConsoleCommandSenderを取得できます。
getServer().getConsoleSender().sendMessage(ChatColor.GOLD + "(゚∀゚)アヒャ")
でサーバーのコンソールに色付きのメッセージを送ることができます。
【Spigot】Bukkitプラグインの作り方講座 - メッセージに色や装飾を付けるChatColor
メッセージに色や装飾を付けるChatColor
@EventHandler
public void onEntityDamageByEntity(EntityDamageByEntityEvent e) {
e.getDamager().sendMessage(ChatColor.RED + "いたいよ~");
}
以上のコードでは、エンティティがエンティティにダメージを与えたときに、ダメージを与えたエンティティに色のついた文字でメッセージを送信します。
ChatColorの使用方法は、ChatColorのお好みの色、装飾(太字や斜め文字、取り消し線など)を設定した場所より右側の文字に反映されます。
e.getDamager().sendMessage(ChatColor.RED + "" + ChatColor.BOLD + "いたいよ~");
BOLD(太字)の装飾を付ける例です。色とともに装飾を付けていますが、装飾を先につけてしまうと色を付けたときに取り消されてしまいますので、注意が必要です。
看板や、プレイヤーの名前、Tabキーで表示されるプレイヤーの名前などにも設定できます。
また、ChatColor同士の結合はできないので、文字列を挟む必要があります。
【Spigot】Bukkitプラグインの作り方講座 - 他のプラグインとの連携
外部プラグインとの連携
例えば、「経済プラグインと連携したい」と言った場合など、
プラグインなどをAPIとして利用して連携したい場合があります。
この場合は、
「プラグインを作る」でプロジェクトを作成したときに、
サーバーのJarファイルを外部JARとして読み込んでいましたが、
全く同じ方法で、プラグインを外部JARとして読み込むことで、
作成するプラグインの中で、
読み込んだプラグインのクラスなどが扱えるようになります。
ただしこの方法では、作成するプラグインに、
読み込んだライブラリを含むことができません。
そのため、サーバー内で他のプラグインと連携したい場合に使うことができます。
IntelliJ IDEAでの設定(Gradle)
プロジェクトのフォルダ内にlibフォルダを作成します。
作成したlibフォルダの中に連携したいプラグインのJarファイルを入れます。
build.gradleファイルのdependencies
内に、
compileOnly fileTree(dir: 'lib', include: '*jar')
を追加します。
例:
dependencies { testCompile group: 'junit', name: 'junit', version: '4.12' compileOnly 'org.spigotmc:spigot-api:1.14.4-R0.1-SNAPSHOT' compileOnly fileTree(dir: 'lib', include: '*jar') }
build.gradleを編集したら、
右下に「変更をインポート」が出てくるので押してください。
これでプラグインと連携することができますが、
IDEで編集する際にプラグインが見つからずエラーになってしまいます。
なので次は、プロジェクトにライブラリーを追加します。
メニューバー(ウィンドウ上部)の ファイル > プロジェクト構造... を押します。
左のメニューの ライブラリー を押して、一覧の上の + から Java を選択します。
libフォルダに入れたJarファイルを一つ選択します。
モジュールの選択という画面になるのでOKを押します。
複数のJarファイルがある場合は以上の作業を繰り返します。
パッケージ等を見つけることができるようになりました。
インポートのあたりに赤文字が出る場合は、
赤文字にカーソルを合わせ、
「Add library '~' to classpath」を押してください。
必須プラグインの設定
作成するプラグインが連携先のプラグインを必須としている場合、
それをplugin.ymlに記載することで、
必須プラグインがない場合はプラグインを読み込まないようにできます。
plugin.ymlにdepend: [Plugin]
と追加すると、
「Plugin」というプラグインを必須プラグインとすることができます。
読み込まれなかったプラグインは/plで見ると赤く表示されています。
プラグインを読み込む順序
プラグインを扱えても、読み込む順番などが求められる場合があります。
例えば連携先のプラグインよりも、作成するプラグインが先に読み込まれてしまうと、
その時点ではまだ連携先のプラグインが読み込まれていないので、連携ができません。
そういったことを回避するために、
plugin.ymlでプラグインを読み込む順序を指定できます。
softdepend: [Plugin]
で「Plugin」というプラグインを先に読み込みます。
loadbefore: [Plugin]
で「Plugin」というプラグインを後で読み込みます。
また、softdependやloadbeforeだけ記載しても、
必須プラグインとはなりません。
【Spigot】Bukkitプラグインの作り方講座 - CraftBukkitの利用と複数のバージョンに対応させる方法
CraftBukkitの利用と複数のバージョンに対応させる方法
ここらへんは少し難しい話になります。
Bukkit、Spigotではクラスではなくインターフェースが多用されていますが、
インターフェースということはそれを実装するクラスがあるということです。
実はそれらのクラスはBukkitの基本的機能であるCraftBukkitにあります。
CraftBukkitを利用することでより細かいことが出来るようになります。
Bukkitの「Entity」はCraftBukkitでは「CraftEntity」、「Arrow」は「CraftArrow」のように、
"Craft+xxx"と言った名前になっているので、開発環境で検索をかけてみると良いと思います。
また、それらのクラスはバージョンごとに違うパッケージの中にあります。
例えばCraftBukkitのバージョン名は「v1_12_R1」のようになります。
CraftBukkit1.12のCraftEntityは「org.bukkit.craftbukkit.v1_12_R1.entity.CraftEntity」のようになっています。
CraftBukkitはMinecraftサーバーを扱いやすくしたもので、
Minecraftサーバーの機能を継承しています。
Minecraftサーバーの機能に触れる事もできますが、弄るのがかなり難しいのでおすすめしません。
また、CraftBukkitのバージョン名はMinecraftサーバーと同じです。
こちらはCraftArrowはEntityArrow、CraftChestはTileEntityのように、
「Entity+xxx」や「TileEntity+xxx」と言った名前になっています。
例えばMinecraftサーバーのEntityは「net.minecraft.server.v1_12_R1.Entity」です。
また、CraftBukkitでの「CraftChest」がMinecraftサーバーでは「TileEntityChest」になるように、
MinecraftサーバーとCraftBukkitでは構造が変わってくるので注意が必要です。
自分の作ったプラグインを、複数のバージョンに対応させる必要がある場合が少なからずあります。
その為には、CraftBukkitのバージョンごとにプラグインを分けるか、
一つのプラグインで複数のバージョンに対応させる方法があります。
私が作ったプラグインにMinecraftサーバーの機能を利用して、
かまどでのアイテムの燃焼時間を取得するものがありますので参考にしてみて下さい。
これの78行目あたりにあるJavaのgetClass()などを利用して、メソッドを実行するメソッドを利用するなどします。
これを応用して複数のバージョンに対応させることが出来ます。
CraftBukkitやMinecraftの機能を利用するにはバージョン名を取得する必要があります。
バージョン名の部分はこの方法で簡単に取得できます。
getServer().getClass().getName().split("\\.")[3]
また、getServer()はサーバーを取得するメソッドで、プラグインのメインクラスで継承しているJavaPluginクラスで使用できます。
他にもBukkit.getServer()でもServerを取得できます。
ちなみにServerもCraftBukkitではCraftServerとなります。
【Spigot】Bukkitプラグインの作り方講座 - ブロックの操作
【Spigot】Bukkitプラグインの作り方講座 - インベントリにアイテムを入れる
インベントリを持っているエンティティにはInventoryHolder
インターフェースが継承されています。
InventoryHolder
インターフェースを持っているのはエンティティだけではなく、チェストなどのブロックにもあります。
```
@EventHandler
public void onInventoryOpen(InventoryOpenEvent e) {
e.getInventory().addItem(new ItemStack(Material.DIAMOND_BLOCK));
}
```
インベントリを開くたび、インベントリにダイヤブロックが追加されます。
なお、チェストだけでなく、かまど、エンチャントテーブル、エンチャントテーブルを閉じたときに自分のインベントリ、エンダーチェスト、シュルカーボックス、ディスペンサー、トラップチェスト、ホッパー、ドロッパー、チェスト付きトロッコ、ホッパー付きトロッコで動作しました。
e.getInventory().setItem(9, new ItemStack(Material.GOLD_INGOT, 3));
インベントリには必ずスロットにインデックスが振られており、左上から右上、下の段に行って左から右の順に0からの番号が振られています。
以上の例では9番目、つまり二段目の一番左のスロットに金インゴットを3つ配置します。
なお、この状態でかまどなどの9番目のスロットがない場合はエラーが発生しますので、e.getInventory().getSize()
でスロットの数を確認してください。
インベントリを開いたプレイヤーのインベントリに鉄インゴットを追加するには以下のコードを書きます。
e.getPlayer().getInventory().addItem(new ItemStack(Material.IRON_INGOT));
if (e.getInventory().getHolder() instanceof Chest) {
((Chest) e.getInventory().getHolder()).getBlock().breakNaturally(new ItemStack(Material.STONE_AXE));
}
以上のコードは、開いたインベントリがチェストであることを判定し、そのチェストを石斧を使って破壊します。破壊するプレイヤーなどはいませんが、プレイヤーが破壊した状態と同じことが起こります。
チェストであることを判定しているので、チェストのブロックを取得することができます。
【Spigot】Bukkitプラグインの作り方講座 - はじめに
Bukkitプラグインとは
- Bukkitとは、ゲーム「Minecraft」のサーバーModの一つ。
- Bukkitには、プラグインを入れることで通常の「バニラサーバー」では出来ない機能を追加できる。
- プラグインはModのようにブロックやアイテムを追加することは出来ない。
- 2017年現在多くのサーバーがBukkitにて稼働しており、プラグインによって経済や要素が追加されている。
- Bukkitは現在更新及び公開が停止しているが、その派生版としてSpigotが存在しBukkitと同様に使用でき、加えて多くの機能が追加されている。ただし、プラグイン開発ではBukkitとSpigotに一部違いがあるため注意が必要。今回はSpigotを使用する。
- Minecraftはプログラミング言語「Java」でできている。ModやBukkitプラグインも同様。
プラグインで出来ること、出来ないこと
出来ること:黒
出来ないこと:赤
- ブロックやアイテム、エンティティの操作や挙動を変える
- 新しい見た目のブロックやアイテム、エンティティの追加
- インベントリの操作や挙動を変える
- 新しい見た目のGUIの追加
- コマンドの追加
- 地形・構造物編集、ワールド作成・管理
- 爆破耐性
- お金、ミニゲームなどの追加
- 別の場所にワープする
- タブキーで表示するプレイヤーリストを書き換える
- クラフトレシピを追加する
- サーバーリストに表示する説明を設定する、などなど...
以上にあげたのはほんの一例で、
プラグインの域を出れば、ウェブと連携したワールドマップや、チャット機能など、Javaでできることを組み合わせることができるため、
出来ることは無限にあります。
上記でできないことはForgeModでできますが、
ForgeModは参加するすべてのプレイヤーがModを導入しないといけない点に注意してください。
ブロックの見た目などを変えるにはリソースパックで実現できますが、
既存のものを変えずに新しく追加することはプラグインではできません。
ちなみに、Bukkitは現在更新及び公開が停止しており、
現在使用されているものはBukkitの派生版であるSpigotです。
SpigotはBukkitの機能に加え、多くの機能が追加されています。
ただし、バージョンにより一部違いがあるため注意が必要です。
ここではSpigotを使用します。
他にも、CauldronというForgeModとプラグインを併用するサーバーModも存在します。
はじめに
読者の皆さんには、
Javaを学ばないとプラグインが作れない、と考えるかもしれませんが、
それではプラグインを作るという目標を失い、
挫折してしまいます。
ですからこの講座でプラグインの作り方とともにJavaに慣れていってください。
プラグインで出来ることはたくさんありますので、
楽しいプラグインをどんどん作りましょう!
注意点
- プログラミングについては詳しく解説していませんので、気になることは調べてください。
- ここでは、開発環境にIntelliJ IDEA、またはeclipseを使用しますが、Windows以外では表示や操作が異なる場合があります。
- 内容によっては、Bukkitのバージョンにより異なる可能性があります。
- ここではポート開放のやり方や、ネットに関する詳しいことは説明しません。