【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

フォーラムルール
質問関連フォーラムで質問する時は、必ず次のトピックを一読/厳守お願い致します。
viewtopic.php?f=5&t=999

返信する

:
不正プログラムによるアクセスを防ぐため、reCaptcha 認証コードの入力を強制しています。表示されている 2 つのワードをテキストフィールドにご入力ください。

BBCode: OFF
スマイリー: OFF
トピックのレビュー
   

ファイルを添付します

展開ビュー トピックのレビュー: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by 面倒くさいから匿名 » 2017年10月25日(水) 22:41

private Objective getRandomObjective(Scoreboard board){
while(true){
String uuid = UUID.randomUUID().toString().substring(0, 15);
Objective objective = board.getObjective(uuid);
if(objective == null)
return board.registerNewObjective(uuid, "dummy");
}
}
スコアボードで同じ名前のスコアボードを作成するとIllegalStateExceptionが発生してしまったため、このような一度も使われていないObjectiveを取得するメソッドを作ったのですが、このメソッドを長期間使用すると容量を圧迫してしまうでしょうか?また、Objectiveをスコアボードから削除する方法はあるでしょうか?
よろしくお願いします

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by 東脳君 » 2017年10月19日(木) 00:27

以上の文言が理解できる程度までは、まずJavaそのものを勉強した方が良いと思う。

時間だけは無駄にあるのでそれもまた良いですね 日々精進します

以上のアドバイスを踏まえて実験すること30分、
コード: 全て選択
public class PlayerJoin implements Listener{
   
   Pvp plugin = Pvp.plugin;
   
   @EventHandler
   public void PlayerJN(PlayerJoinEvent e){
      
      Pvp.plugin.saveDefaultConfig();
      FileConfiguration FIRSTIN = Pvp.plugin.getConfig();
      
      if(FIRSTIN.get(e.getPlayer().getUniqueId().toString() + "FIRST") == null){
         Location loc = new Location(e.getPlayer().getWorld(),315.5,59,312.5);
         e.getPlayer().teleport(loc);
         e.setJoinMessage("初ログイン:" + e.getPlayer().getDisplayName());
          FIRSTIN.set(e.getPlayer().getUniqueId().toString() + "FIRST", 1);
          Pvp.plugin.saveConfig();
      }
   }
}

のように書き換えたら恐ろしいほど簡単に動きました。ありがとうございます!
これでようやく念願の複数クラスでプラグイン作れるぜ!

余談(UUIDをコンフィグで扱った際の容量について)
(コンフィグにプレイヤ一人一人のUUID書きこんでたらとんでもない容量になる気がするけれども大丈夫なのだろうと
計算してみたところ、一文字1バイト、サーバーに1000万人来たとしても16BYTE * 10000000 = 160000000 BYTE = 0.16GB なので全然問題ないみたい。
今後この方法でプレイヤーのUUID使う方は参考にでも)

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by elise_blacklab » 2017年10月19日(木) 00:02

東脳君 さんが書きました:onEnable()でpluginにthisをブチ込むところまでは合ってると思うのですが、それをサブクラスでどのように生かすのかが分かりません。

saveDefaultConfig等々はJavaPluginのインスタンスから呼び出すものだから、plugin.saveDefaultConfig()すればよいのこと…なのだけど、Pvp#pluginが初期化されるのはonEnableが呼び出される後なので、PlayerJoin#pluginにPvp#pluginを代入する処理はそこには書けない。
わざわざフィールドなんて用意しなくても、Pvp#pluginはpublic staticなのだから、直接アクセスしてもいいんじゃないかな。
変な拍子でPvp#pluginが書き換えられるっていう危険はあるが…

以上の文言が理解できる程度までは、まずJavaそのものを勉強した方が良いと思う。

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by 東脳君 » 2017年10月18日(水) 22:38

東脳君 さんが書きました
東脳君さん、こんにちは。
まず、EventListenersはJavaPluginクラスを継承したクラスである必要はありません。
そしてJavaPluginクラス及びそれを継承したクラスは各プラグイン一つのインスタンスしか作成出来ません。
JavaPluginクラスを必要とする処理はクラス変数を使用する事で実行可能です。
メインクラスと他のクラスに下記の様な変数を追加してみて下さいね。

MainClass.class
コード: 全て選択
public static MainClass plugin;

SubClass.class
コード: 全て選択
MainClass plugin = MainClass.plugin;


amata1219さん、迅速な返信有難うございます。
アドバイスを受け、試行錯誤してみるもEclipse側でエラーが発生し、
その後もスレッドを見返したり 何時間かずっと調べているのですが、解決する目途が立ちそうにありません・・・

色々書き足し過ぎたので一度リセットし、現在のような状態になっているのですが、どうすればいいのか・・・

メインクラス:Pvp
コード: 全て選択
package tosatsu;

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

public class Pvp extends JavaPlugin{
   
   public static Pvp plugin;
   
   @Override
   public void onEnable() {
   registerListeners();
   plugin = this;
   }
   
     private void registerListeners()
     {   
       PluginManager mange = getServer().getPluginManager();
       mange.registerEvents(new PlayerJoin(), this);
     }
   
}


サブクラス:PlayerJoin

コード: 全て選択
package tosatsu;

import org.bukkit.Location;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.Plugin;

public class PlayerJoin implements Listener{
   
   Pvp plugin = Pvp.plugin;
   
   @EventHandler
   public void PlayerJN(PlayerJoinEvent e){
      
      saveDefaultConfig();//メソッド saveDefaultConfig() は型 PlayerJoin で未定義です
      FileConfiguration FIRSTIN = getConfig();//メソッド getConfig() は型 PlayerJoin で未定義です
      
      if(FIRSTIN.get(e.getPlayer().getUniqueId().toString() + "FIRST") == null){
         Location loc = new Location(e.getPlayer().getWorld(),315.5,59,312.5);
         e.getPlayer().teleport(loc);
         e.setJoinMessage("初ログイン:" + e.getPlayer().getDisplayName());
          FIRSTIN.set(e.getPlayer().getUniqueId().toString() + "FIRST", 1);
          saveConfig();//メソッド saveConfig() は型 PlayerJoin で未定義です
      }
   }
}


onEnable()でpluginにthisをブチ込むところまでは合ってると思うのですが、それをサブクラスでどのように生かすのかが分かりません。
先ほど教えて貰ったアドバイスを生かせず申し訳ありません・’

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by amata1219 » 2017年10月18日(水) 19:39

東脳君 さんが書きました:解決方法が捻りだせず、挫折寸前での質問、させていただきます。
Bukkit Plugin制作の質問というよりかはオブジェクト指向に関する内容が8割の質問になります。
制作を始めて以来 オブジェクト指向については殆ど触れたことがありません。

現在、プレイヤーが初ログインだった場合に彼を初期位置まで移動させるプラグインを作っております。

処理内容は、
ログインプレイヤーのUUIDを取得し、コンフィグにそのUUIDが存在しなかった場合 新たに書き加え、初期位置に移動させる、というものです。

クラス単体で実行(?シングルトン設計って言う?らしいです)したところ、ちゃんと動作を確認できたのですが、クラスを二つに分けて実行すると動作しません。
Pvp.java
コード: 全て選択
package tosatsu;

import org.bukkit.event.Listener;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;

public class Pvp extends JavaPlugin implements Listener{
   
