提供: Minecraft Modding Wiki
移動先: 案内検索

警告: ログインしていません。編集を行うと、あなたの IP アドレスが公開されます。ログインまたはアカウントを作成すれば、あなたの編集はその利用者名とともに表示されるほか、その他の利点もあります。

この編集を取り消せます。 下記の差分を確認して、本当に取り消していいか検証してください。よろしければ変更を保存して取り消しを完了してください。
最新版 編集中の文章
36行目: 36行目:
  
 
Pleiadesを利用する場合、「開発対象用 JDK」と、ビルドツールMavenが実行できるプラグイン「m2e」が同梱されているものを選択してください。<br/>
 
Pleiadesを利用する場合、「開発対象用 JDK」と、ビルドツールMavenが実行できるプラグイン「m2e」が同梱されているものを選択してください。<br/>
(Eclipseを既に利用している場合でも、m2eを後から追加インストールすることは可能です。)
+
(Eclipseを既に利用している場合でも、m2eを後から追加インストールすることは可能です。)<br/>
 
+
以下、m2eが既に導入されている前提で説明します。
spigotなどのBukkitサーバーの実行環境を利用する場合、BuildTools.jar を利用してサーバー実行環境をビルドする必要がありますが、Mavenが利用できる場合は、Mavenが開発用のライブラリを自動でダウンロードするため、BuildTools.jar を使わなくても開発環境を構築することが可能です。<br/>
 
ただし、当然ですが、デバッグ実行するための実行環境は必要になりますから、BuildTools.jar を利用して実行環境も準備しておいてください。このチュートリアルでは、BuildTools.jar を利用した実行環境の構築は割愛いたします。
 
<!--
 
もし、BuildTools.jar を利用した実行環境の構築について、きれいにまとめられている資料があれば、ここにリンクを置いてください。
 
-->
 
  
 
== Plugin用プロジェクトを始めるために ==
 
== Plugin用プロジェクトを始めるために ==
90行目: 85行目:
  
 
Eclipseの画面に戻ると、左側に TutorialPlugin プロジェクトが作成されているはずです。ここまで、うまく作成できましたか?
 
Eclipseの画面に戻ると、左側に TutorialPlugin プロジェクトが作成されているはずです。ここまで、うまく作成できましたか?
 
「ビルドプランを計算できませんでした。」と出た場合、作成したパッケージを右クリックし「実行」から「Maven install」をクリックすることにより、
 
Mavenのインストールが始まりエラーが出なくなります。
 
  
 
=== Bukkit API の参照設定 ===
 
=== Bukkit API の参照設定 ===
100行目: 92行目:
 
[[Image:create_project4.png]]
 
[[Image:create_project4.png]]
  
まず、Java開発環境(JDK)の参照設定をします。<br/>
+
まず、Java実行環境(JRE)の参照設定をします。<br/>
 
一番最後の行に '''</project>''' というタグがありますが、その1行上に、次の内容を挿入してください。<br/>
 
一番最後の行に '''</project>''' というタグがありますが、その1行上に、次の内容を挿入してください。<br/>
(なお、これは Java 7 を参照してビルドするための設定です。もし Java 6 を参照してビルドしたい場合は、sourceタグとtargetタグに書かれている 1.7 のところを 1.6 に変更してください。また、Java 8を参照したい場合は、1.7を1.8に変更してください。)
+
(なお、これは Java 7 を参照してビルドするための設定です。もし Java 6 を参照してビルドしたい場合は、sourceタグとtargetタグに書かれている 1.7 のところを 1.6 に変更してください。)
  
<pre lang="xml">
+
<code>
 
   <build>
 
   <build>
 
     <plugins>
 
     <plugins>
111行目: 103行目:
 
         <artifactId>maven-compiler-plugin</artifactId>
 
         <artifactId>maven-compiler-plugin</artifactId>
 
         <configuration>
 
         <configuration>
           <source>1.7</source>
+
           <nowiki>&lt;</nowiki>source>1.7</source>
 
           <target>1.7</target>
 
           <target>1.7</target>
 
         </configuration>
 
         </configuration>
117行目: 109行目:
 
     </plugins>
 
     </plugins>
 
   </build>
 
   </build>
</pre>
+
</code>
  
次に、Bukkit APIを実装しているSpigotのリポジトリがどこにあるかURLで示します。<br/>
+
次に、BukkitリポジトリのURL設定を追加します。<br/>
 
下記の内容を追記してください。
 
下記の内容を追記してください。
  
<pre lang="xml">
+
<code>
 
   <repositories>
 
   <repositories>
 
     <repository>
 
     <repository>
       <id>spigot-repo</id>
+
       <id>bukkit-repo</id>
       <url>https://hub.spigotmc.org/nexus/content/groups/public</url>
+
       <url>http://repo.bukkit.org/content/groups/public/</url>
 
     </repository>
 
     </repository>
 
   </repositories>
 
   </repositories>
</pre>
+
</code>
  
 
最後に、Bukkit API の参照設定を追加します。<br/>
 
最後に、Bukkit API の参照設定を追加します。<br/>
 
下記の内容を追記してください。
 
下記の内容を追記してください。
  
<pre lang="xml">
+
<code>
 
   <dependencies>
 
   <dependencies>
 
     <dependency>
 
     <dependency>
 
       <groupId>org.bukkit</groupId>
 
       <groupId>org.bukkit</groupId>
 
       <artifactId>bukkit</artifactId>
 
       <artifactId>bukkit</artifactId>
       <version>1.10.2-R0.1-SNAPSHOT</version>
+
       <version>1.6.4-R2.0</version>
 
     </dependency>
 
     </dependency>
 
   </dependencies>
 
   </dependencies>
</pre>
+
</code>
  
この設定では、Bukkit API 1.10.2-R0.1-SNAPSHOT が参照されます。<br/>
+
この設定では、Bukkit API 1.6.4-R2.0 が参照されます。<br/>
 
別のバージョンを参照したい場合は、versionタグの中を変更してください。<br/>
 
