CraftBukkitを利用したSpigotのプラグイン開発をしよう
CraftBukkitを利用するメリット
CraftBukkitを利用するということは、
例えば、ブロックを壊した場合には次のようなことを考える必要がなくなる。
- 道具の耐久値
- 道具のエンチャント(耐久、幸運、シルクタッチ、etc...)
- ドロップや経験値オーブ
- ユーザーの統計情報
- Eventの再発行
- 他のプラグインとの兼ね合い
- etc...
spigot-apiの標準である Block::breakNaturally(ItemStack)
でブロックを破壊した場合は、上記の項目がどのように処理されているのかを確かめる必要がある。
実際に、ブロックを壊すのに利用した道具(ItemStack)の耐久値は減らず、ユーザーの統計情報も変化しない。また、 BlockBreakEvent
も発行されないため、他のプラグインにも影響を与えることになる。
それらの処理まで自作しようとするとすごく大変なので、CraftBukkitを使いたい。
必要な準備
craftbukkit-*.jarを生成する
BuildTools.jarでビルドするとき --compile craftbukkit
を指定する。
java -jar BuildTools.jar --rev 1.19 --compile craftbukkit
すると craftbukkit-1.19-R0.1-SNAPSHOT.jar
が ./CraftBukkit/target/
に生成されるので、これをライブラリとして読み込めばCraftBukkitのコードを利用した開発ができる。
プロジェクトで読み込む
開発しているプラグインのプロジェクトに libs
等のディレクトリを追加し、そこに生成した craftbukkit-1.19-R0.1-SNAPSHOT.jar
をおき、build.gradle
で次のように読み込む。
dependencies {
compileOnly fileTree(dir: 'libs', include: ['*.jar'])
...
}
これを実際につかうと次のようなコードが書ける。
// ゲームのバージョンによってimport先が異なる
import org.bukkit.craftbukkit.v1_19_R1.CraftWorld
import org.bukkit.craftbukkit.v1_19_R1.entity.CraftPlayer
import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack
// 既存の仕組みをつかってブロックを壊す
fun breakBlock(player: Player, block: Block) {
val craftPlayer = player as CraftPlayer
val blockPosition = BlockPosition(block.x, block.y, block.z)
craftPlayer.handle.d.a(blockPosition)
}
// 既存の仕組みをつかって経験値オーブをだす
fun dropExperience(player: Player, amount: Int) {
val world = (player.world as CraftWorld).handle
val expEntity = EntityExperienceOrb(...)
world.addFreshEntity(expEntity, CreatureSpawnEvent.SpawnReason.DEFAULT)
}
圧縮されたCraftBukkitのソースコードのよみかた
公式のリポジトリで圧縮前のソースコードをよむ。
ソースコードで調べたあとはKotlinの拡張関数や拡張プロパティとして定義しておくことで利用しやすくできる。
Discussion