   @Override
   public void onEnable(){
       registerListeners();
   }
   
     private void registerListeners()
     {
       PluginManager mange = getServer().getPluginManager();
       mange.registerEvents(new PlayerJoin(), this);
       mange.registerEvents(this,this);
     }
   
}

PlayerJoin.java
コード: 全て選択
package tosatsu;

import org.bukkit.Location;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.java.JavaPlugin;

public class PlayerJoin extends JavaPlugin implements Listener{
   
   @EventHandler
   public void PlayerJN(PlayerJoinEvent e){
      
      saveDefaultConfig();
      FileConfiguration FIRSTIN = getConfig();
      
      if(FIRSTIN.get(e.getPlayer().getUniqueId().toString() + "FIRST") == null){
         Location loc = new Location(e.getPlayer().getWorld(),315.5,59,312.5);
         e.getPlayer().teleport(loc);
         e.setJoinMessage("初ログイン:" + e.getPlayer().getDisplayName());
          FIRSTIN.set(e.getPlayer().getUniqueId().toString() + "FIRST", 1);
          saveConfig();
      }
   }
}


エラーはプラグインを導入し、サーバーを起動/リロードする際に発生しました

[17:27:58 INFO]: [TosatsuPvPlugin] Enabling TosatsuPvPlugin v1.8.x
[17:27:58 ERROR]: Error occurred while enabling TosatsuPvPlugin v1.8.x (Is it up
to date?)
java.lang.IllegalArgumentException: Plugin already initialized!
at org.bukkit.plugin.java.PluginClassLoader.initialize(PluginClassLoader
.java:98) ~[craftbukkit.jar:git-Bukkit-33d5de3]
at org.bukkit.plugin.java.JavaPlugin.<init>(JavaPlugin.java:66) ~[craftb
ukkit.jar:git-Bukkit-33d5de3]
at tosatsu.PlayerJoin.<init>(PlayerJoin.java:12) ~[?:?]
at tosatsu.Pvp.registerListeners(Pvp.java:19) ~[?:?]
at tosatsu.Pvp.onEnable(Pvp.java:13) ~[?:?]
at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:321) ~[c
raftbukkit.jar:git-Bukkit-33d5de3]
at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader
.java:327) [craftbukkit.jar:git-Bukkit-33d5de3]
at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManage
r.java:404) [craftbukkit.jar:git-Bukkit-33d5de3]
at org.bukkit.craftbukkit.v1_8_R1.CraftServer.loadPlugin(CraftServer.jav
a:341) [craftbukkit.jar:git-Bukkit-33d5de3]
at org.bukkit.craftbukkit.v1_8_R1.CraftServer.enablePlugins(CraftServer.
java:313) [craftbukkit.jar:git-Bukkit-33d5de3]
at org.bukkit.craftbukkit.v1_8_R1.CraftServer.reload(CraftServer.java:72
5) [craftbukkit.jar:git-Bukkit-33d5de3]
at org.bukkit.Bukkit.reload(Bukkit.java:543) [craftbukkit.jar:git-Bukkit
-33d5de3]
at org.bukkit.command.defaults.ReloadCommand.execute(ReloadCommand.java:
25) [craftbukkit.jar:git-Bukkit-33d5de3]
at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:14
0) [craftbukkit.jar:git-Bukkit-33d5de3]
at org.bukkit.craftbukkit.v1_8_R1.CraftServer.dispatchCommand(CraftServe
r.java:625) [craftbukkit.jar:git-Bukkit-33d5de3]
at net.minecraft.server.v1_8_R1.PlayerConnection.handleCommand(PlayerCon
nection.java:1058) [craftbukkit.jar:git-Bukkit-33d5de3]
at net.minecraft.server.v1_8_R1.PlayerConnection.a(PlayerConnection.java
:919) [craftbukkit.jar:git-Bukkit-33d5de3]
at net.minecraft.server.v1_8_R1.PacketPlayInChat.a(SourceFile:37) [craft
bukkit.jar:git-Bukkit-33d5de3]
at net.minecraft.server.v1_8_R1.PacketPlayInChat.a(SourceFile:9) [craftb
ukkit.jar:git-Bukkit-33d5de3]
at net.minecraft.server.v1_8_R1.PacketHandleTask.run(SourceFile:13) [cra
ftbukkit.jar:git-Bukkit-33d5de3]
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [
?:1.8.0_121]
at java.util.concurrent.FutureTask.run(Unknown Source) [?:1.8.0_121]
at net.minecraft.server.v1_8_R1.MinecraftServer.z(MinecraftServer.java:6
56) [craftbukkit.jar:git-Bukkit-33d5de3]
at net.minecraft.server.v1_8_R1.DedicatedServer.z(DedicatedServer.java:2
84) [craftbukkit.jar:git-Bukkit-33d5de3]
at net.minecraft.server.v1_8_R1.MinecraftServer.y(MinecraftServer.java:6
09) [craftbukkit.jar:git-Bukkit-33d5de3]
at net.minecraft.server.v1_8_R1.MinecraftServer.run(MinecraftServer.java
:517) [craftbukkit.jar:git-Bukkit-33d5de3]
at java.lang.Thread.run(Unknown Source) [?:1.8.0_121]
Caused by: java.lang.IllegalStateException: Initial initialization
at org.bukkit.plugin.java.PluginClassLoader.initialize(PluginClassLoader
.java:101) ~[craftbukkit.jar:git-Bukkit-33d5de3]
at org.bukkit.plugin.java.JavaPlugin.<init>(JavaPlugin.java:66) ~[craftb
ukkit.jar:git-Bukkit-33d5de3]
at tosatsu.Pvp.<init>(Pvp.java:9) ~[?:?]
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
~[?:1.8.0_121]
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
~[?:1.8.0_121]
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Sou
rce) ~[?:1.8.0_121]
at java.lang.reflect.Constructor.newInstance(Unknown Source) ~[?:1.8.0_1
21]
at java.lang.Class.newInstance(Unknown Source) ~[?:1.8.0_121]
at org.bukkit.plugin.java.PluginClassLoader.<init>(PluginClassLoader.jav
a:52) ~[craftbukkit.jar:git-Bukkit-33d5de3]
at org.bukkit.plugin.java.JavaPluginLoader.loadPlugin(JavaPluginLoader.j
ava:129) ~[craftbukkit.jar:git-Bukkit-33d5de3]
at org.bukkit.plugin.SimplePluginManager.loadPlugin(SimplePluginManager.
java:328) ~[craftbukkit.jar:git-Bukkit-33d5de3]
at org.bukkit.plugin.SimplePluginManager.loadPlugins(SimplePluginManager
.java:251) ~[craftbukkit.jar:git-Bukkit-33d5de3]
at org.bukkit.craftbukkit.v1_8_R1.CraftServer.loadPlugins(CraftServer.ja
va:288) ~[craftbukkit.jar:git-Bukkit-33d5de3]
at org.bukkit.craftbukkit.v1_8_R1.CraftServer.reload(CraftServer.java:72
3) ~[craftbukkit.jar:git-Bukkit-33d5de3]
... 16 more


使っているAPIはSpigot V1.8.3です。

思考錯誤しているうちに、PlayerJoin.javaの中で、extends JavaPluginを書かなければ問題なく動作するような気がしましたが、
JavaPluginを拡張(?)実装(?)しないとsaveDefaultConfig();など、コンフィグ関係の処理ができなくなってしまうようです。


