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

Modding・サーバPlugin制作・ツール制作など、開発関連の質問があればこちらにお願い致します。
フォーラムルール
質問関連フォーラムで質問する時は、必ず次のトピックを一読/厳守お願い致します。
viewtopic.php?f=5&t=999
  • (PostNo.307197)

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

投稿記事by Pucian » 2017年8月31日(木) 16:53

いきなりですみません。 チャット発言時に名前の横にマインクラフトのレベルを表示させるプラグインはありますか?
探しても見つからないんです。
Pucian
ID:281c75ac
 

  • (PostNo.307199)

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

投稿記事by miyabi » 2017年8月31日(木) 17:01

Pucian さんが書きました:いきなりですみません。 チャット発言時に名前の横にマインクラフトのレベルを表示させるプラグインはありますか?
探しても見つからないんです。

質問:開発・制作関連
【総合】トピック立てるまでもない質問【Bukkit Plugin制作

カテゴリ名やトピック名は良く読んで投稿するようにしましょう。
削除依頼、移動依頼は以下からどうぞ。
viewtopic.php?f=16&t=3583
マイクラサーバを立てる前に、PCの基礎知識を身につけましょう。
サーバ管理補助ツール MCSC(Windows専用) の開発をしたり、Minecraft Modding Wikiの管理したりしてます。
アバター
miyabi
ID:91b90127
ブタ飼い
 
記事: 6991
登録日時: 2011年8月07日(日) 14:35
お住まい: さいたまさいたまさいたま!

  • (PostNo.307660)

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

投稿記事by hyoreo » 2017年9月11日(月) 16:27

質問です。
名前の付いた特定のアイテムを右クリックすると雪玉が発射されるプラグインを作っていて、
PlayerInteractEventが発生するたびに雪玉を発射する処理を作ってみたのですが、
この方法だと弾が出る頻度を遅くしたり早くしたりすることができず困っています。
スケジューラを使ってなんとかしようとしたけどうまくいかず・・・orz
何かいい方法があればご教示ください!

コードです↓
コード: 全て選択
   String weapon;

   String gun = "銃";

   @EventHandler
   public void onPlayerInteractEvent(PlayerInteractEvent event) {
      if (!event.hasItem()) return;
      ItemStack playeritem = event.getPlayer().getItemInHand();
      if (!playeritem.hasItemMeta()) return;
      if (!event.getAction().equals(Action.RIGHT_CLICK_AIR) ||
         !event.getAction().equals(Action.RIGHT_CLICK_BLOCK)) return;
      if (playeritem.getItemMeta().getDisplayName().equals(gun)) {
         if (playeritem.getType().equals(Material.IRON_BARDING)){
            event.getPlayer().launchProjectile(Snowball.class);
         }
      }
   }
アバター
hyoreo
ID:a0623564
木を殴ってる
 
記事: 36
登録日時: 2014年1月20日(月) 20:41
お住まい: 大都会岡山

  • (PostNo.307682)

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

投稿記事by amata1219 » 2017年9月11日(月) 21:39

hyoreo さんが書きました:質問です。
名前の付いた特定のアイテムを右クリックすると雪玉が発射されるプラグインを作っていて、
PlayerInteractEventが発生するたびに雪玉を発射する処理を作ってみたのですが、
この方法だと弾が出る頻度を遅くしたり早くしたりすることができず困っています。
スケジューラを使ってなんとかしようとしたけどうまくいかず・・・orz
何かいい方法があればご教示ください!

コードです↓
コード: 全て選択
   String weapon;

   String gun = "銃";

   @EventHandler
   public void onPlayerInteractEvent(PlayerInteractEvent event) {
      if (!event.hasItem()) return;
      ItemStack playeritem = event.getPlayer().getItemInHand();
      if (!playeritem.hasItemMeta()) return;
      if (!event.getAction().equals(Action.RIGHT_CLICK_AIR) ||
         !event.getAction().equals(Action.RIGHT_CLICK_BLOCK)) return;
      if (playeritem.getItemMeta().getDisplayName().equals(gun)) {
         if (playeritem.getType().equals(Material.IRON_BARDING)){
            event.getPlayer().launchProjectile(Snowball.class);
         }
      }
   }


hyoreoさんこんばんは。
雪玉発射処理を遅延実行したいのであればスケジューラを用いるだけで可能でして、以下の様にするだけで遅延実行出来ます。
コード: 全て選択
new BukkitRunnable(){
public void run(){
//ここに遅延実行したい処理を記述
}
}.runTaskLater(plugin, tick)

