Eclipseを用いたSpigotプラグイン作成

## やること
<img width="740" alt="スクリーンショット 2019-08-12 23.00.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274950/cb0e4fa2-2780-e6ca-0a75-e845db169013.png">
こんな感じでプラグイン有効時にログを表示すると言う超簡単なプラグインを実装します．
ちゃんとやれば15分もしないくらいで終わる内容です．

## 対象読者
1. minecraftのspigotサーバーを既に構築できている．

## 筆者の環境
macOS Mojave
バーション: 10.14.6

Macbook Pro (15-inch, 2018)
プロセッサ: 2.2GHz Intel Core i7
メモリ: 16GB 2400MHz DDR4
起動ディスク: Macintrosh HD
グラフィックス: Radeon Pro 555X 4GB
            Intel UHD Graphics 630 1536MB

## 総合開発環境(eclipse)の導入
[ダウンロードサイト](http://mergedoc.osdn.jp/)へアクセスします。
すると以下のようなサイトにアクセスできるはずです．
とりあえず自分は最新版を選択しました．
<img width="1442" alt="スクリーンショット 2019-08-12 18.15.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274950/2ae019f1-9dd7-9666-94f4-9391d81b0bec.png">

次にこの中の `Java` の `full Edition` をインストールします．
`Standard Edition`でも問題ないらしいですが特にそちらを選択する理由もないので自分は`full Edition`を使用しました．
<img width="1242" alt="スクリーンショット 2019-08-12 18.17.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274950/5047542d-6752-cba2-f274-e7beba91cafd.png">

ただ，何故かMacのセキュリティで弾かれたので以下のサイトを参考にして解決しました．
(恐らく，Eclipseの最新版がMac側に認証されていなかった?)
[Mac - すべてのアプリケーションの実行を許可](https://pc-karuma.net/macos-sierra-allow-apps-from-anywhere/)

## プロジェクトの作成
まず,`ファイル->新規->Mavenプロジェクト`の順で選択していきます．
<img width="845" alt="スクリーンショット 2019-08-12 18.31.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274950/2d32cf9a-dffb-89e8-4895-e7d7405f2bca.png">

そうすると以下のような画面が表示されるので「シングルなプロジェクトの作成(アーキテクチャの選択をスキップ)」にチャックを入れて「次へ>」をクリックします．
<img width="670" alt="スクリーンショット 2019-08-12 18.37.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274950/b5bfab35-e862-e446-4fd3-878a59af4712.png">

次にプロジェクト情報を入力する画面です．
(QiitaがQIitaになってるのはただの僕のタイポです...)
<img width="666" alt="スクリーンショット 2019-08-12 18.42.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274950/fcbb7877-e563-bdb8-bb9e-1b8005052914.png">
「グループId」は製作者の名前です．
「アーティファクトId」はプロジェクト名=プラグイン名です。好きなように名付けて構いません。
「バージョン」はバージョン番号です。これも好きなように名付けて問題ないです．
この三つを設定します．他は特に変更する必要はないはずです．

これでプロジェクトの作成は完了です！

## `pon.xml`の設定
次にプラグインを設定するための設定を行なっていきます．
ここで「必要なものの(依存関係)」を準備します．
初期状態ではこうなっていると思います．

```xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.github.kubota</groupId>
  <artifactId>QiitaSample</artifactId>
  <version>1.0.0</version>
</project>
```

ここにspigot関係の設定を記載します．
以下のように`spigot-repository` と `Spigot-API`を追加することで'BukkitAPI'を利用できるようになります．

```xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.github.kubota</groupId>
  <artifactId>QiitaSample</artifactId>
  <version>1.0.0</version>

  <!-- ↓ Spigot-repository -->
  <repositories>
    <repository>
      <id>spigot-repo</id>
      <url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
    </repository>
  </repositories>

  <!-- ↓ Spigot-API -->
  <dependencies>
    <dependency>
      <groupId>org.spigotmc</groupId>
      <artifactId>spigot-api</artifactId>

      <!-- ↓ (Minecraftバージョン)-R0.1-SNAPSHOT -->
      <version>1.13.2-R0.1-SNAPSHOT</version>

      <scope>provided</scope>
    </dependency>
  </dependencies>
</project>
```

ただこれだけだとマインクラフトのversionによっては動作しないので以下のようにプロパティを記載します．

```xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.github.kubota</groupId>
  <artifactId>QiitaSample</artifactId>
  <version>1.0.0</version>

  <!-- ↓ Spigot-repository -->
  <repositories>
    <repository>
      <id>spigot-repo</id>
      <url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
    </repository>
  </repositories>

  <!-- ↓ Spigot-API -->
  <dependencies>
    <dependency>
      <groupId>org.spigotmc</groupId>
      <artifactId>spigot-api</artifactId>

      <!-- ↓ (Minecraftバージョン)-R0.1-SNAPSHOT -->
      <version>1.13.2-R0.1-SNAPSHOT</version>

      <scope>provided</scope>
    </dependency>
  </dependencies>

  <!-- ↓ プロパティ設定 -->
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <!-- ↓ Java version 12 -->
    <maven.compiler.source>12</maven.compiler.source>
    <maven.compiler.target>12</maven.compiler.target>
  </properties>
</project>
```

あと現在はのちに追加する`plugin.yml`との連携を容易にするために以下のように変更します．

```xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.github.kubota</groupId>
  <artifactId>QiitaSample</artifactId>
  <version>1.0.0</version>

  <!-- ↓ Spigot-repository -->
  <repositories>
    <repository>
      <id>spigot-repo</id>
      <url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
    </repository>
  </repositories>

  <!-- ↓ Spigot-API -->
  <dependencies>
    <dependency>
      <groupId>org.spigotmc</groupId>
      <artifactId>spigot-api</artifactId>

      <!-- ↓ (Minecraftバージョン)-R0.1-SNAPSHOT -->
      <version>1.13.2-R0.1-SNAPSHOT</version>

      <scope>provided</scope>
    </dependency>
  </dependencies>

  <!-- ↓ プロパティ設定 -->
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <!-- ↓ Java version 12 -->
    <maven.compiler.source>12</maven.compiler.source>
    <maven.compiler.target>12</maven.compiler.target>
  </properties>

  <!-- plugin.yml を pom.xml と連動させる -->
  <build>
    <resources>
      <resource>
        <targetPath>.</targetPath>
        <filtering>true</filtering>
        <directory>src/main/resources/</directory>
      </resource>
    </resources>
  </build>

</project>
```

以上で，`pom.xml`の変更は終了です．

## プロジェクトの更新
`pom.xml`の変更によって依存関係が多少変化したのでその更新を行う必要があります．
やり方としては作成したプロジェクト(僕の画面上では`QiitaSample`が該当)を右クリックし，`Maven->プロジェクトの更新`の順で選択していきます．
こうすることで依存関係の更新が始まります(時間はそんなにかかりませんでした)．
<img width="678" alt="スクリーンショット 2019-08-12 20.07.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274950/cd6e12f0-00a0-631c-2017-9853e384a488.png">

そうすると以下のような画面が出ると思います.
(筆者の場合は以前に作成したプロジェクトも出てきますが,初作成なら一つだけでしょう)
<img width="537" alt="スクリーンショット 2019-08-12 20.12.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274950/a05888e4-86d4-fe07-0c7b-3368146199c9.png">
これに今回作成したプロジェクトをチャックし,OKを押します，
これで更新は完了です！

## プラグインの作成
BukkitAPIの依存関係の設定が完了したのでPlugin自体の作成入っていくことができます．

### メインクラスの作成
作成したプロジェクト下の`src/main/java`を右クリックして「新規」→「パッケージ」の順に選択して行きましょう。
<img width="670" alt="スクリーンショット 2019-08-12 20.16.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274950/74c77c60-4321-1202-3f32-73ee717a9259.png">

次にパッケージ名は **グループIDとプラグイン名を.(ドット)で繋げたもの** を使用するようにしましょう．
筆者の場合はグループIDが`com.github.kubota`，プラグイン名が`QiitaSample`である`com.gtihub.kubota.qiitasample`となります
一部変化しているのはこのパッケージ名は大文字が使えないので小文字に置き換えたり,`-`(ハイフン)が使用できないので`_`(アンダーバー)に置き換えているためです．

そして，作成したパッケージを右クリックして「新規」→「クラス」の順に選択して行きましょう。
<img width="853" alt="スクリーンショット 2019-08-12 20.26.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274950/6afbbee4-eb6c-d8f0-a235-faee17cab416.png">

そうすると以下のような画面が表示されるのでそこに咲くせうするクラス名を記載しましょう．
名前はなんでもいいですが,わかりやすいように今のプロジェクト名か`Main`としましょう．
(ここのQiitaがQIitaになってるのも僕のタイポです...)
<img width="568" alt="スクリーンショット 2019-08-12 20.32.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274950/cc8f0cd7-4cba-06f3-0533-bb3c098db846.png">

これを開くと以下のように記載されているはずです．

```java
package com.github.kubota.qiitasample;

public class QIitaPlugin {

}
```

これを以下のように変更しましょう．

```java
package com.github.kubota.qiitasample;
import org.bukkit.plugin.java.JavaPlugin;

public class QIitaPlugin extends JavaPlugin{
	//↓ onEnableはロードされた時に実行されるメソッド
	@Override
	public void onEnable() {
		// ↓ サーバー上にログを残す
		getLogger().info("Hello, Qiita!");
	}
}
```

それでは変更した箇所を一つ一つ解説していきます．

```java
import org.bukkit.plugin.java.JavaPlugin;
```

この行で`plugin`を作成するのに必要な機能をインポートしています．

```java
public class QIitaPlugin extends JavaPlugin{
```

この箇所で追加した`exetends JavaPlugin`によりマインクラフトの基本機能がすでに実装されているクラスに機能を追加していく形で作成していくことが可能になります．

```java
public class QIitaPlugin extends JavaPlugin{
	//↓ onEnableはロードされた時に実行されるメソッド
	@Override
	public void onEnable() {
		// ↓ サーバー上にログを残す
		getLogger().info("Hello, Qiita!");
	}
}
```

ここで `onEnable`メソッド に関して軽く説明します．
`@Override`と言う箇所で `Javaplugin`クラス内のメソッドを上書きすること示しています．
上書き対象は `onEnable`メソッド です.
`onEnable`メソッド はプラグインが有効になったタイミングで自動的に実行されるメソッドです．
ここの中の処理は上書きをしない状態であれば何も機能はないです.

なので上書き処理として 'getLogger().info()'メソッドで 「Hello,Qiita!」とコンソールに表示と言うものを追加します．
この上書き処理によって **プラグインが有効になったタイミングで自動的に 「Hello,Qiita!」とコンソールに表示する** と言う機能をもつメソッドになりました．

### plugin.ymlの作成
`src/main/resources`を右クリックして「新規」→「ファイル」を選択します.
<img width="791" alt="スクリーンショット 2019-08-12 20.51.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274950/03a27252-e64e-bbde-7956-25c975b9ebf2.png">
そして，`plugin.yml`という名前のファイルを作成します．
<img width="537" alt="スクリーンショット 2019-08-12 20.53.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274950/086a43c6-c254-a62e-a026-dff158c7a580.png">
以下の４つが記載されていればです．

```yml
name: "メインクラス"
version: "バーション"
main: "メインクラス"
api-version: "BukkitAPIのバージョン""
```
`name`はプラグイン名を記載します。
`version`はプラグインのバージョンです。ただ,このversionですが今回は`plugin.yml`を`pom.xml`と連動させているので`${project.version}`と記載すればOKです． 
`main`はメインクラスのパッケージ名とクラス名をドットで繋げたものを記載します。
`api-version`は厳密には必須ではありませんが、ほぼ必須なので記載しておきましょう。

これは対応しているBukkitAPIのバージョンを記載します。たとえば1.13や1.13.2なら1.13、1.14や1.14.2なら1.14という具合です。

```yml
name: "QiitaSample"
version: "${project.version}"
main: "com.github.kubota.qiitasample.QiitaSample"
api-version: "1.13"
```

## プラグインのコンパイル
これでもう大体実装は完了しました．
あとはコンパイルするだけです．
方法はプロジェクト名の部分を右クリックして「実行」→「Maven install」を選択します。
<img width="918" alt="スクリーンショット 2019-08-12 21.14.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274950/6e45c006-9fa6-8e04-04a1-2ca87745ff7f.png">

これを実行するとコンソール画面に結果が表示されます．
`BUILD SUCCESS`と表示されていれば成功です．

```
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.762 s
[INFO] Finished at: 2019-08-12T21:15:44+09:00
[INFO] ------------------------------------------------------------------------
```
そうすると `terget` に `Jar`ファイルが追加されているはずです．
<img width="417" alt="スクリーンショット 2019-08-12 21.18.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274950/ced009cf-1860-75b5-899e-6f8c42a2bd6b.png">

これをもともと作成してあったサーバのディレクトリの `Plugins` にこの`Jar`ファイルを追加して実行すればPluginは動き出します
(諸事情によりプラグイン名が `QiitaTest` になっていますが上記の手順で正常に動作するのを確認しました)
<img width="740" alt="スクリーンショット 2019-08-12 23.00.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274950/cb0e4fa2-2780-e6ca-0a75-e845db169013.png">

と言うことで以上で今回の内容は終了です．
自分はMac環境下でプラグインの開発を行いましたが,Eclipseの使い方自体はWindowsも同様なので参考になると思います.
(多少,ボタンの配置は違うかもしれないですが...)

## 続き
[[MineCraftプラグイン]コマンドを受け付けてイベントを発生させる](https://qiita.com/kubo_programer/items/52613ffbc5eb3c5587ef)

## はまったところ
```yml
name: "SampleProject"
version: "${project.version}"
main: "com.github.kubota.sampleproject.SampleProject"
api-version: "1.13"
```
本編の`plugin.yml`には記載していますが．
この`main`のところをパッケージ名のみで問題ないと勘違いしており以下のように記載していました．

```yml
name: "SampleProject"
version: "${project.version}"
main: "com.github.kubota.sampleproject"
api-version: "1.13"
```

これにより`SampleProject`ファイルが参照できず以下のようなエラーを吐いていました．

```
[16:11:39 ERROR]: Could not load 'plugins/SampleProject' in folder 'plugins'
org.bukkit.plugin.InvalidPluginException: Cannot find main class `com.github.kubota.sampleproject'
	at org.bukkit.plugin.java.PluginClassLoader.<init>(PluginClassLoader.java:62) ~[spigot-1.13.2.jar:git-Spigot-1a3504a-dfa7583]
	at org.bukkit.plugin.java.JavaPluginLoader.loadPlugin(JavaPluginLoader.java:135) ~[spigot-1.13.2.jar:git-Spigot-1a3504a-dfa7583]
	at org.bukkit.plugin.SimplePluginManager.loadPlugin(SimplePluginManager.java:332) ~[spigot-1.13.2.jar:git-Spigot-1a3504a-dfa7583]
	at org.bukkit.plugin.SimplePluginManager.loadPlugins(SimplePluginManager.java:252) [spigot-1.13.2.jar:git-Spigot-1a3504a-dfa7583]
	at org.bukkit.craftbukkit.v1_13_R2.CraftServer.loadPlugins(CraftServer.java:325) [spigot-1.13.2.jar:git-Spigot-1a3504a-dfa7583]
	at net.minecraft.server.v1_13_R2.DedicatedServer.init(DedicatedServer.java:213) [spigot-1.13.2.jar:git-Spigot-1a3504a-dfa7583]
	at net.minecraft.server.v1_13_R2.MinecraftServer.run(MinecraftServer.java:698) [spigot-1.13.2.jar:git-Spigot-1a3504a-dfa7583]
	at java.lang.Thread.run(Thread.java:835) [?:?]
Caused by: java.lang.ClassNotFoundException: com.github.kubota.projectsample
	at java.net.URLClassLoader.findClass(URLClassLoader.java:436) ~[?:?]
	at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:136) ~[spigot-1.13.2.jar:git-Spigot-1a3504a-dfa7583]
	at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:82) ~[spigot-1.13.2.jar:git-Spigot-1a3504a-dfa7583]
	at java.lang.ClassLoader.loadClass(ClassLoader.java:588) ~[?:?]
	at java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[?:?]
	at java.lang.Class.forName0(Native Method) ~[?:?]
	at java.lang.Class.forName(Class.java:415) ~[?:?]
	at org.bukkit.plugin.java.PluginClassLoader.<init>(PluginClassLoader.java:60) ~[spigot-1.13.2.jar:git-Spigot-1a3504a-dfa7583]
	... 7 more

```

## 参考文献
- [Bukkitプロジェクトの作成 Eclipse編](https://e-craft.io/bukkit/development/tutorial/create-project-eclipse/)
- [[Bukkitプラグイン制作講座-其之二]メインクラスの作成、ビルド迄](https://jyn.jp/bukkit-plugin-development-2/)
- [【超初心者向け】Maven超入門](https://qiita.com/tarosa0001/items/e5667cfa857529900216)
- [【Minecraft】(Java未経験者対応)Bukkit/Spigot対応プラグインの作り方講座【準備編】](https://ch.nicovideo.jp/minecrafter/blomaga/ar435132)
- [マインクラフトでマルチサーバーを立てよう! (Think IT Books)](https://www.amazon.co.jp/dp/4295000809/ref=cm_sw_r_tw_dp_U_x_TRsuDbZYTV1YE)