読みにくい文章とは思いますが私にはこれが限界です。なんとか読んでください。お願いします。



東脳君さん、こんにちは。
まず、EventListenersはJavaPluginクラスを継承したクラスである必要はありません。
そしてJavaPluginクラス及びそれを継承したクラスは各プラグイン一つのインスタンスしか作成出来ません。
JavaPluginクラスを必要とする処理はクラス変数を使用する事で実行可能です。
メインクラスと他のクラスに下記の様な変数を追加してみて下さいね。

MainClass.class
コード: 全て選択
public static MainClass plugin;


SubClass.class
コード: 全て選択
MainClass plugin = MainClass.plugin;

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by 東脳君 » 2017年10月18日(水) 17:44

解決方法が捻りだせず、挫折寸前での質問、させていただきます。
Bukkit Plugin制作の質問というよりかはオブジェクト指向に関する内容が8割の質問になります。
制作を始めて以来 オブジェクト指向については殆ど触れたことがありません。

現在、プレイヤーが初ログインだった場合に彼を初期位置まで移動させるプラグインを作っております。

処理内容は、
ログインプレイヤーのUUIDを取得し、コンフィグにそのUUIDが存在しなかった場合 新たに書き加え、初期位置に移動させる、というものです。

クラス単体で実行(?シングルトン設計って言う?らしいです)したところ、ちゃんと動作を確認できたのですが、クラスを二つに分けて実行すると動作しません。
Pvp.java
コード: 全て選択
package tosatsu;

import org.bukkit.event.Listener;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;

public class Pvp extends JavaPlugin implements Listener{
   
   @Override
   public void onEnable(){
       registerListeners();
   }
   
     private void registerListeners()
     {
       PluginManager mange = getServer().getPluginManager();
       mange.registerEvents(new PlayerJoin(), this);
       mange.registerEvents(this,this);
     }
   
}

PlayerJoin.java
コード: 全て選択
package tosatsu;

import org.bukkit.Location;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.java.JavaPlugin;

public class PlayerJoin extends JavaPlugin implements Listener{
   
   @EventHandler
   public void PlayerJN(PlayerJoinEvent e){
      
      saveDefaultConfig();
      FileConfiguration FIRSTIN = getConfig();
      
      if(FIRSTIN.get(e.getPlayer().getUniqueId().toString() + "FIRST") == null){
         Location loc = new Location(e.getPlayer().getWorld(),315.5,59,312.5);
         e.getPlayer().teleport(loc);
         e.setJoinMessage("初ログイン:" + e.getPlayer().getDisplayName());
          FIRSTIN.set(e.getPlayer().getUniqueId().toString() + "FIRST", 1);
          saveConfig();
      }
   }
}


エラーはプラグインを導入し、サーバーを起動/リロードする際に発生しました

[17:27:58 INFO]: [TosatsuPvPlugin] Enabling TosatsuPvPlugin v1.8.x
[17:27:58 ERROR]: Error occurred while enabling TosatsuPvPlugin v1.8.x (Is it up
to date?)
java.lang.IllegalArgumentException: Plugin already initialized!
at org.bukkit.plugin.java.PluginClassLoader.initialize(PluginClassLoader
.java:98) ~[craftbukkit.jar:git-Bukkit-33d5de3]
at org.bukkit.plugin.java.JavaPlugin.<init>(JavaPlugin.java:66) ~[craftb
ukkit.jar:git-Bukkit-33d5de3]
at tosatsu.PlayerJoin.<init>(PlayerJoin.java:12) ~[?:?]
at tosatsu.Pvp.registerListeners(Pvp.java:19) ~[?:?]
at tosatsu.Pvp.onEnable(Pvp.java:13) ~[?:?]
at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:321) ~[c
raftbukkit.jar:git-Bukkit-33d5de3]
at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader
.java:327) [craftbukkit.jar:git-Bukkit-33d5de3]
at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManage
r.java:404) [craftbukkit.jar:git-Bukkit-33d5de3]
at org.bukkit.craftbukkit.v1_8_R1.CraftServer.loadPlugin(CraftServer.jav
a:341) [craftbukkit.jar:git-Bukkit-33d5de3]
at org.bukkit.craftbukkit.v1_8_R1.CraftServer.enablePlugins(CraftServer.
java:313) [craftbukkit.jar:git-Bukkit-33d5de3]
at org.bukkit.craftbukkit.v1_8_R1.CraftServer.reload(CraftServer.java:72
5) [craftbukkit.jar:git-Bukkit-33d5de3]
at org.bukkit.Bukkit.reload(Bukkit.java:543) [craftbukkit.jar:git-Bukkit
-33d5de3]
at org.bukkit.command.defaults.ReloadCommand.execute(ReloadCommand.java:
25) [craftbukkit.jar:git-Bukkit-33d5de3]
at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:14
0) [craftbukkit.jar:git-Bukkit-33d5de3]
at org.bukkit.craftbukkit.v1_8_R1.CraftServer.dispatchCommand(CraftServe
r.java:625) [craftbukkit.jar:git-Bukkit-33d5de3]
at net.minecraft.server.v1_8_R1.PlayerConnection.handleCommand(PlayerCon
nection.java:1058) [craftbukkit.jar:git-Bukkit-33d5de3]
at net.minecraft.server.v1_8_R1.PlayerConnection.a(PlayerConnection.java
:919) [craftbukkit.jar:git-Bukkit-33d5de3]
at net.minecraft.server.v1_8_R1.PacketPlayInChat.a(SourceFile:37) [craft
bukkit.jar:git-Bukkit-33d5de3]
at net.minecraft.server.v1_8_R1.PacketPlayInChat.a(SourceFile:9) [craftb
ukkit.jar:git-Bukkit-33d5de3]
at net.minecraft.server.v1_8_R1.PacketHandleTask.run(SourceFile:13) [cra
ftbukkit.jar:git-Bukkit-33d5de3]
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [
?:1.8.0_121]
at java.util.concurrent.FutureTask.run(Unknown Source) [?:1.8.0_121]
at net.minecraft.server.v1_8_R1.MinecraftServer.z(MinecraftServer.java:6
56) [craftbukkit.jar:git-Bukkit-33d5de3]
at net.minecraft.server.v1_8_R1.DedicatedServer.z(DedicatedServer.java:2
84) [craftbukkit.jar:git-Bukkit-33d5de3]
at net.minecraft.server.v1_8_R1.MinecraftServer.y(MinecraftServer.java:6
09) [craftbukkit.jar:git-Bukkit-33d5de3]
at net.minecraft.server.v1_8_R1.MinecraftServer.run(MinecraftServer.java
:517) [craftbukkit.jar:git-Bukkit-33d5de3]
at java.lang.Thread.run(Unknown Source) [?:1.8.0_121]
Caused by: java.lang.IllegalStateException: Initial initialization
at org.bukkit.plugin.java.PluginClassLoader.initialize(PluginClassLoader
.java:101) ~[craftbukkit.jar:git-Bukkit-33d5de3]
at org.bukkit.plugin.java.JavaPlugin.<init>(JavaPlugin.java:66) ~[craftb
ukkit.jar:git-Bukkit-33d5de3]
at tosatsu.Pvp.<init>(Pvp.java:9) ~[?:?]
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
~[?:1.8.0_121]
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
~[?:1.8.0_121]
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Sou
rce) ~[?:1.8.0_121]
at java.lang.reflect.Constructor.newInstance(Unknown Source) ~[?:1.8.0_1
21]
at java.lang.Class.newInstance(Unknown Source) ~[?:1.8.0_121]
at org.bukkit.plugin.java.PluginClassLoader.<init>(PluginClassLoader.jav
a:52) ~[craftbukkit.jar:git-Bukkit-33d5de3]
at org.bukkit.plugin.java.JavaPluginLoader.loadPlugin(JavaPluginLoader.j
ava:129) ~[craftbukkit.jar:git-Bukkit-33d5de3]
at org.bukkit.plugin.SimplePluginManager.loadPlugin(SimplePluginManager.
java:328) ~[craftbukkit.jar:git-Bukkit-33d5de3]
at org.bukkit.plugin.SimplePluginManager.loadPlugins(SimplePluginManager
.java:251) ~[craftbukkit.jar:git-Bukkit-33d5de3]
at org.bukkit.craftbukkit.v1_8_R1.CraftServer.loadPlugins(CraftServer.ja
va:288) ~[craftbukkit.jar:git-Bukkit-33d5de3]
at org.bukkit.craftbukkit.v1_8_R1.CraftServer.reload(CraftServer.java:72
3) ~[craftbukkit.jar:git-Bukkit-33d5de3]
... 16 more


