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

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

この編集を取り消せます。 下記の差分を確認して、本当に取り消していいか検証してください。よろしければ変更を保存して取り消しを完了してください。
最新版 編集中の文章
26行目: 26行目:
  
 
''config.yml''がデータフォルダ配下に存在しない場合は、空の''config.yml''ファイルを読み込んだ事と等しい結果となり、''FileConfiguration''オブジェクトも空の状態でロードされます。
 
''config.yml''がデータフォルダ配下に存在しない場合は、空の''config.yml''ファイルを読み込んだ事と等しい結果となり、''FileConfiguration''オブジェクトも空の状態でロードされます。
 
 
{{warning}} ''getConfig()''の戻り値は、staticなフィールドに割り当てないで下さい。
 
{{warning}} ''getConfig()''の戻り値は、staticなフィールドに割り当てないで下さい。
 
+
{{warning}} このような割り当てを行うと、''getConfig()''はreloadConfigの後でも再び割り当て処理を繰り返してしまいます。{{note}}''getConfig()''の戻り値は一旦適切なフィールドに割り当ててから利用する事をお勧めします
{{warning}} このような割り当てを行うと、''getConfig()''はreloadConfigの後でも再び割り当て処理を繰り返してしまいます。
 
 
 
{{note}}''getConfig()''の戻り値は一旦適切なフィールドに割り当ててから利用する事をお勧めします
 
 
 
 
 
=== キー ===
 
 
 
コンフィグファイルは、すべての設定内容が、Stringのkeyと、valueのペアで構成されています。
 
valueは、ConfigurationSection または、単一値の型になります。
 
 
 
FileConfigurationSection の ''getKeys(boolean)'' メソッドは、指定されたセクション以下のkeyを返します。
 
 
 
falseが指定された場合は、セクション直下にあるkeyが返されます。
 
trueが指定された場合は、セクション直下だけでなく、その子セクションや孫セクションも含めて全てのkeyが返されます。
 
ある特定のセクションを取得したい場合は、''getKeys(boolean)'' で探して取得する方法もありますが、''getConfigurationSection(String)'' を使って直接取得することもできます。
 
 
 
{{warning}} ''getKeys(boolean)'' メソッドは、Set<String> を返します。
 
 
 
 
 
=== パス ===
 
 
 
コンフィグAPIは、キーと値を階層的に持つことができます。
 
ピリオド(.)で区切ることで、階層をそのまま指定して、セクションやvalueを取得することができます。
 
実例を見てみましょう。
 
 
 
<blockquote><source lang="yaml">
 
key: 'value'
 
one:
 
  two: 'value'
 
  three:
 
    - 1
 
    - 2
 
    - 3
 
  four:
 
    five: 'value'
 
  '*':
 
    six: 'value'
 
    seven: 'value'
 
</source></blockquote>
 
 
 
上記の例では、次のようにkeyを指定することで、valueを取得できます。
 
 
 
*getString("key") → value というStringが取得されます
 
*getConfigurationSection("one") → one の部分がConfigurationSectionで取得されます
 
*getString("one.two") → value というStringが取得されます
 
*getIntegerList("one.three") → [1, 2, 3] というIntegerの配列が取得されます
 
*getConfigurationSection("one.four") → four の部分がConfigurationSectionで取得されます
 
*getString("one.four.five") → value というStringが取得されます
 
*getConfigurationSection("one.*") → '*' の部分がConfigurationSectionで取得されます
 
*getString("one.*.six") → value というStringが取得されます
 
*getString("one.*.seven") → value というStringが取得されます
 
  
 
=== デフォルト値 ===
 
=== デフォルト値 ===
 +
''config.yml''のデフォルト値は、プラグインのユーザに提供されます。
 +
設定ファイルが、プラグインのデータディレクトリ配下に存在しない, 空である, キーが無い・・・といった状態である場合には、プラグインのJarファイル内に定義された値が、デフォルト値としてロードされます。
  
あなたのプラグインの設定ファイル''config.yml''は、プラグイン利用者のために、デフォルト値を設定するようにしてください。
+
デフォルト値は、データフォルダ配下に存在する''config.yml''が提供しようと意図していた内容と、まったく同一な内容のYAML形式ファイルによって提供されるべきで、そのファイル名は''config.yml''であり、[[Plugin YAML|plugin.yml]]と同一の場所に配置されている必要があります。
  
