diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitMain.java b/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitMain.java
index a0f19cb6e..d6c38bec4 100644
--- a/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitMain.java
+++ b/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitMain.java
@@ -88,7 +88,6 @@ import com.plotsquared.core.plot.world.SinglePlotAreaManager;
import com.plotsquared.core.queue.QueueProvider;
import com.plotsquared.core.setup.PlotAreaBuilder;
import com.plotsquared.core.setup.SettingsNodesWrapper;
-import com.plotsquared.core.util.ChatManager;
import com.plotsquared.core.util.ChunkManager;
import com.plotsquared.core.util.ConsoleColors;
import com.plotsquared.core.util.EconHandler;
diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/chat/ArrayWrapper.java b/Bukkit/src/main/java/com/plotsquared/bukkit/chat/ArrayWrapper.java
deleted file mode 100644
index 41aaf4451..000000000
--- a/Bukkit/src/main/java/com/plotsquared/bukkit/chat/ArrayWrapper.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * _____ _ _ _____ _
- * | __ \| | | | / ____| | |
- * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
- * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
- * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
- * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
- * | |
- * |_|
- * PlotSquared plot management system for Minecraft
- * Copyright (C) 2020 IntellectualSites
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see
- * This class is intended for use as a key to a map. - *
- * - * @param- * This class follows the builder pattern, allowing for method chaining. - * It is set up such that invocations of property-setting methods will affect the current editing component, - * and a call to {@link #then()} or {@link #then(String)} will append a new editing component to the end of the message, - * optionally initializing it with text. Further property-setting method calls will affect that editing component. - *
- */ -public class FancyMessage - implements JsonRepresentedObject, Cloneable, IterableTooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.
- * - * @param name The name of the achievement to display, excluding the "achievement." prefix. - * @return This builder instance. - */ - public FancyMessage achievementTooltip(final String name) { - onHover("show_achievement", new JsonString("achievement." + name)); - return this; - } - - /** - * Set the behavior of the current editing component to display information about a parameterless statistic when the client hovers over the text. - *Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.
- * - * @param which The statistic to display. - * @return This builder instance. - * @throws IllegalArgumentException If the statistic requires a parameter which was not supplied. - */ - public FancyMessage statisticTooltip(final Statistic which) { - Type type = which.getType(); - if (type != Type.UNTYPED) { - throw new IllegalArgumentException( - "That statistic requires an additional " + type + " parameter!"); - } - try { - Object statistic = Reflection - .getMethod(Reflection.getOBCClass("CraftStatistic"), "getNMSStatistic", - Statistic.class).invoke(null, which); - return achievementTooltip( - (String) Reflection.getField(Reflection.getNMSClass("Statistic"), "name") - .get(statistic)); - } catch (IllegalAccessException e) { - Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e); - return this; - } catch (IllegalArgumentException e) { - Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e); - return this; - } catch (InvocationTargetException e) { - Bukkit.getLogger() - .log(Level.WARNING, "A error has occurred during invoking of method.", e); - return this; - } - } - - /** - * Set the behavior of the current editing component to display information about a statistic parameter with a material when the client hovers over the text. - *Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.
- * - * @param which The statistic to display. - * @param item The sole material parameter to the statistic. - * @return This builder instance. - * @throws IllegalArgumentException If the statistic requires a parameter which was not supplied, or was supplied a parameter that was not required. - */ - public FancyMessage statisticTooltip(final Statistic which, Material item) { - Type type = which.getType(); - if (type == Type.UNTYPED) { - throw new IllegalArgumentException("That statistic needs no additional parameter!"); - } - if ((type == Type.BLOCK && item.isBlock()) || type == Type.ENTITY) { - throw new IllegalArgumentException( - "Wrong parameter type for that statistic - needs " + type + "!"); - } - try { - Object statistic = Reflection - .getMethod(Reflection.getOBCClass("CraftStatistic"), "getMaterialStatistic", - Statistic.class, Material.class).invoke(null, which, item); - return achievementTooltip( - (String) Reflection.getField(Reflection.getNMSClass("Statistic"), "name") - .get(statistic)); - } catch (IllegalAccessException e) { - Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e); - return this; - } catch (IllegalArgumentException e) { - Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e); - return this; - } catch (InvocationTargetException e) { - Bukkit.getLogger() - .log(Level.WARNING, "A error has occurred during invoking of method.", e); - return this; - } - } - - /** - * Set the behavior of the current editing component to display information about a statistic parameter with an entity type when the client hovers over the text. - *Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.
- * - * @param which The statistic to display. - * @param entity The sole entity type parameter to the statistic. - * @return This builder instance. - * @throws IllegalArgumentException If the statistic requires a parameter which was not supplied, or was supplied a parameter that was not required. - */ - public FancyMessage statisticTooltip(final Statistic which, EntityType entity) { - Type type = which.getType(); - if (type == Type.UNTYPED) { - throw new IllegalArgumentException("That statistic needs no additional parameter!"); - } - if (type != Type.ENTITY) { - throw new IllegalArgumentException( - "Wrong parameter type for that statistic - needs " + type + "!"); - } - try { - Object statistic = Reflection - .getMethod(Reflection.getOBCClass("CraftStatistic"), "getEntityStatistic", - Statistic.class, EntityType.class).invoke(null, which, entity); - return achievementTooltip( - (String) Reflection.getField(Reflection.getNMSClass("Statistic"), "name") - .get(statistic)); - } catch (IllegalAccessException e) { - Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e); - return this; - } catch (IllegalArgumentException e) { - Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e); - return this; - } catch (InvocationTargetException e) { - Bukkit.getLogger() - .log(Level.WARNING, "A error has occurred during invoking of method.", e); - return this; - } - } - - /** - * Set the behavior of the current editing component to display information about an item when the client hovers over the text. - *Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.
- * - * @param itemJSON A string representing the JSON-serialized NBT data tag of an {@link ItemStack}. - * @return This builder instance. - */ - public FancyMessage itemTooltip(final String itemJSON) { - onHover("show_item", new JsonString( - itemJSON)); // Seems a bit hacky, considering we have a JSON object as a parameter - return this; - } - - /** - * Set the behavior of the current editing component to display information about an item when the client hovers over the text. - *Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.
- * - * @param itemStack The stack for which to display information. - * @return This builder instance. - */ - public FancyMessage itemTooltip(final ItemStack itemStack) { - try { - Object nmsItem = Reflection - .getMethod(Reflection.getOBCClass("inventory.CraftItemStack"), "asNMSCopy", - ItemStack.class).invoke(null, itemStack); - return itemTooltip(Reflection.getMethod(Reflection.getNMSClass("ItemStack"), "save", - Reflection.getNMSClass("NBTTagCompound")) - .invoke(nmsItem, Reflection.getNMSClass("NBTTagCompound").newInstance()) - .toString()); - } catch (Exception e) { - e.printStackTrace(); - return this; - } - } - - /** - * Set the behavior of the current editing component to display raw text when the client hovers over the text. - *Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.
- * - * @param text The text, which supports newlines, which will be displayed to the client upon hovering. - * @return This builder instance. - */ - public FancyMessage tooltip(final String text) { - onHover("show_text", new JsonString(text)); - return this; - } - - /** - * Set the behavior of the current editing component to display raw text when the client hovers over the text. - *Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.
- * - * @param lines The lines of text which will be displayed to the client upon hovering. The iteration order of this object will be the order in which the lines of the tooltip are created. - * @return This builder instance. - */ - public FancyMessage tooltip(final IterableTooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.
- * - * @param lines The lines of text which will be displayed to the client upon hovering. - * @return This builder instance. - */ - public FancyMessage tooltip(final String... lines) { - StringBuilder builder = new StringBuilder(); - for (int i = 0; i < lines.length; i++) { - builder.append(lines[i]); - if (i != lines.length - 1) { - builder.append('\n'); - } - } - tooltip(builder.toString()); - return this; - } - - /** - * Set the behavior of the current editing component to display formatted text when the client hovers over the text. - *Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.
- * - * @param text The formatted text which will be displayed to the client upon hovering. - * @return This builder instance. - */ - public FancyMessage formattedTooltip(FancyMessage text) { - for (MessagePart component : text.messageParts) { - if (component.clickActionData != null && component.clickActionName != null) { - throw new IllegalArgumentException("The tooltip text cannot have click data."); - } else if (component.hoverActionData != null && component.hoverActionName != null) { - throw new IllegalArgumentException("The tooltip text cannot have a tooltip."); - } - } - onHover("show_text", text); - return this; - } - - /** - * Set the behavior of the current editing component to display the specified lines of formatted text when the client hovers over the text. - *Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.
- * - * @param lines The lines of formatted text which will be displayed to the client upon hovering. - * @return This builder instance. - */ - public FancyMessage formattedTooltip(FancyMessage... lines) { - if (lines.length < 1) { - onHover(null, null); // Clear tooltip - return this; - } - - FancyMessage result = new FancyMessage(); - result.messageParts - .clear(); // Remove the one existing text component that exists by default, which destabilizes the object - - for (int i = 0; i < lines.length; i++) { - try { - for (MessagePart component : lines[i]) { - if (component.clickActionData != null && component.clickActionName != null) { - throw new IllegalArgumentException( - "The tooltip text cannot have click data."); - } else if (component.hoverActionData != null - && component.hoverActionName != null) { - throw new IllegalArgumentException( - "The tooltip text cannot have a tooltip."); - } - if (component.hasText()) { - result.messageParts.add(component.clone()); - } - } - if (i != lines.length - 1) { - result.messageParts.add(new MessagePart(TextualComponent.rawText("\n"))); - } - } catch (CloneNotSupportedException e) { - Bukkit.getLogger().log(Level.WARNING, "Failed to clone object", e); - return this; - } - } - return formattedTooltip( - result.messageParts.isEmpty() ? null : result); // Throws NPE if size is 0, intended - } - - /** - * Set the behavior of the current editing component to display the specified lines of formatted text when the client hovers over the text. - *Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.
- * - * @param lines The lines of text which will be displayed to the client upon hovering. The iteration order of this object will be the order in which the lines of the tooltip are created. - * @return This builder instance. - */ - public FancyMessage formattedTooltip(final Iterable- * Serialization of this message by using this message will include (in this order for each message part): - *
- * Color and formatting can be removed from the returned string by using {@link ChatColor#stripColor(String)}.
- * - * @return A human-readable string representing limited formatting in addition to the core text of this message. - */ - public String toOldMessageFormat() { - StringBuilder result = new StringBuilder(); - for (MessagePart part : this) { - result.append(part.color == null ? "" : part.color); - for (ChatColor formatSpecifier : part.styles) { - result.append(formatSpecifier); - } - result.append(part.text); - } - return result.toString(); - } - - private MessagePart latest() { - return messageParts.get(messageParts.size() - 1); - } - - private void onClick(final String name, final String data) { - final MessagePart latest = latest(); - latest.clickActionName = name; - latest.clickActionData = data; - dirty = true; - } - - private void onHover(final String name, final JsonRepresentedObject data) { - final MessagePart latest = latest(); - latest.hoverActionName = name; - latest.hoverActionData = data; - dirty = true; - } - - // Doc copied from interface - public Map- * The only match currently attempted by this method is a retrieval by using a parameterless {@code getHandle()} method implemented by the runtime type of the specified object. - *
- * - * @param obj The object for which to retrieve an NMS handle. - * @return The NMS handle of the specified object, or {@code null} if it could not be retrieved using {@code getHandle()}. - */ - public synchronized static Object getHandle(Object obj) - throws InvocationTargetException, IllegalAccessException, IllegalArgumentException { - return getMethod(obj.getClass(), "getHandle").invoke(obj); - } - - /** - * Retrieves a {@link Field} instance declared by the specified class with the specified name. - * Java access modifiers are ignored during this retrieval. No guarantee is made as to whether the field - * returned will be an instance or static field. - *- * A global caching mechanism within this class is used to store fields. Combined with synchronization, this guarantees that - * no field will be reflectively looked up twice. - *
- *- * If a field is deemed suitable for return, {@link Field#setAccessible(boolean) setAccessible} will be invoked with an argument of {@code true} before it is returned. - * This ensures that callers do not have to check or worry about Java access modifiers when dealing with the returned instance. - *
- * - * @param clazz The class which contains the field to retrieve. - * @param name The declared name of the field in the class. - * @return A field object with the specified name declared by the specified class. - * @see Class#getDeclaredField(String) - */ - public synchronized static Field getField(Class> clazz, String name) { - Map- * A global caching mechanism within this class is used to store method. Combined with synchronization, this guarantees that - * no method will be reflectively looked up twice. - *
- * If a method is deemed suitable for return, {@link Method#setAccessible(boolean) setAccessible} will be invoked with an argument of {@code true} before it is returned. - * This ensures that callers do not have to check or worry about Java access modifiers when dealing with the returned instance. - *
- * This method does not search superclasses of the specified type for methods with the specified signature.
- * Callers wishing this behavior should use {@link Class#getDeclaredMethod(String, Class...)}.
- *
- * @param clazz The class which contains the method to retrieve.
- * @param name The declared name of the method in the class.
- * @param args The formal argument types of the method.
- * @return A method object with the specified name declared by the specified class.
- */
- public synchronized static Method getMethod(Class> clazz, String name, Class>... args) {
- _loadedMethods.computeIfAbsent(clazz, k -> new HashMap<>());
-
- Map Different instances of this class can be created with static constructor methods. This is the default type of textual component when a single string
- * literal is given to a method.
- *
- * @param textValue The text which will be represented.
- * @return The text component representing the specified literal text.
- */
- public static TextualComponent rawText(String textValue) {
- return new ArbitraryTextTypeComponent("text", textValue);
- }
-
- /**
- * Create a textual component representing a localized string.
- * The client will see this text component as their localized version of the specified string key, which can be overridden by a
- * resource pack.
- *
- * If the specified translation key is not present on the client resource pack, the translation key will be displayed as a string literal to
- * the client.
- *
- * This method is currently guaranteed to throw an {@code UnsupportedOperationException} as it is only supported on snapshot clients.
- * This method is currently guaranteed to throw an {@code UnsupportedOperationException}
- * as it is only supported on snapshot clients.
- *
- * @param playerName The name of the player whos score will be shown. If
- * this string represents the single-character sequence
- * "*", the viewing player's score will be displayed.
- * Standard minecraft selectors (@a, @p, etc)
- * are not supported.
- * @param scoreboardObjective The name of the objective for
- * which to display the score.
- * @return The text component representing the specified scoreboard score
- * for the specified player, or {@code null} if an error occurs during JSON serialization.
- */
- public static TextualComponent objectiveScore(String playerName, String scoreboardObjective) {
- throwUnsupportedSnapshot(); // Remove this line when the feature is released to non-snapshot versions, in addition to updating ALL THE
- // OVERLOADS documentation accordingly
-
- return new ComplexTextTypeComponent("score",
- ImmutableMap.
- * This method is currently guaranteed to throw an {@code UnsupportedOperationException} as it is only supported on snapshot clients.
- * Exception validating done is on keys and values.
- */
- private static final class ComplexTextTypeComponent extends TextualComponent
- implements ConfigurationSerializable {
-
- private String key;
- private Map> {
-
- @Override public List