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

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

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

投稿記事by youzuki » 2016年3月20日(日) 14:02

ゲスト さんが書きました:返信ありがとうございます。
あれからいろいろと試してみたのですが...ギブアップです。
最終的にたどり着いたのが下記のコードです。問題点、解決方法をご教示ください。

@EventHandler
public void onJoin(PlayerJoinEvent event) {
   World w = Bukkit.getWorld("Lobby");
 List<Player> p = w.getPlayers();
 ((Player) p).sendMessage("Test");
}


Bukkit以前にListの扱い方を学んだほうが良いのでは
絵描きの人です。
https://twitter.com/Shiro_Youduki
アバター
youzuki
ID:445863b2
石炭掘り
 
記事: 189
登録日時: 2013年10月10日(木) 20:28

  • (PostNo.267774)

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

投稿記事by ucchy » 2016年3月20日(日) 14:32

まあまあ・・・。

Player はプレイヤーを示すクラスで、List<Player> は複数のプレイヤーを格納したリストです。
これらは全然別のものですから、キャストすることはできません。わかりますね?
複数のPlayerを格納しているわけですから、その中から一つ一つPlayerを取り出してメッセージを送ってあげれば良いわけです。
そういうときは、拡張for文、または、ラムダ式 を使用します。
例として、拡張for文で実装したときのコードを示します。
コード: 全て選択
    @EventHandler
    public void onPlayerJoin(PlayerJoinEvent event) {
        World world = Bukkit.getWorld("Lobby");
        List<Player> players = world.getPlayers();
        for ( Player player : players ) {
            player.sendMessage(event.getPlayer().getName() + "さんが、Lobbyにログインしました。");
        }
    }


youzukiさんの言っている通り、これはjavaの基本的な構文です。
プラグインを実装するにはjavaの知識が必須ですから、まずはjavaを学ぶ方が、プラグイン作成をマスターする近道になりそうです。
――お知らせ――
パソコンが壊れたため、買い替えるまで、プラグイン開発作業はお休みしています。簡単な質問程度ならお答えいたします。
――お知らせ――
アバター
ucchy
ID:953ffc01
ラピスラズリ収集家
 
記事: 1179
登録日時: 2012年11月07日(水) 00:08

  • (PostNo.267844)

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

投稿記事by オリゼリ » 2016年3月20日(日) 23:21

コマンドでプレイヤーにアイテムを与えたいのですが与えるアイテムに名前を付ける場合どうしたらよいでしょうか?
コード: 全て選択
      if(cmd.getName().equalsIgnoreCase("kit")){
         Player player = (Player) sender;
         PlayerInventory inventory = player.getInventory();
         inventory.addItem(new ItemStack(Material.ENDER_PEARL));
         inventory.addItem(new ItemStack(Material.FIREBALL));
         player.sendMessage(ChatColor.AQUA + "キットを配布しました");
      }
質問の仕方とか直したほうがいいよってことがあったら教えていただければ嬉しいです
オリゼリ
ID:e76ccee0
大工さん
 
記事: 44
登録日時: 2015年4月29日(水) 20:13

  • (PostNo.267845)

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

投稿記事by King(qpwakaba) » 2016年3月20日(日) 23:25

オリゼリ さんが書きました:コマンドでプレイヤーにアイテムを与えたいのですが与えるアイテムに名前を付ける場合どうしたらよいでしょうか?


ItemStack.getItemMeta()ItemMetaを取得して
ItemMeta.setDisplayName(String)でアイテム名を設定した後
ItemStack.setItemMeta(ItemMeta)で設定可能。
以下サイン
調べて見つからないことを質問して、「そのくらい調べろ」と言われたら それは調べが足りないとき。

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

  • (PostNo.267891)

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

投稿記事by オリゼリ » 2016年3月21日(月) 14:47

King(qpwakaba) さんが書きました:
オリゼリ さんが書きました:コマンドでプレイヤーにアイテムを与えたいのですが与えるアイテムに名前を付ける場合どうしたらよいでしょうか?


ItemStack.getItemMeta()ItemMetaを取得して
ItemMeta.setDisplayName(String)でアイテム名を設定した後
ItemStack.setItemMeta(ItemMeta)で設定可能。

