Some code cleanup (#2414)

This commit is contained in:
Photon-GitHub 2023-06-05 15:42:55 +02:00 committed by GitHub
parent 92faaeed46
commit c1ceb472f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 536 additions and 515 deletions

View File

@ -1,17 +1,10 @@
package com.comphenix.protocol; package com.comphenix.protocol;
import java.util.ArrayList; import com.comphenix.protocol.MultipleLinesPrompt.MultipleConversationCanceller;
import java.util.Deque; import com.comphenix.protocol.error.ErrorReporter;
import java.util.HashSet; import com.comphenix.protocol.error.Report;
import java.util.Iterator; import com.comphenix.protocol.error.ReportType;
import java.util.List; import com.comphenix.protocol.events.PacketEvent;
import java.util.Set;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.conversations.Conversable; import org.bukkit.conversations.Conversable;
@ -22,11 +15,16 @@ import org.bukkit.conversations.ConversationContext;
import org.bukkit.conversations.ConversationFactory; import org.bukkit.conversations.ConversationFactory;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import com.comphenix.protocol.MultipleLinesPrompt.MultipleConversationCanceller; import javax.script.Invocable;
import com.comphenix.protocol.error.ErrorReporter; import javax.script.ScriptEngine;
import com.comphenix.protocol.error.Report; import javax.script.ScriptEngineManager;
import com.comphenix.protocol.error.ReportType; import javax.script.ScriptException;
import com.comphenix.protocol.events.PacketEvent; import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/** /**
* A command to apply JavaScript filtering to the packet command. * A command to apply JavaScript filtering to the packet command.
@ -48,7 +46,7 @@ public class CommandFilter extends CommandBase {
* @param ex - the failure. * @param ex - the failure.
* @return TRUE to keep processing this filter, FALSE to remove it. * @return TRUE to keep processing this filter, FALSE to remove it.
*/ */
public boolean handle(PacketEvent event, Filter filter, Exception ex); boolean handle(PacketEvent event, Filter filter, Exception ex);
} }
/** /**
@ -57,7 +55,7 @@ public class CommandFilter extends CommandBase {
* @author Kristian * @author Kristian
*/ */
private enum SubCommand { private enum SubCommand {
ADD, REMOVE; ADD, REMOVE
} }
/** /**
@ -206,13 +204,13 @@ public class CommandFilter extends CommandBase {
private FilterFailedHandler defaultFailedHandler; private FilterFailedHandler defaultFailedHandler;
// Currently registered filters // Currently registered filters
private List<Filter> filters = new ArrayList<Filter>(); private final Map<String, Filter> filters = new HashMap<>();
// Owner plugin // Owner plugin
private final Plugin plugin; private final Plugin plugin;
// Whether or not the command is enabled // Whether the command is enabled
private ProtocolConfig config; private final ProtocolConfig config;
// Script engine // Script engine
private ScriptEngine engine; private ScriptEngine engine;
@ -227,7 +225,7 @@ public class CommandFilter extends CommandBase {
this.uninitialized = true; this.uninitialized = true;
} }
private void initalizeScript() { private void initializeScript() {
try { try {
// First attempt // First attempt
initializeEngine(); initializeEngine();
@ -306,7 +304,7 @@ public class CommandFilter extends CommandBase {
} }
/** /**
* Determine whether or not to pass the given packet event to the packet listeners. * Determine whether to pass the given packet event to the packet listeners.
* <p> * <p>
* Uses a default filter failure handler that simply prints the error message and removes the filter. * Uses a default filter failure handler that simply prints the error message and removes the filter.
* @param event - the event. * @param event - the event.
@ -317,13 +315,13 @@ public class CommandFilter extends CommandBase {
} }
/** /**
* Determine whether or not to pass the given packet event to the packet listeners. * Determine whether to pass the given packet event to the packet listeners.
* @param event - the event. * @param event - the event.
* @param handler - failure handler. * @param handler - failure handler.
* @return TRUE if we should, FALSE otherwise. * @return TRUE if we should, FALSE otherwise.
*/ */
public boolean filterEvent(PacketEvent event, FilterFailedHandler handler) { public boolean filterEvent(PacketEvent event, FilterFailedHandler handler) {
for (Iterator<Filter> it = filters.iterator(); it.hasNext(); ) { for (Iterator<Filter> it = filters.values().iterator(); it.hasNext(); ) {
Filter filter = it.next(); Filter filter = it.next();
try { try {
@ -347,7 +345,7 @@ public class CommandFilter extends CommandBase {
// Start the engine // Start the engine
if (uninitialized) { if (uninitialized) {
uninitialized = false; uninitialized = false;
initalizeScript(); initializeScript();
} }
} }
@ -370,11 +368,12 @@ public class CommandFilter extends CommandBase {
final SubCommand command = parseCommand(args, 0); final SubCommand command = parseCommand(args, 0);
final String name = args[1]; final String name = args[1];
final String lowerCaseName = name.toLowerCase();
switch (command) { switch (command) {
case ADD: case ADD:
// Never overwrite an existing filter // Never overwrite an existing filter
if (findFilter(name) != null) { if(filters.containsKey(lowerCaseName)) {
sender.sendMessage(ChatColor.RED + "Filter " + name + " already exists. Remove it first."); sender.sendMessage(ChatColor.RED + "Filter " + name + " already exists. Remove it first.");
return true; return true;
} }
@ -402,8 +401,8 @@ public class CommandFilter extends CommandBase {
final Conversable whom = event.getContext().getForWhom(); final Conversable whom = event.getContext().getForWhom();
if (event.gracefulExit()) { if (event.gracefulExit()) {
String predicate = prompt.removeAccumulatedInput(event.getContext()); final String predicate = prompt.removeAccumulatedInput(event.getContext());
Filter filter = new Filter(name, predicate, packets); final Filter filter = new Filter(name, predicate, packets);
// Print the last line as well // Print the last line as well
whom.sendRawMessage(prompt.getPromptText(event.getContext())); whom.sendRawMessage(prompt.getPromptText(event.getContext()));
@ -412,7 +411,7 @@ public class CommandFilter extends CommandBase {
// Force early compilation // Force early compilation
filter.compile(engine); filter.compile(engine);
filters.add(filter); filters.put(lowerCaseName, filter);
whom.sendRawMessage(ChatColor.GOLD + "Added filter " + name); whom.sendRawMessage(ChatColor.GOLD + "Added filter " + name);
} catch (ScriptException e) { } catch (ScriptException e) {
e.printStackTrace(); e.printStackTrace();
@ -438,12 +437,12 @@ public class CommandFilter extends CommandBase {
break; break;
case REMOVE: case REMOVE:
Filter filter = findFilter(name); final Filter filter = filters.get(lowerCaseName);
// See if it exists before we remove it // See if it exists before we remove it
if (filter != null) { if (filter != null) {
filter.close(engine); filter.close(engine);
filters.remove(filter); filters.remove(lowerCaseName);
sender.sendMessage(ChatColor.GOLD + "Removed filter " + name); sender.sendMessage(ChatColor.GOLD + "Removed filter " + name);
} else { } else {
sender.sendMessage(ChatColor.RED + "Unable to find a filter by the name " + name); sender.sendMessage(ChatColor.RED + "Unable to find a filter by the name " + name);
@ -453,22 +452,7 @@ public class CommandFilter extends CommandBase {
return true; return true;
} }
/**
* Lookup a filter by its name.
* @param name - the filter name.
* @return The filter, or NULL if not found.
*/
private Filter findFilter(String name) {
// We'll just use a linear scan for now - we don't expect that many filters
for (Filter filter : filters) {
if (filter.getName().equalsIgnoreCase(name)) {
return filter;
}
}
return null;
}
private SubCommand parseCommand(String[] args, int index) { private SubCommand parseCommand(String[] args, int index) {
String text = args[index].toUpperCase(); String text = args[index].toUpperCase();

View File

@ -17,7 +17,21 @@
package com.comphenix.protocol; package com.comphenix.protocol;
import java.lang.reflect.InvocationTargetException; import com.comphenix.protocol.PacketType.Sender;
import com.comphenix.protocol.concurrency.PacketTypeSet;
import com.comphenix.protocol.error.ErrorReporter;
import com.comphenix.protocol.error.ReportType;
import com.comphenix.protocol.events.ListeningWhitelist;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.events.PacketListener;
import com.comphenix.protocol.utility.ChatExtensions;
import com.comphenix.protocol.utility.HexDumper;
import com.google.common.collect.MapMaker;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -30,23 +44,6 @@ import java.util.WeakHashMap;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import com.comphenix.protocol.PacketType.Sender;
import com.comphenix.protocol.concurrency.PacketTypeSet;
import com.comphenix.protocol.error.ErrorReporter;
import com.comphenix.protocol.error.Report;
import com.comphenix.protocol.error.ReportType;
import com.comphenix.protocol.events.ListeningWhitelist;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.events.PacketListener;
import com.comphenix.protocol.utility.ChatExtensions;
import com.comphenix.protocol.utility.HexDumper;
import com.google.common.collect.MapMaker;
/** /**
* Handles the "packet" debug command. * Handles the "packet" debug command.
* *
@ -56,7 +53,7 @@ class CommandPacket extends CommandBase {
public static final ReportType REPORT_CANNOT_SEND_MESSAGE = new ReportType("Cannot send chat message."); public static final ReportType REPORT_CANNOT_SEND_MESSAGE = new ReportType("Cannot send chat message.");
private enum SubCommand { private enum SubCommand {
ADD, REMOVE, NAMES, PAGE; ADD, REMOVE, NAMES, PAGE
} }
/** /**
@ -69,25 +66,25 @@ class CommandPacket extends CommandBase {
*/ */
public static final int PAGE_LINE_COUNT = 9; public static final int PAGE_LINE_COUNT = 9;
private Plugin plugin; private final Plugin plugin;
private Logger logger; private final Logger logger;
private ProtocolManager manager; private final ProtocolManager manager;
private ChatExtensions chatter; private final ChatExtensions chatter;
// The main parser // The main parser
private PacketTypeParser typeParser = new PacketTypeParser(); private final PacketTypeParser typeParser = new PacketTypeParser();
// Paged message // Paged message
private Map<CommandSender, List<String>> pagedMessage = new WeakHashMap<CommandSender, List<String>>(); private final Map<CommandSender, List<String>> pagedMessage = new WeakHashMap<CommandSender, List<String>>();
// Current registered packet types // Current registered packet types
private PacketTypeSet packetTypes = new PacketTypeSet(); private final PacketTypeSet packetTypes = new PacketTypeSet();
private PacketTypeSet extendedTypes = new PacketTypeSet(); private final PacketTypeSet extendedTypes = new PacketTypeSet();
// Compare listeners // Compare listeners
private PacketTypeSet compareTypes = new PacketTypeSet(); private final PacketTypeSet compareTypes = new PacketTypeSet();
private Map<PacketEvent, String> originalPackets = new MapMaker().weakKeys().makeMap(); private final Map<PacketEvent, String> originalPackets = new MapMaker().weakKeys().makeMap();
// The packet listener // The packet listener
private PacketListener listener; private PacketListener listener;
@ -96,7 +93,7 @@ class CommandPacket extends CommandBase {
private PacketListener compareListener; private PacketListener compareListener;
// Filter packet events // Filter packet events
private CommandFilter filter; private final CommandFilter filter;
public CommandPacket(ErrorReporter reporter, Plugin plugin, Logger logger, CommandFilter filter, ProtocolManager manager) { public CommandPacket(ErrorReporter reporter, Plugin plugin, Logger logger, CommandFilter filter, ProtocolManager manager) {
super(reporter, CommandBase.PERMISSION_ADMIN, NAME, 1); super(reporter, CommandBase.PERMISSION_ADMIN, NAME, 1);
@ -156,7 +153,7 @@ class CommandPacket extends CommandBase {
@Override @Override
protected boolean handleCommand(CommandSender sender, String[] args) { protected boolean handleCommand(CommandSender sender, String[] args) {
try { try {
Deque<String> arguments = new ArrayDeque<String>(Arrays.asList(args)); Deque<String> arguments = new ArrayDeque<>(Arrays.asList(args));
SubCommand subCommand = parseCommand(arguments); SubCommand subCommand = parseCommand(arguments);
// Commands with different parameters // Commands with different parameters
@ -247,14 +244,14 @@ class CommandPacket extends CommandBase {
} }
private void executeNamesCommand(CommandSender sender, Set<PacketType> types) { private void executeNamesCommand(CommandSender sender, Set<PacketType> types) {
List<String> messages = new ArrayList<String>(); List<String> messages = new ArrayList<>();
// Print the equivalent name of every given ID // Print the equivalent name of every given ID
for (PacketType type : types) { for (PacketType type : types) {
messages.add(ChatColor.YELLOW + type.toString()); messages.add(ChatColor.YELLOW + type.toString());
} }
if (sender instanceof Player && messages.size() > 0 && messages.size() > PAGE_LINE_COUNT) { if (sender instanceof Player && messages.size() > PAGE_LINE_COUNT) {
// Divide the messages into chuncks // Divide the messages into chuncks
pagedMessage.put(sender, messages); pagedMessage.put(sender, messages);
printPage(sender, 1); printPage(sender, 1);
@ -444,19 +441,6 @@ class CommandPacket extends CommandBase {
private SubCommand parseCommand(Deque<String> arguments) private SubCommand parseCommand(Deque<String> arguments)
{ {
final String text = arguments.remove().toLowerCase(); return SubCommand.valueOf(arguments.remove().toUpperCase());
switch (text) {
case "add":
return SubCommand.ADD;
case "remove":
return SubCommand.REMOVE;
case "names":
return SubCommand.NAMES;
case "page":
return SubCommand.PAGE;
default:
throw new IllegalArgumentException(text + " is not a valid sub command. Must be add or remove.");
}
} }
} }

View File

@ -158,7 +158,7 @@ public class PacketLogging implements CommandExecutor, PacketListener {
sender.sendMessage(ChatColor.RED + "Invalid syntax: /packetlog <protocol> <sender> <packet> [location]"); sender.sendMessage(ChatColor.RED + "Invalid syntax: /packetlog <protocol> <sender> <packet> [location]");
return true; return true;
} catch (Throwable ex) { } catch (Throwable ex) {
sender.sendMessage(ChatColor.RED + "Failed to parse command: " + ex.toString()); sender.sendMessage(ChatColor.RED + "Failed to parse command: " + ex);
return true; return true;
} }
} }
@ -173,7 +173,7 @@ public class PacketLogging implements CommandExecutor, PacketListener {
this.sendingWhitelist = ListeningWhitelist.newBuilder().types(sendingTypes).build(); this.sendingWhitelist = ListeningWhitelist.newBuilder().types(sendingTypes).build();
this.receivingWhitelist = ListeningWhitelist.newBuilder().types(receivingTypes).build(); this.receivingWhitelist = ListeningWhitelist.newBuilder().types(receivingTypes).build();
// Setup the file logger if it hasn't been already // Set up the file logger if it hasn't been already
if (location == LogLocation.FILE && fileLogger == null) { if (location == LogLocation.FILE && fileLogger == null) {
fileLogger = Logger.getLogger("ProtocolLib-FileLogging"); fileLogger = Logger.getLogger("ProtocolLib-FileLogging");
@ -270,15 +270,8 @@ public class PacketLogging implements CommandExecutor, PacketListener {
@Override @Override
public String format(LogRecord record) { public String format(LogRecord record) {
String string = formatMessage(record); final String string = formatMessage(record);
if (string.isEmpty()) { return string.isEmpty() ? LINE_SEPARATOR : MessageFormat.format(FORMAT, DATE.format(record.getMillis()), string) + LINE_SEPARATOR;
return LINE_SEPARATOR;
}
StringBuilder message = new StringBuilder();
message.append(MessageFormat.format(FORMAT, DATE.format(record.getMillis()), string));
message.append(LINE_SEPARATOR);
return message.toString();
} }
} }
} }

View File

@ -621,8 +621,8 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
*/ */
LEGACY("", ""); LEGACY("", "");
private String packetName; private final String packetName;
private String mojangName; private final String mojangName;
Protocol(String packetName, String mojangName) { Protocol(String packetName, String mojangName) {
this.packetName = packetName; this.packetName = packetName;
@ -635,17 +635,14 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
* @return The corresponding protocol. * @return The corresponding protocol.
*/ */
public static Protocol fromVanilla(Enum<?> vanilla) { public static Protocol fromVanilla(Enum<?> vanilla) {
String name = vanilla.name(); switch (vanilla.name()) {
case "HANDSHAKING": return HANDSHAKING;
if ("HANDSHAKING".equals(name)) case "PLAY": return PLAY;
return HANDSHAKING; case "STATUS": return STATUS;
if ("PLAY".equals(name)) case "LOGIN": return LOGIN;
return PLAY; default:
if ("STATUS".equals(name)) throw new IllegalArgumentException("Unrecognized vanilla enum " + vanilla);
return STATUS; }
if ("LOGIN".equals(name))
return LOGIN;
throw new IllegalArgumentException("Unrecognized vanilla enum " + vanilla);
} }
public String getPacketName() { public String getPacketName() {
@ -677,9 +674,9 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
*/ */
SERVER("Clientbound", "Out", "server"); SERVER("Clientbound", "Out", "server");
private String mojangName; private final String mojangName;
private String packetName; private final String packetName;
private String mcpName; private final String mcpName;
Sender(String mojangName, String packetName, String mcpName) { Sender(String mojangName, String packetName, String mcpName) {
this.mojangName = mojangName; this.mojangName = mojangName;
@ -709,7 +706,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
} }
/** /**
* Whether or not packets of this type must be handled asynchronously. * Whether packets of this type must be handled asynchronously.
*/ */
@Target(ElementType.FIELD) @Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@ -828,7 +825,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
* <ul> * <ul>
* <li>{@link PacketType.Play.Server#SPAWN_ENTITY} * <li>{@link PacketType.Play.Server#SPAWN_ENTITY}
* </ul> * </ul>
* However there are some valid uses for packet IDs. Please note that IDs * However, there are some valid uses for packet IDs. Please note that IDs
* change almost every Minecraft version. * change almost every Minecraft version.
* *
* @param protocol - the current protocol. * @param protocol - the current protocol.
@ -907,7 +904,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
/** /**
* Retrieve a packet type from a protocol, sender and packet ID, for pre-1.8. * Retrieve a packet type from a protocol, sender and packet ID, for pre-1.8.
* <p> * <p>
* The packet will automatically be registered if its missing. * The packet will automatically be registered if it is missing.
* @param protocol - the current protocol. * @param protocol - the current protocol.
* @param sender - the sender. * @param sender - the sender.
* @param packetId - the packet ID. Can be UNKNOWN_PACKET. * @param packetId - the packet ID. Can be UNKNOWN_PACKET.
@ -933,7 +930,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
/** /**
* Retrieve a packet type from a protocol, sender, ID, and class for 1.8+ * Retrieve a packet type from a protocol, sender, ID, and class for 1.8+
* <p> * <p>
* The packet will automatically be registered if its missing. * The packet will automatically be registered if it is missing.
* @param protocol - the current protocol. * @param protocol - the current protocol.
* @param sender - the sender. * @param sender - the sender.
* @param packetId - the packet ID. Can be UNKNOWN_PACKET. * @param packetId - the packet ID. Can be UNKNOWN_PACKET.
@ -1092,12 +1089,12 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
this.version = version; this.version = version;
this.classNames = new ArrayList<>(); this.classNames = new ArrayList<>();
for (int i = 0; i < names.length; i++) { for (String classname : names) {
if (isMcpPacketName(names[i])) { // Minecraft MCP packets if (isMcpPacketName(classname)) { // Minecraft MCP packets
classNames.add(formatMcpClassName(protocol, sender, names[i])); classNames.add(formatMcpClassName(protocol, sender, classname));
} else { } else {
classNames.add(formatClassName(protocol, sender, names[i])); classNames.add(formatClassName(protocol, sender, classname));
classNames.add(formatMojangClassName(protocol, sender, names[i])); classNames.add(formatMojangClassName(protocol, sender, classname));
} }
} }
@ -1106,7 +1103,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
/** /**
* Determine if this packet is supported on the current server. * Determine if this packet is supported on the current server.
* @return Whether or not the packet is supported. * @return Whether the packet is supported.
*/ */
public boolean isSupported() { public boolean isSupported() {
return PacketRegistry.isSupported(this); return PacketRegistry.isSupported(this);
@ -1189,7 +1186,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
} }
/** /**
* Whether or not this packet is deprecated. Deprecated packet types have either been renamed, replaced, or removed. * Whether this packet is deprecated. Deprecated packet types have either been renamed, replaced, or removed.
* Kind of like the thing they use to tell children to recycle except with packets you probably shouldn't be using. * Kind of like the thing they use to tell children to recycle except with packets you probably shouldn't be using.
* *
* @return True if the type is deprecated, false if not * @return True if the type is deprecated, false if not
@ -1204,7 +1201,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
} }
/** /**
* Whether or not the processing of this packet must take place on a thread different than the main thread. You don't * Whether the processing of this packet must take place on a thread different from the main thread. You don't
* get a choice. If this is false it's up to you. * get a choice. If this is false it's up to you.
* *
* @return True if async processing is forced, false if not. * @return True if async processing is forced, false if not.
@ -1222,7 +1219,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
} }
/** /**
* Whether or not this packet was dynamically created (i.e. we don't have it registered) * Whether this packet was dynamically created (i.e. we don't have it registered)
* @return True if dnyamic, false if not. * @return True if dnyamic, false if not.
*/ */
public boolean isDynamic() { public boolean isDynamic() {

View File

@ -1,11 +1,12 @@
package com.comphenix.protocol.collections; package com.comphenix.protocol.collections;
import com.comphenix.protocol.utility.IntegerMath;
import com.google.common.base.Preconditions;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import com.google.common.base.Preconditions;
/** /**
* Represents a very quick integer-based lookup map, with a fixed key space size. * Represents a very quick integer-based lookup map, with a fixed key space size.
* <p> * <p>
@ -13,16 +14,17 @@ import com.google.common.base.Preconditions;
* @author Kristian * @author Kristian
*/ */
public class IntegerMap<T> { public class IntegerMap<T> {
private T[] array; private T[] array;
private int size; private int size;
/** /**
* Construct a new integer map with a default capacity. * Construct a new integer map with a default capacity.
*/ */
public IntegerMap() { public IntegerMap() {
this(8); this(8);
} }
/** /**
* Construct a new integer map with a given capacity. * Construct a new integer map with a given capacity.
* @param initialCapacity - the capacity. * @param initialCapacity - the capacity.
@ -42,15 +44,14 @@ public class IntegerMap<T> {
*/ */
public T put(int key, T value) { public T put(int key, T value) {
ensureCapacity(key); ensureCapacity(key);
T old = array[key]; T old = array[key];
array[key] = Preconditions.checkNotNull(value, "value cannot be NULL"); array[key] = Preconditions.checkNotNull(value, "value cannot be NULL");
if (old == null) if (old == null) ++size;
size++;
return old; return old;
} }
/** /**
* Remove an association from the map. * Remove an association from the map.
* @param key - the key of the association to remove. * @param key - the key of the association to remove.
@ -59,33 +60,27 @@ public class IntegerMap<T> {
public T remove(int key) { public T remove(int key) {
T old = array[key]; T old = array[key];
array[key] = null; array[key] = null;
if (old != null) if (old != null) --size;
size--;
return old; return old;
} }
/** /**
* Resize the backing array to fit the given key. * Resize the backing array to fit the given key.
* @param key - the key. * @param key - the key.
*/ */
protected void ensureCapacity(int key) { protected void ensureCapacity(int key) {
int newLength = array.length;
// Don't resize if the key fits // Don't resize if the key fits
if (key < 0) if (key < 0) throw new IllegalArgumentException("Negative key values are not permitted.");
throw new IllegalArgumentException("Negative key values are not permitted."); if (key < array.length) return;
if (key < newLength)
return; // Fast calculation of the new size.
// See IntMath#ceilingPowerOfTwo in newer guava versions.
while (newLength <= key) { int newLength = IntegerMath.nextPowerOfTwo(key);
int next = newLength * 2;
// Handle overflow
newLength = next > newLength ? next : Integer.MAX_VALUE;
}
this.array = Arrays.copyOf(array, newLength); this.array = Arrays.copyOf(array, newLength);
} }
/** /**
* Retrieve the number of mappings in this map. * Retrieve the number of mappings in this map.
* @return The number of mapping. * @return The number of mapping.
@ -100,11 +95,9 @@ public class IntegerMap<T> {
* @return The value, or NULL if not found. * @return The value, or NULL if not found.
*/ */
public T get(int key) { public T get(int key) {
if (key >= 0 && key < array.length) return key >= 0 && key < array.length ? array[key] : null;
return array[key];
return null;
} }
/** /**
* Determine if the given key exists in the map. * Determine if the given key exists in the map.
* @param key - the key to check. * @param key - the key to check.
@ -113,14 +106,14 @@ public class IntegerMap<T> {
public boolean containsKey(int key) { public boolean containsKey(int key) {
return get(key) != null; return get(key) != null;
} }
/** /**
* Convert the current map to an Integer map. * Convert the current map to an Integer map.
* @return The Integer map. * @return The Integer map.
*/ */
public Map<Integer, Object> toMap() { public Map<Integer, Object> toMap() {
final Map<Integer, Object> map = new HashMap<>(); final Map<Integer, Object> map = new HashMap<>();
for (int i = 0; i < array.length; i++) { for (int i = 0; i < array.length; i++) {
if (array[i] != null) { if (array[i] != null) {
map.put(i, array[i]); map.put(i, array[i]);

View File

@ -38,7 +38,7 @@ public abstract class AbstractConcurrentListenerMultimap<T> {
// The core of our map // The core of our map
private final ConcurrentMap<PacketType, SortedCopyOnWriteArray<PrioritizedListener<T>>> mapListeners; private final ConcurrentMap<PacketType, SortedCopyOnWriteArray<PrioritizedListener<T>>> mapListeners;
public AbstractConcurrentListenerMultimap() { protected AbstractConcurrentListenerMultimap() {
this.mapListeners = new ConcurrentHashMap<>(); this.mapListeners = new ConcurrentHashMap<>();
} }
@ -49,21 +49,21 @@ public abstract class AbstractConcurrentListenerMultimap<T> {
* @param whitelist - the packet whitelist to use. * @param whitelist - the packet whitelist to use.
*/ */
public void addListener(T listener, ListeningWhitelist whitelist) { public void addListener(T listener, ListeningWhitelist whitelist) {
PrioritizedListener<T> prioritized = new PrioritizedListener<>(listener, whitelist.getPriority()); final PrioritizedListener<T> prioritized = new PrioritizedListener<>(listener, whitelist.getPriority());
for (PacketType type : whitelist.getTypes()) { for (PacketType type : whitelist.getTypes()) {
this.addListener(type, prioritized); this.addListener(type, prioritized);
} }
} }
// Add the listener to a specific packet notifcation list // Add the listener to a specific packet notification list
private void addListener(PacketType type, PrioritizedListener<T> listener) { private void addListener(PacketType type, PrioritizedListener<T> listener) {
SortedCopyOnWriteArray<PrioritizedListener<T>> list = this.mapListeners.get(type); SortedCopyOnWriteArray<PrioritizedListener<T>> list = this.mapListeners.get(type);
// We don't want to create this for every lookup // We don't want to create this for every lookup
if (list == null) { if (list == null) {
// It would be nice if we could use a PriorityBlockingQueue, but it doesn't preseve iterator order, // It would be nice if we could use a PriorityBlockingQueue, but it doesn't preserve iterator order,
// which is a essential feature for our purposes. // which is an essential feature for our purposes.
final SortedCopyOnWriteArray<PrioritizedListener<T>> value = new SortedCopyOnWriteArray<PrioritizedListener<T>>(); final SortedCopyOnWriteArray<PrioritizedListener<T>> value = new SortedCopyOnWriteArray<>();
// We may end up creating multiple multisets, but we'll agree on which to use // We may end up creating multiple multisets, but we'll agree on which to use
list = this.mapListeners.putIfAbsent(type, value); list = this.mapListeners.putIfAbsent(type, value);
@ -85,24 +85,21 @@ public abstract class AbstractConcurrentListenerMultimap<T> {
* @return Every packet ID that was removed due to no listeners. * @return Every packet ID that was removed due to no listeners.
*/ */
public List<PacketType> removeListener(T listener, ListeningWhitelist whitelist) { public List<PacketType> removeListener(T listener, ListeningWhitelist whitelist) {
List<PacketType> removedPackets = new ArrayList<PacketType>(); List<PacketType> removedPackets = new ArrayList<>();
// Again, not terribly efficient. But adding or removing listeners should be a rare event. // Again, not terribly efficient. But adding or removing listeners should be a rare event.
for (PacketType type : whitelist.getTypes()) { for (PacketType type : whitelist.getTypes()) {
SortedCopyOnWriteArray<PrioritizedListener<T>> list = this.mapListeners.get(type); SortedCopyOnWriteArray<PrioritizedListener<T>> list = this.mapListeners.get(type);
// Remove any listeners if(list == null || list.isEmpty()) continue;
if (list != null) {
// Don't remove from newly created lists
if (list.size() > 0) {
// Remove this listener. Note that priority is generally ignored.
list.remove(new PrioritizedListener<T>(listener, whitelist.getPriority()));
if (list.size() == 0) { // Remove any listeners
this.mapListeners.remove(type); // Remove this listener. Note that priority is generally ignored.
removedPackets.add(type); list.remove(new PrioritizedListener<T>(listener, whitelist.getPriority()));
}
} if (list.isEmpty()) {
this.mapListeners.remove(type);
removedPackets.add(type);
} }
// Move on to the next // Move on to the next
} }

View File

@ -17,15 +17,15 @@
package com.comphenix.protocol.concurrency; package com.comphenix.protocol.concurrency;
import com.google.common.base.Objects;
import com.google.common.collect.Range;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.NavigableMap; import java.util.NavigableMap;
import java.util.Set; import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;
import com.google.common.base.Objects;
import com.google.common.collect.Range;
/** /**
* Represents a generic store of intervals and associated values. No two intervals * Represents a generic store of intervals and associated values. No two intervals
* can overlap in this representation. * can overlap in this representation.
@ -49,8 +49,8 @@ public abstract class AbstractIntervalTree<TKey extends Comparable<TKey>, TValue
* Represents a range and a value in this interval tree. * Represents a range and a value in this interval tree.
*/ */
public class Entry implements Map.Entry<Range<TKey>, TValue> { public class Entry implements Map.Entry<Range<TKey>, TValue> {
private EndPoint left; private final EndPoint left;
private EndPoint right; private final EndPoint right;
Entry(EndPoint left, EndPoint right) { Entry(EndPoint left, EndPoint right) {
if (left == null) if (left == null)
@ -133,7 +133,7 @@ public abstract class AbstractIntervalTree<TKey extends Comparable<TKey>, TValue
} }
// To quickly look up ranges we'll index them by endpoints // To quickly look up ranges we'll index them by endpoints
protected NavigableMap<TKey, EndPoint> bounds = new TreeMap<TKey, EndPoint>(); protected NavigableMap<TKey, EndPoint> bounds = new TreeMap<>();
/** /**
* Removes every interval that intersects with the given range. * Removes every interval that intersects with the given range.
@ -163,8 +163,8 @@ public abstract class AbstractIntervalTree<TKey extends Comparable<TKey>, TValue
EndPoint previous = null; EndPoint previous = null;
EndPoint next = null; EndPoint next = null;
Set<Entry> resized = new HashSet<Entry>(); Set<Entry> resized = new HashSet<>();
Set<Entry> removed = new HashSet<Entry>(); Set<Entry> removed = new HashSet<>();
// Remove the previous element too. A close end-point must be preceded by an OPEN end-point. // Remove the previous element too. A close end-point must be preceded by an OPEN end-point.
if (first != null && first.state == State.CLOSE) { if (first != null && first.state == State.CLOSE) {
@ -315,7 +315,7 @@ public abstract class AbstractIntervalTree<TKey extends Comparable<TKey>, TValue
*/ */
public Set<Entry> entrySet() { public Set<Entry> entrySet() {
// Don't mind the Java noise // Don't mind the Java noise
Set<Entry> result = new HashSet<Entry>(); Set<Entry> result = new HashSet<>();
getEntries(result, bounds); getEntries(result, bounds);
return result; return result;
} }

View File

@ -17,18 +17,18 @@
package com.comphenix.protocol.concurrency; package com.comphenix.protocol.concurrency;
import java.util.Collection;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
import com.comphenix.protocol.utility.SafeCacheBuilder; import com.comphenix.protocol.utility.SafeCacheBuilder;
import com.google.common.cache.CacheLoader; import com.google.common.cache.CacheLoader;
import com.google.common.cache.RemovalCause; import com.google.common.cache.RemovalCause;
import com.google.common.cache.RemovalListener; import com.google.common.cache.RemovalListener;
import com.google.common.cache.RemovalNotification; import com.google.common.cache.RemovalNotification;
import java.util.Collection;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
/** /**
* A map that supports blocking on read operations. Null keys are not supported. * A map that supports blocking on read operations. Null keys are not supported.
* <p> * <p>
@ -80,7 +80,7 @@ public class BlockingHashMap<TKey, TValue> {
build(BlockingHashMap.<TKey, TValue> newInvalidCacheLoader()); build(BlockingHashMap.<TKey, TValue> newInvalidCacheLoader());
// Normal concurrent hash map // Normal concurrent hash map
locks = new ConcurrentHashMap<TKey, Object>(); locks = new ConcurrentHashMap<>();
} }
/** /**
@ -90,7 +90,7 @@ public class BlockingHashMap<TKey, TValue> {
* @return The created map. * @return The created map.
*/ */
public static <TKey, TValue> BlockingHashMap<TKey, TValue> create() { public static <TKey, TValue> BlockingHashMap<TKey, TValue> create() {
return new BlockingHashMap<TKey, TValue>(); return new BlockingHashMap<>();
} }
/** /**

View File

@ -1,14 +1,12 @@
package com.comphenix.protocol.concurrency; package com.comphenix.protocol.concurrency;
import com.comphenix.protocol.utility.SafeCacheBuilder; import com.comphenix.protocol.utility.SafeCacheBuilder;
import com.comphenix.protocol.utility.Util;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.cache.CacheLoader; import com.google.common.cache.CacheLoader;
import com.google.common.cache.RemovalListener; import com.google.common.cache.RemovalListener;
import com.google.common.collect.AbstractIterator; import com.google.common.collect.AbstractIterator;
import com.google.common.util.concurrent.UncheckedExecutionException; import com.google.common.util.concurrent.UncheckedExecutionException;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -304,7 +302,7 @@ public class ConcurrentPlayerMap<TValue> extends AbstractMap<Player, TValue> imp
source.remove(); source.remove();
keyLookup.remove(entry.getKey()); keyLookup.remove(entry.getKey());
} else { } else {
return new SimpleEntry<Player, TValue>(player, entry.getValue()); return new SimpleEntry<>(player, entry.getValue());
} }
} }
return endOfData(); return endOfData();

View File

@ -18,7 +18,6 @@
package com.comphenix.protocol.error; package com.comphenix.protocol.error;
import com.comphenix.protocol.error.Report.ReportBuilder; import com.comphenix.protocol.error.Report.ReportBuilder;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
/** /**
@ -33,7 +32,7 @@ public interface ErrorReporter {
* @param methodName - name of the caller method. * @param methodName - name of the caller method.
* @param error - the exception itself. * @param error - the exception itself.
*/ */
public abstract void reportMinimal(Plugin sender, String methodName, Throwable error); void reportMinimal(Plugin sender, String methodName, Throwable error);
/** /**
* Prints a small minimal error report regarding an exception from another plugin. * Prints a small minimal error report regarding an exception from another plugin.
@ -42,7 +41,7 @@ public interface ErrorReporter {
* @param error - the exception itself. * @param error - the exception itself.
* @param parameters - any relevant parameters to print. * @param parameters - any relevant parameters to print.
*/ */
public abstract void reportMinimal(Plugin sender, String methodName, Throwable error, Object... parameters); void reportMinimal(Plugin sender, String methodName, Throwable error, Object... parameters);
/** /**
* Prints a debug message from the current sender. * Prints a debug message from the current sender.
@ -51,40 +50,40 @@ public interface ErrorReporter {
* @param sender - the sender. * @param sender - the sender.
* @param report - the report. * @param report - the report.
*/ */
public abstract void reportDebug(Object sender, Report report); void reportDebug(Object sender, Report report);
/** /**
* Prints a debug message from the current sender. * Prints a debug message from the current sender.
* @param sender - the sender. * @param sender - the sender.
* @param builder - the report builder. * @param builder - the report builder.
*/ */
public abstract void reportDebug(Object sender, ReportBuilder builder); void reportDebug(Object sender, ReportBuilder builder);
/** /**
* Prints a warning message from the current plugin. * Prints a warning message from the current plugin.
* @param sender - the object containing the caller method. * @param sender - the object containing the caller method.
* @param report - an error report to include. * @param report - an error report to include.
*/ */
public abstract void reportWarning(Object sender, Report report); void reportWarning(Object sender, Report report);
/** /**
* Prints a warning message from the current plugin. * Prints a warning message from the current plugin.
* @param sender - the object containing the caller method. * @param sender - the object containing the caller method.
* @param reportBuilder - an error report builder that will be used to get the report. * @param reportBuilder - an error report builder that will be used to get the report.
*/ */
public abstract void reportWarning(Object sender, ReportBuilder reportBuilder); void reportWarning(Object sender, ReportBuilder reportBuilder);
/** /**
* Prints a detailed error report about an unhandled exception. * Prints a detailed error report about an unhandled exception.
* @param sender - the object containing the caller method. * @param sender - the object containing the caller method.
* @param report - an error report to include. * @param report - an error report to include.
*/ */
public abstract void reportDetailed(Object sender, Report report); void reportDetailed(Object sender, Report report);
/** /**
* Prints a detailed error report about an unhandled exception. * Prints a detailed error report about an unhandled exception.
* @param sender - the object containing the caller method. * @param sender - the object containing the caller method.
* @param reportBuilder - an error report builder that will be used to get the report. * @param reportBuilder - an error report builder that will be used to get the report.
*/ */
public abstract void reportDetailed(Object sender, ReportBuilder reportBuilder); void reportDetailed(Object sender, ReportBuilder reportBuilder);
} }

View File

@ -1254,16 +1254,16 @@ public abstract class AbstractStructure {
* @author dmulloy2 * @author dmulloy2
*/ */
private static class NBTComponentConverter implements EquivalentConverter<WrappedChatComponent[]> { private static class NBTComponentConverter implements EquivalentConverter<WrappedChatComponent[]> {
private EquivalentConverter<NbtBase<?>> nbtConverter = BukkitConverters.getNbtConverter(); private final EquivalentConverter<NbtBase<?>> nbtConverter = BukkitConverters.getNbtConverter();
private final int lines = 4; private static final int LINES = 4;
@Override @Override
public WrappedChatComponent[] getSpecific(Object generic) { public WrappedChatComponent[] getSpecific(Object generic) {
NbtBase<?> nbtBase = nbtConverter.getSpecific(generic); final NbtBase<?> nbtBase = nbtConverter.getSpecific(generic);
NbtCompound compound = (NbtCompound) nbtBase; final NbtCompound compound = (NbtCompound) nbtBase;
WrappedChatComponent[] components = new WrappedChatComponent[lines]; final WrappedChatComponent[] components = new WrappedChatComponent[LINES];
for (int i = 0; i < lines; i++) { for (int i = 0; i < LINES; i++) {
if (compound.containsKey("Text" + (i + 1))) { if (compound.containsKey("Text" + (i + 1))) {
components[i] = WrappedChatComponent.fromJson(compound.getString("Text" + (i + 1))); components[i] = WrappedChatComponent.fromJson(compound.getString("Text" + (i + 1)));
} else { } else {
@ -1278,7 +1278,7 @@ public abstract class AbstractStructure {
public Object getGeneric(WrappedChatComponent[] specific) { public Object getGeneric(WrappedChatComponent[] specific) {
NbtCompound compound = NbtFactory.ofCompound(""); NbtCompound compound = NbtFactory.ofCompound("");
for (int i = 0; i < lines; i++) { for (int i = 0; i < LINES; i++) {
WrappedChatComponent component; WrappedChatComponent component;
if (i < specific.length && specific[i] != null) { if (i < specific.length && specific[i] != null) {
component = specific[i]; component = specific[i];

View File

@ -24,7 +24,7 @@ package com.comphenix.protocol.events;
*/ */
public enum ListenerPriority { public enum ListenerPriority {
/** /**
* Event call is of very low importance and should be ran first, to allow * Event call is of very low importance and should be run first, to allow
* other plugins to further customise the outcome. * other plugins to further customise the outcome.
*/ */
LOWEST(0), LOWEST(0),
@ -33,7 +33,7 @@ public enum ListenerPriority {
*/ */
LOW(1), LOW(1),
/** /**
* Event call is neither important or unimportant, and may be ran normally. * Event call is neither important nor unimportant, and may be run normally.
*/ */
NORMAL(2), NORMAL(2),
/** /**
@ -54,13 +54,13 @@ public enum ListenerPriority {
private final int slot; private final int slot;
private ListenerPriority(int slot) { ListenerPriority(int slot) {
this.slot = slot; this.slot = slot;
} }
/** /**
* A low slot represents a low priority. * A low slot represents a low priority.
* @return Integer representation of this priorty. * @return Integer representation of this priority.
*/ */
public int getSlot() { public int getSlot() {
return slot; return slot;

View File

@ -14,13 +14,13 @@ public interface PacketOutputHandler {
* Higher priority is executed before lower. * Higher priority is executed before lower.
* @return The handler priority. * @return The handler priority.
*/ */
public ListenerPriority getPriority(); ListenerPriority getPriority();
/** /**
* The plugin that owns this output handler. * The plugin that owns this output handler.
* @return The owner plugin. * @return The owner plugin.
*/ */
public Plugin getPlugin(); Plugin getPlugin();
/** /**
* Invoked when a given packet is to be written to the output stream. * Invoked when a given packet is to be written to the output stream.
@ -33,5 +33,5 @@ public interface PacketOutputHandler {
* @param buffer - the data that is currently scheduled to be outputted. * @param buffer - the data that is currently scheduled to be outputted.
* @return The modified byte array to write. NULL is not permitted. * @return The modified byte array to write. NULL is not permitted.
*/ */
public byte[] handle(PacketEvent event, byte[] buffer); byte[] handle(PacketEvent event, byte[] buffer);
} }

View File

@ -11,7 +11,7 @@ public interface PacketPostListener {
* Retrieve the plugin this listener belongs to. * Retrieve the plugin this listener belongs to.
* @return The assoicated plugin. * @return The assoicated plugin.
*/ */
public Plugin getPlugin(); Plugin getPlugin();
/** /**
* Invoked after a packet has been sent or received. * Invoked after a packet has been sent or received.
@ -19,5 +19,5 @@ public interface PacketPostListener {
* Note that this is invoked asynchronously. * Note that this is invoked asynchronously.
* @param event - the packet event. * @param event - the packet event.
*/ */
public void onPostEvent(PacketEvent event); void onPostEvent(PacketEvent event);
} }

View File

@ -26,6 +26,7 @@ import com.comphenix.protocol.wrappers.BukkitConverters;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.primitives.Primitives; import com.google.common.primitives.Primitives;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.util.List; import java.util.List;
@ -42,7 +43,7 @@ public class PacketConstructor {
* <p> * <p>
* Remember to call withPacket(). * Remember to call withPacket().
*/ */
public static PacketConstructor DEFAULT = new PacketConstructor(null); public static final PacketConstructor DEFAULT = new PacketConstructor(null);
// The constructor method that's actually responsible for creating the packet // The constructor method that's actually responsible for creating the packet
private final Constructor<?> constructorMethod; private final Constructor<?> constructorMethod;
@ -56,7 +57,7 @@ public class PacketConstructor {
private PacketConstructor(Constructor<?> constructorMethod) { private PacketConstructor(Constructor<?> constructorMethod) {
this.constructorMethod = constructorMethod; this.constructorMethod = constructorMethod;
this.unwrappers = Lists.newArrayList((Unwrapper) new BukkitUnwrapper(new RethrowErrorReporter())); this.unwrappers = Lists.newArrayList(new BukkitUnwrapper(new RethrowErrorReporter()));
this.unwrappers.addAll(BukkitConverters.getUnwrappers()); this.unwrappers.addAll(BukkitConverters.getUnwrappers());
} }

View File

@ -28,8 +28,8 @@ import com.google.common.primitives.Ints;
*/ */
public class PrioritizedListener<TListener> implements Comparable<PrioritizedListener<TListener>> { public class PrioritizedListener<TListener> implements Comparable<PrioritizedListener<TListener>> {
private TListener listener; private final TListener listener;
private ListenerPriority priority; private final ListenerPriority priority;
public PrioritizedListener(TListener listener, ListenerPriority priority) { public PrioritizedListener(TListener listener, ListenerPriority priority) {
this.listener = listener; this.listener = listener;

View File

@ -17,6 +17,9 @@
package com.comphenix.protocol.reflect; package com.comphenix.protocol.reflect;
import com.comphenix.protocol.reflect.accessors.Accessors;
import com.google.common.primitives.Primitives;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
@ -25,9 +28,6 @@ import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import com.comphenix.protocol.reflect.accessors.Accessors;
import com.google.common.primitives.Primitives;
/** /**
* Used to print the content of an arbitrary class. * Used to print the content of an arbitrary class.
* *
@ -105,7 +105,7 @@ public class PrettyPrinter {
} }
StringBuilder output = new StringBuilder(); StringBuilder output = new StringBuilder();
Set<Object> previous = new HashSet<Object>(); Set<Object> previous = new HashSet<>();
// Start and stop // Start and stop
output.append("{ "); output.append("{ ");
@ -262,7 +262,7 @@ public class PrettyPrinter {
} else if (type.isPrimitive() || Primitives.isWrapperType(type)) { } else if (type.isPrimitive() || Primitives.isWrapperType(type)) {
output.append(value); output.append(value);
} else if (type == String.class || hierachyIndex <= 0) { } else if (type == String.class || hierachyIndex <= 0) {
output.append("\"" + value + "\""); output.append("\"").append(value).append("\"");
} else if (type.isArray()) { } else if (type.isArray()) {
printArray(output, value, type, stop, previous, hierachyIndex, printer); printArray(output, value, type, stop, previous, hierachyIndex, printer);
} else if (Iterable.class.isAssignableFrom(type)) { } else if (Iterable.class.isAssignableFrom(type)) {
@ -271,7 +271,7 @@ public class PrettyPrinter {
printMap(output, (Map<Object, Object>) value, type, stop, previous, hierachyIndex, printer); printMap(output, (Map<Object, Object>) value, type, stop, previous, hierachyIndex, printer);
} else if (ClassLoader.class.isAssignableFrom(type) || previous.contains(value)) { } else if (ClassLoader.class.isAssignableFrom(type) || previous.contains(value)) {
// Don't print previous objects // Don't print previous objects
output.append("\"" + value + "\""); output.append("\"").append(value).append("\"");
} else { } else {
output.append("{ "); output.append("{ ");
printObject(output, value, value.getClass(), stop, previous, hierachyIndex, true, printer); printObject(output, value, value.getClass(), stop, previous, hierachyIndex, true, printer);

View File

@ -24,11 +24,11 @@ package com.comphenix.protocol.reflect.cloning;
*/ */
public interface Cloner { public interface Cloner {
/** /**
* Determine whether or not the current cloner can clone the given object. * Determine whether the current cloner can clone the given object.
* @param source - the object that is being considered. * @param source - the object that is being considered.
* @return TRUE if this cloner can actually clone the given object, FALSE otherwise. * @return TRUE if this cloner can actually clone the given object, FALSE otherwise.
*/ */
public boolean canClone(Object source); boolean canClone(Object source);
/** /**
* Perform the clone. * Perform the clone.
@ -38,5 +38,5 @@ public interface Cloner {
* @return A cloned value. * @return A cloned value.
* @throws IllegalArgumentException If this cloner cannot perform the clone. * @throws IllegalArgumentException If this cloner cannot perform the clone.
*/ */
public Object clone(Object source); Object clone(Object source);
} }

View File

@ -0,0 +1,24 @@
package com.comphenix.protocol.utility;
public final class IntegerMath
{
// The largest positive int in java is 2^31 - 1, so 2^30 is the largest positive int that is a power of 2.
public static final int MAX_SIGNED_POWER_OF_TWO = 1 << (Integer.SIZE - 2);
private IntegerMath() {}
/**
* This calculates the smallest y for which 2^y > x
*
* @param x the number that the next power of 2 should be calculated for.
*
* @return If the next power of two would be larger than {@link #MAX_SIGNED_POWER_OF_TWO}, this method returns {@link Integer#MAX_VALUE}
*
* @see com.google.common.math.IntMath for a similar version, that is not yet implemented in the guava of Minecraft 1.8.
*/
public static int nextPowerOfTwo(int x)
{
if (x > MAX_SIGNED_POWER_OF_TWO) return Integer.MAX_VALUE;
return 1 << -Integer.numberOfLeadingZeros(x - 1);
}
}

View File

@ -1,22 +1,27 @@
package com.comphenix.protocol.wrappers; package com.comphenix.protocol.wrappers;
import com.comphenix.protocol.reflect.ExactReflection;
import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import com.comphenix.protocol.PacketType; import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.PacketType.Protocol; import com.comphenix.protocol.PacketType.Protocol;
import com.comphenix.protocol.ProtocolLogger; import com.comphenix.protocol.ProtocolLogger;
import com.comphenix.protocol.reflect.EquivalentConverter; import com.comphenix.protocol.reflect.EquivalentConverter;
import com.comphenix.protocol.reflect.ExactReflection;
import com.comphenix.protocol.reflect.FuzzyReflection; import com.comphenix.protocol.reflect.FuzzyReflection;
import com.comphenix.protocol.reflect.accessors.Accessors; import com.comphenix.protocol.reflect.accessors.Accessors;
import com.comphenix.protocol.utility.MinecraftVersion;
import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.utility.MinecraftVersion;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import java.lang.reflect.Field;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/** /**
* Represents a generic enum converter. * Represents a generic enum converter.
* @author Kristian * @author Kristian
@ -166,7 +171,7 @@ public abstract class EnumWrappers {
RELEASE_USE_ITEM, RELEASE_USE_ITEM,
SWAP_HELD_ITEMS("SWAP_ITEM_WITH_OFFHAND"); SWAP_HELD_ITEMS("SWAP_ITEM_WITH_OFFHAND");
String[] aliases; final String[] aliases;
PlayerDigType(String... aliases) { PlayerDigType(String... aliases) {
this.aliases = aliases; this.aliases = aliases;
} }
@ -187,7 +192,7 @@ public abstract class EnumWrappers {
OPEN_INVENTORY, OPEN_INVENTORY,
START_FALL_FLYING; START_FALL_FLYING;
String[] aliases; final String[] aliases;
PlayerAction(String... aliases) { PlayerAction(String... aliases) {
this.aliases = aliases; this.aliases = aliases;
} }
@ -866,11 +871,11 @@ public abstract class EnumWrappers {
* Enums whose name has changed across NMS versions. Enums using this must also implement {@link AliasedEnum} * Enums whose name has changed across NMS versions. Enums using this must also implement {@link AliasedEnum}
*/ */
public static class AliasedEnumConverter<T extends Enum<T> & AliasedEnum> implements EquivalentConverter<T> { public static class AliasedEnumConverter<T extends Enum<T> & AliasedEnum> implements EquivalentConverter<T> {
private Class<?> genericType; private final Class<?> genericType;
private Class<T> specificType; private final Class<T> specificType;
private Map<T, Object> genericMap = new ConcurrentHashMap<>(); private final Map<T, Object> genericMap = new ConcurrentHashMap<>();
private Map<Object, T> specificMap = new ConcurrentHashMap<>(); private final Map<Object, T> specificMap = new ConcurrentHashMap<>();
public AliasedEnumConverter(Class<?> genericType, Class<T> specificType) { public AliasedEnumConverter(Class<?> genericType, Class<T> specificType) {
this.genericType = genericType; this.genericType = genericType;
@ -980,8 +985,8 @@ public abstract class EnumWrappers {
} }
public static class IndexedEnumConverter<T extends Enum<T>> implements EquivalentConverter<T> { public static class IndexedEnumConverter<T extends Enum<T>> implements EquivalentConverter<T> {
private Class<T> specificClass; private final Class<T> specificClass;
private Class<?> genericClass; private final Class<?> genericClass;
public IndexedEnumConverter(Class<T> specificClass, Class<?> genericClass) { public IndexedEnumConverter(Class<T> specificClass, Class<?> genericClass) {
this.specificClass = specificClass; this.specificClass = specificClass;

View File

@ -1,10 +1,5 @@
package com.comphenix.protocol.wrappers; package com.comphenix.protocol.wrappers;
import java.lang.reflect.Constructor;
import java.util.*;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import com.comphenix.protocol.PacketType; import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.reflect.FuzzyReflection; import com.comphenix.protocol.reflect.FuzzyReflection;
@ -16,12 +11,17 @@ import com.comphenix.protocol.wrappers.collection.CachedSet;
import com.comphenix.protocol.wrappers.collection.ConvertedSet; import com.comphenix.protocol.wrappers.collection.ConvertedSet;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.lang.reflect.Constructor;
import java.util.*;
/** /**
* Represents a single attribute sent in packet 44. * Represents a single attribute sent in packet 44.
*
* @author Kristian * @author Kristian
*/ */
public class WrappedAttribute extends AbstractWrapper { public class WrappedAttribute extends AbstractWrapper {
@ -29,57 +29,63 @@ public class WrappedAttribute extends AbstractWrapper {
// Shared structure modifier // Shared structure modifier
private static StructureModifier<Object> ATTRIBUTE_MODIFIER; private static StructureModifier<Object> ATTRIBUTE_MODIFIER;
// The one constructor // The one constructor
private static Constructor<?> ATTRIBUTE_CONSTRUCTOR; private static Constructor<?> ATTRIBUTE_CONSTRUCTOR;
private static final Map<String, String> REMAP; /**
* Remaps attributes if needed.
static { *
Map<String, String> remap = new HashMap<>(); * @return the remapped attribute or the attribute itself if no remapping was necessary.
remap.put("generic.maxHealth", "generic.max_health"); */
remap.put("generic.followRange", "generic.follow_range"); private static String remap(String string) {
remap.put("generic.knockbackResistance", "generic.knockback_resistance"); switch (string) {
remap.put("generic.movementSpeed", "generic.movement_speed"); case "generic.maxHealth": return "generic.max_health";
remap.put("generic.attackDamage", "generic.attack_damage"); case "generic.followRange": return "generic.follow_range";
remap.put("generic.attackSpeed", "generic.attack_speed"); case "generic.knockbackResistance": return "generic.knockback_resistance";
remap.put("generic.armorToughness", "generic.armor_toughness"); case "generic.movementSpeed": return "generic.movement_speed";
remap.put("generic.attackKnockback", "generic.attack_knockback"); case "generic.attackDamage": return "generic.attack_damage";
remap.put("horse.jumpStrength", "horse.jump_strength"); case "generic.attackSpeed": return "generic.attack_speed";
remap.put("zombie.spawnReinforcements", "zombie.spawn_reinforcements"); case "generic.armorToughness": return "generic.armor_toughness";
REMAP = ImmutableMap.copyOf(remap); case "generic.attackKnockback": return "generic.attack_knockback";
case "horse.jumpStrength": return "horse.jump_strength";
case "zombie.spawnReinforcements": return "zombie.spawn_reinforcements";
default: return string;
}
} }
/** /**
* Reference to the underlying attribute snapshot. * Reference to the underlying attribute snapshot.
*/ */
protected Object handle; protected Object handle;
protected StructureModifier<Object> modifier; protected StructureModifier<Object> modifier;
// Cached computed value // Cached computed value
private double computedValue = Double.NaN; private double computedValue = Double.NaN;
// Cached modifiers list // Cached modifiers list
private Set<WrappedAttributeModifier> attributeModifiers; private Set<WrappedAttributeModifier> attributeModifiers;
/** /**
* Construct a wrapper around a specific NMS instance. * Construct a wrapper around a specific NMS instance.
*
* @param handle - the NMS instance. * @param handle - the NMS instance.
*/ */
private WrappedAttribute(@Nonnull Object handle) { private WrappedAttribute(@Nonnull Object handle) {
super(MinecraftReflection.getAttributeSnapshotClass()); super(MinecraftReflection.getAttributeSnapshotClass());
setHandle(handle); setHandle(handle);
// Initialize modifier // Initialize modifier
if (ATTRIBUTE_MODIFIER == null) { if (ATTRIBUTE_MODIFIER == null) {
ATTRIBUTE_MODIFIER = new StructureModifier<>(MinecraftReflection.getAttributeSnapshotClass()); ATTRIBUTE_MODIFIER = new StructureModifier<>(MinecraftReflection.getAttributeSnapshotClass());
} }
this.modifier = ATTRIBUTE_MODIFIER.withTarget(handle); this.modifier = ATTRIBUTE_MODIFIER.withTarget(handle);
} }
/** /**
* Construct a new wrapped attribute around a specific NMS instance. * Construct a new wrapped attribute around a specific NMS instance.
*
* @param handle - handle to a NMS AttributeSnapshot. * @param handle - handle to a NMS AttributeSnapshot.
* @return The attribute wrapper. * @return The attribute wrapper.
* @throws IllegalArgumentException If the handle is not a AttributeSnapshot. * @throws IllegalArgumentException If the handle is not a AttributeSnapshot.
@ -87,9 +93,10 @@ public class WrappedAttribute extends AbstractWrapper {
public static WrappedAttribute fromHandle(@Nonnull Object handle) { public static WrappedAttribute fromHandle(@Nonnull Object handle) {
return new WrappedAttribute(handle); return new WrappedAttribute(handle);
} }
/** /**
* Construct a new wrapped attribute builder. * Construct a new wrapped attribute builder.
*
* @return The new builder. * @return The new builder.
*/ */
public static Builder newBuilder() { public static Builder newBuilder() {
@ -98,6 +105,7 @@ public class WrappedAttribute extends AbstractWrapper {
/** /**
* Construct a new wrapped attribute builder initialized to the values from a template. * Construct a new wrapped attribute builder initialized to the values from a template.
*
* @param template - the attribute template. * @param template - the attribute template.
* @return The new builder. * @return The new builder.
*/ */
@ -123,6 +131,7 @@ public class WrappedAttribute extends AbstractWrapper {
* Retrieve the unique attribute key that identifies its function. * Retrieve the unique attribute key that identifies its function.
* <p> * <p>
* Example: "generic.maxHealth" * Example: "generic.maxHealth"
*
* @return The attribute key. * @return The attribute key.
*/ */
public String getAttributeKey() { public String getAttributeKey() {
@ -142,17 +151,19 @@ public class WrappedAttribute extends AbstractWrapper {
public WrappedAttributeBase getBase() { public WrappedAttributeBase getBase() {
return modifier.withType(WrappedAttributeBase.class, ATTRIBUTE_BASE).readSafely(0); return modifier.withType(WrappedAttributeBase.class, ATTRIBUTE_BASE).readSafely(0);
} }
/** /**
* Retrieve the base value of this attribute, before any of the modifiers have been taken into account. * Retrieve the base value of this attribute, before any of the modifiers have been taken into account.
*
* @return The base value. * @return The base value.
*/ */
public double getBaseValue() { public double getBaseValue() {
return (Double) modifier.withType(double.class).read(0); return (Double) modifier.withType(double.class).read(0);
} }
/** /**
* Retrieve the final computed value. * Retrieve the final computed value.
*
* @return The final value. * @return The final value.
*/ */
public double getFinalValue() { public double getFinalValue() {
@ -161,9 +172,10 @@ public class WrappedAttribute extends AbstractWrapper {
} }
return computedValue; return computedValue;
} }
/** /**
* Retrieve the parent update attributes packet. * Retrieve the parent update attributes packet.
*
* @return The parent packet. * @return The parent packet.
* @deprecated Removed in 1.17 * @deprecated Removed in 1.17
*/ */
@ -175,22 +187,24 @@ public class WrappedAttribute extends AbstractWrapper {
} }
return new PacketContainer( return new PacketContainer(
PacketType.Play.Server.UPDATE_ATTRIBUTES, PacketType.Play.Server.UPDATE_ATTRIBUTES,
modifier.withType(MinecraftReflection.getPacketClass()).read(0) modifier.withType(MinecraftReflection.getPacketClass()).read(0)
); );
} }
/** /**
* Determine if the attribute has a given attribute modifier, identified by UUID. * Determine if the attribute has a given attribute modifier, identified by UUID.
*
* @param id - the id to check for. * @param id - the id to check for.
* @return TRUE if it does, FALSE otherwise. * @return TRUE if it does, FALSE otherwise.
*/ */
public boolean hasModifier(UUID id) { public boolean hasModifier(UUID id) {
return getModifiers().contains(WrappedAttributeModifier.newBuilder(id).build()); return getModifiers().contains(WrappedAttributeModifier.newBuilder(id).build());
} }
/** /**
* Retrieve an attribute modifier by UUID. * Retrieve an attribute modifier by UUID.
*
* @param id - the id to look for. * @param id - the id to look for.
* @return The single attribute modifier with the given ID. * @return The single attribute modifier with the given ID.
*/ */
@ -204,9 +218,10 @@ public class WrappedAttribute extends AbstractWrapper {
} }
return null; return null;
} }
/** /**
* Retrieve an immutable set of all the attribute modifiers that will compute the final value of this attribute. * Retrieve an immutable set of all the attribute modifiers that will compute the final value of this attribute.
*
* @return Every attribute modifier. * @return Every attribute modifier.
*/ */
public Set<WrappedAttributeModifier> getModifiers() { public Set<WrappedAttributeModifier> getModifiers() {
@ -216,41 +231,42 @@ public class WrappedAttribute extends AbstractWrapper {
// Convert to an equivalent wrapper // Convert to an equivalent wrapper
ConvertedSet<Object, WrappedAttributeModifier> converted = ConvertedSet<Object, WrappedAttributeModifier> converted =
new ConvertedSet<Object, WrappedAttributeModifier>(getSetSafely(collection)) { new ConvertedSet<Object, WrappedAttributeModifier>(getSetSafely(collection)) {
@Override @Override
protected Object toInner(WrappedAttributeModifier outer) { protected Object toInner(WrappedAttributeModifier outer) {
return outer.getHandle(); return outer.getHandle();
} }
@Override @Override
protected WrappedAttributeModifier toOuter(Object inner) { protected WrappedAttributeModifier toOuter(Object inner) {
return WrappedAttributeModifier.fromHandle(inner); return WrappedAttributeModifier.fromHandle(inner);
} }
}; };
attributeModifiers = new CachedSet<>(converted); attributeModifiers = new CachedSet<>(converted);
} }
return Collections.unmodifiableSet(attributeModifiers); return Collections.unmodifiableSet(attributeModifiers);
} }
/** /**
* Construct an attribute with the same key and name, but a different list of modifiers. * Construct an attribute with the same key and name, but a different list of modifiers.
*
* @param modifiers - attribute modifiers. * @param modifiers - attribute modifiers.
* @return The new attribute. * @return The new attribute.
*/ */
public WrappedAttribute withModifiers(Collection<WrappedAttributeModifier> modifiers) { public WrappedAttribute withModifiers(Collection<WrappedAttributeModifier> modifiers) {
return newBuilder(this).modifiers(modifiers).build(); return newBuilder(this).modifiers(modifiers).build();
} }
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (this == obj) if (this == obj)
return true; return true;
if (obj instanceof WrappedAttribute) { if (obj instanceof WrappedAttribute) {
WrappedAttribute other = (WrappedAttribute) obj; WrappedAttribute other = (WrappedAttribute) obj;
if (getBaseValue() == other.getBaseValue() && if (getBaseValue() == other.getBaseValue() &&
Objects.equal(getAttributeKey(), other.getAttributeKey())) { Objects.equal(getAttributeKey(), other.getAttributeKey())) {
return other.getModifiers().containsAll(getModifiers()); return other.getModifiers().containsAll(getModifiers());
} }
} }
@ -263,16 +279,17 @@ public class WrappedAttribute extends AbstractWrapper {
getModifiers(); getModifiers();
return Objects.hashCode(getAttributeKey(), getBaseValue(), attributeModifiers); return Objects.hashCode(getAttributeKey(), getBaseValue(), attributeModifiers);
} }
/** /**
* Compute the final value from the current attribute modifers. * Compute the final value from the current attribute modifers.
*
* @return The final value. * @return The final value.
*/ */
private double computeValue() { private double computeValue() {
Collection<WrappedAttributeModifier> modifiers = getModifiers(); Collection<WrappedAttributeModifier> modifiers = getModifiers();
double x = getBaseValue(); double x = getBaseValue();
double y = 0; double y = 0;
// Compute each phase // Compute each phase
for (int phase = 0; phase < 3; phase++) { for (int phase = 0; phase < 3; phase++) {
for (WrappedAttributeModifier modifier : modifiers) { for (WrappedAttributeModifier modifier : modifiers) {
@ -287,12 +304,12 @@ public class WrappedAttribute extends AbstractWrapper {
case 2: case 2:
y *= 1 + modifier.getAmount(); y *= 1 + modifier.getAmount();
break; break;
default : default:
throw new IllegalStateException("Unknown phase: " + phase); throw new IllegalStateException("Unknown phase: " + phase);
} }
} }
} }
// The additive phase is finished // The additive phase is finished
if (phase == 0) { if (phase == 0) {
y = x; y = x;
@ -300,23 +317,25 @@ public class WrappedAttribute extends AbstractWrapper {
} }
return y; return y;
} }
@Override @Override
public String toString() { public String toString() {
return "WrappedAttribute[key=" + getAttributeKey() + ", base=" + getBaseValue() + ", final=" + getFinalValue() + ", modifiers=" + getModifiers() + "]"; return "WrappedAttribute[key=" + getAttributeKey() + ", base=" + getBaseValue() + ", final=" + getFinalValue() + ", modifiers=" + getModifiers() + "]";
} }
/** /**
* If the collection is a set, retrieve it - otherwise, create a new set with the same elements. * If the collection is a set, retrieve it - otherwise, create a new set with the same elements.
*
* @param collection - the collection. * @param collection - the collection.
* @return A set with the same elements. * @return A set with the same elements.
*/ */
private static <U> Set<U> getSetSafely(Collection<U> collection) { private static <U> Set<U> getSetSafely(Collection<U> collection) {
return collection instanceof Set ? (Set<U>) collection : Sets.newHashSet(collection); return collection instanceof Set ? (Set<U>) collection : Sets.newHashSet(collection);
} }
/** /**
* Ensure that the given double is not infinite nor NaN. * Ensure that the given double is not infinite nor NaN.
*
* @param value - the value to check. * @param value - the value to check.
*/ */
static double checkDouble(double value) { static double checkDouble(double value) {
@ -326,11 +345,12 @@ public class WrappedAttribute extends AbstractWrapper {
throw new IllegalArgumentException("value cannot be NaN."); throw new IllegalArgumentException("value cannot be NaN.");
return value; return value;
} }
/** /**
* Represents a builder for wrapped attributes. * Represents a builder for wrapped attributes.
* <p> * <p>
* Use {@link WrappedAttribute#newBuilder()} to construct it. * Use {@link WrappedAttribute#newBuilder()} to construct it.
*
* @author Kristian * @author Kristian
*/ */
public static class Builder { public static class Builder {
@ -338,7 +358,7 @@ public class WrappedAttribute extends AbstractWrapper {
private String attributeKey; private String attributeKey;
private PacketContainer packet; private PacketContainer packet;
private Collection<WrappedAttributeModifier> modifiers = Collections.emptyList(); private Collection<WrappedAttributeModifier> modifiers = Collections.emptyList();
private Builder(WrappedAttribute template) { private Builder(WrappedAttribute template) {
if (template != null) { if (template != null) {
baseValue = template.getBaseValue(); baseValue = template.getBaseValue();
@ -347,11 +367,12 @@ public class WrappedAttribute extends AbstractWrapper {
modifiers = template.getModifiers(); modifiers = template.getModifiers();
} }
} }
/** /**
* Change the base value of the attribute. * Change the base value of the attribute.
* <p> * <p>
* The modifiers will automatically supply a value if this is unset. * The modifiers will automatically supply a value if this is unset.
*
* @param baseValue - the base value value. * @param baseValue - the base value value.
* @return This builder, for chaining. * @return This builder, for chaining.
*/ */
@ -359,11 +380,12 @@ public class WrappedAttribute extends AbstractWrapper {
this.baseValue = checkDouble(baseValue); this.baseValue = checkDouble(baseValue);
return this; return this;
} }
/** /**
* Set the unique attribute key that identifies its function. * Set the unique attribute key that identifies its function.
* <p> * <p>
* This is required. * This is required.
*
* @param attributeKey - the unique attribute key. * @param attributeKey - the unique attribute key.
* @return This builder, for chaining. * @return This builder, for chaining.
*/ */
@ -371,9 +393,10 @@ public class WrappedAttribute extends AbstractWrapper {
this.attributeKey = Preconditions.checkNotNull(attributeKey, "attributeKey cannot be NULL."); this.attributeKey = Preconditions.checkNotNull(attributeKey, "attributeKey cannot be NULL.");
return this; return this;
} }
/** /**
* Set the modifers that will be supplied to the client, and used to compute the final value. * Set the modifers that will be supplied to the client, and used to compute the final value.
*
* @param modifiers - the attribute modifiers. * @param modifiers - the attribute modifiers.
* @return This builder, for chaining. * @return This builder, for chaining.
*/ */
@ -381,9 +404,10 @@ public class WrappedAttribute extends AbstractWrapper {
this.modifiers = Preconditions.checkNotNull(modifiers, "modifiers cannot be NULL - use an empty list instead."); this.modifiers = Preconditions.checkNotNull(modifiers, "modifiers cannot be NULL - use an empty list instead.");
return this; return this;
} }
/** /**
* Set the parent update attributes packet (44). * Set the parent update attributes packet (44).
*
* @param packet - the parent packet. * @param packet - the parent packet.
* @return This builder, for chaining. * @return This builder, for chaining.
*/ */
@ -394,28 +418,30 @@ public class WrappedAttribute extends AbstractWrapper {
this.packet = packet; this.packet = packet;
return this; return this;
} }
/** /**
* Retrieve the unwrapped modifiers. * Retrieve the unwrapped modifiers.
*
* @return Unwrapped modifiers. * @return Unwrapped modifiers.
*/ */
private Set<Object> getUnwrappedModifiers() { private Set<Object> getUnwrappedModifiers() {
final Set<Object> output = new HashSet<>(); final Set<Object> output = new HashSet<>();
for (WrappedAttributeModifier modifier : modifiers) { for (WrappedAttributeModifier modifier : modifiers) {
output.add(modifier.getHandle()); output.add(modifier.getHandle());
} }
return output; return output;
} }
/** /**
* Build a new wrapped attribute with the values of this builder. * Build a new wrapped attribute with the values of this builder.
*
* @return The wrapped attribute. * @return The wrapped attribute.
* @throws RuntimeException If anything went wrong with the reflection. * @throws RuntimeException If anything went wrong with the reflection.
*/ */
public WrappedAttribute build() { public WrappedAttribute build() {
Preconditions.checkNotNull(attributeKey, "attributeKey cannot be NULL."); Preconditions.checkNotNull(attributeKey, "attributeKey cannot be NULL.");
// Remember to set the base value // Remember to set the base value
if (Double.isNaN(baseValue)) { if (Double.isNaN(baseValue)) {
throw new IllegalStateException("Base value has not been set."); throw new IllegalStateException("Base value has not been set.");
@ -439,7 +465,7 @@ public class WrappedAttribute extends AbstractWrapper {
Object attributeKey; Object attributeKey;
if (KEY_WRAPPED) { if (KEY_WRAPPED) {
WrappedRegistry registry = WrappedRegistry.getAttributeRegistry(); WrappedRegistry registry = WrappedRegistry.getAttributeRegistry();
String strKey = REMAP.getOrDefault(this.attributeKey, this.attributeKey); String strKey = remap(this.attributeKey);
attributeKey = registry.get(strKey); attributeKey = registry.get(strKey);
if (attributeKey == null) { if (attributeKey == null) {

View File

@ -1,10 +1,5 @@
package com.comphenix.protocol.wrappers; package com.comphenix.protocol.wrappers;
import java.lang.reflect.Constructor;
import java.util.UUID;
import java.util.function.Supplier;
import javax.annotation.Nonnull;
import com.comphenix.protocol.reflect.EquivalentConverter; import com.comphenix.protocol.reflect.EquivalentConverter;
import com.comphenix.protocol.reflect.FuzzyReflection; import com.comphenix.protocol.reflect.FuzzyReflection;
import com.comphenix.protocol.reflect.StructureModifier; import com.comphenix.protocol.reflect.StructureModifier;
@ -14,6 +9,11 @@ import com.comphenix.protocol.utility.MinecraftVersion;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import javax.annotation.Nonnull;
import java.lang.reflect.Constructor;
import java.util.UUID;
import java.util.function.Supplier;
/** /**
* Represents a wrapper around a AttributeModifier. * Represents a wrapper around a AttributeModifier.
* <p> * <p>
@ -27,8 +27,8 @@ public class WrappedAttributeModifier extends AbstractWrapper {
private static final EquivalentConverter<Operation> OPERATION_CONVERTER; private static final EquivalentConverter<Operation> OPERATION_CONVERTER;
private static class IndexedEnumConverter<T extends Enum<T>> implements EquivalentConverter<T> { private static class IndexedEnumConverter<T extends Enum<T>> implements EquivalentConverter<T> {
private Class<T> specificClass; private final Class<T> specificClass;
private Class<?> genericClass; private final Class<?> genericClass;
private IndexedEnumConverter(Class<T> specificClass, Class<?> genericClass) { private IndexedEnumConverter(Class<T> specificClass, Class<?> genericClass) {
this.specificClass = specificClass; this.specificClass = specificClass;
@ -102,9 +102,9 @@ public class WrappedAttributeModifier extends AbstractWrapper {
*/ */
ADD_PERCENTAGE(2); ADD_PERCENTAGE(2);
private int id; private final int id;
private Operation(int id) { Operation(int id) {
this.id = id; this.id = id;
} }
@ -254,12 +254,11 @@ public class WrappedAttributeModifier extends AbstractWrapper {
/** /**
* Initialize modifier from a given handle. * Initialize modifier from a given handle.
* @param handle - the handle. * @param handle - the handle.
* @return The given handle.
*/ */
private void initializeModifier(@Nonnull Object handle) { private void initializeModifier(@Nonnull Object handle) {
// Initialize modifier // Initialize modifier
if (BASE_MODIFIER == null) { if (BASE_MODIFIER == null) {
BASE_MODIFIER = new StructureModifier<Object>(MinecraftReflection.getAttributeModifierClass()); BASE_MODIFIER = new StructureModifier<>(MinecraftReflection.getAttributeModifierClass());
} }
this.modifier = BASE_MODIFIER.withTarget(handle); this.modifier = BASE_MODIFIER.withTarget(handle);
} }
@ -307,17 +306,17 @@ public class WrappedAttributeModifier extends AbstractWrapper {
} }
/** /**
* Set whether or not the modifier is pending synchronization with the client. * Set whether the modifier is pending synchronization with the client.
* <p> * <p>
* This value will be disregarded for {@link #equals(Object)}. * This value will be disregarded for {@link #equals(Object)}.
* @param pending - TRUE if is is, FALSE otherwise. * @param pending - TRUE if it is pending, FALSE otherwise.
*/ */
public void setPendingSynchronization(boolean pending) { public void setPendingSynchronization(boolean pending) {
modifier.withType(boolean.class).write(0, pending); modifier.withType(boolean.class).write(0, pending);
} }
/** /**
* Whether or not the modifier is pending synchronization with the client. * Whether the modifier is pending synchronization with the client.
* @return TRUE if it is, FALSE otherwise. * @return TRUE if it is, FALSE otherwise.
*/ */
public boolean isPendingSynchronization() { public boolean isPendingSynchronization() {

View File

@ -8,5 +8,5 @@ package com.comphenix.protocol.wrappers.collection;
* @param <TResult> - type of the return value. * @param <TResult> - type of the return value.
*/ */
public interface BiFunction<T1, T2, TResult> { public interface BiFunction<T1, T2, TResult> {
public TResult apply(T1 arg1, T2 arg2); TResult apply(T1 arg1, T2 arg2);
} }

View File

@ -1,19 +1,18 @@
package com.comphenix.protocol.wrappers.collection; package com.comphenix.protocol.wrappers.collection;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.annotation.Nullable;
import com.google.common.base.Joiner; import com.google.common.base.Joiner;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import com.google.common.collect.Multiset; import com.google.common.collect.Multiset;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
/** /**
* Represents a multimap that wraps another multimap by transforming the entries that are going in and out. * Represents a multimap that wraps another multimap by transforming the entries that are going in and out.
* @author Kristian * @author Kristian
@ -24,7 +23,7 @@ import com.google.common.collect.Multiset;
*/ */
public abstract class ConvertedMultimap<Key, VInner, VOuter> extends AbstractConverted<VInner, VOuter> implements Multimap<Key, VOuter> { public abstract class ConvertedMultimap<Key, VInner, VOuter> extends AbstractConverted<VInner, VOuter> implements Multimap<Key, VOuter> {
// Inner multimap // Inner multimap
private Multimap<Key, VInner> inner; private final Multimap<Key, VInner> inner;
public ConvertedMultimap(Multimap<Key, VInner> inner) { public ConvertedMultimap(Multimap<Key, VInner> inner) {
this.inner = Preconditions.checkNotNull(inner, "inner map cannot be NULL."); this.inner = Preconditions.checkNotNull(inner, "inner map cannot be NULL.");

View File

@ -60,6 +60,6 @@ class MemoryElement<TType> implements NbtBase<TType> {
@Override @Override
public NbtBase<TType> deepClone() { public NbtBase<TType> deepClone() {
// This assumes value is an immutable object // This assumes value is an immutable object
return new MemoryElement<TType>(name, value, type); return new MemoryElement<>(name, value, type);
} }
} }

View File

@ -1,10 +1,10 @@
package com.comphenix.protocol.wrappers.nbt; package com.comphenix.protocol.wrappers.nbt;
import com.comphenix.protocol.reflect.StructureModifier;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import com.comphenix.protocol.reflect.StructureModifier;
public abstract class NameProperty { public abstract class NameProperty {
private static final Map<Class<?>, StructureModifier<String>> MODIFIERS = new ConcurrentHashMap<>(); private static final Map<Class<?>, StructureModifier<String>> MODIFIERS = new ConcurrentHashMap<>();
@ -30,7 +30,7 @@ public abstract class NameProperty {
// Share modifier // Share modifier
if (modifier == null) { if (modifier == null) {
modifier = new StructureModifier<Object>(baseClass, Object.class, false).withType(String.class); modifier = new StructureModifier<>(baseClass, Object.class, false).withType(String.class);
MODIFIERS.put(baseClass, modifier); MODIFIERS.put(baseClass, modifier);
} }
return modifier; return modifier;

View File

@ -34,13 +34,13 @@ public interface NbtBase<TType> extends ClonableWrapper {
* @param visitor - the hierarchical NBT visitor. * @param visitor - the hierarchical NBT visitor.
* @return TRUE if the parent should continue processing children at the current level, FALSE otherwise. * @return TRUE if the parent should continue processing children at the current level, FALSE otherwise.
*/ */
public abstract boolean accept(NbtVisitor visitor); boolean accept(NbtVisitor visitor);
/** /**
* Retrieve the type of this NBT element. * Retrieve the type of this NBT element.
* @return The type of this NBT element. * @return The type of this NBT element.
*/ */
public abstract NbtType getType(); NbtType getType();
/** /**
* Retrieve the name of this NBT tag. * Retrieve the name of this NBT tag.
@ -48,7 +48,7 @@ public interface NbtBase<TType> extends ClonableWrapper {
* This will be an empty string if the NBT tag is stored in a list. * This will be an empty string if the NBT tag is stored in a list.
* @return Name of the tag. * @return Name of the tag.
*/ */
public abstract String getName(); String getName();
/** /**
* Set the name of this NBT tag. * Set the name of this NBT tag.
@ -56,7 +56,7 @@ public interface NbtBase<TType> extends ClonableWrapper {
* This will be ignored if the NBT tag is stored in a list. * This will be ignored if the NBT tag is stored in a list.
* @param name - name of the tag. * @param name - name of the tag.
*/ */
public abstract void setName(String name); void setName(String name);
/** /**
* Retrieve the value of this NBT tag. * Retrieve the value of this NBT tag.
@ -73,19 +73,19 @@ public interface NbtBase<TType> extends ClonableWrapper {
* {@link java.lang.UnsupportedOperationException UnsupportedOperationException}. * {@link java.lang.UnsupportedOperationException UnsupportedOperationException}.
* @return Value of this tag. * @return Value of this tag.
*/ */
public abstract TType getValue(); TType getValue();
/** /**
* Set the value of this NBT tag. * Set the value of this NBT tag.
* @param newValue - the new value of this tag. * @param newValue - the new value of this tag.
*/ */
public abstract void setValue(TType newValue); void setValue(TType newValue);
/** /**
* Clone the current NBT tag. * Clone the current NBT tag.
* @return The cloned tag. * @return The cloned tag.
*/ */
public abstract NbtBase<TType> deepClone(); NbtBase<TType> deepClone();
default Object getHandle() { default Object getHandle() {
return null; return null;

View File

@ -1,12 +1,11 @@
package com.comphenix.protocol.wrappers.nbt; package com.comphenix.protocol.wrappers.nbt;
import javax.annotation.Nonnull;
import java.util.Collection; import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.annotation.Nonnull;
/** /**
* Represents a mapping of arbitrary NBT elements and their unique names. * Represents a mapping of arbitrary NBT elements and their unique names.
* <p> * <p>
@ -20,20 +19,20 @@ import javax.annotation.Nonnull;
public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<NbtBase<?>> { public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<NbtBase<?>> {
@Override @Override
@Deprecated @Deprecated
public Map<String, NbtBase<?>> getValue(); Map<String, NbtBase<?>> getValue();
/** /**
* Determine if an entry with the given key exists or not. * Determine if an entry with the given key exists or not.
* @param key - the key to lookup. * @param key - the key to lookup.
* @return TRUE if an entry with the given key exists, FALSE otherwise. * @return TRUE if an entry with the given key exists, FALSE otherwise.
*/ */
public abstract boolean containsKey(String key); boolean containsKey(String key);
/** /**
* Retrieve a Set view of the keys of each entry in this compound. * Retrieve a Set view of the keys of each entry in this compound.
* @return The keys of each entry. * @return The keys of each entry.
*/ */
public abstract Set<String> getKeys(); Set<String> getKeys();
/** /**
* Retrieve the value of a given entry. * Retrieve the value of a given entry.
@ -41,7 +40,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param key - key of the entry to retrieve. * @param key - key of the entry to retrieve.
* @return The value of this entry, or NULL if not found. * @return The value of this entry, or NULL if not found.
*/ */
public abstract <T> NbtBase<T> getValue(String key); <T> NbtBase<T> getValue(String key);
/** /**
* Retrieve a value by its key, or assign and return a new NBT element if it doesn't exist. * Retrieve a value by its key, or assign and return a new NBT element if it doesn't exist.
@ -49,7 +48,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param type - the NBT element we will create if not found. * @param type - the NBT element we will create if not found.
* @return The value that was retrieved or just created. * @return The value that was retrieved or just created.
*/ */
public abstract NbtBase<?> getValueOrDefault(String key, NbtType type); NbtBase<?> getValueOrDefault(String key, NbtType type);
/** /**
* Set a entry based on its name. * Set a entry based on its name.
@ -58,7 +57,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @return This compound, for chaining. * @return This compound, for chaining.
* @throws IllegalArgumentException If entry is NULL. * @throws IllegalArgumentException If entry is NULL.
*/ */
public abstract <T> NbtCompound put(@Nonnull NbtBase<T> entry); <T> NbtCompound put(@Nonnull NbtBase<T> entry);
/** /**
* Retrieve the string value of an entry identified by a given key. * Retrieve the string value of an entry identified by a given key.
@ -66,14 +65,14 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @return The string value of the entry. * @return The string value of the entry.
* @throws IllegalArgumentException If the key doesn't exist. * @throws IllegalArgumentException If the key doesn't exist.
*/ */
public abstract String getString(String key); String getString(String key);
/** /**
* Retrieve the string value of an existing entry, or from a new default entry if it doesn't exist. * Retrieve the string value of an existing entry, or from a new default entry if it doesn't exist.
* @param key - the key of the entry. * @param key - the key of the entry.
* @return The value that was retrieved or just created. * @return The value that was retrieved or just created.
*/ */
public abstract String getStringOrDefault(String key); String getStringOrDefault(String key);
/** /**
* Associate a NBT string value with the given key. * Associate a NBT string value with the given key.
@ -81,7 +80,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param value - the value. * @param value - the value.
* @return This current compound, for chaining. * @return This current compound, for chaining.
*/ */
public abstract NbtCompound put(String key, String value); NbtCompound put(String key, String value);
/** /**
* Inserts an entry after cloning it and renaming it to "key". * Inserts an entry after cloning it and renaming it to "key".
@ -89,7 +88,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param entry - the entry to insert. * @param entry - the entry to insert.
* @return This current compound, for chaining. * @return This current compound, for chaining.
*/ */
public abstract NbtCompound put(String key, NbtBase<?> entry); NbtCompound put(String key, NbtBase<?> entry);
/** /**
* Retrieve the byte value of an entry identified by a given key. * Retrieve the byte value of an entry identified by a given key.
@ -97,14 +96,14 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @return The byte value of the entry. * @return The byte value of the entry.
* @throws IllegalArgumentException If the key doesn't exist. * @throws IllegalArgumentException If the key doesn't exist.
*/ */
public abstract byte getByte(String key); byte getByte(String key);
/** /**
* Retrieve the byte value of an existing entry, or from a new default entry if it doesn't exist. * Retrieve the byte value of an existing entry, or from a new default entry if it doesn't exist.
* @param key - the key of the entry. * @param key - the key of the entry.
* @return The value that was retrieved or just created. * @return The value that was retrieved or just created.
*/ */
public abstract byte getByteOrDefault(String key); byte getByteOrDefault(String key);
/** /**
* Associate a NBT byte value with the given key. * Associate a NBT byte value with the given key.
@ -112,7 +111,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param value - the value. * @param value - the value.
* @return This current compound, for chaining. * @return This current compound, for chaining.
*/ */
public abstract NbtCompound put(String key, byte value); NbtCompound put(String key, byte value);
/** /**
* Retrieve the short value of an entry identified by a given key. * Retrieve the short value of an entry identified by a given key.
@ -120,14 +119,14 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @return The short value of the entry. * @return The short value of the entry.
* @throws IllegalArgumentException If the key doesn't exist. * @throws IllegalArgumentException If the key doesn't exist.
*/ */
public abstract Short getShort(String key); Short getShort(String key);
/** /**
* Retrieve the short value of an existing entry, or from a new default entry if it doesn't exist. * Retrieve the short value of an existing entry, or from a new default entry if it doesn't exist.
* @param key - the key of the entry. * @param key - the key of the entry.
* @return The value that was retrieved or just created. * @return The value that was retrieved or just created.
*/ */
public abstract short getShortOrDefault(String key); short getShortOrDefault(String key);
/** /**
* Associate a NBT short value with the given key. * Associate a NBT short value with the given key.
@ -135,7 +134,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param value - the value. * @param value - the value.
* @return This current compound, for chaining. * @return This current compound, for chaining.
*/ */
public abstract NbtCompound put(String key, short value); NbtCompound put(String key, short value);
/** /**
* Retrieve the integer value of an entry identified by a given key. * Retrieve the integer value of an entry identified by a given key.
@ -143,14 +142,14 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @return The integer value of the entry. * @return The integer value of the entry.
* @throws IllegalArgumentException If the key doesn't exist. * @throws IllegalArgumentException If the key doesn't exist.
*/ */
public abstract int getInteger(String key); int getInteger(String key);
/** /**
* Retrieve the integer value of an existing entry, or from a new default entry if it doesn't exist. * Retrieve the integer value of an existing entry, or from a new default entry if it doesn't exist.
* @param key - the key of the entry. * @param key - the key of the entry.
* @return The value that was retrieved or just created. * @return The value that was retrieved or just created.
*/ */
public abstract int getIntegerOrDefault(String key); int getIntegerOrDefault(String key);
/** /**
* Associate a NBT integer value with the given key. * Associate a NBT integer value with the given key.
@ -158,7 +157,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param value - the value. * @param value - the value.
* @return This current compound, for chaining. * @return This current compound, for chaining.
*/ */
public abstract NbtCompound put(String key, int value); NbtCompound put(String key, int value);
/** /**
* Retrieve the long value of an entry identified by a given key. * Retrieve the long value of an entry identified by a given key.
@ -166,14 +165,14 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @return The long value of the entry. * @return The long value of the entry.
* @throws IllegalArgumentException If the key doesn't exist. * @throws IllegalArgumentException If the key doesn't exist.
*/ */
public abstract long getLong(String key); long getLong(String key);
/** /**
* Retrieve the long value of an existing entry, or from a new default entry if it doesn't exist. * Retrieve the long value of an existing entry, or from a new default entry if it doesn't exist.
* @param key - the key of the entry. * @param key - the key of the entry.
* @return The value that was retrieved or just created. * @return The value that was retrieved or just created.
*/ */
public abstract long getLongOrDefault(String key); long getLongOrDefault(String key);
/** /**
* Associate a NBT long value with the given key. * Associate a NBT long value with the given key.
@ -181,7 +180,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param value - the value. * @param value - the value.
* @return This current compound, for chaining. * @return This current compound, for chaining.
*/ */
public abstract NbtCompound put(String key, long value); NbtCompound put(String key, long value);
/** /**
* Retrieve the float value of an entry identified by a given key. * Retrieve the float value of an entry identified by a given key.
@ -189,14 +188,14 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @return The float value of the entry. * @return The float value of the entry.
* @throws IllegalArgumentException If the key doesn't exist. * @throws IllegalArgumentException If the key doesn't exist.
*/ */
public abstract float getFloat(String key); float getFloat(String key);
/** /**
* Retrieve the float value of an existing entry, or from a new default entry if it doesn't exist. * Retrieve the float value of an existing entry, or from a new default entry if it doesn't exist.
* @param key - the key of the entry. * @param key - the key of the entry.
* @return The value that was retrieved or just created. * @return The value that was retrieved or just created.
*/ */
public abstract float getFloatOrDefault(String key); float getFloatOrDefault(String key);
/** /**
* Associate a NBT float value with the given key. * Associate a NBT float value with the given key.
@ -204,7 +203,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param value - the value. * @param value - the value.
* @return This current compound, for chaining. * @return This current compound, for chaining.
*/ */
public abstract NbtCompound put(String key, float value); NbtCompound put(String key, float value);
/** /**
* Retrieve the double value of an entry identified by a given key. * Retrieve the double value of an entry identified by a given key.
@ -212,14 +211,14 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @return The double value of the entry. * @return The double value of the entry.
* @throws IllegalArgumentException If the key doesn't exist. * @throws IllegalArgumentException If the key doesn't exist.
*/ */
public abstract double getDouble(String key); double getDouble(String key);
/** /**
* Retrieve the double value of an existing entry, or from a new default entry if it doesn't exist. * Retrieve the double value of an existing entry, or from a new default entry if it doesn't exist.
* @param key - the key of the entry. * @param key - the key of the entry.
* @return The value that was retrieved or just created. * @return The value that was retrieved or just created.
*/ */
public abstract double getDoubleOrDefault(String key); double getDoubleOrDefault(String key);
/** /**
* Associate a NBT double value with the given key. * Associate a NBT double value with the given key.
@ -227,7 +226,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param value - the value. * @param value - the value.
* @return This current compound, for chaining. * @return This current compound, for chaining.
*/ */
public abstract NbtCompound put(String key, double value); NbtCompound put(String key, double value);
/** /**
* Retrieve the byte array value of an entry identified by a given key. * Retrieve the byte array value of an entry identified by a given key.
@ -235,7 +234,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @return The byte array value of the entry. * @return The byte array value of the entry.
* @throws IllegalArgumentException If the key doesn't exist. * @throws IllegalArgumentException If the key doesn't exist.
*/ */
public abstract byte[] getByteArray(String key); byte[] getByteArray(String key);
/** /**
* Associate a NBT byte array value with the given key. * Associate a NBT byte array value with the given key.
@ -243,7 +242,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param value - the value. * @param value - the value.
* @return This current compound, for chaining. * @return This current compound, for chaining.
*/ */
public abstract NbtCompound put(String key, byte[] value); NbtCompound put(String key, byte[] value);
/** /**
* Retrieve the integer array value of an entry identified by a given key. * Retrieve the integer array value of an entry identified by a given key.
@ -251,7 +250,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @return The integer array value of the entry. * @return The integer array value of the entry.
* @throws IllegalArgumentException If the key doesn't exist. * @throws IllegalArgumentException If the key doesn't exist.
*/ */
public abstract int[] getIntegerArray(String key); int[] getIntegerArray(String key);
/** /**
* Associate a NBT integer array value with the given key. * Associate a NBT integer array value with the given key.
@ -259,7 +258,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param value - the value. * @param value - the value.
* @return This current compound, for chaining. * @return This current compound, for chaining.
*/ */
public abstract NbtCompound put(String key, int[] value); NbtCompound put(String key, int[] value);
/** /**
* Associates a given Java primitive value, list, map or NbtBase with a certain key. * Associates a given Java primitive value, list, map or NbtBase with a certain key.
@ -271,14 +270,14 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param value - the value of the new entry, or NULL to remove the current value. * @param value - the value of the new entry, or NULL to remove the current value.
* @return This current compound, for chaining. * @return This current compound, for chaining.
*/ */
public abstract NbtCompound putObject(String key, Object value); NbtCompound putObject(String key, Object value);
/** /**
* Retrieve the primitive object, NbtList or NbtCompound associated with the given key. * Retrieve the primitive object, NbtList or NbtCompound associated with the given key.
* @param key - the key of the object to find. * @param key - the key of the object to find.
* @return The object with this key, or NULL if we couldn't find anything. * @return The object with this key, or NULL if we couldn't find anything.
*/ */
public abstract Object getObject(String key); Object getObject(String key);
/** /**
* Retrieve the compound (map) value of an entry identified by a given key. * Retrieve the compound (map) value of an entry identified by a given key.
@ -286,21 +285,21 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @return The compound value of the entry. * @return The compound value of the entry.
* @throws IllegalArgumentException If the key doesn't exist. * @throws IllegalArgumentException If the key doesn't exist.
*/ */
public abstract NbtCompound getCompound(String key); NbtCompound getCompound(String key);
/** /**
* Retrieve a compound (map) value by its key, or create a new compound if it doesn't exist. * Retrieve a compound (map) value by its key, or create a new compound if it doesn't exist.
* @param key - the key of the entry to find or create. * @param key - the key of the entry to find or create.
* @return The compound value that was retrieved or just created. * @return The compound value that was retrieved or just created.
*/ */
public abstract NbtCompound getCompoundOrDefault(String key); NbtCompound getCompoundOrDefault(String key);
/** /**
* Associate a NBT compound with its name as key. * Associate a NBT compound with its name as key.
* @param compound - the compound value. * @param compound - the compound value.
* @return This current compound, for chaining. * @return This current compound, for chaining.
*/ */
public abstract NbtCompound put(NbtCompound compound); NbtCompound put(NbtCompound compound);
/** /**
* Retrieve the NBT list value of an entry identified by a given key. * Retrieve the NBT list value of an entry identified by a given key.
@ -309,7 +308,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @return The NBT list value of the entry. * @return The NBT list value of the entry.
* @throws IllegalArgumentException If the key doesn't exist. * @throws IllegalArgumentException If the key doesn't exist.
*/ */
public abstract <T> NbtList<T> getList(String key); <T> NbtList<T> getList(String key);
/** /**
* Retrieve a NBT list value by its key, or create a new list if it doesn't exist. * Retrieve a NBT list value by its key, or create a new list if it doesn't exist.
@ -317,7 +316,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param key - the key of the entry to find or create. * @param key - the key of the entry to find or create.
* @return The compound value that was retrieved or just created. * @return The compound value that was retrieved or just created.
*/ */
public abstract <T> NbtList<T> getListOrDefault(String key); <T> NbtList<T> getListOrDefault(String key);
/** /**
* Associate a NBT list with the given key. * Associate a NBT list with the given key.
@ -325,7 +324,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param list - the list value. * @param list - the list value.
* @return This current compound, for chaining. * @return This current compound, for chaining.
*/ */
public abstract <T> NbtCompound put(NbtList<T> list); <T> NbtCompound put(NbtList<T> list);
/** /**
* Associate a new NBT list with the given key. * Associate a new NBT list with the given key.
@ -334,7 +333,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param list - the list of NBT elements. * @param list - the list of NBT elements.
* @return This current compound, for chaining. * @return This current compound, for chaining.
*/ */
public abstract <T> NbtCompound put(String key, Collection<? extends NbtBase<T>> list); <T> NbtCompound put(String key, Collection<? extends NbtBase<T>> list);
/** /**
* Remove the NBT element that is associated with the given key. * Remove the NBT element that is associated with the given key.
@ -342,12 +341,12 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param key - the key of the element to remove. * @param key - the key of the element to remove.
* @return The removed element, or NULL if no such element was found. * @return The removed element, or NULL if no such element was found.
*/ */
public abstract <T> NbtBase<?> remove(String key); <T> NbtBase<?> remove(String key);
/** /**
* Retrieve an iterator view of the NBT tags stored in this compound. * Retrieve an iterator view of the NBT tags stored in this compound.
* @return The tags stored in this compound. * @return The tags stored in this compound.
*/ */
@Override @Override
public abstract Iterator<NbtBase<?>> iterator(); Iterator<NbtBase<?>> iterator();
} }

View File

@ -17,18 +17,6 @@
package com.comphenix.protocol.wrappers.nbt; package com.comphenix.protocol.wrappers.nbt;
import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import javax.annotation.Nonnull;
import com.comphenix.protocol.reflect.FieldAccessException; import com.comphenix.protocol.reflect.FieldAccessException;
import com.comphenix.protocol.reflect.FuzzyReflection; import com.comphenix.protocol.reflect.FuzzyReflection;
import com.comphenix.protocol.reflect.StructureModifier; import com.comphenix.protocol.reflect.StructureModifier;
@ -39,12 +27,27 @@ import com.comphenix.protocol.utility.MinecraftVersion;
import com.comphenix.protocol.wrappers.BukkitConverters; import com.comphenix.protocol.wrappers.BukkitConverters;
import com.comphenix.protocol.wrappers.nbt.io.NbtBinarySerializer; import com.comphenix.protocol.wrappers.nbt.io.NbtBinarySerializer;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockState; import org.bukkit.block.BlockState;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import javax.annotation.Nonnull;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
/** /**
* Factory methods for creating NBT elements, lists and compounds. * Factory methods for creating NBT elements, lists and compounds.
* *
@ -152,7 +155,7 @@ public class NbtFactory {
/** /**
* Construct a wrapper for an NBT tag stored (in memory) in an item stack. This is where * Construct a wrapper for an NBT tag stored (in memory) in an item stack. This is where
* auxillary data such as enchanting, name and lore is stored. It doesn't include the items * auxiliary data such as enchanting, name and lore is stored. It doesn't include the items
* material, damage value or count. * material, damage value or count.
* <p> * <p>
* The item stack must be a wrapper for a CraftItemStack. Use * The item stack must be a wrapper for a CraftItemStack. Use
@ -176,7 +179,7 @@ public class NbtFactory {
} }
/** /**
* Constructs a wrapper for a NBT tag in an ItemStack. This is where auxillary * Constructs a wrapper for a NBT tag in an ItemStack. This is where auxiliary
* data such as enchantments, name, and lore is stored. It doesn't include the material, * data such as enchantments, name, and lore is stored. It doesn't include the material,
* damage value, or stack size. * damage value, or stack size.
* <p> * <p>

View File

@ -20,7 +20,7 @@ public interface NbtList<TType> extends NbtBase<List<NbtBase<TType>>>, Iterable<
/** /**
* The name of every NBT tag in a list. * The name of every NBT tag in a list.
*/ */
public static String EMPTY_NAME = ""; String EMPTY_NAME = "";
/** /**
* Get the type of each element. * Get the type of each element.
@ -28,13 +28,13 @@ public interface NbtList<TType> extends NbtBase<List<NbtBase<TType>>>, Iterable<
* This will be {@link NbtType#TAG_END TAG_END} if the NBT list has just been created. * This will be {@link NbtType#TAG_END TAG_END} if the NBT list has just been created.
* @return Element type. * @return Element type.
*/ */
public abstract NbtType getElementType(); NbtType getElementType();
/** /**
* Set the type of each element. * Set the type of each element.
* @param type - type of each element. * @param type - type of each element.
*/ */
public abstract void setElementType(NbtType type); void setElementType(NbtType type);
/** /**
* Add a value to a typed list by attempting to convert it to the nearest value. * Add a value to a typed list by attempting to convert it to the nearest value.
@ -42,75 +42,75 @@ public interface NbtList<TType> extends NbtBase<List<NbtBase<TType>>>, Iterable<
* Note that the list must be typed by setting {@link #setElementType(NbtType)} before calling this function. * Note that the list must be typed by setting {@link #setElementType(NbtType)} before calling this function.
* @param value - the value to add. * @param value - the value to add.
*/ */
public abstract void addClosest(Object value); void addClosest(Object value);
/** /**
* Add a NBT list or NBT compound to the list. * Add a NBT list or NBT compound to the list.
* @param element Element to add * @param element Element to add
*/ */
public abstract void add(NbtBase<TType> element); void add(NbtBase<TType> element);
/** /**
* Add a new string element to the list. * Add a new string element to the list.
* @param value - the string element to add. * @param value - the string element to add.
* @throws IllegalArgumentException If this is not a list of strings. * @throws IllegalArgumentException If this is not a list of strings.
*/ */
public abstract void add(String value); void add(String value);
/** /**
* Add a new byte element to the list. * Add a new byte element to the list.
* @param value - the byte element to add. * @param value - the byte element to add.
* @throws IllegalArgumentException If this is not a list of bytes. * @throws IllegalArgumentException If this is not a list of bytes.
*/ */
public abstract void add(byte value); void add(byte value);
/** /**
* Add a new short element to the list. * Add a new short element to the list.
* @param value - the short element to add. * @param value - the short element to add.
* @throws IllegalArgumentException If this is not a list of shorts. * @throws IllegalArgumentException If this is not a list of shorts.
*/ */
public abstract void add(short value); void add(short value);
/** /**
* Add a new integer element to the list. * Add a new integer element to the list.
* @param value - the string element to add. * @param value - the string element to add.
* @throws IllegalArgumentException If this is not a list of integers. * @throws IllegalArgumentException If this is not a list of integers.
*/ */
public abstract void add(int value); void add(int value);
/** /**
* Add a new long element to the list. * Add a new long element to the list.
* @param value - the string element to add. * @param value - the string element to add.
* @throws IllegalArgumentException If this is not a list of longs. * @throws IllegalArgumentException If this is not a list of longs.
*/ */
public abstract void add(long value); void add(long value);
/** /**
* Add a new double element to the list. * Add a new double element to the list.
* @param value - the double element to add. * @param value - the double element to add.
* @throws IllegalArgumentException If this is not a list of doubles. * @throws IllegalArgumentException If this is not a list of doubles.
*/ */
public abstract void add(double value); void add(double value);
/** /**
* Add a new byte array element to the list. * Add a new byte array element to the list.
* @param value - the byte array element to add. * @param value - the byte array element to add.
* @throws IllegalArgumentException If this is not a list of byte arrays. * @throws IllegalArgumentException If this is not a list of byte arrays.
*/ */
public abstract void add(byte[] value); void add(byte[] value);
/** /**
* Add a new int array element to the list. * Add a new int array element to the list.
* @param value - the int array element to add. * @param value - the int array element to add.
* @throws IllegalArgumentException If this is not a list of int arrays. * @throws IllegalArgumentException If this is not a list of int arrays.
*/ */
public abstract void add(int[] value); void add(int[] value);
/** /**
* Remove a given object from the list. * Remove a given object from the list.
* @param remove - the object to remove. * @param remove - the object to remove.
*/ */
public abstract void remove(Object remove); void remove(Object remove);
/** /**
* Retrieve an element by index. * Retrieve an element by index.
@ -118,23 +118,23 @@ public interface NbtList<TType> extends NbtBase<List<NbtBase<TType>>>, Iterable<
* @return The element to retrieve. * @return The element to retrieve.
* @throws IndexOutOfBoundsException If the index is out of range * @throws IndexOutOfBoundsException If the index is out of range
*/ */
public abstract TType getValue(int index); TType getValue(int index);
/** /**
* Retrieve the number of elements in this list. * Retrieve the number of elements in this list.
* @return The number of elements in this list. * @return The number of elements in this list.
*/ */
public abstract int size(); int size();
/** /**
* Retrieve each NBT tag in this list. * Retrieve each NBT tag in this list.
* @return A view of NBT tag in this list. * @return A view of NBT tag in this list.
*/ */
public abstract Collection<NbtBase<TType>> asCollection(); Collection<NbtBase<TType>> asCollection();
/** /**
* Iterate over all the elements in this list. * Iterate over all the elements in this list.
*/ */
@Override @Override
public abstract Iterator<TType> iterator(); Iterator<TType> iterator();
} }

View File

@ -17,12 +17,12 @@
package com.comphenix.protocol.wrappers.nbt; package com.comphenix.protocol.wrappers.nbt;
import com.google.common.primitives.Primitives;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import com.google.common.primitives.Primitives;
/** /**
* Represents all the element types * Represents all the element types
* *
@ -94,22 +94,21 @@ public enum NbtType {
*/ */
TAG_LONG_ARRAY(12, long[].class); TAG_LONG_ARRAY(12, long[].class);
private int rawID; private final int rawID;
private Class<?> valueType; private final Class<?> valueType;
// Used to lookup a specified NBT // Used to look up a specified NBT
private static NbtType[] lookup; private static final NbtType[] lookup;
// Lookup NBT by class // Lookup NBT by class
private static Map<Class<?>, NbtType> classLookup; private static final Map<Class<?>, NbtType> classLookup;
static { static {
NbtType[] values = values(); lookup = new NbtType[values().length];
lookup = new NbtType[values.length]; classLookup = new HashMap<>();
classLookup = new HashMap<Class<?>, NbtType>();
// Initialize lookup tables // Initialize lookup tables
for (NbtType type : values) { for (NbtType type : values()) {
lookup[type.getRawID()] = type; lookup[type.getRawID()] = type;
classLookup.put(type.getValueType(), type); classLookup.put(type.getValueType(), type);
@ -173,10 +172,10 @@ public enum NbtType {
public static NbtType getTypeFromClass(Class<?> clazz) { public static NbtType getTypeFromClass(Class<?> clazz) {
NbtType result = classLookup.get(clazz); NbtType result = classLookup.get(clazz);
// Try to lookup this value // Try to look up this value
if (result != null) { if (result != null) {
return result; return result;
} else { } else {
// Look for interfaces // Look for interfaces
for (Class<?> implemented : clazz.getInterfaces()) { for (Class<?> implemented : clazz.getInterfaces()) {
if (classLookup.containsKey(implemented)) if (classLookup.containsKey(implemented))

View File

@ -11,33 +11,33 @@ public interface NbtVisitor {
* @param node - the visited leaf node. * @param node - the visited leaf node.
* @return TRUE to continue visiting children at this level, FALSE otherwise. * @return TRUE to continue visiting children at this level, FALSE otherwise.
*/ */
public boolean visit(NbtBase<?> node); boolean visit(NbtBase<?> node);
/** /**
* Begin visiting a list node that contains multiple child nodes of the same type. * Begin visiting a list node that contains multiple child nodes of the same type.
* @param list - the NBT tag to process. * @param list - the NBT tag to process.
* @return TRUE to visit the child nodes of this list, FALSE otherwise. * @return TRUE to visit the child nodes of this list, FALSE otherwise.
*/ */
public boolean visitEnter(NbtList<?> list); boolean visitEnter(NbtList<?> list);
/** /**
* Begin visiting a compound node that contains multiple child nodes of different types. * Begin visiting a compound node that contains multiple child nodes of different types.
* @param compound - the NBT tag to process. * @param compound - the NBT tag to process.
* @return TRUE to visit the child nodes of this compound, FALSE otherwise. * @return TRUE to visit the child nodes of this compound, FALSE otherwise.
*/ */
public boolean visitEnter(NbtCompound compound); boolean visitEnter(NbtCompound compound);
/** /**
* Stop visiting a list node. * Stop visiting a list node.
* @param list - the list we're done visiting. * @param list - the list we're done visiting.
* @return TRUE for the parent to visit any subsequent sibling nodes, FALSE otherwise. * @return TRUE for the parent to visit any subsequent sibling nodes, FALSE otherwise.
*/ */
public boolean visitLeave(NbtList<?> list); boolean visitLeave(NbtList<?> list);
/** /**
* Stop visiting a compound node. * Stop visiting a compound node.
* @param compound - the compound we're done visting. * @param compound - the compound we're done visting.
* @return TRUE for the parent to visit any subsequent sibling nodes, FALSE otherwise * @return TRUE for the parent to visit any subsequent sibling nodes, FALSE otherwise
*/ */
public boolean visitLeave(NbtCompound compound); boolean visitLeave(NbtCompound compound);
} }

View File

@ -17,10 +17,10 @@
package com.comphenix.protocol.wrappers.nbt; package com.comphenix.protocol.wrappers.nbt;
import java.io.DataOutput;
import com.comphenix.protocol.wrappers.ClonableWrapper; import com.comphenix.protocol.wrappers.ClonableWrapper;
import java.io.DataOutput;
/** /**
* Indicates that this NBT wraps an underlying net.minecraft.server instance. * Indicates that this NBT wraps an underlying net.minecraft.server instance.
* <p> * <p>
@ -35,11 +35,11 @@ public interface NbtWrapper<TType> extends NbtBase<TType>, ClonableWrapper {
* Retrieve the underlying net.minecraft.server instance. * Retrieve the underlying net.minecraft.server instance.
* @return The NMS instance. * @return The NMS instance.
*/ */
public Object getHandle(); Object getHandle();
/** /**
* Write the current NBT tag to an output stream. * Write the current NBT tag to an output stream.
* @param destination - the destination stream. * @param destination - the destination stream.
*/ */
public void write(DataOutput destination); void write(DataOutput destination);
} }

View File

@ -17,15 +17,15 @@
package com.comphenix.protocol.wrappers.nbt; package com.comphenix.protocol.wrappers.nbt;
import com.comphenix.protocol.wrappers.collection.ConvertedMap;
import com.comphenix.protocol.wrappers.nbt.io.NbtBinarySerializer;
import java.io.DataOutput; import java.io.DataOutput;
import java.util.Collection; import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import com.comphenix.protocol.wrappers.collection.ConvertedMap;
import com.comphenix.protocol.wrappers.nbt.io.NbtBinarySerializer;
/** /**
* A concrete implementation of an NbtCompound that wraps an underlying NMS Compound. * A concrete implementation of an NbtCompound that wraps an underlying NMS Compound.
* *
@ -33,7 +33,7 @@ import com.comphenix.protocol.wrappers.nbt.io.NbtBinarySerializer;
*/ */
class WrappedCompound implements NbtWrapper<Map<String, NbtBase<?>>>, NbtCompound { class WrappedCompound implements NbtWrapper<Map<String, NbtBase<?>>>, NbtCompound {
// A list container // A list container
private WrappedElement<Map<String, Object>> container; private final WrappedElement<Map<String, Object>> container;
// Saved wrapper map // Saved wrapper map
private ConvertedMap<String, Object, NbtBase<?>> savedMap; private ConvertedMap<String, Object, NbtBase<?>> savedMap;
@ -67,7 +67,7 @@ class WrappedCompound implements NbtWrapper<Map<String, NbtBase<?>>>, NbtCompoun
* @param handle - the NMS handle. * @param handle - the NMS handle.
*/ */
public WrappedCompound(Object handle) { public WrappedCompound(Object handle) {
this.container = new WrappedElement<Map<String,Object>>(handle); this.container = new WrappedElement<>(handle);
} }
/** /**
@ -76,7 +76,7 @@ class WrappedCompound implements NbtWrapper<Map<String, NbtBase<?>>>, NbtCompoun
* @param name - the name of the current compound. * @param name - the name of the current compound.
*/ */
public WrappedCompound(Object handle, String name) { public WrappedCompound(Object handle, String name) {
this.container = new WrappedElement<Map<String,Object>>(handle, name); this.container = new WrappedElement<>(handle, name);
} }
@Override @Override
@ -147,7 +147,7 @@ class WrappedCompound implements NbtWrapper<Map<String, NbtBase<?>>>, NbtCompoun
if (inner == null) if (inner == null)
return null; return null;
return NbtFactory.fromNMS(inner); return NbtFactory.fromNMS(inner);
}; }
@Override @Override
protected NbtBase<?> toOuter(String key, Object inner) { protected NbtBase<?> toOuter(String key, Object inner) {
@ -169,13 +169,8 @@ class WrappedCompound implements NbtWrapper<Map<String, NbtBase<?>>>, NbtCompoun
public void setValue(Map<String, NbtBase<?>> newValue) { public void setValue(Map<String, NbtBase<?>> newValue) {
// Write all the entries // Write all the entries
for (Map.Entry<String, NbtBase<?>> entry : newValue.entrySet()) { for (Map.Entry<String, NbtBase<?>> entry : newValue.entrySet()) {
Object value = entry.getValue(); if (entry.getValue() == null) putObject(entry.getKey(), null);
else put(entry.getValue());
// We don't really know
if (value instanceof NbtBase)
put(entry.getValue());
else
putObject(entry.getKey(), entry.getValue());
} }
} }
@ -287,7 +282,7 @@ class WrappedCompound implements NbtWrapper<Map<String, NbtBase<?>>>, NbtCompoun
} else if (value instanceof NbtBase) { } else if (value instanceof NbtBase) {
put(key, (NbtBase<?>) value); put(key, (NbtBase<?>) value);
} else { } else {
NbtBase<?> base = new MemoryElement<Object>(key, value); NbtBase<?> base = new MemoryElement<>(key, value);
put(base); put(base);
} }
return this; return this;
@ -671,16 +666,16 @@ class WrappedCompound implements NbtWrapper<Map<String, NbtBase<?>>>, NbtCompoun
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
builder.append("{"); builder.append("{");
builder.append("\"name\": \"" + getName() + "\""); builder.append("\"name\": \"").append(getName()).append("\"");
for (NbtBase<?> element : this) { for (NbtBase<?> element : this) {
builder.append(", "); builder.append(", ");
// Wrap in quotation marks // Wrap in quotation marks
if (element.getType() == NbtType.TAG_STRING) if (element.getType() == NbtType.TAG_STRING)
builder.append("\"" + element.getName() + "\": \"" + element.getValue() + "\""); builder.append("\"").append(element.getName()).append("\": \"").append(element.getValue()).append("\"");
else else
builder.append("\"" + element.getName() + "\": " + element.getValue()); builder.append("\"").append(element.getName()).append("\": ").append(element.getValue());
} }
builder.append("}"); builder.append("}");

View File

@ -17,9 +17,6 @@
package com.comphenix.protocol.wrappers.nbt; package com.comphenix.protocol.wrappers.nbt;
import java.io.DataOutput;
import java.lang.reflect.Method;
import com.comphenix.protocol.reflect.FieldAccessException; import com.comphenix.protocol.reflect.FieldAccessException;
import com.comphenix.protocol.reflect.FuzzyReflection; import com.comphenix.protocol.reflect.FuzzyReflection;
import com.comphenix.protocol.reflect.StructureModifier; import com.comphenix.protocol.reflect.StructureModifier;
@ -27,6 +24,9 @@ import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.wrappers.nbt.io.NbtBinarySerializer; import com.comphenix.protocol.wrappers.nbt.io.NbtBinarySerializer;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import java.io.DataOutput;
import java.lang.reflect.Method;
/** /**
* Represents a wrapped NBT tag element, composite or not. * Represents a wrapped NBT tag element, composite or not.
* *
@ -43,7 +43,7 @@ class WrappedElement<TType> implements NbtWrapper<TType> {
private static volatile Boolean hasNbtName; private static volatile Boolean hasNbtName;
// Structure modifiers for the different NBT elements // Structure modifiers for the different NBT elements
private static StructureModifier<?>[] modifiers = new StructureModifier<?>[NbtType.values().length]; private static final StructureModifier<?>[] MODIFIERS = new StructureModifier<?>[NbtType.values().length];
// The underlying NBT object // The underlying NBT object
private Object handle; private Object handle;
@ -107,15 +107,15 @@ class WrappedElement<TType> implements NbtWrapper<TType> {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected StructureModifier<Object> getCurrentBaseModifier() { protected StructureModifier<Object> getCurrentBaseModifier() {
int index = getType().ordinal(); int index = getType().ordinal();
StructureModifier<Object> modifier = (StructureModifier<Object>) modifiers[index]; StructureModifier<Object> modifier = (StructureModifier<Object>) MODIFIERS[index];
// Double checked locking // Double checked locking
if (modifier == null) { if (modifier == null) {
synchronized (this) { synchronized (this) {
if (modifiers[index] == null) { if (MODIFIERS[index] == null) {
modifiers[index] = new StructureModifier<Object>(handle.getClass(), MinecraftReflection.getNBTBaseClass(), false); MODIFIERS[index] = new StructureModifier<Object>(handle.getClass(), MinecraftReflection.getNBTBaseClass(), false);
} }
modifier = (StructureModifier<Object>) modifiers[index]; modifier = (StructureModifier<Object>) MODIFIERS[index];
} }
} }

View File

@ -390,11 +390,11 @@ class WrappedList<TType> implements NbtWrapper<List<NbtBase<TType>>>, NbtList<TT
// Essentially JSON // Essentially JSON
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
builder.append("{\"name\": \"" + getName() + "\", \"value\": ["); builder.append("{\"name\": \"").append(getName()).append("\", \"value\": [");
if (size() > 0) { if (size() > 0) {
if (getElementType() == NbtType.TAG_STRING) if (getElementType() == NbtType.TAG_STRING)
builder.append("\"" + Joiner.on("\", \"").join(this) + "\""); builder.append("\"").append(Joiner.on("\", \"").join(this)).append("\"");
else else
builder.append(Joiner.on(", ").join(this)); builder.append(Joiner.on(", ").join(this));
} }

View File

@ -17,17 +17,17 @@
package com.comphenix.protocol; package com.comphenix.protocol;
import com.comphenix.protocol.utility.MinecraftVersion;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import com.comphenix.protocol.utility.MinecraftVersion; class MinecraftVersionTest {
import org.junit.jupiter.api.Test;
public class MinecraftVersionTest {
@Test @Test
public void testComparision() { void testComparision() {
MinecraftVersion within = new MinecraftVersion(1, 2, 5); MinecraftVersion within = new MinecraftVersion(1, 2, 5);
MinecraftVersion outside = new MinecraftVersion(1, 7, 0); MinecraftVersion outside = new MinecraftVersion(1, 7, 0);
@ -49,13 +49,12 @@ public class MinecraftVersionTest {
} */ } */
@Test @Test
public void testParsing() { void testParsing() {
assertEquals(MinecraftVersion.extractVersion("CraftBukkit R3.0 (MC: 1.4.3)"), "1.4.3"); assertEquals("1.4.3", MinecraftVersion.extractVersion("CraftBukkit R3.0 (MC: 1.4.3)"));
assertEquals(MinecraftVersion.extractVersion("CraftBukkit Test Beta 1 (MC: 1.10.01 )"), "1.10.01"); assertEquals("1.10.01", MinecraftVersion.extractVersion("CraftBukkit Test Beta 1 (MC: 1.10.01 )"));
assertEquals(MinecraftVersion.extractVersion("Hello (MC: 2.3.4)"), "2.3.4"); assertEquals("2.3.4", MinecraftVersion.extractVersion("Hello (MC: 2.3.4)"));
assertEquals(MinecraftVersion.fromServerVersion("git-Cauldron-Reloaded-1.7.10-1.1388.1.0 (MC: 1.7.10)"), assertEquals(new MinecraftVersion(1, 7, 10), MinecraftVersion.fromServerVersion("git-Cauldron-Reloaded-1.7.10-1.1388.1.0 (MC: 1.7.10)"));
new MinecraftVersion(1, 7, 10)); assertEquals(new MinecraftVersion(1, 8, 8), MinecraftVersion.fromServerVersion("git-Bukkit-18fbb24 (MC: 1.8.8)"));
assertEquals(MinecraftVersion.fromServerVersion("git-Bukkit-18fbb24 (MC: 1.8.8)"), new MinecraftVersion(1, 8, 8));
} }
} }

View File

@ -1,16 +1,17 @@
package com.comphenix.protocol.reflect.accessors; package com.comphenix.protocol.reflect.accessors;
import com.comphenix.protocol.reflect.ExactReflection;
import org.junit.jupiter.api.Test;
import java.lang.reflect.Field;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import com.comphenix.protocol.reflect.ExactReflection; class AccessorsTest {
import java.lang.reflect.Field;
import org.junit.jupiter.api.Test;
public class AccessorsTest {
@Test @Test
public void testField() { void testField() {
Player player = new Player(123, "ABC"); Player player = new Player(123, "ABC");
Field id = assertDoesNotThrow(() -> ExactReflection.fromClass(Player.class, true).getField("id")); Field id = assertDoesNotThrow(() -> ExactReflection.fromClass(Player.class, true).getField("id"));
@ -24,7 +25,7 @@ public class AccessorsTest {
} }
@Test @Test
public void testMethod() { void testMethod() {
Player player = new Player(123, "ABC"); Player player = new Player(123, "ABC");
assertDoesNotThrow(() -> Accessors.getMethodAccessor(player.getClass(), "setId", int.class).invoke(player, 0)); assertDoesNotThrow(() -> Accessors.getMethodAccessor(player.getClass(), "setId", int.class).invoke(player, 0));
@ -32,7 +33,7 @@ public class AccessorsTest {
} }
@Test @Test
public void testConstructor() { void testConstructor() {
Player player = (Player) assertDoesNotThrow(() -> Accessors Player player = (Player) assertDoesNotThrow(() -> Accessors
.getConstructorAccessor(Player.class, int.class, String.class) .getConstructorAccessor(Player.class, int.class, String.class)
.invoke(12, "hi")); .invoke(12, "hi"));

View File

@ -0,0 +1,26 @@
package com.comphenix.protocol.utility;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class IntegerMathTest
{
@Test
void testNextPowerOfTwo() {
// Test with 0, expected 1 as 2^0 is 1 which is > 0
assertEquals(1, IntegerMath.nextPowerOfTwo(0));
// Test with a power of two, expected the same number as the input is already a power of two
assertEquals(2, IntegerMath.nextPowerOfTwo(2));
assertEquals(16, IntegerMath.nextPowerOfTwo(16));
assertEquals(IntegerMath.MAX_SIGNED_POWER_OF_TWO, IntegerMath.nextPowerOfTwo(IntegerMath.MAX_SIGNED_POWER_OF_TWO));
// Test with a number that is not a power of two, expected the next higher power of two
assertEquals(8, IntegerMath.nextPowerOfTwo(7));
assertEquals(1024, IntegerMath.nextPowerOfTwo(1000));
assertEquals(Integer.MAX_VALUE, IntegerMath.nextPowerOfTwo(Integer.MAX_VALUE - 1));
assertEquals(Integer.MAX_VALUE, IntegerMath.nextPowerOfTwo(Integer.MAX_VALUE));
}
}