一応チュートリアルのURLも貼らせて頂きますね。
スケジューラのプログラミング
アバター
amata1219
ID:03e7ab14
木を殴ってる
 
記事: 24
登録日時: 2016年11月18日(金) 16:46
お住まい: 愛知県

  • (PostNo.307685)

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

投稿記事by King(qpwakaba) » 2017年9月11日(月) 21:56

amata1219 さんが書きました:
hyoreo さんが書きました:

多分連射速度、という意味だと思うんで簡単に方法だけ

最初にInteractEventで スケジューラタスクを開始

連射を止める条件を満たすまで、スケジューラタスクでたまを発射し続ける

連射を止める条件を満たしたら、スケジューラタスクを止める


連射中に速度が変わらなければrunTaskTimerを使うと良いかも。
連射中に速度を変えたいのであれば、runTaskLaterを使って、タスクの中でrunTaskLaterするといいかも。
以下サイン
調べて見つからないことを質問して、「そのくらい調べろ」と言われたら それは調べが足りないとき。

投稿画面のBBコード挿入ボタン を追加するユーザースクリプト作りました。良かったらどうぞ。
https://greasyfork.org/ja/scripts/18657
最大描画距離を64チャンクまで伸ばすMod作ってます。
viewtopic.php?t=30697
アバター
King(qpwakaba)
ID:4e8307eb
ダイヤモンド掘り
 
記事: 819
登録日時: 2013年3月26日(火) 10:25

  • (PostNo.307688)

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

投稿記事by amata1219 » 2017年9月11日(月) 22:29

King(qpwakaba) さんが書きました:
amata1219 さんが書きました:
hyoreo さんが書きました:

多分連射速度、という意味だと思うんで簡単に方法だけ

最初にInteractEventで スケジューラタスクを開始

連射を止める条件を満たすまで、スケジューラタスクでたまを発射し続ける

連射を止める条件を満たしたら、スケジューラタスクを止める


連射中に速度が変わらなければrunTaskTimerを使うと良いかも。
連射中に速度を変えたいのであれば、runTaskLaterを使って、タスクの中でrunTaskLaterするといいかも。

ああ、そういう事でしたか。誤解していました…_(:3 ∠ )_。
付け足しありがとうございます。
アバター
amata1219
ID:03e7ab14
木を殴ってる
 
記事: 24
登録日時: 2016年11月18日(金) 16:46
お住まい: 愛知県

  • (PostNo.307797)

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

投稿記事by hyoreo » 2017年9月14日(木) 23:33

amata1219 さんが書きました:

King(qpwakaba) さんが書きました:

ご回答ありがとうございます。
早速書いてみようと思ったのですが、
連射を止める条件をどうやって検知するのかがわかりません。。。
isBlocking()で右クリックを押しているか検知できるかと思ったのですが、できませんでした・・・
プレイヤーが右クリックしているか確認する関数は存在するのでしょうか?
アバター
hyoreo
ID:a0623564
木を殴ってる
 
記事: 36
登録日時: 2014年1月20日(月) 20:41
お住まい: 大都会岡山

  • (PostNo.307799)

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

投稿記事by ことむー » 2017年9月14日(木) 23:55

hyoreo さんが書きました:
amata1219 さんが書きました:

King(qpwakaba) さんが書きました:

ご回答ありがとうございます。
早速書いてみようと思ったのですが、
連射を止める条件をどうやって検知するのかがわかりません。。。
isBlocking()で右クリックを押しているか検知できるかと思ったのですが、できませんでした・・・
プレイヤーが右クリックしているか確認する関数は存在するのでしょうか?