出来ましたありがとうございます
質問の仕方とか直したほうがいいよってことがあったら教えていただければ嬉しいです
オリゼリ
ID:e76ccee0
大工さん
 
記事: 44
登録日時: 2015年4月29日(水) 20:13

  • (PostNo.267910)

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

投稿記事by カーボンファイバー » 2016年3月21日(月) 17:26

自作しているワールドエディタに、Undo機能をつけたいのですが、変更前のブロックの情報を保存するために
コード: 全て選択
BulidBlock[][][] = new BuildBlock[1000][100][1000]

などというような大量の配列を作成すると、OutOfMemoryになってしまいます。
どのようにOutOfMemoryを出さずに大量のブロック情報をメモリ上に保持できますか?

ちなみにこのサイズの石ブロックをWorldEditで出現させてもOutOfMemoryだすんですよね
自作WorldEditorは0.5tickたったら次の1tickまでブロックを設置しないようにすることと、配列を利用しないようにすることで、大量のブロックでもラグとOutOfMemoryをださないようにしているんですけど、これだとUndo機能が使えないので困っています。100*100*100のサイズ以上の場合はUndoを使えないようにするとか、クリップボード用のファイルを作成して、RunTaskTimer使って少しずつブロックを置いていく等の方法もあるんですけど、あまりやりたくないので・・・
学生なら、IntelliJ IDEA Ultimate EditionとかGit Hub Developer Editionとかの有料サービスがただになるので、試してみてね
アバター
カーボンファイバー
ID:ab1140b8
石炭掘り
 
記事: 181
登録日時: 2013年10月20日(日) 12:40

  • (PostNo.267921)

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

投稿記事by ucchy » 2016年3月21日(月) 19:18

カーボンファイバーさん、

工夫の仕方は、ひとそれぞれアイデア次第でいろいろできるとは思います。
私が、パッと見で思いついた、見直ししてほしいところとして、3つあります。

  • まず、カーボンファイバーさんがおっしゃっていることに矛盾があるのですが、100*100*100のサイズ と言っているのに対して、示してあるソースコードでは
    コード: 全て選択
    BulidBlock[][][] = new BuildBlock[1000][100][1000]

    となっており、1000*100*1000 です。
    このまま誤って実装しているのであれば、既にこの時点でメモリを100倍消費していることになるので、ここを直しましょう。
     
  • 次に、BulidBlock というクラスは自作しているのだと思いますが、このオブジェクトのフィールド(メンバー変数)を見直してほしいです。
    たくさんフィールドを定義すると、それだけメモリを消費するので、不要な定義は減らしていきましょう。
    フィールドに対する、インスタンスのメモリ使用量は、下記のURL先の説明が参考になるので、参照してみてください。
    http://www.limy.org/program/java/memory_usage.html
    また、フィールドに Bukkit の Location や Block や BlockState などを入れてしまっていると、これらはかなりフィールドを持っているのでメモリ使用量を使うので、何か工夫をしてみてください。
    例えば、(world, -10, 20, -30) の Location なら、"world,-10,20,-30" という文字列に置き換えて、フィールドに保存しておく、などです。
     
  • 3つ目として、100*100*100のサイズを保存するために配列を定義されているのだと思いますが、当たり前ですけれども、立方体をまるまる保存することしかできません。
    例えば、立方体の中を全て土ブロックに変更したときに、undo情報を保存するとしましょう。
    変更前のブロックで、1000個は元から土だったとしましょう。土から土に変更したundo情報は、意味がありますか?
    つまりこの場合、1000個のundo情報は省略できるはずです。
    不要な情報を省略するには、いろいろ方法はありそうですが、すぐ思いつく方法としては、HashMap<String, BuildBlock> を使うことです。
    キーにはLocation(を文字列表現にしたもの)、値の方には変更があったBuildBlockのみをputしていきます。
    実際にundoする場合は、このHashMapを全取得してすべて戻せば、変更があったところのみをundoすることができるはずです。

メモリ使用量の節約や高速化などは、なかなか難しい話題ですね。回答も付きにくくなりそうです。
(Bukkitとも、関係が無くなっていきますし・・・)
――お知らせ――
パソコンが壊れたため、買い替えるまで、プラグイン開発作業はお休みしています。簡単な質問程度ならお答えいたします。
――お知らせ――
アバター
ucchy
ID:953ffc01
ラピスラズリ収集家
 