別のバージョンを参照したい場合は、versionタグの中を変更してください。<br/>
設定が可能なバージョン番号の一覧は、[https://hub.spigotmc.org/nexus/content/groups/public/org/bukkit/bukkit/ こちら] を参照してください。
+
設定が可能なバージョン番号の一覧は、[http://repo.bukkit.org/content/groups/public/org/bukkit/bukkit/ こちら] を参照してください。
  
 
ここまで編集をすると、pom.xmlは次のようになっているはずです。確認してみてください。
 
ここまで編集をすると、pom.xmlは次のようになっているはずです。確認してみてください。
  
<pre lang="xml">
+
<code>
 
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 
<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">
 
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
163行目: 155行目:
 
         <artifactId>maven-compiler-plugin</artifactId>
 
         <artifactId>maven-compiler-plugin</artifactId>
 
         <configuration>
 
         <configuration>
           <source>1.7</source>
+
           <nowiki>&lt;</nowiki>source>1.7</source>
 
           <target>1.7</target>
 
           <target>1.7</target>
 
         </configuration>
 
         </configuration>
171行目: 163行目:
 
   <repositories>
 
   <repositories>
 
     <repository>
 
     <repository>
       <id>spigot-repo</id>
+
       <id>bukkit-repo</id>
       <url>https://hub.spigotmc.org/nexus/content/groups/public</url>
+
       <url>http://repo.bukkit.org/content/groups/public/</url>
 
     </repository>
 
     </repository>
 
   </repositories>
 
   </repositories>
179行目: 171行目:
 
       <groupId>org.bukkit</groupId>
 
       <groupId>org.bukkit</groupId>
 
       <artifactId>bukkit</artifactId>
 
       <artifactId>bukkit</artifactId>
       <version>1.10.2-R0.1-SNAPSHOT</version>
+
       <version>1.6.4-R2.0</version>
 +
      <type>jar</type>
 +
      <scope>provided</scope>
 
     </dependency>
 
     </dependency>
 
   </dependencies>
 
   </dependencies>
 
</project>
 
</project>
</pre>
+
</code>
  
 
pom.xmlの編集が完了したら、Ctrl + S でファイルを保存してください。
 
pom.xmlの編集が完了したら、Ctrl + S でファイルを保存してください。
200行目: 194行目:
  
 
[[Image:Create_project6.png]]
 
[[Image:Create_project6.png]]
 
:'''訳者補記''': ダウンロードされた bukkit-x.x.x-Rxx.jar を右クリックし、Maven > Javadoc のダウンロード を実行しておくとよいでしょう。
 
  
 
=== パッケージの作成 ===
 
=== パッケージの作成 ===
219行目: 211行目:
 
次に、プラグインのメインクラスを作成します。<br/>
 
次に、プラグインのメインクラスを作成します。<br/>
 
メインクラスは、JavaPlugin を継承する必要があります。<br/>
 
メインクラスは、JavaPlugin を継承する必要があります。<br/>
(逆に、メインクラス以外のクラスは、直接的にも間接的にも、JavaPlugin を継承しないようにしてください。CraftBukkit 1.7.2-R0.3 以降では、プラグインが正しく動作しなくなります。)<br/>
+
(逆に、メインクラス以外のクラスは、直接的にも間接的にも、'''JavaPlugin を継承しないようにしてください。'''CraftBukkit 1.7.2-R0.3 以降では、プラグインが正しく動作しなくなります。)<br/>
 
メインクラスは、プラグイン名と同じ名前にすることが望ましいです。
 
メインクラスは、プラグイン名と同じ名前にすることが望ましいです。
  
227行目: 219行目:
  
 
名前の欄にクラス名を入力してください。<br/>
 
名前の欄にクラス名を入力してください。<br/>
スーパークラスの欄に「org.bukkit.plugin.java.JavaPlugin」と入力してください。<br/>
+
スーパークラスの欄に「org.bukkit.plugin.java.javaPlugin」と入力してください。<br/>
 
(参照... ボタンを押して、開いたダイアログに「JavaPlugin」と入力して該当クラスを検索して選択しても構いません。)
 
(参照... ボタンを押して、開いたダイアログに「JavaPlugin」と入力して該当クラスを検索して選択しても構いません。)
  
 
完了 を押して、新規クラスが作成されたことを確認して下さい。ソースコードは次のようになっているはずです。
 
完了 を押して、新規クラスが作成されたことを確認して下さい。ソースコードは次のようになっているはずです。
  
<pre lang="java">
+
<source lang="java">
 
package my.test.plugin.tutorialplugin;
 
package my.test.plugin.tutorialplugin;
  
240行目: 232行目:
  
 
}
 
}
</pre>
+
</source>
  
 
{{warning}} メインクラスは、コンストラクタを実行したり、新しいインスタンスを作成したりしないでください。
 
{{warning}} メインクラスは、コンストラクタを実行したり、新しいインスタンスを作成したりしないでください。
264行目: 256行目:
 
''plugin.yml'' に、下記の3行を書いてください。
 
''plugin.yml'' に、下記の3行を書いてください。
  
<syntaxhighlight lang="yaml">
+
<source lang="yaml">
 
name: (あなたのプラグイン名)
 
name: (あなたのプラグイン名)
 
main: (作成したパッケージ名).(作成したメインクラス)
 
main: (作成したパッケージ名).(作成したメインクラス)
 
version: (あなたのプラグインのバージョン)
 
version: (あなたのプラグインのバージョン)
</syntaxhighlight>
+
</source>
  
 
このチュートリアルでは、次のように作成します。
 
このチュートリアルでは、次のように作成します。
  
<syntaxhighlight lang="yml">
+
<source lang="yaml">
 
name: TutorialPlugin
 
name: TutorialPlugin
 
main: my.test.plugin.tutorialplugin.TutorialPlugin
 
main: my.test.plugin.tutorialplugin.TutorialPlugin
 
version: 0.0.1
 
version: 0.0.1
</syntaxhighlight>
+
</source>
  
 
{{note}} メインクラスの設定は、大文字小文字が区別されるので、大文字小文字に注意して設定してください。
 
{{note}} メインクラスの設定は、大文字小文字が区別されるので、大文字小文字に注意して設定してください。
{{note}} コロン(:)のあとにワンスペース( )あるのに注意してください。
 
  
  
287行目: 278行目:
 
このメソッドは、プラグインが有効/無効になったときに、Bukkitから呼び出しされます。<br />
 
このメソッドは、プラグインが有効/無効になったときに、Bukkitから呼び出しされます。<br />
 
デフォルトでは、プラグインは自動的に読み込まれたときに、イベントを登録やデバッグ出力を行うことが出来ます。<br />
 
デフォルトでは、プラグインは自動的に読み込まれたときに、イベントを登録やデバッグ出力を行うことが出来ます。<br />
onEnable()は、Bukkitが起動するときに、プラグインが有効化されたときに呼び出されます。onDisable()は、Bukkitが停止するときに、プラグインが無効化されたときに呼び出されます。<br />
+
onEnable()は、プラグインがBukkitから読み込まれるときに最初に呼ばれ、プラグインを実行するために必須です。<br />
  
 
=== onEnable()とonDisable()の基本 ===
 
=== onEnable()とonDisable()の基本 ===
 
前のセクションで作成したメインクラスに、onEnable()とonDisable()のメソッドを作成します。<br />
 
前のセクションで作成したメインクラスに、onEnable()とonDisable()のメソッドを作成します。<br />
 
<blockquote><source lang="java">
 
<blockquote><source lang="java">
package my.test.plugin.tutorialplugin;
+
public void onEnable(){
 
   
 
   
import org.bukkit.plugin.java.JavaPlugin;
+
}
 
public class TutorialPlugin extends JavaPlugin {
 
 
   
 
   
    @Override
+
public void onDisable(){  
    public void onEnable() {
 
        // TODO ここに、プラグインが有効化された時の処理を実装してください。
 
    }
 
 
   
 
   
    @Override
 
    public void onDisable() {
 
        // TODO ここに、プラグインが無効化された時の処理を実装してください。
 
    }
 
 
}
 
}
 
</source></blockquote>
 
</source></blockquote>
  
  
現時点では、このメソッドは何も行いません。
+
現時点では、このメソッドは何も行いません。また、エラーが発生する事にも気付くでしょう。このエラーは、メインクラスが、プラグインの機能を継承(extends)する必要がある事を示しています。当クラスの定義文を、下記のように変更しましょう。
 +
 
 +
これを・・・
 +
<blockquote><source lang="java">Class <classname> {}</source></blockquote>
  
=== Loggerを利用したメッセージ出力 ===
+
このように変更する。
 +
<blockquote><source lang="java">Class <classname> extends JavaPlugin {}</source></blockquote>
 +
 
 +
すると、前述の追加コードが赤の下線でハイライト表示され、何かが間違っていることを通知してくるはずです。このハイライト部にマウスを重ねると、下記のようなポップアップが表示されるので、「'JavaPlugin'をインポートします(org.bukkit.plugin.java)」を選択します。
 +
 
 +
<blockquote>[[ファイル:to_need_import_package.png]]</blockquote>
  
始めに、プラグインが実際に動作するかどうかを確認するため、シンプルなメッセージをサーバコンソールに表示させてみましょう。<br/>
+
もしくは、
ログを出力するには、''getLogger()''メソッドを実行してLoggerを取得し、そのinfoメソッドを呼び出します。
+
<blockquote><source lang="java">import org.bukkit.plugin.java.JavaPlugin;</source></blockquote>
 +
をコード上部の定義部に記述する事でも同様の事が行えます。
  
<blockquote><source lang="java">
+
=== Loggerを利用したメッセージ出力 ===
getLogger().info("onEnableメソッドが呼び出されたよ!!");
 
