From cbe2cc09d735e1ee7ba9ac2f1e0aefdfa2085816 Mon Sep 17 00:00:00 2001 From: crashdemons Date: Tue, 25 Sep 2018 04:52:47 -0500 Subject: [PATCH] fix NPE when getOwningPlayer.getName() returns null. Add fallback methods to get the name of heads, and to detect null when that fails too (on certain custom heads). --- .../playerheads/PlayerHeadsListener.java | 45 +++++++++++-------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/src/main/java/org/shininet/bukkit/playerheads/PlayerHeadsListener.java b/src/main/java/org/shininet/bukkit/playerheads/PlayerHeadsListener.java index f134daf0..6592cf14 100644 --- a/src/main/java/org/shininet/bukkit/playerheads/PlayerHeadsListener.java +++ b/src/main/java/org/shininet/bukkit/playerheads/PlayerHeadsListener.java @@ -196,26 +196,30 @@ public void onPlayerInteract(PlayerInteractEvent event) { Block block = event.getClickedBlock(); Player player = event.getPlayer(); if (block != null && VanillaSkullType.hasBlock(block) ) { - Skull skullState = (Skull) block.getState(); if (player.hasPermission("playerheads.clickinfo")) { switch (VanillaSkullType.fromBlock(block)) { case PLAYER: + Skull skullState = (Skull) block.getState(); + boolean hadOwner=false; if (skullState.hasOwner()) { String owner = skullState.getOwningPlayer().getName(); - //String ownerStrip = ChatColor.stripColor(owner); //Unnecessary? - CustomSkullType skullType = CustomSkullType.get(owner); - if (skullType != null) { - Tools.formatMsg(player, Lang.CLICKINFO2, skullType.getDisplayName()); - if (!owner.equals(skullType.getOwner())) { - skullState.setOwner(skullType.getOwner()); - skullState.update(); + if(owner==null) owner=skullState.getOwner();//I know this is deprecated but the above method is no longer getting the owner name NBT on custom heads. + if(owner!=null){//and it can STILL be null for custom textured-heads without names, but with profile fields. + hadOwner=true;//finally we can say this is true and prevent the "that's a head" message below - otherwise we would NPE on the message. + //String ownerStrip = ChatColor.stripColor(owner); //Unnecessary? + CustomSkullType skullType = CustomSkullType.get(owner); + if (skullType != null) { + Tools.formatMsg(player, Lang.CLICKINFO2, skullType.getDisplayName()); + if (!owner.equals(skullType.getOwner())) { + skullState.setOwner(skullType.getOwner()); + skullState.update(); + } + } else { + Tools.formatMsg(player, Lang.CLICKINFO, owner); } - } else { - Tools.formatMsg(player, Lang.CLICKINFO, owner); } - } else { - Tools.formatMsg(player, Lang.CLICKINFO2, Lang.HEAD); } + if(!hadOwner) Tools.formatMsg(player, Lang.CLICKINFO2, Lang.HEAD); break; case CREEPER: Tools.formatMsg(player, Lang.CLICKINFO2, Tools.format(Lang.HEAD_CREEPER)); @@ -230,12 +234,17 @@ public void onPlayerInteract(PlayerInteractEvent event) { Tools.formatMsg(player, Lang.CLICKINFO2, Tools.format(Lang.HEAD_ZOMBIE)); break; } - } else if ((VanillaSkullType.fromBlock(block) == VanillaSkullType.PLAYER) && (skullState.hasOwner())) { - String owner = skullState.getOwningPlayer().toString(); - CustomSkullType skullType = CustomSkullType.get(owner); - if ((skullType != null) && (!owner.equals(skullType.getOwner()))) { - skullState.setOwningPlayer(Bukkit.getOfflinePlayer(skullType.getOwner())); - skullState.update(); + } else if ((VanillaSkullType.fromBlock(block) == VanillaSkullType.PLAYER)) { + Skull skullState = (Skull) block.getState(); + if(skullState.hasOwner()){ + String owner = skullState.getOwningPlayer().getName();//was toString() - this just gave the object name, not the owner. + if(owner==null) owner=skullState.getOwner();//I know this is deprecated but the above method is no longer getting the owner name NBT on custom heads. + if(owner!=null) return;//this can still be null for textured heads with no owner name but with a profile field set. + CustomSkullType skullType = CustomSkullType.get(owner); + if ((skullType != null) && (!owner.equals(skullType.getOwner()))) { + skullState.setOwningPlayer(Bukkit.getOfflinePlayer(skullType.getOwner())); + skullState.update(); + } } } }