記事: 1179
登録日時: 2012年11月07日(水) 00:08

  • (PostNo.267939)

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

投稿記事by カーボンファイバー » 2016年3月21日(月) 22:08

ucchy さんが書きました:変更前のブロックで、1000個は元から土だったとしましょう。土から土に変更したundo情報は、意味がありますか?


これは思いつきませんでした
助言ありがとうございます!

ucchy さんが書きました:(world, -10, 20, -30) の Location なら、"world,-10,20,-30" という文字列に置き換えて、フィールドに保存しておく、などです。


Stringはcharの配列で、参照はcharなので。
worldという文字列を使うより、Bukkit.getWorldして、その参照を使用するほうがメモリ使用量は低くないですか?

例えば
Object[] data = new Object[4];
data[0] = Bukkit.getWorld("World");
data[1] = new Integer(x):
data[2] = new Integer(y);
data[3] = new Integer(z);
HashMap<Object[],BuildBlock> buildSpace = new HashMap<Object[],BuildBlock>();

とやったほうが、メモリ使用量も少ないし、扱いやすいと思うのは自分だけでしょうか?
学生なら、IntelliJ IDEA Ultimate EditionとかGit Hub Developer Editionとかの有料サービスがただになるので、試してみてね
アバター
カーボンファイバー
ID:ab1140b8
石炭掘り
 
記事: 181
登録日時: 2013年10月20日(日) 12:40

  • (PostNo.267961)

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

投稿記事by ucchy » 2016年3月22日(火) 01:27

カーボンファイバー さんが書きました:
ucchy さんが書きました:(world, -10, 20, -30) の Location なら、"world,-10,20,-30" という文字列に置き換えて、フィールドに保存しておく、などです。


Stringはcharの配列で、参照はcharなので。
worldという文字列を使うより、Bukkit.getWorldして、その参照を使用するほうがメモリ使用量は低くないですか?

例えば
Object[] data = new Object[4];
data[0] = Bukkit.getWorld("World");
data[1] = new Integer(x):
data[2] = new Integer(y);
data[3] = new Integer(z);
HashMap<Object[],BuildBlock> buildSpace = new HashMap<Object[],BuildBlock>();

とやったほうが、メモリ使用量も少ないし、扱いやすいと思うのは自分だけでしょうか?


うーん、苦労したわりに、String のオブジェクトのメモリ使用量からほとんど減っていないので、そこはStringでいい気がしますが。。。

まあともかく、Location のオブジェクトをそのまま保存すると、
x座標(double)、y座標(double)、z座標(double)、yaw(float)、pitch(float) など、undoで使用しない情報を含んでいるので、
"world,-10,20,-30" のようなStringいっこにすれば、これらの 32byteのメモリ使用量を節約できる、
という話です。
――お知らせ――
パソコンが壊れたため、買い替えるまで、プラグイン開発作業はお休みしています。簡単な質問程度ならお答えいたします。
――お知らせ――
アバター
ucchy
ID:953ffc01
ラピスラズリ収集家
 
記事: 1179
登録日時: 2012年11月07日(水) 00:08

  • (PostNo.267968)

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

投稿記事by カーボンファイバー » 2016年3月22日(火) 07:50

ucchy さんが書きました:"world,-10,20,-30" のようなStringいっこにすれば、これらの 32byteのメモリ使用量を節約できる、

なるほど。丁寧な解説ありがとうございました。
学生なら、IntelliJ IDEA Ultimate EditionとかGit Hub Developer Editionとかの有料サービスがただになるので、試してみてね
アバター
カーボンファイバー
ID:ab1140b8
石炭掘り
 
記事: 181
登録日時: 2013年10月20日(日) 12:40

  • (PostNo.268151)

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

投稿記事by 青鷺火 » 2016年3月24日(木) 21:59

突然ですが、モブのAI処理について精通している方はいませんか?
試行錯誤しているのですが、挙動をうまく制御することができません。

バーションはSpigot1.9_R1です。