</source></blockquote>
 
  
onDisable()メソッドについても同等の記述を行います。<br/>
+
始めに、プラグインが実際に動作するかどうかを確認するため、シンプルなメッセージをサーバコンソールに表示させてみましょう。この処理として、ログ出力機能(Logger)をメインクラスに定義して初期化します。
メインクラスに、次のように実装してみてください。
+
<blockquote><source lang="java">Logger log = this.getLogger();</source></blockquote>
 +
その後、onEnable()メソッドに、プラグインが動作している事を通知するメッセージを出力する処理を記述します。
 +
<blockquote><source lang="java">log.info("Your plugin has been enabled.");</source></blockquote>
  
 +
onDisable()メソッドについても同等の記述を行います。ここまでのコーディングによって、メインクラスは下記の様な内容になっているはずです。
 
<blockquote><source lang="java">
 
<blockquote><source lang="java">
package my.test.plugin.tutorialplugin;
+
package me.<yourname>.<pluginname>;
 
   
 
   
 +
import java.util.logging.Logger;
 
import org.bukkit.plugin.java.JavaPlugin;
 
import org.bukkit.plugin.java.JavaPlugin;
 
   
 
   
public class TutorialPlugin extends JavaPlugin {
+
public class <classname> extends JavaPlugin {
 +
 +
Logger log;
 
   
 
   
    @Override
+
public void onEnable(){
    public void onEnable() {
+
log = this.getLogger();
        getLogger().info("onEnableメソッドが呼び出されたよ!!");
+
log.info("Your plugin has been enabled!");
    }
+
}
 
   
 
   
    @Override
+
public void onDisable(){
    public void onDisable() {
+
log.info("Your plugin has been disabled.");
        getLogger().info("onDisableメソッドが呼び出されたよ!!");
+
}
    }
 
 
}
 
}
 
</source></blockquote>
 
</source></blockquote>
 
ここまで作ったところで、[[#プラグインの配布|プラグインのJarファイルの発行]] を行ってプラグインを作成し、実際にCraftBukkitのpluginsフォルダへ導入して、コンソールに設定したログメッセージが表示されることを確認してみてください。
 
 
=== Reloadを制御する ===
 
 
サーバーが終了処理をするときや、開始処理をするときに限らず、
 
サーバーが /reload コマンドにより、プラグインがdisableされenableされる動作について理解しておくことも重要です。<br/>
 
サーバーが開始したときについてだけ初期化処理を考慮することは危険です。<br/>
 
なぜなら、プレイヤーは既にオンライン状態で接続していますし、ワールドデータやチャンクは既にロードされていますし、他にもいろいろ想定していない違いがあります。
 
 
* /reload が実行されると、プラグインとしては、onDisable() が実行されて、onEnable() が実行されます。
 
* staticで保持していないデータは、全て失われます。
 
* 上記に書いてあるように、プレイヤーやワールドやチャンクは既にロード済みの状態です。
 
  
 
== イベントとリスナ ==
 
== イベントとリスナ ==
373行目: 354行目:
 
具体的には、"give"コマンドは既にいくつかのプラグインで利用されています。
 
具体的には、"give"コマンドは既にいくつかのプラグインで利用されています。
 
もし独自に"give"コマンドを実装した場合は、
 
もし独自に"give"コマンドを実装した場合は、
"give"コマンドを実装している他のプラグインとの互換性は無くなります。<ref group="注">実際には、相互のコマンドを呼び分けるために特定のプレフィクスがコマンドの前に付与されます。しかしそれでも、単にgiveコマンドを呼んだだけではどのコマンドが呼ばれるかわからないことには変わりありません。</ref>
+
"give"コマンドを実装している他のプラグインとの互換性は無くなります。
  
onCommand()は、常にboolean型の値<ref group="注">trueかfalseのどちらか</ref>を戻り値として返さねばなりません。
+
onCommand()は、常にboolean型の値としてtrue,falseのどちらかを戻り値として返さねばなりません。
 
trueを返した場合は、情報表示のためのイベントは発生しません。
 
trueを返した場合は、情報表示のためのイベントは発生しません。
 
falseを返した場合は、プラグインファイルを"usage: property"に戻し、コマンドを実行したプレイヤーに、コマンドの利用方法を通知するメッセージを表示します。
 
falseを返した場合は、プラグインファイルを"usage: property"に戻し、コマンドを実行したプレイヤーに、コマンドの利用方法を通知するメッセージを表示します。
384行目: 365行目:
 
* Command cmd - 実行されたコマンドの内容
 
* Command cmd - 実行されたコマンドの内容
 
* String commandLabel - 利用されたコマンドエイリアス
 
* String commandLabel - 利用されたコマンドエイリアス
* String[] args - コマンドの引数を格納した配列(例:/hello abc defコマンドが入力された場合の内容は、args[0]がabc、args[1]がdefとなる)<ref group="注">半角空白 (U+0020)で分割されて、配列に格納される</ref>
+
* String[] args - コマンドの引数を格納した配列(例:/hello abc defコマンドが入力された場合の内容は、args[0]がabc、args[1]がdefとなる)
  
 
=== コマンドの設定 ===
 
=== コマンドの設定 ===
413行目: 394行目:
 
       description: This is a demo command.
 
       description: This is a demo command.
 
       usage: /<command> [player]
 
       usage: /<command> [player]
       permission: tutorialplugin.basic
+
       permission: <plugin name>.basic
 
       permission-message: You don't have <permission>
 
       permission-message: You don't have <permission>
 
</source>
 
</source>
* basic - コマンド名。
+
* basic - コマンド名
* description - コマンドの説明文。
+
* description - コマンドの説明文
* usage - コマンドの使い方。onCommand() でfalseを返したときに、コマンド実行ユーザに向けて表示されるメッセージの内容。あなたの作ろうとしているコマンドの使い方を、わかりやすく説明してください。
+
* usage - onCommand()がfalseを返した際に、コマンド実行ユーザに向けて表示されるメッセージの内容。コマンドの使い方を明解に書いてください。
* permission - コマンドの実行権限。このコマンドの実行に必要なパーミッションノードを設定します。あなたのプラグイン名と、コマンド名を、ピリオド(.)でつなげたパーミッションノードを設定することを推奨します(例:myplugin.test)。
+
* permission - 当コマンドの動作に必要なプラグインの設定を、コマンド実行ユーザに知らせるメッセージ。(主に、コマンド実行に必要なpermissionを書きます)
* permission-message - 上で設定したコマンド実行権限を持たないユーザがコマンドを実行した場合に、実行権限が無いことを同ユーザに知らせるメッセージ。
+
* permission-message - コマンド実行権限を持たないユーザがコマンドを実行した場合に、その旨を同ユーザに知らせるメッセージ。
 
</blockquote>
 
</blockquote>
  
なお、usage の欄では <command>、permission-message の欄では <permission> というキーワードをそのまま指定できます。それぞれ、設定したコマンド名と、設定したパーミッションノードに置き換えられます。<br>
+
:'''Note''': ymlファイルには、1個タブを2個のスペースで記述する必要があります。タブ文字は構文エラーとなるため利用できません。
詳しい書き方は、[[plugin.ymlの設定一覧#コマンドのオプション設定|plugin.ymlの書き方の、コマンドのオプション設定の節]] を参照してください。
 
 
 
:'''Note''': ymlファイルには、インデントに2個以上の半角スペースを記述する必要があります。タブ文字は構文エラーとなるため利用できません。
 
  
 
=== コンソールコマンドとプレイヤーコマンド ===
 
=== コンソールコマンドとプレイヤーコマンド ===
440行目: 418行目:
 
記述例:  
 
記述例:  
 
<blockquote><source lang="java">
 
<blockquote><source lang="java">
@Override
 
 
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
 
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
if (cmd.getName().equalsIgnoreCase("basic")) {  
+
Player player = null;
// プレイヤーが /basic を実行すると、この部分の処理が実行されます...
+
if (sender instanceof Player) {
 +
player = (Player) sender;
 +
}
 +
 
 +
if (cmd.getName().equalsIgnoreCase("basic")){ // If the player typed /basic then do the following...
 +
// do something...
 
return true;
 
return true;
 
} else if (cmd.getName().equalsIgnoreCase("basic2")) {
 
} else if (cmd.getName().equalsIgnoreCase("basic2")) {
                // プレイヤーが /basic2 を実行すると、この部分の処理が実行されます...
+
if (player == null) {
if (!(sender instanceof Player)) {
+
sender.sendMessage("this command can only be run by a player");
sender.sendMessage("このコマンドはゲーム内から実行してください。");
 
 
} else {
 
} else {
Player player = (Player) sender;
+
// do something else...
// コマンドの実行処理...
 
 
}
 
}
 
return true;
 
return true;
457行目: 437行目:
 
return false;
 
return false;
 
}
 
}
</source> </blockquote>
+
</source> </blockquote>  
  
 
この例では、'''basic''' コマンドはログインプレイヤーとサーバコンソールのどちらからでも実行できます。しかし、'''basic2''' コマンドは、ログインプレイヤーしか実行できません。
 
この例では、'''basic''' コマンドはログインプレイヤーとサーバコンソールのどちらからでも実行できます。しかし、'''basic2''' コマンドは、ログインプレイヤーしか実行できません。
480行目: 460行目:
 
とっても良い具体例:
 
とっても良い具体例:
  
MyPlugin.java (プラグインのメインクラス):
+
MyPlugin.java (the main plugin class):
 
<blockquote><source lang="java">
 
<blockquote><source lang="java">
 +
 +
private MyPluginCommandExecutor myExecutor;
 
@Override
 
@Override
 
public void onEnable() {
 
public void onEnable() {
// plugin.yml に basic というコマンドを定義していないと、
+
// ....
        //実行した時にNullPointerExceptionが発生します。注意してください。
+
getCommand("basic").setExecutor(new MyPluginCommandExecutor(this));
+
myExecutor = new MyPluginCommandExecutor(this);
}
+
getCommand("basic").setExecutor(myExecutor);
</source></blockquote>
+
 +
// ...
 +
}</source></blockquote>
  
 
MyPluginCommandExecutor.java:
 
MyPluginCommandExecutor.java:
 
<blockquote><source lang="java">
 
<blockquote><source lang="java">
 +
 
public class MyPluginCommandExecutor implements CommandExecutor {
 
public class MyPluginCommandExecutor implements CommandExecutor {
 
+
        // メインクラスの参照です。処理の中でメインクラスのメソッドを利用しない場合は、省略して構いません。
+
private MyPlugin plugin;
private final MyPlugin instance;  
+
 
 
 
public MyPluginCommandExecutor(MyPlugin plugin) {
 
public MyPluginCommandExecutor(MyPlugin plugin) {
 
this.plugin = plugin;
 
this.plugin = plugin;
 
}
 
}
 
+
 
@Override
 
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
+
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
// コマンドの実行内容...
+
// ... implementation exactly as before ...
 
}
 
}
 
}
 
}
523行目: 507行目:
 
senderの内部データがPlayer型であるとは限らない事を念頭において、チェックを行って下さい。<br/>
 
senderの内部データがPlayer型であるとは限らない事を念頭において、チェックを行って下さい。<br/>
 
処理例:
 
処理例:
<blockquote><source lang="java">
+
<blockquote><source lang="java">public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args){
@Override
+
if ((sender instanceof Player)) {
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args){
+
          // doSomething
    if (sender instanceof Player) {
+
        } else {
 +
          sender.sendMessage(ChatColor.RED + "You must be a player!");
 +
          return false;
 +
        }
 
         Player player = (Player) sender;
 
         Player player = (Player) sender;
        // ここに、処理を実装する。
 
        return true;
 
    } else {
 
        sender.sendMessage(ChatColor.RED + "ゲーム内から実行してください!");
 
 
         return false;
 
         return false;
    }
+
}</source> </blockquote>
    return false;
 
}
 
