Cleanup some code (fix warns, fix NPE, remove duplicates)
This commit is contained in:
@@ -39,8 +39,7 @@ public final class NPCLib {
|
||||
this.npcClass = npcClass;
|
||||
|
||||
if (npcClass == null) {
|
||||
logger.severe("Failed to initiate. Your server's version ("
|
||||
+ versionName + ") is not supported");
|
||||
logger.severe("Failed to initiate. Your server's version (" + versionName + ") is not supported");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -96,7 +95,7 @@ public final class NPCLib {
|
||||
try {
|
||||
return (NPC) npcClass.getConstructors()[0].newInstance(this, text);
|
||||
} catch (Exception exception) {
|
||||
logger.warning("Failed to create NPC. Please report the following stacktrace message: " + exception.getMessage());
|
||||
logger.warning("Failed to create NPC. Please report the following stacktrace message", exception);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -54,6 +54,7 @@ public class NPCHideEvent extends Event implements Cancellable {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ public class NPCInteractEvent extends Event {
|
||||
return this.npc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ public class NPCShowEvent extends Event implements Cancellable {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
@@ -7,12 +7,13 @@ package net.jitse.npclib.api.skin;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.Scanner;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* @author Jitse Boonstra
|
||||
@@ -20,10 +21,10 @@ import java.util.Scanner;
|
||||
public class MineSkinFetcher {
|
||||
|
||||
private static final String MINESKIN_API = "https://api.mineskin.org/get/id/";
|
||||
private static final ExecutorService threadPool = Executors.newSingleThreadExecutor();
|
||||
private static final ExecutorService EXECUTOR = Executors.newSingleThreadExecutor();
|
||||
|
||||
public static void fetchSkinFromIdAsync(int id, Callback callback) {
|
||||
threadPool.execute(() -> {
|
||||
EXECUTOR.execute(() -> {
|
||||
try {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
HttpURLConnection httpURLConnection = (HttpURLConnection) new URL(MINESKIN_API + id).openConnection();
|
||||
@@ -47,7 +48,7 @@ public class MineSkinFetcher {
|
||||
|
||||
callback.call(new Skin(value, signature));
|
||||
} catch (IOException exception) {
|
||||
Bukkit.getConsoleSender().sendMessage(ChatColor.RED + "Could not fetch skin! (Id: " + id + "). Message: " + exception.getMessage());
|
||||
Bukkit.getLogger().severe("Could not fetch skin! (Id: " + id + "). Message: " + exception.getMessage());
|
||||
exception.printStackTrace();
|
||||
callback.failed();
|
||||
}
|
||||
|
||||
@@ -2,20 +2,30 @@ package net.jitse.npclib.api.state;
|
||||
|
||||
public enum NPCSlot {
|
||||
|
||||
HELMET(4),
|
||||
CHESTPLATE(3),
|
||||
LEGGINGS(2),
|
||||
BOOTS(1),
|
||||
MAINHAND(0),
|
||||
OFFHAND(5);
|
||||
HELMET(4, "HEAD"),
|
||||
CHESTPLATE(3, "CHEST"),
|
||||
LEGGINGS(2, "LEGS"),
|
||||
BOOTS(1, "FEET"),
|
||||
MAINHAND(0, "MAINHAND"),
|
||||
OFFHAND(5, "OFFHAND");
|
||||
|
||||
int slot;
|
||||
private final int slot;
|
||||
private final String nmsName;
|
||||
|
||||
NPCSlot(int slot) {
|
||||
NPCSlot(int slot, String nmsName) {
|
||||
this.slot = slot;
|
||||
this.nmsName = nmsName;
|
||||
}
|
||||
|
||||
public int getSlot() {
|
||||
return slot;
|
||||
}
|
||||
|
||||
public String getNmsName() {
|
||||
return nmsName;
|
||||
}
|
||||
|
||||
public <E extends Enum<E>> E getNmsEnum(Class<E> nmsEnumClass) {
|
||||
return Enum.valueOf(nmsEnumClass, this.nmsName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
package net.jitse.npclib.api.state;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public enum NPCState {
|
||||
|
||||
ON_FIRE((byte) 1),
|
||||
CROUCHED((byte) 2),
|
||||
INVISIBLE((byte) 32);
|
||||
|
||||
private byte b;
|
||||
private final byte b;
|
||||
|
||||
NPCState(byte b) {
|
||||
this.b = b;
|
||||
@@ -16,10 +18,15 @@ public enum NPCState {
|
||||
return b;
|
||||
}
|
||||
|
||||
public static byte getMasked(final NPCState... status) {
|
||||
byte b = 0;
|
||||
for (NPCState s : status) b |= s.getByte();
|
||||
return b;
|
||||
public static byte getMasked(NPCState... states) {
|
||||
byte mask = 0;
|
||||
for (NPCState state : states) mask |= state.getByte();
|
||||
return mask;
|
||||
}
|
||||
|
||||
public static byte getMasked(Collection<NPCState> states) {
|
||||
byte mask = 0;
|
||||
for (NPCState state : states) mask |= state.getByte();
|
||||
return mask;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ package net.jitse.npclib.api.utilities;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class Logger {
|
||||
|
||||
private final String prefix;
|
||||
@@ -21,26 +23,34 @@ public class Logger {
|
||||
}
|
||||
|
||||
public void info(String info) {
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
Bukkit.getLogger().info(prefix + info);
|
||||
log(Level.INFO, info);
|
||||
}
|
||||
|
||||
public void warning(String warning) {
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
log(Level.WARNING, warning);
|
||||
}
|
||||
|
||||
Bukkit.getLogger().warning(prefix + warning);
|
||||
public void warning(String warning, Throwable throwable) {
|
||||
log(Level.WARNING, warning, throwable);
|
||||
}
|
||||
|
||||
public void severe(String severe) {
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
log(Level.SEVERE, severe);
|
||||
}
|
||||
|
||||
Bukkit.getLogger().severe(prefix + severe);
|
||||
public void severe(String severe, Throwable throwable) {
|
||||
log(Level.SEVERE, severe, throwable);
|
||||
}
|
||||
|
||||
public void log(Level level, String message) {
|
||||
if (enabled) {
|
||||
Bukkit.getLogger().log(level, prefix + message);
|
||||
}
|
||||
}
|
||||
|
||||
public void log(Level level, String message, Throwable throwable) {
|
||||
if (enabled) {
|
||||
Bukkit.getLogger().log(level, prefix + message, throwable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public class Hologram {
|
||||
.getConstructor(PACKET_PLAY_OUT_ENTITY_METADATA_CLAZZ, int.class, DATAWATCHER_CLAZZ, boolean.class);
|
||||
|
||||
// Fields:
|
||||
private static final Reflection.FieldAccessor playerConnectionField = Reflection.getField(ENTITY_PLAYER_CLAZZ,
|
||||
private static final Reflection.FieldAccessor<?> playerConnectionField = Reflection.getField(ENTITY_PLAYER_CLAZZ,
|
||||
"playerConnection", PLAYER_CONNECTION_CLAZZ);
|
||||
|
||||
// Methods:
|
||||
@@ -92,8 +92,7 @@ public class Hologram {
|
||||
}
|
||||
|
||||
private void createPackets() {
|
||||
// TODO: Check when this method was changed (1.9 R2 is giving an exception...)
|
||||
Reflection.MethodInvoker gravityMethod = (version.isAboveOrEqual(MinecraftVersion.V1_9_R2) ?
|
||||
Reflection.MethodInvoker gravityMethod = (version.isAboveOrEqual(MinecraftVersion.V1_10_R1) ?
|
||||
Reflection.getMethod(ENTITY_CLAZZ, "setNoGravity", boolean.class) :
|
||||
Reflection.getMethod(ENTITY_ARMOR_STAND_CLAZZ, "setGravity", boolean.class));
|
||||
|
||||
@@ -213,4 +212,3 @@ public class Hologram {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,17 @@ package net.jitse.npclib.internal;
|
||||
|
||||
public enum MinecraftVersion {
|
||||
|
||||
V1_8_R1, V1_8_R2, V1_8_R3, V1_9_R1, V1_9_R2, V1_10_R1, V1_11_R1, V1_12_R1, V1_13_R1, V1_13_R2, V1_14_R1;
|
||||
|
||||
V1_8_R2,
|
||||
V1_8_R3,
|
||||
V1_9_R1,
|
||||
V1_9_R2,
|
||||
V1_10_R1,
|
||||
V1_11_R1,
|
||||
V1_12_R1,
|
||||
V1_13_R1,
|
||||
V1_13_R2,
|
||||
V1_14_R1,
|
||||
V1_15_R1;
|
||||
|
||||
public boolean isAboveOrEqual(MinecraftVersion compare) {
|
||||
return ordinal() >= compare.ordinal();
|
||||
|
||||
@@ -29,12 +29,13 @@ public abstract class NPCBase implements NPC, NPCPacketHandler {
|
||||
protected final int entityId = Integer.MAX_VALUE - NPCManager.getAllNPCs().size();
|
||||
protected final String name = uuid.toString().replace("-", "").substring(0, 10);
|
||||
protected final GameProfile gameProfile = new GameProfile(uuid, name);
|
||||
protected final Set<UUID> hasTeamRegistered = new HashSet<>();
|
||||
protected final Set<NPCState> activeStates = EnumSet.noneOf(NPCState.class);
|
||||
|
||||
private final Set<UUID> shown = new HashSet<>();
|
||||
private final Set<UUID> autoHidden = new HashSet<>();
|
||||
|
||||
protected double cosFOV = Math.cos(Math.toRadians(60));
|
||||
protected NPCState[] activeStates = new NPCState[]{};
|
||||
|
||||
protected NPCLib instance;
|
||||
protected List<String> text;
|
||||
@@ -42,8 +43,7 @@ public abstract class NPCBase implements NPC, NPCPacketHandler {
|
||||
protected Skin skin;
|
||||
protected Hologram hologram;
|
||||
|
||||
// offHand support in 1.9 R1 and later.
|
||||
protected ItemStack helmet, chestplate, leggings, boots, inHand, offHand;
|
||||
protected final Map<NPCSlot, ItemStack> items = new EnumMap<>(NPCSlot.class);
|
||||
|
||||
public NPCBase(NPCLib instance, List<String> text) {
|
||||
this.instance = instance;
|
||||
@@ -136,6 +136,7 @@ public abstract class NPCBase implements NPC, NPCPacketHandler {
|
||||
public void onLogout(Player player) {
|
||||
getAutoHidden().remove(player.getUniqueId());
|
||||
getShown().remove(player.getUniqueId()); // Don't need to use NPC#hide since the entity is not registered in the NMS server.
|
||||
hasTeamRegistered.remove(player.getUniqueId());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -165,7 +166,7 @@ public abstract class NPCBase implements NPC, NPCPacketHandler {
|
||||
sendEquipmentPackets(player);
|
||||
} else {
|
||||
if (isShown(player)) {
|
||||
throw new RuntimeException("Cannot call show method twice.");
|
||||
throw new IllegalStateException("Cannot call show method twice.");
|
||||
}
|
||||
|
||||
if (shown.contains(player.getUniqueId())) {
|
||||
@@ -206,7 +207,7 @@ public abstract class NPCBase implements NPC, NPCPacketHandler {
|
||||
sendHidePackets(player);
|
||||
} else {
|
||||
if (!shown.contains(player.getUniqueId())) {
|
||||
throw new RuntimeException("Cannot call hide method without calling NPC#show.");
|
||||
throw new IllegalStateException("Cannot call hide method without calling NPC#show.");
|
||||
}
|
||||
|
||||
shown.remove(player.getUniqueId());
|
||||
@@ -222,47 +223,15 @@ public abstract class NPCBase implements NPC, NPCPacketHandler {
|
||||
|
||||
@Override
|
||||
public boolean getState(NPCState state) {
|
||||
if (activeStates.length != 0) {
|
||||
for (int i = 0; i < activeStates.length; i++) {
|
||||
if (activeStates[i] == state) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return activeStates.contains(state);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NPC toggleState(NPCState state) {
|
||||
int inActiveStatesIndex = -1;
|
||||
if (activeStates.length == 0) { // If there're no active states, this is the first to be toggled (on).
|
||||
activeStates = new NPCState[]{state};
|
||||
} else { // Otherwise, there have been states that were toggled, check if we need to toggle something off.
|
||||
for (int i = 0; i < activeStates.length; i++) {
|
||||
if (activeStates[i] == state) { // If the state is to be toggled off, save the index so we can remove it.
|
||||
inActiveStatesIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (inActiveStatesIndex > -1) { // If there's a state to be toggled of, create a new array with all items but the one to be toggled off.
|
||||
NPCState[] newArr = new NPCState[activeStates.length - 1];
|
||||
for (int i = 0; i < newArr.length; i++) {
|
||||
if (inActiveStatesIndex == i) {
|
||||
continue;
|
||||
} else if (i < inActiveStatesIndex) {
|
||||
newArr[i] = activeStates[i];
|
||||
} else {
|
||||
newArr[i] = activeStates[i + 1];
|
||||
}
|
||||
}
|
||||
activeStates = newArr;
|
||||
} else { // Else, we need to add a state by appending our state to the array.
|
||||
NPCState[] newArr = new NPCState[activeStates.length + 1];
|
||||
System.arraycopy(activeStates, 0, newArr, 0, activeStates.length);
|
||||
newArr[activeStates.length] = state;
|
||||
activeStates = newArr;
|
||||
}
|
||||
if (activeStates.contains(state)) {
|
||||
activeStates.remove(state);
|
||||
} else {
|
||||
activeStates.add(state);
|
||||
}
|
||||
|
||||
// Send a new metadata packet to all players that can see the NPC.
|
||||
@@ -277,55 +246,16 @@ public abstract class NPCBase implements NPC, NPCPacketHandler {
|
||||
|
||||
@Override
|
||||
public ItemStack getItem(NPCSlot slot) {
|
||||
if (slot == null) {
|
||||
throw new NullPointerException("Slot cannot be null");
|
||||
}
|
||||
switch (slot) {
|
||||
case HELMET:
|
||||
return this.helmet;
|
||||
case CHESTPLATE:
|
||||
return this.chestplate;
|
||||
case LEGGINGS:
|
||||
return this.leggings;
|
||||
case BOOTS:
|
||||
return this.boots;
|
||||
case MAINHAND:
|
||||
return this.inHand;
|
||||
case OFFHAND:
|
||||
return this.offHand;
|
||||
default:
|
||||
throw new IllegalArgumentException("Entered an invalid inventory slot");
|
||||
}
|
||||
Objects.requireNonNull(slot, "Slot cannot be null");
|
||||
|
||||
return items.get(slot);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NPC setItem(NPCSlot slot, ItemStack item) {
|
||||
if (slot == null) {
|
||||
throw new NullPointerException("Slot cannot be null");
|
||||
}
|
||||
Objects.requireNonNull(slot, "Slot cannot be null");
|
||||
|
||||
switch (slot) {
|
||||
case HELMET:
|
||||
this.helmet = item;
|
||||
break;
|
||||
case CHESTPLATE:
|
||||
this.chestplate = item;
|
||||
break;
|
||||
case LEGGINGS:
|
||||
this.leggings = item;
|
||||
break;
|
||||
case BOOTS:
|
||||
this.boots = item;
|
||||
break;
|
||||
case MAINHAND:
|
||||
this.inHand = item;
|
||||
break;
|
||||
case OFFHAND:
|
||||
this.offHand = item;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Entered an invalid inventory slot");
|
||||
}
|
||||
items.put(slot, item);
|
||||
|
||||
for (UUID shownUuid : shown) {
|
||||
Player player = Bukkit.getPlayer(shownUuid);
|
||||
@@ -350,7 +280,7 @@ public abstract class NPCBase implements NPC, NPCPacketHandler {
|
||||
this.text = text;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> getText() {
|
||||
return text;
|
||||
|
||||
@@ -60,7 +60,7 @@ public class ChunkListener implements Listener {
|
||||
Chunk chunk = event.getChunk();
|
||||
|
||||
for (NPCBase npc : NPCManager.getAllNPCs()) {
|
||||
if (!isSameChunk(npc.getLocation(), chunk))
|
||||
if (npc.getLocation() == null || !isSameChunk(npc.getLocation(), chunk))
|
||||
continue; // The NPC is not in the loaded chunk.
|
||||
|
||||
// The chunk being loaded has this NPC in it. Showing it to all the players again.
|
||||
@@ -90,7 +90,6 @@ public class ChunkListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static int getChunkCoordinate(int coordinate) {
|
||||
return coordinate >> 4;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -29,8 +28,8 @@ public class PacketListener {
|
||||
private final Class<?> packetPlayInUseEntityClazz = Reflection.getMinecraftClass("PacketPlayInUseEntity");
|
||||
|
||||
// Fields:
|
||||
private final Reflection.FieldAccessor entityIdField = Reflection.getField(packetPlayInUseEntityClazz, "a", int.class);
|
||||
private final Reflection.FieldAccessor actionField = Reflection.getField(packetPlayInUseEntityClazz, "action", Object.class);
|
||||
private final Reflection.FieldAccessor<Integer> entityIdField = Reflection.getField(packetPlayInUseEntityClazz, "a", int.class);
|
||||
private final Reflection.FieldAccessor<?> actionField = Reflection.getField(packetPlayInUseEntityClazz, "action", Object.class);
|
||||
|
||||
// Prevent players from clicking at very high speeds.
|
||||
private final Set<UUID> delay = new HashSet<>();
|
||||
@@ -54,7 +53,7 @@ public class PacketListener {
|
||||
return true; // We aren't handling the packet.
|
||||
|
||||
NPCBase npc = null;
|
||||
int packetEntityId = (int) entityIdField.get(packet);
|
||||
int packetEntityId = entityIdField.get(packet);
|
||||
|
||||
// Not using streams here is an intentional choice.
|
||||
// Packet listeners is one of the few places where it is important to write optimized code.
|
||||
@@ -102,7 +101,7 @@ public class PacketListener {
|
||||
public void run() {
|
||||
Player player = eventToCall.getWhoClicked();
|
||||
this.listener.delay.remove(player.getUniqueId()); // Remove the NPC from the interact cooldown.
|
||||
if (!Objects.equals(player.getWorld(), eventToCall.getNPC().getWorld()))
|
||||
if (!player.getWorld().equals(eventToCall.getNPC().getWorld()))
|
||||
return; // If the NPC and player are not in the same world, abort!
|
||||
|
||||
double distance = player.getLocation(playerLocation).distanceSquared(eventToCall.getNPC().getLocation());
|
||||
|
||||
Reference in New Issue
Block a user