横から失礼( ´_ゝ`)ノ
もし1tickごとに連射っていう感じでやりたいのであれば
右クリックイベント(PlayerInteractEvent)は1/4秒(5tick)間隔で動いてるので
InteractEventが発生

適当な変数に5を代入

タイマーが動くたびに変数をデクリメント(減算)

その変数が0以下になった場合は連射を止める

って感じの処理でやると良いんでないかな?
まぁ後は工夫して自分のやりやすいように頑張って!(´-ω-`)(雑

昔自分もKing氏に同じような動作アドバイスしてもらった
以下それっぽい動きのやつ、可変可能
https://github.com/kotmw0701/Splatoon-i ... ooter.java
アバター
ことむー
ID:658a9697
石炭掘り
 
記事: 155
登録日時: 2014年5月11日(日) 22:01
お住まい: 日本建築の家(じゃなかったらどこの国のひとだ!?ってなるよな)

  • (PostNo.307813)

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

投稿記事by AKM » 2017年9月15日(金) 17:04

質問なのですが、アイテム(剣、斧などの武器)の攻撃速度や攻撃威力を変更することは不可能なのでしょうか。
ItemMetaからは変更できそうになく、海外のサイトで検索をかけても旧バージョンの方法しか出てきません。
APIの変更で設定できなくなってしまったのでしょうか。
方法を知っている方教えてください。よろしくお願いします。
(spigot-ver-1.12.1)
AKM
ID:f86fe74b
 

  • (PostNo.307879)

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

投稿記事by amata1219 » 2017年9月16日(土) 19:52

AKM さんが書きました:質問なのですが、アイテム(剣、斧などの武器)の攻撃速度や攻撃威力を変更することは不可能なのでしょうか。
ItemMetaからは変更できそうになく、海外のサイトで検索をかけても旧バージョンの方法しか出てきません。
APIの変更で設定できなくなってしまったのでしょうか。
方法を知っている方教えてください。よろしくお願いします。
(spigot-ver-1.12.1)


AKMさんこんにちは。
結論から申し上げますと可能です。
ご存知でしたら申し訳ございませんが、攻撃速度や攻撃威力はAttribute ModifiersというNBTタグの一種であり、ItemMetaからの読み書きは出来ません。
そこで、プラグインからのAttribute Modifiers及びNBTの読み書きにはNMSを利用します。
下記コードは攻撃力+50の木の剣をプレイヤーに与えるコードになります。
コメントアウト部の解説と合わせてご参考にして頂ければと思います。
コード: 全て選択
      ItemStack item = new ItemStack(Material.WOOD_SWORD);
      //新しいアイテムを作成。

      net.minecraft.server.v1_12_R1.ItemStack nmsItem= CraftItemStack.asNMSCopy(item);
      //CraftItemStackクラスのasNMSCopyメソッドでnmsItemStackを取得する。

      NBTTagCompound compound = (nmsItem.hasTag()) ? nmsItem.getTag() : new NBTTagCompound();
      //NMSのItemStackコンパウンドはnullに出来るので確認する。

      NBTTagList modifiers = new NBTTagList();
      //書き込む属性を入れるリストを作成する。

      NBTTagCompound dmg = new NBTTagCompound();
      //attackDamage属性を編集するための変数を作成する。

      dmg.set("AttributeName", new NBTTagString("generic.attackDamage"));
      dmg.set("Name", new NBTTagString("generic.attackDamage"));
      //属性を指定する。名称は公式Wikiを参考にしました。

      dmg.set("Amount", new NBTTagInt(50));
      //ここでダメージ量を指定出来ます。ここでの数値1はハート0.5に値します。

      dmg.set("Operation", new NBTTagInt(0));
      //属性の基本値を編集出来ますが基本触らないため0を指定します。

      dmg.set("UUIDLeast", new NBTTagInt(894654));
      dmg.set("UUIDMost", new NBTTagInt(2872));
      //ここの2つは恐らく触ってはいけません。数値は公式Wikiを参考にしました。

      dmg.set("Slot", new NBTTagString("mainhand"));
      //ここでAttributeModifiers効果を有効にするスロットを指定します。指定しないと全スロットで有効になります。

      modifiers.add(dmg);
      //リストに書き込む。

      compound.set("AttributeModifiers", modifiers);
      //nmsItemStackから取得したItemStackコンパウンドに書き込む。

      nmsItem.setTag(compound);
      //アイテムにNBTを書き込む。

      item = CraftItemStack.asBukkitCopy(nmsItem);
      //CraftItemStackクラスのasBukkitCopyメソッドにNBTTag書き込み済みのnmsItemStackを入れる。

      p.getInventory().addItem(item);
      //プレイヤーにアイテムを与える


参考にした記事:
Minecraft公式Wiki - Attribute
またVer.1.11で英語ではありますがAtturibute Modifiersに関連するチュートリアルを見つけましたので記載させて頂きますね。
NBTTags & Attribute チュートリアル
アバター
amata1219
ID:03e7ab14
木を殴ってる
 
記事: 24
登録日時: 2016年11月18日(金) 16:46
お住まい: 愛知県

  • (PostNo.307897)

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

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

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

  • (PostNo.308204)

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

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

レシピ追加で材料として名前や説明欄がついたアイテムを使う方法を教えていただきたいです
しおん♪
ID:6f1f5662
水から上がったとこ
 
記事: 2
登録日時: 2017年8月18日(金) 20:47

  • (PostNo.308518)

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");
                }
            }
        }
    }

}
サーバー関係の分からないことは英語で検索したら案外出ててくるで!
だってMinecraftって海外生まれやで!
最近はSkriptを使って色々自作してサーバー作ってます。
もしよければSkript作成してもいいゾ(激ムズは拒否するかも・・・)
詳しくはPMで!
【Skript自作コード公開中】
アバター
mcgo
ID:cc16d7cb
石炭掘り
 