</source> </blockquote>
 
 
 
このように、'''<code>if (sender instanceof Player)</code>''' で必ずPlayerであることをチェックしないと、プレイヤーでないコマンド実行者(例えばコンソール)がコマンドを実行したときに、'''<code>Player player = (Player) sender</code>''' のところで処理が失敗してしまいます。
 
  
 
=== コマンドのパラメタ長をチェックする ===
 
=== コマンドのパラメタ長をチェックする ===
545行目: 523行目:
 
<blockquote><source lang="java">public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args){
 
<blockquote><source lang="java">public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args){
 
if (args.length > 4) {
 
if (args.length > 4) {
           sender.sendMessage(ChatColor.RED + "パラメタが多すぎます!");
+
           sender.sendMessage(ChatColor.RED + "Too many arguments!");
 
           return false;
 
           return false;
 
         }  
 
         }  
 
         if (args.length < 2) {
 
         if (args.length < 2) {
           sender.sendMessage(ChatColor.RED + "パラメタが足りません!");
+
           sender.sendMessage(ChatColor.RED + "Not enough arguments!");
 
           return false;
 
           return false;
 
         }
 
         }
555行目: 533行目:
  
 
=== プレイヤーがオンラインである事を確認する ===
 
=== プレイヤーがオンラインである事を確認する ===
特定のプレイヤーのPlayerインスタンスを利用したい場合、必ずそのプレイヤーがオンラインである必要があります。<br/>
+
特定のプレイヤーのPlayerインスタンスを利用したい場合、<br/>
 +
必ずそのプレイヤーがオンラインである必要があります。<br/>
 
オンラインであるかどうかをチェックして下さい。<br/>
 
オンラインであるかどうかをチェックして下さい。<br/>
Bukkit.getPlayer(プレイヤー名) または、Bukkit.getPlayerExact(プレイヤー名) で、オンラインのプレイヤーを取得できます。<br/>
 
(Bukkit.getPlayer はプレイヤー名と前方一致で、Bukkit.getPlayerExact は完全一致で、プレイヤーを取得します。)<br/>
 
もし、指定したプレイヤーがオフラインだった場合は、nullが返されます。<br/>
 
 
処理例:
 
処理例:
 
+
<blockquote><source lang="java">public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args){
<blockquote><source lang="java">
+
Player other = (Bukkit.getServer().getPlayer(args[0]));
@Override
+
        if (other == null) {
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+
          sender.sendMessage(ChatColor.RED + args[0] + " is not online!");
    if (args.length < 1) {
+
          return false;
        sender.sendMessage("コマンドの後にプレイヤー名を指定してください!");
+
        }
 
         return false;
 
         return false;
    }
+
}</source> </blockquote>  
    Player target = Bukkit.getPlayerExact(args[0]);
 
    if ( target == null ) {
 
        sender.sendMessage(ChatColor.RED + args[0] + "さんはオフラインです!");
 
        return true;
 
    } else {
 
        sender.sendMessage(ChatColor.AQUA + args[0] + "さんはオンラインです!");
 
        return true;
 
    }
 
}
 
</source> </blockquote>  
 
  
 
オンラインではないプレイヤーのインスタンスに操作を加えたい場合は、一般的には<code>'''OfflinePlayer'''</code>クラスを利用して行う事ができます。
 
オンラインではないプレイヤーのインスタンスに操作を加えたい場合は、一般的には<code>'''OfflinePlayer'''</code>クラスを利用して行う事ができます。
586行目: 552行目:
  
 
== 権限 ==
 
== 権限 ==
:'''Note''': この節は、日本語読者向けに独自の内容を記述しています。
+
Bukkitのパーミッション(権限)APIの利用は、簡単ではありません。
  
Bukkitにおける権限の利用は、とっても簡単です!
+
プレイヤーが特定の権限を持っているかどうかを調べる処理は次のようになります:
 +
<blockquote><source lang="java">if(player.hasPermission("some.pointless.permission")) {
 +
  //Do something
 +
}else{
 +
  //Do something else
 +
}</source></blockquote>
  
権限がセットされているか、いない(Javaの'''null'''と同等)かを調べるには以下のメソッドを利用します:
+
権限がセットされているか、いない(Javaの'''null'''と同等)かを調べる処理は次のようになります:
 