ソースです。
RZombieクラス
コード: 全て選択
public class RZombie extends EntityZombie
{
    public RZombie(org.bukkit.World world,Location loc)
    {
        super(((CraftWorld)world).getHandle());

        Set<Object> goalB = (Set<Object>)getPrivateField("b", PathfinderGoalSelector.class, goalSelector); goalB.clear();
        Set<Object> goalC = (Set<Object>)getPrivateField("c", PathfinderGoalSelector.class, goalSelector); goalC.clear();
        Set<Object> targetB = (Set<Object>)getPrivateField("b", PathfinderGoalSelector.class, targetSelector); targetB.clear();
        Set<Object> targetC = (Set<Object>)getPrivateField("c", PathfinderGoalSelector.class, targetSelector); targetC.clear();

        this.setBaby(true);

        this.goalSelector.a(0, new PathfinderGoalFloat(this));
        if(loc != null) this.goalSelector.a(0, new PathfinderGoalWalkToLoc(this,loc,0.5D));
    }

    public static Object getPrivateField(String fieldName, Class clazz, Object object)
    {
        Field field;
        Object o = null;
        try
        {
            field = clazz.getDeclaredField(fieldName);

            field.setAccessible(true);

            o = field.get(object);
        }
        catch(NoSuchFieldException e)
        {
            e.printStackTrace();
        }
        catch(IllegalAccessException e)
        {
            e.printStackTrace();
        }

        return o;
    }
}

PathfinderGoalWalkToLocクラス(自作AI処理)
コード: 全て選択
public class PathfinderGoalWalkToLoc extends PathfinderGoal {

    private EntityInsentient entity;
    private Navigation navigation;
    private double speed;
    private Location loc;

    public PathfinderGoalWalkToLoc(EntityInsentient entity, Location loc,
                                   double speed) {
        this.entity = entity;
        this.navigation = (Navigation) this.entity.getNavigation();
        this.speed = speed;
        this.loc = loc;
    }

    public boolean a()
    {
        return true;
    }

    public void c()
    {
        PathEntity pathEntity = this.navigation.a(loc.getX(), loc.getY(), loc.getZ());

        this.navigation.a(pathEntity, speed);

    }

}

EntityTypes列挙型
コード: 全て選択
public enum EntityTypes
{
    //NAME("Entity name", Entity ID, yourcustomclass.class);
    CUSTOM_ZOMBIE("RIUU", 54, RZombie.class); //You can add as many as you want.

    EntityTypes(String name, int id, Class<? extends Entity> custom)
    {
        addToMaps(custom, name, id);
    }

    public static org.bukkit.entity.Entity spawnEntity(Entity entity, Location loc)
    {
        entity.setLocation(loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch());
        ((CraftWorld)loc.getWorld()).getHandle().addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM);
        return entity.getBukkitEntity();
    }

    private static void addToMaps(Class clazz, String name, int id)
    {
        //getPrivateField is the method from above.
        //Remove the lines with // in front of them if you want to override default entities (You'd have to remove the default entity from the map first though).
        ((Map)RZombie.getPrivateField("c", net.minecraft.server.v1_9_R1.EntityTypes.class, null)).put(name, clazz);
        ((Map)RZombie.getPrivateField("d", net.minecraft.server.v1_9_R1.EntityTypes.class, null)).put(clazz, name);
        //((Map)RZombie.getPrivateField("e", net.minecraft.server.v1_9_R1.EntityTypes.class, null)).put(Integer.valueOf(id), clazz);
        ((Map)RZombie.getPrivateField("f", net.minecraft.server.v1_9_R1.EntityTypes.class, null)).put(clazz, Integer.valueOf(id));
        //((Map)RZombie.getPrivateField("g", net.minecraft.server.v1_9_R1.EntityTypes.class, null)).put(name, Integer.valueOf(id));
    }
}


ここを参考にさせてもらいました。
https://www.spigotmc.org/threads/tutorial-creating-custom-entities-with-pathfindergoals.18519/

PathfinderGoalWalkToLocクラスは、モブを指定の座標まで移動させるAIを記述しています。
EntityTypes列挙型からRZombieを新モブとして登録?し、スポーンさせるというような内容になっております。

質問というのは、AIを設定している処理(RZombieクラスのコンストラクラ内)
goalSelector.a(int, PathfinderGoal.class)
の仕様がいまいち分からないことです。

ソースではスポーンしたあとに指定の位置まで移動するという処理になっていますが、普通にスポーンさせても移動しませんでした。
ところが水中でスポーンさせるとちゃんと指定の位置まで移動しました。
これは1.8でも同じ挙動が起きました。