使っているAPIはSpigot V1.8.3です。

思考錯誤しているうちに、PlayerJoin.javaの中で、extends JavaPluginを書かなければ問題なく動作するような気がしましたが、
JavaPluginを拡張(?)実装(?)しないとsaveDefaultConfig();など、コンフィグ関係の処理ができなくなってしまうようです。


読みにくい文章とは思いますが私にはこれが限界です。なんとか読んでください。お願いします。

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by mcgo » 2017年10月08日(日) 10:12

amata1219さん、elise_blacklabさんおっしゃる通りです。
for文で発生したエラーは新規作成したスロットの数が9個だったため、確保したスロット以上のスロットに
アイテムをセットしようとしていたことが原因でした。
また、配列の数のチェックに関しては、自分の理解力が無く、間違った認識で書き直したので同じ指摘をさせてしまいました。
今回は大変勉強になりました。
ありがとうございました。

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by amata1219 » 2017年10月05日(木) 18:33

mcgo さんが書きました:amata1219さんご回答ありがとうございます。
amata1219さんのサンプルコードと全く同じように引数が無い場合のみでif文を書きましたが
やはり例外処理にいってしまいます。
チェックを入れてみたところ、
コード: 全て選択
 public boolean onCommand(CommandSender sender, Command cmd, String s, String[] args) {
        if (cmd.getName().equalsIgnoreCase("playerinfo")) {
            getLogger().info("コマンド実行");
            if ("reload".equals(args[0])) {
                処理
            } else if (!(sender instanceof Player)) {
                処理
            } else {
                getLogger().info("コマンド実行2");
                if (sender.isOp()) {
                    getLogger().info("0");
                    if (args.length == 0) {
                       以下省略: 処理

/playerinfoと実行したときにgetLogger().info("コマンド実行2");が実行されていませんでした。
そのときエラーが以下のようにです。
エラー
コード: 全て選択
[16:20:51 ERROR]: null
org.bukkit.command.CommandException: Unhandled exception executing command 'playerinfo' in plugin PlayerInfo v1.0
        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:46) ~[patched_1.10.2.jar:git-Paper-916.2]
        at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:151) ~[patched_1.10.2.jar:git-Paper-916.2]
        at org.bukkit.craftbukkit.v1_10_R1.CraftServer.dispatchCommand(CraftServer.java:672) ~[patched_1.10.2.jar:git-Paper-916.2]
        at net.minecraft.server.v1_10_R1.PlayerConnection.handleCommand(PlayerConnection.java:1396) [patched_1.10.2.jar:git-Paper-916.2]
        at net.minecraft.server.v1_10_R1.PlayerConnection.a(PlayerConnection.java:1201) [patched_1.10.2.jar:git-Paper-916.2]
        at net.minecraft.server.v1_10_R1.PacketPlayInChat.a(PacketPlayInChat.java:45) [patched_1.10.2.jar:git-Paper-916.2]
        at net.minecraft.server.v1_10_R1.PacketPlayInChat.a(PacketPlayInChat.java:5) [patched_1.10.2.jar:git-Paper-916.2]
        at net.minecraft.server.v1_10_R1.PlayerConnectionUtils$1.run(SourceFile:13) [patched_1.10.2.jar:git-Paper-916.2]
        at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [?:1.8.0_112]
        at java.util.concurrent.FutureTask.run(Unknown Source) [?:1.8.0_112]
        at net.minecraft.server.v1_10_R1.SystemUtils.a(SourceFile:45) [patched_1.10.2.jar:git-Paper-916.2]
        at net.minecraft.server.v1_10_R1.MinecraftServer.D(MinecraftServer.java:808) [patched_1.10.2.jar:git-Paper-916.2]
        at net.minecraft.server.v1_10_R1.DedicatedServer.D(DedicatedServer.java:404) [patched_1.10.2.jar:git-Paper-916.2]
        at net.minecraft.server.v1_10_R1.MinecraftServer.C(MinecraftServer.java:740) [patched_1.10.2.jar:git-Paper-916.2]
        at net.minecraft.server.v1_10_R1.MinecraftServer.run(MinecraftServer.java:639) [patched_1.10.2.jar:git-Paper-916.2]
        at java.lang.Thread.run(Unknown Source) [?:1.8.0_112]
Caused by: java.lang.ArrayIndexOutOfBoundsException: 0
        at mc.gogojp.playerinfo.PlayerInfo.onCommand(PlayerInfo.java:50) ~[?:?]
        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44) ~[patched_1.10.2.jar:git-Paper-916.2]
        ... 15 more


もう一つ、プレイヤーのインベントリ表示についてですが、自分の説明不足でした。すみません。
自分の考えてたことは、指定したプレイヤーのインベントリ、ホットバー、防具、オフハンドのアイテムを
1つのGUIに表示するというものです。
そのためfor文を複数使い新規作成したGUIにプレイヤーのインベントリから取得したアイテムをセットするという
処理を書きました。
しかし、なぜかfor文の手前で処理が例外処理へいってしまい、正常に動作しないという状況なのです。
解決策はないでしょうか?


大変分かりづらい説明で申し訳ございません。
elise_blacklabさんの仰る通りで説明に抜けがありまして、自分は"発生したエラー"に対しての説明でなく"エラーを回避するため"の説明をしておりました。
ですが、サンプルコードと同じ記述をしていた場合まず最初に配列の長さの確認が出来ているためエラーは発生しません。
mcgoさんご自身は全く同じ記述をされているおつもりの様ですが、配列の長さを最初に確認出来ていませんのでその問題点を修正して下さい…。

コード: 全て選択
if(args.length == 0){
   //この条件に当てはまる場合は「/playerinfo」のみ入力されています。
}else if(args[0].equalsIgnoreCase("help"){
   //この条件に当てはまる場合は[/playerinfo help」と入力されています。
}

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by elise_blacklab » 2017年10月05日(木) 17:43

mcgo さんが書きました:試行錯誤をした結果、引数が無い場合のhelpの表示に成功しました。

デバッグしてる間はいいんだろうけどこのままだと,コンソールからコマンド打った時に同じ過ちを繰り返すぞ
コード: 全て選択
        if (cmd.getName().equalsIgnoreCase("playerinfo")) {
            if (!(sender instanceof Player)) {
                if ("reload".equals(args[0])) {//←
                    処理
                } else {
                    処理
                }
            }}

コンソールアプリを作った経験はおありで?引数を使うときは,サイズのチェックは真っ先に(2回目)

mcgo さんが書きました:これに関しては2つ目の引数でプレイヤーのフルネームや、プレイヤーの名前の一部(testというplayerなら引数2にtやteやtes)を
入れて実行するとエラーが発生します。

まずどこでExceptionを吐いているのか認識できているのか怪しいところですが
コード: 全て選択
Caused by: java.lang.ArrayIndexOutOfBoundsException: 9
        at org.bukkit.craftbukkit.v1_10_R1.inventory.CraftInventoryCustom$MinecraftInventory.setItem(CraftInventoryCustom.java:105) ~[patched_1.10.2.jar:git-Paper-916.2]
        at org.bukkit.craftbukkit.v1_10_R1.inventory.CraftInventory.setItem(CraftInventory.java:88) ~[patched_1.10.2.jar:git-Paper-916.2]
        at mc.gogojp.playerinfo.PlayerInfo.onCommand(PlayerInfo.java:138) ~[?:?]
        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44) ~[patched_1.10.2.jar:git-Paper-916.2]
        ... 15 more
とある通りsetItemを呼ぶ際に吐いてるんですね
で,「9」でIndexOutOfBoundsを呼ばれているということは,「9」を指定してsetItemを呼んでいそうな箇所って「for文の手前」じゃなくてブロックの中なんですよね

(PlayerInfo.java:138)の部分を見ると,例外を吐いている行数が分かるので,そこ周辺を確かめると良いですよ
大方,範囲外のスロット番号を指定しているとかじゃないですかね

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by mcgo » 2017年10月05日(木) 17:27

code
コード: 全て選択
public boolean onCommand(CommandSender sender, Command cmd, String s, String[] args) {
        if (cmd.getName().equalsIgnoreCase("playerinfo")) {
            if (!(sender instanceof Player)) {
                if ("reload".equals(args[0])) {
                    処理
                } else {
                    処理
                }
            } else {
                if (sender.isOp()) {
                    getLogger().info("0");
                    if (args.length == 0) {
                       処理
                    } else if ("reload".equals(args[0])) {
                        処理
                    } else if ("help".equals(args[0])) {
                        処理
                    } else if ("show".equals(args[0])) {
                        if (args.length == 1) {
                            処理
                        } else if (getServer().getPlayer(args[1]) == null) {
                            処理
                        } else {
                            処理
                        }
                    } else if ("open".equals(args[0])) {
                        getLogger().info("1");
                        if (args.length == 1) {
                            処理
                        } else if (getServer().getPlayer(args[1]) == null) {
                            処理
                        } else {
                            getLogger().info("2");
                            Player senderP = (Player) sender;
                            getLogger().info("3");
                            int c;
                            getLogger().info("4");
                            Player p = getServer().getPlayer(args[1]);
                            getLogger().info("5");
                            Inventory playerInv = Bukkit.createInventory(null, 9, p.getName() + "'s inventory");
                            getLogger().info("6");
                            for (c = 0; c <= 26; c++) {
                                playerInv.setItem(c, p.getInventory().getItem(c + 9));
                            }
                            getLogger().info("7");
                            for (c = 27; c <= 35; c++) {
                                playerInv.setItem(c, new ItemStack(Material.STAINED_GLASS));
                            }
                            getLogger().info("8");
                            for (c = 36; c <= 44; c++) {
                                playerInv.setItem(c, p.getInventory().getItem(c));
                            }
                            getLogger().info("9");
                            int cc = 45;
                            getLogger().info("10");
                            for (c = 103; c >= 100; c--) {
                                playerInv.setItem(cc, p.getInventory().getItem(c));
                                cc++;
                            }
                            getLogger().info("11");
                            playerInv.setItem(49, new ItemStack(Material.STAINED_GLASS));
                            getLogger().info("12");
                            playerInv.setItem(50, p.getEquipment().getItemInOffHand());
                            getLogger().info("13");
                            for (c = 51; c <= 53; c++) {
                                playerInv.setItem(c, new ItemStack(Material.STAINED_GLASS));
                            }
                            getLogger().info("14");
                            senderP.openInventory(playerInv);
                            getLogger().info("15");
                            return true;
                        }
                    } else {
                        処理
                    }
                } else {
                    処理
                }
                return true;
            }
        }
        return false;
    }


試行錯誤をした結果、引数が無い場合のhelpの表示に成功しました。
上記がそのコードです。
もう一つ、プレイヤーのインベントリ表示についてですが、自分の説明不足でした。すみません。
自分の考えてたことは、指定したプレイヤーのインベントリ、ホットバー、防具、オフハンドのアイテムを
1つのGUIに表示するというものです。
そのためfor文を複数使い新規作成したGUIにプレイヤーのインベントリから取得したアイテムをセットするという
処理を書きました。
しかし、なぜかfor文の手前で処理が例外処理へいってしまい、正常に動作しないという状況なのです。

これに関しては2つ目の引数でプレイヤーのフルネームや、プレイヤーの名前の一部(testというplayerなら引数2にtやteやtes)を
入れて実行するとエラーが発生します。
エラー
コード: 全て選択
[17:24:19 ERROR]: null
org.bukkit.command.CommandException: Unhandled exception executing command 'playerinfo' in plugin PlayerInfo v1.0
        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:46) ~[patched_1.10.2.jar:git-Paper-916.2]
        at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:151) ~[patched_1.10.2.jar:git-Paper-916.2]
        at org.bukkit.craftbukkit.v1_10_R1.CraftServer.dispatchCommand(CraftServer.java:672) ~[patched_1.10.2.jar:git-Paper-916.2]
        at net.minecraft.server.v1_10_R1.PlayerConnection.handleCommand(PlayerConnection.java:1396) [patched_1.10.2.jar:git-Paper-916.2]
        at net.minecraft.server.v1_10_R1.PlayerConnection.a(PlayerConnection.java:1201) [patched_1.10.2.jar:git-Paper-916.2]
        at net.minecraft.server.v1_10_R1.PacketPlayInChat.a(PacketPlayInChat.java:45) [patched_1.10.2.jar:git-Paper-916.2]
        at net.minecraft.server.v1_10_R1.PacketPlayInChat.a(PacketPlayInChat.java:5) [patched_1.10.2.jar:git-Paper-916.2]
        at net.minecraft.server.v1_10_R1.PlayerConnectionUtils$1.run(SourceFile:13) [patched_1.10.2.jar:git-Paper-916.2]
        at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [?:1.8.0_112]
        at java.util.concurrent.FutureTask.run(Unknown Source) [?:1.8.0_112]
        at net.minecraft.server.v1_10_R1.SystemUtils.a(SourceFile:45) [patched_1.10.2.jar:git-Paper-916.2]
        at net.minecraft.server.v1_10_R1.MinecraftServer.D(MinecraftServer.java:808) [patched_1.10.2.jar:git-Paper-916.2]
        at net.minecraft.server.v1_10_R1.DedicatedServer.D(DedicatedServer.java:404) [patched_1.10.2.jar:git-Paper-916.2]
        at net.minecraft.server.v1_10_R1.MinecraftServer.C(MinecraftServer.java:740) [patched_1.10.2.jar:git-Paper-916.2]
        at net.minecraft.server.v1_10_R1.MinecraftServer.run(MinecraftServer.java:639) [patched_1.10.2.jar:git-Paper-916.2]
        at java.lang.Thread.run(Unknown Source) [?:1.8.0_112]