<blockquote><source lang="java">boolean isPermissionSet(String name)</source></blockquote>  
 
<blockquote><source lang="java">boolean isPermissionSet(String name)</source></blockquote>  
  
また、権限を持っているかどうかを調べるには以下のメソッドを利用します:
+
なぜグループの概念が存在しないかと思った方もいるでしょうが、
<blockquote><source lang="java">boolean hasPermission(String name)</source></blockquote>
+
そもそも、権限にはグルーピングの概念は不要なのです。
  
これを利用してプレイヤーが特定の権限を持っているかどうかを調べる処理は次のようになります:
+
元々、グループの主な用途はチャットメッセージをフォーマッティングする事にありました。<br/>
<blockquote><source lang="java">if(player.hasPermission("some.pointless.permission")) {
+
これは権限の機能を利用してもっと簡単に行えます。<br/>
  player.sendMessage("あなたは権限を持っています。");
+
例えば、チャットプラグインの設定において、権限とプレフィクスの関連を定義する事が該当します。<br/>
}else{
+
具体的には、権限'''"someChat.prefix.admin"'''をプレフィクス'''[Admin]'''に対応させる定義を行い、<br/>
  player.sendMessage("あなたは権限を持っていません。");
+
プレイヤーがチャットで発言する度に、プレイヤー名の先頭に'''[Admin]'''が付くようになる機能が挙げられます。
}</source></blockquote>
+
 
 +
他にも、グループに所属する複数のユーザに、<br/>
 +
メッセージを送信するような機能を実現するために利用する事が考えられます。<br/>
 +
この例を、権限を利用した処理で記述すると以下のようになります:
 +
<blockquote><source lang="java">for(Player player: getServer().getOnlinePlayers()) {
 +
 
 +
    if(player.hasPermission("send.recieve.message")) {
 +
        player.sendMessage("You were sent a message");
 +
    }
  
2メソッドの違いは、権限がセットされていなくてもデフォルトで与えられていれば権限を持っているという扱いになるかどうかです。<br>
+
}</source> </blockquote>  
hasPermissionでは デフォルトで与えられていればtrueが返ります。
 
  
PermissionsExなどで 権限はグループとして扱われることが多いですが、Bukkitには権限をグループとして扱う機能はありません。<br/>
+
さて、依然として<br/>
グループとして扱う場合は、別途 上記のようなプラグインを使うか、自分で作る必要があります。
+
「グループを利用せずに、複数のプレイヤーに権限をセットする良い方法は何なのか?」が疑問かと思いますが・・・<br/>
 +
BukkitのAPI自体は、グループの概念を提供していません。<br/>
 +
グループの概念を利用するためには、permissionsBukkitのような<br/>
 +
グループ権限の機能を提供するプラグインを利用する事になります。<br/>
 +
とどのつまり、'''このAPIはインタフェース(Interface)であり、実装(Implementation)ではない'''のです。
  
 
=== 権限の設定 ===
 
=== 権限の設定 ===
  
デフォルトで権限を付与させたり、OPにのみデフォルトで付与させたい場合は、<br>
+
権限を利用して細かな制御を行いたい場合は、<br/>
''plugin.yml''を使うと簡単にできます。
+
デフォルト権限と、子権限の設定を''plugin.yml''に追記する事を検討して下さい。<br/>
 +
この2種類の設定は、オプション(必須ではなく完全に任意で利用される)項目ではありますが、お勧めします。<br/>
  
 
下記は、''plugin.yml''の最後に追加する形で設定する権限です:
 
下記は、''plugin.yml''の最後に追加する形で設定する権限です:
<blockquote>
+
<blockquote><code><source lang="yaml">permissions:
<syntaxhighlight lang="yaml">
 
permissions:
 
 
     doorman.*:
 
     doorman.*:
 
         description: Gives access to all doorman commands
 
         description: Gives access to all doorman commands
635行目: 616行目:
 
         default: true
 
         default: true
 
     doorman.denied:
 
     doorman.denied:
         description: Prevents this user from entering the door
+
         description: Prevents this user from entering the door</source>
</syntaxhighlight>
+
</code></blockquote>
</blockquote>
 
  
  
655行目: 635行目:
 
==== 子権限 ====
 
==== 子権限 ====
  
権限を設定するときに''* 権限''を利用すると、その権限の子権限すべてを操作することができます。<br/>
+
恐らく今までに、''* 権限''を利用してサブ権限を割り当てた事があると思います。<br/>
 
これは、変更されたBukkit APIと、子権限の定義によって実現した機能であり、<br/>
 
これは、変更されたBukkit APIと、子権限の定義によって実現した機能であり、<br/>
 
高い柔軟性を提供しています。<br/>
 
高い柔軟性を提供しています。<br/>
 
下記はその実装例です:
 
下記はその実装例です:
<blockquote>
+
<blockquote><source lang="yaml">permissions:
<syntaxhighlight lang="yaml">
 
permissions:
 
 
     doorman.*:
 
     doorman.*:
 
         description: Gives access to all doorman commands
 
         description: Gives access to all doorman commands
669行目: 647行目:
 
             doorman.knock: true
 
             doorman.knock: true
 
             doorman.denied: false</source>
 
             doorman.denied: false</source>
</syntaxhighlight>
+
 
 
''doorman.*''権限は、いくつかの子権限を含んでいます。
 
''doorman.*''権限は、いくつかの子権限を含んでいます。
 
''doorman.*''権限がtrueである場合に、
 
''doorman.*''権限がtrueである場合に、
676行目: 654行目:
 
その子権限のデフォルト権限は、全て反転(trueが定義値ならfalseになる)された状態で機能します。
 
その子権限のデフォルト権限は、全て反転(trueが定義値ならfalseになる)された状態で機能します。
 
</blockquote>  
 
</blockquote>  
 
ねっ、簡単でしょ?
 
  
 
=== 独自の権限設定 ===
 
=== 独自の権限設定 ===
699行目: 675行目:
  
 
== ブロックの操作 ==
 
== ブロックの操作 ==
 
 
ブロックを生成する簡単な方法は、既存のブロックを取得して変更する事です。<br/>
 
ブロックを生成する簡単な方法は、既存のブロックを取得して変更する事です。<br/>
 
例えば、あなたの5ブロック上方にあるブロックを変更したい場合、<br/>
 
例えば、あなたの5ブロック上方にあるブロックを変更したい場合、<br/>
 
まずはそのブロックを取得した上で、変更を加えることになります。<br/>
 
まずはそのブロックを取得した上で、変更を加えることになります。<br/>
 
PlayerMoveイベントの処理中でこれを行う例を示します:
 
PlayerMoveイベントの処理中でこれを行う例を示します:
<blockquote><source lang="java">
+
<blockquote><source lang="java">public void onPlayerMove(PlayerMoveEvent evt) {
@EventHandler
+
Location loc = evt.getPlayer().getLocation(); // プレイヤーからその位置を得る
public void onPlayerMove(PlayerMoveEvent evt) {
+
World w = loc.getWorld(); // 位置からワールドを得る
    // プレイヤーの位置を取得します。
+
loc.setY(loc.getY() + 5); // 位置のY座標を+5する
    Location loc = event.getPlayer().getLocation();
+
Block b = w.getBlockAt(loc); // ワールド上の指定位置のブロックを得る
    // 位置のY座標を+5します。位置情報を変更しているだけで、実際にプレイヤーの位置が移動するわけではないことに注意してください。
+
b.setTypeId(1); // ブロックのタイプIDに1をセットする
    loc.setY(loc.getY() + 5);
 
    // 指定位置のブロックを取得します。
 
    Block b = loc.getBlock();
 
    // ブロックの種類に石(STONE)を設定します。
 
    b.setType(Material.STONE);
 
 
}</source></blockquote>  
 
}</source></blockquote>  
  
 
このコードの処理は、プレイヤーが移動する(=PlayerMoveイベントが発生する)度に、<br/>
 