これはSpigotかマイクラの仕様なのかなとも思いましたが、情報元でそのような話を発見することはできませんでした。
私の英語力がないせいかもしれませんが…


それと、上記のaというメソッドの第一引数の整数の意味も理解できずにいます。
ソースを見ると、他のゴールの整数と比較している処理があったので優先関係か何かでしょうか…?
どなたか分かる方がいらっしゃいましたらご教示願います。
マインクラフトのプラグインを作っています。
青鷺日記
アバター
青鷺火
ID:ee9551fc
石炭掘り
 
記事: 153
登録日時: 2013年10月09日(水) 18:52

  • (PostNo.268182)

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

投稿記事by King(qpwakaba) » 2016年3月25日(金) 10:44

青鷺火 さんが書きました:それと、上記のaというメソッドの第一引数の整数の意味も理解できずにいます。
ソースを見ると、他のゴールの整数と比較している処理があったので優先関係か何かでしょうか…?
どなたか分かる方がいらっしゃいましたらご教示願います。


もしかするとご存知の方法かもしれませんし直接的な回答ではないですが…

net.minecraft.server (以下NMS)のクラスを扱うときは プラグインの知識というよりはModの知識(の応用)の範囲といえると思うので、
CraftBukkitのデコンパイルなどで理解できない部分は 同じバージョン、もしくは その1つ前のバージョン(今回でいうなら 1.9や1.8.8) あたりのmcpを参考にするのもアリかもしれません。

MCP Mapping Viewer という 難読化コードを可読化するためのマッピングを調べられるツールがあるのでそれも活用するとわかりやすいかもしれません。

(ただし CraftBukkitと MCPとでは マッピングのされ方が違うので ほとんどのクラス名は似ていることが多いですが たまにまったく異なるクラス名で登録されていることもあります。 そのあたりは 他の そのクラスを参照しているクラス を見つけてそこからたどっていくなどするとよいかもです)


ちなみに 1.8のMCPのマッピングによると 第一引数のintはpriority だそうです。
以下サイン
調べて見つからないことを質問して、「そのくらい調べろ」と言われたら それは調べが足りないとき。

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

  • (PostNo.268194)

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

投稿記事by 青鷺火 » 2016年3月25日(金) 13:22

King(qpwakaba) さんが書きました:
もしかするとご存知の方法かもしれませんし直接的な回答ではないですが…

net.minecraft.server (以下NMS)のクラスを扱うときは プラグインの知識というよりはModの知識(の応用)の範囲といえると思うので、
CraftBukkitのデコンパイルなどで理解できない部分は 同じバージョン、もしくは その1つ前のバージョン(今回でいうなら 1.9や1.8.8) あたりのmcpを参考にするのもアリかもしれません。

MCP Mapping Viewer という 難読化コードを可読化するためのマッピングを調べられるツールがあるのでそれも活用するとわかりやすいかもしれません。

(ただし CraftBukkitと MCPとでは マッピングのされ方が違うので ほとんどのクラス名は似ていることが多いですが たまにまったく異なるクラス名で登録されていることもあります。 そのあたりは 他の そのクラスを参照しているクラス を見つけてそこからたどっていくなどするとよいかもです)


ちなみに 1.8のMCPのマッピングによると 第一引数のintはpriority だそうです。


確かに普通に作るプラグインとは違う気がしますね。失礼しました。

MCP Mapping Viewerぜひ活用させてもらいます!ありがとうございました!
マインクラフトのプラグインを作っています。
青鷺日記
アバター
青鷺火
ID:ee9551fc
石炭掘り
 
記事: 153
登録日時: 2013年10月09日(水) 18:52

  • (PostNo.268417)

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

投稿記事by オリゼリ » 2016年3月27日(日) 16:03

カウントダウンのプラグインを作っています。
これはBountifulAPIを使ってアクションバーに文字を出せるようにしています。
カウントダウンするとこまでできたのですが、コマンドでカウントダウンのキャンセルの仕方が分からなくて困っています
コード: 全て選択
   @Override
    public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args){
      if(cmd.getName().equalsIgnoreCase("test")){
         new BukkitRunnable() {
            int count = 50;
             @Override
             public void run() {
                if(count > 0){
                   BountifulAPI.sendActionBarToAllPlayers("残り" + count + "");
                } else {
                   BountifulAPI.sendActionBarToAllPlayers("終了!!");
                   cancel();
                }
                count--;
             }
         }.runTaskTimer(this, 0, 20);
         return true;
      }
      return false;
   }