記事: 227
登録日時: 2016年11月04日(金) 00:05

  • (PostNo.308544)

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つ目の質問が解決してないので解決策ご教授お願いします。
サーバー関係の分からないことは英語で検索したら案外出ててくるで!
だってMinecraftって海外生まれやで!
最近はSkriptを使って色々自作してサーバー作ってます。
もしよければSkript作成してもいいゾ(激ムズは拒否するかも・・・)
詳しくはPMで!
【Skript自作コード公開中】
アバター
mcgo
ID:cc16d7cb
石炭掘り
 
記事: 227
登録日時: 2016年11月04日(金) 00:05

  • (PostNo.308579)

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("オフハンド処理!");
      }
   }
Bukkitプラグインや外部支援ツールなどちょくちょく作っているsupermarisa6です。
回答するとき、質問を理解せず答えて見当違いなことをよく言いってしまいます。(申し訳ないです)
supermarisa6
ID:94f14014
石炭掘り
 
記事: 153
登録日時: 2013年6月05日(水) 17:37
お住まい: 幻想郷

  • (PostNo.308602)

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

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

supermarisa6 さんが書きました:snip

ご回答ありがとうございます。
メインハンドだった時というifを書かないと2回動作してしまうんですね。
まだ初めてなもので無知な部分がたくさんあるので助かります。
ありがとうございました。
サーバー関係の分からないことは英語で検索したら案外出ててくるで!
だってMinecraftって海外生まれやで!
最近はSkriptを使って色々自作してサーバー作ってます。
もしよければSkript作成してもいいゾ(激ムズは拒否するかも・・・)
詳しくはPMで!
【Skript自作コード公開中】
アバター
mcgo
ID:cc16d7cb
石炭掘り
 
記事: 227
登録日時: 2016年11月04日(金) 00:05

  • (PostNo.308731)

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
特にエラーはありません
サーバー関係の分からないことは英語で検索したら案外出ててくるで!
だってMinecraftって海外生まれやで!
最近はSkriptを使って色々自作してサーバー作ってます。
もしよければSkript作成してもいいゾ(激ムズは拒否するかも・・・)
詳しくはPMで!
【Skript自作コード公開中】
アバター
mcgo
ID:54bef510
石炭掘り
 
記事: 227
登録日時: 2016年11月04日(金) 00:05

  • (PostNo.308735)

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;
}
アバター
amata1219
ID:71b855fd
木を殴ってる
 
記事: 24
登録日時: 2016年11月18日(金) 16:46
お住まい: 愛知県

  • (PostNo.308738)

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文の手前で処理が例外処理へいってしまい、正常に動作しないという状況なのです。
解決策はないでしょうか?
サーバー関係の分からないことは英語で検索したら案外出ててくるで!
だってMinecraftって海外生まれやで!
最近はSkriptを使って色々自作してサーバー作ってます。
もしよければSkript作成してもいいゾ(激ムズは拒否するかも・・・)
詳しくはPMで!
【Skript自作コード公開中】
アバター
mcgo
ID:54bef510
石炭掘り
 
記事: 227
登録日時: 2016年11月04日(金) 00:05

  • (PostNo.308741)

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文の手前…はちょっと状況がわかりにくいので,そちらのログも貼ってくれると回答しやすいです.
最後に編集したユーザー elise_blacklab [ 2017年10月05日(木) 17:29 ], 累計 1 回
メイドつくってたりします.http://el-blacklab.net/
アバター
elise_blacklab
ID:0f87040f
掘り廃人
 
記事: 2405
登録日時: 2014年6月25日(水) 18:30

1つ前へ次へ

Return to 質問:開発・制作関連

x