このコードの処理は、プレイヤーが移動する(=PlayerMoveイベントが発生する)度に、<br/>
プレイヤーの5ブロック上方のブロックがStoneに変化する動作として見えるでしょう。<br/>
+
プレイヤーの5ブロック上方のブロックがStone(TypeIdが1のブロック)に変化する動作として見えるでしょう。<br/>
 
ブロック取得までの流れは・・・
 
ブロック取得までの流れは・・・
 
# 取得したプレイヤーの位置から、ワールドを取得する
 
# 取得したプレイヤーの位置から、ワールドを取得する
 
# 位置のY座標を+5する
 
# 位置のY座標を+5する
# <code>'''loc.getBlockAt(loc);'''</code>で、指定位置に存在するブロックを得る
+
# <code>'''w.getBlockAt(loc);'''</code>で、ワールドにおける位置に存在するブロックを得る
 
となります。<br/>
 
となります。<br/>
  
 
位置(''loc'')中のブロックインスタンス(''b'')に対して、<br/>
 
位置(''loc'')中のブロックインスタンス(''b'')に対して、<br/>
Materialを変えたり、ブロックデータ自体を変更する事もできます。
+
IDを変えたり、ブロックデータ自体を変更する事もできます。
詳しくは、JavaDocを参照してください。<br/>
 
  
建物の生成や、一定のアルゴリズムに従ったブロック生成処理などを行う一例を示します。<br/>
+
また、ブロックの種類を表すデータはbyte型であるため、<br/>
 +
byte型にキャストしたデータを与えた指定ができます。<br/>
 +
例えば、<code>'''b.setData((byte)3); '''</code>です。
 +
 
 +
 
 +
建物の生成や、一定のアルゴリズムに従ったブロック生成処理などを行う事ができます。<br/>
 
例えば、固体ブロックによる立方体を生成する処理は、<br/>
 
例えば、固体ブロックによる立方体を生成する処理は、<br/>
 
3階層にネストしたforループ処理によって記述できます。
 
3階層にネストしたforループ処理によって記述できます。
<blockquote><source lang="java">
+
<blockquote><source lang="java">public void generateCube(Location point, int length){ // public visible method generateCube() with 2 parameters point and location
    public void generateCube(Location loc, int length){
+
World world = point.getWorld();
        // 与えられたLocationから、立方体の端の座標を取得します。
+
 
        // getN()メソッドを使うと intへキャストする必要がありますが、
+
int x_start = point.getBlockX();     // Set the startpoints to the coordinates of the given location
        // getBlockN()メソッドを使えばそのままintで座標を取得できます。
+
int y_start = point.getBlockY();     // I use getBlockX() instead of getX() because it gives you a int value and so you dont have to cast it with (int)point.getX()
        int x1 = loc.getBlockX();  
+
int z_start = point.getBlockZ();
        int y1 = loc.getBlockY();
+
 
        int z1 = loc.getBlockZ();
+
int x_lenght = x_start + length;   // now i set the lenghts for each dimension... should be clear.
   
+
int y_lenght = y_start + length;
        // 一辺の長さを足すことで、立方体の反対側の座標を計算します。
+
int z_lenght = z_start + length;
        int x2 = x1 + length;
+
 
        int y2 = y1 + length;
+
for(int x_operate = x_start; x_operate <= x_length; x_operate++){  
        int z2 = z1 + length;
+
// Loop 1 for the X-Dimension "for x_operate (which is set to x_start)
   
+
//do whats inside the loop while x_operate is
        World world = loc.getWorld();
+
//<= x_length and after each loop increase
   
+
//x_operate by 1 (x_operate++ is the same as x_operate=x_operate+1;)
        // x座標方向のループ
+
for(int y_operate = y_start; y_operate <= y_length; y_operate++){// Loop 2 for the Y-Dimension
        for (int xPoint = x1; xPoint <= x2; xPoint++) {  
+
for(int z_operate = z_start; z_operate <= z_length; z_operate++){// Loop 3 for the Z-Dimension
            // y座標方向のループ
+
 
            for (int yPoint = y1; yPoint <= y2; yPoint++) {
+
Block blockToChange = world.getBlockAt(x_operate,y_operate,z_operate); // get the block with the current coordinates
                // z座標方向のループ
+
blockToChange.setTypeId(34);   // set the block to Type 34
                for (int zPoint = z1; zPoint <= z2; zPoint++) {
+
}
                    // ループで処理する座標のブロックを取得します。
+
}
                    Block currentBlock = world.getBlockAt(xPoint, yPoint, zPoint);
+
}
                    // ダイアモンドブロックに設定します!
+
}</source></blockquote>  
                    currentBlock.setType(Material.DIAMOND_BLOCK);
 
                }
 
            }
 
        }
 
    }
 
</source></blockquote>  
 
  
 
このメソッドは、辺の長さと開始点の指定を受けて、任意のサイズと位置を持つ直方体を生成する処理です。<br/>
 
このメソッドは、辺の長さと開始点の指定を受けて、任意のサイズと位置を持つ直方体を生成する処理です。<br/>
 
ブロックの削除処理の場合も、このロジックを真似て同様のアルゴリズムで実装する事ができます。<br/>
 
ブロックの削除処理の場合も、このロジックを真似て同様のアルゴリズムで実装する事ができます。<br/>
ただし、セットするブロックの種類はMaterial.AIRになりますね。
+
ただし、セットするブロックのIDはゼロ(=air)になりますね。
  
 
== プレイヤーインベントリの操作 ==
 
== プレイヤーインベントリの操作 ==
804行目: 772行目:
 
=== エンチャント ===
 
=== エンチャント ===
  
