Began full javadoc

This commit is contained in:
Auxilor
2020-11-29 20:39:59 +00:00
parent 1ae30e2d31
commit 61106312b6
38 changed files with 583 additions and 85 deletions

View File

@@ -23,7 +23,14 @@ import org.bukkit.permissions.PermissionDefault;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
@SuppressWarnings({"unchecked", "deprecation"})
public abstract class EcoEnchant extends Enchantment implements Listener, Registerable, Watcher {
@@ -58,7 +65,7 @@ public abstract class EcoEnchant extends Enchantment implements Listener, Regist
ConfigManager.addEnchantmentConfig(new EnchantmentConfig(this.permissionName, plugin, this.type));
this.config = ConfigManager.getEnchantmentConfig(this.permissionName);
if(Bukkit.getPluginManager().getPermission("ecoenchants.fromtable." + permissionName) == null) {
if (Bukkit.getPluginManager().getPermission("ecoenchants.fromtable." + permissionName) == null) {
Permission permission = new Permission(
"ecoenchants.fromtable." + permissionName,
"Allows getting " + permissionName + " from an Enchanting Table",
@@ -68,7 +75,7 @@ public abstract class EcoEnchant extends Enchantment implements Listener, Regist
Bukkit.getPluginManager().addPermission(permission);
}
if(!Prerequisite.areMet(prerequisites))
if (!Prerequisite.areMet(prerequisites))
return;
this.update();
@@ -128,11 +135,13 @@ public abstract class EcoEnchant extends Enchantment implements Listener, Regist
f.setAccessible(false);
Enchantment.registerEnchantment(this);
} catch (NoSuchFieldException | IllegalAccessException ignored) {}
} catch (NoSuchFieldException | IllegalAccessException ignored) {
}
}
/**
* Get if enchantment can be removed in grindstone
*
* @return Whether the enchantment can be removed
*/
public boolean isGrindstoneable() {
@@ -141,12 +150,16 @@ public abstract class EcoEnchant extends Enchantment implements Listener, Regist
/**
* Get {@link EnchantmentType} of enchantment
*
* @return The {@link EnchantmentType}
*/
public EnchantmentType getType() { return this.type; }
public EnchantmentType getType() {
return this.type;
}
/**
* Get a set of all conflicts
*
* @return Conflicts
*/
public Set<Enchantment> getConflicts() {
@@ -155,6 +168,7 @@ public abstract class EcoEnchant extends Enchantment implements Listener, Regist
/**
* Get if enchantment is enabled
*
* @return If enabled
*/
public boolean isEnabled() {
@@ -163,6 +177,7 @@ public abstract class EcoEnchant extends Enchantment implements Listener, Regist
/**
* Get permission name of enchantment
*
* @return The permission name
*/
public String getPermissionName() {
@@ -171,6 +186,7 @@ public abstract class EcoEnchant extends Enchantment implements Listener, Regist
/**
* Get description of enchantment
*
* @return The description
*/
public List<String> getDescription() {
@@ -179,6 +195,7 @@ public abstract class EcoEnchant extends Enchantment implements Listener, Regist
/**
* Get if enchantment can be obtained from an enchanting table
*
* @return If can be obtained
*/
public boolean canGetFromTable() {
@@ -187,6 +204,7 @@ public abstract class EcoEnchant extends Enchantment implements Listener, Regist
/**
* Get if enchantment can be obtained from a villager
*
* @return If can be obtained
*/
public boolean canGetFromVillager() {
@@ -195,6 +213,7 @@ public abstract class EcoEnchant extends Enchantment implements Listener, Regist
/**
* Get if enchantment can be obtained from chest loot
*
* @return If can be obtained
*/
public boolean canGetFromLoot() {
@@ -203,6 +222,7 @@ public abstract class EcoEnchant extends Enchantment implements Listener, Regist
/**
* Get {@link EnchantmentRarity} of enchantment
*
* @return The enchantment rarity
*/
public EnchantmentRarity getRarity() {
@@ -211,6 +231,7 @@ public abstract class EcoEnchant extends Enchantment implements Listener, Regist
/**
* If enchantment conflicts with any enchantment in set
*
* @param enchantments The set to test against
* @return If there are any conflicts
*/
@@ -220,6 +241,7 @@ public abstract class EcoEnchant extends Enchantment implements Listener, Regist
/**
* Get enchantment cast to {@link Enchantment}
*
* @return The enchantment
*/
public Enchantment getEnchantment() {
@@ -228,6 +250,7 @@ public abstract class EcoEnchant extends Enchantment implements Listener, Regist
/**
* Get the target of enchantment
*
* @return Set of enchantable items
*/
public Set<Material> getTarget() {
@@ -236,6 +259,7 @@ public abstract class EcoEnchant extends Enchantment implements Listener, Regist
/**
* Get raw target of enchantment
*
* @return {@link com.willfp.ecoenchants.enchantments.meta.EnchantmentTarget}
*/
public Set<com.willfp.ecoenchants.enchantments.meta.EnchantmentTarget> getRawTargets() {
@@ -244,6 +268,7 @@ public abstract class EcoEnchant extends Enchantment implements Listener, Regist
/**
* Get {@link EnchantmentConfig} of enchantment
*
* @return The config
*/
public EnchantmentConfig getConfig() {
@@ -263,6 +288,7 @@ public abstract class EcoEnchant extends Enchantment implements Listener, Regist
/**
* Get max level of enchantment
*
* @return The max level
*/
@Override
@@ -283,7 +309,6 @@ public abstract class EcoEnchant extends Enchantment implements Listener, Regist
* Only here for compatibility with {@link Enchantment}
*
* @return Returns {@link EnchantmentTarget#ALL}. Do not use.
*
* @deprecated {@link EnchantmentTarget} is not supported due to its lack of flexibility. Use {@link EcoEnchant#getTarget()} instead.
*/
@Override
@@ -304,7 +329,6 @@ public abstract class EcoEnchant extends Enchantment implements Listener, Regist
/**
* @return Returns if enchantment is cursed.
*
* @deprecated Use {@link EcoEnchant#getType()} instead.
*/
@Override
@@ -315,6 +339,7 @@ public abstract class EcoEnchant extends Enchantment implements Listener, Regist
/**
* Get if enchantment conflicts with specified enchantment
*
* @param enchantment The enchantment to test against
* @return If conflicts
*/
@@ -325,6 +350,7 @@ public abstract class EcoEnchant extends Enchantment implements Listener, Regist
/**
* If enchantment can be applied to item
*
* @param itemStack The {@link ItemStack} to test against
* @return If can be applied
*/
@@ -350,11 +376,12 @@ public abstract class EcoEnchant extends Enchantment implements Listener, Regist
/**
* Create simple EnchantmentType
*
* <p>
* Singularity and Color will not be updated using this constructor
* @param name The name of the type
*
* @param name The name of the type
* @param singular Whether an item can have several enchantments of this type
* @param color The color for enchantments with this type in lore to have
* @param color The color for enchantments with this type in lore to have
*/
public EnchantmentType(String name, boolean singular, String color) {
this(name, () -> singular, () -> color);
@@ -362,10 +389,11 @@ public abstract class EcoEnchant extends Enchantment implements Listener, Regist
/**
* Create EnchantmentType with updatable color
*
* <p>
* Singularity will not be updated using this constructor
* @param name The name of the type
* @param singular Whether an item can have several enchantments of this type
*
* @param name The name of the type
* @param singular Whether an item can have several enchantments of this type
* @param colorCallable Lambda to fetch the color of enchantments with this type to have. Updates on /ecoreload
*/
public EnchantmentType(String name, boolean singular, ObjectCallable<String> colorCallable) {
@@ -374,9 +402,10 @@ public abstract class EcoEnchant extends Enchantment implements Listener, Regist
/**
* Create EnchantmentType with updatable color and singularity
* @param name The name of the type
*
* @param name The name of the type
* @param singularCallable Lambda to fetch whether an item can have several enchantments of this type. Updates on /ecoreload
* @param colorCallable Lambda to fetch the color of enchantments with this type to have. Updates on /ecoreload
* @param colorCallable Lambda to fetch the color of enchantments with this type to have. Updates on /ecoreload
*/
public EnchantmentType(String name, ObjectCallable<Boolean> singularCallable, ObjectCallable<String> colorCallable) {
this.name = name;

View File

@@ -1,5 +1,8 @@
package com.willfp.ecoenchants.integrations;
/**
* Interface for all integrations with optional dependencies
*/
public interface Integration {
/**
* Get the name of integration

View File

@@ -2,6 +2,16 @@ package com.willfp.ecoenchants.integrations.anvilgui;
import com.willfp.ecoenchants.integrations.Integration;
/**
* Interface for AnvilGUI integrations
*/
public interface AnvilGUIIntegration extends Integration {
/**
* Get if the NMS inventory is an instance of an AnvilGUI
*
* @param object The NMS inventory to check
* @return If the object is an AnvilGUI
* @see com.willfp.ecoenchants.nms.OpenInventory
*/
boolean isInstance(Object object);
}

View File

@@ -6,15 +6,29 @@ import org.bukkit.entity.Player;
import java.util.HashSet;
import java.util.Set;
/**
* Utility class for interfacing with plugins that use WesJD's AnvilGUI library
*/
public class AnvilGUIManager {
private static final Set<AnvilGUIIntegration> integrations = new HashSet<>();
/**
* Register a new AnvilGUI integration
*
* @param integration The integration to register
*/
public static void registerIntegration(AnvilGUIIntegration integration) {
integrations.add(integration);
}
/**
* Get if a player's open inventory is an AnvilGUI
*
* @param player The player to check
* @return If the player's open inventory is an AnvilGUI
*/
public static boolean hasAnvilGUIOpen(Player player) {
if(integrations.isEmpty())
if (integrations.isEmpty())
return false;
return integrations.stream().anyMatch(integration -> integration.isInstance(OpenInventory.getOpenInventory(player)));
}

View File

@@ -3,6 +3,9 @@ package com.willfp.ecoenchants.integrations.anvilgui.plugins;
import com.willfp.ecoenchants.EcoEnchantsPlugin;
import com.willfp.ecoenchants.integrations.anvilgui.AnvilGUIIntegration;
/**
* Concrete implementation of {@link AnvilGUIIntegration}
*/
public class AnvilGUIImpl implements AnvilGUIIntegration {
private static final String ANVIL_GUI_CLASS = "net.wesjd.anvilgui.version.Wrapper" + EcoEnchantsPlugin.NMS_VERSION.substring(1) + "$AnvilContainer";

View File

@@ -3,13 +3,24 @@ package com.willfp.ecoenchants.integrations.essentials;
import java.util.HashSet;
import java.util.Set;
/**
* Utility class for interfacing with EssentialsX
*/
public class EssentialsManager {
private static final Set<EssentialsWrapper> registered = new HashSet<>();
/**
* Register a new essentials integration
*
* @param essentials The integration to register
*/
public static void register(EssentialsWrapper essentials) {
registered.add(essentials);
}
/**
* Register all {@link com.willfp.ecoenchants.enchantments.EcoEnchant}s with Essentials
*/
public static void registerEnchantments() {
registered.forEach((EssentialsWrapper::registerAllEnchantments));
}

View File

@@ -2,6 +2,12 @@ package com.willfp.ecoenchants.integrations.essentials;
import com.willfp.ecoenchants.integrations.Integration;
/**
* Interface for Essentials Integration
*/
public interface EssentialsWrapper extends Integration {
/**
* @see EssentialsManager#registerEnchantments()
*/
void registerAllEnchantments();
}

View File

@@ -8,6 +8,9 @@ import org.bukkit.enchantments.Enchantment;
import java.util.Map;
/**
* Concrete implementation of {@link EssentialsWrapper}
*/
@SuppressWarnings("unchecked")
public class IntegrationEssentials implements EssentialsWrapper {
@Override

View File

@@ -3,6 +3,12 @@ package com.willfp.ecoenchants.integrations.mcmmo;
import com.willfp.ecoenchants.integrations.Integration;
import org.bukkit.event.Event;
/**
* Interface for mcMMO integrations
*/
public interface McmmoIntegration extends Integration {
/**
* @see McmmoManager#isFake(Event)
*/
boolean isFake(Event event);
}

View File

@@ -6,17 +6,31 @@ import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Utility class for interfacing with mcMMO
*/
public class McmmoManager {
private static final Set<McmmoIntegration> integrations = new HashSet<>();
/**
* Register a new mcMMO integration
*
* @param integration The integration to register
*/
public static void registerIntegration(McmmoIntegration integration) {
integrations.add(integration);
}
/**
* Get if an event is fake
*
* @param event The event to check
* @return If the event is fake
*/
public static boolean isFake(Event event) {
AtomicBoolean isFake = new AtomicBoolean(false);
integrations.forEach(integration -> {
if(integration.isFake(event)) isFake.set(true);
if (integration.isFake(event)) isFake.set(true);
});
return isFake.get();

View File

@@ -4,6 +4,9 @@ import com.gmail.nossr50.events.fake.FakeEvent;
import com.willfp.ecoenchants.integrations.mcmmo.McmmoIntegration;
import org.bukkit.event.Event;
/**
* Concrete implementation of {@link McmmoIntegration}
*/
public class McmmoIntegrationImpl implements McmmoIntegration {
@Override
public boolean isFake(Event event) {

View File

@@ -2,30 +2,63 @@ package com.willfp.ecoenchants.integrations.placeholder;
import com.willfp.ecoenchants.util.interfaces.ObjectBiCallable;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable;
/**
* A placeholder entry consists of an identifier and an {@link ObjectBiCallable<String, Player>} to fetch the result
*/
public class PlaceholderEntry {
private final String identifier;
private final ObjectBiCallable<String, Player> function;
private final boolean requiresPlayer;
/**
* Create a placeholder entry that doesn't require a player
*
* @param identifier The identifier of the placeholder
* @param function A lambda to get the result of the placeholder
*/
public PlaceholderEntry(String identifier, ObjectBiCallable<String, Player> function) {
this(identifier, function, false);
}
/**
* Create a placeholder entry that may require a player
*
* @param identifier The identifier of the placeholder
* @param function A lambda to get the result of the placeholder
* @param requiresPlayer If the placeholder requires a player
*/
public PlaceholderEntry(String identifier, ObjectBiCallable<String, Player> function, boolean requiresPlayer) {
this.identifier = identifier;
this.function = function;
this.requiresPlayer = requiresPlayer;
}
/**
* Get the identifier of the placeholder
*
* @return The identifier
*/
public String getIdentifier() {
return this.identifier;
}
public String getResult(Player player) {
/**
* 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);
}
/**
* Get if the placeholder requires a player to get a result
*
* @return If the placeholder requires a player
*/
public boolean requiresPlayer() {
return requiresPlayer;
}

View File

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

View File

@@ -1,37 +1,65 @@
package com.willfp.ecoenchants.integrations.placeholder;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
/**
* Utility class for placeholders
*/
public class PlaceholderManager {
private static final Set<PlaceholderEntry> placeholders = new HashSet<>();
private static final Set<PlaceholderIntegration> integrations = new HashSet<>();
/**
* Register a new placeholder integration
*
* @param integration The {@link PlaceholderIntegration} to register
*/
public static void addIntegration(PlaceholderIntegration integration) {
integration.registerIntegration();
integrations.add(integration);
}
/**
* Register a placeholder
*
* @param expansion The {@link PlaceholderEntry} to register
*/
public static void registerPlaceholder(PlaceholderEntry expansion) {
placeholders.removeIf(placeholderEntry -> placeholderEntry.getIdentifier().equalsIgnoreCase(expansion.getIdentifier()));
placeholders.add(expansion);
}
public static String getResult(Player player, String identifier) {
/**
* Get the result of a placeholder with respect to a player
*
* @param player The player to get the result from
* @param identifier The placeholder identifier
* @return The value of the placeholder
*/
public static String getResult(@Nullable Player player, String identifier) {
Optional<PlaceholderEntry> matching = placeholders.stream().filter(expansion -> expansion.getIdentifier().equalsIgnoreCase(identifier)).findFirst();
if(!matching.isPresent())
if (!matching.isPresent())
return null;
PlaceholderEntry entry = matching.get();
if(player == null && entry.requiresPlayer())
if (player == null && entry.requiresPlayer())
return "";
return entry.getResult(player);
}
public static String translatePlaceholders(String text, Player player) {
/**
* Translate all placeholders with respect to a player
*
* @param text The text that may contain placeholders to translate
* @param player The player to translate the placeholders with respect to
* @return The text, translated
*/
public static String translatePlaceholders(String text, @Nullable Player player) {
AtomicReference<String> translatedReference = new AtomicReference<>(text);
integrations.forEach(placeholderIntegration -> translatedReference.set(placeholderIntegration.translate(translatedReference.get(), player)));
return translatedReference.get();

View File

@@ -8,6 +8,9 @@ import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
/**
* PlaceholderAPI integration
*/
public class PlaceholderIntegrationPAPI extends PlaceholderExpansion implements PlaceholderIntegration {
@Override
public boolean persist() {

View File

@@ -4,10 +4,15 @@ import com.willfp.ecoenchants.EcoEnchantsPlugin;
import com.willfp.ecoenchants.nms.API.BlockBreakWrapper;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.ApiStatus;
/**
* Utility class to break a block as if the player had done it manually
*/
public class BlockBreak {
private static BlockBreakWrapper blockBreakWrapper;
@ApiStatus.Internal
public static boolean init() {
try {
final Class<?> class2 = Class.forName("com.willfp.ecoenchants." + EcoEnchantsPlugin.NMS_VERSION + ".BlockBreak");
@@ -21,6 +26,12 @@ public class BlockBreak {
return blockBreakWrapper != null;
}
/**
* Break a block as a player
*
* @param player The player to break the block as
* @param block The block to break
*/
public static void breakBlock(Player player, Block block) {
assert blockBreakWrapper != null;
blockBreakWrapper.breakBlock(player, block);

View File

@@ -4,12 +4,17 @@ package com.willfp.ecoenchants.nms;
import com.willfp.ecoenchants.nms.API.CooldownWrapper;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.ApiStatus;
/**
* Utility class to get the attack cooldown of a player
*/
public class Cooldown {
private static CooldownWrapper cooldown;
private static final String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
@ApiStatus.Internal
public static boolean init() {
try {
final Class<?> class2 = Class.forName("com.willfp.ecoenchants." + version + ".Cooldown");
@@ -23,6 +28,12 @@ public class Cooldown {
return cooldown != null;
}
/**
* Get a player's attack cooldown
*
* @param player The player to check
* @return A value between 0 and 1, with 1 representing max strength
*/
public static double getCooldown(Player player) {
assert cooldown != null;
return cooldown.getAttackCooldown(player);

View File

@@ -3,10 +3,15 @@ package com.willfp.ecoenchants.nms;
import com.willfp.ecoenchants.EcoEnchantsPlugin;
import com.willfp.ecoenchants.nms.API.OpenInventoryWrapper;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.ApiStatus;
/**
* Utility class to get the NMS implementation of a players' currently open inventory
*/
public class OpenInventory {
private static OpenInventoryWrapper openInventoryWrapper;
@ApiStatus.Internal
public static boolean init() {
try {
final Class<?> class2 = Class.forName("com.willfp.ecoenchants." + EcoEnchantsPlugin.NMS_VERSION + ".OpenInventory");
@@ -20,6 +25,12 @@ public class OpenInventory {
return openInventoryWrapper != null;
}
/**
* Get the NMS container of the inventory
*
* @param player The player to check
* @return The NMS container
*/
public static Object getOpenInventory(Player player) {
assert openInventoryWrapper != null;
return openInventoryWrapper.getOpenInventory(player);

View File

@@ -3,10 +3,15 @@ package com.willfp.ecoenchants.nms;
import com.willfp.ecoenchants.EcoEnchantsPlugin;
import com.willfp.ecoenchants.nms.API.RepairCostWrapper;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
/**
* Utility class to get and set the anvil rework penalty of an item
*/
public class RepairCost {
private static RepairCostWrapper repairCostWrapper;
@ApiStatus.Internal
public static boolean init() {
try {
final Class<?> class2 = Class.forName("com.willfp.ecoenchants." + EcoEnchantsPlugin.NMS_VERSION + ".RepairCost");
@@ -20,11 +25,24 @@ public class RepairCost {
return repairCostWrapper != null;
}
/**
* Get the rework penalty of an ItemStack
*
* @param itemStack The item to check
* @return The anvil rework penalty
*/
public static int getRepairCost(ItemStack itemStack) {
assert repairCostWrapper != null;
return repairCostWrapper.getRepairCost(itemStack);
}
/**
* Set the rework penalty of an ItemStack
*
* @param itemStack The item to set
* @param cost The penalty to set
* @return The ItemStack, with the repair cost set
*/
public static ItemStack setRepairCost(ItemStack itemStack, int cost) {
assert repairCostWrapper != null;
return repairCostWrapper.setRepairCost(itemStack, cost);

View File

@@ -5,12 +5,17 @@ import com.willfp.ecoenchants.nms.API.TridentStackWrapper;
import org.bukkit.Bukkit;
import org.bukkit.entity.Trident;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
/**
* Utility class to get the {@link ItemStack} of a given {@link Trident}
*/
public class TridentStack {
private static TridentStackWrapper tridentStackWrapper;
private static final String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
@ApiStatus.Internal
public static boolean init() {
try {
final Class<?> class2 = Class.forName("com.willfp.ecoenchants." + version + ".TridentStack");
@@ -24,6 +29,12 @@ public class TridentStack {
return tridentStackWrapper != null;
}
/**
* Get the {@link ItemStack} of a given {@link Trident}
*
* @param trident The trident to get the ItemStack from
* @return The ItemStack associated with the trident
*/
public static ItemStack getTridentStack(Trident trident) {
assert tridentStackWrapper != null;
return tridentStackWrapper.getTridentStack(trident);

View File

@@ -14,14 +14,23 @@ public class BlockUtils {
Block block = start.getRelative(face);
if (!blocks.contains(block) && allowedMaterials.contains(block.getType())) {
blocks.add(block);
if(blocks.size() > limit) return blocks;
if(blocks.size() > 2500) return blocks; // anti stack overflow
if (blocks.size() > limit) return blocks;
if (blocks.size() > 2500) return blocks; // anti stack overflow
blocks.addAll(getNearbyBlocks(block, allowedMaterials, blocks, limit));
}
}
return blocks;
}
/**
* Get a set of all blocks in contact with each other of a specific type
*
* @param start The initial block
* @param allowedMaterials A list of all valid {@link Material}s
* @param limit The maximum size of vein to return
* @return A set of all {@link Block}s
*/
public static Set<Block> getVein(Block start, List<Material> allowedMaterials, int limit) {
return getNearbyBlocks(start, allowedMaterials, new HashSet<>(), limit);
}

View File

@@ -1,6 +1,13 @@
package com.willfp.ecoenchants.util;
public class ClassUtils {
/**
* Get if a class exists
*
* @param className The class to check
* @return If the class exists
* @see Class#forName(String)
*/
public static boolean exists(String className) {
try {
Class.forName(className);

View File

@@ -21,63 +21,64 @@ public class DurabilityUtils {
* Armor slots are 39 (helmet), 38 (chestplate), 37 (leggings), 36 (boots)
*
* @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 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) {
if(item == null) return;
if(item.getItemMeta() == null) return;
if (item == null) return;
if (item.getItemMeta() == null) return;
if(item.getItemMeta().isUnbreakable()) return;
if (item.getItemMeta().isUnbreakable()) return;
PlayerItemDamageEvent event3 = new PlayerItemDamageEvent(player, item, damage);
Bukkit.getPluginManager().callEvent(event3);
if(!event3.isCancelled()) {
if (!event3.isCancelled()) {
int damage2 = event3.getDamage();
if(item.getItemMeta() instanceof Damageable) {
if (item.getItemMeta() instanceof Damageable) {
Damageable meta = (Damageable) item.getItemMeta();
meta.setDamage(meta.getDamage() + damage2);
if(meta.getDamage() >= item.getType().getMaxDurability()) {
if (meta.getDamage() >= item.getType().getMaxDurability()) {
meta.setDamage(item.getType().getMaxDurability());
item.setItemMeta((ItemMeta) meta);
PlayerItemBreakEvent event = new PlayerItemBreakEvent(player, item);
Bukkit.getPluginManager().callEvent(event);
player.getInventory().clear(slot);
player.playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, SoundCategory.BLOCKS,1, 1);
player.playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, SoundCategory.BLOCKS, 1, 1);
} else {
item.setItemMeta((ItemMeta) meta);
}
}
}
}
/**
* 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 player The player
*/
public static void damageItemNoBreak(ItemStack item, int damage, Player player) {
if(item == null) return;
if(item.getItemMeta() == null) return;
if (item == null) return;
if (item.getItemMeta() == null) return;
if(item.getItemMeta().isUnbreakable()) return;
if (item.getItemMeta().isUnbreakable()) return;
PlayerItemDamageEvent event3 = new PlayerItemDamageEvent(player, item, damage);
Bukkit.getPluginManager().callEvent(event3);
if(!event3.isCancelled()) {
if (!event3.isCancelled()) {
int damage2 = event3.getDamage();
if(item.getItemMeta() instanceof Damageable) {
if (item.getItemMeta() instanceof Damageable) {
Damageable meta = (Damageable) item.getItemMeta();
meta.setDamage(meta.getDamage() + damage2);
if(meta.getDamage() >= item.getType().getMaxDurability()) {
if (meta.getDamage() >= item.getType().getMaxDurability()) {
meta.setDamage(item.getType().getMaxDurability() - 1);
}
item.setItemMeta((ItemMeta) meta);
@@ -90,19 +91,19 @@ public class DurabilityUtils {
* 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
*/
public static void repairItem(ItemStack item, int repair) {
if(item == null) return;
if(item.getItemMeta() == null) return;
if (item == null) return;
if (item.getItemMeta() == null) return;
if(item.getItemMeta().isUnbreakable()) return;
if(item.getItemMeta() instanceof Damageable) {
if (item.getItemMeta().isUnbreakable()) return;
if (item.getItemMeta() instanceof Damageable) {
Damageable meta = (Damageable) item.getItemMeta();
meta.setDamage(meta.getDamage() - repair);
if(meta.getDamage() < 0) {
if (meta.getDamage() < 0) {
meta.setDamage(0);
}
item.setItemMeta((ItemMeta) meta);

View File

@@ -10,11 +10,12 @@ public class LightningUtils {
/**
* Strike lightning on player without fire
*
* @param victim The entity to smite
* @param damage The damage to deal
*/
public static void strike(LivingEntity victim, double damage) {
if(victim == null) return;
if (victim == null) return;
Location loc = victim.getLocation();

View File

@@ -27,20 +27,22 @@ public class NumberUtils {
/**
* Bias the input value according to a curve
*
* @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
*/
public static double bias(double input, double bias) {
double k = Math.pow(1-bias, 3);
double k = Math.pow(1 - bias, 3);
return (input * k) / (input * k - input + 1);
}
/**
* If value is above maximum, set it to maximum
*
* @param toChange The value to test
* @param limit The maximum
* @param limit The maximum
* @return The new value
*/
public static int equalIfOver(int toChange, int limit) {
@@ -52,8 +54,9 @@ public class NumberUtils {
/**
* If value is above maximum, set it to maximum
*
* @param toChange The value to test
* @param limit The maximum
* @param limit The maximum
* @return The new value
*/
public static double equalIfOver(double toChange, double limit) {
@@ -65,6 +68,7 @@ public class NumberUtils {
/**
* Get Roman Numeral from number
*
* @param number The number to convert
* @return The number, converted to a roman numeral
*/
@@ -80,6 +84,7 @@ public class NumberUtils {
/**
* Generate random integer in range
*
* @param min Minimum
* @param max Maximum
* @return Random integer
@@ -90,6 +95,7 @@ public class NumberUtils {
/**
* Generate random double in range
*
* @param min Minimum
* @param max Maximum
* @return Random double
@@ -101,9 +107,10 @@ public class NumberUtils {
/**
* Generate random double with a triangular distribution
*
* @param minimum Minimum
* @param maximum Maximum
* @param peak Peak
* @param peak Peak
* @return Random double
*/
public static double triangularDistribution(double minimum, double maximum, double peak) {
@@ -118,15 +125,17 @@ public class NumberUtils {
/**
* Get Log base 2 of a number
*
* @param N The number
* @return The result
*/
public static int log2(int N) {
return (int)(Math.log(N) / Math.log(2));
return (int) (Math.log(N) / Math.log(2));
}
/**
* Format double to string
*
* @param toFormat The number to format
* @return Formatted
*/

View File

@@ -3,6 +3,7 @@ package com.willfp.ecoenchants.util;
import com.willfp.ecoenchants.integrations.placeholder.PlaceholderManager;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.regex.Matcher;
@@ -12,13 +13,27 @@ import java.util.stream.Collectors;
import static net.md_5.bungee.api.ChatColor.COLOR_CHAR;
public class StringUtils {
public static String translate(String message, Player player) {
/**
* Translate a string - converts Placeholders and Color codes
*
* @param message The message to translate
* @param player The player to translate placeholders with respect to
* @return The message, translated
*/
public static String translate(String message, @Nullable Player player) {
message = PlaceholderManager.translatePlaceholders(message, player);
message = translateHexColorCodes(message);
message = ChatColor.translateAlternateColorCodes('&', message);
return ChatColor.translateAlternateColorCodes('&', translateHexColorCodes(message));
}
/**
* Translate a string without respect to a player
*
* @param message The message to translate
* @return The message, translated
* @see StringUtils#translate(String, Player)
*/
public static String translate(String message) {
message = PlaceholderManager.translatePlaceholders(message, null);
message = translateHexColorCodes(message);
@@ -30,32 +45,46 @@ public class StringUtils {
Pattern hexPattern = Pattern.compile("&#" + "([A-Fa-f0-9]{6})" + "");
Matcher matcher = hexPattern.matcher(message);
StringBuffer buffer = new StringBuffer(message.length() + 4 * 8);
while(matcher.find()) {
while (matcher.find()) {
String group = matcher.group(1);
matcher.appendReplacement(buffer, COLOR_CHAR + "x"
+ COLOR_CHAR + group.charAt(0) + COLOR_CHAR + group.charAt(1)
+ COLOR_CHAR + group.charAt(2) + COLOR_CHAR + group.charAt(3)
+ COLOR_CHAR + group.charAt(4) + COLOR_CHAR + group.charAt(5));
+ COLOR_CHAR + group.charAt(0) + COLOR_CHAR + group.charAt(1)
+ COLOR_CHAR + group.charAt(2) + COLOR_CHAR + group.charAt(3)
+ COLOR_CHAR + group.charAt(4) + COLOR_CHAR + group.charAt(5));
}
return matcher.appendTail(buffer).toString();
}
public static String internalToString(Object object) {
if(object == null) return "null";
/**
* Internal implementation of {@link String#valueOf}
* Formats collections and doubles better
*
* @param object The object to convert to string
* @return The object stringified
*/
public static String internalToString(@Nullable Object object) {
if (object == null) return "null";
if (object instanceof Integer) {
return ((Integer) object).toString();
} else if(object instanceof String) {
} else if (object instanceof String) {
return (String) object;
} else if(object instanceof Double) {
} else if (object instanceof Double) {
return NumberUtils.format((Double) object);
} else if(object instanceof Collection<?>) {
} else if (object instanceof Collection<?>) {
Collection<?> c = (Collection<?>) object;
return c.stream().map(String::valueOf).collect(Collectors.joining(", "));
} else return String.valueOf(object);
}
/**
* Remove a string of characters from the start of a string
*
* @param s The string to remove the prefix from
* @param prefix The substring to remove
* @return The string with the prefix removed
*/
public static String removePrefix(String s, String prefix) {
if (s != null && prefix != null && s.startsWith(prefix)) {
return s.substring(prefix.length());

View File

@@ -6,6 +6,12 @@ import org.bukkit.util.Vector;
import java.util.ArrayList;
public class VectorUtils {
/**
* If vector has all components as finite
*
* @param vector The vector to check
* @return If the vector is finite
*/
public static boolean isFinite(Vector vector) {
try {
NumberConversions.checkFinite(vector.getX(), "x not finite");
@@ -53,6 +59,7 @@ public class VectorUtils {
/**
* Get circle as relative vectors
*
* @param radius The radius
* @return An array of {@link Vector}s
*/
@@ -81,6 +88,7 @@ public class VectorUtils {
/**
* Get square as relative vectors
*
* @param radius The radius of the square
* @return An array of {@link Vector}s
*/
@@ -104,6 +112,7 @@ public class VectorUtils {
/**
* Get cube as relative vectors
*
* @param radius The radius of the cube
* @return An array of {@link Vector}s
*/

View File

@@ -1,5 +1,8 @@
package com.willfp.ecoenchants.util.interfaces;
/**
* Simple functional interface to run some code on demand
*/
@FunctionalInterface
public interface Callable {
void call();

View File

@@ -1,5 +1,11 @@
package com.willfp.ecoenchants.util.interfaces;
/**
* Functional Interface to return a value of a specified type given a certain parameter
*
* @param <A> The type of object to return
* @param <B> The type of object for the parameter
*/
@FunctionalInterface
public interface ObjectBiCallable<A, B> {
A call(B object);

View File

@@ -1,5 +1,10 @@
package com.willfp.ecoenchants.util.interfaces;
/**
* Functional Interface to return a value of a given type
*
* @param <A> The type to return
*/
@FunctionalInterface
public interface ObjectCallable<A> {
A call();

View File

@@ -1,5 +1,8 @@
package com.willfp.ecoenchants.util.interfaces;
/**
* Interface for objects that can be internally registered
*/
public interface Registerable {
void register();
}

View File

@@ -3,7 +3,11 @@ package com.willfp.ecoenchants.util.internal;
import com.willfp.ecoenchants.enchantments.EcoEnchants;
import com.willfp.ecoenchants.enchantments.util.EnchantChecks;
import com.willfp.ecoenchants.util.NumberUtils;
import org.bukkit.*;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.SoundCategory;
import org.bukkit.World;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.ExperienceOrb;
import org.bukkit.entity.Player;
@@ -18,7 +22,7 @@ import java.util.List;
/**
* All drops generated from enchantments should be sent through a {@link DropQueue}
*
* Interacts with {@link EcoEnchants#TELEKINESIS}
*/
public class DropQueue {
private final List<ItemStack> items;
@@ -30,6 +34,7 @@ public class DropQueue {
/**
* Create {@link DropQueue} linked to player
*
* @param player The player
*/
public DropQueue(Player player) {
@@ -42,6 +47,7 @@ public class DropQueue {
/**
* Add item to queue
*
* @param item The item to add
* @return The DropQueue
*/
@@ -52,6 +58,7 @@ public class DropQueue {
/**
* Add multiple items to queue
*
* @param itemStacks The items to add
* @return The DropQueue
*/
@@ -62,6 +69,7 @@ public class DropQueue {
/**
* Add xp to queue
*
* @param amount The amount to add
* @return The DropQueue
*/
@@ -72,6 +80,7 @@ public class DropQueue {
/**
* Set location of the origin of the drops
*
* @param l The location
* @return The DropQueue
*/
@@ -82,6 +91,7 @@ public class DropQueue {
/**
* Force the queue to act as if player has {@link EcoEnchants#TELEKINESIS}
*
* @return The DropQueue
*/
public DropQueue forceTelekinesis() {
@@ -105,8 +115,8 @@ public class DropQueue {
* Push the queue
*/
public void push() {
if(!hasTelekinesis) hasTelekinesis = EnchantChecks.item(item, EcoEnchants.TELEKINESIS);
if(hasTelekinesis && !EcoEnchants.TELEKINESIS.isEnabled()) hasTelekinesis = false;
if (!hasTelekinesis) hasTelekinesis = EnchantChecks.item(item, EcoEnchants.TELEKINESIS);
if (hasTelekinesis && !EcoEnchants.TELEKINESIS.isEnabled()) hasTelekinesis = false;
World world = loc.getWorld();
@@ -122,7 +132,7 @@ public class DropQueue {
if (xp > 0) {
PlayerExpChangeEvent event = new PlayerExpChangeEvent(player, xp);
Bukkit.getPluginManager().callEvent(event);
if(EcoEnchants.TELEKINESIS.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "use-orb")) {
if (EcoEnchants.TELEKINESIS.getConfig().getBool(EcoEnchants.CONFIG_LOCATION + "use-orb")) {
ExperienceOrb orb = (ExperienceOrb) player.getWorld().spawnEntity(player.getLocation().add(0, 0.2, 0), EntityType.EXPERIENCE_ORB);
orb.setVelocity(new Vector(0, 0, 0));
orb.setExperience(event.getAmount());

View File

@@ -33,7 +33,12 @@ import com.willfp.ecoenchants.integrations.anticheat.plugins.AnticheatMatrix;
import com.willfp.ecoenchants.integrations.anticheat.plugins.AnticheatNCP;
import com.willfp.ecoenchants.integrations.anticheat.plugins.AnticheatSpartan;
import com.willfp.ecoenchants.integrations.antigrief.AntigriefManager;
import com.willfp.ecoenchants.integrations.antigrief.plugins.*;
import com.willfp.ecoenchants.integrations.antigrief.plugins.AntigriefFactionsUUID;
import com.willfp.ecoenchants.integrations.antigrief.plugins.AntigriefGriefPrevention;
import com.willfp.ecoenchants.integrations.antigrief.plugins.AntigriefKingdoms;
import com.willfp.ecoenchants.integrations.antigrief.plugins.AntigriefLands;
import com.willfp.ecoenchants.integrations.antigrief.plugins.AntigriefTowny;
import com.willfp.ecoenchants.integrations.antigrief.plugins.AntigriefWorldGuard;
import com.willfp.ecoenchants.integrations.anvilgui.AnvilGUIManager;
import com.willfp.ecoenchants.integrations.anvilgui.plugins.AnvilGUIImpl;
import com.willfp.ecoenchants.integrations.essentials.EssentialsManager;
@@ -44,7 +49,11 @@ import com.willfp.ecoenchants.integrations.placeholder.PlaceholderManager;
import com.willfp.ecoenchants.integrations.placeholder.plugins.PlaceholderIntegrationPAPI;
import com.willfp.ecoenchants.listeners.ArrowListeners;
import com.willfp.ecoenchants.listeners.PlayerJoinListener;
import com.willfp.ecoenchants.nms.*;
import com.willfp.ecoenchants.nms.BlockBreak;
import com.willfp.ecoenchants.nms.Cooldown;
import com.willfp.ecoenchants.nms.OpenInventory;
import com.willfp.ecoenchants.nms.RepairCost;
import com.willfp.ecoenchants.nms.TridentStack;
import com.willfp.ecoenchants.util.interfaces.Callable;
import com.willfp.ecoenchants.util.interfaces.EcoRunnable;
import com.willfp.ecoenchants.util.optional.Prerequisite;
@@ -55,7 +64,11 @@ import org.bukkit.event.HandlerList;
import org.bukkit.generator.BlockPopulator;
import org.bukkit.plugin.Plugin;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
@@ -88,7 +101,7 @@ public class Loader {
Logger.info("Loading ProtocolLib...");
EcoEnchantsPlugin.getInstance().protocolManager = ProtocolLibrary.getProtocolManager();
if(ConfigManager.getConfig().getBool("villager.enabled")) {
if (ConfigManager.getConfig().getBool("villager.enabled")) {
new PacketOpenWindowMerchant().register();
}
new PacketSetCreativeSlot().register();
@@ -103,7 +116,7 @@ public class Loader {
Logger.info("Loading NMS APIs...");
if(Cooldown.init()) {
if (Cooldown.init()) {
Logger.info("Cooldown: &aSUCCESS");
} else {
Logger.info("Cooldown: &cFAILURE");
@@ -111,7 +124,7 @@ public class Loader {
Bukkit.getPluginManager().disablePlugin(EcoEnchantsPlugin.getInstance());
}
if(TridentStack.init()) {
if (TridentStack.init()) {
Logger.info("Trident API: &aSUCCESS");
} else {
Logger.info("Trident API: &cFAILURE");
@@ -119,7 +132,7 @@ public class Loader {
Bukkit.getPluginManager().disablePlugin(EcoEnchantsPlugin.getInstance());
}
if(BlockBreak.init()) {
if (BlockBreak.init()) {
Logger.info("Block Break: &aSUCCESS");
} else {
Logger.info("Block Break: &cFAILURE");
@@ -127,7 +140,7 @@ public class Loader {
Bukkit.getPluginManager().disablePlugin(EcoEnchantsPlugin.getInstance());
}
if(RepairCost.init()) {
if (RepairCost.init()) {
Logger.info("Repair Cost: &aSUCCESS");
} else {
Logger.info("Repair Cost: &cFAILURE");
@@ -135,7 +148,7 @@ public class Loader {
Bukkit.getPluginManager().disablePlugin(EcoEnchantsPlugin.getInstance());
}
if(OpenInventory.init()) {
if (OpenInventory.init()) {
Logger.info("Open Inventory: &aSUCCESS");
} else {
Logger.info("Open Inventory: &cFAILURE");
@@ -195,7 +208,7 @@ public class Loader {
integrations.forEach(((s, callable) -> {
StringBuilder log = new StringBuilder();
log.append(s).append(": ");
if(enabledPlugins.contains(s)) {
if (enabledPlugins.contains(s)) {
callable.call();
log.append("&aENABLED");
} else {
@@ -225,7 +238,7 @@ public class Loader {
Logger.info("Adding Enchantments to API...");
EnchantmentRarity.update();
EnchantmentTarget.update();
if(EnchantmentRarity.getAll().size() == 0 || EnchantmentTarget.getAll().size() == 0) {
if (EnchantmentRarity.getAll().size() == 0 || EnchantmentTarget.getAll().size() == 0) {
Logger.error("&cError loading rarities or targets! Aborting...");
Bukkit.getPluginManager().disablePlugin(EcoEnchantsPlugin.getInstance());
return;
@@ -252,7 +265,7 @@ public class Loader {
EcoEnchantsPlugin.getInstance().getExtensionLoader().loadExtensions();
if(EcoEnchantsPlugin.getInstance().getExtensionLoader().getLoadedExtensions().isEmpty()){
if (EcoEnchantsPlugin.getInstance().getExtensionLoader().getLoadedExtensions().isEmpty()) {
Logger.info("&cNo extensions found");
} else {
Logger.info("Extensions Loaded:");
@@ -295,7 +308,7 @@ public class Loader {
Logger.info("Registering Enchantment Listeners...");
EcoEnchants.getAll().forEach((ecoEnchant -> {
if(ecoEnchant.isEnabled()) {
if (ecoEnchant.isEnabled()) {
Bukkit.getPluginManager().registerEvents(ecoEnchant, EcoEnchantsPlugin.getInstance());
}
}));
@@ -307,7 +320,7 @@ public class Loader {
Logger.info("Registering Enchantment Tasks...");
EcoEnchants.getAll().forEach((ecoEnchant -> {
if(ecoEnchant instanceof EcoRunnable) {
if (ecoEnchant instanceof EcoRunnable) {
Bukkit.getScheduler().scheduleSyncRepeatingTask(EcoEnchantsPlugin.getInstance(), (Runnable) ecoEnchant, 5, ((EcoRunnable) ecoEnchant).getTime());
}
}));
@@ -411,7 +424,7 @@ public class Loader {
Bukkit.getServer().getWorlds().forEach((world -> {
List<BlockPopulator> populators = new ArrayList<>(world.getPopulators());
populators.forEach((blockPopulator -> {
if(blockPopulator instanceof LootPopulator) {
if (blockPopulator instanceof LootPopulator) {
world.getPopulators().remove(blockPopulator);
}
}));
@@ -438,7 +451,7 @@ public class Loader {
HandlerList.unregisterAll(ecoEnchant);
Bukkit.getScheduler().runTaskLater(EcoEnchantsPlugin.getInstance(), () -> {
if(ecoEnchant.isEnabled()) {
if (ecoEnchant.isEnabled()) {
Bukkit.getPluginManager().registerEvents(ecoEnchant, EcoEnchantsPlugin.getInstance());
}
}, 1);

View File

@@ -3,17 +3,36 @@ package com.willfp.ecoenchants.util.internal;
import com.willfp.ecoenchants.EcoEnchantsPlugin;
import com.willfp.ecoenchants.util.StringUtils;
/**
* The internal logger for EcoEnchants
* Automatically formats all inputs using {@link StringUtils#translate(String)}
*/
public class Logger {
private static final EcoEnchantsPlugin INSTANCE = EcoEnchantsPlugin.getInstance();
/**
* Print an info (neutral) message to console
*
* @param message The message to send
*/
public static void info(String message) {
INSTANCE.getLogger().info(StringUtils.translate(message));
}
/**
* Print a warning to console
*
* @param message The warning
*/
public static void warn(String message) {
INSTANCE.getLogger().warning(StringUtils.translate(message));
}
/**
* Print an error to console
*
* @param message The error
*/
public static void error(String message) {
INSTANCE.getLogger().severe(StringUtils.translate(message));
}

View File

@@ -9,19 +9,32 @@ import java.io.InputStream;
import java.net.URL;
import java.util.Scanner;
/**
* Checks spigot if EcoEnchants is out of date
*/
public class UpdateChecker {
private static boolean outdated;
private static String newVersion;
private final Plugin plugin;
private final int resourceId;
/**
* Create an update checker for the specified spigot resource id
*
* @param plugin The plugin to check
* @param resourceId The resource ID of the plugin
*/
public UpdateChecker(Plugin plugin, int resourceId) {
this.plugin = plugin;
this.resourceId = resourceId;
}
/**
* Get the latest version of the plugin
*
* @param consumer The process to run after checking
*/
public void getVersion(final Consumer<? super String> consumer) {
Bukkit.getScheduler().runTaskAsynchronously(this.plugin, () -> {
try (InputStream inputStream = new URL("https://api.spigotmc.org/legacy/update.php?resource=" + this.resourceId).openStream(); Scanner scanner = new Scanner(inputStream)) {
@@ -34,18 +47,38 @@ public class UpdateChecker {
});
}
/**
* Get if the plugin is outdated
*
* @return If the plugin is outdated
*/
public static boolean isOutdated() {
return outdated;
}
/**
* Get the newest available version of the plugin
*
* @return The latest version
*/
public static String getNewVersion() {
return newVersion;
}
/**
* Mark the plugin as outdated or not
*
* @param outdated Whether the plugin is outdated
*/
public static void setOutdated(boolean outdated) {
UpdateChecker.outdated = outdated;
}
/**
* Set the newest available version of the plugin
*
* @param newVersion The newest version
*/
public static void setNewVersion(String newVersion) {
UpdateChecker.newVersion = newVersion;
}

View File

@@ -8,13 +8,23 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* An object representing a condition that must be met in order to perform an action
*/
public class Prerequisite {
private static final List<Prerequisite> values = new ArrayList<>();
/**
* Requires the server to be running minecraft version 1.16 or higher
*/
public static final Prerequisite MinVer1_16 = new Prerequisite(
() -> !Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3].contains("15"),
"Requires minimum server version of 1.16"
);
/**
* Requires the server to be running an implementation of paper
*/
public static final Prerequisite HasPaper = new Prerequisite(
() -> ClassUtils.exists("com.destroystokyo.paper.event.player.PlayerElytraBoostEvent"),
"Requires server to be running paper (or a fork)"
@@ -24,6 +34,12 @@ public class Prerequisite {
private final ObjectCallable<Boolean> isMetCallable;
private final String description;
/**
* Create a prerequisite
*
* @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
*/
public Prerequisite(ObjectCallable<Boolean> isMetCallable, String description) {
this.isMetCallable = isMetCallable;
this.isMet = isMetCallable.call();
@@ -31,10 +47,20 @@ public class Prerequisite {
values.add(this);
}
/**
* Get the description of the prerequisite
*
* @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;
}
@@ -43,10 +69,19 @@ public class Prerequisite {
this.isMet = this.isMetCallable.call();
}
/**
* Update all prerequisites' {@link Prerequisite#isMet}
*/
public static void update() {
values.forEach(Prerequisite::refresh);
}
/**
* Check if all prerequisites in array are met
*
* @param prerequisites A primitive array of prerequisites to check
* @return If all the prerequisites are met
*/
public static boolean areMet(Prerequisite[] prerequisites) {
update();
return Arrays.stream(prerequisites).allMatch(Prerequisite::isMet);

View File

@@ -7,23 +7,49 @@ public class Pair<A, B> {
private A first;
private B second;
/**
* Create a pair
*
* @param first The first item in the tuplet
* @param second The second item in the tuplet
*/
public Pair(A first, B second) {
this.first = first;
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;
}

View File

@@ -8,32 +8,69 @@ public class Triplet<A, B, C> {
private B second;
private C third;
/**
* Create a triplet
*
* @param first The first item in the tuplet
* @param second The second item in the tuplet
* @param third The third item in the tuplet
*/
public Triplet(A first, B second, C third) {
this.first = first;
this.second = second;
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;
}