質問の仕方とか直したほうがいいよってことがあったら教えていただければ嬉しいです
オリゼリ
ID:e76ccee0
大工さん
 
記事: 44
登録日時: 2015年4月29日(水) 20:13

  • (PostNo.268443)

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

投稿記事by 青鷺火 » 2016年3月27日(日) 19:44

オリゼリ さんが書きました:カウントダウンのプラグインを作っています。
これはBountifulAPIを使ってアクションバーに文字を出せるようにしています。
カウントダウンするとこまでできたのですが、コマンドでカウントダウンのキャンセルの仕方が分からなくて困っています


インスタンス生成したBukkitRunnableを変数としてどこかに保存しておき、
コマンド発動時にcancelメソッドを使うといいと思いますよ。
マインクラフトのプラグインを作っています。
青鷺日記
アバター
青鷺火
ID:ee9551fc
石炭掘り
 
記事: 153
登録日時: 2013年10月09日(水) 18:52

  • (PostNo.268481)

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

投稿記事by オリゼリ » 2016年3月27日(日) 23:40

青鷺火 さんが書きました:インスタンス生成したBukkitRunnableを変数としてどこかに保存しておき、
コマンド発動時にcancelメソッドを使うといいと思いますよ。

回答ありがとうございます
変数にするまではできたと思うのですが、コマンドでキャンセルをする方法が分からないです。教えていただけないでしょうか?
現在のコード
コード: 全て選択
   @Override
    public boolean onCommand(CommandSender sender, final Command cmd, String commandLabel, String[] args){
      if(cmd.getName().equalsIgnoreCase("test")){
         BukkitTask timer = new BukkitRunnable() {
            int count = 50;
             @Override
             public void run() {
                if(count > 0){
                   BountifulAPI.sendActionBarToAllPlayers("残り" + count + "");
                  
                  
                } else {
                   BountifulAPI.sendActionBarToAllPlayers("終了!!");
                   cancel();
                }
                count--;
             }
         }.runTaskTimer(this, 0, 20);
         return true;
      }
      return false;
   }
質問の仕方とか直したほうがいいよってことがあったら教えていただければ嬉しいです
オリゼリ
ID:e76ccee0
大工さん
 
記事: 44
登録日時: 2015年4月29日(水) 20:13

  • (PostNo.268505)

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

投稿記事by 青鷺火 » 2016年3月28日(月) 09:11

オリゼリ さんが書きました:
青鷺火 さんが書きました:インスタンス生成したBukkitRunnableを変数としてどこかに保存しておき、
コマンド発動時にcancelメソッドを使うといいと思いますよ。

回答ありがとうございます
変数にするまではできたと思うのですが、コマンドでキャンセルをする方法が分からないです。教えていただけないでしょうか?

onCommandメソッド内で変数にするだけでは次にコマンドを実行したときにその変数を参照することができないので
onCommandメソッド外で変数として保存してください。

たとえばonCommandメソッドのあるクラスをMainクラスとすると非常にわかりづらく申し訳ないのですが、
コード: 全て選択
public class Main extends JavaPlugin{
   
    BukkitTask t;//←メソッド外

    @Override
    public void onEnable(){}

    @Override
    public boolean onCommand(CommandSender sender,Command cmd,String label,String[] args){
    /*onCommandメソッド内
   
    //カウント開始
    t = new BukkitRunnable(){
   
        @Override
        public void run(){}
   
    }.runTaskLater(~~);

    //ストップ
    t.cancel();

    */
    }

}


このことはJava 変数 スコープなどで調べることができるjava(というかほとんどのプログラミング言語)の基礎知識です。
頑張って勉強してください。
マインクラフトのプラグインを作っています。
青鷺日記
アバター
青鷺火
ID:ee9551fc
石炭掘り
 
記事: 153
登録日時: 2013年10月09日(水) 18:52

  • (PostNo.268541)

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

投稿記事by Hinyari_Gohan » 2016年3月28日(月) 14:45

解決出来ない問題が発生したので質問します。