もし''config.yml''が、プラグインのデータフォルダ配下に存在しない, 空である, キーが無い・・・といった状態である場合には、プラグインのJarファイル内に含まれる''config.yml''に定義された値が、デフォルト値として使用されます。
+
プラグインのデータフォルダ配下の''config.yml''をデフォルト値で上書きしたい場合は、JavaPluginクラスの''saveDefaultConfig()''メソッドを呼び出す必要があります。既存のファイルを上書きしたくない場合は、copyDefaultsオプションにtrueを設定します。
  
デフォルト値として使用する''config.yml''は、Jarファイルのトップに配置されるようにしてください。
+
動的な値をデフォルト値とする場合、addDefaults(Map&lt;String,Object&gt;)や'''addDefault(String, Object)'''のようにコーディングする事で実現できます。
[[Plugin YAML|plugin.yml]]と同一の場所になります。
 
  
プラグインのデータフォルダ配下の''config.yml''をデフォルト値で上書きしたい場合は、JavaPluginクラスの''saveDefaultConfig()''メソッドを呼び出してください。
+
特殊なケースとして、新規のデフォルト値を既存の''config.yml''に追加したい場合は、copyDefaultsにtrueをセットします。 <blockquote><source lang="java">getConfig().options().copyDefaults(true)</source></blockquote>
 
 
<blockquote><source lang="java">this.saveDefaultConfig()</source></blockquote>
 
 
 
データフォルダにある''config.yml''の既存の設定値を上書きしたくないが、Jarファイル内にある''config.yml''に定義されている新しいキーと値のペアを追加したい場合は、copyDefaults(true) を実行してください。
 
 
 
<blockquote><source lang="java">this.getConfig().options().copyDefaults(true)</source></blockquote>
 
 
 
<strike>config.ymlに ShiftJISで日本語を含めたプラグインは、Windowsでしか正常に起動しなくなります。</strike><br>
 
<strike>逆に、UTF-8N(BOM無し) で日本語を含めたプラグインは、MacintoshとLinuxでしか正常に起動しなくなります。</strike><br>
 
Bukkit 1.9 以降のバージョンでは、config.yml に日本語などのマルチバイト文字を含めたい場合は、常に UTF-8N(BOM無し) のエンコードで作成してください。
 
  
 
=== コンフィグ値の取得 ===
 