アイテムにエンチャントを付与するには、ItemStackクラスの '''addEnchantment(Enchantment enchant, int level)''' メソッドを使用します。
+
アイテムに対するエンチャントに触れる前に、[http://ja.minecraftwiki.net/wiki/Data_values Item Code] と [http://ja.minecraftwiki.net/wiki/Enchanting EID]を見てから以下の解説を読んでください。
  
addEnchantment()メソッドでは、元々エンチャントが出来ないアイテムに対して、独自にエンチャントを付与する処理は書けません。<br/>
+
エンチャントは、Enchantmentクラスが受け持っている機能ですが、<br/>
もし、通常ありえないエンチャントを設定したい場合は、addEnchantment()メソッドの代わりにaddUnsafeEnchantment()メソッドを使ってください。
+
Enchantmentクラス自体は抽象クラスであるため、インスタンス化('''new Enchantment()''')出来ません。
 +
エンチャントはEnchantmentWrapperクラスから利用する必要があるからです。
  
Sharpness 1 エンチャントを石の剣に付与する例を示します。
+
元々エンチャントが出来ないアイテムに対して、独自にエンチャントを付与する処理は書けません。<br/>
 +
Bukkitサーバ自体が、エンチャント不可能なアイテムに対して、エンチャント情報を付与する仕組みを備えていないからです。<br/>
 +
つまり、Fire AspectedなStick(火のエンチャントが付いた木の棒)はあり得ません。
 
<blockquote><source lang="java">
 
<blockquote><source lang="java">
// 新しい石の剣を生成します。
+
int itemCode = 280;  // StickのItemID
ItemStack myItem = new ItemStack(Material.STONE_SWORD);
+
int effectId = 20; // 効果Fire AspectのEID
 +
int enchantmentLevel = 100; // エンチャントのレベル
  
// エンチャントを付与します。
+
ItemStack myItem = new ItemStack(itemCode);  // 木の棒のインスタンスを生成する
myItem.addEnchantment(Enchantment.DAMAGE_ALL, 1);   
+
Enchantment myEnchantment = new EnchantmentWrapper(effectId);  // エンチャント効果のインスタンスを生成する
 +
myItem.addEnchantment(myEnchantment, enchantmentLevel);  // 木の棒にFireAspectを付与する(ただし付与は成功しない)
 
</source></blockquote>
 
</source></blockquote>
  
次に、火属性 100 を、木の棒に付与する例を示します。
+
== Matadata ==
<blockquote><source lang="java">
 
// 新しい木の棒を生成します。
 
ItemStack myItem = new ItemStack(Material.STICK);
 
 
 
// 木の棒にFireAspectレベル100を付与します。
 
// ただしFireAspectレベル100は通常存在しないので、addEnchantment を使うと失敗します。
 
// ありえないエンチャントを設定したい場合は、addUnsafeEnchantment を使ってください。
 
myItem.addUnsafeEnchantment(Enchantment.FIRE_ASPECT, 100); 
 
</source></blockquote>
 
 
 
=== ItemMeta ===
 
 
 
アイテムの表示名を変更するには、次のようにします。
 
<blockquote><source lang="java">
 
String myDisplayName = "すごい剣";
 
 
ItemStack myItem = new ItemStack(Material.DIAMOND_SWORD);  //アイテムを生成します。
 
ItemMeta im = myItem.getItemMeta(); //ItemStackから、ItemMetaを取得します。
 
im.setDisplayName(myDisplayName); //アイテム表示名を設定します。
 
myItem.setItemMeta(im); //元のItemStackに、変更したItemMetaを設定します。
 
</source></blockquote>
 
 
 
次に、loreを設定してみましょう。loreは、ゲーム内でアイテムにカーソルを合わせたときに表示される説明文のことです。
 
<blockquote><source lang="java">
 
List<String> lores = new ArrayList<String>();
 
lores.add("loreのテストです。");
 
lores.add("これは2行目です。");
 
 
 
ItemStack myItem = new ItemStack(Material.DIAMOND_SWORD);  //アイテムを生成します。
 
ItemMeta im = myItem.getItemMeta(); //ItemStackから、ItemMetaを取得します。
 
im.setLore(lores); //loreを設定します。
 
myItem.setItemMeta(im); //元のItemStackに、変更したItemMetaを設定します。
 
</source></blockquote>
 
 
 
== Metadata ==
 
  
 
Bukkit では、プラグインの開発をより簡単にするため、Playerクラス、Entityクラス、Worldクラスに紐づく追加データをMetadataという形式で管理できるようになっています。
 
Bukkit では、プラグインの開発をより簡単にするため、Playerクラス、Entityクラス、Worldクラスに紐づく追加データをMetadataという形式で管理できるようになっています。
956行目: 894行目:
 
ここで、正しいバージョンのJDKが選択されていることを確認してください。
 
ここで、正しいバージョンのJDKが選択されていることを確認してください。
  
このチュートリアルで紹介したJDKが同梱のPleiadesを利用している場合で、
 
<blockquote>
 
[ERROR] Unable to locate the Javac Compiler in:<br/>
 
[ERROR] C:\pleiades\java\7\..\lib\tools.jar
 
</blockquote>
 
のようなエラーが出ることがあります。これは上記のメッセージの通り、最初から同梱されているJDKにtools.jarが含まれているのに参照設定されていないからです。<br/>
 
これを解決するには、次のようにします。
 
*Pleiadesのメニューから、ウィンドウ > 設定 と選び、設定ダイアログを表示します。
 
*設定ダイアログの左側で、java > インストール済みのJRE と選びます。
 
*使用しているJRE(先ほどのエラーメッセージに含まれるファイルパスと、ロケーションが、一致するもの)を選択し、「編集...」を押します。
 
*JREの編集ダイアログで、「外部Jar追加...」を押し、tools.jarを探して選択します。例えばエラーメッセージが「C:\pleiades\java\7\..\lib\tools.jar」なら、「C:\pleiades\java\7\lib\tools.jar」に見つかるはずです。
 
*「OK」を押して、設定ダイアログを閉じます。
 
*再度、「mvn install」を実行して、今度は正常にビルドができることを確認してください。
 
  
 
ビルドがうまくいった場合、プロジェクトのフォルダの中に target フォルダが作成されており、そのフォルダの中にビルドされたJarファイルがあります。
 
ビルドがうまくいった場合、プロジェクトのフォルダの中に target フォルダが作成されており、そのフォルダの中にビルドされたJarファイルがあります。
998行目: 923行目:
 
             return false;
 
             return false;
 
         }
 
         }
   
+
 
         // 燃やすプレイヤーを取得します。
 
         // 燃やすプレイヤーを取得します。
         Player target = Bukkit.getPlayerExact(args[0]);
+
         Player target = Bukkit.getServer().getPlayer(args[0]);
   
+
 
         // 対象プレイヤーが、オンラインかどうかを確認します。
 
         // 対象プレイヤーが、オンラインかどうかを確認します。
 
         if (target == null) {
 
         if (target == null) {
1,007行目: 932行目:
 
             return true;
 
             return true;
 
         }
 
         }
   
+
 
         // 対象プレイヤーを、1000tick(=50秒) の間、燃えるようにします。
 
         // 対象プレイヤーを、1000tick(=50秒) の間、燃えるようにします。
 
         target.setFireTicks(1000);
 
         target.setFireTicks(1000);
1,023行目: 948行目:
 
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args){
 
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args){
 
     if(cmd.getName().equalsIgnoreCase("KillPlayer")){
 
     if(cmd.getName().equalsIgnoreCase("KillPlayer")){
        // コマンドのパラメータに、殺害するプレイヤーが指定されているかどうかを
+
         Player target = sender.getServer().getPlayer(args[0]);
        // 確認します。
+
        // 対象プレイヤーがオンラインかどうかを確認します。
        if (args.length != 1) {
 
            // onCommandでfalseを戻すと、plugin.ymlのusageに設定したメッセージを
 
            // コマンド実行者の画面に表示します。
 
            return false;
 
        }
 
         Player target = Bukkit.getPlayerExact(args[0]);
 
        // 対象プレイヤーがオンラインかどうかを確認します。
 
 
         if (target == null) {
 
         if (target == null) {
 
             sender.sendMessage(args[0] + " というプレイヤーは見つかりません!");
 
             sender.sendMessage(args[0] + " というプレイヤーは見つかりません!");
 
             return true;
 
             return true;
 
         }
 
         }
        // 対象に1000ダメージを与えます。
+
         target.setHealth(0);  
         target.damage(1000);
 
        return true;
 
 
     }
 
     }
 
     return false;
 
     return false;
1,046行目: 962行目:
 
上記の拡張版として、プレイヤーを爆死させる処理を下記に示します:  
 
上記の拡張版として、プレイヤーを爆死させる処理を下記に示します:  
 
<blockquote><source lang="java">
 
<blockquote><source lang="java">
@Override
+
float explosionPower = 4F; //This is the explosion power - TNT explosions are 4F by default
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
+
Player target = sender.getWorld().getPlayer(args[0]);
    if(cmd.getName().equalsIgnoreCase("KillPlayer")){
+
target.getWorld().createExplosion(target.getLocation(), explosionPower);
        Player target = Bukkit.getPlayerExact(args[0]);
+
target.setHealth(0);
        // 対象プレイヤーがオンラインかどうかを確認します。
 
        if (target == null) {
 
            sender.sendMessage(args[0] + " というプレイヤーは見つかりません!");
 
            return true;
 
        }
 
        float explosionPower = 4F; // 爆発の大きさです。1Fでガストの火球、3Fでクリーパーの爆発、4FでTNTの爆発 に相当します。
 
 
 
        // 爆発を起こしつつ、対象に1000ダメージを与えます。
 
        target.getWorld().createExplosion(target.getLocation(), explosionPower);
 
        target.damage(1000);
 
        return true;
 
    }
 
    return false;
 
}
 
 
</source> </blockquote>
 
</source> </blockquote>
  
1,075行目: 977行目:
  
 
     // このイベントは、点火されたTNTにより発生したのかどうかを確認します。
 
     // このイベントは、点火されたTNTにより発生したのかどうかを確認します。
    // (つまり、TNTの爆発はこれで無効化されますが、クリーパーの爆発は無効化されません)
