🐤

Kotlin で作る Spigot Plugin

2021/11/14に公開

はじめに

この記事では、Kotlin を使った Spigot (Minecraft Server) 用のプラグインを作成する方法を解説します。ここに示した方法でいわゆる一括破壊のプラグインを作ってみましたが、割とさくさく書けて体験が良かったので、紹介していきます。

プラグインの作り方

環境構築

この記事では、以下の環境で執筆しています。

  • IntelliJ IDEA Community Edition 2021.2.3
  • Open JDK 17
  • Kotlin 1.5.31
  • Minecraft (Spigot) 1.17.1

Gradle によるプロジェクトの初期化

まずは IntelliJ を起動しまして、Gradle を使ってプロジェクトを初期化していきます。Java の方は使わないのでチェックを外してしまっても大丈夫です。

Gradle プロジェクトの作成

続いてプロジェクト名を設定します。Group Id にはお手持ちのドメインを逆順でお使いください。衝突しなければ良いだけの話なので、ない場合は Github の ID (e.g. io.github.aruneko) を流用するのも可能かと思います。

プロジェクト名の設定

Gradle のバージョン更新

執筆当初デフォルトで使われる Gradle のバージョンは 7.1 でしたが、JDK 17 に対応した Gradle 7.3 は出たばかりのため手動更新が必要でした。下記コマンドにてバージョンアップ作業を行います。将来必要なくなればこの手順はスキップ可能です。

# バージョンの書き換え
$ ./gradlew wrapper --gradle-version 7.3
# 適当なタスクを走らせてバージョンアップを実施
$ ./gradlew wrapper

gradle.properties の編集

もろもろのバージョン情報は gradle.proerties に外出ししておくと取り回しが良くて便利です。今回は Kotlin と Minecraft のバージョンをこちらに記述しておきます。最初から書いてある kotlin.code.style はそのままにして、追記しましょう。

kotlin.code.style=official
kotlin_version=1.5.30
mc_version=1.17.1

build.gradle の編集

build.gradle には Spigot の依存情報と、jar ファイルの作り方を記述します。まず、Spigot の依存情報を載せるために、リポジトリを追加してあげましょう。

repositories {
    mavenCentral()
    maven {
        url = "https://hub.spigotmc.org/nexus/content/repositories/snapshots/"
    }
}

続いて依存関係を書いていきます。Spigot API は実行時に Spigot 本体から参照できるため完成後の jar ファイルに同梱させる必要が無いので、compileOnly で指定してしまっています。

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib:${kotlin_version}"
    compileOnly "org.spigotmc:spigot-api:${mc_version}-R0.1-SNAPSHOT"
}

指定した JDK でビルドしてもらえるようにコンパイルオプションを渡しておきます。執筆時点で Kotlin はまだ JDK17 に最適化したバイナリを吐かないようなので、16 で固定しておきます。また、Kotlin のランタイムを同梱してもらえるように noStdlib オプションは無効化しておきます。

compileKotlin {
    kotlinOptions.jvmTarget = "16"
    kotlinOptions.noStdlib = false
}

最後に jar を吐くスクリプトを書いてあげれば完成です。

jar {
    from {
        configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
    }
}

ついでに plugins セクションで外出しいておいた Kotlin のバージョンを参照するようにしてあげると良いでしょう。

plugins {
    id 'org.jetbrains.kotlin.jvm' version "${kotlin_version}"
}

ソースコードの準備

トップ階層にディレクトリ /src/main/kotlin/net/aruneko/example-kotlin-plugin を作成して、そこにソースコードを置いていきます。また、Spigot が読み取るプラグイン情報ファイルを /src/main/resources/plugin.yml に置く必要があるので、これも準備しておきます。

$ mkdir -p src/main/kotlin/net/aruneko/example_kotlin_plugin
# kt ファイルの作成はターミナルでやっても IntelliJ から生成してもらっても構いません
$ touch src/main/kotlin/net/aruneko/example_kotlin_plugin/ExampleKotlinPlugin.kt
$ mkdir -p src/main/resources
$ touch src/main/resources/plugin.yml