=== コンフィグ値の取得 ===
 
 
コンフィグ値の読み込み処理は、複数のgetterメソッドの呼び出し処理から成ります。全てのgetterメソッドの一覧は[http://jd.bukkit.org/doxygen/dd/d7c/classorg_1_1bukkit_1_1configuration_1_1file_1_1FileConfiguration.html こちら]です。一般的な用途のgetterメソッドは下記です。
 
コンフィグ値の読み込み処理は、複数のgetterメソッドの呼び出し処理から成ります。全てのgetterメソッドの一覧は[http://jd.bukkit.org/doxygen/dd/d7c/classorg_1_1bukkit_1_1configuration_1_1file_1_1FileConfiguration.html こちら]です。一般的な用途のgetterメソッドは下記です。
 
*getBoolean(String)  
 
*getBoolean(String)  
111行目: 49行目:
 
*getStringList(String)
 
*getStringList(String)
  
 +
==== Keyの活用 ====
 +
キーを用いたコンフィグ値の取得処理には、'''FileConfigurationSection'''(コンフィグファイルの階層構造を表すオブジェクト)と、それにアクセスするための'''キー'''と呼ばれる値を利用して行います。キー値の取得には''getKeys(boolean)''メソッドを用い、セクションの取得には''getConfigurationSection(String)''メソッドを用います。キーに先立って、コンフィグファイルのセクションが必要です。
 +
 +
''getKeys(boolean)''メソッドのboolean型パラメタは、キーを再帰的に取得するかどうかを指定します。trueであれば、子階層のキーも含めて取得します。falseであれば、対象階層のみのキーを返します。
 +
 +
*getKeys(boolean)
 +
{{note}} このメソッドは、String型の[http://download.oracle.com/javase/1,5.0/docs/api/java/util/Set.html Set] を返します。
  
 
=== コンフィグ値のセット ===  
 
=== コンフィグ値のセット ===  
122行目: 67行目:
  
 
利用例: <blockquote><source lang="java">
 
利用例: <blockquote><source lang="java">
// boolean値をセットします。
+
// setting a boolean value
 
this.getConfig().set("path.to.boolean", true);
 
this.getConfig().set("path.to.boolean", true);
  
// String値をセットします。
+
// setting a String
this.getConfig().set("path.to.string", "みなさんこんにちは!");
+
String string = "Hello World!";
 +
this.getConfig().set("path.to.string", stringValue);
  
// StringのListをセットします。
+
// Setting a List of Strings
// 配列はセットできないので、List<String>型に変換してセットします。
+
// The List of Strings is first defined in this array
String[] listOfStrings = {"こんにちは!", "いらっしゃいませ!", "楽しんでね!"};
+
String[] listOfStrings = {"Hello World", "Welcome to Bukkit", "Have a Good Day!"};
this.getConfig().set("path.to.list", Arrays.asList(listOfStrings));
+
this.getConfig().set("path.to.list", Arrays.asList(listOfStrings);
  
// Vector(Bukkitのクラス)の値をセットします。
+
// Setting a vector
 +
// event is assumed to be an existing event inside an "onEvent" method.
 
Vector vector = event.getPlayer().getLocation().toVector();
 
Vector vector = event.getPlayer().getLocation().toVector();
 
this.getConfig().set("path.to.vector", vector);
 
this.getConfig().set("path.to.vector", vector);
  
// 値を削除します。
+
// Erasing a value
this.getConfig().set("path.to.boolean", null);
+
this.getConfig().set("path.to.value", null);</source></blockquote><br>  
</source></blockquote>  
 
  
 
==== HashMapの活用 ====
 
==== HashMapの活用 ====
148行目: 94行目:
 
=== コンフィグファイルのセーブ ===
 
=== コンフィグファイルのセーブ ===
 
setメソッドを利用して''FileConfiguration''に多くの変更を加えるか、''Lists''(設定値インスタンスの内部値がList派生型になっている領域を指している)の内容を変更した場合、プラグインの無効化後も残したい設定値であればディスクに書き出すべきです。'''saveConfig'''メソッドを呼び出して、既存の(ディスク上の)コンフィグファイルに上書き保存しましょう。<blockquote><source lang="java">this.saveConfig();</source></blockquote>
 
setメソッドを利用して''FileConfiguration''に多くの変更を加えるか、''Lists''(設定値インスタンスの内部値がList派生型になっている領域を指している)の内容を変更した場合、プラグインの無効化後も残したい設定値であればディスクに書き出すべきです。'''saveConfig'''メソッドを呼び出して、既存の(ディスク上の)コンフィグファイルに上書き保存しましょう。<blockquote><source lang="java">this.saveConfig();</source></blockquote>
 
  
 
=== ディスクからのリロード ===
 
=== ディスクからのリロード ===
プラグインのデータフォルダ上の''config.yml''が、ユーザによって変更されている可能性を疑って下さい。この変更点はメモリ上の設定値に反映されていません。''reloadConfig()''メソッドを呼び出して、ディスク上の設定値をプラグインにロードする事ができます。ただしメモリ上の設定値が、ロード内容で上書きされる事にも留意して下さい。
+
プラグインのデータフォルダ上の''config.yml''が、ユーザによって変更されている可能性を疑って下さい。この変更点はメモリ上の設定値に反映されていません。''reloadConfig()''メソッドを呼び出して、ディスク上の設定値をプラグインにロードする事ができます。ただしメモリ上の設定値が、ロード内容で上書きされる事にも留意して下さい。<source lang="java">this.reloadConfig();</source>
<blockquote><source lang="java">this.reloadConfig();</source></blockquote>
 
 
 
 
 
=== 別の設定ファイルを利用する ===
 
もしあなたが、''config.yml''ではなく、別のYamlファイルを利用したい場合は、YamlConfiguration クラスを使って読み込むことができます。
 
  
<blockquote><source lang="java">
 
FileConfiguration data = YamlConfiguration.loadConfiguration(new File(getDataFolder(), "data.yml"));
 
</source></blockquote>
 
 
上記のサンプルコードは、データフォルダにある''data.yml''ファイルを読み込んで、FileConfiguration を返します。<br/>
 
もし、データフォルダに''data.yml''が存在しない場合は、空っぽの FileConfiguration が返されます。<br/>
 
 
<!-- なんか微妙。この説明、要るかなあ?
 
もしあなたが、Jarファイル内の''data.yml''を読み出したいなら、InputStreamを使って次のようにロードすることが可能です。
 
 
<blockquote><source lang="java">
 
FileConfiguration data = YamlConfiguration.loadConfiguration(getResource("data.yml"))
 
</source></blockquote>
 
 
This takes the InputStream from getResource, which gets a file embedded in the jar, and retreives a FileConfiguration from that.
 
-->
 
 
<!-- 下記の内容は、内容が難しくて、かえって混乱を生むので、いまのところ非表示にしています。
 
 
== 応用 ==
 
== 応用 ==
  
 
以下は、より高度なプラグインを製作するための、応用のトピックです。<br>
 
以下は、より高度なプラグインを製作するための、応用のトピックです。<br>
あなたが既定の''config.yml''を作成したり読み込んだり保存したいだけであれば、下記を読む必要はありません。
+
あなたは既定の''config.yml''を作成するだけでよく、保存したり、移動したりする必要は今後ありません。
  
 
=== コンフィグのオプション ===
 
=== コンフィグのオプション ===
189行目: 111行目:
 
現在、4つのオプションがあります。<br>
 
現在、4つのオプションがあります。<br>
 
メソッドはオーバーロードされているものがあり、例えば、''copyDefaults()''はブール値を返しますが、''copyDefaults(boolean)''は自分自身を返します。<br>
 
メソッドはオーバーロードされているものがあり、例えば、''copyDefaults()''はブール値を返しますが、''copyDefaults(boolean)''は自分自身を返します。<br>
'''訳者注''' 引数を指定しないメソッドは現在のオプション値を返し、引数を指定するメソッドはオプション値を設定するメソッドです。
+
'''訳者注''' 引数を指定しないメソッドはオプション値を返し、引数を指定するメソッドはオプション値を設定するようです。
  
 
==== CopyDefaults ====
 
==== CopyDefaults ====
  
''CopyDefaults''オプションは''Configuration''クラスのsaveメソッドの動作を変更します。<br>
+
''CopyDefaults''オプションは''Configuration''クラスのsaveメソッドを変更しています。<br>
既定はfalseで、デフォルトのコンフィグを保存先ファイルに上書きしません。<br>
+
既定では、デフォルトのコンフィグを保存先ファイルに上書きしません。<br>
引数にtrueを設定した場合、ファイルの上書きをするようになります。<br>
+
もし引数にtrueが設定された場合、ファイルの上書きをします。<br>
しかし、1度書き込みが行われるのみで、あなたがデフォルト値を変更したとしてもその値が即座に反映されるわけではありません。
+
しかし、1度書き込みが行われるのみで、あなたがデフォルト値を変更したとしてもその値が反映されるわけではありません。
  
 
==== PathSeparator ====
 
==== PathSeparator ====
227行目: 149行目:
 
プラグインのメソッドを実装した後、それと同じコンテキストで継承された''getConfig()''、 ''reloadConfig()''、 ''saveConfig()''、および ''saveDefaultConfig()''メソッドで呼び出すことができます。<br>
 
プラグインのメソッドを実装した後、それと同じコンテキストで継承された''getConfig()''、 ''reloadConfig()''、 ''saveConfig()''、および ''saveDefaultConfig()''メソッドで呼び出すことができます。<br>
 
下記のコード例では、1つのクラスで複数の yaml ファイルにアクセスすることができます。<br>
 
下記のコード例では、1つのクラスで複数の yaml ファイルにアクセスすることができます。<br>
このようなクラス実装例を、 [https://gist.github.com/3174347 ここに] 示します。
+
このようなクラス実装例を、 [https://gist.github.com/3174347 ここに] 示します。  
  
 
まず、2つのフィールドを宣言し、カスタム構成ファイルごとに null に初期化する必要があります。<br>
 
まず、2つのフィールドを宣言し、カスタム構成ファイルごとに null に初期化する必要があります。<br>
246行目: 168行目:
 
public void reloadCustomConfig() {
 
public void reloadCustomConfig() {
 
     if (customConfigFile == null) {
 
     if (customConfigFile == null) {
        customConfigFile = new File(getDataFolder(), "customConfig.yml");
+
    customConfigFile = new File(getDataFolder(), "customConfig.yml");
 
     }
 
     }
 
     customConfig = YamlConfiguration.loadConfiguration(customConfigFile);
 
     customConfig = YamlConfiguration.loadConfiguration(customConfigFile);
280行目: 202行目:
 
public void saveCustomConfig() {
 
public void saveCustomConfig() {
 
     if (customConfig == null || customConfigFile == null) {
 
     if (customConfig == null || customConfigFile == null) {
        return;
+
    return;
 
     }
 
     }
 
     try {
 
     try {
299行目: 221行目:
 
         customConfigFile = new File(getDataFolder(), "customConfig.yml");
 
         customConfigFile = new File(getDataFolder(), "customConfig.yml");
 
     }
 
     }
     if (!configFile.exists()) {
+
     if (!configFile.exists()) {          
 
         this.plugin.saveResource(fileName, false);
 
         this.plugin.saveResource(fileName, false);
    }
+
    }
 
}
 
}
 
</source></blockquote>
 
</source></blockquote>
309行目: 231行目:
 
コンフィグAPI は、前述のように''ConfigurationSerializable''インターフェイスを実装する Java オブジェクトを格納することができます。<br>
 
コンフィグAPI は、前述のように''ConfigurationSerializable''インターフェイスを実装する Java オブジェクトを格納することができます。<br>
 
オブジェクトのシリアル化では、各種オブジェクトを簡単に保存したり読み込んだりする仕組みを、実装者に提供してくれています。<br>
 
オブジェクトのシリアル化では、各種オブジェクトを簡単に保存したり読み込んだりする仕組みを、実装者に提供してくれています。<br>
例えば開発者は、''[http://jd.bukkit.org/doxygen/da/dac/classorg_1_1bukkit_1_1Location.html Location]''を取得できるシリアライズラッパークラスを使うことで、YAMLに''Location''を保存するような処理がとても簡単に使用することができます。
+
開発者は'[http://jd.bukkit.org/doxygen/da/dac/classorg_1_1bukkit_1_1Location.html Location]''を取得できるシリアライズラッパークラスを使うことで、YAMLに''Location''を保存するような処理がとても簡単に使用することができます。
  
API でシリアル化することができるクラスを実装するには、''ConfigurationSerializable''インターフェイスを実装するだけでなく、以下のいずれかを実装する必要があります。<br>
+
API でシリアル化することができますようにクラスは''ConfigurationSerializable''インターフェイスを実装するだけでなく、また implment、Javadoc で指摘したように、以下のいずれかの必要があります。<br>
* '''1つの''Map''を受け入れるコンストラクター''' <source lang="java">public PlayerData(Map data) {</source>
+
* 1つの''Map''を受け入れるコンストラクター
* '''1つの''Map''を受け入れてクラスを返す、"deserialize" という名前のstaticメソッド''' <source lang="java">public static PlayerData deserialize(Map data) {</source>
+
* 1つの''Map''を受け入れてクラスを返す、"deserialize" という名前のstaticメソッド
* '''1つの''Map''を受け入れてクラスを返す、"valueOf" という名前のstaticメソッド''' <source lang="java">public static PlayerData valueOf(Map data) {</source>
+
* 1つの''Map''を受け入れてクラスを返す、"valueOf" という名前のstaticメソッド
  
 
シリアライズされたオブジェクトをデシリアライズするには、ConfigurationSerialization に登録されている必要があります。<br>
 
シリアライズされたオブジェクトをデシリアライズするには、ConfigurationSerialization に登録されている必要があります。<br>
registerClass メソッドは、シリアル化されたクラスごとに1回ずつ実行してください。
+
registerClass メソッドは、シリアル化されたクラスごとに1回呼び出す必要があります。
  
 
このステートメントは、メインクラスの初期化ブロックに記述することができます。
 
このステートメントは、メインクラスの初期化ブロックに記述することができます。
329行目: 251行目:
 
クラスがシリアル化されるとき、完全修飾名でマークされています。
 
クラスがシリアル化されるとき、完全修飾名でマークされています。
  
エイリアスをクラスに設定しておくと、完全修飾名の代わりにエイリアスでマークされます。<br>
+
エイリアスをクラスに設定しておくと、代わりにクラスが、エイリアスの完全修飾名を持つ形でシリアル化されません。<br>
''SerializeAs''アノテーションを、ConfigurationSerializableを実装するクラスに指定します。
+
''SerializeAs''アノテーションを、ConfigurationSerializableを実装するクラスに指定します。  
 
<source lang="java">@SerilizeAs(String)</source>
 
<source lang="java">@SerilizeAs(String)</source>
  
338行目: 260行目:
 
ConfigurationSerialization.registerClass(Class<? extends ConfigurationSerializable>, String)
 
ConfigurationSerialization.registerClass(Class<? extends ConfigurationSerializable>, String)
 
</source></blockquote>
 
</source></blockquote>
 
-->
 
  
 
== 利用例 ==
 
== 利用例 ==
361行目: 281行目:
 
         // もしconfig.ymlが存在しないなら、既定のconfig.ymlをコピーします。
 
         // もしconfig.ymlが存在しないなら、既定のconfig.ymlをコピーします。
 
         this.saveDefaultConfig();
 
         this.saveDefaultConfig();
 
+
       
 
         // 新しいリスナーを登録します。
 
         // 新しいリスナーを登録します。
 
         getServer().getPluginManager().registerEvents(new Listener() {
 
         getServer().getPluginManager().registerEvents(new Listener() {
 
+
           
 
             @EventHandler
 
             @EventHandler
             public void playerJoin(PlayerJoinEvent event) {
+
             public playerJoin(PlayerJoinEvent event) {
 
                 // プレイヤーがサーバーに参加したときに、config.ymlに書かれたメッセージを送ります。
 
                 // プレイヤーがサーバーに参加したときに、config.ymlに書かれたメッセージを送ります。
 
                 event.getPlayer().sendMessage(SimpleMOTD.this.getConfig().getString("message"));
 
                 event.getPlayer().sendMessage(SimpleMOTD.this.getConfig().getString("message"));
 
                // 特定のプレイヤーだった場合は、追加メッセージを送ります。
 
                if ( SimpleMOTD.this.getConfig().contains("additional." + event.getPlayer().getName()) ) {
 
                    event.getPlayer().sendMessage(SimpleMOTD.this.getConfig().getString(
 
                            "additional." + event.getPlayer().getName()));
 
                }
 
 
             }
 
             }
 
         }, this);
 
         }, this);
380行目: 294行目:
 
         // rulesコマンドのCommandExecutorを登録します。
 
         // rulesコマンドのCommandExecutorを登録します。
 
         this.getCommand("rules").setExecutor(new CommandExecutor() {
 
         this.getCommand("rules").setExecutor(new CommandExecutor() {
 
+
           
 
             public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
 
             public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
 
                 // コマンド実行時にコマンド実行者へ、config.ymlのrulesの内容を送ります。
 
                 // コマンド実行時にコマンド実行者へ、config.ymlのrulesの内容を送ります。
 
                 List<String> rules = SimpleMOTD.this.getConfig().getStringList("rules");
 
                 List<String> rules = SimpleMOTD.this.getConfig().getStringList("rules");
                 for (String s : rules) {
+
                 for (String s : rules)
 
                     sender.sendMessage(s);
 
                     sender.sendMessage(s);
 
                 }
 
                 }
402行目: 316行目:
 
   - Respect others
 
   - Respect others
 
   - Have Fun
 
   - Have Fun
additional:
 
  Anna: Hi Anna!
 
  Billy: Hey Billy!
 
 
</source>
 
</source>

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

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

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

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