Java バージョン = jdk_1.7.0_79
Spigot バージョン : CraftBukkit version git-Spigot-db6de12-18fbb24 (MC: 1.8.8) (Implementing API version 1.8.8-R0.1-SNAPSHOT)

コマンドを実行した際に手に持ったアイテムが~ならばという物を実装しているのですが、手に何も持っていない状態に「あなたは手に何も持っていません」等と表示させる為に以下のコードを使用すると、NullPointerExceptionエラーが発生します。

例:
コード: 全て選択
if ( player.getItemInHand() != null ) {
    nullでない場合のコード
} else {
    nullの場合(手に何も持っていない)のコード
( player.sendMessage("You don't have any items!"); 等)
}


上記の場合だと else の場合のコードにデッドコード(到達不可能コード)と表示されます。

実際に実装しようとしているコード
コード: 全て選択
            if ( args.length == 0 ) {
               Player p = (Player) sender;
               ItemStack i = p.getItemInHand();
               ItemMeta im = i.getItemMeta();
               int level = im.getEnchantLevel(Enchantment.DURABILITY);
               Scoreboard b = p.getScoreboard();
               Objective o = b.getObjective("rank");
               Score score = o.getScore(p);
               int rank = score.getScore();
               String name = p.getName();
               String[] array = new String[] {ChatColor.RED + "Red" , ChatColor.GOLD + "Orange",
                     ChatColor.YELLOW + "Yellow", ChatColor.GREEN + "Green", ChatColor.BLUE + "Blue",
                     ChatColor.DARK_BLUE + "Indigo", ChatColor.DARK_PURPLE + "Violet",
                     ChatColor.WHITE + "UltraViolet"};
               String wrong = "違うランクアイテムを持っています。正しいランクアイテムを持つ必要があります。";
               if ( i != null || i.getTypeId() != 0 ) {
                  if ( i.getType() == Material.INK_SACK ){
                     if ( rank == 1 ){
                        if ( level == 2 ){
                           score.setScore(2);
                           Bukkit.broadcastMessage(name + "さんが" + array[rank] + ChatColor.RESET + "ランクにランクアップしました!");
                        }
                        else {
                           p.sendMessage(wrong);
                        }
                     }
                     if ( rank == 2 ){
                        if ( level == 3 ){
                           score.setScore(3);
                           Bukkit.broadcastMessage(name + "さんが" + array[rank] + ChatColor.RESET + "ランクにランクアップしました!");
                        }
                        else {
                           p.sendMessage(wrong);
                        }
                     }
                     if ( rank == 3 ){
                        if ( level == 4 ){
                           score.setScore(4);
                           Bukkit.broadcastMessage(name + "さんが" + array[rank] + ChatColor.RESET + "ランクにランクアップしました!");
                        }
                        else {
                           p.sendMessage(wrong);
                        }
                     }
                     if ( rank == 4 ){
                        if ( level == 5 ){
                           score.setScore(5);
                           Bukkit.broadcastMessage(name + "さんが" + array[rank] + ChatColor.RESET + "ランクにランクアップしました!");
                        }
                        else {
                           p.sendMessage(wrong);
                        }
                     }
                     if ( rank == 5 ){
                        if ( level == 6 ){
                           score.setScore(6);
                           Bukkit.broadcastMessage(name + "さんが" + array[rank] + ChatColor.RESET + "ランクにランクアップしました!");
                        }
                        else {
                           p.sendMessage(wrong);
                        }
                     }
                     if ( rank == 6 ){
                        if ( level == 7 ){
                           score.setScore(7);
                           Bukkit.broadcastMessage(name + "さんが" + array[rank] + ChatColor.RESET + "ランクにランクアップしました!");
                        }
                        else {
                           p.sendMessage(wrong);
                        }
                     }
                     if ( rank == 7 ){
                        if ( level == 8 ){
                           score.setScore(8);
                           Bukkit.broadcastMessage(name + "さんが" + array[rank] + ChatColor.RESET + "ランクにランクアップしました!");
                        }
                        else {
                           p.sendMessage(wrong);
                        }
                     }
                  }
                  else {
                     if ( rank == 8 ){
                        p.sendMessage(ChatColor.LIGHT_PURPLE + "あなたは最高ランクへ達しています。");
                     }
                        else {
                           p.sendMessage("ランクアイテムを持つ必要があります。");
                        }
                  }
               }
               else {
                  p.sendMessage("アイテムを持っていません。");
               }
            }