plugins.yml の編集

とりあえず必須4項目だけ埋めてしまいます。今回は 1.17 以降向けのプラグインとして作ります。

  • name: プラグインの名称
  • main: エントリーポイントとなるクラスのありか
  • version: このプラグインのバージョン
  • api-version: サポートする最低の Minecraft バージョン
name: ExampleKotlinPlugin
main: net.aruneko.example_kotlin_plugin.ExampleKotlinPlugin
version: 1.0.0
api-version: 1.17

エントリーポイントの作成

JavaPlugin クラスを継承したクラスを作ればそれが自動的にエントリーポイントとなります。あとは plugin.yml に記した通りに読み込んでくれます。

今回はサンプルですので、起動時にログにメッセージを流すだけのシンプルなプラグインを作ってみましょう。

package net.aruneko.example_kotlin_plugin

import org.bukkit.plugin.java.JavaPlugin

class ExampleKotlinPlugin: JavaPlugin() {
    override fun onEnable() {
        println("Hello, this is an example plugin!")
    }
}

ビルドの実行

先ほど記述しておいた jar タスクを走らせます。終わると ./build/libs 以下に jar ファイルができあがっています。

$ ./gradelw jar
$ ls ./build/libs
example-kotlin-plugin-1.0.0.jar

起動テスト

お手持ちの Spigot 1.17.1 環境にできたプラグインを入れて起動してみましょう。一応 Spigot 環境の作り方もメモ程度に示しておきます。

$ wget https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar
$ java -jar BuildTools.jar --rev 1.17.1
$ mkdir plugins
$ cp ${project_root}/build/libs/example-kotlin-plugin-1.0.0.jar plugins
$ echo 'eula=true' > eula.txt
$ java -jar spigot-1.17.1.jar -nogui

こんな感じで起動時のログに先ほどのメッセージが出てくれば完成です!

Loading libraries, please wait...
(中略)
[22:59:07] [Server thread/INFO]: Debug logging is disabled
[22:59:07] [Server thread/INFO]: Server Ping Player Sample Count: 12
[22:59:07] [Server thread/INFO]: Using 4 threads for Netty based IO
[22:59:07] [Server thread/INFO]: Default game type: SURVIVAL
[22:59:07] [Server thread/INFO]: Generating keypair
[22:59:08] [Server thread/INFO]: Starting Minecraft server on *:25565
[22:59:08] [Server thread/INFO]: Using epoll channel type
[22:59:08] [Server thread/INFO]: [ExampleKotlinPlugin] Loading ExampleKotlinPlugin v1.0.0
[22:59:08] [Server thread/INFO]: Preparing level "world"
(中略)
[22:59:21] [Server thread/INFO]: Preparing start region for dimension minecraft:the_end
[22:59:21] [Worker-Main-9/INFO]: Preparing spawn area: 0%
[22:59:22] [Server thread/INFO]: Time elapsed: 483 ms
[22:59:22] [Server thread/INFO]: [ExampleKotlinPlugin] Enabling ExampleKotlinPlugin v1.0.0
[22:59:22] [Server thread/INFO]: Hello, this is an example plugin!
[22:59:22] [Server thread/INFO]: Done (14.004s)! For help, type "help"

おわりに

この記事では Kotlin で Spigot 用のプラグインを作成する方法を紹介してきました。今回は環境構築をメインにご紹介したため、実践的なプラグインの作成方法については紹介を省いています。一応[1]公式の Java Doc があるので、ここに生えている API を叩きながら何か作ってみるというのも面白いかと思います。

皆さんも何かしら便利プラグインを作って Github で公開してみてはいかがでしょうか?

脚注
  1. 読んで全てが分かるとは一言も申し上げておりません ↩︎

Discussion