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;
import java.util.ArrayList;
import java.util.Deque;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import com.comphenix.protocol.MultipleLinesPrompt.MultipleConversationCanceller;
import com.comphenix.protocol.error.ErrorReporter;
import com.comphenix.protocol.error.Report;
import com.comphenix.protocol.error.ReportType;
import com.comphenix.protocol.events.PacketEvent;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.conversations.Conversable;
@ -22,11 +15,16 @@ import org.bukkit.conversations.ConversationContext;
import org.bukkit.conversations.ConversationFactory;
import org.bukkit.plugin.Plugin;
import com.comphenix.protocol.MultipleLinesPrompt.MultipleConversationCanceller;
import com.comphenix.protocol.error.ErrorReporter;
import com.comphenix.protocol.error.Report;
import com.comphenix.protocol.error.ReportType;
import com.comphenix.protocol.events.PacketEvent;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
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.
@ -48,7 +46,7 @@ public class CommandFilter extends CommandBase {
* @param ex - the failure.
* @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
*/
private enum SubCommand {
ADD, REMOVE;
ADD, REMOVE
}
/**
@ -206,13 +204,13 @@ public class CommandFilter extends CommandBase {
private FilterFailedHandler defaultFailedHandler;
// Currently registered filters
private List<Filter> filters = new ArrayList<Filter>();
private final Map<String, Filter> filters = new HashMap<>();
// Owner plugin
private final Plugin plugin;
// Whether or not the command is enabled
private ProtocolConfig config;
// Whether the command is enabled
private final ProtocolConfig config;
// Script engine
private ScriptEngine engine;
@ -227,7 +225,7 @@ public class CommandFilter extends CommandBase {
this.uninitialized = true;
}
private void initalizeScript() {
private void initializeScript() {
try {
// First attempt
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>
* Uses a default filter failure handler that simply prints the error message and removes the filter.
* @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 handler - failure handler.
* @return TRUE if we should, FALSE otherwise.
*/
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();
try {
@ -347,7 +345,7 @@ public class CommandFilter extends CommandBase {
// Start the engine
if (uninitialized) {
uninitialized = false;
initalizeScript();
initializeScript();
}
}
@ -370,11 +368,12 @@ public class CommandFilter extends CommandBase {
final SubCommand command = parseCommand(args, 0);
final String name = args[1];
final String lowerCaseName = name.toLowerCase();
switch (command) {
case ADD:
// Never overwrite an existing filter
if (findFilter(name) != null) {
if(filters.containsKey(lowerCaseName)) {
sender.sendMessage(ChatColor.RED + "Filter " + name + " already exists. Remove it first.");
return true;
}
@ -402,8 +401,8 @@ public class CommandFilter extends CommandBase {
final Conversable whom = event.getContext().getForWhom();
if (event.gracefulExit()) {
String predicate = prompt.removeAccumulatedInput(event.getContext());
Filter filter = new Filter(name, predicate, packets);
final String predicate = prompt.removeAccumulatedInput(event.getContext());
final Filter filter = new Filter(name, predicate, packets);
// Print the last line as well
whom.sendRawMessage(prompt.getPromptText(event.getContext()));
@ -412,7 +411,7 @@ public class CommandFilter extends CommandBase {
// Force early compilation
filter.compile(engine);
filters.add(filter);
filters.put(lowerCaseName, filter);
whom.sendRawMessage(ChatColor.GOLD + "Added filter " + name);
} catch (ScriptException e) {
e.printStackTrace();
@ -438,12 +437,12 @@ public class CommandFilter extends CommandBase {
break;
case REMOVE:
Filter filter = findFilter(name);
final Filter filter = filters.get(lowerCaseName);
// See if it exists before we remove it
if (filter != null) {
filter.close(engine);
filters.remove(filter);
filters.remove(lowerCaseName);
sender.sendMessage(ChatColor.GOLD + "Removed filter " + name);
} else {
sender.sendMessage(ChatColor.RED + "Unable to find a filter by the name " + name);
@ -453,22 +452,7 @@ public class CommandFilter extends CommandBase {
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) {
String text = args[index].toUpperCase();

View File

@ -17,7 +17,21 @@
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.ArrayList;
import java.util.Arrays;
@ -30,23 +44,6 @@ import java.util.WeakHashMap;
import java.util.logging.Level;
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.
*
@ -56,7 +53,7 @@ class CommandPacket extends CommandBase {
public static final ReportType REPORT_CANNOT_SEND_MESSAGE = new ReportType("Cannot send chat message.");
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;
private Plugin plugin;
private Logger logger;
private ProtocolManager manager;
private final Plugin plugin;
private final Logger logger;
private final ProtocolManager manager;
private ChatExtensions chatter;
private final ChatExtensions chatter;
// The main parser
private PacketTypeParser typeParser = new PacketTypeParser();
private final PacketTypeParser typeParser = new PacketTypeParser();
// 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
private PacketTypeSet packetTypes = new PacketTypeSet();
private PacketTypeSet extendedTypes = new PacketTypeSet();
private final PacketTypeSet packetTypes = new PacketTypeSet();
private final PacketTypeSet extendedTypes = new PacketTypeSet();
// Compare listeners
private PacketTypeSet compareTypes = new PacketTypeSet();
private Map<PacketEvent, String> originalPackets = new MapMaker().weakKeys().makeMap();
private final PacketTypeSet compareTypes = new PacketTypeSet();
private final Map<PacketEvent, String> originalPackets = new MapMaker().weakKeys().makeMap();
// The packet listener
private PacketListener listener;
@ -96,7 +93,7 @@ class CommandPacket extends CommandBase {
private PacketListener compareListener;
// Filter packet events
private CommandFilter filter;
private final CommandFilter filter;
public CommandPacket(ErrorReporter reporter, Plugin plugin, Logger logger, CommandFilter filter, ProtocolManager manager) {
super(reporter, CommandBase.PERMISSION_ADMIN, NAME, 1);
@ -156,7 +153,7 @@ class CommandPacket extends CommandBase {
@Override
protected boolean handleCommand(CommandSender sender, String[] args) {
try {
Deque<String> arguments = new ArrayDeque<String>(Arrays.asList(args));
Deque<String> arguments = new ArrayDeque<>(Arrays.asList(args));
SubCommand subCommand = parseCommand(arguments);
// Commands with different parameters
@ -247,14 +244,14 @@ class CommandPacket extends CommandBase {
}
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
for (PacketType type : types) {
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
pagedMessage.put(sender, messages);
printPage(sender, 1);
@ -444,19 +441,6 @@ class CommandPacket extends CommandBase {
private SubCommand parseCommand(Deque<String> arguments)
{
final String text = arguments.remove().toLowerCase();
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.");
}
return SubCommand.valueOf(arguments.remove().toUpperCase());
}
}

View File

@ -158,7 +158,7 @@ public class PacketLogging implements CommandExecutor, PacketListener {
sender.sendMessage(ChatColor.RED + "Invalid syntax: /packetlog <protocol> <sender> <packet> [location]");
return true;
} catch (Throwable ex) {
sender.sendMessage(ChatColor.RED + "Failed to parse command: " + ex.toString());
sender.sendMessage(ChatColor.RED + "Failed to parse command: " + ex);
return true;
}
}
@ -173,7 +173,7 @@ public class PacketLogging implements CommandExecutor, PacketListener {
this.sendingWhitelist = ListeningWhitelist.newBuilder().types(sendingTypes).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) {
fileLogger = Logger.getLogger("ProtocolLib-FileLogging");
@ -270,15 +270,8 @@ public class PacketLogging implements CommandExecutor, PacketListener {
@Override
public String format(LogRecord record) {
String string = formatMessage(record);
if (string.isEmpty()) {
return LINE_SEPARATOR;
}
StringBuilder message = new StringBuilder();
message.append(MessageFormat.format(FORMAT, DATE.format(record.getMillis()), string));
message.append(LINE_SEPARATOR);
return message.toString();
final String string = formatMessage(record);
return string.isEmpty() ? LINE_SEPARATOR : MessageFormat.format(FORMAT, DATE.format(record.getMillis()), string) + LINE_SEPARATOR;
}
}
}

View File

@ -621,8 +621,8 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
*/
LEGACY("", "");
private String packetName;
private String mojangName;
private final String packetName;
private final String mojangName;
Protocol(String packetName, String mojangName) {
this.packetName = packetName;
@ -635,17 +635,14 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
* @return The corresponding protocol.
*/
public static Protocol fromVanilla(Enum<?> vanilla) {
String name = vanilla.name();
if ("HANDSHAKING".equals(name))
return HANDSHAKING;
if ("PLAY".equals(name))
return PLAY;
if ("STATUS".equals(name))
return STATUS;
if ("LOGIN".equals(name))
return LOGIN;
throw new IllegalArgumentException("Unrecognized vanilla enum " + vanilla);
switch (vanilla.name()) {
case "HANDSHAKING": return HANDSHAKING;
case "PLAY": return PLAY;
case "STATUS": return STATUS;
case "LOGIN": return LOGIN;
default:
throw new IllegalArgumentException("Unrecognized vanilla enum " + vanilla);
}
}
public String getPacketName() {
@ -677,9 +674,9 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
*/
SERVER("Clientbound", "Out", "server");
private String mojangName;
private String packetName;
private String mcpName;
private final String mojangName;
private final String packetName;
private final String mcpName;
Sender(String mojangName, String packetName, String mcpName) {
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)
@Retention(RetentionPolicy.RUNTIME)
@ -828,7 +825,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
* <ul>
* <li>{@link PacketType.Play.Server#SPAWN_ENTITY}
* </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.
*
* @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.
* <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 sender - the sender.
* @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+
* <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 sender - the sender.
* @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.classNames = new ArrayList<>();
for (int i = 0; i < names.length; i++) {
if (isMcpPacketName(names[i])) { // Minecraft MCP packets
classNames.add(formatMcpClassName(protocol, sender, names[i]));
for (String classname : names) {
if (isMcpPacketName(classname)) { // Minecraft MCP packets
classNames.add(formatMcpClassName(protocol, sender, classname));
} else {
classNames.add(formatClassName(protocol, sender, names[i]));
classNames.add(formatMojangClassName(protocol, sender, names[i]));
classNames.add(formatClassName(protocol, sender, classname));
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.
* @return Whether or not the packet is supported.
* @return Whether the packet is supported.
*/
public boolean isSupported() {
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.
*
* @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.
*
* @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.
*/
public boolean isDynamic() {

View File

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

View File

@ -38,7 +38,7 @@ public abstract class AbstractConcurrentListenerMultimap<T> {
// The core of our map
private final ConcurrentMap<PacketType, SortedCopyOnWriteArray<PrioritizedListener<T>>> mapListeners;
public AbstractConcurrentListenerMultimap() {
protected AbstractConcurrentListenerMultimap() {
this.mapListeners = new ConcurrentHashMap<>();
}
@ -49,21 +49,21 @@ public abstract class AbstractConcurrentListenerMultimap<T> {
* @param whitelist - the packet whitelist to use.
*/
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()) {
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) {
SortedCopyOnWriteArray<PrioritizedListener<T>> list = this.mapListeners.get(type);
// We don't want to create this for every lookup
if (list == null) {
// It would be nice if we could use a PriorityBlockingQueue, but it doesn't preseve iterator order,
// which is a essential feature for our purposes.
final SortedCopyOnWriteArray<PrioritizedListener<T>> value = new SortedCopyOnWriteArray<PrioritizedListener<T>>();
// It would be nice if we could use a PriorityBlockingQueue, but it doesn't preserve iterator order,
// which is an essential feature for our purposes.
final SortedCopyOnWriteArray<PrioritizedListener<T>> value = new SortedCopyOnWriteArray<>();
// We may end up creating multiple multisets, but we'll agree on which to use
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.
*/
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.
for (PacketType type : whitelist.getTypes()) {
SortedCopyOnWriteArray<PrioritizedListener<T>> list = this.mapListeners.get(type);
// Remove any listeners
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 == null || list.isEmpty()) continue;
if (list.size() == 0) {
this.mapListeners.remove(type);
removedPackets.add(type);
}
}
// Remove any listeners
// Remove this listener. Note that priority is generally ignored.
list.remove(new PrioritizedListener<T>(listener, whitelist.getPriority()));
if (list.isEmpty()) {
this.mapListeners.remove(type);
removedPackets.add(type);
}
// Move on to the next
}

View File

@ -17,15 +17,15 @@
package com.comphenix.protocol.concurrency;
import com.google.common.base.Objects;
import com.google.common.collect.Range;
import java.util.HashSet;
import java.util.Map;
import java.util.NavigableMap;
import java.util.Set;
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
* 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.
*/
public class Entry implements Map.Entry<Range<TKey>, TValue> {
private EndPoint left;
private EndPoint right;
private final EndPoint left;
private final EndPoint right;
Entry(EndPoint left, EndPoint right) {
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
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.
@ -163,8 +163,8 @@ public abstract class AbstractIntervalTree<TKey extends Comparable<TKey>, TValue
EndPoint previous = null;
EndPoint next = null;
Set<Entry> resized = new HashSet<Entry>();
Set<Entry> removed = new HashSet<Entry>();
Set<Entry> resized = new HashSet<>();
Set<Entry> removed = new HashSet<>();
// Remove the previous element too. A close end-point must be preceded by an OPEN end-point.
if (first != null && first.state == State.CLOSE) {
@ -315,7 +315,7 @@ public abstract class AbstractIntervalTree<TKey extends Comparable<TKey>, TValue
*/
public Set<Entry> entrySet() {
// Don't mind the Java noise
Set<Entry> result = new HashSet<Entry>();
Set<Entry> result = new HashSet<>();
getEntries(result, bounds);
return result;
}

View File

@ -17,18 +17,18 @@
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.google.common.cache.CacheLoader;
import com.google.common.cache.RemovalCause;
import com.google.common.cache.RemovalListener;
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.
* <p>
@ -80,7 +80,7 @@ public class BlockingHashMap<TKey, TValue> {
build(BlockingHashMap.<TKey, TValue> newInvalidCacheLoader());
// 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.
*/
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;
import com.comphenix.protocol.utility.SafeCacheBuilder;
import com.comphenix.protocol.utility.Util;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.RemovalListener;
import com.google.common.collect.AbstractIterator;
import com.google.common.util.concurrent.UncheckedExecutionException;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
@ -304,7 +302,7 @@ public class ConcurrentPlayerMap<TValue> extends AbstractMap<Player, TValue> imp
source.remove();
keyLookup.remove(entry.getKey());
} else {
return new SimpleEntry<Player, TValue>(player, entry.getValue());
return new SimpleEntry<>(player, entry.getValue());
}
}
return endOfData();

View File

@ -18,7 +18,6 @@
package com.comphenix.protocol.error;
import com.comphenix.protocol.error.Report.ReportBuilder;
import org.bukkit.plugin.Plugin;
/**
@ -33,7 +32,7 @@ public interface ErrorReporter {
* @param methodName - name of the caller method.
* @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.
@ -42,7 +41,7 @@ public interface ErrorReporter {
* @param error - the exception itself.
* @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.
@ -51,40 +50,40 @@ public interface ErrorReporter {
* @param sender - the sender.
* @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.
* @param sender - the sender.
* @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.
* @param sender - the object containing the caller method.
* @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.
* @param sender - the object containing the caller method.
* @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.
* @param sender - the object containing the caller method.
* @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.
* @param sender - the object containing the caller method.
* @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
*/
private static class NBTComponentConverter implements EquivalentConverter<WrappedChatComponent[]> {
private EquivalentConverter<NbtBase<?>> nbtConverter = BukkitConverters.getNbtConverter();
private final int lines = 4;
private final EquivalentConverter<NbtBase<?>> nbtConverter = BukkitConverters.getNbtConverter();
private static final int LINES = 4;
@Override
public WrappedChatComponent[] getSpecific(Object generic) {
NbtBase<?> nbtBase = nbtConverter.getSpecific(generic);
NbtCompound compound = (NbtCompound) nbtBase;
final NbtBase<?> nbtBase = nbtConverter.getSpecific(generic);
final NbtCompound compound = (NbtCompound) nbtBase;
WrappedChatComponent[] components = new WrappedChatComponent[lines];
for (int i = 0; i < lines; i++) {
final WrappedChatComponent[] components = new WrappedChatComponent[LINES];
for (int i = 0; i < LINES; i++) {
if (compound.containsKey("Text" + (i + 1))) {
components[i] = WrappedChatComponent.fromJson(compound.getString("Text" + (i + 1)));
} else {
@ -1278,7 +1278,7 @@ public abstract class AbstractStructure {
public Object getGeneric(WrappedChatComponent[] specific) {
NbtCompound compound = NbtFactory.ofCompound("");
for (int i = 0; i < lines; i++) {
for (int i = 0; i < LINES; i++) {
WrappedChatComponent component;
if (i < specific.length && specific[i] != null) {
component = specific[i];

View File

@ -24,7 +24,7 @@ package com.comphenix.protocol.events;
*/
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.
*/
LOWEST(0),
@ -33,7 +33,7 @@ public enum ListenerPriority {
*/
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),
/**
@ -54,13 +54,13 @@ public enum ListenerPriority {
private final int slot;
private ListenerPriority(int slot) {
ListenerPriority(int slot) {
this.slot = slot;
}
/**
* A low slot represents a low priority.
* @return Integer representation of this priorty.
* @return Integer representation of this priority.
*/
public int getSlot() {
return slot;

View File

@ -14,13 +14,13 @@ public interface PacketOutputHandler {
* Higher priority is executed before lower.
* @return The handler priority.
*/
public ListenerPriority getPriority();
ListenerPriority getPriority();
/**
* The plugin that owns this output handler.
* @return The owner plugin.
*/
public Plugin getPlugin();
Plugin getPlugin();
/**
* 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.
* @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.
* @return The assoicated plugin.
*/
public Plugin getPlugin();
Plugin getPlugin();
/**
* Invoked after a packet has been sent or received.
@ -19,5 +19,5 @@ public interface PacketPostListener {
* Note that this is invoked asynchronously.
* @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.Lists;
import com.google.common.primitives.Primitives;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
@ -42,7 +43,7 @@ public class PacketConstructor {
* <p>
* 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
private final Constructor<?> constructorMethod;
@ -56,7 +57,7 @@ public class PacketConstructor {
private PacketConstructor(Constructor<?> 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());
}

View File

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

View File

@ -17,6 +17,9 @@
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.Field;
import java.lang.reflect.Modifier;
@ -25,9 +28,6 @@ import java.util.Map;
import java.util.Map.Entry;
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.
*
@ -105,7 +105,7 @@ public class PrettyPrinter {
}
StringBuilder output = new StringBuilder();
Set<Object> previous = new HashSet<Object>();
Set<Object> previous = new HashSet<>();
// Start and stop
output.append("{ ");
@ -262,7 +262,7 @@ public class PrettyPrinter {
} else if (type.isPrimitive() || Primitives.isWrapperType(type)) {
output.append(value);
} else if (type == String.class || hierachyIndex <= 0) {
output.append("\"" + value + "\"");
output.append("\"").append(value).append("\"");
} else if (type.isArray()) {
printArray(output, value, type, stop, previous, hierachyIndex, printer);
} else if (Iterable.class.isAssignableFrom(type)) {
@ -271,7 +271,7 @@ public class PrettyPrinter {
printMap(output, (Map<Object, Object>) value, type, stop, previous, hierachyIndex, printer);
} else if (ClassLoader.class.isAssignableFrom(type) || previous.contains(value)) {
// Don't print previous objects
output.append("\"" + value + "\"");
output.append("\"").append(value).append("\"");
} else {
output.append("{ ");
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 {
/**
* 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.
* @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.
@ -38,5 +38,5 @@ public interface Cloner {
* @return A cloned value.
* @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;
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.Protocol;
import com.comphenix.protocol.ProtocolLogger;
import com.comphenix.protocol.reflect.EquivalentConverter;
import com.comphenix.protocol.reflect.ExactReflection;
import com.comphenix.protocol.reflect.FuzzyReflection;
import com.comphenix.protocol.reflect.accessors.Accessors;
import com.comphenix.protocol.utility.MinecraftVersion;
import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.utility.MinecraftVersion;
import org.apache.commons.lang.Validate;
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.
* @author Kristian
@ -166,7 +171,7 @@ public abstract class EnumWrappers {
RELEASE_USE_ITEM,
SWAP_HELD_ITEMS("SWAP_ITEM_WITH_OFFHAND");
String[] aliases;
final String[] aliases;
PlayerDigType(String... aliases) {
this.aliases = aliases;
}
@ -187,7 +192,7 @@ public abstract class EnumWrappers {
OPEN_INVENTORY,
START_FALL_FLYING;
String[] aliases;
final String[] aliases;
PlayerAction(String... 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}
*/
public static class AliasedEnumConverter<T extends Enum<T> & AliasedEnum> implements EquivalentConverter<T> {
private Class<?> genericType;
private Class<T> specificType;
private final Class<?> genericType;
private final Class<T> specificType;
private Map<T, Object> genericMap = new ConcurrentHashMap<>();
private Map<Object, T> specificMap = new ConcurrentHashMap<>();
private final Map<T, Object> genericMap = new ConcurrentHashMap<>();
private final Map<Object, T> specificMap = new ConcurrentHashMap<>();
public AliasedEnumConverter(Class<?> genericType, Class<T> specificType) {
this.genericType = genericType;
@ -980,8 +985,8 @@ public abstract class EnumWrappers {
}
public static class IndexedEnumConverter<T extends Enum<T>> implements EquivalentConverter<T> {
private Class<T> specificClass;
private Class<?> genericClass;
private final Class<T> specificClass;
private final Class<?> genericClass;
public IndexedEnumConverter(Class<T> specificClass, Class<?> genericClass) {
this.specificClass = specificClass;

View File

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

View File

@ -1,10 +1,5 @@
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.FuzzyReflection;
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.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.
* <p>
@ -27,8 +27,8 @@ public class WrappedAttributeModifier extends AbstractWrapper {
private static final EquivalentConverter<Operation> OPERATION_CONVERTER;
private static class IndexedEnumConverter<T extends Enum<T>> implements EquivalentConverter<T> {
private Class<T> specificClass;
private Class<?> genericClass;
private final Class<T> specificClass;
private final Class<?> genericClass;
private IndexedEnumConverter(Class<T> specificClass, Class<?> genericClass) {
this.specificClass = specificClass;
@ -102,9 +102,9 @@ public class WrappedAttributeModifier extends AbstractWrapper {
*/
ADD_PERCENTAGE(2);
private int id;
private final int id;
private Operation(int id) {
Operation(int id) {
this.id = id;
}
@ -254,12 +254,11 @@ public class WrappedAttributeModifier extends AbstractWrapper {
/**
* Initialize modifier from a given handle.
* @param handle - the handle.
* @return The given handle.
*/
private void initializeModifier(@Nonnull Object handle) {
// Initialize modifier
if (BASE_MODIFIER == null) {
BASE_MODIFIER = new StructureModifier<Object>(MinecraftReflection.getAttributeModifierClass());
BASE_MODIFIER = new StructureModifier<>(MinecraftReflection.getAttributeModifierClass());
}
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>
* 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) {
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.
*/
public boolean isPendingSynchronization() {

View File

@ -8,5 +8,5 @@ package com.comphenix.protocol.wrappers.collection;
* @param <TResult> - type of the return value.
*/
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;
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.Preconditions;
import com.google.common.collect.Iterables;
import com.google.common.collect.Multimap;
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.
* @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> {
// Inner multimap
private Multimap<Key, VInner> inner;
private final Multimap<Key, VInner> inner;
public ConvertedMultimap(Multimap<Key, VInner> inner) {
this.inner = Preconditions.checkNotNull(inner, "inner map cannot be NULL.");

View File

@ -60,6 +60,6 @@ class MemoryElement<TType> implements NbtBase<TType> {
@Override
public NbtBase<TType> deepClone() {
// 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;
import com.comphenix.protocol.reflect.StructureModifier;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.comphenix.protocol.reflect.StructureModifier;
public abstract class NameProperty {
private static final Map<Class<?>, StructureModifier<String>> MODIFIERS = new ConcurrentHashMap<>();
@ -30,7 +30,7 @@ public abstract class NameProperty {
// Share modifier
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);
}
return modifier;

View File

@ -34,13 +34,13 @@ public interface NbtBase<TType> extends ClonableWrapper {
* @param visitor - the hierarchical NBT visitor.
* @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.
* @return The type of this NBT element.
*/
public abstract NbtType getType();
NbtType getType();
/**
* 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.
* @return Name of the tag.
*/
public abstract String getName();
String getName();
/**
* 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.
* @param name - name of the tag.
*/
public abstract void setName(String name);
void setName(String name);
/**
* Retrieve the value of this NBT tag.
@ -73,19 +73,19 @@ public interface NbtBase<TType> extends ClonableWrapper {
* {@link java.lang.UnsupportedOperationException UnsupportedOperationException}.
* @return Value of this tag.
*/
public abstract TType getValue();
TType getValue();
/**
* Set the value of this NBT tag.
* @param newValue - the new value of this tag.
*/
public abstract void setValue(TType newValue);
void setValue(TType newValue);
/**
* Clone the current NBT tag.
* @return The cloned tag.
*/
public abstract NbtBase<TType> deepClone();
NbtBase<TType> deepClone();
default Object getHandle() {
return null;

View File

@ -1,12 +1,11 @@
package com.comphenix.protocol.wrappers.nbt;
import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nonnull;
/**
* Represents a mapping of arbitrary NBT elements and their unique names.
* <p>
@ -20,20 +19,20 @@ import javax.annotation.Nonnull;
public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<NbtBase<?>> {
@Override
@Deprecated
public Map<String, NbtBase<?>> getValue();
Map<String, NbtBase<?>> getValue();
/**
* Determine if an entry with the given key exists or not.
* @param key - the key to lookup.
* @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.
* @return The keys of each entry.
*/
public abstract Set<String> getKeys();
Set<String> getKeys();
/**
* 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.
* @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.
@ -49,7 +48,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param type - the NBT element we will create if not found.
* @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.
@ -58,7 +57,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @return This compound, for chaining.
* @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.
@ -66,14 +65,14 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @return The string value of the entry.
* @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.
* @param key - the key of the entry.
* @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.
@ -81,7 +80,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param value - the value.
* @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".
@ -89,7 +88,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param entry - the entry to insert.
* @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.
@ -97,14 +96,14 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @return The byte value of the entry.
* @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.
* @param key - the key of the entry.
* @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.
@ -112,7 +111,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param value - the value.
* @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.
@ -120,14 +119,14 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @return The short value of the entry.
* @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.
* @param key - the key of the entry.
* @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.
@ -135,7 +134,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param value - the value.
* @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.
@ -143,14 +142,14 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @return The integer value of the entry.
* @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.
* @param key - the key of the entry.
* @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.
@ -158,7 +157,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param value - the value.
* @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.
@ -166,14 +165,14 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @return The long value of the entry.
* @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.
* @param key - the key of the entry.
* @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.
@ -181,7 +180,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param value - the value.
* @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.
@ -189,14 +188,14 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @return The float value of the entry.
* @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.
* @param key - the key of the entry.
* @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.
@ -204,7 +203,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param value - the value.
* @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.
@ -212,14 +211,14 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @return The double value of the entry.
* @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.
* @param key - the key of the entry.
* @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.
@ -227,7 +226,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param value - the value.
* @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.
@ -235,7 +234,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @return The byte array value of the entry.
* @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.
@ -243,7 +242,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param value - the value.
* @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.
@ -251,7 +250,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @return The integer array value of the entry.
* @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.
@ -259,7 +258,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param value - the value.
* @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.
@ -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.
* @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.
* @param key - the key of the object to find.
* @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.
@ -286,21 +285,21 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @return The compound value of the entry.
* @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.
* @param key - the key of the entry to find or create.
* @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.
* @param compound - the compound value.
* @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.
@ -309,7 +308,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @return The NBT list value of the entry.
* @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.
@ -317,7 +316,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param key - the key of the entry to find or create.
* @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.
@ -325,7 +324,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param list - the list value.
* @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.
@ -334,7 +333,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param list - the list of NBT elements.
* @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.
@ -342,12 +341,12 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param key - the key of the element to remove.
* @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.
* @return The tags stored in this compound.
*/
@Override
public abstract Iterator<NbtBase<?>> iterator();
Iterator<NbtBase<?>> iterator();
}

View File

@ -17,18 +17,6 @@
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.FuzzyReflection;
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.nbt.io.NbtBinarySerializer;
import com.google.common.base.Preconditions;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
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.
*
@ -152,7 +155,7 @@ public class NbtFactory {
/**
* 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.
* <p>
* 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,
* damage value, or stack size.
* <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.
*/
public static String EMPTY_NAME = "";
String EMPTY_NAME = "";
/**
* 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.
* @return Element type.
*/
public abstract NbtType getElementType();
NbtType getElementType();
/**
* Set the 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.
@ -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.
* @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.
* @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.
* @param value - the string element to add.
* @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.
* @param value - the byte element to add.
* @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.
* @param value - the short element to add.
* @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.
* @param value - the string element to add.
* @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.
* @param value - the string element to add.
* @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.
* @param value - the double element to add.
* @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.
* @param value - the byte array element to add.
* @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.
* @param value - the int array element to add.
* @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.
* @param remove - the object to remove.
*/
public abstract void remove(Object remove);
void remove(Object remove);
/**
* Retrieve an element by index.
@ -118,23 +118,23 @@ public interface NbtList<TType> extends NbtBase<List<NbtBase<TType>>>, Iterable<
* @return The element to retrieve.
* @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.
* @return The number of elements in this list.
*/
public abstract int size();
int size();
/**
* Retrieve each 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.
*/
@Override
public abstract Iterator<TType> iterator();
Iterator<TType> iterator();
}

View File

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

View File

@ -11,33 +11,33 @@ public interface NbtVisitor {
* @param node - the visited leaf node.
* @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.
* @param list - the NBT tag to process.
* @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.
* @param compound - the NBT tag to process.
* @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.
* @param list - the list we're done visiting.
* @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.
* @param compound - the compound we're done visting.
* @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;
import java.io.DataOutput;
import com.comphenix.protocol.wrappers.ClonableWrapper;
import java.io.DataOutput;
/**
* Indicates that this NBT wraps an underlying net.minecraft.server instance.
* <p>
@ -35,11 +35,11 @@ public interface NbtWrapper<TType> extends NbtBase<TType>, ClonableWrapper {
* Retrieve the underlying net.minecraft.server instance.
* @return The NMS instance.
*/
public Object getHandle();
Object getHandle();
/**
* Write the current NBT tag to an output 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;
import com.comphenix.protocol.wrappers.collection.ConvertedMap;
import com.comphenix.protocol.wrappers.nbt.io.NbtBinarySerializer;
import java.io.DataOutput;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
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.
*
@ -33,7 +33,7 @@ import com.comphenix.protocol.wrappers.nbt.io.NbtBinarySerializer;
*/
class WrappedCompound implements NbtWrapper<Map<String, NbtBase<?>>>, NbtCompound {
// A list container
private WrappedElement<Map<String, Object>> container;
private final WrappedElement<Map<String, Object>> container;
// Saved wrapper map
private ConvertedMap<String, Object, NbtBase<?>> savedMap;
@ -67,7 +67,7 @@ class WrappedCompound implements NbtWrapper<Map<String, NbtBase<?>>>, NbtCompoun
* @param handle - the NMS 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.
*/
public WrappedCompound(Object handle, String name) {
this.container = new WrappedElement<Map<String,Object>>(handle, name);
this.container = new WrappedElement<>(handle, name);
}
@Override
@ -147,7 +147,7 @@ class WrappedCompound implements NbtWrapper<Map<String, NbtBase<?>>>, NbtCompoun
if (inner == null)
return null;
return NbtFactory.fromNMS(inner);
};
}
@Override
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) {
// Write all the entries
for (Map.Entry<String, NbtBase<?>> entry : newValue.entrySet()) {
Object value = entry.getValue();
// We don't really know
if (value instanceof NbtBase)
put(entry.getValue());
else
putObject(entry.getKey(), entry.getValue());
if (entry.getValue() == null) putObject(entry.getKey(), null);
else put(entry.getValue());
}
}
@ -287,7 +282,7 @@ class WrappedCompound implements NbtWrapper<Map<String, NbtBase<?>>>, NbtCompoun
} else if (value instanceof NbtBase) {
put(key, (NbtBase<?>) value);
} else {
NbtBase<?> base = new MemoryElement<Object>(key, value);
NbtBase<?> base = new MemoryElement<>(key, value);
put(base);
}
return this;
@ -671,16 +666,16 @@ class WrappedCompound implements NbtWrapper<Map<String, NbtBase<?>>>, NbtCompoun
StringBuilder builder = new StringBuilder();
builder.append("{");
builder.append("\"name\": \"" + getName() + "\"");
builder.append("\"name\": \"").append(getName()).append("\"");
for (NbtBase<?> element : this) {
builder.append(", ");
// Wrap in quotation marks
if (element.getType() == NbtType.TAG_STRING)
builder.append("\"" + element.getName() + "\": \"" + element.getValue() + "\"");
builder.append("\"").append(element.getName()).append("\": \"").append(element.getValue()).append("\"");
else
builder.append("\"" + element.getName() + "\": " + element.getValue());
builder.append("\"").append(element.getName()).append("\": ").append(element.getValue());
}
builder.append("}");

View File

@ -17,9 +17,6 @@
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.FuzzyReflection;
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.google.common.base.Objects;
import java.io.DataOutput;
import java.lang.reflect.Method;
/**
* Represents a wrapped NBT tag element, composite or not.
*
@ -43,7 +43,7 @@ class WrappedElement<TType> implements NbtWrapper<TType> {
private static volatile Boolean hasNbtName;
// 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
private Object handle;
@ -107,15 +107,15 @@ class WrappedElement<TType> implements NbtWrapper<TType> {
@SuppressWarnings("unchecked")
protected StructureModifier<Object> getCurrentBaseModifier() {
int index = getType().ordinal();
StructureModifier<Object> modifier = (StructureModifier<Object>) modifiers[index];
StructureModifier<Object> modifier = (StructureModifier<Object>) MODIFIERS[index];
// Double checked locking
if (modifier == null) {
synchronized (this) {
if (modifiers[index] == null) {
modifiers[index] = new StructureModifier<Object>(handle.getClass(), MinecraftReflection.getNBTBaseClass(), false);
if (MODIFIERS[index] == null) {
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
StringBuilder builder = new StringBuilder();
builder.append("{\"name\": \"" + getName() + "\", \"value\": [");
builder.append("{\"name\": \"").append(getName()).append("\", \"value\": [");
if (size() > 0) {
if (getElementType() == NbtType.TAG_STRING)
builder.append("\"" + Joiner.on("\", \"").join(this) + "\"");
builder.append("\"").append(Joiner.on("\", \"").join(this)).append("\"");
else
builder.append(Joiner.on(", ").join(this));
}

View File

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

View File

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