🐥

CraftBukkitを利用したSpigotのプラグイン開発をしよう

2022/08/07に公開

CraftBukkitを利用するメリット

CraftBukkitを利用するということは、\textcolor{blue}{サーバーそのものの仕組みをつかっている} ことになる。そのため、ブロックを壊した場合などに \textcolor{red}{状態や副作用を考える必要がない}

例えば、ブロックを壊した場合には次のようなことを考える必要がなくなる。

  • 道具の耐久値
  • 道具のエンチャント(耐久、幸運、シルクタッチ、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 で次のように読み込む。

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のソースコードのよみかた

公式のリポジトリで圧縮前のソースコードをよむ。

https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/browse/src/main/java/org/bukkit/craftbukkit

ソースコードで調べたあとはKotlinの拡張関数や拡張プロパティとして定義しておくことで利用しやすくできる。

https://github.com/m4kvn/spigot-miner/blob/master/src/main/java/com/m4kvn/spigot/miner/nms/NMS_Utils.kt#L13-L38

Discussion