+
    // (つまり、TNTの爆発はこれで無効化されますが、クリーパーの爆発は無効化されません)
 
     if (entity instanceof TNTPrimed) {
 
     if (entity instanceof TNTPrimed) {
        event.setCancelled(true); // イベントをキャンセルして、爆発を無かったことにする
+
         entity.getWorld().createExplosion(entity.getLocation(), 0);
         entity.getWorld().createExplosion(entity.getLocation(), 0); // 偽物の爆発を発生させる
 
 
     }
 
     }
 
}
 
}
1,100行目: 1,001行目:
 
         // sender instanceof Player の検査が終わっているので、Playerクラスへ安全にキャストできます。
 
         // sender instanceof Player の検査が終わっているので、Playerクラスへ安全にキャストできます。
 
         Player s = (Player) sender;
 
         Player s = (Player) sender;
 
        // コマンドのパラメータに、対象のプレイヤーが指定されているかどうかを確認します。
 
        if (args.length != 1) {
 
            // onCommandでfalseを戻すと、plugin.ymlのusageに設定したメッセージを
 
            // コマンド実行者の画面に表示します。
 
            return false;
 
        }
 
  
 
         // 指定されたプレイヤーを取得します。
 
         // 指定されたプレイヤーを取得します。
 
         // 指定されたプレイヤーがサーバーに接続していない場合、targetはnullになります。
 
         // 指定されたプレイヤーがサーバーに接続していない場合、targetはnullになります。
         Player target = Bukkit.getPlayerExact(args[0]);
+
         Player target = Bukkit.getServer().getPlayer(args[0]);
 
         if (target == null) {
 
         if (target == null) {
             sender.sendMessage("Player " + args[0] + " というプレイヤーは見つかりません!");
+
             sender.sendMessage("Player " + args[0] + " is not online.");
 
             return true;
 
             return true;
 
         }
 
         }
1,120行目: 1,014行目:
 
     }
 
     }
 
     return false;
 
     return false;
}
+
}</source>
</source>
 
 
</blockquote>
 
</blockquote>
  
1,132行目: 1,025行目:
 
@EventHandler
 
@EventHandler
 
public void onPlayerInteractBlock(PlayerInteractEvent event) {
 
public void onPlayerInteractBlock(PlayerInteractEvent event) {
 
 
     Player player = event.getPlayer();
 
     Player player = event.getPlayer();
  
     if (player.getItemInHand().getType() == Material.FISHING_ROD) {
+
     if (player.getItemInHand().getTypeId() == Material.FISHING_ROD.getId()) {
 
         // プレイヤーが見ている場所に雷をおとします。
 
         // プレイヤーが見ている場所に雷をおとします。
 +
        // 距離が200ブロック以内なら、ターゲットブロックを取得することができます。
 +
        player.getWorld().strikeLightning(player.getTargetBlock(null, 200).getLocation());
 +
    }
 +
}</source>
 +
</blockquote>
 +
 +
== リクエストに応じて書かれた記事 ==
  
        Block target = getTargetBlock(player);
+
=== mavenを利用したプラグイン開発 ===
        if (target != null) {
+
gitのリポジトリ上にある'''BukkitPluginArchetype'''をcloneし、それをビルドする:
            target.getWorld().strikeLightning(target.getLocation());
+
<blockquote><source lang="bash">
        }
+
git clone git://github.com/keyz182/BukkitPluginArchetype.git
    }
+
cd BukkitPluginArchetype
}
+
mvn clean install
 +
</source></blockquote>
 +
 
 +
作成するプラグインのフォルダに移動して下記のコマンドを実行します:
 +
<blockquote><source lang="bash">mvn archetype:generate -DarchetypeCatalog=local</source></blockquote>
 +
 
 +
プロンプトに表示されたリストから下記を選択します:
 +
<blockquote>uk.co.dbyz:bukkitplugin (bukkitplugin) </blockquote>
  
private Block getTargetBlock(Player player) {
 
   
 
    // 視線上のブロックを100ブロック先まで取得
 
    BlockIterator it = new BlockIterator(player, 100);
 
  
    // 手前側から検証を行う。
+
GroupIDには筆頭(プラグインのトップ階層)としたいJavaパッケージ名を指定し、ArtifactIDにはパッケージ名の末端の名称(Jarファイルのような成果物の名称として利用されます)を入力します。そして、確認メッセージに'''Y&lt;enter&gt;'''で応答します。
    // Blockが取得できた時点でreturnして終了する。
 
    while ( it.hasNext() ) {
 
  
        Block block = it.next();
+
例:
 +
<blockquote><source lang="bash">
 +
Define value for property 'groupId': : uk.co.dbyz.mc
 +
Define value for property 'artifactId': : plugin
 +
Define value for property 'version': 1.0-SNAPSHOT:
 +
Define value for property 'package': uk.co.dbyz.mc:
 +
</source></blockquote>
  
        if ( block.getType() != Material.AIR ) {
+
ArchetypeIDに指定した文字列と同名のフォルダが生成され、配下に'''src'''フォルダと'''pom.xml'''ファイルが配置されます。
            // ブロックが見つかった
+
 
            return block;
+
'''src/main/java/&lt;package&gt;'''フォルダに存在する'''&lt;archetypeid&gt;CommandExecuter.java'''ファイルを開き、コード<source lang="java">//Do Something</source>の部分に書きのコードを記述します:
        }
+
<blockquote><source lang="java">
    }
+
Player player = (Player) sender;
 +
player.setHealth(1000f);
 +
</source></blockquote>
  
    // 最後までブロックがみつからなかった
+
ベースのフォルダに移動して下記を実行します:
    return null;
+
<blockquote><source lang="bash">
}
+
mvn clean package
</source>
+
</source></blockquote>  
</blockquote>
+
ダウンロード処理が走りますが、他の作業を並行して行っても大丈夫です。
 +
''clean package''処理が完了すると、targetフォルダの中に'''&lt;archetypeid&gt;-1.0-SNAPSHOT.jar'''ファイルが生成されます(これがビルドされたプラグインのJarファイルです)。このファイルをBukkitのpluginsフォルダへコピーして、Bukkitサーバを起動して下さい。
  
 +
ゲーム内で'''/&lt;archetypeid&gt;'''コマンドを実行すると、そのプレイヤーのHealthが全快します。
  
 
== プラグインのサンプル兼雛形 ==
 
== プラグインのサンプル兼雛形 ==
1,177行目: 1,087行目:
 
この内容について質問がある場合、遠慮なく[http://forums.bukkit.org/members/adamki11s.42417/ Adamki11s]か[http://wiki.bukkit.org/IRC BukkitDevのIRCチャンネル](当Wikiの原文を掲載しているサイトのIRCチャンネルです)で聞いてください。
 
この内容について質問がある場合、遠慮なく[http://forums.bukkit.org/members/adamki11s.42417/ Adamki11s]か[http://wiki.bukkit.org/IRC BukkitDevのIRCチャンネル](当Wikiの原文を掲載しているサイトのIRCチャンネルです)で聞いてください。
 
:'''Note''': 当ページは訳文であるため、訳文自体に対する文責は原著者にありません。その点を考慮して必ず原文にも目を通してから質問して下さい。
 
:'''Note''': 当ページは訳文であるため、訳文自体に対する文責は原著者にありません。その点を考慮して必ず原文にも目を通してから質問して下さい。
 
[[カテゴリ:Bukkitチュートリアル|*]]
 

Minecraft Modding Wikiへの投稿はすべて、他の投稿者によって編集、変更、除去される場合があります。 自分が書いたものが他の人に容赦なく編集されるのを望まない場合は、ここに投稿しないでください。
また、投稿するのは、自分で書いたものか、パブリック ドメインまたはそれに類するフリーな資料からの複製であることを約束してください(詳細はMinecraft Modding Wiki:著作権を参照)。 著作権保護されている作品は、許諾なしに投稿しないでください!

このページを編集するには、下記の確認用の質問に回答してください (詳細):

取り消し 編集の仕方 (新しいウィンドウで開きます)

このページで使用されているテンプレート: