Almost finished documenting and lombokifying eco-util

This commit is contained in:
Auxilor 2020-12-23 19:37:31 +00:00
parent 56ac45820d
commit 90dbdcb5d9
35 changed files with 658 additions and 507 deletions

View File

@ -8,6 +8,7 @@ import com.willfp.eco.core.proxy.proxies.ChatComponentProxy;
import com.willfp.eco.util.ProxyUtils; import com.willfp.eco.util.ProxyUtils;
import com.willfp.eco.util.packets.AbstractPacketAdapter; import com.willfp.eco.util.packets.AbstractPacketAdapter;
import com.willfp.eco.util.plugin.AbstractEcoPlugin; import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import org.jetbrains.annotations.NotNull;
public class PacketChat extends AbstractPacketAdapter { public class PacketChat extends AbstractPacketAdapter {
public PacketChat(AbstractEcoPlugin plugin) { public PacketChat(AbstractEcoPlugin plugin) {
@ -15,7 +16,7 @@ public class PacketChat extends AbstractPacketAdapter {
} }
@Override @Override
public void onSend(PacketContainer packet) { public void onSend(@NotNull PacketContainer packet) {
for (int i = 0; i < packet.getChatComponents().size(); i++) { for (int i = 0; i < packet.getChatComponents().size(); i++) {
WrappedChatComponent component = packet.getChatComponents().read(i); WrappedChatComponent component = packet.getChatComponents().read(i);
if (component == null) if (component == null)

View File

@ -9,6 +9,7 @@ import com.willfp.ecoenchants.display.EnchantDisplay;
import com.willfp.ecoenchants.enchantments.meta.EnchantmentTarget; import com.willfp.ecoenchants.enchantments.meta.EnchantmentTarget;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.MerchantRecipe; import org.bukkit.inventory.MerchantRecipe;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
@ -22,7 +23,7 @@ public class PacketOpenWindowMerchant extends AbstractPacketAdapter {
} }
@Override @Override
public void onSend(PacketContainer packet) { public void onSend(@NotNull PacketContainer packet) {
List<MerchantRecipe> recipes = packet.getMerchantRecipeLists().readSafely(0); List<MerchantRecipe> recipes = packet.getMerchantRecipeLists().readSafely(0);
recipes = recipes.stream().peek(merchantRecipe -> { recipes = recipes.stream().peek(merchantRecipe -> {

View File

@ -5,6 +5,7 @@ import com.comphenix.protocol.events.PacketContainer;
import com.willfp.eco.util.packets.AbstractPacketAdapter; import com.willfp.eco.util.packets.AbstractPacketAdapter;
import com.willfp.eco.util.plugin.AbstractEcoPlugin; import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import com.willfp.ecoenchants.display.EnchantDisplay; import com.willfp.ecoenchants.display.EnchantDisplay;
import org.jetbrains.annotations.NotNull;
public class PacketSetCreativeSlot extends AbstractPacketAdapter { public class PacketSetCreativeSlot extends AbstractPacketAdapter {
public PacketSetCreativeSlot(AbstractEcoPlugin plugin) { public PacketSetCreativeSlot(AbstractEcoPlugin plugin) {
@ -12,7 +13,7 @@ public class PacketSetCreativeSlot extends AbstractPacketAdapter {
} }
@Override @Override
public void onReceive(PacketContainer packet) { public void onReceive(@NotNull PacketContainer packet) {
packet.getItemModifier().modify(0, (item) -> { packet.getItemModifier().modify(0, (item) -> {
item = EnchantDisplay.revertDisplay(item); item = EnchantDisplay.revertDisplay(item);
return item; return item;

View File

@ -6,6 +6,7 @@ import com.willfp.eco.util.packets.AbstractPacketAdapter;
import com.willfp.eco.util.plugin.AbstractEcoPlugin; import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import com.willfp.ecoenchants.display.EnchantDisplay; import com.willfp.ecoenchants.display.EnchantDisplay;
import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemFlag;
import org.jetbrains.annotations.NotNull;
public class PacketSetSlot extends AbstractPacketAdapter { public class PacketSetSlot extends AbstractPacketAdapter {
public PacketSetSlot(AbstractEcoPlugin plugin) { public PacketSetSlot(AbstractEcoPlugin plugin) {
@ -13,7 +14,7 @@ public class PacketSetSlot extends AbstractPacketAdapter {
} }
@Override @Override
public void onSend(PacketContainer packet) { public void onSend(@NotNull PacketContainer packet) {
packet.getItemModifier().modify(0, (item) -> { packet.getItemModifier().modify(0, (item) -> {
boolean hideEnchants = false; boolean hideEnchants = false;

View File

@ -6,6 +6,7 @@ import com.willfp.eco.util.packets.AbstractPacketAdapter;
import com.willfp.eco.util.plugin.AbstractEcoPlugin; import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import com.willfp.ecoenchants.display.EnchantDisplay; import com.willfp.ecoenchants.display.EnchantDisplay;
import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemFlag;
import org.jetbrains.annotations.NotNull;
public class PacketWindowItems extends AbstractPacketAdapter { public class PacketWindowItems extends AbstractPacketAdapter {
public PacketWindowItems(AbstractEcoPlugin plugin) { public PacketWindowItems(AbstractEcoPlugin plugin) {
@ -13,7 +14,7 @@ public class PacketWindowItems extends AbstractPacketAdapter {
} }
@Override @Override
public void onSend(PacketContainer packet) { public void onSend(@NotNull PacketContainer packet) {
packet.getItemListModifier().modify(0, (itemStacks) -> { packet.getItemListModifier().modify(0, (itemStacks) -> {
if (itemStacks == null) return null; if (itemStacks == null) return null;
itemStacks.forEach(item -> { itemStacks.forEach(item -> {

View File

@ -1,21 +1,28 @@
package com.willfp.eco.util; package com.willfp.eco.util;
import lombok.experimental.UtilityClass;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@UtilityClass
public class BlockUtils { public class BlockUtils {
private static Set<Block> getNearbyBlocks(Block start, List<Material> allowedMaterials, HashSet<Block> blocks, int limit) { private Set<Block> getNearbyBlocks(@NotNull final Block start,
@NotNull final List<Material> allowedMaterials,
@NotNull final HashSet<Block> blocks,
final int limit) {
for (BlockFace face : BlockFace.values()) { for (BlockFace face : BlockFace.values()) {
Block block = start.getRelative(face); Block block = start.getRelative(face);
if (!blocks.contains(block) && allowedMaterials.contains(block.getType())) { if (!blocks.contains(block) && allowedMaterials.contains(block.getType())) {
blocks.add(block); blocks.add(block);
if (blocks.size() > limit) return blocks; if (blocks.size() > limit || blocks.size() > 2500) {
if (blocks.size() > 2500) return blocks; // anti stack overflow return blocks;
}
blocks.addAll(getNearbyBlocks(block, allowedMaterials, blocks, limit)); blocks.addAll(getNearbyBlocks(block, allowedMaterials, blocks, limit));
} }
} }
@ -24,15 +31,17 @@ public class BlockUtils {
/** /**
* Get a set of all blocks in contact with each other of a specific type * Get a set of all blocks in contact with each other of a specific type.
* *
* @param start The initial block * @param start The initial block.
* @param allowedMaterials A list of all valid {@link Material}s * @param allowedMaterials A list of all valid {@link Material}s.
* @param limit The maximum size of vein to return * @param limit The maximum size of vein to return.
* *
* @return A set of all {@link Block}s * @return A set of all {@link Block}s.
*/ */
public static Set<Block> getVein(Block start, List<Material> allowedMaterials, int limit) { public Set<Block> getVein(@NotNull final Block start,
@NotNull final List<Material> allowedMaterials,
final int limit) {
return getNearbyBlocks(start, allowedMaterials, new HashSet<>(), limit); return getNearbyBlocks(start, allowedMaterials, new HashSet<>(), limit);
} }
} }

View File

@ -1,16 +1,18 @@
package com.willfp.eco.util; package com.willfp.eco.util;
import lombok.experimental.UtilityClass;
import org.jetbrains.annotations.NotNull;
@UtilityClass
public class ClassUtils { public class ClassUtils {
/** /**
* Get if a class exists * Get if a class exists.
*
* @param className The class to check
*
* @return If the class exists
* *
* @param className The class to check.
* @return If the class exists.
* @see Class#forName(String) * @see Class#forName(String)
*/ */
public static boolean exists(String className) { public boolean exists(@NotNull final String className) {
try { try {
Class.forName(className); Class.forName(className);
return true; return true;

View File

@ -1,5 +1,6 @@
package com.willfp.eco.util; package com.willfp.eco.util;
import lombok.experimental.UtilityClass;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.SoundCategory; import org.bukkit.SoundCategory;
@ -10,26 +11,31 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory; import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.Damageable; import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
/** @UtilityClass
* Contains methods for damaging/repairing items
*/
public class DurabilityUtils { public class DurabilityUtils {
/** /**
* Damage an item in a player's inventory * Damage an item in a player's inventory.
* The slot of a held item can be obtained with {@link PlayerInventory#getHeldItemSlot()} * The slot of a held item can be obtained with {@link PlayerInventory#getHeldItemSlot()}.
* Armor slots are 39 (helmet), 38 (chestplate), 37 (leggings), 36 (boots) * Armor slots are 39 (helmet), 38 (chestplate), 37 (leggings), 36 (boots).
* *
* @param player The player * @param player The player.
* @param item The item to damage * @param item The item to damage.
* @param damage The amount of damage to deal * @param damage The amount of damage to deal.
* @param slot The slot in the inventory of the item * @param slot The slot in the inventory of the item.
*/ */
public static void damageItem(Player player, ItemStack item, int damage, int slot) { public void damageItem(@NotNull final Player player,
if (item == null) return; @NotNull final ItemStack item,
if (item.getItemMeta() == null) return; final int damage,
final int slot) {
if (item.getItemMeta() == null) {
return;
}
if (item.getItemMeta().isUnbreakable()) return; if (item.getItemMeta().isUnbreakable()) {
return;
}
PlayerItemDamageEvent event3 = new PlayerItemDamageEvent(player, item, damage); PlayerItemDamageEvent event3 = new PlayerItemDamageEvent(player, item, damage);
Bukkit.getPluginManager().callEvent(event3); Bukkit.getPluginManager().callEvent(event3);
@ -55,19 +61,22 @@ public class DurabilityUtils {
} }
/** /**
* Damage an item in a player's inventory without breaking it * Damage an item in a player's inventory without breaking it.
* The slot of a held item can be obtained with {@link PlayerInventory#getHeldItemSlot()}
* Armor slots are 39 (helmet), 38 (chestplate), 37 (leggings), 36 (boots)
* *
* @param item The item to damage * @param item The item to damage.
* @param damage The amount of damage to deal * @param damage The amount of damage to deal.
* @param player The player * @param player The player.
*/ */
public static void damageItemNoBreak(ItemStack item, int damage, Player player) { public void damageItemNoBreak(@NotNull final ItemStack item,
if (item == null) return; final int damage,
if (item.getItemMeta() == null) return; @NotNull final Player player) {
if (item.getItemMeta() == null) {
return;
}
if (item.getItemMeta().isUnbreakable()) return; if (item.getItemMeta().isUnbreakable()) {
return;
}
PlayerItemDamageEvent event3 = new PlayerItemDamageEvent(player, item, damage); PlayerItemDamageEvent event3 = new PlayerItemDamageEvent(player, item, damage);
Bukkit.getPluginManager().callEvent(event3); Bukkit.getPluginManager().callEvent(event3);
@ -87,18 +96,21 @@ public class DurabilityUtils {
} }
/** /**
* Repair an item in a player's inventory * Repair an item in a player's inventory.
* The slot of a held item can be obtained with {@link PlayerInventory#getHeldItemSlot()}
* Armor slots are 39 (helmet), 38 (chestplate), 37 (leggings), 36 (boots)
* *
* @param item The item to damage * @param item The item to damage.
* @param repair The amount of damage to heal * @param repair The amount of damage to heal.
*/ */
public static void repairItem(ItemStack item, int repair) { public void repairItem(@NotNull final ItemStack item,
if (item == null) return; final int repair) {
if (item.getItemMeta() == null) return; if (item.getItemMeta() == null) {
return;
}
if (item.getItemMeta().isUnbreakable()) {
return;
}
if (item.getItemMeta().isUnbreakable()) return;
if (item.getItemMeta() instanceof Damageable) { if (item.getItemMeta() instanceof Damageable) {
Damageable meta = (Damageable) item.getItemMeta(); Damageable meta = (Damageable) item.getItemMeta();
meta.setDamage(meta.getDamage() - repair); meta.setDamage(meta.getDamage() - repair);

View File

@ -1,22 +1,20 @@
package com.willfp.eco.util; package com.willfp.eco.util;
import lombok.experimental.UtilityClass;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
import org.jetbrains.annotations.NotNull;
/** @UtilityClass
* Class containing methods for striking lightning
*/
public class LightningUtils { public class LightningUtils {
/** /**
* Strike lightning on player without fire * Strike lightning on player without fire.
* *
* @param victim The entity to smite * @param victim The entity to smite.
* @param damage The damage to deal * @param damage The damage to deal.
*/ */
public static void strike(LivingEntity victim, double damage) { public void strike(@NotNull final LivingEntity victim,
if (victim == null) return; final double damage) {
Location loc = victim.getLocation(); Location loc = victim.getLocation();
victim.getWorld().strikeLightningEffect(loc); victim.getWorld().strikeLightningEffect(loc);

View File

@ -1,15 +1,24 @@
package com.willfp.eco.util; package com.willfp.eco.util;
import lombok.experimental.UtilityClass;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.Random; import java.util.Random;
import java.util.TreeMap; import java.util.TreeMap;
@UtilityClass
public class NumberUtils { public class NumberUtils {
/**
* The RNG to use.
*/
private static final Random RANDOM = new Random(); private static final Random RANDOM = new Random();
/**
* Set of roman numerals to look up.
*/
private static final TreeMap<Integer, String> NUMERALS = new TreeMap<>(); private static final TreeMap<Integer, String> NUMERALS = new TreeMap<>();
static { static {
NUMERALS.put(1000, "M"); NUMERALS.put(1000, "M");
NUMERALS.put(900, "CM"); NUMERALS.put(900, "CM");
NUMERALS.put(500, "D"); NUMERALS.put(500, "D");
@ -23,107 +32,102 @@ public class NumberUtils {
NUMERALS.put(5, "V"); NUMERALS.put(5, "V");
NUMERALS.put(4, "IV"); NUMERALS.put(4, "IV");
NUMERALS.put(1, "I"); NUMERALS.put(1, "I");
} }
/** /**
* Bias the input value according to a curve * Bias the input value according to a curve.
* *
* @param input The input value * @param input The input value.
* @param bias The bias between -1 and 1, where higher values bias input values to lower output values * @param bias The bias between -1 and 1, where higher values bias input values to lower output values.
* * @return The biased output.
* @return The biased output
*/ */
public static double bias(double input, double bias) { public double bias(final double input,
final double bias) {
double k = Math.pow(1 - bias, 3); double k = Math.pow(1 - bias, 3);
return (input * k) / (input * k - input + 1); return (input * k) / (input * k - input + 1);
} }
/** /**
* If value is above maximum, set it to maximum * If value is above maximum, set it to maximum.
* *
* @param toChange The value to test * @param toChange The value to test.
* @param limit The maximum * @param limit The maximum.
* * @return The new value.
* @return The new value
*/ */
public static int equalIfOver(int toChange, int limit) { public int equalIfOver(final int toChange,
if (toChange > limit) { final int limit) {
toChange = limit; return Math.min(toChange, limit);
}
return toChange;
} }
/** /**
* If value is above maximum, set it to maximum * If value is above maximum, set it to maximum.
* *
* @param toChange The value to test * @param toChange The value to test.
* @param limit The maximum * @param limit The maximum.
* * @return The new value.
* @return The new value
*/ */
public static double equalIfOver(double toChange, double limit) { public double equalIfOver(final double toChange,
if (toChange > limit) { final double limit) {
toChange = limit; return Math.min(toChange, limit);
}
return toChange;
} }
/** /**
* Get Roman Numeral from number * Get Roman Numeral from number.
* *
* @param number The number to convert * @param number The number to convert.
* * @return The number, converted to a roman numeral.
* @return The number, converted to a roman numeral
*/ */
public static String toNumeral(int number) { public String toNumeral(final int number) {
if (number >= 1 && number <= 4096) { if (number >= 1 && number <= 4096) {
int l = NUMERALS.floorKey(number); int l = NUMERALS.floorKey(number);
if (number == l) { if (number == l) {
return NUMERALS.get(number); return NUMERALS.get(number);
} }
return NUMERALS.get(l) + toNumeral(number - l); return NUMERALS.get(l) + toNumeral(number - l);
} else return String.valueOf(number); } else {
return String.valueOf(number);
}
} }
/** /**
* Generate random integer in range * Generate random integer in range.
* *
* @param min Minimum * @param min Minimum.
* @param max Maximum * @param max Maximum.
* * @return Random integer.
* @return Random integer
*/ */
public static int randInt(int min, int max) { public int randInt(final int min,
final int max) {
return (int) ((long) min + Math.random() * ((long) max - min + 1)); return (int) ((long) min + Math.random() * ((long) max - min + 1));
} }
/** /**
* Generate random double in range * Generate random double in range.
* *
* @param min Minimum * @param min Minimum.
* @param max Maximum * @param max Maximum.
* * @return Random double.
* @return Random double
*/ */
public static double randFloat(double min, double max) { public double randFloat(final double min,
final double max) {
return RANDOM.nextFloat() * (max - min) + min; return RANDOM.nextFloat() * (max - min) + min;
} }
/** /**
* Generate random double with a triangular distribution * Generate random double with a triangular distribution.
* *
* @param minimum Minimum * @param minimum Minimum.
* @param maximum Maximum * @param maximum Maximum.
* @param peak Peak * @param peak Peak.
* * @return Random double.
* @return Random double
*/ */
public static double triangularDistribution(double minimum, double maximum, double peak) { public double triangularDistribution(final double minimum,
double F = (peak - minimum) / (maximum - minimum); final double maximum,
final double peak) {
double f = (peak - minimum) / (maximum - minimum);
double rand = Math.random(); double rand = Math.random();
if (rand < F) { if (rand < f) {
return minimum + Math.sqrt(rand * (maximum - minimum) * (peak - minimum)); return minimum + Math.sqrt(rand * (maximum - minimum) * (peak - minimum));
} else { } else {
return maximum - Math.sqrt((1 - rand) * (maximum - minimum) * (maximum - peak)); return maximum - Math.sqrt((1 - rand) * (maximum - minimum) * (maximum - peak));
@ -131,24 +135,22 @@ public class NumberUtils {
} }
/** /**
* Get Log base 2 of a number * Get Log base 2 of a number.
* *
* @param N The number * @param N The number.
* * @return The result.
* @return The result
*/ */
public static int log2(int N) { public int log2(final int N) {
return (int) (Math.log(N) / Math.log(2)); return (int) (Math.log(N) / Math.log(2));
} }
/** /**
* Format double to string * Format double to string.
* *
* @param toFormat The number to format * @param toFormat The number to format.
* * @return Formatted.
* @return Formatted
*/ */
public static String format(double toFormat) { public String format(final double toFormat) {
DecimalFormat df = new DecimalFormat("0.00"); DecimalFormat df = new DecimalFormat("0.00");
String formatted = df.format(toFormat); String formatted = df.format(toFormat);

View File

@ -1,8 +1,10 @@
package com.willfp.eco.util; package com.willfp.eco.util;
import com.willfp.eco.util.integrations.placeholder.PlaceholderManager; import com.willfp.eco.util.integrations.placeholder.PlaceholderManager;
import lombok.experimental.UtilityClass;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.Collection; import java.util.Collection;
@ -12,16 +14,17 @@ import java.util.stream.Collectors;
import static net.md_5.bungee.api.ChatColor.COLOR_CHAR; import static net.md_5.bungee.api.ChatColor.COLOR_CHAR;
@UtilityClass
public class StringUtils { public class StringUtils {
/** /**
* Translate a string - converts Placeholders and Color codes * Translate a string - converts Placeholders and Color codes.
* *
* @param message The message to translate * @param message The message to translate.
* @param player The player to translate placeholders with respect to * @param player The player to translate placeholders with respect to.
* * @return The message, translated.
* @return The message, translated
*/ */
public static String translate(String message, @Nullable Player player) { public String translate(@NotNull String message,
@Nullable final Player player) {
message = PlaceholderManager.translatePlaceholders(message, player); message = PlaceholderManager.translatePlaceholders(message, player);
message = translateHexColorCodes(message); message = translateHexColorCodes(message);
message = ChatColor.translateAlternateColorCodes('&', message); message = ChatColor.translateAlternateColorCodes('&', message);
@ -29,15 +32,13 @@ public class StringUtils {
} }
/** /**
* Translate a string without respect to a player * Translate a string without respect to a player.
*
* @param message The message to translate
*
* @return The message, translated
* *
* @param message The message to translate.
* @return The message, translated.
* @see StringUtils#translate(String, Player) * @see StringUtils#translate(String, Player)
*/ */
public static String translate(String message) { public String translate(@NotNull String message) {
message = PlaceholderManager.translatePlaceholders(message, null); message = PlaceholderManager.translatePlaceholders(message, null);
message = translateHexColorCodes(message); message = translateHexColorCodes(message);
message = ChatColor.translateAlternateColorCodes('&', message); message = ChatColor.translateAlternateColorCodes('&', message);
@ -60,15 +61,16 @@ public class StringUtils {
} }
/** /**
* Internal implementation of {@link String#valueOf} * Internal implementation of {@link String#valueOf}.
* Formats collections and doubles better * Formats collections and doubles better.
* *
* @param object The object to convert to string * @param object The object to convert to string.
* * @return The object stringified.
* @return The object stringified
*/ */
public static String internalToString(@Nullable Object object) { public String internalToString(@Nullable final Object object) {
if (object == null) return "null"; if (object == null) {
return "null";
}
if (object instanceof Integer) { if (object instanceof Integer) {
return ((Integer) object).toString(); return ((Integer) object).toString();
@ -79,19 +81,21 @@ public class StringUtils {
} else if (object instanceof Collection<?>) { } else if (object instanceof Collection<?>) {
Collection<?> c = (Collection<?>) object; Collection<?> c = (Collection<?>) object;
return c.stream().map(StringUtils::internalToString).collect(Collectors.joining(", ")); return c.stream().map(StringUtils::internalToString).collect(Collectors.joining(", "));
} else return String.valueOf(object); } else {
return String.valueOf(object);
}
} }
/** /**
* Remove a string of characters from the start of a string * Remove a string of characters from the start of a string.
* *
* @param s The string to remove the prefix from * @param s The string to remove the prefix from.
* @param prefix The substring to remove * @param prefix The substring to remove.
* * @return The string with the prefix removed.
* @return The string with the prefix removed
*/ */
public static String removePrefix(String s, String prefix) { public String removePrefix(@NotNull final String s,
if (s != null && prefix != null && s.startsWith(prefix)) { @NotNull final String prefix) {
if (s.startsWith(prefix)) {
return s.substring(prefix.length()); return s.substring(prefix.length());
} }
return s; return s;

View File

@ -1,19 +1,21 @@
package com.willfp.eco.util; package com.willfp.eco.util;
import lombok.experimental.UtilityClass;
import org.bukkit.util.NumberConversions; import org.bukkit.util.NumberConversions;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList; import java.util.ArrayList;
@UtilityClass
public class VectorUtils { public class VectorUtils {
/** /**
* If vector has all components as finite * If vector has all components as finite.
* *
* @param vector The vector to check * @param vector The vector to check.
* * @return If the vector is finite.
* @return If the vector is finite
*/ */
public static boolean isFinite(Vector vector) { public boolean isFinite(@NotNull final Vector vector) {
try { try {
NumberConversions.checkFinite(vector.getX(), "x not finite"); NumberConversions.checkFinite(vector.getX(), "x not finite");
NumberConversions.checkFinite(vector.getY(), "y not finite"); NumberConversions.checkFinite(vector.getY(), "y not finite");
@ -26,13 +28,12 @@ public class VectorUtils {
/** /**
* Only keep largest part of normalised vector. * Only keep largest part of normalised vector.
* For example: -0.8, 0.01, -0.2 would become -1, 0, 0 * For example: -0.8, 0.01, -0.2 would become -1, 0, 0.
* *
* @param vec The vector to simplify * @param vec The vector to simplify.
* * @return The vector, simplified.
* @return The vector, simplified
*/ */
public static Vector simplifyVector(Vector vec) { public Vector simplifyVector(@NotNull final Vector vec) {
double x = Math.abs(vec.getX()); double x = Math.abs(vec.getX());
double y = Math.abs(vec.getY()); double y = Math.abs(vec.getY());
double z = Math.abs(vec.getZ()); double z = Math.abs(vec.getZ());
@ -59,13 +60,12 @@ public class VectorUtils {
} }
/** /**
* Get circle as relative vectors * Get circle as relative vectors.
* *
* @param radius The radius * @param radius The radius.
* * @return An array of {@link Vector}s.
* @return An array of {@link Vector}s
*/ */
public static Vector[] getCircle(int radius) { public Vector[] getCircle(final int radius) {
ArrayList<Vector> circleVecs = new ArrayList<>(); ArrayList<Vector> circleVecs = new ArrayList<>();
int xoffset = -radius; int xoffset = -radius;
@ -89,13 +89,12 @@ public class VectorUtils {
} }
/** /**
* Get square as relative vectors * Get square as relative vectors.
* *
* @param radius The radius of the square * @param radius The radius of the square.
* * @return An array of {@link Vector}s.
* @return An array of {@link Vector}s
*/ */
public static Vector[] getSquare(int radius) { public Vector[] getSquare(final int radius) {
ArrayList<Vector> circleVecs = new ArrayList<>(); ArrayList<Vector> circleVecs = new ArrayList<>();
int xoffset = -radius; int xoffset = -radius;
@ -114,30 +113,20 @@ public class VectorUtils {
} }
/** /**
* Get cube as relative vectors * Get cube as relative vectors.
* *
* @param radius The radius of the cube * @param radius The radius of the cube.
* * @return An array of {@link Vector}s.
* @return An array of {@link Vector}s
*/ */
public static Vector[] getCube(int radius) { public Vector[] getCube(final int radius) {
ArrayList<Vector> cubeVecs = new ArrayList<>(); ArrayList<Vector> cubeVecs = new ArrayList<>();
int xoffset = -radius; for (int y = -radius; y <= radius; y++) {
int zoffset = -radius; for (int z = -radius; z <= radius; z++) {
int yoffset = -radius; for (int x = -radius; x <= radius; x++) {
cubeVecs.add(new Vector(x, y, z));
while (yoffset <= radius) {
while (zoffset <= radius) {
while (xoffset <= radius) {
cubeVecs.add(new Vector(xoffset, yoffset, zoffset));
xoffset++;
} }
xoffset = -radius;
zoffset++;
} }
zoffset = -radius;
yoffset++;
} }
return cubeVecs.toArray(new Vector[0]); return cubeVecs.toArray(new Vector[0]);

View File

@ -1,6 +1,6 @@
package com.willfp.eco.util.drops.telekinesis; package com.willfp.eco.util.drops.telekinesis;
import com.willfp.eco.util.lambda.ObjectBiCallable; import com.willfp.eco.util.lambda.ObjectInputCallable;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -11,7 +11,7 @@ public class EcoTelekinesisTests implements TelekinesisTests {
/** /**
* Set of tests that return if the player is telekinetic. * Set of tests that return if the player is telekinetic.
*/ */
private final Set<ObjectBiCallable<Boolean, Player>> tests = new HashSet<>(); private final Set<ObjectInputCallable<Boolean, Player>> tests = new HashSet<>();
/** /**
* Register a new test to check against. * Register a new test to check against.
@ -19,7 +19,7 @@ public class EcoTelekinesisTests implements TelekinesisTests {
* @param test The test to register, where the boolean output is if the player is telekinetic. * @param test The test to register, where the boolean output is if the player is telekinetic.
*/ */
@Override @Override
public void registerTest(@NotNull final ObjectBiCallable<Boolean, Player> test) { public void registerTest(@NotNull final ObjectInputCallable<Boolean, Player> test) {
tests.add(test); tests.add(test);
} }
@ -33,7 +33,7 @@ public class EcoTelekinesisTests implements TelekinesisTests {
*/ */
@Override @Override
public boolean testPlayer(@NotNull final Player player) { public boolean testPlayer(@NotNull final Player player) {
for (ObjectBiCallable<Boolean, Player> test : tests) { for (ObjectInputCallable<Boolean, Player> test : tests) {
if (test.call(player)) { if (test.call(player)) {
return true; return true;
} }

View File

@ -1,6 +1,6 @@
package com.willfp.eco.util.drops.telekinesis; package com.willfp.eco.util.drops.telekinesis;
import com.willfp.eco.util.lambda.ObjectBiCallable; import com.willfp.eco.util.lambda.ObjectInputCallable;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -10,7 +10,7 @@ public interface TelekinesisTests {
* *
* @param test The test to register, where the boolean output is if the player is telekinetic. * @param test The test to register, where the boolean output is if the player is telekinetic.
*/ */
void registerTest(@NotNull ObjectBiCallable<Boolean, Player> test); void registerTest(@NotNull ObjectInputCallable<Boolean, Player> test);
/** /**
* Test the player for telekinesis. * Test the player for telekinesis.

View File

@ -1,25 +1,32 @@
package com.willfp.eco.util.integrations.anticheat; package com.willfp.eco.util.integrations.anticheat;
import com.willfp.eco.util.plugin.AbstractEcoPlugin; import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import lombok.experimental.UtilityClass;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
/** @UtilityClass
* Utility class for Anticheat Integrations
*/
public class AnticheatManager { public class AnticheatManager {
private static final AbstractEcoPlugin plugin = AbstractEcoPlugin.getInstance(); /**
private static final Set<AnticheatWrapper> anticheats = new HashSet<>(); * The linked {@link AbstractEcoPlugin} to register anticheat listeners to.
*/
private final AbstractEcoPlugin plugin = AbstractEcoPlugin.getInstance();
/** /**
* Register a new anticheat * A set of all registered anticheats.
*
* @param anticheat The anticheat to register
*/ */
public static void register(AnticheatWrapper anticheat) { private final Set<AnticheatWrapper> anticheats = new HashSet<>();
/**
* Register a new anticheat.
*
* @param anticheat The anticheat to register.
*/
public void register(@NotNull final AnticheatWrapper anticheat) {
if (anticheat instanceof Listener) { if (anticheat instanceof Listener) {
plugin.getEventManager().registerListener((Listener) anticheat); plugin.getEventManager().registerListener((Listener) anticheat);
} }
@ -27,21 +34,21 @@ public class AnticheatManager {
} }
/** /**
* Exempt a player from triggering anticheats * Exempt a player from triggering anticheats.
* *
* @param player The player to exempt * @param player The player to exempt.
*/ */
public static void exemptPlayer(Player player) { public void exemptPlayer(@NotNull final Player player) {
anticheats.forEach(anticheat -> anticheat.exempt(player)); anticheats.forEach(anticheat -> anticheat.exempt(player));
} }
/** /**
* Unexempt a player from triggering anticheats * Unexempt a player from triggering anticheats.
* This is ran a tick after it is called to ensure that there are no event timing conflicts * This is ran a tick after it is called to ensure that there are no event timing conflicts.
* *
* @param player The player to remove the exemption * @param player The player to remove the exemption.
*/ */
public static void unexemptPlayer(Player player) { public void unexemptPlayer(@NotNull final Player player) {
plugin.getScheduler().runLater(() -> { plugin.getScheduler().runLater(() -> {
anticheats.forEach(anticheat -> anticheat.unexempt(player)); anticheats.forEach(anticheat -> anticheat.unexempt(player));
}, 1); }, 1);

View File

@ -2,22 +2,20 @@ package com.willfp.eco.util.integrations.anticheat;
import com.willfp.eco.util.integrations.Integration; import com.willfp.eco.util.integrations.Integration;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
/**
* Interface for anticheat integrations
*/
public interface AnticheatWrapper extends Integration { public interface AnticheatWrapper extends Integration {
/** /**
* Exempt a player from checks * Exempt a player from checks.
* *
* @param player The player to exempt * @param player The player to exempt.
*/ */
void exempt(Player player); void exempt(@NotNull Player player);
/** /**
* Unexempt a player from checks * Unexempt a player from checks.
* *
* @param player The player to unexempt * @param player The player to unexempt.
*/ */
void unexempt(Player player); void unexempt(@NotNull Player player);
} }

View File

@ -6,6 +6,7 @@ import me.konsolas.aac.api.AACExemption;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.jetbrains.annotations.NotNull;
public class AnticheatAAC implements AnticheatWrapper, Listener { public class AnticheatAAC implements AnticheatWrapper, Listener {
private final AACExemption ecoEnchantsExemption = new AACExemption("EcoEnchants"); private final AACExemption ecoEnchantsExemption = new AACExemption("EcoEnchants");
@ -17,12 +18,12 @@ public class AnticheatAAC implements AnticheatWrapper, Listener {
} }
@Override @Override
public void exempt(Player player) { public void exempt(@NotNull Player player) {
api.addExemption(player, ecoEnchantsExemption); api.addExemption(player, ecoEnchantsExemption);
} }
@Override @Override
public void unexempt(Player player) { public void unexempt(@NotNull Player player) {
api.removeExemption(player, ecoEnchantsExemption); api.removeExemption(player, ecoEnchantsExemption);
} }
} }

View File

@ -6,6 +6,7 @@ import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@ -20,12 +21,12 @@ public class AnticheatMatrix implements AnticheatWrapper, Listener {
} }
@Override @Override
public void exempt(Player player) { public void exempt(@NotNull Player player) {
this.exempt.add(player.getUniqueId()); this.exempt.add(player.getUniqueId());
} }
@Override @Override
public void unexempt(Player player) { public void unexempt(@NotNull Player player) {
this.exempt.remove(player.getUniqueId()); this.exempt.remove(player.getUniqueId());
} }

View File

@ -4,6 +4,7 @@ import com.willfp.eco.util.integrations.anticheat.AnticheatWrapper;
import fr.neatmonster.nocheatplus.checks.CheckType; import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager; import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@ -18,7 +19,7 @@ public class AnticheatNCP implements AnticheatWrapper {
} }
@Override @Override
public void exempt(Player player) { public void exempt(@NotNull Player player) {
if (!NCPExemptionManager.isExempted(player, CheckType.ALL)) { if (!NCPExemptionManager.isExempted(player, CheckType.ALL)) {
return; return;
} }
@ -29,7 +30,7 @@ public class AnticheatNCP implements AnticheatWrapper {
} }
@Override @Override
public void unexempt(Player player) { public void unexempt(@NotNull Player player) {
if (exempt.remove(player.getUniqueId())) { if (exempt.remove(player.getUniqueId())) {
NCPExemptionManager.unexempt(player, CheckType.ALL); NCPExemptionManager.unexempt(player, CheckType.ALL);
} }

View File

@ -6,6 +6,7 @@ import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@ -20,12 +21,12 @@ public class AnticheatSpartan implements AnticheatWrapper, Listener {
} }
@Override @Override
public void exempt(Player player) { public void exempt(@NotNull Player player) {
this.exempt.add(player.getUniqueId()); this.exempt.add(player.getUniqueId());
} }
@Override @Override
public void unexempt(Player player) { public void unexempt(@NotNull Player player) {
this.exempt.remove(player.getUniqueId()); this.exempt.remove(player.getUniqueId());
} }

View File

@ -1,63 +1,72 @@
package com.willfp.eco.util.integrations.placeholder; package com.willfp.eco.util.integrations.placeholder;
import com.willfp.eco.util.lambda.ObjectBiCallable; import com.willfp.eco.util.lambda.ObjectInputCallable;
import lombok.Getter;
import org.apache.commons.lang.Validate;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
/**
* A placeholder entry consists of an identifier and an {@link ObjectBiCallable} to fetch the result
*/
public class PlaceholderEntry { public class PlaceholderEntry {
/**
* The name of the placeholder, used in lookups.
*/
@Getter
private final String identifier; private final String identifier;
private final ObjectBiCallable<String, Player> function;
/**
* The lambda to retrieve the output of the placeholder given a player.
*/
private final ObjectInputCallable<String, Player> function;
/**
* If the placeholder requires a player to lookup.
*/
private final boolean requiresPlayer; private final boolean requiresPlayer;
/** /**
* Create a placeholder entry that doesn't require a player * Create a placeholder entry that doesn't require a player.
* *
* @param identifier The identifier of the placeholder * @param identifier The identifier of the placeholder.
* @param function A lambda to get the result of the placeholder * @param function A lambda to get the result of the placeholder given a player.
*/ */
public PlaceholderEntry(String identifier, ObjectBiCallable<String, Player> function) { public PlaceholderEntry(@NotNull final String identifier,
@NotNull final ObjectInputCallable<String, Player> function) {
this(identifier, function, false); this(identifier, function, false);
} }
/** /**
* Create a placeholder entry that may require a player * Create a placeholder entry that may require a player.
* *
* @param identifier The identifier of the placeholder * @param identifier The identifier of the placeholder.
* @param function A lambda to get the result of the placeholder * @param function A lambda to get the result of the placeholder.
* @param requiresPlayer If the placeholder requires a player * @param requiresPlayer If the placeholder requires a player.
*/ */
public PlaceholderEntry(String identifier, ObjectBiCallable<String, Player> function, boolean requiresPlayer) { public PlaceholderEntry(@NotNull final String identifier,
@NotNull final ObjectInputCallable<String, Player> function,
final boolean requiresPlayer) {
this.identifier = identifier; this.identifier = identifier;
this.function = function; this.function = function;
this.requiresPlayer = requiresPlayer; this.requiresPlayer = requiresPlayer;
} }
/** /**
* Get the identifier of the placeholder * Get the result of the placeholder with respect to a player.
* *
* @return The identifier * @param player The player to translate with respect to.
* @return The result of the placeholder.
*/ */
public String getIdentifier() { public String getResult(@Nullable final Player player) {
return this.identifier; if (player == null) {
} Validate.isTrue(!requiresPlayer, "null player passed to requiresPlayer placeholder.");
}
/**
* Get the result of the placeholder with respect to a player
*
* @param player The player to translate with respect to
* @return The result of the placeholder
*/
public String getResult(@Nullable Player player) {
return this.function.call(player); return this.function.call(player);
} }
/** /**
* Get if the placeholder requires a player to get a result * Get if the placeholder requires a player to get a result.
* *
* @return If the placeholder requires a player * @return If the placeholder requires a player.
*/ */
public boolean requiresPlayer() { public boolean requiresPlayer() {
return requiresPlayer; return requiresPlayer;

View File

@ -2,23 +2,23 @@ package com.willfp.eco.util.integrations.placeholder;
import com.willfp.eco.util.integrations.Integration; import com.willfp.eco.util.integrations.Integration;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Interface for Placeholder integrations
*/
public interface PlaceholderIntegration extends Integration { public interface PlaceholderIntegration extends Integration {
/** /**
* Register the integration with the specified plugin * Register the integration with the specified plugin.
* Not to be confused with internal registration in {@link PlaceholderManager#addIntegration(PlaceholderIntegration)} * Not to be confused with internal registration in {@link PlaceholderManager#addIntegration(PlaceholderIntegration)}.
*/ */
void registerIntegration(); void registerIntegration();
/** /**
* Translate all the placeholders in a string with respect to a player * Translate all the placeholders in a string with respect to a player.
* *
* @param text The text to translate * @param text The text to translate.
* @param player The player to translate with respect to * @param player The player to translate with respect to.
* @return The string, translated * @return The string, translated.
*/ */
String translate(String text, Player player); String translate(@NotNull String text,
@Nullable Player player);
} }

View File

@ -59,7 +59,7 @@ public class PlaceholderIntegrationPAPI extends PlaceholderExpansion implements
} }
@Override @Override
public String translate(String text, Player player) { public String translate(@NotNull String text, Player player) {
return PlaceholderAPI.setPlaceholders(player, text); return PlaceholderAPI.setPlaceholders(player, text);
} }
} }

View File

@ -1,5 +1,11 @@
package com.willfp.eco.util.interfaces; package com.willfp.eco.util.interfaces;
public interface EcoRunnable extends Runnable { public interface EcoRunnable extends Runnable {
/**
* The EcoRunnable interface is generally used for repeating tasks.
* This method is to retrieve the ticks between repetitions.
*
* @return The ticks between repetitions.
*/
long getTime(); long getTime();
} }

View File

@ -1,8 +1,8 @@
package com.willfp.eco.util.interfaces; package com.willfp.eco.util.interfaces;
/**
* Interface for objects that can be internally registered
*/
public interface Registerable { public interface Registerable {
/**
* Register an object with its respective registry.
*/
void register(); void register();
} }

View File

@ -1,9 +1,12 @@
package com.willfp.eco.util.lambda; package com.willfp.eco.util.lambda;
/** /**
* Simple functional interface to run some code on demand * Represents code that can be later executed.
*/ */
@FunctionalInterface @FunctionalInterface
public interface Callable { public interface Callable {
/**
* Execute the lambda.
*/
void call(); void call();
} }

View File

@ -1,11 +1,16 @@
package com.willfp.eco.util.lambda; package com.willfp.eco.util.lambda;
/** /**
* Functional Interface that requires an object * Functional Interface that requires an object as a parameter.
* *
* @param <A> The type of the object to require * @param <A> The type of the object to require.
*/ */
@FunctionalInterface @FunctionalInterface
public interface InputCallable<A> { public interface InputCallable<A> {
/**
* Execute the lambda.
*
* @param object The lambda parameter.
*/
void call(A object); void call(A object);
} }

View File

@ -7,5 +7,10 @@ package com.willfp.eco.util.lambda;
*/ */
@FunctionalInterface @FunctionalInterface
public interface ObjectCallable<A> { public interface ObjectCallable<A> {
/**
* Execute the lambda.
*
* @return The return value of the specified type.
*/
A call(); A call();
} }

View File

@ -1,12 +1,18 @@
package com.willfp.eco.util.lambda; package com.willfp.eco.util.lambda;
/** /**
* Functional Interface to return a value of a specified type given a certain parameter * Functional Interface to return a value of a specified type given a certain parameter.
* *
* @param <A> The type of object to return * @param <A> The type of object to return
* @param <B> The type of object for the parameter * @param <B> The type of object for the parameter
*/ */
@FunctionalInterface @FunctionalInterface
public interface ObjectBiCallable<A, B> { public interface ObjectInputCallable<A, B> {
/**
* Execute the lambda.
*
* @param object The lambda parameter.
* @return The required return type.
*/
A call(B object); A call(B object);
} }

View File

@ -2,17 +2,22 @@ package com.willfp.eco.util.optional;
import com.willfp.eco.util.ClassUtils; import com.willfp.eco.util.ClassUtils;
import com.willfp.eco.util.lambda.ObjectCallable; import com.willfp.eco.util.lambda.ObjectCallable;
import lombok.Getter;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
public class Prerequisite { public class Prerequisite {
/**
* All existing prerequisites are registered on creation.
*/
private static final List<Prerequisite> values = new ArrayList<>(); private static final List<Prerequisite> values = new ArrayList<>();
/** /**
* Requires the server to be running minecraft version 1.16 or higher * Requires the server to be running minecraft version 1.16 or higher.
*/ */
public static final Prerequisite MinVer1_16 = new Prerequisite( public static final Prerequisite MinVer1_16 = new Prerequisite(
() -> !Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3].contains("15"), () -> !Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3].contains("15"),
@ -20,24 +25,38 @@ public class Prerequisite {
); );
/** /**
* Requires the server to be running an implementation of paper * Requires the server to be running an implementation of paper.
*/ */
public static final Prerequisite HasPaper = new Prerequisite( public static final Prerequisite HasPaper = new Prerequisite(
() -> ClassUtils.exists("com.destroystokyo.paper.event.player.PlayerElytraBoostEvent"), () -> ClassUtils.exists("com.destroystokyo.paper.event.player.PlayerElytraBoostEvent"),
"Requires server to be running paper (or a fork)" "Requires server to be running paper (or a fork)"
); );
/**
* If the necessary prerequisite condition has been met.
*/
@Getter
private boolean isMet; private boolean isMet;
/**
* Retrieve if the necessary prerequisite condition is met.
*/
private final ObjectCallable<Boolean> isMetCallable; private final ObjectCallable<Boolean> isMetCallable;
/**
* The description of the requirements of the prerequisite.
*/
@Getter
private final String description; private final String description;
/** /**
* Create a prerequisite * Create a prerequisite.
* *
* @param isMetCallable An {@link ObjectCallable<Boolean>} that returns if the prerequisite is met * @param isMetCallable An {@link ObjectCallable<Boolean>} that returns if the prerequisite is met
* @param description The description of the prerequisite, shown to the user if it isn't * @param description The description of the prerequisite, shown to the user if it isn't
*/ */
public Prerequisite(ObjectCallable<Boolean> isMetCallable, String description) { public Prerequisite(@NotNull final ObjectCallable<Boolean> isMetCallable,
@NotNull final String description) {
this.isMetCallable = isMetCallable; this.isMetCallable = isMetCallable;
this.isMet = isMetCallable.call(); this.isMet = isMetCallable.call();
this.description = description; this.description = description;
@ -45,42 +64,26 @@ public class Prerequisite {
} }
/** /**
* Get the description of the prerequisite * Refresh the condition set in the callable, updates {@link this#isMet}.
*
* @return The description
*/ */
public String getDescription() {
return description;
}
/**
* Get if the prerequisite has been met
*
* @return If the prerequisite is met
*/
public boolean isMet() {
return isMet;
}
private void refresh() { private void refresh() {
this.isMet = this.isMetCallable.call(); this.isMet = this.isMetCallable.call();
} }
/** /**
* Update all prerequisites' {@link Prerequisite#isMet} * Update all prerequisites' {@link Prerequisite#isMet}.
*/ */
public static void update() { public static void update() {
values.forEach(Prerequisite::refresh); values.forEach(Prerequisite::refresh);
} }
/** /**
* Check if all prerequisites in array are met * Check if all prerequisites in array are met.
* *
* @param prerequisites A primitive array of prerequisites to check * @param prerequisites A primitive array of prerequisites to check.
* * @return If all the prerequisites are met.
* @return If all the prerequisites are met
*/ */
public static boolean areMet(Prerequisite[] prerequisites) { public static boolean areMet(@NotNull final Prerequisite[] prerequisites) {
update(); update();
return Arrays.stream(prerequisites).allMatch(Prerequisite::isMet); return Arrays.stream(prerequisites).allMatch(Prerequisite::isMet);
} }

View File

@ -7,62 +7,115 @@ import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent; import com.comphenix.protocol.events.PacketEvent;
import com.willfp.eco.util.plugin.AbstractEcoPlugin; import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import java.util.Collections; import java.util.Collections;
public abstract class AbstractPacketAdapter extends PacketAdapter { public abstract class AbstractPacketAdapter extends PacketAdapter {
/**
* The packet type to listen for.
*/
private final PacketType type; private final PacketType type;
/**
* Whether the packet adapter should be registered after the server has loaded.
* <p>
* Useful for monitor priority adapters that <b>must</b> be ran last.
*/
@Getter
private final boolean postLoad; private final boolean postLoad;
protected AbstractPacketAdapter(AbstractEcoPlugin plugin, PacketType type, ListenerPriority priority, boolean postLoad) { /**
* Create a new packet adapter for a specified plugin and type.
*
* @param plugin The plugin that ProtocolLib should mark as the owner.
* @param type The {@link PacketType} to listen for.
* @param priority The priority at which the adapter should be ran on packet send/receive.
* @param postLoad If the packet adapter should be registered after the server has loaded.
*/
protected AbstractPacketAdapter(@NotNull final AbstractEcoPlugin plugin,
@NotNull final PacketType type,
@NotNull final ListenerPriority priority,
final boolean postLoad) {
super(plugin, priority, Collections.singletonList(type)); super(plugin, priority, Collections.singletonList(type));
this.type = type; this.type = type;
this.postLoad = postLoad; this.postLoad = postLoad;
} }
protected AbstractPacketAdapter(AbstractEcoPlugin plugin, PacketType type, boolean postLoad) { /**
super(plugin, Collections.singletonList(type)); * Create a new packet adapter for a specified plugin and type.
this.type = type; *
this.postLoad = postLoad; * @param plugin The plugin that ProtocolLib should mark as the owner.
* @param type The {@link PacketType} to listen for.
* @param postLoad If the packet adapter should be registered after the server has loaded.
*/
protected AbstractPacketAdapter(@NotNull final AbstractEcoPlugin plugin,
@NotNull final PacketType type,
final boolean postLoad) {
this(plugin, type, ListenerPriority.NORMAL, postLoad);
} }
public void onReceive(PacketContainer packet) { /**
* The code that should be executed once the packet has been received.
*
* @param packet The packet.
*/
public void onReceive(@NotNull final PacketContainer packet) {
// Empty rather than abstract as implementations don't need both // Empty rather than abstract as implementations don't need both
} }
public void onSend(PacketContainer packet) { /**
* THe code that should be executed once the packet has been sent.
*
* @param packet The packet.
*/
public void onSend(@NotNull final PacketContainer packet) {
// Empty rather than abstract as implementations don't need both // Empty rather than abstract as implementations don't need both
} }
/**
* Boilerplate to assert that the packet is of the specified type.
*
* @param event The ProtocolLib event.
*/
@Override @Override
public final void onPacketReceiving(PacketEvent event) { public final void onPacketReceiving(final PacketEvent event) {
if (event.getPacket() == null) if (event.getPacket() == null) {
return; return;
}
if (!event.getPacket().getType().equals(type)) if (!event.getPacket().getType().equals(type)) {
return; return;
}
onReceive(event.getPacket()); onReceive(event.getPacket());
} }
/**
* Boilerplate to assert that the packet is of the specified type.
*
* @param event The ProtocolLib event.
*/
@Override @Override
public final void onPacketSending(PacketEvent event) { public final void onPacketSending(final PacketEvent event) {
if (event.getPacket() == null) if (event.getPacket() == null) {
return; return;
}
if (!event.getPacket().getType().equals(type)) if (!event.getPacket().getType().equals(type)) {
return; return;
}
onSend(event.getPacket()); onSend(event.getPacket());
} }
/**
* Register the packet adapter with ProtocolLib.
*/
public final void register() { public final void register() {
if (!ProtocolLibrary.getProtocolManager().getPacketListeners().contains(this)) { if (!ProtocolLibrary.getProtocolManager().getPacketListeners().contains(this)) {
ProtocolLibrary.getProtocolManager().addPacketListener(this); ProtocolLibrary.getProtocolManager().addPacketListener(this);
} }
} }
public final boolean isPostLoad() {
return postLoad;
}
} }

View File

@ -41,6 +41,7 @@ import com.willfp.eco.util.integrations.placeholder.plugins.PlaceholderIntegrati
import com.willfp.eco.util.optional.Prerequisite; import com.willfp.eco.util.optional.Prerequisite;
import com.willfp.eco.util.packets.AbstractPacketAdapter; import com.willfp.eco.util.packets.AbstractPacketAdapter;
import com.willfp.eco.util.updater.UpdateChecker; import com.willfp.eco.util.updater.UpdateChecker;
import lombok.Getter;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion; import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.bstats.bukkit.Metrics; import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -48,6 +49,7 @@ import org.bukkit.event.Listener;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.ServicePriority; import org.bukkit.plugin.ServicePriority;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -56,25 +58,95 @@ import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public abstract class AbstractEcoPlugin extends JavaPlugin { public abstract class AbstractEcoPlugin extends JavaPlugin {
protected static AbstractEcoPlugin instance; /**
* The instance of the plugin.
*/
@Getter
private static AbstractEcoPlugin instance;
protected final String pluginName; /**
protected final int resourceId; * The name of the plugin.
protected final int bStatsId; */
@Getter
private final String pluginName;
/**
* The spigot resource ID of the plugin.
*/
@Getter
private final int resourceId;
/**
* The bStats resource ID of the plugin.
*/
@Getter
private final int bStatsId;
/**
* Set of external plugin integrations.
*/
private final List<IntegrationLoader> integrations = new ArrayList<>(); private final List<IntegrationLoader> integrations = new ArrayList<>();
/**
* The internal plugin logger.
*/
@Getter
private final Logger log; private final Logger log;
/**
* The internal plugin scheduler.
*/
@Getter
private final Scheduler scheduler; private final Scheduler scheduler;
/**
* The internal plugin Event Manager.
*/
@Getter
private final EventManager eventManager; private final EventManager eventManager;
/**
* The internal factory to produce {@link org.bukkit.NamespacedKey}s.
*/
@Getter
private final NamespacedKeyFactory namespacedKeyFactory; private final NamespacedKeyFactory namespacedKeyFactory;
/**
* The internal factory to produce {@link org.bukkit.metadata.FixedMetadataValue}s.
*/
@Getter
private final MetadataValueFactory metadataValueFactory; private final MetadataValueFactory metadataValueFactory;
/**
* The internal factory to produce {@link com.willfp.eco.util.bukkit.scheduling.EcoBukkitRunnable}s.
*/
@Getter
private final RunnableFactory runnableFactory; private final RunnableFactory runnableFactory;
/**
* The loader for all plugin extensions.
*
* @see com.willfp.eco.util.extensions.Extension
*/
@Getter
private final ExtensionLoader extensionLoader; private final ExtensionLoader extensionLoader;
protected boolean outdated = false; /**
* If the server is running an outdated version of the plugin.
*/
@Getter
private boolean outdated = false;
protected AbstractEcoPlugin(String pluginName, int resourceId, int bStatsId) { /**
* Create a new plugin.
*
* @param pluginName The name of the plugin.
* @param resourceId The spigot resource ID for the plugin.
* @param bStatsId The bStats resource ID for the plugin.
*/
protected AbstractEcoPlugin(@NotNull final String pluginName,
final int resourceId,
final int bStatsId) {
this.pluginName = pluginName; this.pluginName = pluginName;
this.resourceId = resourceId; this.resourceId = resourceId;
this.bStatsId = bStatsId; this.bStatsId = bStatsId;
@ -88,12 +160,15 @@ public abstract class AbstractEcoPlugin extends JavaPlugin {
this.extensionLoader = new EcoExtensionLoader(this); this.extensionLoader = new EcoExtensionLoader(this);
if (!Bukkit.getServicesManager().isProvidedFor(TelekinesisTests.class)) { if (!Bukkit.getServicesManager().isProvidedFor(TelekinesisTests.class)) {
Bukkit.getServicesManager().register(TelekinesisTests.class, new EcoTelekinesisTests(this), this, ServicePriority.Normal); Bukkit.getServicesManager().register(TelekinesisTests.class, new EcoTelekinesisTests(), this, ServicePriority.Normal);
} }
TelekinesisUtils.update(); TelekinesisUtils.update();
} }
/**
* Default code to be executed on plugin enable.
*/
@Override @Override
public final void onEnable() { public final void onEnable() {
super.onLoad(); super.onLoad();
@ -113,10 +188,11 @@ public abstract class AbstractEcoPlugin extends JavaPlugin {
new FastCollatedDropQueue.CollatedRunnable(this); new FastCollatedDropQueue.CollatedRunnable(this);
new UpdateChecker(this, resourceId).getVersion(version -> { new UpdateChecker(this).getVersion(version -> {
DefaultArtifactVersion currentVersion = new DefaultArtifactVersion(this.getDescription().getVersion()); DefaultArtifactVersion currentVersion = new DefaultArtifactVersion(this.getDescription().getVersion());
DefaultArtifactVersion mostRecentVersion = new DefaultArtifactVersion(version); DefaultArtifactVersion mostRecentVersion = new DefaultArtifactVersion(version);
if (!(currentVersion.compareTo(mostRecentVersion) > 0 || currentVersion.equals(mostRecentVersion))) { if (!(currentVersion.compareTo(mostRecentVersion) > 0 || currentVersion.equals(mostRecentVersion))) {
this.outdated = true;
this.getScheduler().runTimer(() -> { this.getScheduler().runTimer(() -> {
this.getLog().info("&c " + this.pluginName + " is out of date! (Version " + this.getDescription().getVersion() + ")"); this.getLog().info("&c " + this.pluginName + " is out of date! (Version " + this.getDescription().getVersion() + ")");
this.getLog().info("&cThe newest version is &f" + version); this.getLog().info("&cThe newest version is &f" + version);
@ -145,7 +221,9 @@ public abstract class AbstractEcoPlugin extends JavaPlugin {
Prerequisite.update(); Prerequisite.update();
this.getPacketAdapters().forEach(abstractPacketAdapter -> { this.getPacketAdapters().forEach(abstractPacketAdapter -> {
if(!abstractPacketAdapter.isPostLoad()) abstractPacketAdapter.register(); if (!abstractPacketAdapter.isPostLoad()) {
abstractPacketAdapter.register();
}
}); });
this.getListeners().forEach(listener -> this.getEventManager().registerListener(listener)); this.getListeners().forEach(listener -> this.getEventManager().registerListener(listener));
@ -157,6 +235,9 @@ public abstract class AbstractEcoPlugin extends JavaPlugin {
this.enable(); this.enable();
} }
/**
* Default code to be executed on plugin disable.
*/
@Override @Override
public final void onDisable() { public final void onDisable() {
super.onDisable(); super.onDisable();
@ -167,6 +248,9 @@ public abstract class AbstractEcoPlugin extends JavaPlugin {
this.disable(); this.disable();
} }
/**
* Default code to be executed on plugin load.
*/
@Override @Override
public final void onLoad() { public final void onLoad() {
super.onLoad(); super.onLoad();
@ -176,9 +260,12 @@ public abstract class AbstractEcoPlugin extends JavaPlugin {
this.load(); this.load();
} }
/**
* Default code to be executed after the server is up.
*/
public final void afterLoad() { public final void afterLoad() {
this.getPacketAdapters().forEach(abstractPacketAdapter -> { this.getPacketAdapters().forEach(abstractPacketAdapter -> {
if(abstractPacketAdapter.isPostLoad()) abstractPacketAdapter.register(); if (abstractPacketAdapter.isPostLoad()) abstractPacketAdapter.register();
}); });
if (!Prerequisite.HasPaper.isMet()) { if (!Prerequisite.HasPaper.isMet()) {
@ -201,6 +288,9 @@ public abstract class AbstractEcoPlugin extends JavaPlugin {
this.getLog().info("Loaded &a" + this.pluginName); this.getLog().info("Loaded &a" + this.pluginName);
} }
/**
* Default code to be executed on plugin reload.
*/
public final void onReload() { public final void onReload() {
Configs.update(); Configs.update();
DropManager.update(); DropManager.update();
@ -210,6 +300,11 @@ public abstract class AbstractEcoPlugin extends JavaPlugin {
this.reload(); this.reload();
} }
/**
* Default integrations that exist within {@link AbstractEcoPlugin}.
*
* @return The default integrations.
*/
public final List<IntegrationLoader> getDefaultIntegrations() { public final List<IntegrationLoader> getDefaultIntegrations() {
integrations.add(new IntegrationLoader("PlaceholderAPI", () -> PlaceholderManager.addIntegration(new PlaceholderIntegrationPAPI(this)))); integrations.add(new IntegrationLoader("PlaceholderAPI", () -> PlaceholderManager.addIntegration(new PlaceholderIntegrationPAPI(this))));
@ -230,57 +325,58 @@ public abstract class AbstractEcoPlugin extends JavaPlugin {
return integrations; return integrations;
} }
/**
* The plugin-specific code to be executed on enable.
*/
public abstract void enable(); public abstract void enable();
/**
* The plugin-specific code to be executed on disable.
*/
public abstract void disable(); public abstract void disable();
/**
* The plugin-specific code to be executed on load.
*/
public abstract void load(); public abstract void load();
/**
* The plugin-specific code to be executed on reload.
*/
public abstract void reload(); public abstract void reload();
/**
* The plugin-specific code to be executed after the server is up.
*/
public abstract void postLoad(); public abstract void postLoad();
/**
* The plugin-specific integrations to be tested and loaded.
*
* @return A list of integrations.
*/
public abstract List<IntegrationLoader> getIntegrations(); public abstract List<IntegrationLoader> getIntegrations();
/**
* The command to be registered.
*
* @return A list of commands.
*/
public abstract List<AbstractCommand> getCommands(); public abstract List<AbstractCommand> getCommands();
/**
* ProtocolLib packet adapters to be registered.
* <p>
* If the plugin does not require ProtocolLib this can be left empty.
*
* @return A list of packet adapters.
*/
public abstract List<AbstractPacketAdapter> getPacketAdapters(); public abstract List<AbstractPacketAdapter> getPacketAdapters();
/**
* All listeners to be registered.
*
* @return A list of all listeners.
*/
public abstract List<Listener> getListeners(); public abstract List<Listener> getListeners();
public final Logger getLog() {
return log;
}
public final Scheduler getScheduler() {
return scheduler;
}
public final EventManager getEventManager() {
return eventManager;
}
public final NamespacedKeyFactory getNamespacedKeyFactory() {
return namespacedKeyFactory;
}
public final MetadataValueFactory getMetadataValueFactory() {
return metadataValueFactory;
}
public final RunnableFactory getRunnableFactory() {
return runnableFactory;
}
public final ExtensionLoader getExtensionLoader() {
return extensionLoader;
}
public final boolean isOutdated() {
return outdated;
}
public static AbstractEcoPlugin getInstance() {
return instance;
}
} }

View File

@ -1,64 +1,37 @@
package com.willfp.eco.util.tuplets; package com.willfp.eco.util.tuplets;
/** import lombok.Getter;
* Spigot doesn't include javafx import lombok.Setter;
*/ import lombok.ToString;
import org.jetbrains.annotations.Nullable;
@ToString
public class Pair<A, B> { public class Pair<A, B> {
/**
* The first value in the pair.
*/
@Getter
@Setter
@Nullable
private A first; private A first;
/**
* The second value in the pair.
*/
@Getter
@Setter
@Nullable
private B second; private B second;
/** /**
* Create a pair * Create a pair of values.
* *
* @param first The first item in the tuplet * @param first The first item in the pair.
* @param second The second item in the tuplet * @param second The second item in the pair.
*/ */
public Pair(A first, B second) { public Pair(@Nullable final A first,
@Nullable final B second) {
this.first = first; this.first = first;
this.second = second; this.second = second;
} }
/**
* Get the first item in the tuplet
*
* @return The first item
*/
public A getFirst() {
return first;
}
/**
* Get the second item in the tuplet
*
* @return The second item
*/
public B getSecond() {
return second;
}
/**
* Set the first item in the tuplet
*
* @param first The value to set the first item to
*/
public void setFirst(A first) {
this.first = first;
}
/**
* Set the second item in the tuplet
*
* @param second The value to set the second item to
*/
public void setSecond(B second) {
this.second = second;
}
@Override
public String toString() {
return "Pair{" +
"first=" + first +
", second=" + second +
'}';
}
} }

View File

@ -1,86 +1,48 @@
package com.willfp.eco.util.tuplets; package com.willfp.eco.util.tuplets;
/** import lombok.Getter;
* Spigot doesn't include javafx import lombok.Setter;
*/ import lombok.ToString;
import org.jetbrains.annotations.Nullable;
@ToString
public class Triplet<A, B, C> { public class Triplet<A, B, C> {
/**
* The first item in the triplet.
*/
@Getter
@Setter
@Nullable
private A first; private A first;
/**
* The second item in the triplet.
*/
@Getter
@Setter
@Nullable
private B second; private B second;
/**
* The third item in the triplet.
*/
@Getter
@Setter
@Nullable
private C third; private C third;
/** /**
* Create a triplet * Create a triplet.
* *
* @param first The first item in the tuplet * @param first The first item in the triplet.
* @param second The second item in the tuplet * @param second The second item in the triplet.
* @param third The third item in the tuplet * @param third The third item in the triplet.
*/ */
public Triplet(A first, B second, C third) { public Triplet(@Nullable final A first,
@Nullable final B second,
@Nullable final C third) {
this.first = first; this.first = first;
this.second = second; this.second = second;
this.third = third; this.third = third;
} }
/**
* Get the first item in the tuplet
*
* @return The first item
*/
public A getFirst() {
return first;
}
/**
* Get the second item in the tuplet
*
* @return The second item
*/
public B getSecond() {
return second;
}
/**
* Get the third item in the tuplet
*
* @return The third item
*/
public C getThird() {
return third;
}
/**
* Set the first item in the tuplet
*
* @param first The value to set
*/
public void setFirst(A first) {
this.first = first;
}
/**
* Set the second item in the tuplet
*
* @param second The value to set
*/
public void setSecond(B second) {
this.second = second;
}
/**
* Set the third item in the tuplet
*
* @param third The value to set
*/
public void setThird(C third) {
this.third = third;
}
@Override
public String toString() {
return "Triplet{" +
"first=" + first +
", second=" + second +
", third=" + third +
'}';
}
} }

View File

@ -1,46 +1,46 @@
package com.willfp.eco.util.updater; package com.willfp.eco.util.updater;
import com.willfp.eco.util.plugin.AbstractEcoPlugin; import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import lombok.AccessLevel;
import lombok.Getter;
import org.bukkit.util.Consumer; import org.bukkit.util.Consumer;
import org.jetbrains.annotations.NotNull;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URL; import java.net.URL;
import java.util.Scanner; import java.util.Scanner;
/**
* Checks spigot if a plugin is out of date
*/
public class UpdateChecker { public class UpdateChecker {
/**
* The instance of the plugin to check updates for.
*/
@Getter(AccessLevel.PRIVATE)
private final AbstractEcoPlugin plugin; private final AbstractEcoPlugin plugin;
private final int resourceId;
/** /**
* Create an update checker for the specified spigot resource id * Create an update checker for the specified spigot resource id.
* *
* @param plugin The plugin to check * @param plugin The plugin to check.
* @param resourceId The resource ID of the plugin
*/ */
public UpdateChecker(AbstractEcoPlugin plugin, int resourceId) { public UpdateChecker(@NotNull final AbstractEcoPlugin plugin) {
this.plugin = plugin; this.plugin = plugin;
this.resourceId = resourceId;
} }
/** /**
* Get the latest version of the plugin * Get the latest version of the plugin.
* *
* @param consumer The process to run after checking * @param consumer The process to run after checking.
*/ */
public void getVersion(final Consumer<? super String> consumer) { public void getVersion(@NotNull final Consumer<? super String> consumer) {
this.plugin.getScheduler().runAsync(() -> { this.getPlugin().getScheduler().runAsync(() -> {
try (InputStream inputStream = new URL("https://api.spigotmc.org/legacy/update.php?resource=" + this.resourceId).openStream(); Scanner scanner = new Scanner(inputStream)) { try (InputStream inputStream = new URL("https://api.spigotmc.org/legacy/update.php?resource=" + this.getPlugin().getResourceId()).openStream(); Scanner scanner = new Scanner(inputStream)) {
if (scanner.hasNext()) { if (scanner.hasNext()) {
consumer.accept(scanner.next()); consumer.accept(scanner.next());
} }
} catch (IOException exception) { } catch (IOException exception) {
this.plugin.getLogger().warning("Failed to check for updates: " + exception.getMessage()); this.getPlugin().getLogger().warning("Failed to check for updates: " + exception.getMessage());
} }
}); });
} }
} }