Caused by: java.lang.ArrayIndexOutOfBoundsException: 9
        at org.bukkit.craftbukkit.v1_10_R1.inventory.CraftInventoryCustom$MinecraftInventory.setItem(CraftInventoryCustom.java:105) ~[patched_1.10.2.jar:git-Paper-916.2]
        at org.bukkit.craftbukkit.v1_10_R1.inventory.CraftInventory.setItem(CraftInventory.java:88) ~[patched_1.10.2.jar:git-Paper-916.2]
        at mc.gogojp.playerinfo.PlayerInfo.onCommand(PlayerInfo.java:138) ~[?:?]
        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44) ~[patched_1.10.2.jar:git-Paper-916.2]
        ... 15 more

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by elise_blacklab » 2017年10月05日(木) 17:25

mcgo さんが書きました:amata1219さんのサンプルコードと全く同じように引数が無い場合のみでif文を書きましたが
やはり例外処理にいってしまいます。

そこでargs.length == 0をチェックしても意味がない.
/playerinfo とだけ打った時のように,引数がない場合は,そもそもargsの要素は「ない」はずだから,そもそもargs[0]を参照することができない.
amata1219氏の説明にはちょっと抜けがあって,
コード: 全て選択
if("reload".equals(args[0]))
という記述はargs[0]がnullだからエラーになるんじゃなくて,そもそも0番目の要素なんてないからエラーになっている.出力にもArrayIndexOutOfBoundsExceptionを吐いているのが分かる.
配列を扱うときは,なるべく真っ先に要素数のチェックを行わないと,存在しない要素への参照をやらかしやすくなる.
あとむやみにtry-catchで押し通そうとするとデバッグの邪魔になるから,メソッドがthrowするとかnullableを扱う時とか最低限にとどめないと苦しみます.