エラー文
コード: 全て選択
 [Server thread/ERROR]: null
org.bukkit.command.CommandException: Unhandled exception executing command 'rankup' in plugin BMCPlugin v3.1
   at org.bukkit.command.PluginCommand.execute(PluginCommand.java:46) ~[spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
   at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:141) ~[spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
   at org.bukkit.craftbukkit.v1_8_R3.CraftServer.dispatchCommand(CraftServer.java:641) ~[spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
   at net.minecraft.server.v1_8_R3.PlayerConnection.handleCommand(PlayerConnection.java:1162) [spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
   at net.minecraft.server.v1_8_R3.PlayerConnection.a(PlayerConnection.java:997) [spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
   at net.minecraft.server.v1_8_R3.PacketPlayInChat.a(PacketPlayInChat.java:45) [spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
   at net.minecraft.server.v1_8_R3.PacketPlayInChat.a(PacketPlayInChat.java:1) [spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
   at net.minecraft.server.v1_8_R3.PlayerConnectionUtils$1.run(SourceFile:13) [spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
   at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [?:1.7.0_79]
   at java.util.concurrent.FutureTask.run(Unknown Source) [?:1.7.0_79]
   at net.minecraft.server.v1_8_R3.SystemUtils.a(SourceFile:44) [spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
   at net.minecraft.server.v1_8_R3.MinecraftServer.B(MinecraftServer.java:715) [spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
   at net.minecraft.server.v1_8_R3.DedicatedServer.B(DedicatedServer.java:374) [spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
   at net.minecraft.server.v1_8_R3.MinecraftServer.A(MinecraftServer.java:654) [spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
   at net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java:557) [spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
   at java.lang.Thread.run(Unknown Source) [?:1.7.0_79]
Caused by: java.lang.NullPointerException
   at com.github.gotochan.Rank.BMCRankUpCommand.onCommand(BMCRankUpCommand.java:29) ~[?:?]
   at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44) ~[spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
   ... 15 more
Hinyari_Gohanで主に活動しております。
見かけた際はどうぞよろしく。
アバター
Hinyari_Gohan
ID:9a401533
石掘り
 
記事: 96
登録日時: 2014年4月19日(土) 09:00
お住まい: 愛知県

  • (PostNo.268553)

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

投稿記事by ucchy » 2016年3月28日(月) 16:20

syunsyungotoさん、

下記の行に、実装ミスがあります。
 
コード: 全て選択
              if ( i != null || i.getTypeId() != 0 ) {

たぶん、「nullじゃないし、かつ、IDが0でもない場合は」と実装したいのだと思いますが、
現状は、「nullじゃない、または、IDが0ではない場合は」という実装になっています。
||を&&に変えてみてくださいね。
――お知らせ――
パソコンが壊れたため、買い替えるまで、プラグイン開発作業はお休みしています。簡単な質問程度ならお答えいたします。
――お知らせ――
アバター
ucchy
ID:8571d135
ラピスラズリ収集家
 
記事: 1179
登録日時: 2012年11月07日(水) 00:08

  • (PostNo.268572)

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

投稿記事by Hinyari_Gohan » 2016年3月28日(月) 17:31

ucchy さんが書きました:syunsyungotoさん、

下記の行に、実装ミスがあります。
 
コード: 全て選択
              if ( i != null || i.getTypeId() != 0 ) {

たぶん、「nullじゃないし、かつ、IDが0でもない場合は」と実装したいのだと思いますが、
現状は、「nullじゃない、または、IDが0ではない場合は」という実装になっています。
||を&&に変えてみてくださいね。


素早い返答ありがとうございます。
ご指摘を頂いた場所を修正しましたがエラーは変わらないままです。
どうすれば希望通りの動作をするでしょうか?ご教授くださると助かります。
Hinyari_Gohanで主に活動しております。
見かけた際はどうぞよろしく。
アバター
Hinyari_Gohan
ID:9a401533
石掘り
 
記事: 96
登録日時: 2014年4月19日(土) 09:00
お住まい: 愛知県

1つ前へ次へ

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

x