for文の手前…はちょっと状況がわかりにくいので,そちらのログも貼ってくれると回答しやすいです.

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by mcgo » 2017年10月05日(木) 16:43

amata1219さんご回答ありがとうございます。
amata1219さんのサンプルコードと全く同じように引数が無い場合のみでif文を書きましたが
やはり例外処理にいってしまいます。
チェックを入れてみたところ、
コード: 全て選択
 public boolean onCommand(CommandSender sender, Command cmd, String s, String[] args) {
        if (cmd.getName().equalsIgnoreCase("playerinfo")) {
            getLogger().info("コマンド実行");
            if ("reload".equals(args[0])) {
                処理
            } else if (!(sender instanceof Player)) {
                処理
            } else {
                getLogger().info("コマンド実行2");
                if (sender.isOp()) {
                    getLogger().info("0");
                    if (args.length == 0) {
                       以下省略: 処理

/playerinfoと実行したときにgetLogger().info("コマンド実行2");が実行されていませんでした。
そのときエラーが以下のようにです。
エラー
コード: 全て選択
[16:20:51 ERROR]: null
org.bukkit.command.CommandException: Unhandled exception executing command 'playerinfo' in plugin PlayerInfo v1.0
        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:46) ~[patched_1.10.2.jar:git-Paper-916.2]
        at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:151) ~[patched_1.10.2.jar:git-Paper-916.2]
        at org.bukkit.craftbukkit.v1_10_R1.CraftServer.dispatchCommand(CraftServer.java:672) ~[patched_1.10.2.jar:git-Paper-916.2]
        at net.minecraft.server.v1_10_R1.PlayerConnection.handleCommand(PlayerConnection.java:1396) [patched_1.10.2.jar:git-Paper-916.2]
        at net.minecraft.server.v1_10_R1.PlayerConnection.a(PlayerConnection.java:1201) [patched_1.10.2.jar:git-Paper-916.2]
        at net.minecraft.server.v1_10_R1.PacketPlayInChat.a(PacketPlayInChat.java:45) [patched_1.10.2.jar:git-Paper-916.2]
        at net.minecraft.server.v1_10_R1.PacketPlayInChat.a(PacketPlayInChat.java:5) [patched_1.10.2.jar:git-Paper-916.2]
        at net.minecraft.server.v1_10_R1.PlayerConnectionUtils$1.run(SourceFile:13) [patched_1.10.2.jar:git-Paper-916.2]
        at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [?:1.8.0_112]
        at java.util.concurrent.FutureTask.run(Unknown Source) [?:1.8.0_112]
        at net.minecraft.server.v1_10_R1.SystemUtils.a(SourceFile:45) [patched_1.10.2.jar:git-Paper-916.2]
        at net.minecraft.server.v1_10_R1.MinecraftServer.D(MinecraftServer.java:808) [patched_1.10.2.jar:git-Paper-916.2]
        at net.minecraft.server.v1_10_R1.DedicatedServer.D(DedicatedServer.java:404) [patched_1.10.2.jar:git-Paper-916.2]
        at net.minecraft.server.v1_10_R1.MinecraftServer.C(MinecraftServer.java:740) [patched_1.10.2.jar:git-Paper-916.2]
        at net.minecraft.server.v1_10_R1.MinecraftServer.run(MinecraftServer.java:639) [patched_1.10.2.jar:git-Paper-916.2]
        at java.lang.Thread.run(Unknown Source) [?:1.8.0_112]
Caused by: java.lang.ArrayIndexOutOfBoundsException: 0
        at mc.gogojp.playerinfo.PlayerInfo.onCommand(PlayerInfo.java:50) ~[?:?]
        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44) ~[patched_1.10.2.jar:git-Paper-916.2]
        ... 15 more


もう一つ、プレイヤーのインベントリ表示についてですが、自分の説明不足でした。すみません。
自分の考えてたことは、指定したプレイヤーのインベントリ、ホットバー、防具、オフハンドのアイテムを
1つのGUIに表示するというものです。
そのためfor文を複数使い新規作成したGUIにプレイヤーのインベントリから取得したアイテムをセットするという
処理を書きました。
しかし、なぜかfor文の手前で処理が例外処理へいってしまい、正常に動作しないという状況なのです。
解決策はないでしょうか?

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by amata1219 » 2017年10月05日(木) 15:23

mcgo さんが書きました:
code
コード: 全て選択
@Override
    public boolean onCommand(CommandSender sender, Command cmd, String s, String[] args) {
        if (cmd.getName().equalsIgnoreCase("playerinfo")) {
            try {
                if ("reload".equals(args[0])) {
                    処理
                } else if (!(sender instanceof Player)) {
                    処理
                } else {
                    if (sender.isOp()) {
                        getLogger().info("0");
                        if (args.length == 0 || "help".equals(args[0])) {
                            ヘルプ表示
                        } else if ("show".equals(args[0])) {
                            処理
                        } else if ("open".equals(args[0])) {
                            getLogger().info("1");
                            if (getServer().getPlayer(args[1]) == null) {
                                sender.sendMessage("[PlayerInfo] " + ChatColor.RED + args[1] + " is not online player.");
                            } else {
                                getLogger().info("2");
                                Player senderP = (Player) sender;
                                getLogger().info("3");
                                int c;
                                getLogger().info("4");
                                Player p = getServer().getPlayer(args[1]);
                                getLogger().info("5");
                                Inventory playerInv = Bukkit.createInventory(null, 9, p.getName() + "'s inventory");
                                getLogger().info("6");
                                for (c = 0; c <= 26; c++) {
                                    playerInv.setItem(c, p.getInventory().getItem(c + 9));
                                }
                                getLogger().info("7");
                                for (c = 27; c <= 35; c++) {
                                    playerInv.setItem(c, new ItemStack(Material.STAINED_GLASS));
                                }
                                getLogger().info("8");
                                for (c = 36; c <= 44; c++) {
                                    playerInv.setItem(c, p.getInventory().getItem(c));
                                }
                                getLogger().info("9");
                                int cc = 45;
                                getLogger().info("10");
                                for (c = 103; c >= 100; c--) {
                                    playerInv.setItem(cc, p.getInventory().getItem(c));
                                    cc++;
                                }
                                getLogger().info("11");
                                playerInv.setItem(49, new ItemStack(Material.STAINED_GLASS));
                                getLogger().info("12");
                                playerInv.setItem(50, p.getEquipment().getItemInOffHand());
                                getLogger().info("13");
                                for (c = 51; c <= 53; c++) {
                                    playerInv.setItem(c, new ItemStack(Material.STAINED_GLASS));
                                }
                                getLogger().info("14");
                                senderP.openInventory(playerInv);
                                getLogger().info("15");
                            }
                        } else {
                            処理
                        }
                    } else {
                        処理
                    }
                    return true;
                }
            } catch (ArrayIndexOutOfBoundsException e) {
               処理
            }
        }
        return false;
    }

簡易的なプレイヤーの情報が見れるプラグインを作っています。
指定したプレイヤーのインベントリの中身を表示するものを作っていたのですが
なぜかfor文の手前のgetLogger().info("6");で止まってしまい例外処理に行ってしまいます。
また引数が無い場合と引数1がhelpの時にヘルプを表示させたいのですが
引数が無い場合に例外処理に行ってしまいます。
解決策のご教授お願いします。

ver 1.10.2
特にエラーはありません


mcgoさんこんにちは。
まず、他プレイヤーのインベントリを表示させるだけであれば、態々インベントリを新規作成せずに表示出来ます。
下記コードとコメントアウト部の解説をご参考にして頂ければと思います。

コード: 全て選択
Player p1 = (Player) sender;
//コマンド送信者
Player p2 = Bukkit.getServer().getPlayer(p2);
//nullチェック済みの対象者
p1.openInventory(p2.getInventory());
//openInventory(Inventory inventory)を使うと簡単にインベントリを表示させられる。getInventory()でInventoryデータが取得出来るのでそのままp1に表示させる。


次にHelp表示の件ですが、基本的にtry文を用いる必要はありませんのでそれを前提にお話します。
他の引数確認処理の影響を受けてしまい正常に動作しない可能性がありますので、ここでは引数が無い場合の処理は最初に記述します。
これも同じく下記コードとコメントアウト部の解説をご参考下さい。
コード: 全て選択
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args){
   if(cmd.getName().equalsIgnoreCase("playerinfo"){
      //コマンド名の確認
      if(args.length == 0){
         //配列の長さの確認
         sender.sendMessage("help");
         //処理の記述
         return true;
      }else if(args[0].equalsIgnoreCase("help"){
         //手前に記述した配列の長さの確認によりargs[0]がnullでない事も同時に証明されるので、そのままargs[0]に対して文字列の比較を行う
         sender.sendMessage("help");
         return true;
      }else if(args[0].equalsIgnoreCase("~~~"){
         //他の処理
         return true;
   }
return false;
}

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by mcgo » 2017年10月05日(木) 10:38

code
コード: 全て選択
@Override
    public boolean onCommand(CommandSender sender, Command cmd, String s, String[] args) {
        if (cmd.getName().equalsIgnoreCase("playerinfo")) {
            try {
                if ("reload".equals(args[0])) {
                    処理
                } else if (!(sender instanceof Player)) {
                    処理
                } else {
                    if (sender.isOp()) {
                        getLogger().info("0");
                        if (args.length == 0 || "help".equals(args[0])) {
                            ヘルプ表示
                        } else if ("show".equals(args[0])) {
                            処理
                        } else if ("open".equals(args[0])) {
                            getLogger().info("1");
                            if (getServer().getPlayer(args[1]) == null) {
                                sender.sendMessage("[PlayerInfo] " + ChatColor.RED + args[1] + " is not online player.");
                            } else {
                                getLogger().info("2");
                                Player senderP = (Player) sender;
                                getLogger().info("3");
                                int c;
                                getLogger().info("4");
                                Player p = getServer().getPlayer(args[1]);
                                getLogger().info("5");
                                Inventory playerInv = Bukkit.createInventory(null, 9, p.getName() + "'s inventory");
                                getLogger().info("6");
                                for (c = 0; c <= 26; c++) {
                                    playerInv.setItem(c, p.getInventory().getItem(c + 9));
                                }
                                getLogger().info("7");
                                for (c = 27; c <= 35; c++) {
                                    playerInv.setItem(c, new ItemStack(Material.STAINED_GLASS));
                                }
                                getLogger().info("8");
                                for (c = 36; c <= 44; c++) {
                                    playerInv.setItem(c, p.getInventory().getItem(c));
                                }
                                getLogger().info("9");
                                int cc = 45;
                                getLogger().info("10");
                                for (c = 103; c >= 100; c--) {
                                    playerInv.setItem(cc, p.getInventory().getItem(c));
                                    cc++;
                                }
                                getLogger().info("11");
                                playerInv.setItem(49, new ItemStack(Material.STAINED_GLASS));
                                getLogger().info("12");
                                playerInv.setItem(50, p.getEquipment().getItemInOffHand());
                                getLogger().info("13");
                                for (c = 51; c <= 53; c++) {
                                    playerInv.setItem(c, new ItemStack(Material.STAINED_GLASS));
                                }
                                getLogger().info("14");
                                senderP.openInventory(playerInv);
                                getLogger().info("15");
                            }
                        } else {
                            処理
                        }
                    } else {
                        処理
                    }
                    return true;
                }
            } catch (ArrayIndexOutOfBoundsException e) {
               処理
            }
        }
        return false;
    }

簡易的なプレイヤーの情報が見れるプラグインを作っています。
指定したプレイヤーのインベントリの中身を表示するものを作っていたのですが
なぜかfor文の手前のgetLogger().info("6");で止まってしまい例外処理に行ってしまいます。
また引数が無い場合と引数1がhelpの時にヘルプを表示させたいのですが
引数が無い場合に例外処理に行ってしまいます。
解決策のご教授お願いします。

ver 1.10.2
特にエラーはありません

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by mcgo » 2017年10月01日(日) 22:14

supermarisa6 さんが書きました:snip

ご回答ありがとうございます。
メインハンドだった時というifを書かないと2回動作してしまうんですね。
まだ初めてなもので無知な部分がたくさんあるので助かります。
ありがとうございました。

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by supermarisa6 » 2017年10月01日(日) 19:04

mcgo さんが書きました:最近プラグインを作ってみたいと思って行き詰まったことがあるので質問させて頂きます。
Java初心者なので記載に不備などがあれば指摘お願いします。

1つ目の質問
/mynameと打つとチャットに『コマンド実行者>>> <player>』と表示されるものをやっていたのですが、
ymlに記載したusegeの部分が表示されて動作しません。

2つ目の質問
エメラルドブロックを手に何も持ってない状態で⇒右クリックするとYes、何か持ってる状態だとNoと表示されるものです。
しかし、何も持ってない状態でエメラルドブロックを右クリックするとなぜかYesと2回表示されます。

プラグインは正常に動作しており、コンソールにエラーなどは出ておりません。
解決策お願いします。
ver : spigot 1.10.2

追記:ツルハシなどのツールを持った状態で右クリックしてもNoが2回でます。

plugin.yml
コード: 全て選択
name: TestPlugin
version: 1.0
main: com.mycompany.test.TestPlugin

commands:
    myname:
       description: test
       usage: /<command>
       default: true
       permission: test.use
       permission-message: You don't have <permission>

code
コード: 全て選択
package com.mycompany.test;

import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;

public class TestPlugin extends JavaPlugin implements Listener {

    @Override
    public void onEnable() {
        super.onEnable();
        getServer().getPluginManager().registerEvents(this, this);
        this.getServer().getConsoleSender().sendMessage("[TestPlugin] " + ChatColor.YELLOW + "Successfully loading this plugin");
    }

    @Override
    public void onDisable() {
        super.onDisable();
        this.getServer().getConsoleSender().sendMessage("[TestPlugin] " + ChatColor.RED + "Successfully unloading this plugin");
    }

    @Override
    public void onLoad() {
        super.onLoad();
    }
   
    public boolean onCommand(CommandSender sender, Command cmd, String s, String[] args[]) {
        if (cmd.getName().equalsIgnoreCase("myname")) {
            if (!(sender instanceof Player)) {
                sender.sendMessage("このコマンドはプレイヤーのみが使えます");
                return true;
            } else {
                String senderPlayer = sender.getName();
                sender.sendMessage("コマンド実行者>>> " + senderPlayer);
                return true;
            }
        }
        return false;
    }

    @EventHandler
    public void clickEvent(PlayerInteractEvent e) {
        Action action = e.getAction();
        Player player = e.getPlayer();
        Block block = e.getClickedBlock();
        ItemStack heldItem = player.getItemInHand();
        if (action.equals(Action.RIGHT_CLICK_BLOCK)) {
            if (block.getType().equals(Material.EMERALD_BLOCK)) {
                if (heldItem.getType().equals(Material.AIR)) {
                    player.sendMessage("Yes");
                } else {
                    player.sendMessage("No");
                }
            }
        }
    }

}


持っているアイテム名などを表示させてみるとわかりますが、Minecraftでオフハンドが追加されて以降、メインハンドとオフハンドで2回イベントが呼ばれるようになっています。
それによって2回イベントが呼ばれ、メッセージが2度表示されているのだと考えられます。

メインハンド、オフハンドの違いはPlayerInteractEvent#getHand()EquipmentSlot.HANDEquipmentSlot.OFF_HANDかどうかで調べられます。

サンプルソース
コード: 全て選択
   @EventHandler
   public void onPlayerInteract(PlayerInteractEvent event){
      if(event.getHand() == EquipmentSlot.HAND){
         Bukkit.broadcastMessage("メインハンド処理!");
      }else if(event.getHand() == EquipmentSlot.OFF_HAND){
         Bukkit.broadcastMessage("オフハンド処理!");
      }
   }

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by mcgo » 2017年10月01日(日) 00:03

mcgo さんが書きました:1つ目の質問
/mynameと打つとチャットに『コマンド実行者>>> <player>』と表示されるものをやっていたのですが、
ymlに記載したusegeの部分が表示されて動作しません。

1つ目の質問は解決いたしました。
原因は書き方のミスでした。
コード: 全て選択
 public boolean onCommand(CommandSender sender, Command cmd, String s, String[] args[]) {

args[]というふうに書いていたので[]を消してargsにしたら動作しました。

まだ2つ目の質問が解決してないので解決策ご教授お願いします。

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by mcgo » 2017年9月30日(土) 14:48

最近プラグインを作ってみたいと思って行き詰まったことがあるので質問させて頂きます。
Java初心者なので記載に不備などがあれば指摘お願いします。

1つ目の質問
/mynameと打つとチャットに『コマンド実行者>>> <player>』と表示されるものをやっていたのですが、
ymlに記載したusegeの部分が表示されて動作しません。

2つ目の質問
エメラルドブロックを手に何も持ってない状態で⇒右クリックするとYes、何か持ってる状態だとNoと表示されるものです。
しかし、何も持ってない状態でエメラルドブロックを右クリックするとなぜかYesと2回表示されます。

プラグインは正常に動作しており、コンソールにエラーなどは出ておりません。
解決策お願いします。
ver : spigot 1.10.2

追記:ツルハシなどのツールを持った状態で右クリックしてもNoが2回でます。

plugin.yml
コード: 全て選択
name: TestPlugin
version: 1.0
main: com.mycompany.test.TestPlugin

commands:
    myname:
       description: test
       usage: /<command>
       default: true
       permission: test.use
       permission-message: You don't have <permission>

code
コード: 全て選択
package com.mycompany.test;

import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;

public class TestPlugin extends JavaPlugin implements Listener {

    @Override
    public void onEnable() {
        super.onEnable();
        getServer().getPluginManager().registerEvents(this, this);
        this.getServer().getConsoleSender().sendMessage("[TestPlugin] " + ChatColor.YELLOW + "Successfully loading this plugin");
    }

    @Override
    public void onDisable() {
        super.onDisable();
        this.getServer().getConsoleSender().sendMessage("[TestPlugin] " + ChatColor.RED + "Successfully unloading this plugin");
    }

    @Override
    public void onLoad() {
        super.onLoad();
    }
   
    public boolean onCommand(CommandSender sender, Command cmd, String s, String[] args[]) {
        if (cmd.getName().equalsIgnoreCase("myname")) {
            if (!(sender instanceof Player)) {
                sender.sendMessage("このコマンドはプレイヤーのみが使えます");
                return true;
            } else {
                String senderPlayer = sender.getName();
                sender.sendMessage("コマンド実行者>>> " + senderPlayer);
                return true;
            }
        }
        return false;
    }

    @EventHandler
    public void clickEvent(PlayerInteractEvent e) {
        Action action = e.getAction();
        Player player = e.getPlayer();
        Block block = e.getClickedBlock();
        ItemStack heldItem = player.getItemInHand();
        if (action.equals(Action.RIGHT_CLICK_BLOCK)) {
            if (block.getType().equals(Material.EMERALD_BLOCK)) {
                if (heldItem.getType().equals(Material.AIR)) {
                    player.sendMessage("Yes");
                } else {
                    player.sendMessage("No");
                }
            }
        }
    }

}

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by しおん♪ » 2017年9月23日(土) 22:13

レシピ追加で材料として名前や説明欄がついたアイテムを使う方法を教えていただきたいです

Re: 【総合】トピック立てるまでもない質問【Bukkit Plugin制作】

投稿記事 by AKM » 2017年9月16日(土) 22:27

丁寧な解説ありがとうございます。
提示していただいた例とサイトを使って頑張って見ます。
ありがとうございました!

ページトップ

x